OrinNX部署运行ROS2版本的vinsfusiongpu步骤整理

OrinNX上部署运行ROS2版本的vinsfusiongpu 20240429

OrinNX部署运行ROS2版本的vinsfusiongpu步骤整理 

OrinNX ubuntu20.04上前提已经装好ros foxy
ros2版本的vinsfusiongpu仓库为:https://github.com/zinuok/VINS-Fusion-ROS2

装opencv3.4.1+opencv_contrib3.4.1

新建一个opencv341文件夹,文件夹内打开终端运行下面命令,下载opencv和opencv_contrib

git clone -b 3.4.1 https://github.com/opencv/opencv.git
git clone -b 3.4.1 https://github.com/opencv/opencv_contrib.git

在/opencv341/opencv/文件夹下新建一个build文件夹,并在build文件夹下打开一个终端运行下面命令
注意不同平台CUDA_ARCH_BIN的值不同,比如Xavier NX上CUDA_ARCH_BIN=7.2

cmake -D CMAKE_BUILD_TYPE=RELEASE \
        -D CMAKE_INSTALL_PREFIX=/usr/local \
        -D WITH_CUDA=ON \
        -D CUDA_ARCH_BIN=8.7 \
        -D CUDA_ARCH_PTX="" \
        -D ENABLE_FAST_MATH=ON \
        -D CUDA_FAST_MATH=ON \
        -D WITH_CUBLAS=ON \
        -D WITH_LIBV4L=ON \
        -D WITH_GSTREAMER=ON \
        -D WITH_GSTREAMER_0_10=OFF \
        -D WITH_QT=ON \
        -D WITH_OPENGL=ON \
        -D CUDA_NVCC_FLAGS="--expt-relaxed-constexpr" \
        -D CUDA_nppicom_LIBRARY=stdc++ \
        -D WITH_TBB=ON \
        -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
         ../
make -j4
sudo make install

打开jtop看到opencv版本显示为这样代表OK,注意with CUDA为yes

输入图片说明

装ceres 2.1.0

sudo apt-get install liblapack-dev libsuitesparse-dev libcxsparse3 libgflags-dev libgoogle-glog-dev libeigen3-dev libgtest-dev

git clone -b 2.1.0 https://github.com/ceres-solver/ceres-solver.git
cd ceres-solver/
mkdir build
cd build
cmake ..
make
sudo make install

源码编译安装ros2的cv_bridge

mkdir cv_bridge_ros2_ws/src
cd cv_bridge_ros2_ws
cd src
git clone https://github.com/ros-perception/vision_opencv.git -b foxy

把cv_bridge功能包里的cmakelists(/cv_bridge_ros2_ws/src/vision_opencv/cv_bridge/CMakeLists.txt)里这里的OpenCV 4改为OpenCV 3

输入图片说明

输入图片说明

改完后保存编译

cd ..
colcon build

部署ros2的vins fusion gpu

cd $(PATH_TO_YOUR_ROS2_WS)/src
git clone https://github.com/zinuok/VINS-Fusion-ROS2

在ros2的vins fusion的三个用到opencv的功能包(vins loop_fusion camera_models)里面的cmakelist里面加上这两句,这么做是确保其链接的是opencv3.4.1

set(OpenCV_DIR "your-path/opencv-x.x.x/build")
set(cv_bridge_DIR "your-path/cv_bridge_ros2_ws/install/cv_bridge/share/cv_bridge/cmake")

比如我的是加这两句

set(OpenCV_DIR "/home/nvidia/opencv341/opencv/build")
set(cv_bridge_DIR "/home/nvidia/cv_bridge_ros2_ws/install/cv_bridge/share/cv_bridge/cmake")

输入图片说明


 

输入图片说明

输入图片说明

改完保存编译

cd ..
colcon build --symlink-install && source ./install/setup.bash && source ./install/local_setup.bash

此时可以在config文件夹下放入自己对应的比如D435i的双目imu的标定参数文件,此操作同普通vins-fusion一样。

启动命令示例,后面跟实际路径下的yaml文件

run vins vins_node ***/realsense_stereo_imu_config.yaml

如果要GPU加速,yaml文件里面记得加上这三句,这三个参数都置为1。

# GPU acceleration
use_gpu         : 1
use_gpu_acc_flow: 1
use_gpu_ceres   : 1

官方仓库给的启动rviz的命令是,这样启动后rviz需要手动修改坐标系添加话题,比较麻烦,而且作者说 Rviz config cannot be saved due to some issue.. still fixing

ros2 launch vins vins_rviz.launch.xml

个人建议用这个命令启动rviz,配置可以更改保存。

