初始位姿偏移问题

  • 需在对应配置文件中配置
    1
    2
    3
    4
    <!-- 设置初始位置 -->
    <param name="initial_pose_x" value="0.0"/>
    <param name="initial_pose_y" value="0.0"/>
    <param name="initial_pose_a" value="0.0"/>

Reference

问题描述

在ROS Noetic中仿真两轮差速小车时,出现以下错误信息:

1
2
3
4
Warning: TF_REPEATED_DATA ignoring data with redundant timestamp for frame omni_b_link (parent car_base_link) at time 1488.072000 according to authority unknown_publisher
Warning: TF_REPEATED_DATA ignoring data with redundant timestamp for frame omni_f_link (parent car_base_link) at time 1488.072000 according to authority unknown_publisher
Warning: TF_REPEATED_DATA ignoring data with redundant timestamp for frame wheel_l_link (parent car_base_link) at time 1488.072000 according to authority unknown_publisher
Warning: TF_REPEATED_DATA ignoring data with redundant timestamp for frame wheel_r_link (parent car_base_link) at time 1488.072000 according to authority unknown_publisher

同时发现:

  • /gazebo发布odom到base_footprint的频率为101.099Hz
  • /robot_state_publisher发布后续tf的频率为1000.00Hz

问题根本原因

TF_REPEATED_DATA错误原因

该错误表明有多个发布者在相同时间戳为相同的tf变换发布数据,导致数据冲突。具体原因:

  1. 多个控制器冲突gazebo_ros_diff_drive插件和gazebo_ros_control插件同时控制相同的关节
  2. 重复的tf发布:两个插件都在发布相同关节的tf变换
  3. 频率不匹配:不同发布者的更新频率不一致

Transmission配置的作用

Transmission是ROS控制系统中定义执行器与关节连接关系的配置:

1
2
3
4
5
6
7
8
9
10
<transmission name="wheel_l_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="wheel_l_joint">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="wheel_l_motor">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>

工作流程

1
2
命令输入 → 控制器 → 传动系统 → 执行器 → 关节 → 链接运动
cmd_vel → diff_drive → transmission → motor → joint → link

解决方案

方案一:使用gazebo_ros_diff_drive(推荐用于简单差分驱动)

1. 删除gazebo_ros_control插件

在主URDF文件中注释或删除:

1
2
3
4
5
6
7
8
9
10
11
<!-- 删除这部分配置 -->
<!--
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/zeus_s1</robotNamespace>
<robotParam>robot_description</robotParam>
<robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
<legacyModeNS>true</legacyModeNS>
</plugin>
</gazebo>
-->

2. 优化gazebo_ros_diff_drive配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<gazebo>
<plugin filename="libgazebo_ros_diff_drive.so" name="differential_drive_controller">
<robotNamespace>/</robotNamespace>
<rosDebugLevel>Error</rosDebugLevel>
<publishWheelTF>false</publishWheelTF>
<publishTf>1</publishTf>
<publishOdomTF>1</publishOdomTF>
<odometrySource>world</odometrySource>
<publishWheelJointState>true</publishWheelJointState> <!-- 改为true -->
<alwaysOn>true</alwaysOn>
<updateRate>50.0</updateRate> <!-- 与robot_state_publisher同步 -->
<legacyMode>true</legacyMode>
<leftJoint>wheel_l_joint</leftJoint>
<rightJoint>wheel_r_joint</rightJoint>
<wheelSeparation>0.33</wheelSeparation>
<wheelDiameter>0.125</wheelDiameter>
<broadcastTF>1</broadcastTF>
<wheelTorque>6.5</wheelTorque>
<wheelAcceleration>0.5</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<odometryFrame>odom</odometryFrame>
<odometryTopic>odom</odometryTopic>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo>

3. 删除wheel的transmission配置

在wheel_125mm.xacro中注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 删除或注释掉wheel的transmission -->
<!--
<transmission name="${wheel_prefix}_wheel_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${wheel_prefix}_joint">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="${wheel_prefix}_wheel_motor">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
-->

