首页IT科技相机的测距仪是干什么的(ZED2跑ORB-SLAM3+双目相机、IMU联合标定+显卡驱动与cuda/cudnn安装)

相机的测距仪是干什么的(ZED2跑ORB-SLAM3+双目相机、IMU联合标定+显卡驱动与cuda/cudnn安装)

时间2025-06-17 12:49:49分类IT科技浏览8430
导读:一、引言 同样是项目需求,需要利用视觉惯性导航做一些开发,所以第一步先做些算法的测试–仿真与实物测验,通过仿真的测试结果,最终是决定使用ORB-SLAM3来完成任务,当然了,Vins-fusion作为备用方案。 系统版本与ROS版本:Ubuntu18.04、Melodic...

一              、引言

同样是项目需求              ,需要利用视觉惯性导航做一些开发                       ,所以第一步先做些算法的测试–仿真与实物测验        ,通过仿真的测试结果              ,最终是决定使用ORB-SLAM3来完成任务                      ,当然了        ,Vins-fusion作为备用方案              。 系统版本与ROS版本:Ubuntu18.04                       、Melodic 内容:(1)zed2的SDK以及开发例程安装(2)cuda与cudnn安装(3)双目相机        、IMU标定以及联合标定(4)算法运行结果展示(5)分享一些遇到的问题以及解决方式 写此文一方面是为了阶段性总结       ,一方面是还有一些问题希望能有人一起讨论下                      ,也算是把网上所有相关博客都看了一遍               ,提炼出来了精华部分做此总结       ,再次感谢各位前辈的肩膀~~ 本文属于综合性博客                      ,涉及面比较广               ,希望给大家更全面的帮助~~(手动狗头) 之前的博客好像有些烂尾,也没办法                      ,真就是四处炼丹                       。        。              。                      。 至于可能编译过程会出现一些问题                       ,基本上就是缺少依赖包,注意看error信息              ,还有可能是Cmakelist文件的问题                       ,根据报错信息做相应修改就行        ,学会自己百度              ,之后熟悉了就能很快定位问题

二              、安装显卡驱动                      、cuda        、cudnn

正常做linux系统下的开发都缺少不了三件套:显卡驱动       、cuda                      、cudnn

2.1 安装显卡驱动

这部分可以参考我之前的博客

2.2 安装cuda和cudnn

这里很容易                      ,总结起来就是去官网下载文件        ,然后配置下bashrc的环境变量

首先是cuda,点击进入官网后       ,选择cuda11.0或者cuda11.1或者其他版本的                      ,之后下载会得到一个.run文件               ,跟下图一致        。

执行以下命令执行安装(文件名记得改成自己的) sudo sh cuda_10.2.89_440.33.01_linux.run

之后其他地方不是accept就回车就行       ,只是到了下图的地方配置要注意                      ,取消Driver的选择(按回车可以取消)               ,取消驱动下载选项后可以选择Install,静候结果就可以了

完成之后进入bashrc添加环境变量 sudo gedit ~/.bashrc

在文件末尾添加:(同样记得改成自己的版本号)

export CUDA_HOME=/usr/local/cuda export PATH=$PATH:$CUDA_HOME/bin export LD_LIBRARY_PATH=/usr/local/cuda-11.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

最后测试是否安装成功

cd /usr/local/cuda/samples/1_Utilities/deviceQuery sudo make ./deviceQuery

输出为Pass即安装成功                      ,否则就重新安装一次

如果想要安装多个版本的cuda进行切换的话                       ,第一个地方要把环境变量改了,第二个地方如下图我安装了两个cuda              ,cuda-11.0和cuda11.1                       ,还有一个cuda文件是软连接        ,切换时候需要将这个软链接删除              ,重新指向cuda-11.0或cuda11.1文件夹即可                      ,第三个地方就是需要重新安装下cudnn文件        ,具体如果还是不明白       ,评论区见~~

接下来安装cudnn                      ,同样需要进入官网下载文件               ,这里下载的文件需要和安装的cuda版本对应起来       , 最后的操作也很简单                      ,只要把文件复制到原来安装的cuda的对应位置即可       。 sudo cp cuda/include/cudnn.h /usr/local/cuda/include/ sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64/

之后修改访问权限:

sudo chmod a+r /usr/local/cuda/include/cudnn.h sudo chmod a+r /usr/local/cuda/lib64/libcudnn*

完事儿~~最麻烦的是下载文件了               ,其他的我觉得操作挺easy的,熟练之后就好了

