位置: IT常识 - 正文

ZED2跑ORB-SLAM3+双目相机、IMU联合标定+显卡驱动与cuda/cudnn安装

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

推荐整理分享ZED2跑ORB-SLAM3+双目相机、IMU联合标定+显卡驱动与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/cudaexport 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/deviceQuerysudo 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.hsudo 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.gitcd zed-python-api/srcpip3 install -r requirements.txt -i http://pypi.douban.com/simple --trusted-host pypi.douban.compython3 setup.py buildpython3 setup.py install

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

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

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

3.3 安装zed ros wrapper

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

cd ~/catkin_ws/srcgit clone --recursive https://github.com/stereolabs/zed-ros-wrapper.gitgit clone https://github.com/stereolabs/zed-ros-examples.gitcd ../catkin_makesource ./devel/setup.bashroslaunch 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-devsudo add-apt-repository ppa:igraph/ppasudo apt-get update # update your package database sudo apt-get install python-igraph

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

mkdir -p ~/kalibr_workspace/srccd ~/kalibr_workspacecatkin_makeZED2跑ORB-SLAM3+双目相机、IMU联合标定+显卡驱动与cuda/cudnn安装

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

cd ~/kalibr_workspace/srcgit clone https://github.com/ethz-asl/Kalibr.gitcatkin build -DCMAKE_BUILD_TYPE=Release -j4

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

cd ~/catkin_ws/srcgit clone https://github.com/gaowenliang/code_utilsarget_type: 'aprilgrid' #gridtypetagCols: 6 #number of apriltagstagRows: 6 #number of apriltagstagSize: 0.088 #size of apriltag, edge to edge [m]tagSpacing: 0.3 #ratio of space between tags to tagSizesudo apt-get install libdw-devcd ../catkin_make

下载编译imu_utils

git clone https://github.com/gaowenliang/imu_utilscd ../catkin_make4.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' #gridtypetagCols: 6 #number of apriltagstagRows: 6 #number of apriltagstagSize: 0.088 #size of apriltag, edge to edge [m]tagSpacing: 0.3 #ratio of space between tags to tagSizecodeOffset: 0 #code offset for the first tag in the aprilboard4.3 ZED2录制bag包准备标定

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

roslaunch zed_wrapper zed2.launchrqt_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,作用是使各个摄像头数据同步。

roscorerosrun 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_colorcam1: 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_color4.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.launchrosbag play -r 200 imu_calibration.bag

最后到标定结果文件,从而创建对应的imu.yaml(取标定结果Acc及Gyr的平均值填入imu.yaml文件) (2)直接用官方数据 创建imu.yaml 填入

#Accelerometersaccelerometer_noise_density: 1.4e-03 #Noise density (continuous-time)accelerometer_random_walk: 8.0e-05 #Bias random walk#Gyroscopesgyroscope_noise_density: 8.6e-05 #Noise density (continuous-time)gyroscope_random_walk: 2.2e-06 #Bias random walkrostopic: /zed2/zed_node/imu/data_raw #the IMU ROS topicupdate_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这几个文件尽量用绝对路径

roscorerosrun 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.018432058955920882cam1: 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-SLAM35.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.gitcd ORB_SLAM3-masterchmod +x build.sh./build.shcd ORB_SLAM3-master/Examples_old/ROS/ORB_SLAM3mkdir buildcd buildcmake ..make

下面添加配置文件

cd ORB_SLAM3-master/Examples_old/ROS/ORB_SLAM3/srctouch zed2_stereo_inertial.cctouch 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.5277384633465Camera.fy: 258.08249705047217Camera.cx: 325.50319459226085Camera.cy: 180.96517806223522# 用的是校正过的节点,所以畸变参数设置为0Camera.k1: -0.020457937535071292Camera.k2: 0.01104746035697357Camera.p1: 0.00020521550183980535Camera.p2: -0.0015638016748186173Camera.width: 640Camera.height: 360# Camera frames per secondCamera.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-04IMU.NoiseAcc: 0.0014 # 2.0000e-3IMU.GyroWalk: 2.2e-06IMU.AccWalk: 8.0e-05 # 3.0000e-3IMU.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: 360LEFT.width: 640LEFT.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: 360RIGHT.width: 640RIGHT.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 imageORBextractor.nFeatures: 2200# ORB Extractor: Scale factor between levels in the scale pyramidORBextractor.scaleFactor: 1.2# ORB Extractor: Number of levels in the scale pyramidORBextractor.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 contrastORBextractor.iniThFAST: 20ORBextractor.minThFAST: 7#--------------------------------------------------------------------------------------------# Viewer Parameters#--------------------------------------------------------------------------------------------Viewer.KeyFrameSize: 0.05Viewer.KeyFrameLineWidth: 1Viewer.GraphLineWidth: 0.9Viewer.PointSize:2Viewer.CameraSize: 0.08Viewer.CameraLineWidth: 3Viewer.ViewpointX: 0Viewer.ViewpointY: -0.7Viewer.ViewpointZ: -1.8Viewer.ViewpointF: 500