4. 调整robot_state_publisher频率

在launch文件中:

1
2
3
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen">
<param name="publish_frequency" type="double" value="50.0" />
</node>

方案二:使用gazebo_ros_control(适用于复杂控制需求)

1. 删除gazebo_ros_diff_drive插件

2. 修改gazebo_ros_control配置

1
2
3
4
5
6
7
8
9
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/</robotNamespace> <!-- 移除zeus_s1 -->
<robotParam>robot_description</robotParam>
<robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
<legacyModeNS>true</legacyModeNS>
<updateRate>50.0</updateRate> <!-- 添加更新频率 -->
</plugin>
</gazebo>

3. 修正transmission配置

1
2
3
4
5
6
7
8
9
10
<transmission name="${wheel_prefix}_wheel_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${wheel_prefix}_joint">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="${wheel_prefix}_wheel_motor">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>

4. 添加控制器配置

在launch文件中:

1
2
3
<rosparam file="$(find zeus_s1_description)/config/control.yaml" command="load"/>
<node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
output="screen" args="joint_state_controller diff_drive_controller"/>

control.yaml文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Joint state controller
joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: 50

# Differential drive controller
diff_drive_controller:
type: diff_drive_controller/DiffDriveController
left_wheel: 'wheel_l_joint'
right_wheel: 'wheel_r_joint'
publish_rate: 50
pose_covariance_diagonal: [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0]
twist_covariance_diagonal: [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0]
wheel_separation: 0.33
wheel_radius: 0.0625
base_frame_id: base_footprint
odom_frame_id: odom

调试和验证方法

检查TF发布状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看TF树结构
rosrun tf view_frames
evince frames.pdf

# 监控特定TF变换
rosrun tf tf_monitor odom base_footprint

# 查看TF变换关系
rosrun tf tf_echo odom base_footprint

# 检查当前运行的节点
rosnode list | grep -E "(robot_state_publisher|gazebo)"

# 查看tf话题内容
rostopic echo /tf | grep frame_id

验证关节状态发布

1
2
3
4
5
6
# 查看关节状态话题
rostopic echo /joint_states

# 检查话题发布频率
rostopic hz /joint_states
rostopic hz /tf

最佳实践建议

何时使用Transmission配置

需要使用的场景

  • 复杂控制需求(PID调节、轨迹跟踪)
  • 多种控制模式切换(位置、速度、力矩)
  • 存在机械减速的真实情况
  • 自定义控制器开发
  • 多关节协调控制(如机械臂)

不需要使用的场景

  • 简单差分驱动机器人
  • 固定关节连接
  • 基础仿真演示

频率同步建议

  1. 统一更新频率:将所有相关组件设置为相同频率(推荐50-100Hz)
  2. 避免过高频率:1000Hz通常不必要,会增加计算负担
  3. 渐进调试:从低频率开始,逐步优化

总结

对于简单的差分驱动机器人仿真,推荐使用方案一(gazebo_ros_diff_drive),因为:

  1. 配置简单:无需复杂的transmission和控制器配置
  2. 功能完整:自动处理差分驱动逻辑和里程计
  3. 稳定可靠:减少配置冲突的可能性
  4. 易于调试:问题定位更直接

TF_REPEATED_DATA错误的核心是避免多个发布者控制相同的关节,选择合适的控制架构是关键。

Reference

问题描述

在ROS Noetic中使用rqt_graph保存.dot类型的话题链接情况文件时,出现以下错误:

1
2
3
4
5
zhao@zhao:~/WS/Now/demo_ws$ rosrun rqt_graph rqt_graph 
Traceback (most recent call last):
File "/opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py", line 414, in save_dot
handle.write(self._current_dotcode)
TypeError: write(self, Union[QByteArray, bytes, bytearray]): argument 1 has unexpected type 'str'

问题特征

  • 保存默认名称frames.dot可以正常工作
  • 保存自定义名称LIO-SAM-Debug-Active.dot时出现错误
  • 保存的文件无法正确打开

问题根本原因

1. 编码类型不匹配

