1208 字
6 分钟
ROS2 常用指令
2025-02-16

项目构建#

Terminal window
cd ~/ros2_learning
colcon build --symlink-install
source install/setup.sh

ROS2 常用指令#

节点#

  • ros2 run node 运行对应功能节点

ros2 run turtlesim turtlesim_node ros2 run turtlesim turtle_teleop_key

  • ros2 node list 查看所有正在运行的节点
  • ros2 node info /node 查看正在运行节点的详细信息

话题#

  • ros2 topic list 查看所有已发布的话题
  • ros2 topic echo /node/topic 打印话题发布的信息
  • ros2 topic pub /node/topic msg "detail_info" 针对话题发布指令

其他#

查询所有可用接口

Terminal window
ros2 interface list

查询接口的详细信息

Terminal window
ros2 interface show sensor_msgs/msg/Image

查询所有服务

Terminal window
ros2 service list

调用服务

Terminal window
ros2 service call service_name service_type "values"
# ros2 service call /add_two_ints learning_interface/srv/AddTwoInts "a: 5, b: 10"
  • ros2 action

  • ros2 bag record 录制数据

  • ros2 bag paly 播放录制的数据

  • ros2 action send_goal /node/action act "detail_info" 发送动作

  • colcon build --symlink-install --packages-select package_name


ROS2 环境配置#

ROS2 一键安装:

Terminal window
wget http://fishros.com/install -O fishros && . fishros

ROS2 手动安装:

基本上参考官方手册就能完成配置,唯一需要注意的是拉取 ROS2 仓库时,需要为 raw.githubusercontent.com 的修改 host,可能报错:

ERROR: cannot download default sources list from: 20-default.list. Website may be down.

hosts 配置:

Terminal window
185.199.108.133 raw.githubusercontent.com
185.199.109.133 raw.githubusercontent.com
185.199.110.133 raw.githubusercontent.com
185.199.111.133 raw.githubusercontent.com
20.205.243.166 github.com

ROS2 基础#

创建&编译工作空间#

准备环境和相关工具

Terminal window
sudo apt update
sudo apt install -y python-is-python3
sudo apt install -y python3-pip
sudo apt install python3-colcon-common-extensions

创建工作空间

Terminal window
# ~/
mkdir -p ros2_learning/src
cd ros2_learning

编译工作空间

~/ros2_learning/
git clone https://github.com/ros2/examples src/examples -b foxy
colcon build --symlink-install # colcon build
# 测试构建完成的包
colcon test
# 配置环境
source install/local_setup.sh
# 开启订阅者的测试节点
ros2 run examples_rclcpp_minimal_subscriber subscriber_member_function
# 开启发布者的测试节点
ros2 run examples_rclcpp_minimal_publisher publisher_member_function
  • colcon build:通常用于生产环境或发布阶段,它将会把构建的文件复制到安装目录中,确保安装后的文件是稳定的,不会因为源代码的修改而改变。
  • colcon build --symlink-install:在开发过程中更常用,因为它使用符号链接指向源代码目录,而不是复制文件。

创建包#

在工作空间中创建功能包:

~/ros2_learning/src/
ros2 pkg create --build-type ament_cmake cpp_package
ros2 pkg create --build-type ament_python py_package

创建包时,创建测试节点:

Terminal window
ros2 pkg create --build-type ament_cmake --node-name my_node my_package
  • --node-name 设置节点名称
.
├── [4.0K] cpp_learning_node
│ ├── [1.2K] CMakeLists.txt
│ ├── [4.0K] include
│ ├── [ 601] package.xml
│ └── [4.0K] src
└── [4.0K] py_learning_node
├── [ 630] package.xml
├── [4.0K] py_learning_node
│ └── [ 0] __init__.py
├── [4.0K] resource
│ └── [ 0] py_learning_node
├── [ 101] setup.cfg
├── [ 691] setup.py
└── [4.0K] test

创建节点 Python#

  1. py_learning_node/py_learning_node 中创建代码文件 node_helloworld.py

  2. 测试代码

import rclpy
from rclpy.node import Node
import time
def main(args=None):
rclpy.init(args=args)
node = Node("node_helloworld")
while rclpy.ok():
node.get_logger().info("Hello World")
time.sleep(0.5)
node.destroy_node()
rclpy.shutdown()

或者自定义一个节点类:

import rclpy
from rclpy.node import Node
import time
class HelloWorldNode(Node):
def __init__(self, name):
super().__init__(name)
while rclpy.ok():
self.get_logger().info("Hello World")
time.sleep(0.5)
def main(args=None):
rclpy.init(args=args)
node = HelloWorldNode("node_helloworld_class")
node.destroy_node()
rclpy.shutdown()
  1. 在包配置文件 setup.py 中添加节点信息
from setuptools import setup
package_name = 'py_learning_node'
setup(
....
entry_points={
'console_scripts': [
'node_helloworld = py_learning_node.node_helloworld:main',
'node_helloworld_class = py_learning_node.node_helloworld_class:main',
],
},
)
  1. 退回到工作空间 ~/ros2_learning,构建包
Terminal window
colcon build --symlink-install
source install/setup.sh

创建节点 C++#

基础的参考上文

测试代码:

#include "rclcpp/rclcpp.hpp"
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<rclcpp::Node>("node_helloworld");
RCLCPP_INFO(node->get_logger(), "Hello World");
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}

重点在于 CMakeLists.txt

# 添加 rclcpp 包
find_package(rclcpp REQUIRED)
# 添加节点的关联代码和依赖
add_executable(node_helloworld src/node_helloworld.cpp)
ament_target_dependencies(node_helloworld rclcpp)
# 将编译完成的 node 安装到指定路径
install(TARGETS
node_helloworld
DESTINATION lib/${PROJECT_NAME}
)

接口 interface#

Terminal window
ros2 pkg create --build-type ament_cmake learning_interface

消息 message#

Terminal window
float64 radius # 基础消息
geometry_msgs/Point center # 引用其他包里的消息

其他的基础消息可通过以下指令查看:

Terminal window
ros2 interface show std_msgs/msg/

服务 service#

Terminal window
int64 a # 请求
int64 b
int64 c
---
int64 sum # 结果

动作 action#

参考 Understanding actions

Terminal window
float32 theta # 动作接收端的目标
---
float32 delta # 动作接收端在完成动作后的结果反馈
---
float32 remaining # 动作接收端在执行动作中的实时反馈

CMakeLists.txt#

Terminal window
find_package(geometry_msgs REQUIRED) # 消息中引入了其他包的消息
find_package(rosidl_default_generators REQUIRED) # 定义接口必须导入的包
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/Num.msg"
"msg/Sphere.msg"
"srv/AddThreeInts.srv"
"action/MoveCircle.action"
DEPENDENCIES geometry_msgs # Add packages that above messages depend on, in this case geometry_msgs for Sphere.msg
)

package.xml#

<depend>geometry_msgs</depend>
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
  • 由于接口依赖于 rosidl_default_generators 生成特定语言的代码,因此需要声明对它的构建工具依赖关系。
  • rosidl_default_runtime 是运行时或执行阶段依赖项,需要稍后才能使用接口。
  • rosidl_interface_packages 是您的包应与之关联的依赖项组的名称 tutorial_interfaces,使用 标记声明。

参数 Parameter#

Terminal window
ros2 pkg create --build-type ament_python learning_parameter_py --dependencies rclpy
ros2 pkg create --build-type ament_cmake learning_parameter_cpp --dependencies rclcpp

声明参数:

key = '变量名称'
value = '变量值'
self.declare_parameter(key, value)

获取参数:

param = self.get_parameter('robot_name').get_parameter_value().string_value
# rcl_interfaces.msg.ParameterValue(
# type=4, 类型从1开始计数,4表示第4个元素,string_value
# bool_value=False,
# integer_value=0,
# double_value=0.0,
# string_value='mbot',
# byte_array_value=[],
# bool_array_value=[],
# integer_array_value=[],
# double_array_value=[],
# string_array_value=[])

更新参数:

new_name_param = rclpy.parameter.Parameter('robot_name', rclpy.Parameter.Type.STRING, 'mbot')
new_count_param = rclpy.parameter.Parameter('count', rclpy.Parameter.Type.INTEGER, count_param)
all_new_parameters = [new_name_param, new_count_param]
self.set_parameters(all_new_parameters)

rclpy.Parameter.Type 需要参考 ros2 的 api:https://docs.ros2.org/foxy/api/rclpy/api/parameters.html


参考资料#

ROS1 高效进阶系列

ROS 2 Documentation: Foxy

ROS 2 Foxy API

ROS2 常用指令
https://fuwari.vercel.app/posts/工具/ros2-常用指令/
作者
Asuwee
发布于
2025-02-16
许可协议
CC BY-NC-SA 4.0