目录

  • 1 智能移动机器人-基础篇
    • 1.1 第一讲 坐标变换(5课时)
    • 1.2 第二讲 ROS基本概念(3课时)
      • 1.2.1 实训
    • 1.3 第三讲-编写简单的订阅者和发布者节点(4课时)
      • 1.3.1 实训
      • 1.3.2 实训2
    • 1.4 第四讲 ROS服务及编程(2课时)
    • 1.5 第五讲 ROS坐标变换工具TF(4课时))
    • 1.6 第六讲 ROS参数及应用(2课时))
    • 1.7 第七讲 运动学模型及航迹推算(4课时)
      • 1.7.1 实训1.7.1
    • 1.8 第八讲 URDF机器人建模及应用(4课时))
      • 1.8.1 实训1.8.1
    • 1.9 第九讲 QT-ROS交互界面应用开发(4课时)
  • 2 智能移动机器人-提高篇
    • 2.1 第一讲 栅格地图及应用(2课时)
    • 2.2 第二讲 局部路径规划及避障(6课时)
    • 2.3 第三讲 运动学模型的概率表示(2课时)
    • 2.4 spark实验5-激光雷达信息处理-标定
    • 2.5 第四讲 激光雷达及其测量模型(4课时)
    • 2.6 第五讲 蒙特卡洛定位(MCL)(4课时)
    • 2.7 第六讲 并发定位与建图(SLAM)(4课时)
    • 2.8 第七讲 自主导航(6课时)
    • 2.9 第八讲 Librviz可视化应用开发(4课时)(4课时)
  • 3 实训篇-SparkT移动机器人(室内)
    • 3.1 SparkT移动机器人介绍
    • 3.2 演示视频
    • 3.3 相关工具及资料下载
    • 3.4 spark实验1-控制spark移动
    • 3.5 spark实验2-编写节点控制spark移动
      • 3.5.1 python版本
    • 3.6 spark实验3-并发定位与建图
    • 3.7 spark实验4-机器人定位与导航
    • 3.8 spark实验6-基于激光雷达的行人检测与跟踪
    • 3.9 spark实验7-机械臂抓取
    • 3.10 2023年夺宝奇兵大赛培训资料
    • 3.11 2024年夺宝奇兵半自动赛培训
      • 3.11.1 半自动赛程序设计方法2024年7月3日
    • 3.12 2024年夺宝奇兵自动任务赛培训
      • 3.12.1 代码框架(noetic版本)
      • 3.12.2 代码框架(kinetic版本)
      • 3.12.3 自动赛讲解视频2024年6月29日
      • 3.12.4 ROS下QT界面开发2024年6月30日
      • 3.12.5 目标识别与机械臂抓取7月1日
      • 3.12.6 自动赛思路讲解(2024,.7.3)结课
      • 3.12.7 基于大模型的辅助开发(python)
        • 3.12.7.1 案例1:激光雷达数据订阅与发布
        • 3.12.7.2 案例2:激光雷达与地图匹配程度计算
        • 3.12.7.3 案例3:基于Web的机器人远程控制
        • 3.12.7.4 案例4:ROS的QT界面应用开发
        • 3.12.7.5 案例5:ROS下语音识别及QT界面
        • 3.12.7.6 案例6:从摄像头获取图像数据并进行二维码识别
        • 3.12.7.7 案例7:Gazebo仿真
        • 3.12.7.8 案例8:基于RGBD的行人识别与跟踪
    • 3.13 spark实验-基于teb-local-planner的导航
    • 3.14 Spark实验-利用rf2o提高定位精度
  • 4 室外自主导航车(AGV)-实训篇
    • 4.1 AGV本体介绍
    • 4.2 实训项目1-AGV建模(URDF)
    • 4.3 实训项目2-AGV运动学模型及航迹推算
    • 4.4 实训项目3-AGV运动控制
    • 4.5 实训项目4-基于GPS的点对点导航
    • 4.6 实训项目5-基于GPS的循迹
    • 4.7 实训项目6-基于三维激光雷达(点云)的障碍物检测与避障
    • 4.8 实训项目7-基于深度相机(RGBD)的目标识别与跟踪
  • 5 智能机器人技术实践上课录屏
    • 5.1 实训项目1-2024年9月3日
spark实验5-激光雷达信息处理-标定


1、二维激光雷达传感器

测距原理:三角测距(rplidar A1)、TOF(飞行时间)测距(rplidar C1)

https://bucket-download.slamtec.com/9049dfabcba70679557103820a8b6e1dfe938f27/SLAMTEC_rplidar_datasheet_C1_v1.1_cn.pdf