在ROS Noetic(Python 3)中,write()方法期望接收字节类型数据(bytesbytearrayQByteArray),但实际接收到的是字符串类型(str)。

根本原因

  • Python 3对字符串和字节的处理更加严格
  • self._current_dotcode是字符串类型
  • 文件句柄的write()方法期望字节类型数据

2. 文件名特殊字符影响

初步怀疑是文件名中的连字符(-)导致的问题,但实际上主要是编码转换问题。

验证方法

1
2
3
4
# 测试不同文件名
frames.dot # ✓ 正常
LIO-SAM-Debug-Active.dot # ✗ 报错
LIO_SAM_Debug_Active.dot # ✗ 同样报错(如果未修复编码问题)

解决方案

方案一:源码修改(推荐)

1. 备份原文件

1
sudo cp /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py.bak

2. 修改源代码

1
sudo nano /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py

3. 找到第414行,进行修改

原代码:

1
handle.write(self._current_dotcode)

修改为:

1
handle.write(self._current_dotcode.encode('utf-8'))

方案二:更完整的修改(避免潜在问题)

如果需要更安全的修改,可以添加类型检查:

1
2
3
4
if isinstance(self._current_dotcode, str):
handle.write(self._current_dotcode.encode('utf-8'))
else:
handle.write(self._current_dotcode)

注意事项

  • 保持原有的缩进格式,避免TabError
  • 如果文件使用制表符缩进,修改时也要使用制表符
  • 如果文件使用空格缩进,修改时也要使用空格

调试过程中的错误

TabError: inconsistent use of tabs and spaces

在修改过程中遇到的缩进错误:

1
TabError: inconsistent use of tabs and spaces in indentation

解决方法

  1. 恢复备份文件
  2. 使用与原文件相同的缩进方式
  3. 检查编辑器设置,确保制表符和空格一致

检查缩进方式

1
2
# 查看文件缩进类型
sed -n '410,420p' /opt/ros/noetic/lib/python3/dist-packages/rqt_graph/ros_graph.py | cat -A

验证修复

测试步骤

1. 基本功能测试

1
rosrun rqt_graph rqt_graph

2. 文件名测试

1
2
3
4
5
# 测试各种文件名
frames.dot # 默认名称
test.dot # 简单名称
LIO_SAM_Debug_Active.dot # 下划线分隔
LIO-SAM-Debug-Active.dot # 连字符分隔

3. 文件内容验证

1
2
3
4
5
# 检查生成的.dot文件内容
cat your_file.dot

# 使用graphviz生成图像
dot -Tpng your_file.dot -o output.png

文件命名建议

虽然编码问题已解决,但为了避免潜在的兼容性问题,建议:

推荐的文件命名规范

1
2
3
4
5
6
7
8
9
# 推荐使用
LIO_SAM_Debug_Active.dot
rqt_graph_output.dot
robot_tf_graph.dot

# 避免使用
LIO-SAM-Debug-Active.dot # 连字符可能在某些系统中引起问题
空格 文件名.dot # 空格需要转义
特殊字符@#$.dot # 特殊字符可能引起解析问题

替代方案

使用命令行工具

如果不想修改源码,可以使用ROS的命令行工具:

1
2
3
4
5
6
7
8
9
# 查看当前节点和话题
rosnode list
rostopic list

# 生成节点图(需要先安装graphviz)
rosrun rqt_graph rqt_graph_cmd --output=/tmp/graph.dot

# 手动转换为图片
dot -Tpng /tmp/graph.dot -o /tmp/graph.png

重新安装

如果修改出现问题,可以重新安装:

1
2
sudo apt update
sudo apt install --reinstall ros-noetic-rqt-graph

问题分析总结

技术原因

  1. Python 2 → Python 3 迁移遗留问题:ROS Noetic使用Python 3,对字符串处理更严格
  2. Qt文件处理接口变化:Qt的文件写入接口期望字节类型数据
  3. 编码转换缺失:源码中未处理字符串到字节的转换