三               、安装ZED2的SDK以及Python与ROS的API

总之都是从官网上扒下来的                      ,官网上的东西都挺全的                       ,各种功能,不愧是产品化的东西~~

(ps:这里本来分享了个链接                      。               。       。                      。结果违规了               。。                      。                       。我还是删掉)

3.1 下载ZED2的SDK

进入官网https://www.stereolabs.com/zed-2/

选择下图SDK Downloads

选择ZED SDK for ubuntu18              ,可以下载得到一个.run文件(记得修改文件名) chmod +x ZED_SDK_Ubuntu18_cuda11.1_v3.7.4.run ./ZED_SDK_Ubuntu18_cuda11.1_v3.7.4.run

后面一直y就可以了

3.2 下载ZED2的python的API

GitHub下载python的API然后安装(前面安装SDK的时候其实也会执行安装                       ,但是因为网络的问题不会成功        ,所以直接手动安)

git clone https://github.com/stereolabs/zed-python-api.git cd zed-python-api/src pip3 install -r requirements.txt -i http://pypi.douban.com/simple --trusted-host pypi.douban.com python3 setup.py build python3 setup.py install

安装完成后测试是否成功              ,这里记住一定要用USB3.0口                      ,否则可能会启动SDK失败

cd /usr/local/zed/tools ./ZED_Depth_Viewer

出现双目的界面就是成功了

3.3 安装zed ros wrapper

这里默认各位已经有自己的工作空间了

cd ~/catkin_ws/src git clone --recursive https://github.com/stereolabs/zed-ros-wrapper.git git clone https://github.com/stereolabs/zed-ros-examples.git cd ../ catkin_make source ./devel/setup.bash roslaunch zed_display_rviz display_zed.launch

能正常显示图像就是安装成功

四       、双目相机                      、IMU               、联合标定

4.1 安装标定工具

首先安装相关依赖

sudo apt-get install python-setuptools python-rosinstall ipython libeigen3-dev libboost-all-dev doxygen libopencv-dev ros-melodic-vision-opencv ros-melodic-image-transport-plugins ros-melodic-cmake-modules software-properties-common software-properties-common libpoco-dev python-matplotlib python-scipy python-git python-pip ipython libtbb-dev libblas-dev liblapack-dev python-catkin-tools libv4l-dev sudo add-apt-repository ppa:igraph/ppa sudo apt-get update # update your package database sudo apt-get install python-igraph

创建新的工作空间        ,记得在bashrc里面添加环境变量 source ~/kalibr_workspace/devel/setup.bash

mkdir -p ~/kalibr_workspace/src cd ~/kalibr_workspace catkin_make

下载源码并编译(catkin_make和catkin_build不一样       ,所以需要创建新的工作空间)

cd ~/kalibr_workspace/src git clone https://github.com/ethz-asl/Kalibr.git catkin build -DCMAKE_BUILD_TYPE=Release -j4

下载编译code_utils(这里要在catkin_make创建的工作空间下编译                      ,我的是catkin_ws)

cd ~/catkin_ws/src git clone https://github.com/gaowenliang/code_utilsarget_type: aprilgrid #gridtype tagCols: 6 #number of apriltags tagRows: 6 #number of apriltags tagSize: 0.088 #size of apriltag, edge to edge [m] tagSpacing: 0.3 #ratio of space between tags to tagSize sudo apt-get install libdw-dev cd ../ catkin_make

下载编译imu_utils

git clone https://github.com/gaowenliang/imu_utils cd ../ catkin_make

4.2 下载标定板和yaml文件

进入GitHub下载相关参数文件https://github.com/ethz-asl/kalibr/wiki/downloads#calibration-targets

选择 Aprilgrid 6x6 0.8x0.8 m (A0 page)               ,下载其pdf和yaml文件

以下是yaml文件内容:

其中codeOffset参数没用       ,可以删掉                      ,tagSize就是黑色大方格的边长               ,tagSpacing是黑色小方格的边长/黑色大方格的边长 target_type: aprilgrid #gridtype tagCols: 6 #number of apriltags tagRows: 6 #number of apriltags tagSize: 0.088 #size of apriltag, edge to edge [m] tagSpacing: 0.3 #ratio of space between tags to tagSize codeOffset: 0 #code offset for the first tag in the aprilboard

4.3 ZED2录制bag包准备标定