1、二维(单线)激光雷达数据格式

在ROS中,二维激光雷达消息格式为sensor_msgs/LaserScan,可以通过指令rosmsg show sensor_msgs/LaserScan 来显示,如下

[sensor_msgs/LaserScan]:
std_msgs/Header header
 uint32 seq
 time stamp
 string frame_id
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities


其中,angle_min为最小角度,
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities

一次典型的二维激光扫描:


其中红色点为激光雷达感知到的环境数据,坐标系为激光雷达坐标系。

对应的数据通过指令rostopic echo -n 1 /scan显示如下

header: 
 seq: 169388
 stamp:
   secs: 1710639412
   nsecs: 218304993
 frame_id: "lidar_link"
angle_min: 0.0
angle_max: 6.26573181152
angle_increment: 0.0174532923847
time_increment: 2.3761715795e-07
scan_time: 0.000186054225196
range_min: 0.15000000596
range_max: 5.0
ranges: [4.007999897003174, 3.990000009536743, 4.070000171661377, 4.214000225067139, 4.363999843597412, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 2.0139999389648438, 2.0409998893737793, 2.0179998874664307, 1.1430000066757202, 1.149999976158142, 0.9399999976158142, 0.843999981880188, 0.7760000228881836, inf, inf, inf, 0.6399999856948853, 0.6430000066757202, 0.6549999713897705, 0.6549999713897705, inf, inf, inf, inf, inf, 0.6890000104904175, 0.6919999718666077, 0.6959999799728394, 0.699999988079071, 0.7049999833106995, 0.7110000252723694, 0.7160000205039978, 0.722000002861023, 0.7329999804496765, 0.7450000047683716, 0.7599999904632568, 0.7730000019073486, 0.7730000019073486, 0.7450000047683716, 0.7609999775886536, 0.7749999761581421, 0.8040000200271606, 0.8040000200271606, 0.8149999976158142, 0.8309999704360962, 0.843999981880188, 0.8560000061988831, 0.8669999837875366, 0.8820000290870667, 0.8939999938011169, 0.9160000085830688, 0.9330000281333923, 0.9490000009536743, 0.9660000205039978, 0.9850000143051147, 1.0130000114440918, 1.034999966621399, 1.059000015258789, 1.1059999465942383, inf, inf, 1.1649999618530273, 1.2029999494552612, 1.2350000143051147, 1.2690000534057617, 1.3049999475479126, 1.3569999933242798, 1.4559999704360962, 1.468999981880188, 1.559000015258789, 1.6160000562667847, 1.6640000343322754, inf, inf, inf, inf, 2.177999973297119, 2.2799999713897705, 2.5199999809265137, 2.194000005722046, 2.8519999980926514, 3.947000026702881, 3.938999891281128, 3.930999994277954, 3.9260001182556152, 3.921999931335449, 3.884999990463257, 3.88100004196167, 4.01200008392334, 3.871999979019165, 3.868000030517578, 3.868000030517578, 3.871999979019165, 3.868000030517578, 3.871999979019165, 3.868000030517578, 3.871999979019165, 3.875999927520752, 3.875999927520752, 3.88100004196167, 3.884999990463257, 3.8889999389648438, 3.8929998874664307, 3.930999994277954, 3.9690001010894775, 3.9820001125335693, 3.999000072479248, 3.999000072479248, 4.007999897003174, 4.015999794006348, 4.019999980926514, 4.107999801635742, 4.125999927520752, 4.078999996185303, 4.146999835968018, 4.146999835968018, 4.173999786376953, inf, 3.812000036239624, 3.753000020980835, 3.756999969482422, 3.756999969482422, 3.753000020980835, 3.753000020980835, 3.75, 3.7809998989105225, 4.070000171661377, 3.9600000381469727, 3.828000068664551, 3.7839999198913574, 3.686000108718872, 3.624000072479248, 2.9739999771118164, inf, inf, 2.765000104904175, 2.677999973297119, 2.627000093460083, 2.5950000286102295, 2.565999984741211, 2.509999990463257, 2.499000072479248, 2.4539999961853027, 2.427999973297119, 2.4030001163482666, 2.378999948501587, 2.430000066757202, 2.4839999675750732, 2.5429999828338623, 2.7119998931884766, 2.677999973297119, 2.628000020980835, 2.5999999046325684, 2.575000047683716, 2.563999891281128, 2.5390000343322754, inf, 1.6139999628067017, 1.6030000448226929, 1.590999960899353, 1.5809999704360962, 1.5709999799728394, 1.5579999685287476, 1.5440000295639038, 1.5390000343322754, 1.5299999713897705, 1.5219999551773071, 1.5169999599456787, 1.5089999437332153, 1.5010000467300415, 1.49399995803833, 1.4900000095367432, 1.4889999628067017, 1.4819999933242798, 1.4759999513626099, 1.475000023841858, 1.4769999980926514, 1.503999948501587, inf, 1.4329999685287476, 1.4579999446868896, 1.4630000591278076, 1.4630000591278076, 1.4630000591278076, 1.465000033378601, 1.4630000591278076, 1.4639999866485596, 1.4700000286102295, 1.4709999561309814, 1.4730000495910645, 2.2639999389648438, 2.2660000324249268, 2.2690000534057617, inf, inf, inf, 2.309000015258789, 2.313999891281128, 2.319999933242798, 2.3489999771118164, 2.3559999465942383, 2.374000072479248, 2.384000062942505, 2.390000104904175, 2.421999931335449, 2.430000066757202, 2.438999891281128, 2.4769999980926514, 2.486999988555908, 2.510999917984009, 2.5339999198913574, 2.559999942779541, 2.571000099182129, 2.617000102996826, 2.630000114440918, 2.674999952316284, 2.687999963760376, 2.7179999351501465, 2.755000114440918, 2.7909998893737793, 2.821000099182129, 2.8580000400543213, 2.9130001068115234, 2.936000108718872, 3.010999917984009, 3.0739998817443848, 3.0950000286102295, 3.1640000343322754, 3.2109999656677246, 3.259999990463257, 3.325000047683716, 3.4049999713897705, 3.4860000610351562, 3.5190000534057617, 3.6059999465942383, 3.6530001163482666, 3.808000087738037, inf, 4.007999897003174, 4.01200008392334, 4.133999824523926, 4.2829999923706055, 4.36899995803833, 4.515999794006348, 4.624000072479248, 3.4140000343322754, inf, inf, inf, inf, 2.694000005722046, inf, inf, inf, inf, inf, 2.5409998893737793, 2.5409998893737793, 2.5390000343322754, 2.5390000343322754, 2.5220000743865967, 2.5360000133514404, 2.5220000743865967, 2.5220000743865967, inf, inf, 2.5160000324249268, inf, 4.01200008392334, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, 3.88100004196167, 3.571000099182129, 3.2799999713897705, 3.0789999961853027, 2.756999969482422, 2.507999897003174, 2.371000051498413, 2.236999988555908, 2.11899995803833, 2.0179998874664307, 1.8600000143051147, 1.7640000581741333, 1.7680000066757202, 1.7999999523162842, 1.812999963760376, 1.8350000381469727, inf, inf, inf, 1.847000002861023, 1.8890000581741333, 1.9110000133514404, 1.9390000104904175, 1.972000002861023, 2.0220000743865967, 1.9570000171661377, 2.046999931335449, 2.118000030517578, 3.563999891281128, 3.4560000896453857, 1.86899995803833, 3.325000047683716, inf, inf, inf, inf, 3.010999917984009, 2.9719998836517334, 2.8949999809265137, inf, 2.821000099182129, 2.7839999198913574, 2.749000072479248, 2.7019999027252197, 2.7119998931884766, 2.7780001163482666, 2.8429999351501465, 2.9130001068115234, 2.9670000076293945, 3.0409998893737793, 4.204999923706055, 4.146999835968018, 4.083000183105469, 4.083000183105469, 4.065999984741211]
intensities: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]