解决思路

  1. 直接修复:在写入前进行编码转换
  2. 类型检查:添加类型判断以提高兼容性
  3. 频率对齐:确保文件操作的一致性

最佳实践建议

开发建议

  1. 备份重要文件:修改系统文件前务必备份
  2. 渐进测试:从简单测试开始,逐步验证功能
  3. 记录修改:详细记录修改内容和原因

系统维护

  1. 定期更新:关注ROS官方更新,此类问题可能在后续版本中修复
  2. 环境一致性:确保开发环境与部署环境一致
  3. 文档记录:将解决方案记录在项目文档中

总结

这个问题的核心是ROS Noetic中Python 3对字符串和字节类型的严格区分。通过简单的编码转换(encode('utf-8'))即可解决。

关键要点

  • 问题出现在字符串到字节的类型转换上
  • 文件名的特殊字符不是主要原因
  • 修改时要注意保持原有的缩进格式
  • 建议在修改前备份原文件

修复后的效果

  • 可以正常保存各种文件名的.dot文件
  • 生成的文件可以正确打开和处理
  • 不再出现TypeError错误

Reference

批量录制 ROS 话题到 Bag 文件

  • 确保目标目录存在

    1
    mkdir -p /full/path/to/data
  • TopicsRecord.txt 文件读取话题列表并录制到指定路径

    1
    rosbag record -o /full/path/to/data/my_bag $(cat TopicsRecord.txt)
  • 检查录制的 bag 文件内容

    1
    rosbag info /full/path/to/data/my_bag_2025-07-04-16-54-00.bag
  • 使用压缩选项录制以减少文件大小

    1
    rosbag record -j -o /full/path/to/data/my_bag $(cat TopicsRecord.txt)
  • 按文件大小分割录制(例如,每 1024 MB 分割)

    1
    rosbag record --split --size=1024 -o /full/path/to/data/my_bag $(cat TopicsRecord.txt)
  • 限制录制时长(例如,60 秒)

    1
    rosbag record --duration=60 -o /full/path/to/data/my_bag $(cat TopicsRecord.txt)

示例 TopicsRecord.txt 文件内容

1
2
3
4
5
6
7
8
/clock
/imu
/tf
/tf_static
/scan
/d435_cam/color/camera_info
/d435_cam/depth/camera_info
/rgbd_lidar_node/rgbd_cloud_info

可视化查看TF关系树

  • 可视化TF树

    1
    rosrun tf view_frames
  • 在当前路径下生成pdf文件

    1
    evince frames.pdf
  • 单独查看两个坐标之间的发布状态

    1
    rosrun tf tf_monitor <source_frame> <target_frame>
  • 查看两个坐标系的变换关系

    1
    rosrun tf tf_echo <source_frame> <target_frame>

Reference

一、换源 Conda 镜像源方法

1. 创建或修改 .condarc 文件

1
nano ~/.condarc

将内容替换为以下格式 (以 清华源 为例):

1
2
3
4
5
6
channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r/
- defaults
show_channel_urls: true

建议保留 defaults 作为备用源


二、常用镜像源列表

镜像站 地址
清华大 https://mirrors.tuna.tsinghua.edu.cn/anaconda/
中科大 https://mirrors.ustc.edu.cn/anaconda/
阿里云 https://mirrors.aliyun.com/anaconda/
华为云 https://repo.huaweicloud.com/anaconda/

以中科大镜像为例:

1
2
3
4
5
6
channels:
- https://mirrors.ustc.edu.cn/anaconda/pkgs/main/
- https://mirrors.ustc.edu.cn/anaconda/pkgs/free/
- https://mirrors.ustc.edu.cn/anaconda/pkgs/r/
- defaults
show_channel_urls: true

三、更新 Conda 缓存

换源后建议清除并更新缓存:

1
2
conda clean -i  # 清除索引缓存
conda update conda

四、配置 Conda Forge 镜像 (可选)

如你使用 conda-forge 频道,也可配置为国内镜像:

1
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge

1、前期准备

  • 下载并解压缩KITTI中关于3D物体的数据集

  • Step 1: 下载数据集
    wget https://s3.eu-central-1.amazonaws.com/avg-kitti/data_object_velodyne.zip
    wget https://s3.eu-central-1.amazonaws.com/avg-kitti/data_object_label_2.zip
    wget https://s3.eu-central-1.amazonaws.com/avg-kitti/data_object_calib.zip

  • Step 2: 解压数据集
    unzip data_object_velodyne.zip -d kitti_dataset
    unzip data_object_label_2.zip -d kitti_dataset
    unzip data_object_calib.zip -d kitti_dataset

2、检查是否已经安装好了训练环境

  • Step 1:配置对应conda环境,安装依赖

    这里我使用的是pointnet++的pytorch版本,参考了下面的仓库:

    1
    https://github.com/yanx27/Pointnet_Pointnet2_pytorch.git
  • Step 2:终端打开到虚拟环境,运行命令测试
    import torch
    输出空行
    torch.cuda.is_available()
    输出:True
    torch.cuda.device_count()
    输出:1
    torch.cuda.device(0)
    输出:<torch.cuda.device object at 0x7fd95fd1fa90>
    torch.cuda.get_device_name(0)
    输出:’NVIDIA GeForce RTX 4060 Laptop GPU’

  • Step3:未完待续

CMake 3.26 和 GCC 11 安装总结

1. 手动从源码安装 CMake 3.26 版本

为了安装 CMake 3.26,可以通过以下步骤手动编译安装:

1.1 下载 CMake 源码

首先,访问 CMake GitHub releases 页面 或者使用 wget 下载 CMake 3.26 的源码包:

1
wget https://github.com/Kitware/CMake/releases/download/v3.26.0/cmake-3.26.0.tar.gz

1.2 解压源码包

下载完成后,解压文件:

1
2
tar -zxvf cmake-3.26.0.tar.gz
cd cmake-3.26.0

1.3 编译并安装

运行以下命令来编译并安装 CMake:

1
2
3
./bootstrap
make
sudo make install

这可能需要一些时间来完成编译。

1.4 验证安装

安装完成后,使用以下命令验证 CMake 是否已成功安装:

1
cmake --version

你应该看到类似以下的输出,表示已安装 CMake 3.26:

1
cmake version 3.26.x

2. 升级到 GCC 11

2.1 安装 GCC 11

为了在 Ubuntu 中安装 GCC 11,你可以通过 APT 包管理器来进行安装。首先更新 APT 包管理器,并安装 GCC 11:

1
2
sudo apt update
sudo apt install gcc-11 g++-11

2.2 切换默认 GCC 版本

安装完成后,你可以使用 update-alternatives 工具来选择使用 GCC 11 作为默认编译器。运行以下命令来配置默认的 GCC 和 G++ 版本:

1
sudo update-alternatives --config gcc

在提示选择时,输入对应的数字(例如选择 gcc-11),然后按回车。

同样,对于 G++,使用以下命令:

1
sudo update-alternatives --config g++

2.3 验证 GCC 版本

安装并切换完成后,使用以下命令检查当前的 GCC 版本:

1
2
gcc --version
g++ --version

输出应该显示 GCC 和 G++ 版本为 11.x.x。

1
2
gcc (Ubuntu 11.x.x) ...
g++ (Ubuntu 11.x.x) ...

总结

  • 通过从源码安装 CMake 3.26 版本,你可以确保获得最新的稳定版本。
  • GCC 11 的安装和切换是为了确保支持现代 C++ 特性,如 <ranges> 等。
  • 在完成这两个工具的安装和配置后,你的开发环境将能够支持更高级的 CMake 和 GCC 功能。

1、Gitclone对应仓库并编译

  • 从下方链接下载:

    https://github.com/XidianLemon/calibration_camera_lidar

    下载后到自己项目的src中,然后正常catkin_make编译:

    提示遇到错误,运行命令sudo apt install ros-noetic-jsk-recognition-msgs即可

    1
    2
    3
    4
    5
    Could not find a package configuration file provided by
    "jsk_recognition_msgs" with any of the following names:

    jsk_recognition_msgsConfig.cmake
    jsk_recognition_msgs-config.cmake

