返回列表 发布新帖
查看: 891|回复: 1

激光雷达标定及源码分享

2

主题

0

回帖

20

积分

新手上路

积分
20
发表于 2024-5-23 09:08:12 | 查看全部 |阅读模式
本帖最后由 duanzhuohua 于 2024-5-23 12:17 编辑

激光雷达安装在本体上时,其相对于本体的位姿有时并不完全与说明书相同。因此标定激光雷达相对本体的方向对于机器人准确导航非常关键。

本实验的目的是获取机器人正前方激光雷达的射线编号。(本实验在Spark-T机器人上进行了测试,您也可以用于其它本体)。
实验场景如附图(凳子垂直于本体的X轴,这样本体正前方的激光射线距离最短)
源码:
  1. /**
  2. * 节点laserscan_calib01
  3. * 使用LaserScan消息基础示例
  4. * 从scan话题订阅sensor_msgs/LaserScan消息
  5. * 显示第一次订阅的消息
  6. * 显示一定距离范围内的消息(用于激光雷达相对与机器人本体的方位标定)
  7. * 例如,让机器人在空扩的地方,正面向前方的柱子,距离1m~2m的范围的扫描点即为该柱子  

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


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

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

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

  30.   ROS_INFO("Ranges between %f to %f", mind, maxd);  
  31.   double minmin=maxd;
  32.   int mini;
  33.   double bearingi;
  34.   int count=0;

  35.   for (unsigned int i = 0; i < scan_msg->ranges.size(); i++)
  36.   {
  37.    bearingi=scan_msg->angle_min+scan_msg->angle_increment*i;
  38.    if (scan_msg->ranges[i]>=mind && scan_msg->ranges[i]<=maxd)
  39.       {
  40.         count++;
  41.         ROS_INFO("index:%d angle:%f dist:%f x:%f y:%f",
  42.              i,bearingi,scan_msg->ranges[i],
  43.              scan_msg->ranges[i]*cos(bearingi),scan_msg->ranges[i]*sin(bearingi));
  44.         //该范围内的最小距离值及其编号(方向),场景:在机器人正前方放置一块木板,
  45.         //该木板与激光内的扫描面相交的部分距离范围为mind~maxd(环境中其它目标在此之外)
  46.         if (minmin>scan_msg->ranges[i]){
  47.            minmin=scan_msg->ranges[i];
  48.            mini=i;
  49.          }
  50.         
  51.       }   
  52.   }
  53.   if (count>0){
  54.     bearingi=scan_msg->angle_min+scan_msg->angle_increment*mini;
  55.     ROS_INFO("rightahead_index:%d angle:%f dist:%f x:%f y:%f",
  56.              mini,bearingi,scan_msg->ranges[mini],
  57.              scan_msg->ranges[mini]*cos(bearingi),
  58.              scan_msg->ranges[mini]*sin(bearingi));
  59.   } else ROS_INFO("nonething found!");
  60.   

  61. }


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

  66.   if (!first) return;
  67.   first=0;
  68.   show(min_dist,max_dist,scan_msg);
  69.   
  70. }

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

  84.   ros::Subscriber sub = n.subscribe("scan", 10, scanCallback);//初始化订阅者对象   
  85.    
  86.   ros::Rate loop_rate(10);
  87.   //设置发布频率
  88.   while (ros::ok())
  89.   {   
  90.    
  91.     ros::spinOnce();
  92.     loop_rate.sleep();
  93.   }
  94.   
  95.   return 0;
  96. }
复制代码



回复

举报

2

主题

11

回帖

85

积分

管理员

积分
85
发表于 2024-5-23 16:58:45 | 查看全部
沙发!
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关灯 在本版发帖
扫一扫添加微信客服
返回顶部
快速回复 返回顶部 返回列表