在catkin_ws/src/zed-ros-wrapper/zed_wrapper/params文件夹下找到common.yaml(参数配置文件),里面可以配置相机输出分辨率                      ,我设置了resolution为2                       ,分辨率大小为1280720,但是实际上标定时订阅ros话题获取的图像分辨率是这个的一半              ,即640360                       ,感觉很离谱        ,继续继续~~              ,要是同志们知道为啥麻烦评论区告诉我一声。

接下来启动ZED2: roslaunch zed_wrapper zed2.launch rqt_image_view ## 可视化图像                      ,选择/zed2/zed_node/stereo/image_rect_color

默认的相机发布频率是15Hz        ,IMU发布频率为200Hz       ,下面要开始录制用于标定的bag包了                      ,有几个注意事项:(1)注意录制的时候要让二维码的全貌暴露在在双目相机的两个摄像头的视野中               ,通过rqt_image_view可以查看              。(2)充分让二维码移动到相机视野的每个角落(3)沿着相机的三个轴分别前后左右移动三个轮回       ,绕着三个轴来回摆动三个轮回                      ,具体的操作可以先看下这个视频https://youtu.be/puNXsnrYWTY?t=57

rosbag record -O Kalib_data_HD720.bag /zed2/zed_node/imu/data_raw /zed2/zed_node/left/image_rect_color /zed2/zed_node/right/image_rect_color

一共录制三个话题               ,相机图像和IMU的                       。网上有很多人说要降低频率,倒是没啥大必要                      ,直接录制就行        。

4.4 相机标定

记得Kalib_data_HD720.bag(录制的bag包)和april.yaml(标定板参数文件)替换为自己实际位置所在的路径                       ,一会儿就标好了,反正我是没有报错的              ,如果真的报错了                       ,建议重新录制              。 在标定过程中可以可视化角点检测情况是否良好        ,发现角点重投影出现严重错误; --approx-sync 0.04              ,其中0.04可以看情况调整到0.1                      ,作用是使各个摄像头数据同步                      。

roscore rosrun kalibr kalibr_calibrate_cameras --bag Kalib_data_HD720.bag --topics /zed2/zed_node/left/image_rect_color /zed2/zed_node/right/image_rect_color --models pinhole-radtan pinhole-radtan --target april.yaml

标定结束后会获得相机的内参等文件        ,其中yaml文件可用于联合标定        。

我的Kalib_data_HD720-camchain.yaml文件内容: cam0: cam_overlaps: [1] camera_model: pinhole distortion_coeffs: [-0.020457937535071292, 0.01104746035697357, 0.00020521550183980535, -0.0015638016748186173] distortion_model: radtan intrinsics: [256.5277384633465, 258.08249705047217, 325.50319459226085, 180.96517806223522] resolution: [640, 360] rostopic: /zed2/zed_node/left/image_rect_color cam1: T_cn_cnm1: - [0.9999953299145323, -0.0004175552431604406, -0.0030275066874908296, -0.1187894654449685] - [0.0004273153754671597, 0.9999947119574588, 0.003223888752289577, -5.5098799754223526e-05] - [0.0030261445262547908, -0.003225167396610463, 0.999990220324463, 7.990539895358612e-05] - [0.0, 0.0, 0.0, 1.0] cam_overlaps: [0] camera_model: pinhole distortion_coeffs: [-0.04197232826018052, 0.043604460293796686, 9.290216968896611e-05, -0.0025178786825268214] distortion_model: radtan intrinsics: [256.7217295800593, 258.5591545191309, 326.7180901852667, 180.36186639653016] resolution: [640, 360] rostopic: /zed2/zed_node/right/image_rect_color

4.5 IMU标定

(1)用imu_utils手动标定

rosbag record -O imu_calibration /zed2/zed_node/imu/data_raw

要录制超过两小时       ,创建launch文件                      ,命名为ZED2_calibration.launch

<launch> <node pkg="imu_utils" type="imu_an" name="imu_an" output="screen"> <param name="imu_topic" type="string" value= "/zed2/zed_node/imu/data_raw"/> <param name="imu_name" type="string" value= "ZED2"/> <param name="data_save_path" type="string" value= "$(find imu_utils)/data/"/> <param name="max_time_min" type="int" value= "120"/> <param name="max_cluster" type="int" value= "200"/> </node> </launch>

启动标定

roslaunch imu_utils ZED2_calibration.launch rosbag play -r 200 imu_calibration.bag

最后到标定结果文件               ,从而创建对应的imu.yaml(取标定结果Acc及Gyr的平均值填入imu.yaml文件)

(2)直接用官方数据

创建imu.yaml