2、仿真中进行录制

  • 参考链接博文,下载场景,并自行导入自己的小车模型,然后开启小车的仿真,录制rosbag

    模型的下载地址:

    1
    https://pan.baidu.com/s/1H314s6Hn-bY1qFphinnNrg?pwd=2022

    博客的链接地址:

    1
    https://blog.csdn.net/weixin_43807148/article/details/114241862

2、阿里云OSS控制台账号获取

3、Typora安装与配置

Ubuntu 20.04完整安装ORB_SLAM2及配置对应ROS

0、创建包路径

  • 强烈建议,先在终端创建路径Packages,然后在这个文件夹下进行后续的1、2、3、这三个包的安装

1、安装Opencv4.2.0

  • 下载压缩包

    1
    https://github.com/opencv/opencv/archive/4.2.0.zip
  • 使用unzip -x opencv4.2.0.zip 解压,进入文件夹后依次运行如下命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    # 依赖库安装
    sudo apt-get install build-essential cmake git
    sudo apt-get install libgtk2.0-dev pkg-config libavcodec-dev
    sudo apt-get install libavformat-dev libswscale-dev
    sudo apt-get install python-dev python-numpy python3-dev python3-numpy
    sudo apt-get install libtbb2 libtbb-dev libjasper-dev libdc1394-22-dev
    sudo apt-get install libjpeg-dev libpng-dev libtiff-dev
    # 正式安装
    mkdir build && cd build
    cmake -D CMAKE_INSTALL_PREFIX=/usr/local/opencv4 -D CMAKE_BUILD_TYPE="Release" -D OPENCV_GENERATE_PKGCONFIG=ON ..
    make -j4
    sudo make install
    # 检查安装
    sudo gedit /etc/ld.so.conf.d/opencv.conf
    # 进入编辑页面后输入
    /usr/local/opencv4/lib
    # 然后ctrl+s保存,关闭gedit页面后还在这个终端下运行
    sudo ldconfig
    # 编辑bashrc文件,运行
    sudo gedit ~/.bashrc
    # 在文件最后添加
    #opencv-4.2.0
    export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/usr/local/opencv4/lib/pkgconfig
    export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:./usr/local/opencv4/lib
    # 然后ctrl+s保存,关闭gedit页面后还在这个终端下运行
    source ~/.bashrc
    # 最终检查,依次运行下列命令
    pkg-config --modversion opencv4
    pkg-config --cflags opencv4
    pkg-config --libs opencv4
    # 均有正常输出即可,其中第一个命令输出为4.2.0

2、安装依赖Pangolin

  • 安装依赖项

    1
    2
    sudo apt-get install libglew-dev libboost-dev libboost-thread-dev libboost-filesystem-dev
    sudo apt-get install ffmpeg libavcodec-dev libavutil-dev libavformat-dev libswscale-dev libpng-dev

    安装Pangolin 0.6(稳定版)(官网下载地址),不要下载最新master版,编译的时候可能有错误)

  • 配置并编译

    1
    2
    3
    4
    5
    cd Pangolin 
    mkdir build && cd build
    cmake -DCPP11_NO_BOOST=1 ..
    make
    sudo make install
  • 验证

    1
    2
    3
    4
    5
    cd ../examples/HelloPangolin
    mkdir build && cd build
    cmake ..
    make
    ./HelloPangolin

    成功后会弹出一个终端,里面是一个立方体有三色,关闭即可。

3、安装依赖Eigen3

  • 方案一:直接安装

    Eigen3是一个纯头文件的库,这个特点让使用者省去了很多安装和环境配置的麻烦,可以直接安装:

    1
    sudo apt-get install libeigen3-dev
  • 方案二:源码安装

    源码(地址)安装,执行以下指令:

    1
    2
    3
    4
    5
    cd eigen3
    mkdir build && cd build
    cmake ..
    make
    sudo make install

    安装后头文件在:

    1
    /usr/local/include/eigen3/

    复制头文件到/usr/local/include

    1
    sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include

