当前位置: 首页 > 编程日记 > 正文

ORB-SLAM2系统的实时点云地图构建

ORB-SLAM2系统的实时点云地图构建

  • 这篇博客
  • 点云地图构建的流程
  • 代码介绍
    • 点云地图构建类对象
    • 小调整
    • 获取关键帧
    • 点云地图构建与叠加
    • 在地图中设置当前相机位置
    • 点云地图到Octomap的转换
  • 地图效果
  • 结尾

这篇博客

(PS:修改于2020-9-21,添加了关于System和Tracking类中相关函数的修改(“小调整”中的内容))
 这篇博客介绍如何给ORB-SLAM2系统添加实时点云地图构建环节。这个项目高翔博士已经做过,在GitHub上也能找到相关代码。在参考这个项目之后,我尝试用自己的方式来实现地图构建环节,并添加了一些新的东西。下面来看一下修改后的整个环节的工作流程。

点云地图构建的流程

构建点云地图需要用到彩色图,深度图和帧的位姿信息。为了防止构建的地图过大,降低内存负担,系统只使用关键帧来构建点云地图(也能减少点云地图中重叠的部分)。整个地图构建的流程如下:

 最后两步是自己做的修改部分,目的在于增强地图的可视效果,以及给后续导航操作提供便利。整个系统是在ROS下运行的,相关代码实现如下:

代码介绍

在代码中,将地图构建环节定义为一个类对象,通过其中的成员函数来完成流程图中的操作。原来的项目是单独拿出一个线程来实现点云地图的更新和显示操作。但为了适应后面新加的部分操作,这里就不使用单独的线程来实现,而是在Tracking的线程中进行该类对象的函数调用。
 先来看看构建地图的类包含了哪些成员。

点云地图构建类对象

class MyPclMapping
{
public:typedef pcl::PointXYZRGBA PointT;typedef pcl::PointCloud<PointT> PointCloud;//类对象的构建函数MyPclMapping();//获取新关键帧的函数void insertKF(KeyFrame* kf,Mat &color,Mat &depth);//构建关键帧对应的点云地图,并将新旧地图叠加void generatepcl(KeyFrame *kf,Mat &color,Mat &depth);//返回以构建的完整点云地图。这个在进行八叉树转换时使用PointCloud::Ptr Getglobalmap(){unique_lock<mutex> locker(generation);return globalMap;}//设置当前相机在地图中的位置void setcurrentCamera(Mat Rwc,Mat twc);
private://保存构建所使用的彩色图像,深度图和关键帧vector<Mat> rgbs;vector<Mat> depthes;vector<KeyFrame*> kfs;//构建的完整点云地图PointCloud::Ptr globalMap;Eigen::Vector3d kfplace;//使用PCLVisualizer对象来显示地图pcl::visualization::PCLVisualizer showcamera;Eigen::Vector3d currentcamera;cv::Mat currentTwc;
};

小调整

在System类和Tracking类中定义上述类对象的指针,以便其获得关键帧和对应的图像信息(在初始化System和Tracking类对象时同时初始化地图构建的指针即可):
1、对System类中成员和函数的一些修改:

//加在System.h中,声明一些新成员和函数
MyPclMapping* pointcloud;
MyPclMapping* Getpcl()
{return pointcloud;
}
//加在System类构造函数体中,用于初始化MyPclMapping和Tracking的类对象
pointcloud=new MyPclMapping();
mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer,mpMap,pointcloud ,mpKeyFrameDatabase, strSettingsFile, mSensor);

2、对Tracking类中成员和函数的一些修改:

