ROS2小车学习

项目场景:

ROS2 foxy 小车 传感器融合
*本文编写规则
1、大写斜体 需替换为自定义名称


相关命令

1、节点启动

遥控控制
ros2 launch wheeltec_joy wheeltec_wire_joy.launch.py
动作捕获定位
ros2 launch vrpn_client_ros sample.launch.py
ros2 run fusion Mocap_node
底盘运动+寻磁
ros2 run chassis_control Car_control

ros2 run chassis_magnetic magnetic
ros2 run pid_c pid
ros2 launch ums_fiction_driver ums_fiction_v1.launch.py
寻磁启止
ros2 topic pub /Turn std_msgs/msg/Int8 data:\ 1
ros2 topic pub /Turn std_msgs/msg/Int8 data:\ 0
RFID
ros2 run data_publishing rfid
imu
ros2 run chassis_control car_motion_control
ros2 run data_publishing imu
UWB
ros2 run fusion UWB_node
融合定位
ros2 run fusion fusion_node
轨迹追踪
ros2 run path_track mpc_tracker
ros2 run path_track stanley_tracker
雷达建图
~/map_ws$ ros2 launch sllidar_ros2 sllidar_a1_launch.py

2、ROS2安装配置

(1) ROS2
ros2一键安装:wget http://fishros.com/install -O fishros && . fishros
ros2一键卸载:sudo apt remove ros-foxy-* && sudo apt autoremove
查看ros版本号:rosversion -d

创建工作空间
mkdir -p town_ws/src
cd town_ws/src
创建python功能包
ros2 pkg create <package_name> --build-type ament_python --dependencies rclpy

(2) 工具
1、RQT安装:
sudo apt-get install ros-$ROS_DISTRO-rqt
sudo apt install ros-$ROS_DISTRO-rqt*
2、rviz IMU插件:
sudo apt-get install ros-$ROS_DISTRO-imu-tools
3、python库安装:
pip install pyserial
pip install heapdict

(3) 更新环境变量
更新工作空间环境变量(每次build后都要)
source ./install/setup.bash
将source写入系统全局变量(build后自动source)
echo “source /home/用户名/文件夹/install/setup.bash” >> ~/.bashrc
source ~/.bashrc

(4) 指定源安装
-i https://pypi.tuna.tsinghua.edu.cn/simple some-package

(5) 编译指令
全局编译: colcon build
单独编译: colcon build --packages-select PACKAGE_NAME
python 静态链接编译 :colcon build --symlink-install

(6) 串口绑定
1、查看串口详细信息
$ udevadm info --attribute-walk --name=/dev/ttyUSB1 |grep KERNELS
>>>
KERNELS==“ttyUSB1”
KERNELS==“2-1.2.2:1.0”
KERNELS==“2-1.2.2”
KERNELS==“2-1.2”
KERNELS==“2-1”
KERNELS==“usb2”
KERNELS==“fc880000.usb”
KERNELS==“platform”

2、绑定串口(串口重命名)
$ sudo vim /etc/udev/rules.d/robotbase_port.rules
ACTION==“add”,KERNELS==“2-1.3.1:1.0”,SUBSYSTEMS==“usb”,MODE:=“0777”,SYMLINK+=“com_car”

3、重载串口
$ service udev reload
$ service udev restart
重新拔插串口
( ( 1.78 - 0.455 ) ^ 2 + 1.2 ^ 2 ) ^ ( 0.5 )

3、测试

(1) rosbag记录器
记录全部话题 ros2 bag record -a
命名记录文件并挑选记录话题 ros2 bag record -o BAG-NAME /PACKAGE-NAME
播放纪录包并指定话题 ros2 bag play BAG-NAME --topics /PACKAGE-NAME
查看纪录包详情 ros2 bag info BAG-NAME

ros2 bag record -o RosbagRecord /test_car_1 /imu /uwb_distance /rfid_data /car1_Marker3/pose /Fused/pose /Mocap/pose /Fused/path /Mocap/path /Error

(2) 计算器欧式距离公式
((4.2−0.6)2+(4.8−1.2)2+(0.52−0.29)2)0.5

(3) ros系统桌面UI foxglove

1.启动桥:ros2 launch foxglove_bridge foxglove_bridge_launch.xml
2.打开foxglove studio

4、常用指令

(1) 话题相关
查看话题列表: ros2 topic list
查看话题列表及消息类型:ros2 topic list -t
订阅话题:ros2 topic echo TOPIC_NAME
查看话题频率:ros2 topic hz TOPIC_NAME
查看话题详情 (消息类型和发布者/订阅者的数量): ros2 topic info TOPIC_NAME

(2) 消息相关
查看消息定义:ros2 interface show geometry_msgs/msg/PoseStamped

5、ubuntu快捷指令

(1) linux 命令行指令
查看所有历史命令:history
查看包含关键词‘KEYWORD‘历史命令:history |grep KEYWORD
根据序号选择命令并执行:!001
查找包含输入字符的历史命令:ctrl R

(2)主目录查看隐藏文件(.bashrc)
ctrl H


Debug记录


编译问题