ros2 run rviz2 rviz2 -d config.rviz

把ros1的bag包转为ros2的(不基于bag包跑vins可以跳过这步)

推荐使用一个叫 rosbags 的工具进行转换,它不依赖于 ROS1 和 ROS2 环境,可以非常快速地实现 .bag 和 .db3 格式的相互转换。

rosbags 是一个 Python 编写的工具,可通过 pip 进行安装:

pip install rosbags

以后如果需要更新 rosbags,可以执行下面命令:

pip install --upgrade rosbags

安装好之后,系统会增加一个 rosbags-convert 命令,转换方法非常简单。例如:

将 ROS2 的 rosbag 转换为 ROS1 格式:

rosbags-convert <your-ros2-bag>

将 ROS1 的 rosbag 转换为 ROS2 格式:

rosbags-convert <your-ros1-bag>

这个命令运行完之后会在bag包相同目录下生成一个和bag包名称相同的文件夹,里面是一个.db3文件和一个yaml文件

输入图片说明

播放ros2的bag包用命令

ros2 bag play *****.db3

装 realsense 的ros2功能包

sudo apt-get install ros-foxy-realsense2-camera

安装好后,可以在/opt/ros/foxy/share/realsense2_camera/launch目录下,找到rs_launch.py,修改rs_launch.py使得其启动D435i可以发出30hz的分辨率640*480双目灰度图话题和200hz的/camera/imu话题,给vins节点订阅使用。
修改rs_launch.py前需要先赋予权限

sudo chmod 777 rs_launch.py

修改后的可以发出30hz的分辨率640*480双目灰度图话题和200hz的/camera/imu话题和rs_launch.py如下
目前没有实现通过rs_launch.py关闭红外光点,所以需要物理手段也就是通过胶带把发射红外光点的地方遮挡住,避免影响灰度图,进而影响vins。

# License: Apache 2.0. See LICENSE file in root directory.
# Copyright(c) 2022 Intel Corporation. All Rights Reserved.

"""Launch realsense2_camera node."""
import os
from launch import LaunchDescription
from ament_index_python.packages import get_package_share_directory
import launch_ros.actions
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch.conditions import IfCondition