激光雷达数据读取方法,核心代码:

void show(double mind,double maxd,const sensor_msgs::LaserScan::ConstPtr& scan_msg)
//显示scan_msg的信息,以及距离在mind-maxd之间的测量
{
 
 ROS_INFO("range_min %f", scan_msg->range_min);  
 ROS_INFO("range_max %f", scan_msg->range_max);
 ROS_INFO("angle_min %f", scan_msg->angle_min);  
 ROS_INFO("angle_max %f", scan_msg->angle_max);
 ROS_INFO("angle_increment %f", scan_msg->angle_increment);
 ROS_INFO("scan_msg->ranges.size()  %d", scan_msg->ranges.size() );
 const std::size_t num_measurements = std::ceil(
     (scan_msg->angle_max - scan_msg->angle_min) / scan_msg->angle_increment) +1;
 ROS_INFO("ceil((scan_msg->angle_max - scan_msg->angle_min)/scan_msg->angle_increment)  %d", num_measurements );

 ROS_INFO("Ranges between %f to %f", mind, maxd);  
 double minmin=maxd;
 int mini;
 double bearingi;
 int count=0;

 for (unsigned int i = 0; i < scan_msg->ranges.size(); i++)
 {
  bearingi=scan_msg->angle_min+scan_msg->angle_increment*i;
  if (scan_msg->ranges[i]>=mind && scan_msg->ranges[i]<=maxd)
     {
       count++;
       ROS_INFO("index:%d angle:%f dist:%f x:%f y:%f",
            i,bearingi,scan_msg->ranges[i],
            scan_msg->ranges[i]*cos(bearingi),scan_msg->ranges[i]*sin(bearingi));
       //该范围内的最小距离值及其编号(方向),场景:在机器人正前方放置一块木板,
       //该木板与激光内的扫描面相交的部分距离范围为mind~maxd(环境中其它目标在此之外)
       if (minmin>scan_msg->ranges[i]){
          minmin=scan_msg->ranges[i];
          mini=i;
        }
       
     }  
 }
 if (count>0){
   bearingi=scan_msg->angle_min+scan_msg->angle_increment*mini;
   ROS_INFO("rightahead_index:%d angle:%f dist:%f x:%f y:%f",
            mini,bearingi,scan_msg->ranges[mini],
            scan_msg->ranges[mini]*cos(bearingi),
            scan_msg->ranges[mini]*sin(bearingi));
 } else ROS_INFO("nonething found!");
 

}





