【ROS2教程-续更中】

ROS2

  • [1 使用Windows子系统WSL安装ROS2并运行小海龟的详细教程](#1 使用Windows子系统WSL安装ROS2并运行小海龟的详细教程)
  • [2 CLI工具](#2 CLI工具)
    • [2.1 配置环境](#2.1 配置环境)
    • [2.2 使用 turtlesim 、 ros2 和 rqt](#2.2 使用 turtlesim 、 ros2 和 rqt)
      • [2.2.1 Turtlesim安装和使用](#2.2.1 Turtlesim安装和使用)
      • [2.2.2 rqt安装与使用](#2.2.2 rqt安装与使用)
    • [2.3 理解节点](#2.3 理解节点)
      • [2.3.1 运行可执行文件](#2.3.1 运行可执行文件)
      • [2.3.2 节点查询](#2.3.2 节点查询)
    • [2.4 理解话题](#2.4 理解话题)
    • [2.5 理解服务](#2.5 理解服务)
    • [2.6 理解参数](#2.6 理解参数)
    • [2.7 理解行为](#2.7 理解行为)
    • [2.8 使用 rqt_console 查看日志](#2.8 使用 rqt_console 查看日志)
    • [2.9 启动节点](#2.9 启动节点)
    • [2.10 录制和回放数据](#2.10 录制和回放数据)
  • [3 客户端库](#3 客户端库)
    • [3.1 使用colcon构建软件包](#3.1 使用colcon构建软件包)

1 使用Windows子系统WSL安装ROS2并运行小海龟的详细教程

第一步:安装WSL(根据官方教程Maybe可以跳过)

官方教程:https://learn.microsoft.com/zh-cn/windows/wsl/install

  1. 启用WSL功能
    打开"控制面板",选择"程序">"程序和功能">"启用或关闭Windows功能",勾选"适用于Linux的Windows子系统"和"虚拟机平台",然后点击"确定"并重启计算机。
    或者在PowerShell中运行以下命令:
bash 复制代码
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

然后重启计算机。

  1. 安装Ubuntu24.04.3 LTS

命令行安装

打开PowerShell,运行以下命令:

复制代码
wsl --install
wsl --set-default-version 2
wsl --install -d Ubuntu-24.04.3 LTS

应用商店安装

在Microsoft Store中搜索并安装Ubuntu24.04.3 LTS。

第二步:安装ROS2

直接一键安装

bash 复制代码
wget http://fishros.com/install -O fishros && bash fishros

第三步:运行小海龟

启动小海龟节点

在一个终端中运行以下命令启动小海龟节点:

bash 复制代码
ros2 run turtlesim turtlesim_node

这时会弹出一个小海龟的图形界面。

启动键盘控制

在另一个终端中运行以下命令启动键盘控制节点:

bash 复制代码
ros2 run turtlesim turtle_teleop_key

使用键盘的上下左右键可以控制小海龟的移动。

2 CLI工具

2.1 配置环境

1.背景

ROS2依赖于使用Shell环境组合工作空间的概念。所谓的"工作空间"是ROS中用于开发ROS2的位置。

2.任务

(1)导入设置文件

在每次打开新的Shell时,需要运行以下命令以便访问ROS2命令:

bash 复制代码
source /opt/ros/kilted/setup.bash

(2)将源命令添加到您的shell启动脚本

如果您不想每次打开新的shell时都要进行源命令设置(跳过任务1),您可以将该命令添加到您的shell启动脚本中:

bash 复制代码
source vim ~/.bashrc
echo "source /opt/ros/kilted/setup.bash" >> ~/.bashrc

(3)检查环境变量

使用ROS2设置文件会设置几个操作ROS2所必需的环境变量。确认环境正确设置:

bash 复制代码
printenv | grep -i ROS

此外,还要介绍两个变量概念:

ROS_DOMAIN_ID 变量 和 ROS_LOCALHOST_ONLY 变量

域ID由DDS用于计算用于发现和通信的UDP端口,ROS2用于通信的默认中间件是DDS,在DDS中,不同逻辑网络共享物理网络的主要机制被称为Domain ID,同一域中的ROS2节点可以自由地发现和相互发送消息,而不同域中的ROS2节点则不能。所有ROS 2节点默认使用域ID 0。为了避免在同一网络上运行ROS 2的不同计算机组之间的干扰,应为每个组设置不同的域ID。一般来说,只需选择一个安全的数字,简单地选择一个介于0和101之间(包括0和101)的域ID即可。

bash 复制代码
export ROS_DOMAIN_ID=<your_domain_id>
或者
echo "export ROS_DOMAIN_ID=<your_domain_id>" >> ~/.bashrc

ROS_LOCALHOST_ONLY 变量 默认情况下,ROS 2通信不限于本地主机。ROS_LOCALHOST_ONLY环境变量允许您将ROS 2通信限制为仅限本地主机。这意味着您的ROS 2系统及其话题、服务和操作将对本地网络上的其他计算机不可见。在某些情况下,使用ROS_LOCALHOST_ONLY非常有帮助,比如在教室中,多个机器人可能会向同一话题发布,从而导致奇怪的行为。

bash 复制代码
export ROS_LOCALHOST_ONLY=1
或者
echo "export ROS_LOCALHOST_ONLY=1" >> ~/.bashrc

2.2 使用 turtlesim 、 ros2 和 rqt

Turtlesim是一个轻量级的用于学习ROS 2的模拟器。它以最基本的方式展示了ROS 2的功能,让您对以后在真实机器人或机器人模拟中要做什么有个基本的了解。

ros2工具是用户管理、检视和与ROS系统交互的方式。它支持多个命令,针对系统及其操作的不同方面。用户可以使用它来启动一个节点、设置参数、监听话题等等。ros2工具是ROS 2核心安装的一部分。

rqt 是一个用于ROS 2的图形用户界面(GUI)工具。rqt 中的所有操作都可以通过命令行完成,但是rqt 提供了一种更加用户友好的方式来操作ROS 2元素。该小节也会介绍了ROS 2的核心概念,如节点(nodes)、话题(topics)和服务(services)。

2.2.1 Turtlesim安装和使用

1.安装

bash 复制代码
sudo apt update
sudo apt install ros-humble-turtlesim
# 检查是否安装了该软件包
ros2 pkg executables turtlesim

2.使用

启动turtlesim,请在终端中输入以下命令:

bash 复制代码
ros2 run turtlesim turtlesim_node

模拟器窗口应出现,并在中心显示一个随机的乌龟

然后打开一个新的终端并再次启动ROS 2。运行一个新节点来控制第一个节点中的海龟:

bash 复制代码
ros2 run turtlesim turtle_teleop_key

可以使用键盘上的箭头键来控制海龟。它将在屏幕上移动,并使用其附加的"笔"来绘制它迄今为止所经过的路径。

使用各自命令的list子命令查看节点及其关联的话题、服务和操作:

bash 复制代码
ros2 node list
ros2 topic list
ros2 service list
ros2 action list

2.2.2 rqt安装与使用

1.安装

bash 复制代码
sudo apt update
sudo apt install ~nros-kilted-rqt*
# 运行
rqt

2.使用

第一次运行 rqt 时,窗口将为空白。 不用担心;只需从顶部的菜单栏中选择插件>服务>服务调用者。
rqt 可能需要一些时间才能找到所有插件。 如果您单击插件但没有看到服务或任何其他选项,您应该关闭 rqt 并在终端中输入命令。rqt --force-discover

3.spwan服务

/spawn将在turtlesim窗口中创建另一只海龟,然后通过重映射 可以实现对另一只海龟的控制。

在一个新的终端中,设置ROS 2环境并运行:

bash 复制代码
ros2 run turtlesim turtle_teleop_key --ros-args --remap turtle1/cmd_vel:=turtle2/cmd_vel

2.3 理解节点

一个完整的机器人系统由许多协同工作的节点组成。在ROS 2中,单个可执行文件(C++程序、Python程序等)可以包含一个或多个节点ROS中的每个节点应该负责一个单一的模块化功能,每个节点可以通过话题(topics)、服务(services)、行为(actions)或参数(parameters)与其他节点进行数据的发送和接收。

2.3.1 运行可执行文件

命令ros2 run会从一个软件包中启动一个可执行文件。

bash 复制代码
ros2 run <pack_name> <executable_name>

2.3.2 节点查询

1.未知节点

使用 ros2 node list 命令查找节点名称

2.已知节点

根据节点名称访问更多信息

bash 复制代码
ros2 node info <node_name>

ros2 node info返回订阅者、发布者、服务和行为的列表,即与该节点进行交互的ROS图连接。

2.4 理解话题

话题是数据在节点之间以及系统不同部分之间传递的主要方式之一,按照发布-订阅模型,允许节点订阅数据流并获得持续更新。一个节点可以向任意数量的话题发布数据,并同时订阅任意数量的话题。

(1)查看节点和话题

可视化节点和话题的变化,以及它们之间的连接:

bash 复制代码
rqt_graph

(2)也可以通过打开 rqt 并选择 Plugins > Introspection > Node Graph 来打开 rqt_graph.

bash 复制代码
# 返回系统中当前活动的所有话题的列表
ros2 topic list
# 返回系统中当前活动的所有话题+消息类型的列表
ros2 topic list -t
# 查看在话题上发布的数据,(实时观察数据)
ros2 topic echo <topic_name>
# 查看话题数量
# 话题不仅可以是一对一的通信,还可以是一对多的、多对一的或多对多的通信
ros2 topic info <topic_name>
# 查看节点使用消息在话题上发送期望的数据结构
ros2 interface show <msg_type>
# 直接从命令行发布数据到一个话题,这个参数需要以 YAML 语法输入
ros2 topic pub <topic_name> <msg_type> '<args>'
## 例1:发布一条消息后退出 (--once)
ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
## 例2:持续不断接收命令(--rate 1,以 1 Hz 的恒定速率发布命令)
ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
# 查看数据发布的速率
ros2 topic hz /turtle1/pose

2.5 理解服务

服务是ROS图中节点之间的另一种通信方法。服务基于调用-响应模型,服务仅在客户端特定调用时提供数据。

与话题不同,话题是一种单向通信模式,其中一个节点发布信息,可以由一个或多个订阅者消费。服务是一种请求/响应模式,其中客户端向提供服务的节点发出请求,服务处理请求并生成响应。

通常情况下,不应该使用服务进行连续调用;更适合使用话题或者甚至是行为。

bash 复制代码
# 查看当前系统中所有活动服务的列表
ros2 service list
# 查看服务具有描述服务的请求和响应数据结构的类型
ros2 service type <service_name>
# 查看所有活动服务和服务的类型
ros2 service list -t
# 查看特定类型的所有服务
ros2 service find <type_name>
# 查看服务类型的输入参数的结构
## 数据结构:(请求结构---接收结构)
ros2 interface show <type_name>
# 调用服务( <arguments>为可选)
ros2 service call <service_name> <service_type> <arguments>

2.6 理解参数

参数是节点的配置值。您可以将参数视为节点设置。节点可以将参数存储为整数、浮点数、布尔值、字符串和列表。在 ROS 2 中,每个节点都维护其自己的参数.

bash 复制代码
# 查看节点的参数
ros2 param list
# 显示参数的类型和当前值
ros2 param get <node_name> <parameter_name>
# 在运行时更改参数的值
ros2 param set <node_name> <parameter_name> <value>
# 查看节点的所有当前参数值
ros2 param dump <node_name>
# 将参数值重定向到文件中以便以后使用
ros2 param dump <node_name> > <parameter_file>
ros2 param dump /turtlesim > turtlesim.yaml
# 将参数从文件加载到当前运行的节点
ros2 param load <node_name> <parameter_file>
# 在节点启动时加载参数文件
ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>

2.7 理解行为

行为是ROS 2中的一种通信类型,用于长时间运行的任务。它们由三个部分组成:目标(goal),反馈(feedback)和结果(result)

行为是建立在话题(topics)和服务(services)之上的。它们的功能类似于服务,但行为可以被取消。与只返回单个响应的服务不同,行为还提供稳定的反馈。

行为使用客户端-服务器模型,类似于发布者-订阅者模型。一个"行为客户端"节点向一个"行为服务器"节点发送一个目标,服务器节点确认目标并返回一系列反馈和结果流。

不要假设每个行为服务器在收到新目标时都会选择中止当前目标。行为服务器可以选择中止第一个目标执行一个新的目标。也可以选择拒绝新目标或在第一个目标完成后执行第二个目标。

行为类似于服务,允许您执行长时间运行的任务,提供定期反馈,并可取消。

一个机器人系统可能会使用行为进行导航。一个行为目标可以告诉机器人前往一个位置。当机器人导航到该位置时,它可以沿途发送更新(即反馈),然后在到达目的地后发送最终结果消息。

bash 复制代码
# 查看ROS图中的所有行为
ros2 action list
# 查看ROS图中的所有行为及行为类型
ros2 action list -t
# 查看ROS图中的行为类型详情,如服务和客户端的行为数量等
ros2 action info <Waction_name>
# 查看行为类型的结构(目标请求的结构---结果的结构---反馈的结构)
ros2 interface show <action_type>
# 发送一个行为目标 (<values> 需要以 YAML 格式提供)
ros2 action send_goal <action_name> <action_type> <values> --feedback

2.8 使用 rqt_console 查看日志

rqt_console 是一个用于在ROS 2中检查日志消息的图形界面工具。通常,日志消息会显示在终端中。使用 rqt_console,可以随时间收集这些消息,以更加仔细和有组织的方式查看它们,对它们进行过滤、保存,甚至可以重新加载保存的文件以在不同的时间进行检查。

bash 复制代码
# 启动 rqt_console
ros2 run rqt_console rqt_console
# 日志记录器级别
Fatal(致命)消息表明系统将终止以试图保护自身免受损害。
Error(错误)消息表示存在重要问题,这些问题不一定会损坏系统,但会阻止其正常运行。
Warn 消息表示意外活动或非理想结果,可能表示更深层问题,但不会直接影响功能。
Info 消息表示事件和状态更新,作为系统正常运行的可视验证。
Debug 消息详细描述系统执行的每个步骤。
默认级别是 Info。只会看到默认严重级别和更严重级别的消息,Debug级别的消息被隐藏。
如果将默认级别设置为Warn,您只会看到Warn、Error和Fatal严重程度的消息。
# 设置默认日志记录器级别
ros2 run turtlesim turtlesim_node --ros-args --log-level WARN

2.9 启动节点

使用ros2 launch命令运行单个启动文件将一次性启动整个系统 - 所有节点及其配置。启动文件允许您同时启动和配置包含 ROS 2 节点的多个可执行文件。

推荐使用Python编写Launch文件。一般来说是可以采用 Python、XML 和 YAML 三种方式编写 ROS 2 启动文件。

bash 复制代码
# 运行Launch文件
ros2 launch turtlesim multisim.launch.py

# 使用python编写Launch文件
# turtlesim/launch/multisim.launch.py
from launch import LaunchDescription
import launch_ros.actions

def generate_launch_description():
    return LaunchDescription([
        launch_ros.actions.Node(
            namespace= "turtlesim1", package='turtlesim', executable='turtlesim_node', output='screen'),
        launch_ros.actions.Node(
            namespace= "turtlesim2", package='turtlesim', executable='turtlesim_node', output='screen'),
    ])

2.10 录制和回放数据

ros2 bag 是一个命令行工具,用于记录系统中发布在话题上的数据。

它会累积通过任意数量的话题传递的数据,并将其保存在数据库中。然后回放这些数据,以重现测试和实验结果。记录话题也是分享工作并允许他人重新创建的好方法。

bash 复制代码
# 安装ros2 bag
一般情况下,在按照ROS2时,ros2 bag就作为其中的一部分进行一同安装。
# 录制(完成后按``Ctrl+C``)
mkdir bag_files
cd bag_files
ros2 bag record <topic_name>
# 录制多个话题
ros2 bag record -o <bag_file_name> <topic_name1> <topic_name2>
ros2 bag record -o subset /turtle1/cmd_vel /turtle1/pose
# 查看有关记录的详细信息
ros2 bag info <bag_file_name>
ros2 bag info subset
# 回放
ros2 bag play <bag_file_name>
ros2 bag play subset

# 了解位置数据发布的频率
ros2 topic hz /turtle1/pose

3 客户端库

3.1 使用colcon构建软件包

colcon是对ROS构建工具catkin_make、catkin_make_isolated、catkin_toolsament_tools的改进。使用colcon创建和构建ROS 2工作空间。

1.安装colcon

bash 复制代码
sudo apt install python3-colcon-common-extensions

2.基础知识

ROS工作空间是一个具有特定结构的目录。通常有一个 src 子目录,在该子目录下是ROS软件包的源代码所在位置,通常该目录开始时为空。

colcon进行外部构建。默认情况下,它会创建以下目录作为 src 目录的同级目录:

build 目录将用于存储中间文件。对于每个软件包,将在其中创建一个子文件夹,例如在该子文件夹中调用 CMake。

install 目录是每个软件包将要安装到的位置。默认情况下,每个软件包将被安装到单独的子目录中。

log 目录包含有关每个 colcon 调用的各种日志信息。

注:与catkin相比,是没有devel目录的

bash 复制代码
# 创建工作空间(ros2_ws文件夹来表示工作空间)
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
# 解决包依赖(在工作空间的根目录下)
rosdep install -i --from-path src --rosdistro kilted -y
# 构建工作空间(在工作空间的根目录下)
colcon build --symlink-install
构建完成后,可生成build、install 和 log 文件夹
--packages-up-to 构建所需的包及其所有依赖项,而不是整个工作空间(节省时间)
--symlink-install 在您调整Python脚本时,无需每次重新构建
--event-handlers console_direct+ 在构建时显示控制台输出(否则可在``log``目录中找到)
# 运行测试,对刚构建的软件包运行测试
colcon test
# 加载环境变量
source install/setup.bash
或者
使用绝对路径放至~/.bashrc
# 创建自己的包(在src文件夹下,创建软件包,每个软件包位于自己的文件夹中)
ros2 pkg create 
# 设置 colcon_cd
## colcon_cd 允许您快速将当前工作目录更改为包的目录
echo "source /usr/share/colcon_cd/function/colcon_cd.sh" >> ~/.bashrc
echo "export _colcon_cd_root=/opt/ros/kilted/" >> ~/.bashrc
# 设置 colcon 的选项自动补全
确保colcon-argcomplete安装
echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> ~/.bashrc
# 从软件包中运行单个特定测试
colcon test --packages-select YOUR_PKG_NAME --ctest-args -R YOUR_TEST_IN_PKG

1.不想构建特定的软件包,请在目录中放置一个名为"COLCON_IGNORE"的空文件,它将不会被索引
2.想避免在CMake软件包中配置和构建测试,可以传递参数:--cmake-args -DBUILD_TESTING=0

一个简单的工作空间样例:

python 复制代码
workspace_folder/
    src/
      cpp_package_1/
          CMakeLists.txt
          include/cpp_package_1/
          package.xml
          src/

      py_package_1/
          package.xml
          resource/py_package_1
          setup.cfg
          setup.py
          py_package_1/
      ...
      cpp_package_n/
          CMakeLists.txt
          include/cpp_package_n/
          package.xml
          src/

3.官方支持的CMake或者Python两种方式构建包

(1)CMake

  • 构建方式
bash 复制代码
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake <package_name>
  • 构建结果
bash 复制代码
my_package/
     CMakeLists.txt # 描述了如何构建软件包内的代码
     include/my_package/ # 包含该包的公共头文件
     package.xml # 包含有关该包的元信息
     src/ #包含该包源代码

(2)Python

  • 构建方式
bash 复制代码
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python <package_name>
  • 构建结果
bash 复制代码
my_package/ 
      package.xml #包含有关该包的元信息
      resource/my_package #用于标记该包
      setup.cfg #当一个软件包包含可执行文件时,需要使用``setup.cfg``,以便``ros2 run``能够找到它们
      setup.py #``setup.py``包含了安装该软件包的指令
      my_package/ #与软件包同名的目录,被ROS 2工具用于查找软件包,包含``__init__.py``

4.运行colcon build一次性构建多个软件包

bash 复制代码
cd ~/ros2_ws
# 构建工作空间中的所有包
colcon build
# 构建工作空间中的特定包
colcon build --packages-select my_package

5.检查软件包内容

  • CMake检查软件包内容
bash 复制代码
CMakeLists.txt  include  package.xml  src

my_node.cpp 位于 src 目录中。这是以后将放置所有自定义 C++ 节点的位置。

  • Python检查软件包内容
bash 复制代码
my_package  package.xml  resource  setup.cfg  setup.py  test

my_node.py 位于 my_package 目录中。这是以后将放置所有自定义 Python 节点的位置。

6.自定义package.xml

设置对包的描述和许可声明,

  • CMake
bash 复制代码
<?xml version="1.0"?>
<?xml-model
   href="http://download.ros.org/schema/package_format3.xsd"
   schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
 <name>my_package</name>
 <version>0.0.0</version>
 <description>TODO: Package description</description>
 <maintainer email="user@todo.todo">user</maintainer>
 <license>TODO: License declaration</license>

 <buildtool_depend>ament_cmake</buildtool_depend>

 <test_depend>ament_lint_auto</test_depend>
 <test_depend>ament_lint_common</test_depend>

 <export>
   <build_type>ament_cmake</build_type>
 </export>
</package>
  • Python
bash 复制代码
<?xml version="1.0"?>
<?xml-model
   href="http://download.ros.org/schema/package_format3.xsd"
   schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
 <name>my_package</name>
 <version>0.0.0</version>
 <description>TODO: Package description</description>
 <maintainer email="user@todo.todo">user</maintainer>
 <license>TODO: License declaration</license>

 <test_depend>ament_copyright</test_depend>
 <test_depend>ament_flake8</test_depend>
 <test_depend>ament_pep257</test_depend>
 <test_depend>python3-pytest</test_depend>

 <export>
   <build_type>ament_python</build_type>
 </export>
</package>

setup.py文件包含了与package.xml相同的描述、维护者和许可证字段,所以你也需要设置它们。两个文件中的内容必须完全匹配。版本和名称(package_name)也必须完全匹配,并且应该在两个文件中自动填充。

bash 复制代码
from setuptools import setup

package_name = 'my_py_pkg'

setup(
 name=package_name,
 version='0.0.0',
 packages=[package_name],
 data_files=[
     ('share/ament_index/resource_index/packages',
             ['resource/' + package_name]),
     ('share/' + package_name, ['package.xml']),
   ],
 install_requires=['setuptools'],
 zip_safe=True,
 maintainer='TODO',
 maintainer_email='TODO',
 description='TODO: Package description',
 license='TODO: License declaration',
 tests_require=['pytest'],
 entry_points={
     'console_scripts': [
             'my_node = my_py_pkg.my_node:main'
     ],
   },
)

https://github.com/NCAIRNigeria/NCAIR_Rasp-Bot

相关推荐
漫漫求1 天前
ros2常用命令
ros2
奔跑的花短裤4 天前
ROS2安装
ros·ros2·ros1
敬往事一杯酒哈4 天前
1.3 Ros2快速体验
python·ros2
sunshine~~~5 天前
ROS 2 Jazzy + Python 3.12 + Web 前端案例
开发语言·前端·python·anaconda·ros2
G果5 天前
Modbus CRC16 算法(举例)
can·modbus·ros2·crc16
boss-dog6 天前
UR robot ROS2 Driver 快速入门使用
机械臂·ros2·urdf·moveit2·ur
boss-dog6 天前
Moveit2使用说明(C++)
c++·ros2·moveit2
小帽哥aicv6 天前
ubuntu22 安装ros2-humble, Navigation2, RTABMap
linux·ros2
叠叠乐8 天前
ubuntu ROS1 wifi开关 热点开关 链接指定wifi 扫描wifi节点
ubuntu·ros2
敬往事一杯酒哈9 天前
1.4 ROS2 集成开发环境搭建
ros2