configurable_parameters = [{'name': 'camera_name',                  'default': 'camera', 'description': 'camera unique name'},
                           {'name': 'serial_no',                    'default': "''", 'description': 'choose device by serial number'},
                           {'name': 'usb_port_id',                  'default': "''", 'description': 'choose device by usb port id'},
                           {'name': 'device_type',                  'default': "''", 'description': 'choose device by type'},
                           {'name': 'config_file',                  'default': "''", 'description': 'yaml config file'},
                           {'name': 'unite_imu_method',             'default': "2", 'description': '[0-None, 1-copy, 2-linear_interpolation]'},
                           {'name': 'json_file_path',               'default': "''", 'description': 'allows advanced configuration'},
                           {'name': 'log_level',                    'default': 'info', 'description': 'debug log level [DEBUG|INFO|WARN|ERROR|FATAL]'},
                           {'name': 'output',                       'default': 'screen', 'description': 'pipe node output [screen|log]'},
                           {'name': 'depth_module.profile',         'default': '640,480,30', 'description': 'depth module profile'},                           
                           {'name': 'enable_depth',                 'default': 'false', 'description': 'enable depth stream'},
                           {'name': 'rgb_camera.profile',           'default': '0,0,0', 'description': 'color image width'},
                           {'name': 'enable_color',                 'default': 'false', 'description': 'enable color stream'},
                           {'name': 'enable_infra1',                'default': 'true', 'description': 'enable infra1 stream'},
                           {'name': 'enable_infra2',                'default': 'true', 'description': 'enable infra2 stream'},
                           {'name': 'infra_rgb',                    'default': 'false', 'description': 'enable infra2 stream'},
                           {'name': 'tracking_module.profile',      'default': '0,0,0', 'description': 'fisheye width'},
                           {'name': 'enable_fisheye1',              'default': 'true', 'description': 'enable fisheye1 stream'},
                           {'name': 'enable_fisheye2',              'default': 'true', 'description': 'enable fisheye2 stream'},
                           {'name': 'enable_confidence',            'default': 'true', 'description': 'enable depth stream'},
                           {'name': 'gyro_fps',                     'default': '0', 'description': "''"},                           
                           {'name': 'accel_fps',                    'default': '0', 'description': "''"},                           
                           {'name': 'enable_gyro',                  'default': 'true', 'description': "''"},                           
                           {'name': 'enable_accel',                 'default': 'true', 'description': "''"},                           
                           {'name': 'enable_pose',                  'default': 'true', 'description': "''"},                           
                           {'name': 'pose_fps',                     'default': '200', 'description': "''"},                           
                           {'name': 'pointcloud.enable',            'default': 'false', 'description': ''}, 
                           {'name': 'pointcloud.stream_filter',     'default': '2', 'description': 'texture stream for pointcloud'},
                           {'name': 'pointcloud.stream_index_filter','default': '0', 'description': 'texture stream index for pointcloud'},
                           {'name': 'enable_sync',                  'default': 'true', 'description': "''"},                           
                           {'name': 'align_depth.enable',           'default': 'false', 'description': "''"},                           
                           {'name': 'colorizer.enable',             'default': 'false', 'description': "''"},
                           {'name': 'clip_distance',                'default': '-2.', 'description': "''"},                           
                           {'name': 'linear_accel_cov',             'default': '0.01', 'description': "''"},                           
                           {'name': 'initial_reset',                'default': 'false', 'description': "''"},                           
                           {'name': 'allow_no_texture_points',      'default': 'false', 'description': "''"},                           
                           {'name': 'ordered_pc',                   'default': 'false', 'description': ''},
                           {'name': 'calib_odom_file',              'default': "''", 'description': "''"},
                           {'name': 'topic_odom_in',                'default': "''", 'description': 'topic for T265 wheel odometry'},
                           {'name': 'tf_publish_rate',              'default': '0.0', 'description': 'Rate of publishing static_tf'},
                           {'name': 'diagnostics_period',           'default': '0.0', 'description': 'Rate of publishing diagnostics. 0=Disabled'},
                           {'name': 'decimation_filter.enable',     'default': 'false', 'description': 'Rate of publishing static_tf'},
                           {'name': 'rosbag_filename',              'default': "''", 'description': 'A realsense bagfile to run from as a device'},
                           {'name': 'depth_module.exposure.1',     'default': '7500', 'description': 'Initial value for hdr_merge filter'},
                           {'name': 'depth_module.gain.1',         'default': '16', 'description': 'Initial value for hdr_merge filter'},
                           {'name': 'depth_module.exposure.2',     'default': '1', 'description': 'Initial value for hdr_merge filter'},
                           {'name': 'depth_module.gain.2',         'default': '16', 'description': 'Initial value for hdr_merge filter'},
                           {'name': 'wait_for_device_timeout',      'default': '-1.', 'description': 'Timeout for waiting for device to connect (Seconds)'},
                           {'name': 'reconnect_timeout',            'default': '6.', 'description': 'Timeout(seconds) between consequtive reconnection attempts'},
                          ]

def declare_configurable_parameters(parameters):
    return [DeclareLaunchArgument(param['name'], default_value=param['default'], description=param['description']) for param in parameters]

def set_configurable_parameters(parameters):
    return dict([(param['name'], LaunchConfiguration(param['name'])) for param in parameters])

def generate_launch_description():
    log_level = 'info'
    if (os.getenv('ROS_DISTRO') == "dashing") or (os.getenv('ROS_DISTRO') == "eloquent"):
        return LaunchDescription(declare_configurable_parameters(configurable_parameters) + [
            # Realsense
            launch_ros.actions.Node(
                condition=IfCondition(PythonExpression([LaunchConfiguration('config_file'), " == ''"])),
                package='realsense2_camera',
                node_namespace=LaunchConfiguration("camera_name"),
                node_name=LaunchConfiguration("camera_name"),
                node_executable='realsense2_camera_node',
                prefix=['stdbuf -o L'],
                parameters=[set_configurable_parameters(configurable_parameters)
                            ],
                output='screen',
                arguments=['--ros-args', '--log-level', LaunchConfiguration('log_level')],
                ),
            launch_ros.actions.Node(
                condition=IfCondition(PythonExpression([LaunchConfiguration('config_file'), " != ''"])),
                package='realsense2_camera',
                node_namespace=LaunchConfiguration("camera_name"),
                node_name=LaunchConfiguration("camera_name"),
                node_executable='realsense2_camera_node',
                prefix=['stdbuf -o L'],
                parameters=[set_configurable_parameters(configurable_parameters)
                            , PythonExpression([LaunchConfiguration("config_file")])
                            ],
                output='screen',
                arguments=['--ros-args', '--log-level', LaunchConfiguration('log_level')],
                ),
            ])
    else:
        return LaunchDescription(declare_configurable_parameters(configurable_parameters) + [
            # Realsense
            launch_ros.actions.Node(
                condition=IfCondition(PythonExpression([LaunchConfiguration('config_file'), " == ''"])),
                package='realsense2_camera',
                namespace=LaunchConfiguration("camera_name"),
                name=LaunchConfiguration("camera_name"),
                executable='realsense2_camera_node',
                parameters=[set_configurable_parameters(configurable_parameters)
                            ],
                output='screen',
                arguments=['--ros-args', '--log-level', LaunchConfiguration('log_level')],
                emulate_tty=True,
                ),
            launch_ros.actions.Node(
                condition=IfCondition(PythonExpression([LaunchConfiguration('config_file'), " != ''"])),
                package='realsense2_camera',
                namespace=LaunchConfiguration("camera_name"),
                name=LaunchConfiguration("camera_name"),
                executable='realsense2_camera_node',
                parameters=[set_configurable_parameters(configurable_parameters)
                            , PythonExpression([LaunchConfiguration("config_file")])
                            ],
                output='screen',
                arguments=['--ros-args', '--log-level', LaunchConfiguration('log_level')],
                emulate_tty=True,
                ),
        ])