填入 #Accelerometers accelerometer_noise_density: 1.4e-03 #Noise density (continuous-time) accelerometer_random_walk: 8.0e-05 #Bias random walk #Gyroscopes gyroscope_noise_density: 8.6e-05 #Noise density (continuous-time) gyroscope_random_walk: 2.2e-06 #Bias random walk rostopic: /zed2/zed_node/imu/data_raw #the IMU ROS topic update_rate: 200.0 #Hz (for discretization of the values above)

4.6 双目相机/IMU联合标定

注意Kalib_data_HD720.bag 、camchain-Kalib_data_HD720.yaml                      、imu.yaml                       、april.yaml这几个文件尽量用绝对路径

roscore rosrun kalibr kalibr_calibrate_imu_camera --bag Kalib_data_HD720.bag --cam camchain-Kalib_data_HD720.yaml --imu imu.yaml --target april.yaml

最终可以获得联合标定参数Kalib_data_HD720-imu.yaml:

cam0: T_cam_imu: - [0.011189492088057723, -0.9999089154286149, 0.007546927400109649, 0.030171769239718378] - [-0.005170435177808852, -0.0076051555206256005, -0.9999577132107034, 0.006834916768468505] - [0.999924028047573, 0.011149998021449559, -0.0052550620584632945, -0.018995636408175094] - [0.0, 0.0, 0.0, 1.0] cam_overlaps: [1] camera_model: pinhole distortion_coeffs: [-0.020457937535071292, 0.01104746035697357, 0.00020521550183980535, -0.0015638016748186173] distortion_model: radtan intrinsics: [256.5277384633465, 258.08249705047217, 325.50319459226085, 180.96517806223522] resolution: [640, 360] rostopic: /zed2/zed_node/left/image_rect_color timeshift_cam_imu: 0.018432058955920882 cam1: T_cam_imu: - [0.008164322092594406, -0.9999348268895338, 0.0079803394769285, -0.0885631816490655] - [-0.001941982567148115, -0.007996445404659519, -0.9999661422091248, 0.006731434867725931] - [0.9999647856542138, 0.008148547986540189, -0.002007141557983233, -0.01884628485444885] - [0.0, 0.0, 0.0, 1.0] T_cn_cnm1: - [0.9999953299145328, -0.0004175552431604405, -0.003027506687490829, -0.1187894654449685] - [0.00042731537546715964, 0.9999947119574593, 0.0032238887522895773, -5.5098799754223526e-05] - [0.0030261445262547903, -0.0032251673966104634, 0.9999902203244635, 7.990539895358612e-05] - [0.0, 0.0, 0.0, 1.0] cam_overlaps: [0] camera_model: pinhole distortion_coeffs: [-0.04197232826018052, 0.043604460293796686, 9.290216968896611e-05, -0.0025178786825268214] distortion_model: radtan intrinsics: [256.7217295800593, 258.5591545191309, 326.7180901852667, 180.36186639653016] resolution: [640, 360] rostopic: /zed2/zed_node/right/image_rect_color timeshift_cam_imu: 0.018616236206986332

五、ZED2跑ORB-SLAM3

5.1 编译安装ORB-SLAM3

这里直接引用一个博主的内容吧       ,我在三台计算机设备上都配置过                      ,其实问题一个是环境变量               ,在bashrc中添加

export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/lixushi/ORB_SLAM3-master/Examples_old/ROS(路径要换成自己的),一个是缺少依赖库                      ,如Sophus库                       ,这里可以安《视觉SLAM14讲》里的那个库不会有什么奇怪的问题,其他的遇到了自己根据报错信息安就行              ,官网讲的挺详细了                       ,还有一个问题是CmakeList文件        ,编译时候一方面opencv指向要改一下              ,编译ros的那个CmakeList文件中                      ,有关AR的.cc文件编译部分删掉        ,后面基本没有其他问题了. git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git cd ORB_SLAM3-master chmod +x build.sh ./build.sh cd ORB_SLAM3-master/Examples_old/ROS/ORB_SLAM3 mkdir build cd build cmake .. make

下面添加配置文件

cd ORB_SLAM3-master/Examples_old/ROS/ORB_SLAM3/src touch zed2_stereo_inertial.cc touch zed2_stereo_inertial.yaml

在zed2_stereo_inertial.cc文件中添加以下信息

