一,软件安装
#ros安装,推荐使用鱼香ros一键安装,换源,安装,更新rosdep方便省心
wget http://fishros.com/install -O fishros && . fishros
#然后建议安装多终端操作软件Terminator,方便多终端操作
sudo apt install terminator
#Ctrl+Alt+T开启,Alt+A同时操作,Alt+O关闭同时操作
#realsense安装
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE || sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE
sudo add-apt-repository "deb https://librealsense.intel.com/Debian/apt-repo $(lsb_release -cs) main" -u
sudo apt-get install librealsense2-dkms
sudo apt-get install librealsense2-utils
sudo apt-get install librealsense2-dev
sudo apt-get install librealsense2-dbg
#测试:realsense-viewer
注意测试时左上角显示的USB必须是3.x,如果是2.x,可能是USB线是2.0的,或者插在了2.0的USB口上(3.0的线和口都是蓝色的)
#ceres-solver安装
官方网站http://www.ceres-solver.org/installation.html
sudo apt-get install cmake
sudo apt-get install libgoogle-glog-dev libgflags-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libeigen3-dev
sudo apt-get install libsuitesparse-dev
git clone https://ceres-solver.googlesource.com/ceres-solver
或者直接下载安装包,注意版本,需要CMake 3.10 或更高版本,需要Eigen 3.3 或更高版本。
tar zxf ceres-solver-2.1.0.tar.gz
mkdir ceres-bin
cd ceres-bin
cmake ../ceres-solver-2.1.0
sudo make -j8
make test
sudo make install
#构建VINS-Fusion,创建工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
git clone https://github.com/HKUST-Aerial-Robotics/VINS-Fusion.git
cd ../
catkin_make
source ~/catkin_ws/devel/setup.bash
(如果此步骤失败,请尝试寻找另一台系统干净的计算机或重新安装 Ubuntu 和 ROS)
设置环境变量默认路径,在终端中输入该命令,会进入一个文件
gedit ~/.bashrc
文件打开后直接翻到最后面可以找到
>>> fishros initialize >>>
source /opt/ros/melodic/setup.bash
下面一行加入工作空间路径
<<< fishros initialize <<<
source ~/catkin_ws/devel/setup.bash
#编译安装 OctomapServer 建图包
cd src/
git clone https://github.com/OctoMap/octomap_mapping.git
返回你的工作空间主目录,安装下依赖,然后开始编译:
cd ../
rosdep install octomap_mapping
catkin_make
ROS 中提供了一个 Rviz 可视化 Octomap 的插件,如果没有安装使用下面的命令即可:
sudo apt-get install ros-你的ROS版本-octomap-rviz-plugins
安装完成后rviz工具中会出现octomap相关选项
其中的OccupancyGrid是显示三维概率地图,也就是octomap地图。OccupancyMap是显示二维占据栅格地图。
二,配置参数
1.创建启动文件
cd ~/catkin_ws/src/realsense-ros-development/realsense2_camera/launch
touch rs_camera_vins.launch
在rs_camera_vins.launch文件中填入如下代码:
<launch>
<arg name="serial_no" default=""/>
<arg name="usb_port_id" default=""/>
<arg name="device_type" default=""/>
<arg name="json_file_path" default=""/>
<arg name="camera" default="camera"/>
<arg name="tf_prefix" default="$(arg camera)"/>
<arg name="external_manager" default="false"/>
<arg name="manager" default="realsense2_camera_manager"/>
<arg name="fisheye_width" default="640"/>
<arg name="fisheye_height" default="480"/>
<arg name="enable_fisheye" default="false"/>
<arg name="depth_width" default="640"/>
<arg name="depth_height" default="480"/>
<arg name="enable_depth" default="true"/>
<arg name="infra_width" default="640"/>
<arg name="infra_height" default="480"/>
<arg name="enable_infra1" default="true"/>
<arg name="enable_infra2" default="true"/>
<arg name="color_width" default="640"/>
<arg name="color_height" default="480"/>
<arg name="enable_color" default="true"/>
<arg name="fisheye_fps" default="30"/>
<arg name="depth_fps" default="30"/>
<arg name="infra_fps" default="30"/>
<arg name="color_fps" default="30"/>
<arg name="gyro_fps" default="200"/>
<arg name="accel_fps" default="200"/>
<arg name="enable_gyro" default="true"/>
<arg name="enable_accel" default="true"/>
<arg name="enable_pointcloud" default="false"/>
<arg name="pointcloud_texture_stream" default="RS2_STREAM_COLOR"/>
<arg name="pointcloud_texture_index" default="0"/>
<arg name="enable_sync" default="true"/>
<arg name="align_depth" default="true"/>
<arg name="publish_tf" default="true"/>
<arg name="tf_publish_rate" default="0"/>
<arg name="filters" default=""/>
<arg name="clip_distance" default="-2"/>
<arg name="linear_accel_cov" default="0.01"/>
<arg name="initial_reset" default="false"/>
<arg name="unite_imu_method" default="linear_interpolation"/>
<arg name="topic_odom_in" default="odom_in"/>
<arg name="calib_odom_file" default=""/>
<arg name="publish_odom_tf" default="true"/>
<arg name="allow_no_texture_points" default="false"/>
<arg name="emitter_enable" default="false"/>
<!-- rosparam set /camera/stereo_module/emitter_enabled false -->
<rosparam>
/camera/stereo_module/emitter_enabled: 0
</rosparam>
<rosparam if="$(arg emitter_enable)">
/camera/stereo_module/emitter_enabled: 1
</rosparam>
<group ns="$(arg camera)">
<include file="$(find realsense2_camera)/launch/includes/nodelet.launch.xml">
<arg name="tf_prefix" value="$(arg tf_prefix)"/>
<arg name="external_manager" value="$(arg external_manager)"/>
<arg name="manager" value="$(arg manager)"/>
<arg name="serial_no" value="$(arg serial_no)"/>
<arg name="usb_port_id" value="$(arg usb_port_id)"/>
<arg name="device_type" value="$(arg device_type)"/>
<arg name="json_file_path" value="$(arg json_file_path)"/>
<arg name="enable_pointcloud" value="$(arg enable_pointcloud)"/>
<arg name="pointcloud_texture_stream" value="$(arg pointcloud_texture_stream)"/>
<arg name="pointcloud_texture_index" value="$(arg pointcloud_texture_index)"/>
<arg name="enable_sync" value="$(arg enable_sync)"/>
<arg name="align_depth" value="$(arg align_depth)"/>
<arg name="fisheye_width" value="$(arg fisheye_width)"/>
<arg name="fisheye_height" value="$(arg fisheye_height)"/>
<arg name="enable_fisheye" value="$(arg enable_fisheye)"/>
<arg name="depth_width" value="$(arg depth_width)"/>
<arg name="depth_height" value="$(arg depth_height)"/>
<arg name="enable_depth" value="$(arg enable_depth)"/>
<arg name="color_width" value="$(arg color_width)"/>
<arg name="color_height" value="$(arg color_height)"/>
<arg name="enable_color" value="$(arg enable_color)"/>
<arg name="infra_width" value="$(arg infra_width)"/>
<arg name="infra_height" value="$(arg infra_height)"/>
<arg name="enable_infra1" value="$(arg enable_infra1)"/>
<arg name="enable_infra2" value="$(arg enable_infra2)"/>
<arg name="fisheye_fps" value="$(arg fisheye_fps)"/>
<arg name="depth_fps" value="$(arg depth_fps)"/>
<arg name="infra_fps" value="$(arg infra_fps)"/>
<arg name="color_fps" value="$(arg color_fps)"/>
<arg name="gyro_fps" value="$(arg gyro_fps)"/>
<arg name="accel_fps" value="$(arg accel_fps)"/>
<arg name="enable_gyro" value="$(arg enable_gyro)"/>
<arg name="enable_accel" value="$(arg enable_accel)"/>
<arg name="publish_tf" value="$(arg publish_tf)"/>
<arg name="tf_publish_rate" value="$(arg tf_publish_rate)"/>
<arg name="filters" value="$(arg filters)"/>
<arg name="clip_distance" value="$(arg clip_distance)"/>
<arg name="linear_accel_cov" value="$(arg linear_accel_cov)"/>
<arg name="initial_reset" value="$(arg initial_reset)"/>
<arg name="unite_imu_method" value="$(arg unite_imu_method)"/>
<arg name="topic_odom_in" value="$(arg topic_odom_in)"/>
<arg name="calib_odom_file" value="$(arg calib_odom_file)"/>
<arg name="publish_odom_tf" value="$(arg publish_odom_tf)"/>
<arg name="allow_no_texture_points" value="$(arg allow_no_texture_points)"/>
</include>
</group>
</launch>
2.修改外参
打开~/catkin_ws/src/VINS-Fusion/config/realsense_d435i/
路径下 的realsense_stereo_imu_config.yaml
%YAML:1.0
#common parameters
#support: 1 imu 1 cam; 1 imu 2 cam: 2 cam;
imu: 1
num_of_cam: 2
imu_topic: "/camera/imu"
image0_topic: "/camera/infra1/image_rect_raw"
image1_topic: "/camera/infra2/image_rect_raw"
output_path: "/home/dji/output/"
cam0_calib: "left.yaml"
cam1_calib: "right.yaml"
image_width: 640
image_height: 480
# IMU和Camera之间的外部参数。
estimate_extrinsic : 1 # 0 有一个准确的外在参数。我们将信任以下 imu^R_cam,imu^T_cam,不要更改它。
# 1 初步猜测外在参数。我们将围绕您最初的猜测进行优化。
body_T_cam0: !!opencv-matrix
rows: 4
cols: 4
dt: d
data: [ 1, 0, 0, -0.00552,
0, 1, 0, 0.0051,
0, 0, 1, 0.01174,
0, 0, 0, 1 ]
body_T_cam1: !!opencv-matrix
rows: 4
cols: 4
dt: d
data: [ 1, 0, 0, 0.0446571,
0, 1, 0, 0.0051,
0, 0, 1, 0.01174,
0, 0, 0, 1 ]
#多线程支持
multiple_thread: 1
#特征跟踪器参数
max_cnt : 150 #特征跟踪中的最大特征数
min_dist : 30 #两个特征之间的最小距离
freq : 10 #发布跟踪结果的频率 (Hz)。至少 10Hz 以获得良好的估计。如果设置为 0,则频率将与原始图像相同
F_threshold : 1.0 # ransac 阈值(像素)
show_track : 0 # 将跟踪图像发布为主题
flow_back : 1 #执行正向和反向光流以提高特征跟踪精度
#优化参数
max_solver_time : 0.04 #最大求解器迭代时间(毫秒),保证实时
max_num_iterations : 8 #最大求解器迭代次数,以保证实时
keyframe_parallax : 10.0 #关键帧选择阈值(像素)
# imu 参数 你提供的参数越准确,性能越好
acc_n : 0.1 #加速度计测量噪声标准偏差。#0.2 0.04
gyr_n : 0.01 #陀螺仪测量噪声标准偏差。#0.05 0.004
acc_w : 0.001 #加速度计偏差随机工作噪声标准偏差。#0.002
gyr_w : 0.0001 #陀螺仪偏差随机工作噪声标准偏差。#4.0e-5
g_norm : 9.805 #重力大小
#非同步参数
estimate_td : 1 #在线估计相机和imu之间的时间偏移
td : 0.00 #时间偏移的初始值。单位。读取图像时钟 + td = 真实图像时钟(IMU 时钟)
#闭环参数
load_previous_pose_graph : 0 #加载并重用之前的位姿图;从“pose_graph_save_path”加载
pose_graph_save_path : " /home/dji/output/pose_graph/ " #保存和加载路径
save_image : 0 # 将图像保存在姿势图中,以便可视化;您可以通过设置0来关闭此功能
上面的参数可以套用,但是时间长了还是会飘走,建议有条件还是标定一下相机吧,相机参数文件标定参考Ubuntu 18.04 ———(Intel RealSense D435i)标定后结果用于VINS-Fusion_@曾记否的博客-CSDN博客
注意修改显示image-track
show_track = 1 # 将跟踪图像发布为主题
修改开启回环检测:
save_image: 1 # 将图像保存在姿势图中,以便可视化;您可以通过设置0来关闭此功能
3.修改内参
首先启动相机
roslaunch realsense2_camera rs_camera_vins.launch
查看相机话题
rostopic list
/camera/depth/camera_info为深度相机的参数话题
rostopic echo /camera/depth/camera_info
其中
K: [390.0747375488281, 0.0, 322.1644592285156, 0.0, 390.0747375488281, 235.8865509033203, 0.0, 0.0, 1.0]为相机内参,每个相机内参都不一样,别无脑复制别人的,不然模型效果很差。
390.0747375488281为fx
390.0747375488281为fy
322.1644592285156为cx
235.8865509033203为cy
复制后修改~/catkin_ws/src/VINS-Fusion-master/config/realsense_d435i目录下的
left.yaml和right.yaml参数一样
三,使用Vins-fusion建立Octomap
1.链接D435i启动vins连接相机
roslaunch realsense2_camera rs_camera_vins.launch
2.连接相机参数
rosrun vins vins_node ~/catkin_ws/src/VINS-Fusion-master/config/realsense_d435i/realsense_stereo_imu_config.yaml
3.开启回环检测
rosrun loop_fusion loop_fusion_node ~/catkin_ws/src/VINS-Fusion-master/config/realsense_d435i/realsense_stereo_imu_config.yaml
4.启动vins rviz
roslaunch vins vins_rviz.launch
vins生成的点云如图所示,可以查一下生成点云的话题名
rostopic list
可以看到vins和相机发布的话题,其中的/vins_estimator/point_cloud即是我们需要的点云话题。但是由于我们使用的点云转octomap需要的是pointcloud2,所以我们需要先把pointcloud转换为pointcloud2。
发布pointcloud2的源码地址GitHub - 1332927388/pcl2octomap
point_cloud_converter.launch的内容为
<launch>
<node pkg="point_cloud_converter" name="point_cloud_converter" type="point_cloud_converter_node" >
<remap from="points_in" to="/vins_estimator/point_cloud"/>
<remap from="points2_out" to="/points" />
<!--
<remap from="points2_in" to="velodyne_points"/>
<remap from="points_out" to="velodyne_points" />
-->
</node>
</launch>
作用是将pointcloud转换为pointcloud2。
编辑:~/catkin_ws/src/octomap_mapping-kinetic-devel/octomap_server/launch中的octomap_mapping.launch,将两个launch文件合二为一
<!--
Example launch file for octomap_server mapping:
Listens to incoming PointCloud2 data and incrementally builds an octomap.
The data is sent out in different representations.
Copy this file into your workspace and adjust as needed, see
www.ros.org/wiki/octomap_server for details
-->
<launch>
<node pkg="point_cloud_converter" name="point_cloud_converter" type="point_cloud_converter_node" >
<remap from="points_in" to="/vins_estimator/point_cloud"/>
<remap from="points2_out" to="/points" />
<!--
<remap from="points2_in" to="velodyne_points"/>
<remap from="points_out" to="velodyne_points" />
-->
</node>
<node pkg="octomap_server" type="octomap_server_node" name="octomap_server">
<param name="resolution" value="0.05" />
<!-- fixed map frame (set to 'map' if SLAM or localization running!) -->
<param name="frame_id" type="string" value="world" />
<!-- maximum range to integrate (speedup!) -->
<param name="sensor_model/max_range" value="5.0" />
<!-- data source to integrate (PointCloud2) -->
<remap from="cloud_in" to="points" />
</node>
</launch>
启动octomap_server
roslaunch octomap_server octomap_mapping.launch
最后在rviz 中添加一个 “OccupancyGrid” 模块,设置 topic 为"/octomap_full",即可以得到如下结果:
启动 octomap_server 节点后,可以使用它提供的地图保存服务
保存压缩的二进制存储格式地图:
rosrun octomap_server octomap_saver 2022.bt
保存一个完整的概率八叉树地图:
rosrun octomap_server octomap_saver -f 2022.ot
保存一个二维栅格地图:
rosrun map_server map_server map:=/projected_map -f mapname
安装Octovis可视化工具可以查看八叉树模型效果
sudo apt-get install octovis
查看ocotmap.bt八叉树地图文件
octovis 2022.bt
可以按高程显示
可以看到如果直接使用vins的点云转化八叉树模型,没有滤波效果还是很差,噪点会让空中也布满模型,导致转换的八叉树模型很杂乱,下面介绍另一种方法
四,使用 DenseSurfelMapping建立Octomap
源码地址:GitHub - HKUST-Aerial-Robotics/DenseSurfelMapping at VINS-supported
下载源码到工作空间,并使用catkin_make编译,和Vins-fusion步骤一样
cd ~/catkin_ws/src
git clone https://github.com/HKUST-Aerial-Robotics/DenseSurfelMapping/tree/VINS-supported
cd ..
catkin_make
**1.然后链接D435i启动vins连接相机 **
roslaunch realsense2_camera rs_camera_vins.launch
** 2.连接相机参数**
rosrun vins vins_node ~/catkin_ws/src/VINS-Fusion-master/config/realsense_d435i/realsense_stereo_imu_config.yaml
**3.开启回环检测 **
rosrun loop_fusion loop_fusion_node ~/catkin_ws/src/VINS-Fusion-master/config/realsense_d435i/realsense_stereo_imu_config.yaml
4.启动 Surfel Fusion
roslaunch surfel_fusion vins_realsense.launch
拿起相机扫一扫周围,转一圈形成闭环,观察模型效果,是否错位,如果错位,调整相机参数。
数据来源:西安大地测绘股份有限公司
数据来源:西安大地测绘股份有限公司
此生成彩色点云数据,topic为 /surfel_fusion/rgb_pointcloud
修改编辑:~/catkin_ws/src/octomap_mapping-kinetic-devel/octomap_server/launch中的octomap_mapping.launch中的point
<!-- data source to integrate (PointCloud2) -->
<remap from="cloud_in" to="points" />
point改为/surfel_fusion/rgb_pointcloud
<!--
Example launch file for octomap_server mapping:
Listens to incoming PointCloud2 data and incrementally builds an octomap.
The data is sent out in different representations.
Copy this file into your workspace and adjust as needed, see
www.ros.org/wiki/octomap_server for details
-->
<launch>
<node pkg="point_cloud_converter" name="point_cloud_converter" type="point_cloud_converter_node" >
<remap from="points_in" to="/vins_estimator/point_cloud"/>
<remap from="points2_out" to="/points" />
<!--
<remap from="points2_in" to="velodyne_points"/>
<remap from="points_out" to="velodyne_points" />
-->
</node>
<node pkg="octomap_server" type="octomap_server_node" name="octomap_server">
<param name="resolution" value="0.05" />
<!-- fixed map frame (set to 'map' if SLAM or localization running!) -->
<param name="frame_id" type="string" value="world" />
<!-- maximum range to integrate (speedup!) -->
<param name="sensor_model/max_range" value="5.0" />
<!-- data source to integrate (PointCloud2) -->
<remap from="cloud_in" to="/surfel_fusion/rgb_pointcloud" />
</node>
</launch>
5.运行Octomap
roslaunch octomap_server octomap_mapping.launch
最后在rviz 中添加一个 “OccupancyGrid” 模块. 设置 topic 为"/octomap_full",即可以得到如下结果:
数据来源:西安大地测绘股份有限公司
栅格模型和彩色点云数据一起显示,如果觉得卡的话可以只显示栅格模型
数据来源:西安大地测绘股份有限公司
6.同样,可以使用命令保存二进制成果
rosrun octomap_server octomap_saver 2022.bt
数据来源:西安大地测绘股份有限公司
数据来源:西安大地测绘股份有限公司
数据来源:西安大地测绘股份有限公司
**完结 **
版权归原作者 zsy00100 所有, 如有侵权,请联系我们删除。