2、激光雷达标定:编写节点,对激光雷达信息进行处理,本实验主要对激光雷达进行标定。就是获得激光雷达相对于机器人的位姿。具体获得机器人正前方的激光雷达射线编号。

前提:要求已经完成了实验2(spark机器人控制(2)--编写节点完成对机器人的控制)。


步骤1:


新建一个终端,进入simple_nodes包(注,此处改为自己所建立的包)


$roscd simple_nodes


注:执行上述指令后,当前目录应该为~/ros_tut/src/simple_nodes$,在此基础上继续执行以下指令


$cd src


步骤2:


将laserscan_calib01.cpp下载(拷贝至该当前目录,拷贝的方法,通过scp命令:台式机与spark联通后,cmd启动台式机终端,转到laserscan_calib01.cpp文件所在的目录,通过下面的指令进行复制:


scp laserscan_calib01.cpp spark@10.42.0.1:~/ros_tut/src/simple_nodes/src   


按提示输入yes,密码输入spark  )


拷贝成功后,在spark机器人端通过ls命令可以看到laserscan_calib01.cpp(源代码如下,也可以直接拷贝)

/**
* 节点laserscan_calib01
* 使用LaserScan消息基础示例
* 从scan话题订阅sensor_msgs/LaserScan消息
* 显示第一次订阅的消息
* 显示一定距离范围内的消息(用于激光雷达相对与机器人本体的方位标定)
* 例如,让机器人在空扩的地方,正面向前方的柱子,距离1m~2m的范围的扫描点即为该柱子  

* 开发者:段琢华,duanzhuohua@163.com 2021-5-10
*/


#include "ros/ros.h"
#include "sensor_msgs/LaserScan.h"
//申明sensor_msgs::LaserScan消息类型
#include <cmath>
#include <vector>

int first=1;//只对第一次获得的数据进行处理
double min_dist,max_dist;

void show(double mind,double maxd,const sensor_msgs::LaserScan::ConstPtr& scan_msg)
//显示scan_msg的信息,以及距离在mind-maxd之间的测量
{
 
 ROS_INFO("range_min %f", scan_msg->range_min);  
 ROS_INFO("range_max %f", scan_msg->range_max);
 ROS_INFO("angle_min %f", scan_msg->angle_min);  
 ROS_INFO("angle_max %f", scan_msg->angle_max);
 ROS_INFO("angle_increment %f", scan_msg->angle_increment);
 ROS_INFO("scan_msg->ranges.size()  %d", scan_msg->ranges.size() );
 const std::size_t num_measurements = std::ceil(
     (scan_msg->angle_max - scan_msg->angle_min) / scan_msg->angle_increment) +1;
 ROS_INFO("ceil((scan_msg->angle_max - scan_msg->angle_min)/scan_msg->angle_increment)  %d", num_measurements );

 ROS_INFO("Ranges between %f to %f", mind, maxd);  
 double minmin=maxd;
 int mini;
 double bearingi;
 int count=0;

 for (unsigned int i = 0; i < scan_msg->ranges.size(); i++)
 {
  bearingi=scan_msg->angle_min+scan_msg->angle_increment*i;
  if (scan_msg->ranges[i]>=mind && scan_msg->ranges[i]<=maxd)
     {
       count++;
       ROS_INFO("index:%d angle:%f dist:%f x:%f y:%f",
            i,bearingi,scan_msg->ranges[i],
            scan_msg->ranges[i]*cos(bearingi),scan_msg->ranges[i]*sin(bearingi));
       //该范围内的最小距离值及其编号(方向),场景:在机器人正前方放置一块木板,
       //该木板与激光内的扫描面相交的部分距离范围为mind~maxd(环境中其它目标在此之外)
       if (minmin>scan_msg->ranges[i]){
          minmin=scan_msg->ranges[i];
          mini=i;
        }
       
     }  
 }
 if (count>0){
   bearingi=scan_msg->angle_min+scan_msg->angle_increment*mini;
   ROS_INFO("rightahead_index:%d angle:%f dist:%f x:%f y:%f",
            mini,bearingi,scan_msg->ranges[mini],
            scan_msg->ranges[mini]*cos(bearingi),
            scan_msg->ranges[mini]*sin(bearingi));
 } else ROS_INFO("nonething found!");
 

}