/** * This file is part of ORB-SLAM3 * * Copyright (C) 2017-2021 Carlos Campos, Richard Elvira, Juan J. Gómez Rodríguez, José M.M. Montiel and Juan D. Tardós, University of Zaragoza. * Copyright (C) 2014-2016 Raúl Mur-Artal, José M.M. Montiel and Juan D. Tardós, University of Zaragoza. * * ORB-SLAM3 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ORB-SLAM3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with ORB-SLAM3. * If not, see <http://www.gnu.org/licenses/>. */ #include<iostream> #include<algorithm> #include<fstream> #include<chrono> #include<vector> #include<queue> #include<thread> #include<mutex> #include<ros/ros.h> #include<cv_bridge/cv_bridge.h> #include<sensor_msgs/Imu.h> #include<opencv2/core/core.hpp> #include"../../../include/System.h" #include"include/ImuTypes.h" using namespace std; class ImuGrabber { public: ImuGrabber(){}; void GrabImu(const sensor_msgs::ImuConstPtr &imu_msg); queue<sensor_msgs::ImuConstPtr> imuBuf; std::mutex mBufMutex; }; class ImageGrabber { public: ImageGrabber(ORB_SLAM3::System* pSLAM, ImuGrabber *pImuGb, const bool bRect, const bool bClahe): mpSLAM(pSLAM), mpImuGb(pImuGb), do_rectify(bRect), mbClahe(bClahe){} void GrabImageLeft(const sensor_msgs::ImageConstPtr& msg); void GrabImageRight(const sensor_msgs::ImageConstPtr& msg); cv::Mat GetImage(const sensor_msgs::ImageConstPtr &img_msg); void SyncWithImu(); queue<sensor_msgs::ImageConstPtr> imgLeftBuf, imgRightBuf; std::mutex mBufMutexLeft,mBufMutexRight; ORB_SLAM3::System* mpSLAM; ImuGrabber *mpImuGb; const bool do_rectify; cv::Mat M1l,M2l,M1r,M2r; const bool mbClahe; cv::Ptr<cv::CLAHE> mClahe = cv::createCLAHE(3.0, cv::Size(8, 8)); }; int main(int argc, char **argv) { ros::init(argc, argv, "Stereo_Inertial"); ros::NodeHandle n("~"); ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Info); bool bEqual = false; if(argc < 4 || argc > 5) { cerr << endl << "Usage: rosrun ORB_SLAM3 Stereo_Inertial path_to_vocabulary path_to_settings do_rectify [do_equalize]" << endl; ros::shutdown(); return 1; } std::string sbRect(argv[3]); if(argc==5) { std::string sbEqual(argv[4]); if(sbEqual == "true") bEqual = true; } // Create SLAM system. It initializes all system threads and gets ready to process frames. ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_STEREO,true); ImuGrabber imugb; ImageGrabber igb(&SLAM,&imugb,sbRect == "true",bEqual); if(igb.do_rectify) { // Load settings related to stereo calibration cv::FileStorage fsSettings(argv[2], cv::FileStorage::READ); if(!fsSettings.isOpened()) { cerr << "ERROR: Wrong path to settings" << endl; return -1; } cv::Mat K_l, K_r, P_l, P_r, R_l, R_r, D_l, D_r; fsSettings["LEFT.K"] >> K_l; fsSettings["RIGHT.K"] >> K_r; fsSettings["LEFT.P"] >> P_l; fsSettings["RIGHT.P"] >> P_r; fsSettings["LEFT.R"] >> R_l; fsSettings["RIGHT.R"] >> R_r; fsSettings["LEFT.D"] >> D_l; fsSettings["RIGHT.D"] >> D_r; int rows_l = fsSettings["LEFT.height"]; int cols_l = fsSettings["LEFT.width"]; int rows_r = fsSettings["RIGHT.height"]; int cols_r = fsSettings["RIGHT.width"]; if(K_l.empty() || K_r.empty() || P_l.empty() || P_r.empty() || R_l.empty() || R_r.empty() || D_l.empty() || D_r.empty() || rows_l==0 || rows_r==0 || cols_l==0 || cols_r==0) { cerr << "ERROR: Calibration parameters to rectify stereo are missing!" << endl; return -1; } cv::initUndistortRectifyMap(K_l,D_l,R_l,P_l.rowRange(0,3).colRange(0,3),cv::Size(cols_l,rows_l),CV_32F,igb.M1l,igb.M2l); cv::initUndistortRectifyMap(K_r,D_r,R_r,P_r.rowRange(0,3).colRange(0,3),cv::Size(cols_r,rows_r),CV_32F,igb.M1r,igb.M2r); } // Maximum delay, 5 seconds //ros::Subscriber sub_imu = n.subscribe("/imu", 1000, &ImuGrabber::GrabImu, &imugb); //ros::Subscriber sub_img_left = n.subscribe("/camera/left/image_raw", 100, &ImageGrabber::GrabImageLeft,&igb); //ros::Subscriber sub_img_right = n.subscribe("/camera/right/image_raw", 100, &ImageGrabber::GrabImageRight,&igb); ros::Subscriber sub_imu = n.subscribe("/zed2/zed_node/imu/data_raw", 1000, &ImuGrabber::GrabImu, &imugb); ros::Subscriber sub_img_left = n.subscribe("/zed2/zed_node/left/image_rect_color", 100, &ImageGrabber::GrabImageLeft,&igb); ros::Subscriber sub_img_right = n.subscribe("/zed2/zed_node/right/image_rect_color", 100, &ImageGrabber::GrabImageRight,&igb); std::thread sync_thread(&ImageGrabber::SyncWithImu,&igb); ros::spin(); return 0; } void ImageGrabber::GrabImageLeft(const sensor_msgs::ImageConstPtr &img_msg) { mBufMutexLeft.lock(); if (!imgLeftBuf.empty()) imgLeftBuf.pop(); imgLeftBuf.push(img_msg); mBufMutexLeft.unlock(); } void ImageGrabber::GrabImageRight(const sensor_msgs::ImageConstPtr &img_msg) { mBufMutexRight.lock(); if (!imgRightBuf.empty()) imgRightBuf.pop(); imgRightBuf.push(img_msg); mBufMutexRight.unlock(); } cv::Mat ImageGrabber::GetImage(const sensor_msgs::ImageConstPtr &img_msg) { // Copy the ros image message to cv::Mat. cv_bridge::CvImageConstPtr cv_ptr; try { cv_ptr = cv_bridge::toCvShare(img_msg, sensor_msgs::image_encodings::MONO8); } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge exception: %s", e.what()); } if(cv_ptr->image.type()==0) { return cv_ptr->image.clone(); } else { std::cout << "Error type" << std::endl; return cv_ptr->image.clone(); } } void ImageGrabber::SyncWithImu() { const double maxTimeDiff = 0.01; while(1) { cv::Mat imLeft, imRight; double tImLeft = 0, tImRight = 0; if (!imgLeftBuf.empty()&&!imgRightBuf.empty()&&!mpImuGb->imuBuf.empty()) { tImLeft = imgLeftBuf.front()->header.stamp.toSec(); tImRight = imgRightBuf.front()->header.stamp.toSec(); this->mBufMutexRight.lock(); while((tImLeft-tImRight)>maxTimeDiff && imgRightBuf.size()>1) { imgRightBuf.pop(); tImRight = imgRightBuf.front()->header.stamp.toSec(); } this->mBufMutexRight.unlock(); this->mBufMutexLeft.lock(); while((tImRight-tImLeft)>maxTimeDiff && imgLeftBuf.size()>1) { imgLeftBuf.pop(); tImLeft = imgLeftBuf.front()->header.stamp.toSec(); } this->mBufMutexLeft.unlock(); if((tImLeft-tImRight)>maxTimeDiff || (tImRight-tImLeft)>maxTimeDiff) { // std::cout << "big time difference" << std::endl; continue; } if(tImLeft>mpImuGb->imuBuf.back()->header.stamp.toSec()) continue; this->mBufMutexLeft.lock(); imLeft = GetImage(imgLeftBuf.front()); imgLeftBuf.pop(); this->mBufMutexLeft.unlock(); this->mBufMutexRight.lock(); imRight = GetImage(imgRightBuf.front()); imgRightBuf.pop(); this->mBufMutexRight.unlock(); vector<ORB_SLAM3::IMU::Point> vImuMeas; mpImuGb->mBufMutex.lock(); if(!mpImuGb->imuBuf.empty()) { // Load imu measurements from buffer vImuMeas.clear(); while(!mpImuGb->imuBuf.empty() && mpImuGb->imuBuf.front()->header.stamp.toSec()<=tImLeft) { double t = mpImuGb->imuBuf.front()->header.stamp.toSec(); cv::Point3f acc(mpImuGb->imuBuf.front()->linear_acceleration.x, mpImuGb->imuBuf.front()->linear_acceleration.y, mpImuGb->imuBuf.front()->linear_acceleration.z); cv::Point3f gyr(mpImuGb->imuBuf.front()->angular_velocity.x, mpImuGb->imuBuf.front()->angular_velocity.y, mpImuGb->imuBuf.front()->angular_velocity.z); vImuMeas.push_back(ORB_SLAM3::IMU::Point(acc,gyr,t)); mpImuGb->imuBuf.pop(); } } mpImuGb->mBufMutex.unlock(); if(mbClahe) { mClahe->apply(imLeft,imLeft); mClahe->apply(imRight,imRight); } if(do_rectify) { cv::remap(imLeft,imLeft,M1l,M2l,cv::INTER_LINEAR); cv::remap(imRight,imRight,M1r,M2r,cv::INTER_LINEAR); } mpSLAM->TrackStereo(imLeft,imRight,tImLeft,vImuMeas); std::chrono::milliseconds tSleep(1); std::this_thread::sleep_for(tSleep); } } } void ImuGrabber::GrabImu(const sensor_msgs::ImuConstPtr &imu_msg) { mBufMutex.lock(); imuBuf.push(imu_msg); mBufMutex.unlock(); return; }