//在Tracking.h中添加MyPclMapping类对象指针,并调整Trakcing类的构造函数中的形参
Tracking(System* pSys, ORBVocabulary* pVoc, FrameDrawer* pFrameDrawer, MapDrawer* pMapDrawer, Map* pMap,MyPclMapping* pCloud,KeyFrameDatabase* pKFDB, const string &strSettingPath, const int sensor);
MyPclMapping* pointmapping;
//在Tracking类构造函数中使用成员初始化表初始化MyPclMapping类对象指针
Tracking::Tracking(System *pSys, ORBVocabulary* pVoc, FrameDrawer *pFrameDrawer, MapDrawer *pMapDrawer, Map *pMap,MyPclMapping* pCloud, KeyFrameDatabase* pKFDB, const string &strSettingPath, const int sensor):mState(NO_IMAGES_YET), mSensor(sensor), mbOnlyTracking(false), mbVO(false), mpORBVocabulary(pVoc),mpKeyFrameDB(pKFDB), mpInitializer(static_cast<Initializer*>(NULL)), mpSystem(pSys), mpViewer(NULL),mpFrameDrawer(pFrameDrawer), mpMapDrawer(pMapDrawer), mpMap(pMap), mnLastRelocFrameId(0),pointmapping(pCloud)

(这一部分是添加的内容)
下面介绍如何一步步实现流程中的操作,首先是获得关键帧:

获取关键帧

因为关键帧是由Tracking类中的CreateNewKeyFrame成员函数产生的,所以该函数的最后添加下述代码:
pointmapping->insertKF(pKF,this->currentrgb,this->currentdepth);
pointmappingTracking中定义的地图构建指针对象。关于它的insertKF函数的代码如下:

void MyPclMapping::insertKF(KeyFrame* kf,cv::Mat &color,cv::Mat &depth)
{//在更新已有地图时加锁,防止和Getglobalmap函数冲突unique_lock<mutex> locker(generation);cv::Mat rgb=color.clone();cv::Mat D=depth.clone();//构建关键帧对应的点云地图generatepcl(kf,rgb,D);//将这些信息保存下来rgbs.push_back(color.clone());depthes.push_back(depth.clone());kfs.push_back(kf);
}   

至此第一步就完成了。需要注意的是代码中的 “currentdepth” 是原深度图经过一定变化后的Mat对象。变换的方法如下(代码添加在Tracking中的GrabImageRGBD函数后面):

if(mDepthMapFactor!=1 || imDepth.type()!=CV_32F)//一定要注意调节这里!!!!
{imDepth.convertTo(imDepth,CV_32F,mDepthMapFactor);
}
currentdepth=imDepth;

深度图要经过转换后(根据RGB-D相机的深度单位进行变换)再用于构建点云地图,否则构建出的地图会像千层饼一样(血的教训)。彩色图像使用原图即可。之后介绍点云地图的构建和叠加操作。
PS:这里的 “currentrgb” 和 “currentdepth” 是在Tracking类中新加的对象,专门用来构建点云地图的。

点云地图构建与叠加

地图的构建和叠加通过generatepcl函数实现:

void MyPclMapping::generatepcl(KeyFrame* kf,cv::Mat &color,cv::Mat &depth)
{//用temp保存关键帧对应的点云地图PointCloud::Ptr temp(new PointCloud());//获得关键帧的估计位姿Eigen::Isometry3d T=ORB_SLAM2::Converter::toSE3Quat(kf->GetPoseInverse());//遍历彩色图像,构建点云地图(在关键帧的坐标系下)for(int v=0;v<color.rows;v+=3)//为了降低地图占用的内存大小,遍历的步长定为3{for(int u=0;u<color.cols;u+=3){float d=depth.ptr<float>(v)[u];if(d<0) continue;PointT p;//计算地图点的坐标p.z=d;p.x=p.z*(u-kf->cx)/kf->fx;p.y=p.z*(v-kf->cy)/kf->fy;//给地图点上色p.b=color.data[v*color.step+u*color.channels()];p.g=color.data[v*color.step+u*color.channels()+1];p.r=color.data[v*color.step+u*color.channels()+2];temp->points.push_back(p);}   }PointCloud::Ptr cloud(new PointCloud());//将新构建的地图变换到世界坐标系下pcl::transformPointCloud(*temp,*cloud,T.matrix());cloud->is_dense=false;//完成新旧地图的叠加(*globalMap)+=(*cloud);
}