4、安装ORB_SLAM2

  • 使用鱼香ROS的一键配置命令,配置rosdepc,终端执行下列命令,然后输入密码,选择rosdepc,然后配置好了之后会提示让rosdep init之类的命令,执行命令就好了

    1
    wget http://fishros.com/install -O fishros && . fishros
  • 进入到自己的ROS工作空间的src文件夹下,下载并解压源文件,然后打开,此处我的工作空间地址为:/home/zhao/WS/Now/ant_ws/src/ORB_SLAM2

  • 修改各个CMakeLists.txt,将其中关于OpenCV的部分做如下修改:

    1、主目录ORB_SLAM2下的CMakeLists.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 注释掉下面这7行,类似的也是把涉及到的部分注释调
    # find_package(OpenCV 3.0 QUIET)
    # if(NOT OpenCV_FOUND)
    # find_package(OpenCV 2.4.3 QUIET)
    # if(NOT OpenCV_FOUND)
    # message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
    # endif()
    # endif()

    # 然后添加这两行
    set(CMAKE_PREFIX_PATH "/usr/local/opencv4")
    find_package(OpenCV 4.0 QUIET)

    2、ORB_SLAM2/Thirdparty/DBoW2文件夹下的CMakeLists.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # find_package(OpenCV 3.0 QUIET)
    # if(NOT OpenCV_FOUND)
    # find_package(OpenCV 2.4.3 QUIET)
    # if(NOT OpenCV_FOUND)
    # message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
    # endif()
    # endif()

    set(CMAKE_PREFIX_PATH "/usr/local/opencv4")
    find_package(OpenCV 4.0 QUIET)

    3、ORB_SLAM2/Examples/ROS/ORB_SLAM2文件夹下的CMakeLists.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # find_package(OpenCV 3.0 QUIET)
    # if(NOT OpenCV_FOUND)
    # find_package(OpenCV 2.4.3 QUIET)
    # if(NOT OpenCV_FOUND)
    # message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
    # endif()
    # endif()

    set(CMAKE_PREFIX_PATH "/usr/local/opencv4")
    find_package(OpenCV 4.0 QUIET)
  • 修改ros示例源文件,为Examples/ROS/ORB_SLAM2/src路径下的所有.cc文件添加头文件

    1
    #include <unistd.h>
  • ORB_SLAM2/Examples/文件夹下的所有示例源文件中导入图像数据的参数 CV_LOAD_IMAGE_UNCHANGED 修改为下列表述,建议在这个文件夹下使用code . 命令开启vscode,使用侧边栏的搜索,然后全局替换(应该是6个)

    1
    cv::IMREAD_UNCHANGED
  • 把ORB-SLAM2源码目录中include/LoopClosing.h文件中的

    1
    2
    typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
    Eigen::aligned_allocator<std::pair<const KeyFrame*, g2o::Sim3> > > KeyFrameAndPose;

    修改成:

    1
    2
    typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
    Eigen::aligned_allocator<std::pair<KeyFrame *const, g2o::Sim3> > > KeyFrameAndPose;
  • 解压源文件,在该文件夹下打开终端:

    这里建议使用记事本打开build.sh,然后逐个命令执行,方便检查错误,且注意!每次运行到最后的make命令如果失败了,在修复了之后需要依次删除对应的build文件夹,重新创建并编译!

    1
    2
    3
    cd ORB_SLAM2
    chmod +x build.sh
    ./build.sh

    如果在运行时出现问题:

    1
    error: ’usleep’ was not declared in this scope

    那么找到对应的.cc文件,在其开头的#include部分添加内容:

    1
    #include <unistd.h>

    然后,需要对照着build.sh中的内容,将涉及到的所有build文件夹全部删除并重新开始!

  • 在终端添加ROS路径,执行以下两行命令

    1
    2
    echo 'export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:'"`pwd`/Examples/ROS" >> ~/.bashrc
    source ~/.bashrc
  • 编译ros节点,此时便不再会出现问题了

    1
    ./build_ros.sh

5、Reference