这个算法的标定板和之前使用的autoware等其他网上的方法不一样,需要特制的,板子的参数在ros的wiki里面作者有给出参数,我找了一家做木板的厂定制了一块,切掉了中间四个圆孔,然后四个正方形是自己后面一点点量出来再贴上Apriltag,这个木板是合成木,运输过来是容易有断层的,但是凑合着用了。板子的实物图和我最小标定系统如图所示。加工好以后四个角贴上的Apriltag样式需要和论文中给出的一样是不能换的。二维码我放百度网盘吧。
如上图可知我就随便找了个实验室能用罗技的720P USB相机,使用ros的usb_cam来启动相机,由于这个程序还需要相机的内参,所以我提前用ros自带的camera_calibration使用棋盘格标定板标定了相机的内参。
打开Debug的话是可以发布相机和雷达检测的结果的方便调试,我的代码是已经打开,需要关闭的话找到velo2cam_calibration/include/velo2cam.utils.h中第30行的
#define DEBUG 1
改为
#define DEBUG 0
改完直接重新编译。
打开一个终端,输入命令
source devel/setup.bash
roslaunch velo2cam_calibration mono_pattern.launch camera_name:=/camera image_topic:=image_raw frame_name:=camera_optical_link
成功的话会打开相机检测的画面,通过检测四个AprilTag,估计出四个圆心的位置。我已经打开了Debug这个画面会自动弹出的。
新打开一个终端窗口,输入指令( cloud_topic)写你的点云主题名称。
source devel/setup.bash
roslaunch velo2cam_calibration lidar_pattern.launch cloud_topic:=/sensing/lidar/pointcloud
终端会开始输出检测结果,如下图所示,可以打开rviz来查看检测。雷达检测圆洞的方法是检测断点,如果周围环境太复杂会影响检测结果,因为可以人为过滤一下。
再新开一个终端窗口运行:
rosrun rqt_reconfigure rqt_reconfigure
这是一个过滤器我们要把点云过滤一下,类似下图的效果图,在/lidar_pattern/zyx_filtered中只留下板子和透过圆洞打过去的点,在lidar_pattern/range_filtered_cloud中只留下板子,这样是检测效果最好的。
激光雷达透过圆心的激光束一定要至少3 ring,不然会检测不到圆心的。雷达这边需要时间慢慢来。过滤完之后,可以把检测结果在RVIZ中显示出来,效果如下,绿色的就是检测出来的圆心。
确保上面雷达和相机打开检测都没问题了,再新开一个窗口:
source devel/setup.bash
roslaunch velo2cam_calibration registration.launch sensor1_type:=mono sensor2_type:=lidar
我们用的是单目相机所以参数选择在mono如果双目的选择stereo。
一直输入Y,应该是有三次输入Y,迭代完成后会询问是否需要换一个姿态继续,就是把板子挪挪位置,可以斜起来等重复步骤2.3-2.5直到不想继续了,我做的时候按照作者提出的完成三个姿态。
在完成标定之后会立刻在终端显示标定结果,也就是一个tf,具体的还可以在velo2cam_calibration/launch/calibrated_tf.launch中查看,他给了三个坐标系之间的静态tf,lidar先到一个旋转了一下的相机坐标,旋转的相机坐标再到相机的光心坐标,但我们需要的是lidar到camera的。我写了一个程序用来订阅这个静态tf来转换得到外参矩阵。
roslaunch velo2cam_calibration calibration_tf.launch
roslaunch tf_matrix tf_listen.launch
在终端会打印出一个final就是lidar到相机的外参矩阵。
用points2image得到的结果
作者是在Gazebo7上面搭建的仿真环境,ros melodic的话是Gazebo9了需要调整一下API的函数才能编译成功。
编译的时候会有类似如下的错误:
这个就是Gazebo的版本冲突问题,翻阅github issue以及Gazebo的官方github代码一点点把参数改了。
最终得到的精度和Ground Truth相比观察平移矩阵x,y,z误差几乎在0.01m范围内,是可接受范围,欧拉角因为我是放平的旋转标定出来也几乎为0。