此函数完成了点云地图的构建和更新。之后要做的是在地图中显示出相机的位置,以及完成地图到Octomap(八叉树地图)的转换。

在地图中设置当前相机位置

原来的项目使用pcl::visualization::CloudViewer类来显示点云地图。这个类的功能较少,几乎就只有显示地图这个用途。因此,在这里用pcl::visualization::PCLVisualizer类来显示地图和相机的位置。下面是相关代码:

//参数:从相机坐标系到世界坐标系的旋转矩阵和平移向量
void MyPclMapping::setcurrentCamera(Mat Rwc,Mat twc)
{Mat Twc=Mat::eye(4,4,Rwc.type());//获得当前相机的位姿Rwc.copyTo(Twc(Rect(0,0,3,3)));twc.copyTo(Twc(Rect(3,0,1,3)));currentTwc=Twc.clone();g2o::SE3Quat q=ORB_SLAM2::Converter::toSE3Quat(currentTwc);Eigen::Isometry3d T=Eigen::Isometry3d::Identity();T.rotate(q.rotation());T.pretranslate(q.translation());Eigen::Vector3d currentpoint(0.1,0.1,0.1);//获得相机在世界坐标系下的坐标位置currentcamera=T*currentpoint;PointCloud::Ptr temp(Getglobalmap());//获得完整的点云地图//刷新PCLVisualizer对象中保存的内容showcamera.removeAllPointClouds();showcamera.removeAllShapes();showcamera.addPointCloud(temp);Eigen::Quaternionf qf(float(q.rotation().coeffs()[3]),float(q.rotation().coeffs()[0]),float(q.rotation().coeffs()[1]),float(q.rotation().coeffs()[2]));//用一个立方体来表示相机showcamera.addCube(Eigen::Vector3f(q.translation()[0],q.translation()[1],q.translation()[2]),qf,0.7,0.7,1.2);//显示一次当前地图中的内容showcamera.spinOnce();
}

函数通过不断刷新PCLVisualizer类对象保存的内容,达到显示点云地图和实时相机位置的功能。相机的实时位姿要依据Tracking线程的跟踪结果,所以在Tracking类的GrabImageRGBD函数的最后加上这一行调用代码:
pointmapping->setcurrentCamera(mCurrentFrame.GetRotationInverse(),mCurrentFrame.GetCameraCenter());
 到此关于点云地图部分的操作就弄完了,之后就是如何将其转换成Octomap。

点云地图到Octomap的转换

点云地图转换到Octomap的代码实现请参考这个博客。但这里是使用ROS中的octomap_server节点,将点云地图转成Octomap。这需要把已构建的点云地图发布到一个topic上。因此对原来系统的ros_rgbd.cpp文件进行修改,主要修改其中定义的ImageGrabber类对象:

class ImageGrabber
{
public:ImageGrabber(ORB_SLAM2::System* pSLAM):mpSLAM(pSLAM){//修改:创建一个线程实时地向ROS发布已构建的点云地图pclpub=make_shared<thread>( bind(&ImageGrabber::pclpublish, this ) );}void GrabRGBD(const sensor_msgs::ImageConstPtr& msgRGB,const sensor_msgs::ImageConstPtr& msgD);//修改:发布点云地图的函数void pclpublish();ORB_SLAM2::System* mpSLAM;//修改:地图发布线程对象shared_ptr<thread> pclpub;
};

ImageGrabber类对象添加了用于实时发布点云地图信息的函数和线程。发布地图信息的pclpublish函数代码如下:

void ImageGrabber::pclpublish()
{ros::NodeHandle nh;//将点云地图发布到 “pcltext” 话题上ros::Publisher pub=nh.advertise<sensor_msgs::PointCloud2>("/pcltext",1);string frameid="camera";sensor_msgs::PointCloud2 msg;while(1){//获得已构建的点云地图PointCloud::Ptr pointmap((mpSLAM->Getpcl())->Getglobalmap());pcl::PointCloud<pcl::PointXYZ> pclmsg;//octomap_server转换需要的是没有颜色的点云地图//所以将以构建的彩色点云地图变成无色的for(int i=0;i<pointmap->points.size();i++){pcl::PointXYZ point;point.x=pointmap->points[i].x;point.y=pointmap->points[i].y;point.z=pointmap->points[i].z;pclmsg.points.push_back(point);}//将点云地图转换成ROS中的信息数据形式pcl::toROSMsg(pclmsg,msg);msg.header.stamp=ros::Time::now();msg.header.frame_id=frameid;//发布地图信息pub.publish(msg);usleep(2000);}
}

通过这个函数就将构建好的点云地图发布到了对应的ROS话题上。在这里使用了多线程的方法。
 之后用octomap_server接受 “pcltext” 话题的信息就能完成地图的转换。为了方便启动octomap_server节点,编写一个launch文件:

<launch><!-- 使用的功能包的名称;启动的节点;启动后节点的名字--><node pkg="octomap_server" type="octomap_server_node" name="octomap_server"><!--分辨率(米/像素) --><param name="resolution" value="0.05" /><!-- name of the fixed frame, needs to be "/map" for SLAM这里需要和发布的点云地图中的frameid一致 --><param name="frame_id" type="string" value="/camera" /><!-- max range / depth resolution of the kinect in meter超出100的读数,它的值用100代替 --><param name="sensor_model/max_range" value="100.0" /><param name="latch" value="true" /><!-- max/min height for occupancy map, should be in meters --><param name="pointcloud_max_z" value="1000" /><param name="pointcloud_min_z" value="0" /><!-- 让节点订阅点云地图发布的话题 --><remap from="/cloud_in" to="/pcltext" /></node>
</launch>

在操作过程中,先启动带有点云地图发布的系统,再启动这个launch文件(要让 “pcltext” 话题上有点云地图的信息)。

地图效果

上述就是整个地图构建环节的实现代码。在操作过程中,先启动带有点云地图发布的系统,再启动关于octomap_server的launch文件。最后通过Rviz显示构建的Octomap(点云地图已设置了显示窗口)。关于如何使用Rviz来显示八叉树地图大家可以参考这个博客。这个博客也介绍了一种构建地图的方法(🐂)。
 最终整个系统在仿真环境(仿真环境在GitHub上开源,是其他前辈写的)中工作的效果图如下所示:

 左下角的是实时构建的点云地图。地图中使用一个立方体来表示相机当前的位置,放大来看就是:

 使用立方体的长轴表示相机的前后两个方向,短轴则是左右方向。这样的好处是可以只通过这个地图来控制机器在环境中移动,躲避障碍。这个图的上方就是转换后的Octomap。

结尾

至此整个修改后的点云地图构建环节就介绍完了。之前想着再在点云地图中显示所有关键帧的位置,以表明相机的运动轨迹。但这样会消耗挺大内存,所以需要考虑其他方法。此外,这个系统还存在不足的地方:
 1、在检测到闭环以后,已构建的点云地图不会根据闭环进行地图的修复;
 2、立方体前后方向、左右方向区分度很差。
 看来还是任重而道远,慢慢来吧。

参考资料:
 1、https://blog.csdn.net/crp997576280/article/details/74605766
 2、https://blog.csdn.net/fb_941219/article/details/89002257

PS:转载请标明出处

相关文章:

使用maven导入jar包

我们都经历过自己写代码时有时就要引用一些第三方的jar包&#xff0c;这个我们都会&#xff0c;但在公司里进行团队开发时&#xff0c;是不允许我们自己导入jar包的&#xff0c;是由项目组长之类的统一导入jar包&#xff0c;我们在这里来了解一下这个过程&#xff1a; a、先创建…

Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法...

Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法 www.MyException.Cn 发布于&#xff1a;2012-09-15 19:09:28 浏览&#xff1a;164次0Struts2中action接收参数的三种方法及ModelDriven和Preparable接口结合JAVA反射机制的灵活…

关于CSS的长度单位及颜色表示

长度单位 1.q 1/4mm. 2.px 计算机语言中的像素。大多数网页制作常用图片分辨率为72&#xff0c;即每英寸像素为72,1英寸等于2.54cm。那么通过换算可以得出每厘米等于28像素。 3.em 它是描述相对于应用在当前元素的字体尺寸&#xff0c;所以它也是相对长度单位。一班浏览器字体大…

2021年中国工业互联网安全大赛核能行业赛道writeup之鱿鱼游戏

目录 一、尝试 二、Writeup 附加题 鱿鱼游戏&#xff08;来自最近一部很火的韩剧&#xff09; 题目描述&#xff1a; 小王由于操作不规范&#xff0c;误将不明U盘插入到上位机中&#xff0c;导致上位机中的某些关键文件被加密&#xff0c;但攻击者在U盘中还留下了一个可执行…

视觉惯性SLAM: VI ORB-SLAM

视觉惯性SLAM: VI ORB-SLAM这篇博客视觉惯性SLAM预备知识符号说明&#xff1a;相机投影变换矩阵IMU数据更新方程IMU数据的预积分VI ORB-SLAM各环节工作方式InitializationTrackingLocalMappingLoop ClosingFull BAIMU初始化估计bgb_{g}bg​估计尺度sss和重力向量gWg_{W}gW​&am…

AEC、AGC、ANS在视音频会议中的作用?

AGC是自动增益补偿功能&#xff08;Automatic Gain Control&#xff09;&#xff0c;AGC可以自动调麦克风的收音量&#xff0c;使与会者收到一定的音量水平&#xff0c;不会因发言者与麦克风的距离改变时&#xff0c;声音有忽大忽小声的缺点。ANS是背景噪音抑制功能&#xff08…

Java中的拆箱与装箱

我们先来了解一下拆箱与装箱的概念&#xff1a; 装箱&#xff1a;将基本数据类型转换为包装类&#xff1b; 拆箱&#xff1a;将包装类转换为基本数据类型 我们来看两串代码&#xff1a; Integer b1 127;Integer b2 127;System.out.println(b1b2);//trueInteger b3 128;Inte…

WannaCry的UWP版,哈哈哈

转载于:https://www.cnblogs.com/R00R/p/6916731.html

2021年中国工业互联网安全大赛核能行业赛道writeup之数据库登录

附件题&#xff1a;数据库登录&#xff08;一道MISC、流量分析类型题目&#xff09; 题目描述&#xff1a; 具体描述已经忘记o(╯□╰)o 大概意思就是分析附件里的.pcapng包&#xff0c;找到flag。流量涉及到 MySQL 数据库了。 附件下载&#xff1a; https://download.csdn.n…

学生管理系统(用maven来导入jar包)

不废话&#xff0c;直接上 先看一下项目列表&#xff1a; 首先创建一个maven工程&#xff0c;然后导入相应的jar包&#xff0c;请参考&#xff1a;使用maven导入jar包 接着在Source Folder创建具体的项目&#xff1a; Main类&#xff08;客户端&#xff09; package com.z…

视觉惯性SLAM:VINS-Mono

视觉惯性SLAM&#xff1a;VINS-Mono这篇博客一些符号说明IV 测量数据的预处理A.视觉处理前端B.IMU预积分V. 初始化A.Vision-Only SfM in Sliding WindowB.Visual-Inertial AlignmentVI.TIGHTLY COUPLED MONOCULAR VIOA.公式介绍B.IMU误差C.视觉误差D.边缘化E.位姿优化F.以IMU采…

mysql 0x80004005 unable to connect to any of the specified mysql hosts

语言&#xff1a;c# 问题&#xff1a;偶尔会出现连不上mysql 报标题的这个错误。 解决方法&#xff1a;把server localhost 改为 127.0.0.1 或者静态IP &#xff0c;按着改暂时没出现了&#xff0c;继续观望&#xff01; 转载于:https://www.cnblogs.com/wdw31210/p/9857514…

iOS开发-自己定义重用机制给ScrollerView加入子视图

iOS开发-自己定义重用机制给ScrollerView加入子视图 事实上这个问题我非常早就想过&#xff0c;仅仅是没有通过去写程序实现&#xff0c;昨天有人提起&#xff0c;我就巧了一下 不知道大家打印郭tableview&#xff1a;cellforrow中cell初始的次数&#xff0c;也就是重用池中的c…

2021年中国工业互联网安全大赛核能行业赛道writeup之Webshell密码

附件题&#xff1a;Webshell密码 题目描述&#xff1a; 某次攻防演练中&#xff0c;抓到了一个webshell的流量&#xff0c;请分析出密码&#xff0c;flag形式&#xff1a;flag{密码} 附件下载&#xff1a; https://download.csdn.net/download/qpeity/33675356https://downlo…

关于python3与python2同时存在情况下导入pyqt失败解决记录

最近感觉tkinter功能还是比较不适合新手做出高大上的界面&#xff0c;故开始使用pyqt&#xff0c;通过pip安装好了之后&#xff0c;利用qt设计师设计好界面之后&#xff0c;cmd运行之&#xff0c;报错提示没有找到pyqt5模块&#xff0c;IDE运行能正常加载 查找资料后发现&#…

ORBSLAM-Altas:多地图SLAM

ORBSLAM-Atlas&#xff1a;多地图SLAM这篇博客ORBSLAM-Altas这个系统系统方法两类子地图新地图的构建相机位姿的可观测性子地图融合系统线程结尾这篇博客 最近ORB-SLAM3横空出世&#xff0c;马上跑去GitHub膜拜。然后在项目的相关工作中看到了ORB-SLAM3使用了一个多地图方法。这…

Android驱动学习-内部机制_回顾binder框架关键点

内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie client使用服务前要先getService&#xff1a;会在驱动程序里对该服务构造一个binder_ref, binder_ref含有desc, node成员…

数据库--事务

我们知道数据库中的SQL语句分为DDL(数据定义语言)、DQL(数据查询语言)、DML(数据操纵语言)、DCL(数据控制语言)&#xff0c;详情请看SQL语句 当数据库的表中数据执行完添加、删除、和修改等数据操纵语言&#xff08;DML&#xff09;后&#xff0c;需要执行commit(提交)数据控制…

2021年中国工业互联网安全大赛核能行业赛道writeup之传统流量取证

附件题&#xff1a;传统流量取证 题目描述&#xff1a; 在某次攻防演练中&#xff0c;小王发现流量探针平台突然告警&#xff0c;小王第一时间下载了告警流量包&#xff0c;并进行分析&#xff1a;发现攻击队攻击在攻入内网后&#xff0c;利用了一个内网OA的一个漏洞&#xff…

ORB-SLAM3 论文笔记

ORB-SLAM3 论文笔记这篇博客ORB-SLAM3系统相机模型的抽象(Camera Model)重定位的问题图片矫正的问题视觉惯性SLAM的工作原理相关公式IMU初始化跟踪和建图系统对跟踪丢失的应对多地图的闭环检测和地图融合位置识别视觉地图融合方法视觉惯性地图的融合方法单个地图中的闭环融合结…

为什么需要 外键 呢?

生活现象&#xff1a; 不知你们是否遇到过这样的现象&#xff0c;就是你辛辛苦苦花了几十块钱注册一个会员&#xff0c;结果家里的七大姑&#xff0c;八大姨都要拿去用&#xff0c;而且完全可以用。还有就是一个淘宝账号里却可以添加好多个收获地址(里面包括收货人的姓名&#…

JavaScript闭包函数箭头函数调用与执行

一、标准的闭包函数 //一、标准的闭包函数 function A() {var i0;i;console.log(i : i);return function b() {return function c() {return i}} }var a A(); // 初始化A&#xff0c;执行A内的非function语句 ‘ i0; i‘&#xff0c;输出 I : 1 console.log(a()); // 执行fu…

jlink api sdk c# 离线数获取 标定

jlink 如何 离开 keil、IAR 监控变量呢&#xff1f; 目前 jlink的 api 可以做到&#xff0c;自己可以用C# 做一个 上位机&#xff0c;监控RAM里面的变量。而不用打开keil 调试。还可以 刷写 flash&#xff0c;可以用在产品量产的刷写上。SEGGER 的 jlink sdk并不是免费的&…

2021年中国工业互联网安全大赛核能行业赛道writeup之usb流量分析

目录 一、USB协议 二、键盘流量 三、鼠标流量 四、writeup 附件题&#xff1a;usb流量分析 题目描述&#xff1a; 具体描述忘记了o(╯□╰)o 大概意思是有个U盘插到电脑上&#xff0c;然后经过一些操作导致该电脑重启了。找到这个过程中的flag。 附件下载&#xff1a; 20…

BOS项目 第2天(BaseDao、BaseAction、用户登录、自定义strust登录拦截器)

BOS项目 第2天 今天内容安排&#xff1a; 1、根据提供的pdm文件生成sql 2、持久层和表现层设计---BaseDao、BaseAction 3、实现用户登录功能 4、jQuery EasyUI 消息提示控件 5、jQuery EasyUI menubutton菜单按钮 6、自定义struts2拦截器&#xff0c;实现用户未登录自动跳转到…

服务器 主动 推送 客户端浏览器 消息***

前言 通常情况下&#xff0c;无论是web浏览器还是移动app&#xff0c;我们与服务器之间的交互都是主动的&#xff0c;客户端向服务器端发出请求&#xff0c;然后服务器端返回数据给客户端&#xff0c;客户端浏览器再将信息呈现&#xff0c;客户端与服务端对应的模式是: 客户端请…

数据库表(字段类型、约束、截断表、修改表字段、重命名表)

字段类型&#xff1a; 在这里只列举一些常用的字段类型&#xff1a; 整数类型:int(Integer):普通大小的整数 小数类型&#xff1a; float(m,d)&#xff1a;单精度浮点数&#xff0c;m表示数字长度&#xff0c;d表示小数位数&#xff0c;例如float(5,2)最大值999.99double(m,d…

(转载)动态SLAM系统:VDO-SLAM!

动态SLAM系统&#xff1a;VDO-SLAM&#xff01;这篇博客是转载 计算机视觉life 公众号中的文章。这篇文章是对VDO-SLAM论文的全文翻译&#xff0c;是 &#xff01;&#xff01;真人工翻译&#xff01;&#xff01;不是机器翻译&#xff0c;我看了之后觉得挺好&#xff0c;所以分…

2021年中国工业互联网安全大赛核能行业赛道writeup之入门的黑客

附件题&#xff1a;入门的黑客 题目描述&#xff1a; 在某次工控攻防演练中&#xff0c;防守方使用蜜罐捕捉到了某黑客在入侵时留下的恶意程序样本&#xff0c;现在要对该黑客进行画像&#xff0c;需要从该恶意程序中分析出反连时的IP和端口信息&#xff0c;看看聪明的你能否能…

一种视觉惯性+激光传感器的SLAM系统

一种视觉惯性激光传感器的SLAM系统这篇博客论文摘要一些假设和标注系统总览VI 里程计扫描匹配&#xff08;scan matching&#xff09;优化提高系统鲁棒性的措施闭环检测和临近检测全局位姿图优化总结这篇博客 这篇论文“Robust High Accuracy Visual-Inertial-Laser SLAM Syste…