在zed2_stereo_inertial.yaml中添加以下信息(这里是我的相机参数       ,大家根据自己情况修改)

这里面的DKRP数据我是直接用的ZED左右目原始图像的camera_info话题中的数据                      ,大家可以rostopic list找一下               ,此外       ,zed2相机基线长度为120

参数说明可以参考博客:

https://blog.csdn.net/chenguowen21/article/details/83044654

https://blog.csdn.net/sinat_16643223/article/details/115224938

https://blog.csdn.net/zhubaohua_bupt/article/details/80222321 %YAML:1.0 #-------------------------------------------------------------------------------------------- # Camera Parameters. Adjust them! #-------------------------------------------------------------------------------------------- Camera.type: "PinHole" # Camera calibration and distortion parameters (OpenCV) (equal for both cameras after stereo rectification) Camera.fx: 256.5277384633465 Camera.fy: 258.08249705047217 Camera.cx: 325.50319459226085 Camera.cy: 180.96517806223522 # 用的是校正过的节点                      ,所以畸变参数设置为0 Camera.k1: -0.020457937535071292 Camera.k2: 0.01104746035697357 Camera.p1: 0.00020521550183980535 Camera.p2: -0.0015638016748186173 Camera.width: 640 Camera.height: 360 # Camera frames per second Camera.fps: 15.0 # stereo baseline times fx 基线和fx的乘积 Camera.bf: 30.7824 # Color order of the images (0: BGR, 1: RGB. It is ignored if images are grayscale) Camera.RGB: 1 # Close/Far threshold. Baseline times. ThDepth: 40.0 # 35 # Transformation from camera 0 to body-frame (imu) # 从左目转换到IMU坐标系 Tbc: !!opencv-matrix rows: 4 cols: 4 dt: f data: [ 0.011189492088057723, -0.005170435177808852, 0.999924028047573, -0.030171769239718378, -0.9999089154286149, -0.0076051555206256005, 0.011149998021449559, +0.006834916768468505, 0.007546927400109649, -0.9999577132107034, -0.0052550620584632945, -0.018995636408175094, 0.0, 0.0, 0.0, 1.0] # IMU noise # get it from Project of **zed-examples/tutorials/tutorial 7 - sensor data/**. IMU.NoiseGyro: 8.6e-05 # 1.6968e-04 IMU.NoiseAcc: 0.0014 # 2.0000e-3 IMU.GyroWalk: 2.2e-06 IMU.AccWalk: 8.0e-05 # 3.0000e-3 IMU.Frequency: 200 #-------------------------------------------------------------------------------------------- # Stereo Rectification. Only if you need to pre-rectify the images. # Camera.fx, .fy, etc must be the same as in LEFT.P #-------------------------------------------------------------------------------------------- LEFT.height: 360 LEFT.width: 640 LEFT.D: !!opencv-matrix rows: 1 cols: 5 dt: d data: [-0.040750399231910706, 0.009019049815833569, -0.004655580036342144, -0.0006361529813148081, 0.0003129479882773012] LEFT.K: !!opencv-matrix rows: 3 cols: 3 dt: d data: [264.1424865722656, 0.0, 328.0299987792969, 0.0, 263.9525146484375, 180.45175170898438, 0.0, 0.0, 1.0] LEFT.R: !!opencv-matrix rows: 3 cols: 3 dt: d data: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] LEFT.Rf: !!opencv-matrix rows: 3 cols: 3 dt: f data: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] LEFT.P: !!opencv-matrix rows: 3 cols: 4 dt: d data: [264.1424865722656, 0.0, 328.0299987792969, 0.0, 0.0, 263.9525146484375, 180.45175170898438, 0.0, 0.0, 0.0, 1.0, 0.0] RIGHT.height: 360 RIGHT.width: 640 RIGHT.D: !!opencv-matrix rows: 1 cols: 5 dt: d data: [-0.03843430057168007, 0.005912320222705603, -0.0034095800947397947, 6.041819870006293e-05, -0.00011238799925195053] RIGHT.K: !!opencv-matrix rows: 3 cols: 3 dt: d data: [263.0425109863281, 0.0, 326.2799987792969, 0.0, 262.93499755859375, 180.3209991455078, 0.0, 0.0, 1.0] RIGHT.R: !!opencv-matrix rows: 3 cols: 3 dt: d data: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] RIGHT.P: !!opencv-matrix rows: 3 cols: 4 dt: d data: [263.0425109863281, 0.0, 326.2799987792969, -31.668317794799805, 0.0, 262.93499755859375, 180.3209991455078, 0.0, 0.0, 0.0, 1.0, 0.0] #-------------------------------------------------------------------------------------------- # ORB Parameters #-------------------------------------------------------------------------------------------- # ORB Extractor: Number of features per image ORBextractor.nFeatures: 2200 # ORB Extractor: Scale factor between levels in the scale pyramid ORBextractor.scaleFactor: 1.2 # ORB Extractor: Number of levels in the scale pyramid ORBextractor.nLevels: 8 # ORB Extractor: Fast threshold # Image is divided in a grid. At each cell FAST are extracted imposing a minimum response. # Firstly we impose iniThFAST. If no corners are detected we impose a lower value minThFAST # You can lower these values if your images have low contrast ORBextractor.iniThFAST: 20 ORBextractor.minThFAST: 7 #-------------------------------------------------------------------------------------------- # Viewer Parameters #-------------------------------------------------------------------------------------------- Viewer.KeyFrameSize: 0.05 Viewer.KeyFrameLineWidth: 1 Viewer.GraphLineWidth: 0.9 Viewer.PointSize:2 Viewer.CameraSize: 0.08 Viewer.CameraLineWidth: 3 Viewer.ViewpointX: 0 Viewer.ViewpointY: -0.7 Viewer.ViewpointZ: -1.8 Viewer.ViewpointF: 500

