文章目录
- 一 硬件参数
- 1.1 雷达参数
- 1.2 相机参数
- 二 相机雷达标定示例环境配置
- 2.1 网络设置
- 2.1.1 Windows采用静态IP和上位机软件与激光雷达链接
- 2.1.2 Ubuntu采用静态IP连接Avia
- 2.2 Docker配置
- 2.3 运行前设置
- 2.4 环境测试
- 2.5 POE口连接相机
- 2.6 远程显示可视化界面
- 三 相机标定
- 3.1 图片拍摄
- 3.2 参数设置
- 四 雷达数据采集
- 4.1 标定场景
- 4.2 雷达数据录制
- 五 理论知识
- 5.1 cmake基础知识
- 5.2 ROS系统基础学习
- 5.2.1 通讯形式
- 5.2.2 参数
- 5.2.3 ROS节点
- 5.3 相机标定
- 5.3.1 为什么要进行相机标定
- 5.3.2 畸变矫正
- 5.3.3 张正友标定法
- 人性化设置
- 官方文档资料
一 硬件参数
1.1 雷达参数
雷达使用Livox Aiva
激光雷达参数中的反射率是指目标物体表面反射激光信号的能力。它表示物体表面反射回激光雷达接收器的激光能量比例。激光雷达对于反射率小的物体有效量程更短。
当被测物体距离 Livox Avia 小于 1 m 时,Livox Avia 无法对其进行测量。此时,Livox Avia 将会输出遮挡预警,LivoxViewer 中相应的测距仪 SN 码将变换颜色,用户也可通过 SDK 得到预警数据包。
1.2 相机参数
相机使用水星二代 MERCURY2 工业相机,参数如链接所示。
二 相机雷达标定示例环境配置
使用Livox官方提供示例
2.1 网络设置
2.1.1 Windows采用静态IP和上位机软件与激光雷达链接
根据 Livox Avia 用户手册说明,所有的 Livox Avia 出厂默认为静态 IP , IP 地址为 192.168.1.1xx (xx为序列号最后两位数字),子网掩码为 255.255.255.0 ,默认网关为 192.168.1.1 。
需关闭Winows的防火墙,按照手册步骤配置即可,我手里的这台设备按照默认设置即可。
上位机软件搜到设备后,点击链接设备,打开眼睛图标展示设备数据,最后点击上方的播放摁钮即可在右侧可视化检测到的点云数据。
点击左侧的设备,可以查看设备的ip地址,我手里这台的IP地址是192.168.1.122
2.1.2 Ubuntu采用静态IP连接Avia
根据手册,需将Ubuntu设备改到和Avia同一频段,使用Ifconfig
查看本机的网口名称
更改本机Ip
sudo ifconfig enp1s0 192.168.1.50 netmask 255.255.255.0
2.2 Docker配置
由于给我发的这个服务器过去配置了ROS2的环境,环境变量和包和ROS1冲突,没办法按照教程进行配置,所以打算直接利用Docker加载一个Hub上配置好的环境。
-
挑选镜像
选中了这个镜像,上边已经装好了需要的SDK,和ROS driver。
-
加载镜像
由于服务器连不上docker hub的服务器,我这里用我的widows装了一个wsl:wsl --update
,装好后直接在Windows的命令行里通过Pull命令直接拉取就可以了,最后把散的镜像文件打包成一个压缩包传到服务器上docker save -o livox_image.tar eehantiming/livox:1.5
在服务器上使用以下命令加载镜像:
docker load -i /path/to/livox_image.tar
-
通过镜像来创建容器,我这里创建的容器要求挂载一个工作目录,退出保存数据的容器。配置容器时注意三个事情:
-e "DISPLAY=$DISPLAY"
当使用vscode远程连接服务器时,并不会设置$DISPLAY
这个环境变量,所以如果要设置可视化界面,需要通过远程桌面连接登录服务器,然后再来创建容器。--network=host
一定要设置容器的网络环境和host相同,服务器的以太网接口也要按照手册里配置好,这样才能够与激光雷达通讯,我在这里卡了一天,血泪的教训。- 创建时要在ws_liovx文件夹的上级目录。
docker run -it \--privileged \--network=host \-e "DISPLAY=$DISPLAY" \-e "QT_X11_NO_MITSHM=1" \-v "/tmp/.X11-unix:/tmp/.X11-unix:rw" \-v "$(pwd):/workspace:rw" \--name livox1.6\livox1.1
启动并进入容器
docker start -i livox
进入正在运行的容器
docker exec -it livox bash
- docker exec 在正在运行的容器中执行命令
- -it 以交互模式运行并分配一个伪终端
- livox 容器的名称
- bash 要在容器内运行的命令,这里是启动bash shell
-
编译
按照官方给的示例从SDK开始一步一步来即可,环境依赖按照可以跳过。
2.3 运行前设置
-
进入docker后,设置当前空间的环境变量,注意每开启一个新的终端环境,都要进行设置。
source devel/setup.bash
-
开启ROS的主节点
`roscore`
-
另开一个终端,执行其他。
2.4 环境测试
运行下述命令,无报错,显示可视化界面,界面中有雷达数据即配置成功。
//roslaunch [package_name] [node_name]
roslaunch livox_ros_driver livox_lidar_rviz.launch
2.5 POE口连接相机
接线:POE交换机用网线连接相机和服务器网口即可。POE口自带供电,不需要额外给相机供电了。
我安装了大恒提供的MVS软件控制相机,安装包在文章最开头的连接中。
踩的一个小坑:
- 打开MVS软件后可以看到相机,但无法连接,看到相机IP地址是192.168.1.111,ping不同。在ping的log中发现回拨的信息来自地址192.168.1.1,原来是之前调docker连接激光雷达时建立的网桥的问题,这个网桥也不用了,使用
docker network ls
查看所有Docker 网络,找到ID后,remove掉docker network rm 9a688ce16015
。可以ping通,也可以在MVS软件中就可以连接了。
2.6 远程显示可视化界面
每次运行时都要开软件,比较麻烦,暂时不搞了,以后有机会,或者读者想研究一下可以参考一下下面的文章。
https://zhuanlan.zhihu.com/p/648140981
三 相机标定
3.1 图片拍摄
拍了二十多张,站在距离摄像头两三米左右进行拍摄的。
按照官方例程中2.3那节的方法来计算参数,拍好照片后放置到指定目录下,同时通过下边这行命令读取当前文件夹下所有jpg的文件名并生成txt文档:
find . -type f -name "*.jpg" -exec basename {} \; > in.txt
3.2 参数设置
我使用的标定板正方形边长是58mm,行数为4,列数为6,需要在cameraCalib.launch文件下将对应的参数修改好。注意这里的行和列在openCV中是内角点的数量而不是方块的数量。
这里又踩了个小坑,由于标定代码里含有可视化文件,而远程连接调用可视化就会报错,所以如果要远程跑的话需要cameraCalib.cpp里的imshow
函数注释掉,接着运行:
roslaunch camera_lidar_calibration cameraCalib.launch
就可以进行标定了。
四 雷达数据采集
4.1 标定场景
采集的场景需要包含角点和直线,同时目标尽量距离激光雷达三米以上。
4.2 雷达数据录制
做好如下的文件夹lidar存放录制后的文件,pcdFiles存放pcd文件。
根据文档里边的要求,需要把msg的launch的rosbag_enable设为true,同时制定转发的格式为自定义格式,也就是要将xfer_format该为1,如下图所示:
录之前打开:
roslaunch livox_ros_driver livox_lidar_msg.launch
然后另起一个终端,进入docker后使用下述命令开始录制:
rosbag record /livox/lidar
录制好的bag文件会自动保存到运行这条命令的文件夹下面。接下来需要将bag文件转正pcd格式,要把bag放在lidar文件夹下,同时按照文件的数量命名0,1,2,3…,也要把launch中对应的bag数量变量改好,然后运行:
roslaunch camera_lidar_calibration pcdTransfer.launch
可视化pcd文件需要运行:
pcl_viewer -use_point_picking xx.pcd
就可以查看点云的数据了。
五 理论知识
5.1 cmake基础知识
首先,了解一下makefile,makefile就是一个叫makefile(也可以叫Makeflile)的文件,里面记录了一下类似bash脚本的命令,如下就是调用g++编译器来编译main.cpp文件生成名称为out的可执行文件。
这样,在命令行运行make命令后,会自动调用当前目录下的makefile文件,运行生成的可执行文件即相当于执行了cpp文件
Cmake类似于更完善的makefile,提供的各种选项更多
5.2 ROS系统基础学习
在配置好环境后,例程并没有讲如何让Liadar和服务器通信,这部分需要掌握ROS的基础知识,这里我根据需要什么学什么原则,只学习那些和该标定例程相关的ROS基础知识。
参考ROS官方教程:
https://wiki.ros.org/cn/ROS/Tutorials
ROS(Robot Operation System)旨在提高机器人研发中的软件复用率。
节点相当于一个独立的单元,例如一个激光雷达,一个摄像头,是可以独立运行,独立编码的。类似于windows中的一个可执行文件。节点和节点管理器之间进行松耦合的通信,每个节点的命名唯一。
ROSMater负责为节点提供命名和注册服务,节点间不知道互相存在,由ROS Master为两个节点建立通信
5.2.1 通讯形式
- 话题通讯
数据的管道定义为话题。话题是单向的通信,例如摄像头会不断的发布数据,订阅者会接受发布到的数据。
话题中的数据定义为消息。
- 服务通讯
5.2.2 参数
ROS Mater会维护一个全局的字典服务器,各个节点可以找Master去设置变量。Talker去找Master设置自己的相关参数,Listener找Master获取Talker的参数。
5.2.3 ROS节点
roscore
是你在运行所有ROS程序前首先要运行的命令
打开一个新终端,可以使用rosnode看看roscore运行时干了些什么…… 记得要保持以前的终端开着,比如打开一个新的标签页,或者最小化之前的窗口。
注意:
当打开一个新的终端时,环境将会重置,/.bashrc文件将会生效。如果你在运行rosnode等命令时出现一些问题,那么可能需要将一些环境设置文件添加到~/.bashrc或手动source一下。
rosnode显示当前正在运行的ROS节点信息。rosnode list命令会列出这些活动的节点:
$ rosnode list
你会看到:
/rosout
这表示当前只有一个节点在运行: rosout。因为这个节点用于收集和记录节点的调试输出,所以它总是在运行的。
在运行上边提到的点云可视化命令后看到:
有了livox雷达的发布节点,和可视化工具rviz的节点
roslaunch livox_ros_driver livox_lidar_rviz.launch bd_list:=“3JEDLC80018J22”
5.3 相机标定
我找到关于相机标定写的最好的文章:
https://zhuanlan.zhihu.com/p/94244568
相机成像过程中会涉及到多个坐标系的变化,首先物体在世界坐标系下有他的坐标,但我们是从摄像头来观察这个世界的,所以以摄像头为原点,向右为X轴正方向,向下为Y轴正方向,摄像头的光轴方向为Z轴,我们可以构建摄像头的相机坐标系。在世界坐标系的物体,通过刚体变换可以得到在相机坐标系下的坐标。
而在相机坐标系下,就是小孔成像模型了,物体发出的光源会被投影到图像坐标系,每个坐标点可以通过线性变换得到在图像上的坐标,计算时只涉及到相机的内参焦距 f f f。
在图像处理过程中,我们规定左上角为一张图像的坐标原点,这又涉及到将图像坐标系的原点(画面中间)转移到左上角和一个像素代表多少的实际物理距离。此次变换有四个内参:dx和dy表示感光芯片CMOS或CCD上像素的实际大小,是连接像素坐标系和真实尺寸坐标系的,u0,v0是图像平面中心
最终在像素平面上的坐标(u,v)可由下式计算得到:
在四个坐标系下的转换关系如下图总结:
θ \theta θ表示感光板的横边和纵边之间的角度(90°表示无误差)。
5.3.1 为什么要进行相机标定
为什么要进行相机标定呢?比如,当我们拿到一张图片,进行识别之后,得到的两部分之间的距离为多少多少像素,但是这多少多少像素究竟对应实际世界中的多少米呢?这就需要利用相机标定的结果来将像素坐标转换到物理坐标来计算距离(当然这里值得说明,仅仅利用单目相机标定的结果,是无法直接从像素坐标转化到物理坐标的,因为透视投影丢失了一个维度的坐标,所以测距其实需要双目相机)。
5.3.2 畸变矫正
另外,相机拍摄的图片还存在一定的畸变,畸变包括桶形畸变和枕形畸变。这部分我就不展开学习了。
畸变模型包括径向畸变和切向畸变。
相机标定的第二个目的就是获得相机的畸变参数,如 k 1 , k 2 , k 3 , p 1 , p 2 k_1,k_2,k_3,p_1,p_2 k1,k2,k3,p1,p2等,进而对拍摄的图片进行去畸变处理。
5.3.3 张正友标定法
相机的内参在不调整相机时是保持不变的,而外参对于同一张图片是相同的,所以如果我们希望求解相机的8个内参的话,我们只需要4个点就可以正定约束我们的方程(每个点提供两个约束),张正友标定法就是利用棋盘图像中的角点提供约束,对于角点来说,标定板上每一个格子的大小是已知的,我们可以计算得到每一个角点在世界坐标系下的物理坐标。
对于畸变参数的矫正类似。
具体数学推导懒得看。
人性化设置
VSCode配置SSH免密登录服务器
https://i007it.com/2022/07/14/VSCode%E8%BF%9C%E7%A8%8B%E8%BF%9E%E6%8E%A5%E6%9C%8D%E5%8A%A1%E5%99%A8-%E5%85%8D%E5%AF%86%E7%99%BB%E5%BD%95/
官方文档资料
Avia官网介绍:https://www.livoxtech.com/cn/avia
Avia激光雷达SDK:https://github.com/Livox-SDK/Livox-SDK/blob/master/README_CN.md
Livox驱动文档:https://github.com/Livox-SDK/livox_ros_driver?tab=readme-ov-file
相机雷达标定文档:https://github.com/Livox-SDK/livox_camera_lidar_calibration/blob/master/doc_resources/README_cn.md
相机控制软件:https://www.daheng-imaging.com/downloads/