欢迎光临
我们一直在努力

ROS2 Service、参数与 Launch 一键启动复盘:/robot/set_mode 模式切换实现

创建纯 Python 包(生成 setup.py 结构):

ros2 pkg create –build-type ament_python 包名

创建 C++/接口包(生成 CMakeLists.txt 结构):

ros2 pkg create –build-type ament_cmake 包名

1. Service 的作用

ROS2 中,Service 适合处理“一次请求,一次响应”的任务。

/robot/set_mode 的本质是:

客户端请求机器人切换模式,服务端判断是否合法,然后返回成功或失败。

它不像 Topic 那样持续发布数据,而是更像一次函数调用。


2. 自定义 Service 接口

文件位置:robot_interfaces/srv/SetMode.srv

string mode

bool success
string message

字段

所属部分

作用

mode

Request

客户端请求切换的模式

success

Response

服务端返回是否成功

message

Response

服务端返回说明信息

这里的 — 用来分隔请求部分和响应部分。


3. 接口包 package.xml 配置

robot_interfaces 是专门放自定义接口的包。

<build_depend>rosidl_default_generators</build_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

声明这是一个接口包


4. 接口包 CMakeLists.txt 配置

find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
"srv/SetMode.srv"
)

这段代码告诉 ROS2:

请把 SetMode.srv 生成为 Python/C++ 可以调用的 Service 接口。


5. 功能包依赖接口包

在 robot_base/package.xml 中加入:

<depend>robot_interfaces</depend>

含义是:

robot_base 需要使用 robot_interfaces 中定义的自定义 Service。

没有这个依赖,robot_base 就无法导入 SetMode。


6. 服务节点入口注册

在 robot_base/setup.py 中注册节点:

entry_points={
'console_scripts': [
'mode_service_node = robot_base.mode_service_node:main',
],
},

这表示之后可以通过 ROS2 运行 mode_service_node 这个节点。


7. /robot/set_mode 核心代码

文件位置:robot_base/robot_base/mode_service_node.py

import rclpy
from rclpy.node import Node

from robot_interfaces.srv import SetMode

class ModeServiceNode(Node):
def __init__(self):
super().__init__('mode_service_node')

self.current_mode = 'stop'
self.valid_modes = {'stand', 'walk', 'stop', 'estop'}

self.declare_parameter('max_linear_speed', 0.3)
self.declare_parameter('max_angular_speed', 0.8)
self.declare_parameter('safe_distance', 0.5)

self.service = self.create_service(
SetMode,
'/robot/set_mode',
self.handle_set_mode
)

self.get_logger().info('/robot/set_mode service is ready')

def handle_set_mode(self, request, response):
mode = request.mode

if mode not in self.valid_modes:
response.success = False
response.message = f'Invalid mode: {mode}'
self.get_logger().warn(response.message)
return response

self.current_mode = mode

response.success = True
response.message = f'Successfully switched to {mode} mode'

self.get_logger().info(response.message)
return response

def main(args=None):
rclpy.init(args=args)

node = ModeServiceNode()
rclpy.spin(node)

node.destroy_node()
rclpy.shutdown()


8. 代码逻辑理解

这段节点代码可以拆成四层:

层级

作用

初始化节点

创建 mode_service_node

声明参数

配置最大速度和安全距离

创建 Service

暴露 /robot/set_mode

处理请求

判断模式是否合法并返回结果

核心判断逻辑是:

if mode not in self.valid_modes:
response.success = False
response.message = f'Invalid mode: {mode}'
return response

这表示:

如果客户端传入的模式不在允许列表中,就拒绝切换。


9. 支持的机器人模式

self.valid_modes = {'stand', 'walk', 'stop', 'estop'}

模式

含义

stand

站立或准备状态

walk

行走状态

stop

普通停止

estop

紧急停止

其中 estop 是 emergency stop,表示紧急停止。真实机器人中,它的安全优先级通常最高。


10. 参数代码理解

self.declare_parameter('max_linear_speed', 0.3)
self.declare_parameter('max_angular_speed', 0.8)
self.declare_parameter('safe_distance', 0.5)

这三个参数分别表示:

参数

作用

max_linear_speed

限制最大前进速度

max_angular_speed

限制最大旋转速度

safe_distance

设置安全距离阈值

这些值做成参数的好处是:

后续调试不同机器人或不同场地时,不需要修改代码,只需要调整参数。


11. 验证方式

验证目标

使用内容

查看接口定义

ros2 interface show robot_interfaces/srv/SetMode

启动服务节点

ros2 run robot_base mode_service_node

查看服务列表

ros2 service list

调用合法模式

ros2 service call /robot/set_mode robot_interfaces/srv/SetMode "{mode: 'walk'}"

调用非法模式

ros2 service call /robot/set_mode robot_interfaces/srv/SetMode "{mode: 'run'}"

查看参数

ros2 param list

获取参数值

ros2 param get /mode_service_node max_linear_speed


12. Launch 文件的作用

ROS2 的 launch 文件可以理解为“节点启动脚本”。

当项目只有一个节点时,可以手动启动;但当系统里有多个节点,比如模式切换、状态发布、速度控制、视觉感知、FSM 状态机时,一个个开终端会很麻烦。

所以 launch 主要解决:

问题

作用

多节点启动麻烦

一条命令统一启动

参数配置分散

启动时统一传入参数

Demo 展示不方便

面试时可以快速启动系统

Launch 负责“怎么启动系统”,节点代码负责“系统启动后做什么”。


13. 当前 launch 文件代码

文件位置:

src/robot_base/launch/mode_service_launch.py

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
mode_service_node = Node(
package='robot_base',
executable='mode_service_node',
name='mode_service_node',
output='screen',
parameters=[
{
'max_linear_speed': 0.3,
'max_angular_speed': 0.8,
'safe_distance': 0.5,
}
]
)

return LaunchDescription([
mode_service_node
])

这段代码的核心作用是:启动 robot_base 包中的 mode_service_node 节点,并传入运行参数。

配置

含义

package='robot_base'

节点来自 robot_base 包

executable='mode_service_node'

启动注册过的节点入口

name='mode_service_node'

设置节点名称

output='screen'

日志输出到终端

parameters=[…]

启动时传入 ROS2 参数


14. setup.py 中安装 launch 文件

为了让 ROS2 能通过 ros2 launch 找到 launch 文件,需要在 setup.py 中安装它。

需要在文件顶部加入:

import os
from glob import glob

然后在 data_files 中加入:

(
os.path.join('share', package_name, 'launch'),
glob('launch/*.py')
),

把 launch 目录下的 .py 文件安装到 ROS2 包的共享目录中。

如果没有这一步,可能会出现 launch 文件找不到的问题。


15. 验证结果

常用验证命令:

目的

命令

启动 launch

ros2 launch robot_base mode_service_launch.py

查看节点

ros2 node list

查看服务

ros2 service list

查看参数

ros2 param get /mode_service_node safe_distance

调用服务

ros2 service call /robot/set_mode robot_interfaces/srv/SetMode "{mode: 'walk'}"

赞(0)
未经允许不得转载:171主机测评 » ROS2 Service、参数与 Launch 一键启动复盘:/robot/set_mode 模式切换实现
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址