这篇博客是记录一下自己遇到的问题。
相机是单目相机,激光雷达是机械式激光雷达。标定板是8×6,格宽112毫米。工控机x86架构,无CUDA,Ubuntu18.04,ROS Melodic。安装过程中需要科学上网。
一、准备好相机和激光雷达的ROS驱动
已有的相机驱动在工控机上编译出现了一些问题:
问题1:报错 undefined reference to `cv::*
解决:修改CMakeLists.txt
target_link_libraries(calibration_publisher
${catkin_LIBRARIES}
${OpenCV_LIBS}
)
问题2:报错Bad argument (Invalid pointer to file storage)
解决:修改CMakeLists.txt
find_package(OpenCV 版本号 REQUIRED) //pkg-config --modversion opencv 查看OpenCV版本
问题3:‘CV_*’ was not declared in this scope
解决:把 CV_ 前缀去掉,因为 OpenCV4以上的版本,把这个常量名称前面的 CV_ 给去掉了。
----------------------------------------------------------------------------------------------------------------------------
已有的相机驱动没有对图像去畸并发布,因此利用OpenCV的cv::undistort函数矫正图像。
参考文章:OpenCV: Camera calibration With OpenCV
相机内参数据存储在驱动ROS包的launch文件夹下
%YAML:1.0
---
CameraExtrinsicMat: !!opencv-matrix
rows: 4
cols: 4
dt: d
data: [ 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0.,
1. ]
CameraMat: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 1007.50155, 0. , 632.8408 ,
0. , 1002.83854, 349.68827,
0. , 0. , 1. ]
DistCoeff: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [-0.507477, 0.212361, 0.013718, -0.011629, 0.000000]
Projection: !!opencv-matrix
rows: 3
cols: 4
dt: d
data: [ 743.61829, 0. , 588.62008, 0. ,
0. , 931.75195, 355.15731, 0. ,
0. , 0. , 1. , 0. ]
ImageHeight: 720
ImageWidth: 1280
ImageSize: [1280, 720]
Reprojection Error: 0.0
DistModel: plumb_bob
rtsp: "rtsp://admin:admin123@192.168.3.210:554/h264/ch1/main/av_stream"
device_id: 0
二、 安装Autoware.ai
参考官方Wiki,用Docker安装,最方便。
第一步: 用自动安装脚本,安装Docker。
第二步: 用官方脚本,自动拉取Autoware。
问题:could not select device driver "" with capabilities: [[gpu]],usermod: UID '0' already exists
/*-c off :运行不带CUDA的版本
-s :跳过uid modification步骤 */
$ ./run.sh -c off -s
参考文章: Generic x86 Docker · autowarefoundation/autoware_ai_documentation Wiki · GitHub
三、 准备好标定软件
标定软件依赖 nlopt,安装参考:GitHub - stevengj/nlopt: library for nonlinear optimization, wrapping many algorithms for global and local, constrained or unconstrained, optimization
问题: nlopt::opt::get_errmsg() const': /usr/local/include/nlopt.hpp:516: undefined reference tonlopt_get_errmsg’
解决:以前用apt安装过nlopt,需要把apt安装的卸载
sudo apt remove libnlopt-dev
问题: CMakeLists.txt没定义Melodic版本导致编译不过
解决: CMakeLists.txt里所有 (indigo|jade|kinetic) 改为 (indigo|jade|kinetic|melodic)
四、 标定相机内参
第一步: 启动相机和激光雷达的ROS驱动
第二步: 启动相机标定软件
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.112 image:=/camera/image
第三步: 改变棋盘格在图像中的位置、大小、角度。等界面右侧的X、Y、Size、Skew的进度条都变成绿色后,点击右侧的CALIBRATE按键,等待标定结果计算完成。结果会显示在终端上。
第四步: 点击SAVE按键,保存标定结果
标定结果如下:
image_width: 1280
image_height: 720
camera_name: narrow_stereo
camera_matrix:
rows: 3
cols: 3
data: [ 1007.50155, 0. , 632.8408 ,
0. , 1002.83854, 349.68827,
0. , 0. , 1. ]
distortion_model: plumb_bob
distortion_coefficients:
rows: 1
cols: 5
data: [-0.507477, 0.212361, 0.013718, -0.011629, 0.000000]
rectification_matrix:
rows: 3
cols: 3
data: [ 1., 0., 0.,
0., 1., 0.,
0., 0., 1.]
projection_matrix:
rows: 3
cols: 4
data: [ 743.61829, 0. , 588.62008, 0. ,
0. , 931.75195, 355.15731, 0. ,
0. , 0. , 1. , 0. ]
五、 相机-激光雷达联合标定
第一步: 启动相机和激光雷达ROS驱动
第二步: 录制rosbag。
标定板要同时在相机和雷达的视野内,不停调整标定板的角度,录制的时候尽量录得长一点,这样的话后续可以有足够的时间调试。
参考别人的说法,录制的时候要手拿标定板,经过六个位置:
近处左、近处中、近处右
远处左、远处中、远处右
经过每个位置的时候,应该有五个动作:
平拿、左倾、右倾、上倾、下倾
录制结束后,关闭相机和激光雷达ROS驱动,播放rosbag
rosbag play 2023-02-06-14-11-11.bag --pause
参考:无人驾驶汽车系统入门(二十二)——使用Autoware实践激光雷达与摄像机组合标定_AdamShan的博客-优快云博客_autoware标定原理
第三步: 启动标定软件
rosrun calibration_camera_lidar calibration_toolkit
标定软件订阅的激光雷达点云的话题是 /points_raw
第四步: 播放 rosbag,当进行到合适位置角度时,暂停包, 点击MainWindow右上角”Grab”,生成下半部分的摄像机和激光雷达信息的一组数据,建议抓取20组数据。
注: 如果摁Grab后没反应,是因为软件没有识别到棋盘格。
第五步: 在右下图选择标定版所在的点云。
注:激光雷达点云窗口的操作方法
- 移动点云:上下左右方向键、PgUp、PgDn
- 旋转点云:a、d、w、s、q、e
- 切换模式:数字 1 和数字 2
- 视角缩放:减号缩小、加号放大
- 点云大小:o 键使用小点云、p 使用大点云
- 改变点云窗口背景颜色:b
因为点云是黑色的,所以先把背景颜色改成白色,方便观察。如果看不到点云可以摁”2“调整视角。
第六步: 点击右上角”Calibrate“,等待左侧相机外参矩阵计算完成后,点击”Project“进行验证, 左下方图像中会出现根据计算结果和激光雷达数据生成的图像对应位置,以红色散点表示。如果散点分布在标定板上,说明标定正确;如果散点不在标定板上,则对右下方激光图像重新点选。
第七步: 点击”Save“保存结果。
结果如下:
%YAML:1.0
---
CameraExtrinsicMat: !!opencv-matrix
rows: 4
cols: 4
dt: d
data: [ -6.6509416238362151e-02, 1.3199913382493766e-02,
9.9769848142528894e-01, 6.8346409603131542e-02,
-9.9760973802460917e-01, 1.7903454143900599e-02,
-6.6740369553880075e-02, -4.9583755059319737e-02,
-1.8743216108864091e-02, -9.9975258370079378e-01,
1.1977613847695578e-02, -1.2174364878299902e-01, 0., 0., 0., 1. ]
CameraMat: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 9.9868357534321535e+02, 0., 6.1304656309192160e+02, 0.,
9.9742355204236799e+02, 3.9721506187397307e+02, 0., 0., 1. ]
DistCoeff: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ 7.4253599884789731e-02, -5.7266121814878035e-01,
2.3726414468503909e-03, 2.6464864302885730e-03,
1.1595234975696214e+00 ]
ImageSize: [ 1280, 720 ]
ReprojectionError: 1.7367420059669290e+00
六、 查看融合效果
参考:使用Autoware标定工具包进行相机和激光雷达的联合标定_范猛男的博客-优快云博客_autoware联合标定
问题: Docker中的ROS和本地ROS通信