当前位置:网站首页>Aloam code reading and summary
Aloam code reading and summary
2022-07-02 17:53:00 【xiaoma_ bk】
List of articles
Aloam
A-LOAMyesLOAMAdvanced implementation of , It USES Eigen and Ceres Solver To simplify the code structure . This code is created byLOAMandLOAM_NOTEATo modify . This code is simple and clear , There is no complex mathematical derivation and redundant operation . about SLAM It is a good learning material for beginners .Node diagram :
KITTI Example
- download KITTI Odometry dataset Data set to Your dataset folder , Set up
dataset_folderandsequence_numberParameters . - Please note that , You can also use the
kitti_helper.launchSet appropriate parameters in to KITTI Data sets are converted to package files for ease of use .
- download KITTI Odometry dataset Data set to Your dataset folder , Set up
Summary
advantage :
- The code is indeed much simpler , If there is loam The foundation is looking at this , It's really clear at a glance .
Suggest :
When calculating curvature , Between every line shift Not taken into account , But it doesn't affect , Because how many starting points of each line are skipped when extracting features
When filtering features based on curvature , Because the point cloud has been ordered based on curvature
- Corner point :if The curvature should be greater than 0.1 establish , Otherwise directly break Is it not good? , Do not waste time after traversing
- Plane point :if The curvature should be less than 0.1 establish , Otherwise directly break Is it not good? , Do not waste time after traversing
Make sure when you get close Straight line and plane I don't feel it lio-sam Medium and high precision
ceres Optimize , How about a manual derivation
rosbag read_write
- Reading and writing rosbag be used bag class , See the following example for specific use :
// Define read / write objects , And declare that
rosbag::Bag i_bag, o_bag;
i_bag.open(src_bag, rosbag::bagmode::Read);
o_bag.open(new_bag, rosbag::bagmode::Write);
// Define an array
std::vector<std::string> topics;
topics.push_back(std::string(imu_topic));
topics.push_back(std::string(pcd_topic));
// Affirming rosbag::View object
rosbag::View view(i_bag, rosbag::TopicQuery(topics));
///< Read method 1 :
for (auto m : view) {
// Traverse view
sensor_msgs::Imu::ConstPtr imu = m.instantiate<sensor_msgs::Imu>();
if (imu == nullptr) {
// Is there a imu
std::cerr << "imu null " << std::endl;
} else {
std::cout << "imu stamp:" << imu->header.stamp << std::endl;
o_bag.write(imu_topic, imu->header.stamp, imu);
}
sensor_msgs::PointCloud2::ConstPtr pcd =
m.instantiate<sensor_msgs::PointCloud2>();
if (pcd == nullptr) {
std::cerr << "pcd null " << std::endl;
} else {
std::cout << "pcd stamp:" << pcd->header.stamp << std::endl;
o_bag.write(pcd2_topic, pcd->header.stamp, pcd);
}
}
///< Read method 2 :
rosbag::View view(bag);
for (const rosbag::ConnectionInfo* c : view.getConnections()) {
const std::string& topic = c->topic;
if (topic_to_publisher.count(topic) == 0) {
ros::AdvertiseOptions options(c->topic, kQueueSize, c->md5sum,
c->datatype, c->msg_def);
topic_to_publisher[topic] = node_handle.advertise(options);
}
}
scanRegistration
The main function :
- Ros node
- ros Node initialization
scanRegistration - Read parameters :
scan_line、minimum_range
- ros Node initialization
- Only support 16,32,64 Linear velodyne, If not return
- Subscribe to the topic :
/velodyne_pointslaserCloudHandler
- Post topics :
sensor_msgs::PointCloud2>("/velodyne_cloud_2", 100);sensor_msgs::PointCloud2>("/laser_cloud_sharp", 100);sensor_msgs::PointCloud2>("/laser_cloud_less_sharp", 100);sensor_msgs::PointCloud2>("/laser_cloud_flat", 100);sensor_msgs::PointCloud2>("/laser_cloud_less_flat", 100);sensor_msgs::PointCloud2>("/laser_remove_points", 100);
- Based on parameters Determine whether to publish each line Normal does not execute
laserCloudHandler
- The last system initialization , Is simply how many frames to skip
- Point cloud rotation pcl Format ,pcl::removeNaNFromPointCloud
- Remove the nearest point ,removeClosedPointCloud
- Traverse each point , seek Point to Laser distance , If the distance is less than the threshold , be continue
- Otherwise, put the point into a new container
- Starting angle calculation :
- Starting angle :startOri = -atan2(pointp[0].y,pointp[0].x)
- End angle :endOri = -atan2(pointp[size-1].y,pointp[size-1].x)+2π
- if endOri-startOri > 3π endOri -= 2π
- if endOri-startOri < 3π endOri += 2π
- Calculation scanID + relTime
- scanID Which line , Good calculation
- relTime Time difference from the initial point Calculate the horizontal angle with the initial point * cycle / Total angle
- Calculate the curvature of each point
- Follow loam The calculation is the same
- Between every line shift Not taken into account , But it doesn't affect , Because how many starting points of each line are skipped when extracting features
- Traverse Multi line
N_SCANS, For each line , Divide the point cloud into 6 Share :- Calculate the starting subscript of each copy : sp,ep
- Sort each point cloud according to the curvature from small to large
std::sortfunction - Corner finding , Reverse traversal of ordered point clouds
- If the curvature is greater than 0.1 And The surrounding points can be feature points when :
- Find the one with the largest curvature 2 Point in
cornerPointsSharpPoint cloud markers :2 - Find curvature maximal 20 Put in
cornerPointsLessSharpPoint cloud markers :1 - If the point is marked as a characteristic point , The surrounding 5 A point cannot be a feature point
- Find the one with the largest curvature 2 Point in
- If the curvature is greater than 0.1 And The surrounding points can be feature points when :
- Find a flat point , Traverse the ordered point cloud forward
- If the curvature is less than 0.1 And The surrounding points can be feature points when :
- Find the one with the largest curvature 4 Point in
surfPointsFlatPoint cloud markers :-1 - If the point is marked as a characteristic point , The surrounding 5 A point cannot be a feature point
- Find the one with the largest curvature 4 Point in
- If the curvature is less than 0.1 And The surrounding points can be feature points when :
- if Marked as -1 Put in
surfPointsLessFlatScan
laserOdometry
The main function :
- Ros node
- ros Node initialization
laserOdometry - Read parameters :
mapping_skip_frameDefault 2
- ros Node initialization
- Subscribe to the topic :
/velodyne_cloud_2laserCloudFullResHandler- This point cloud goes to the nearest point and nan Of
- This callback is also relatively simple , take Put the data in the queue
- Four characteristics , Corner point , Corner point less, Plane point , Plane point less
- These four callbacks are relatively simple , Just put the data in the queue
- Release :
- Corner point and Plane point
velodyne_cloud_3laser_odom_to_initlaser_odom_path
- while The main thread ,ros::spin0nce,100hz
- above 5 All kinds of data arrive And Take the first data when the time is the same
- When 5 All kinds of data arrive , The time must be the same , atypism ros Report errors
- 5 Kind of data pcl Data conversion
- if systemInited== flase when :
- Direct assignment systemInited=true
- otherwise , Optimize twice , Do the following for each time :
- The optimization variable is Postures para_q,para_t,4+3 A degree of freedom
- Traverse corner features :
- Convert corners to odometer coordinate system ,TransformToStart
- adopt kdTree find A straight line
- adopt kdTree Find the nearest corner subscript in the previous frame
pointSearchInd - This point subscript Up and down range The nearest point in is Another point
- Two points form a straight line
- adopt kdTree Find the nearest corner subscript in the previous frame
- adopt LidarEdgeFactor structure ceres Direct constraint
- And add residuals
- Traverse planar features :
- Convert the plane point to the odometer coordinate system ,TransformToStart
- adopt kdTree find Plane
- adopt kdTree Find the nearest corner subscript in the previous frame
pointSearchInd - This point subscript Up and down range The nearest point in is Another point
- same ring in Stretch forward Planar features as The third point
- adopt kdTree Find the nearest corner subscript in the previous frame
- adopt LidarPlaneFactor structure ceres Direct constraint
- And add residuals
- Build solver : iteration 4 Time ,QR decompose , Get the solution
- to update
q_w_currandt_w_curr - to update On a frame Corner points and plane points kdTree
- above 5 All kinds of data arrive And Take the first data when the time is the same
TransformToStart
- The relationship between the last odometer coordinate system is recorded , Directly convert according to the last relationship
- The idea that The initial value of the current frame is the same as that of the previous frame , Easy to calculate
LidarEdgeFactor
- The distance between a point and a line , Automatic derivation
LidarPlaneFactor
- Point to the distance of peace , Automatic derivation
laserMapping
The main function :
- ros Node initialization
- Define the node
laserMapping - Read parameters :
mapping_line_resolution0.4mapping_plane_resolution0.8
- Define the node
- Subscribe to the topic :
/laser_cloud_corner_lastlaserCloudCornerLastHandler/laser_cloud_surf_lastlaserCloudSurfLastHandler/laser_odom_to_initlaserOdometryHandler/velodyne_cloud_3laserCloudFullResHandler
- Post topics :
- The main thread mapping_process process
callback
- 3 Each laser callback puts the data into its own queue , There are mutually exclusive locks
- Laser odometer callback in addition to putting the data into the queue , It also sends data from the world coordinate system based on odometer drift
process
while 1 loop ,2s Do it once
- Data synchronization , Translates into pcl Format
- if 3 Point cloud data and When odometer data is not empty :
- If a certain kind of comparison
cornerLastBuf.front()Data early , be pop
- If a certain kind of comparison
- Take the first data of each data , should The time of these four kinds of data is consistent
- Sent by the same node , And the timestamp of the four kinds of data is the same
- take 3 Kind of point cloud data through pcl Convert to respective objects , And from the queue pop_front
- if
cornerLastBufWhen is not empty , pop Its data , Real time
- if 3 Point cloud data and When odometer data is not empty :
- Get the pose of the current frame in the world coordinate system transformAssociateToMap()
- L W T = O W T ∗ L O T { _L^WT=_O^WT*_L^OT} LWT=OWT∗LOT
- 1、 Optimize processing Find the current estimate lidar Which posture belongs to cube,I/J/K Corresponding cube The index of
- cube Central location index ,50m The resolution of the , Initial value [10,10,5]
- 2、 If the current frame lidar The posture corresponds to cube In the whole big cube The edge moves the index one unit towards the center
- width Direction :centerCubeI and The central position index changes accordingly
- centerCubeI stay width Small end of direction , Frame cube The pointer moves towards the center , namely i = i-1
- centerCubeI stay width The big end of the direction , Frame cube The pointer moves towards the center , namely i = i+1
- height Direction :centerCubeJ and The central position index changes accordingly
- centerCubeJ stay height Small end of direction , Frame cube The pointer moves towards the center , namely i = i-1
- centerCubeJ stay height The big end of the direction , Frame cube The pointer moves towards the center , namely i = i+1
- depth Direction :centerCubeK and The central position index changes accordingly
- centerCubeK stay depth Small end of direction , Frame cube The pointer moves towards the center , namely i = i-1
- centerCubeK stay depth The big end of the direction , Frame cube The pointer moves towards the center , namely i = i+1
- width Direction :centerCubeI and The central position index changes accordingly
- 3、 take centerCube The surrounding point cloud is composed Local map
- At present centerCube Of Expand in three directions 2 Each of them Valid array
- take centerCube Surrounding valid arrays Corner point 、 The point cloud of the plane point atlas wants to add up
- 4、 The current frame Corner point and Plane point feature Down sampling
- 5、 Get the pose matching the current frame with the map
- If meet The number of corner maps is greater than 10 And The number of points in the plane point map is greater than 50, To perform
- take Map point cloud Put in kdtree Easy to find
- Iterate twice solve :
- Traverse the current frame Corner features , structure ceres error model
- Turn the current corner to the world coordinate system , And look for 5 A recent point
- if 5 All points are less than 1m when
- obtain 5 The covariance of points , And calculate its eigenvalue and eigenvector
- If it is indeed a line feature , Build line feature model ( Note that the feature library sorts the feature values in ascending order )
- Traverse the current frame Pastry features , structure ceres error model
- Go to the world coordinate system , And look for 5 A recent point
- if 5 All points are less than 1m when , structure 5 Equation of points : ax+by+c=1
- If plane 5 The distance from each point to the plane is less than 0.2m, Prove that the plane holds , Build a face feature model
- Build a face feature model
- solve obtain Matching results
- Traverse the current frame Corner features , structure ceres error model
- 6、 After optimization , Update data
- Update the pose
- Update the corner in the current frame stay cube, And add the map
- Update the current frame Plane point stay cubeI, And put it into the map
- 7、 Voxel filter the map Downsampling
- 8、 Publish corresponding data
边栏推荐
- 体验一下阿里云文字识别OCR
- From a professional background, I can't get into a small company for interview
- 透过华为军团看科技之变(六):智慧公路
- PFC232-SOP8/14/16应广一级可带烧录程序编带
- wait_for_gap -- 从主库归档备库恢复归档
- Viewing technological changes through Huawei Corps (VI): smart highway
- Map集合详细讲解
- PMS150C应广单片机开发案例
- Outsourcing for five years, abandoned
- 2 juillet: BitTorrent est sorti; L'acquisition du système commercial linspire; Sony Deployment PlayStation now
猜你喜欢