编辑CMakeLists.txt文件

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

在最下面添加

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

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

rospack profile5.2 运行ORB-SLAM3

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

roscorerosrun 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 truerosbag 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

本文链接地址:https://www.jiuchutong.com/zhishi/299196.html 转载请保留说明!

上一篇:新一代 L1 公链Aptos:安全、可扩展和可升级的Web3基础设施 |Tokenview(公链dapp)

下一篇:Sklearn GridSearchCV跑SVM很慢或卡死解决办法,SVM线性核函数卡死

  • 朋友圈一条直线中间一点什么意思(朋友圈一条直线一个点是什么意思)

    朋友圈一条直线中间一点什么意思(朋友圈一条直线一个点是什么意思)

  • 小米手环3放了一年无法充电(小米手环3放了很久充电没反应)

    小米手环3放了一年无法充电(小米手环3放了很久充电没反应)

  • 微信封号了,里面的钱怎么拿出来(微信封号了零钱通里的钱可以提出来吗)

    微信封号了,里面的钱怎么拿出来(微信封号了零钱通里的钱可以提出来吗)

  • 表现媒体是什么(表示媒体和表现媒体的区别)

    表现媒体是什么(表示媒体和表现媒体的区别)

  • 快手能指定谁看作品么(快手怎么让指定的人才能看)

    快手能指定谁看作品么(快手怎么让指定的人才能看)

  • 苹果通话记录自动清空(苹果通话记录自己删除)

    苹果通话记录自动清空(苹果通话记录自己删除)

  • 拼多多卖家退款次数多有影响吗(拼多多卖家退款流程)

    拼多多卖家退款次数多有影响吗(拼多多卖家退款流程)

  • vivo手机收音机在哪里(vivo手机收音机功能在哪里)

    vivo手机收音机在哪里(vivo手机收音机功能在哪里)

  • 天猫自动确认收货时间是几天(天猫自动确认收货,但东西还没到)

    天猫自动确认收货时间是几天(天猫自动确认收货,但东西还没到)

  • 手机信号放大器对人体有害吗(手机信号放大器怎么调试)

    手机信号放大器对人体有害吗(手机信号放大器怎么调试)

  • 安卓手机怎么强制重启(安卓手机怎么强制格式化)

    安卓手机怎么强制重启(安卓手机怎么强制格式化)

  • 苹果11忘记id密码怎么办(苹果11忘记id密码和锁屏密码)

    苹果11忘记id密码怎么办(苹果11忘记id密码和锁屏密码)

  • 格式化存储盘是什么意思(格式化储存卡是什么意思)

    格式化存储盘是什么意思(格式化储存卡是什么意思)

  • 怎样知道对方退出微信(怎样知道对方退没退企业微信)

    怎样知道对方退出微信(怎样知道对方退没退企业微信)

  • 商业组织的域名是啥(商业组织的域名全称)

    商业组织的域名是啥(商业组织的域名全称)

  • 苹果手机怎么恢复微信草稿(苹果手机怎么恢复出厂设置抹掉所有内容)

    苹果手机怎么恢复微信草稿(苹果手机怎么恢复出厂设置抹掉所有内容)

  • 拼多多ip地址在哪儿(拼多多ip地址查询)

    拼多多ip地址在哪儿(拼多多ip地址查询)

  • 苹果11消息闪光灯怎么开(苹果11消息闪光灯怎么关闭)

    苹果11消息闪光灯怎么开(苹果11消息闪光灯怎么关闭)

  • 电脑微信提示操作频率过快请稍后再试(电脑版微信提示)

    电脑微信提示操作频率过快请稍后再试(电脑版微信提示)

  • uc不支持打开该文件怎么办(uc不支持打开该文件)

    uc不支持打开该文件怎么办(uc不支持打开该文件)

  • 计算机onc是什么键(计算机on/c)

    计算机onc是什么键(计算机on/c)

  • 抖音注销后是已重置吗(抖音已经注销)

    抖音注销后是已重置吗(抖音已经注销)

  • 钉钉免费电话怎么注销(钉钉电话免费吗)

    钉钉免费电话怎么注销(钉钉电话免费吗)

  • 手机免提声音小怎么办(手机免提声音小是怎么回事)

    手机免提声音小怎么办(手机免提声音小是怎么回事)

  • 微信运动有什么用(微信运动有什么办法让它不计步)

    微信运动有什么用(微信运动有什么办法让它不计步)

  • 设置melogincn(设置朋友圈仅限三天怎么设置)

    设置melogincn(设置朋友圈仅限三天怎么设置)

  • macOS big sur电池百分比显示怎么设置?(macos big sur 电池)

    macOS big sur电池百分比显示怎么设置?(macos big sur 电池)

  • 嵌入式软件产品的增值税即征即退具体实例
  • 所得税汇算清缴后发现有误怎么办
  • 进项抵扣税率是多少
  • 如何判断会计政策变动
  • 企业股权无偿转让不缴增值税
  • 税控盘交服务费
  • 住宿费电子发票样式
  • 以银行存款支付水电费
  • 账务核对有账表核对吗
  • 营业利润为负数说明什么
  • 开票与实际收款不一致有什么风险
  • 计提出口关税会计分录
  • 专票当月抵扣后当月作废会被发现吗
  • 收了款未开票凭证如何做
  • 持有营业执照
  • 个人去税务局开居间费发票
  • 租的厂房再转租怎么开票抵扣
  • 公司向个人借款利率最高多少
  • 增值税专用发票电子版
  • 报废固定资产增值税税率
  • 企业所得税 税法
  • 发票对方已认证怎么冲红
  • 中小企业代扣代缴增值税抵扣时限
  • 农民专业合作社属于什么企业类型
  • 免税和退税的区别出口企业
  • 短期借款的明细科目是什么
  • 城建附加减半征收文件
  • 计提的利息收入交所得税吗
  • 折旧可以计入主体成本吗
  • 人力资源服务收入计入什么科目
  • 安装adsl modem必须安装什么协议
  • 中国各省市区域划分
  • 房屋装修各项费用比例
  • 备用金会涨额度吗
  • php domdocument
  • 哪些情况下公司不能辞退员工
  • vue用法
  • 公司变更需要哪些资料~问华杰 财务
  • 多模态教学模式论文
  • 科大讯飞语音识别主要产品
  • php对接第三方支付
  • 给工程项目买保险合法吗
  • 公司账户收款退回怎么查
  • mongodb修改命令
  • 购办公桌椅入什么费用
  • 白条怎么收拾
  • 餐饮服务税率是服务类税率还是货物类
  • 关联债资比例是什么意思
  • 预付账款可以抵扣增值税么
  • mysql的性能优化方案有哪些
  • 加工费计入什么科目制造企业成本
  • 什么叫日常业务
  • 积分兑换商品怎么查快递
  • 取得股票期权的个人所得税问题
  • 机票电子行程单查询
  • 商贸企业如何结转已销商贸成本
  • 广告业和一般服务性行业有何异同?
  • 其他人挂靠公司交社保会计处理怎么做?
  • 公司从个人手中购买设备
  • 以前年度多计提了费用
  • 年末转出未交增值税借方余额怎么处理
  • 施工企业的具体工作有哪些
  • 软件租赁费入什么账户
  • window8更新
  • XP系统安装不了QQ
  • xp系统怎样打开隐藏文件
  • 笔记本bios密码怎么强制清除
  • windows10总是弹出用户账户控制
  • 解决Extjs 4 Panel作为Window组件的子组件时出现双重边框问题
  • 如何让卖家给你乖乖退款
  • perl \w
  • Node.js中的核心模块包括哪些内容?
  • css 定位
  • java项目怎么变成web项目
  • js的类型有哪几种
  • ajax实现无刷新
  • 深圳12366怎么转人工
  • 免征增值税的销售额
  • 外经证核销在公司所在地还是在项目所在地
  • 四川企业退休人员80岁高龄补贴
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设