Q1、功能包编译 部分代码在install下不更新
python:将python功能包做静态链接 colcon build --symlink-install
c++:删除install 、build文件夹重新编译

Q2、找不到依赖功能包编译失败
方法一:先单独编译依赖功能包再全局编译 编译完后更新环境变量

colcon build --packages-select car_interfaces
colcon build
source ./install/setup.bash
colcon build --symlink-install

方法二:修改功能包的 package.xml 文件和 CMakeLists.txt 文件

在ROS2中,如果一个包(例如B_package)依赖于另一个包(例如A_package),需要在B_package的package.xml和CMakeLists.txt文件中声明这种依赖关系。
1.修改 package.xml 文件
在 package.xml 文件中,你需要添加 标签来声明对 A_package 的依赖。例如:

<package format="3">
  <name>B_package</name>
  <!-- 其他元数据... -->

  <depend>A_package</depend>

  <!-- 其他依赖... -->
</package>

2.修改 CMakeLists.txt 文件
需要在 find_package() 方法中添加 A_package 这个依赖。例如:

cmake_minimum_required(VERSION 3.5)
project(B_package)

# Default to C99
if(NOT CMAKE_C_STANDARD)
 set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
 set(CMAKE_CXX_STANDARD 14)
endif()

find_package(ament_cmake REQUIRED)
find_package(A_package REQUIRED) # 添加这行代码

\# 其他的 'find_package' 调用...

\# 剩下的 CMakeLists.txt 内容...

同时,如果你在 B_package 中使用了 A_package 的消息,则还需要在 add_dependencies() 方法中添加目标依赖。例如,如果你创建了一个名为 my_node 的可执行文件,那么应该这样做:

add_executable(my_node src/my_node.cpp)
ament_target_dependencies(my_node A_package) # 添加这行代码

使用这种方法,Ament工具(ROS 2的构建系统)将首先构建A_package,然后再构建B_package。

方法三:使用–packages-up-to命令,找到并编译所有依赖后再编译该包

colcon build --packages-up-to cartographer_ros

Q3、时钟错误编译失败
cmake会先查看文件的最新修改时间,跟log记录的时间比较决定是否进行更新。可以将系统设置为自动更新时间,或者输入命令强制更新时间

sudo date -s ‘2023-11-09 15:47:00’

Q4、python静态链接编译通过却无法rosrun

Traceback (most recent call last):
  File "/home/cat/agv_ws/install/fusion/lib/fusion/testHZ_node", line 33, in <module>
    sys.exit(load_entry_point('fusion', 'console_scripts', 'testHZ_node')())
  File "/home/cat/agv_ws/install/fusion/lib/fusion/testHZ_node", line 22, in importlib_load_entry_point
    for entry_point in distribution(dist_name).entry_points
  File "/usr/lib/python3.10/importlib/metadata/__init__.py", line 969, in distribution
    return Distribution.from_name(distribution_name)
  File "/usr/lib/python3.10/importlib/metadata/__init__.py", line 548, in from_name
    raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: No package metadata was found for fusion
[ros2run]: Process exited with failure 1

colcon build --symlink-install默认不执行soure,需要手动source一下环境。

source ./install/setup.bash



分布式测试问题

Q1、不同设备话题冲突混乱
在同一局域网下域ID可能相同,导致设备能互相接收话题,可以为每一个设备修改域ID

#进入设备用户根目录
vim .bashrc

在bash文件最后输入设置域ID命令,每个设备的ID号都要不一样

export ROS_DOMAIN_ID=XXX

最后更新用户环境变量

source .bashrc

Q2、ROS1和ROS2共存坑

  1. 启动终端选择ROS版本时会默认执行一次 source ~/.bashrc 。因此如果在系统全局变量.bashrc中添加了对ros1工作空间环境的source bash,如:source /home/dn/ROS1_Project/UAV_ws/devel/setup.bash,则会将部分全局变量设置为ROS1环境,导致ROS2运行出问题,反之同理。