编辑CMakeLists.txt文件

cd ORB_SLAM3-master/Examples_old/ROS/ORB_SLAM3 gedit CMakeLists.txt

在最下面添加

rosbuild_add_executable(zed2_stereo_inertial src/zed2_stereo_inertial.cc ) target_link_libraries(zed2_stereo_inertial ${LIBS} )

重新编译即可               ,如果找不到可执行文件,运行

rospack profile

5.2 运行ORB-SLAM3

这里我是在学校里面录了bag包

roscore rosrun ORB_SLAM3 zed2_stereo_inertial /home/lixushi/ORB_SLAM3-master/Vocabulary/ORBvoc.txt /home/lixushi/ORB_SLAM3-master/Examples_old/ROS/ORB_SLAM3/src/zed2_stereo_inertial.yaml true rosbag play Kalib_data_HD720-4.bag

运行效果如下图                      ,还是可以的                       ,都跑了六百米左右

六              、总结

总体来说标定一次成功还是很开心的,网上没有详细的教程走了很多坑              ,希望能帮到各位                       ,但是还有个问题       。                      。               。为啥rosbag运行完以后不会保存轨迹文件呢???有人能告诉我一下不       。                      。               。

七                       、参考文献

[1] https://blog.csdn.net/m0_37201243/article/details/103439613

[2]https://blog.csdn.net/slamer111/article/details/124360452

[3]https://blog.csdn.net/xiaojinger_123/article/details/120849737?spm=1001.2014.3001.5501

[4]https://blog.csdn.net/xiaojinger_123/article/details/121232948

[5]https://blog.csdn.net/sinat_16643223/article/details/115416277?spm=1001.2014.3001.5506

[6]https://blog.csdn.net/weixin_43492473/article/details/124476546?spm=1001.2014.3001.5502

[7]https://blog.csdn.net/xiaojinger_123/article/details/121232948

[8]https://blog.csdn.net/slender_1031/article/details/115030053

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
php水印生成源码(PHPCMS中PNG水印不显示?) 摄像头osd是什么意思(os x yosemite dp5下载地址 os x 10.10 dp5更新内容)