用rs_launch.py启动D435i的命令如下

ros2 launch realsense2_camera rs_launch.py

OrinNX上跑ROS2版本vinsfusiongpu启动命令示例

运行前可以先把OrinNX的CPU频率和GPU频率提到最大,用下面这两个脚本

sudo sh max_cpu_freq.sh
sudo sh max_gpu_freq.sh

max_cpu_freq.sh内如如下

# Set CPU frequency to maximum
sudo echo "***** Set CPU frequency to maximum *****"
sudo echo "- Previous frequency of cores"
sudo cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq
sudo echo "- Previous CPU governor of cores"
sudo cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
sudo echo

sudo echo "- The list of available frequencies"
sudo cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies
sudo echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
sudo echo 1971200 > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed
sudo echo 115200 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
sudo echo 1971200 > /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq

sudo echo
sudo echo "- Changed frequency of cores"
sudo cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq
sudo echo "- Changed CPU governor of cores"
sudo cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor

max_gpu_freq.sh内容如下

#!/bin/bash
# Set GPU frequency to maximum
sudo echo "***** Set GPU frequency to maximum *****"
sudo echo "- Previous frequency of GPU"
sudo cat /sys/devices/17000000.ga10b/devfreq/17000000.ga10b/cur_freq
sudo echo "- The list of available frequencies"
sudo cat /sys/devices/17000000.ga10b/devfreq/17000000.ga10b/available_frequencies
sudo echo 765000000 > /sys/devices/17000000.ga10b/devfreq/17000000.ga10b/max_freq
sudo echo 765000000 > /sys/devices/17000000.ga10b/devfreq/17000000.ga10b/min_freq
sudo echo "- Changed frequency of GPU"
sudo cat /sys/devices/17000000.ga10b/devfreq/17000000.ga10b/cur_freq

基于bag包跑ROS2的vinsfusiongpu总的启动命令sh脚本示例

gnome-terminal --window -e 'bash -c " source ~/vins_ros2_ws/install/setup.bash;ros2 run vins vins_node /home/nvidia/vins_ros2_ws/src/VINS-Fusion-ROS2/config/euroc/euroc_stereo_imu_config.yaml; exec bash"' \
--tab -e 'bash -c "sleep 10;ros2 run rviz2 rviz2 -d /home/nvidia/vins_ros2_ws/src/VINS-Fusion-ROS2/vins/launch/config.rviz; exec bash"' \
--tab -e 'bash -c "sleep 16; ros2 bag play /home/nvidia/MH_01_easy/MH_01_easy.db3; exec bash"' \
--window -e 'bash -c "sleep 25; ros2 topic echo /odometry; exec bash"' \

基于D435i跑ROS2的vinsfusiongpu总的启动命令sh脚本示例
注意D435i插在OrinNX USB3.0的口上,而且用胶带把发红外光点的位置遮挡住

gnome-terminal --window -e 'bash -c " source ~/vins_ros2_ws/install/setup.bash;ros2 run vins vins_node /home/nvidia/vins_ros2_ws/src/VINS-Fusion-ROS2/config/realsense_d435i/realsense_stereo_imu_config.yaml; exec bash"' \
--tab -e 'bash -c "sleep 10;ros2 run rviz2 rviz2 -d /home/nvidia/vins_ros2_ws/src/VINS-Fusion-ROS2/vins/launch/config.rviz; exec bash"' \
--tab -e 'bash -c "sleep 16;ros2 launch realsense2_camera rs_launch_maxi.py ; exec bash"' \
--window -e 'bash -c "sleep 25; ros2 topic echo /odometry; exec bash"' \

  • 70
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值