Q3、code-server安装
ubuntu 20.04 code-server 安装
1、code-server github上下载deb文件
![架构区别
2、安装

dpkg -i code-server_4.2.0_amd64.deb

3、运行一次,生成配置文件

code-server

4、关闭程序,修改配置文件

vim ~/.config/code-server/config.yaml

bind-addr改为0.0.0.0并设置需要的端口(8080),更改password(abcd)
5、开启服务
sudo systemctl start code-server@username
6、开机自启
sudo systemctl enable --now code-server@$USER

Q4、rqt启动异常
ros/ros2同样的报错:

Traceback (most recent call last):
  File "/opt/ros/noetic/bin/rqt", line 13, in <module>
    sys.exit(main.main())
  File "/opt/ros/noetic/lib/python3/dist-packages/rqt_gui/main.py", line 61, in main
    return super(
  File "/opt/ros/noetic/lib/python3/dist-packages/qt_gui/main.py", line 407, in main
    from python_qt_binding import QT_BINDING
  File "/opt/ros/noetic/lib/python3/dist-packages/python_qt_binding/__init__.py", line 55, in <module>
    from .binding_helper import loadUi, QT_BINDING, QT_BINDING_MODULES, QT_BINDING_VERSION  # @UnusedImport
  File "/opt/ros/noetic/lib/python3/dist-packages/python_qt_binding/binding_helper.py", line 277, in <module>
    _select_qt_binding(
  File "/opt/ros/noetic/lib/python3/dist-packages/python_qt_binding/binding_helper.py", line 111, in _select_qt_binding
    QT_BINDING_VERSION = binding_loader(required_modules, optional_modules)
  File "/opt/ros/noetic/lib/python3/dist-packages/python_qt_binding/binding_helper.py", line 158, in _load_pyqt
    _named_optional_import('PyQt5.%s' % module_name)
  File "/opt/ros/noetic/lib/python3/dist-packages/python_qt_binding/binding_helper.py", line 145, in _named_optional_import
    _named_import(name)
  File "/opt/ros/noetic/lib/python3/dist-packages/python_qt_binding/binding_helper.py", line 136, in _named_import
    module = builtins.__import__(name)
ValueError: PyCapsule_GetPointer called with incorrect name

参考:运行rqt报错PyCapsule_GetPointer called with incorrect name解决办法

1、找到文件位置
ROS :

/opt/ros/noetic/lib/python3/dist-packages/python_qt_binding.binding_helper.py

ROS2:

/opt/ros/foxy/lib/python3.8/site-packages/python_qt_binding.binding_helper.py

2、打开文件
只读文件需要sudo权限才能修改

sudo vim binding_helper.py

3、修改文件
把QtWebKitWidgets注释

#‘QtWebKitWidgets’, # Qt 5.0 - 5.5

4、结果
可以打开rqt 但是仍然会报错 不影响使用

RosPluginProvider.load(qt_gui_cpp/CppPluginProvider) exception raised in __builtin__.__import__(qt_gui_cpp.cpp_plugin_provider, [CppPluginProvider]):
Traceback (most recent call last):
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_gui/ros_plugin_provider.py", line 80, in load
    module = __builtin__.__import__(
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui_cpp/cpp_plugin_provider.py", line 33, in <module>
    from .cpp_binding_helper import qt_gui_cpp
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui_cpp/cpp_binding_helper.py", line 43, in <module>
    from . import libqt_gui_cpp_sip
ValueError: PyCapsule_GetPointer called with incorrect name

RecursivePluginProvider.discover() loading plugin "qt_gui_cpp/CppPluginProvider" failed:
Traceback (most recent call last):
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui/recursive_plugin_provider.py", line 60, in discover
    instance = self._plugin_provider.load(plugin_descriptor.plugin_id(), None)
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_gui/ros_plugin_provider.py", line 91, in load
    raise e
  File "/opt/ros/foxy/lib/python3.8/site-packages/rqt_gui/ros_plugin_provider.py", line 80, in load
    module = __builtin__.__import__(
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui_cpp/cpp_plugin_provider.py", line 33, in <module>
    from .cpp_binding_helper import qt_gui_cpp
  File "/opt/ros/foxy/lib/python3.8/site-packages/qt_gui_cpp/cpp_binding_helper.py", line 43, in <module>
    from . import libqt_gui_cpp_sip
ValueError: PyCapsule_GetPointer called with incorrect name

ROS2教程

参考:ROS2中python引用自定义py文件

文件架构 (*表示自己创建的文件/文件夹)

workspace (工作空间)
|-> ...
|-> src
      |-> mypackage (python类型功能包)
             |-> mypackage (代码执行区)
                    |-> config                (*参数文件夹,需要被调用)
                           |->__init__.py 
                           |-> settings.py
                    |-> view                 (*功能文件夹,需要调用cofig包)
                           |->__init__.py 
                           |-> plot.py
                    |-> src                   (*主功能文件夹,需要调用cofig包,自身文件夹内部也需要互相调用)
                           |->__init__.py
                           |-> model.py
                           |-> train.py
                    |->__init__.py 
                    |-> main.py               (*功能包下的文件,需要调用cofig包)
             |-> launch                       (*lauch文件夹,批量启动节点)
                    |-> my.launch.py 
             |-> resource
                    |-> ...
             |-> test
                    |-> ...
             |-> package.xml
             |-> setup.cfg
             |-> setup.py  (配置文件 告诉ros文件怎么组织)

文件示例
1、setup.py:向编译器说明功能包的组织架构
参考: python打包分发工具:setuptools

from setuptools import setup
from glob import glob
import os

# 给出python包的路径
package_name = 'mypackage'
src = 'mypackage/src'
cofig = 'mypackage/cofig'
view = 'mypackage/view'

setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name, src, cofig, view],   # 在编译时把这几个文件夹都复制到install/mypackage/..下
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
        (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')), # 给出launch文件路径
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='nvidia',
    maintainer_email='xxx@qq.com',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            "main_node = fusion.main:main",
            "train_node = fusion.src.train:main",
            "view_node = fusion.view.plot:main",
        ],
    },
)

2、导入自定义python包裹

# main.py导入settings.py
from .config import settings

# train.py导入model.py
from . import model

# train.py导入plot.py
from ..view import plot

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值