标定方法:https://adamshan.blog.csdn.net/article/details/105736726 提及的cam_lidar_calibration包。
标定环境:雷神32线雷达,笔记本摄像头,使用简单的rosbag record -a -o 记录的bag
存在问题以及解决方案:
问题1:最开始使用的作者提供的雷达和图像数据包,标定成功后自己使用32线的雷神激光雷达和笔记本摄像头录制了一个雷达相机功能包,使用autoware发现自己录制的包存在时间不同步的问题,在cam_lidar_calibration里有时间同步函数,这要求两个话题的时间基本一致才能收集两者的话题等待两者的到达同一时间的时候进入回调函数。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLxkTN4MjNxMTM4EjNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
解决方案:分析图像帧数高于雷达帧数,所以在播放bag包的时候将图像的时间戳赋值给雷达达到基本的同步。
Python代码如下所示:
import rospy
import rosbag
import sys
from std_msgs.msg import Header
bag_name = 'leishen_cam_small_2021-06-17-18-33-24.bag'
out_bag_name = 'out_leishen_cam_small_2021-06-17-18-33-24.bag'
dst_dir = '/home/ubuntu/'
with rosbag.Bag(dst_dir+out_bag_name, 'w') as outbag:
new_stamp = Header()
new_stamp2 = Header()
for topic, msg, t in rosbag.Bag(dst_dir+bag_name).read_messages():
if topic == '/usb_cam/image_raw':
new_stamp.stamp = msg.header.stamp
outbag.write(topic, msg, new_stamp.stamp)
continue
elif topic == '/lslidar_point_cloud':
new_stamp2.stamp = msg.header.stamp
msg.header.stamp = new_stamp.stamp
outbag.write(topic, msg,new_stamp.stamp)
continue
print("finished")
经过这个代码的转换之后,就能通过message_filters的时间同步检测。
接下来会遇到如下提示
问题2 之前标定成功用的是velodyne雷达,这次我们使用的是雷神雷达,就会出现上述的消息不配的情况。
在检查发现两个的雷达数据格式并不一样。(消息的offset)
解决办法:查找雷神的驱动程序,将其定义的雷达消息格式复制到标定算法需要的雷达数据消息格式。
转换成:
struct PointXYZIR
{
PCL_ADD_POINT4D;/
uint8_t intensity;
uint8_t ring;
uint64_t timestamp;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // make sure our new allocators are aligned
}EIGEN_ALIGN16;
}
POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZIR,
(float, x, x)(float, y, y)(float, z, z)
(uint8_t, intensity, intensity)
(uint8_t, ring, ring)
(double, timestamp, timestamp))
编译后就能进行标定了
下面一点小心得:在做数据集的时候停顿个5秒,然后注意不要抖动,给采样留够时间。标定板的大小最好不要有太大的边框。背景选择平面较少区域。
这种就很容易雷达检测不全平面,影响算法效果。在标定过程中每次标定算法出错,就药把标定算法和rviz重启,特殊情况时平面检测成柱状就要连roscore全部关闭重开。
由于标定板制作的非常粗糙。只有如下效果,等待后续重新制作标定板和数据集时使用。
更新:在雷神雷达驱动关闭掉时间同步,这样雷达就会以ROS的时间为准
发现代码对一些雷达不适用,雷神雷达的ring没有按顺序排列,在下一篇中对代码进行修改