透过华为军团看科技之变(六):智慧公路
![[target tracking] | data set summary](/img/2f/39a56d8cfb1638697735616b5e0412.png)
[target tracking] | data set summary

USB interface powered Bluetooth color light strip controller

Rk1126 platform project summary

体验一下阿里云文字识别OCR

Outsourcing for five years, abandoned

应广单片机开发 工规 PMC131 带AD芯片检测电池电压单片机SOP8/14

Develop a controller that prohibits deleting namespaces

【Zuul】com.netflix.zuul.exception.ZuulException: Hystrix Readed time out

Linux中,mysql设置job任务自动启动
随机推荐
嵌入式 ~ 介绍
Modbus协议通信异常
HDU - 1114 Piggy Bank (full backpack)
Modbus protocol communication exception
PFC232-SOP8/14/16应广一级可带烧录程序编带
Wechat applet - arrows floating up and down
阿里云子账户 - 权限策略 - 授权给某个账户某个 OSS Bucket 的完全控制权限
应广单片机开发调试应注意的问题
HDU - 1114 Piggy-Bank(完全背包)
SAP commerce Cloud Architecture Overview
Platform management background and merchant menu resource management: merchant role management design
Two pieces of nature a day! Duan Fengfeng, an alumnus of the University of science and technology of China, was the third Chinese winner of the belby medal
松翰SN8P2511 SOP8单片机 可代烧录 提供单片机方案开发 单片机解密
wait_for_gap -- 从主库归档备库恢复归档
一日2篇Nature!中科大校友段镶锋团队纳米材料新成果,曾是贝尔比奖章第三位华人得主...
使用Zadig从0到1搭建持续交付平台
外包干了五年,废了...
台风来袭,多景区暂时关闭,省文旅厅提醒注意安全!
Easyai notes - deep learning
Laravel文档阅读笔记-Custom Authentication Login And Registration Using Laravel 8
