基于Autoware的二维激光雷达与相机的标定下,雷达图像显示不正确的问题处理

项目场景:

使用Autoware中的 Calibration Toolkit 进行二维激光雷达和相机的标定。目标是获取坐标系转换的外参矩阵,将相机的坐标系变换到雷达坐标系上。

实验设备

Sick Tim561 一个,realsense D435i 一个,设备摆放如下图所示
在这里插入图片描述

实验环境

Ubuntu18.04,ROS melodic
Calibration Toolkit
sick Tim561驱动


问题描述

问题一

雷达数据的显示不符合预期,整体的雷达数据在Calibration Toolkit 中的显示顺时针旋转了90度。
在这里插入图片描述

问题二

标定后的外参矩阵不符合预期,旋转矩阵数据存在问题。


原因分析:

原因一:传感器的坐标系定义

需要搞清楚realsense和sick雷达的坐标系是以何种形式的定义的,两者都采用右手坐标系

Realsense坐标系

根据Realsense ROS的官方文档中提到的 “All data published in our wrapper topics is optical data taken directly from our camera sensors” 。可知相机传感器发出的数据,是基于Optical坐标系。
也就是说标定过程中拍摄的标定板的位姿,是基于Optical坐标系下的坐标定义的。

在这里插入图片描述

Sick雷达坐标系

Sick 二维激光雷达本身并没有定义XYZ坐标系,而是采用的极坐标系。如下图所示,Sick的扫描角度范围为 − 45 < θ < 225 -45<\theta<225 45<θ<225 。雷达扫描到的一个物体采用角度 θ \theta θ和距离range 表示。

Sick激光雷达扫描角度
而XYZ坐标系是在Calibration Toolkit中人为定义的,源程序中将极坐标系,转换成了XY坐标系。具体如何转换的会在后面说明。

//selectionwidget.cpp:380
void PointsExtractor::updateLaserScan(sensor_msgs::LaserScanConstPtr lidarPoints)
{
    pointsptr=lidarPoints;
    int i,pointsnum=(pointsptr->angle_max-pointsptr->angle_min)/pointsptr->angle_increment+1;
    points.resize(pointsnum);
    for(i=0;i<pointsnum;i++)
    {
        float angle=pointsptr->angle_min+i*pointsptr->angle_increment;
        points[i]=QPointF(pointsptr->ranges[i]*cos(angle),pointsptr->ranges[i]*sin(angle)); //极坐标转换成XY坐标
    }
    drawPoints();
}

将坐标系总结画在下图中
在这里插入图片描述

原因二:Sick激光雷达传入的原始数据

激光雷达在ROS中的数据为Scan,数据格式如下所示。

# 测量的激光扫描角度,逆时针为正
# 设备坐标帧的0度面向前(沿着X轴方向)
Header header            # Header也是一个结构体,包含了seq,stamp,frame_id,其中seq指的是扫描顺序增加的id,stamp包含了开始扫描的时间和与开始扫描的时间差,frame_id是扫描的参考系名称.注意扫描是逆时针从正前方开始扫描的.
 
float32 angle_min        # 开始扫描的角度(角度)
float32 angle_max        # 结束扫描的角度(角度)
float32 angle_increment  # 每一次扫描增加的角度(角度)
 
float32 time_increment   # 测量的时间间隔(s)
float32 scan_time        # 扫描的时间间隔(s)
 
float32 range_min        # 距离最小值(m)
float32 range_max        # 距离最大值(m)
 
float32[] ranges         # 距离数组(长度360)(注意: 值 < range_min 或 > range_max 应当被丢弃)
float32[] intensities    # 与设备有关,强度数组(长度360)

所以Sick激光雷达将极坐标转换成XY坐标的时候,选取angle_min作为起始角度,每次遍历一帧中其他的点的时候就加一次angle_increment。再结合点的距离range,就可以获得在XY坐标系下的点。

    for(i=0;i<pointsnum;i++)
    {
        float angle=pointsptr->angle_min+i*pointsptr->angle_increment;
        points[i]=QPointF(pointsptr->ranges[i]*cos(angle),pointsptr->ranges[i]*sin(angle)); //极坐标转换成XY坐标
    }

这里有个坑,sick雷达传过来的数据中,angle_minangle_max并不是-45和225,利用rostopic查看数据。发现实际的angle_min是-2.35rad(-135度),angle_max是2.35rad(135度)。
在这里插入图片描述
通过下面的图可以发现,这样计算出来的点的坐标是有问题的。假定的坐标系应该是0°沿x轴正方向,90°沿y轴正方向(如下右图所示)
在这里插入图片描述


解决方案:

解决方法就很简单了,只要将原先的angle加上90度就可以实现所有点在XY坐标系下逆时针旋转90度。

//selectionwidget.cpp:387
points[i]=QPointF(pointsptr->ranges[i]*cos(angle + PI/2,pointsptr->ranges[i]*sin(angle + PI/2)); 

在这里插入图片描述

参考资料

1.【学习笔记】手把手教你使用Autoware标定SICK-2D激光雷达和相机
2. Mark一下~激光雷达点云投影到图像的方法(基于autoware的lidar_camera_calibration,外参不匹配的一些坑)

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值