|
本帖最后由 duanzhuohua 于 2024-5-23 12:17 编辑
激光雷达安装在本体上时,其相对于本体的位姿有时并不完全与说明书相同。因此标定激光雷达相对本体的方向对于机器人准确导航非常关键。
本实验的目的是获取机器人正前方激光雷达的射线编号。(本实验在Spark-T机器人上进行了测试,您也可以用于其它本体)。
实验场景如附图(凳子垂直于本体的X轴,这样本体正前方的激光射线距离最短)
源码:
- /**
- * 节点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;
- }
复制代码
|
|