void scanCallback(const sensor_msgs::LaserScan::ConstPtr& scan_msg)
{
 //回调函数,接收sensor_msgs::LaserScan消息
 std::vector<double> scan_ranges_doubles(scan_msg->ranges.begin(), scan_msg->ranges.end());

 if (!first) return;
 first=0;
 show(min_dist,max_dist,scan_msg);
 
}

int main(int argc, char **argv)
{
 ros::init(argc, argv, "laserscan_calib01");
 if (argc <= 2)
 {//命令行中处理命令本身,还要两个额外的参数min_dist,max_dist
  //如果参数不够,提示使用方法并退出
   ROS_INFO("usage: %s min_dist,max_dist",argv[0]);
   return 1;
 }
 
 min_dist = atof(argv[1]);//获取请求消息的第一个参数,atof函数把字符串转换为浮点数
 max_dist = atof(argv[2]);//获取请求消息的第二个参数
 ros::NodeHandle n;

 ros::Subscriber sub = n.subscribe("scan", 10, scanCallback);//初始化订阅者对象  
 
 ros::Rate loop_rate(10);
 //设置发布频率
 while (ros::ok())
 {    
   
   ros::spinOnce();
   loop_rate.sleep();
 }
 
 return 0;
}


$cd ..


$gedit  CMakeLists.txt


将下面的两行加入到文件末尾,然后保存文件并退出编辑


add_executable(laserscan_calib01 src/laserscan_calib01.cpp)
target_link_libraries(laserscan_calib01 ${catkin_LIBRARIES})


$cd ~/ros_tut


$catkin_make


构建成功后继续后面的步骤,否则根据提示信息修改源程序,再通过步骤1来构建。


步骤2:测试节点


新开一个终端,启动机器人建图节点


$roslaunch spark_slam 2d_slam.launch


确保机器人在一个比较空阔的地方,周围1米内没有障碍。


然后将一个长方形障碍垂直于机器人X轴,放置于机器人前方(约0.5m处),另开一个终端执行下面指令


$rosrun simple_nodes laserscan_calib01 0.2 1


记录获得的结果。据此分析机器人正前方激光雷达射线的编号。

实验场景:


在spark-9ca7设备上实验结果如下:

[ INFO] [1712624673.114900911]: rightahead_index:156 angle:-0.411295 dist:0.393000 x:0.360225 y:-0.157120

即机器人正前方的射线编号为156号(在ranges数组中的下标)

3、根据标定结果设置机器人模型参数

激光雷达数据如下:

$ rostopic echo /scan -n 1

header: 

  seq: 58090

  stamp: 

    secs: 1712626839

    nsecs:  77204753

  frame_id: "lidar_link"

angle_min: -3.14159274101

angle_max: 3.14159274101

angle_increment: 0.0175019092858

time_increment: 1.39922036624e-07

scan_time: 0.000184417251148

range_min: 0.15000000596

range_max: 5.0


根据标定结果以及上述信息,计算获得激光雷达相对于本体的旋转角度(绕z轴):


156*0.017502= 2.73

3.14-2.73=0.41

在模型文件

~/spark/src/spark/spark_description/urdf/sensors/spark_lidar.urdf

中设置该值如下:


<!-- lidar -->

<robot name="lidar_frame">

<link name="lidar_link"/>

  <joint name="lidar_joint" type="fixed">

      <origin xyz="0 0 0.08" rpy="0 0 0.41" />

      <parent link="base_link"/>

      <child link="lidar_link"/>

  </joint>


</robot>

修改了模型参数后,重新启动SLAM(roslaunch spark_slam 2d_slam.launch),结果如下

其中,坐标系为本体坐标系,可以看到,前方的凳子于本体的X轴垂直,如实际的场景一致。