ROS2 细节知识学习

1. rosidl_generate_interfaces()

在 ROS2 中,rosidl_generate_interfaces是一个关键的构建工具功能。它主要用于从接口定义文件(如.msg消息文件.srv服务文件.action动作文件)生成不同编程语言(如 C++、Python 等)可以使用的接口代码。这些接口是 ROS2 中节点间通信的基础,确保了数据在不同组件之间能够准确、高效地传递。

在构建系统中的使用(以 CMake 为例)

find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/Odometry.msg"
  "srv/GetRobotStatus.srv"
  "action/MoveToPosition.action"
  DEPENDENCIES std_msgs geometry_msgs
)

1. 通过find_package找到rosidl_default_generators包,它提供了生成接口代码的工具。

2. rosidl_generate_interfaces函数被调用,${PROJECT_NAME}是生成代码所属的项目名称。

3. 后面列出了要生成接口的消息服务动作文件,并且通过DEPENDENCIES关键字指定了这些接口所依赖的其他消息包(如std_msgsgeometry_msgs

4. 在package.xml文件中进行功能包声明

  
  rosidl_interface_packages

2. colcon build 需要在工作空间目录_ws下执行

3.rclcpp::spin_until_future_complete(this->get_node_base_interface(), future)

1. 函数所属的库及作用

在 ROS 2 的编程模式里,节点通常是事件驱动的,需要处理诸如服务请求响应、订阅话题的消息接收等各种异步事件。这个函数的主要作用就是在节点的执行流程中,阻塞当前线程,直到指定的异步操作完成,确保能正确获取到异步操作的结果并进行后续处理,同时也让节点有机会去处理其他相关的回调等事件,维持整个节点的正常运行逻辑。

2. 函数的参数含义

第一个参数
this->get_node_base_interface() 通常返回节点的基础接口指针。在 rclcpp 框架中,节点有不同层面的接口来提供各种功能,基础接口包含了节点运行的一些基本要素和操作,比如管理节点的生命周期、执行回调等基础功能相关的能力。将节点的基础接口传递进去,使得函数能够在这个节点的上下文环境中去执行等待操作,确保和节点本身的其他运行机制协同工作,比如在等待的过程中,节点还可以处理其他已经触发的回调函数等情况。

第二个参数future

future代表一个异步操作的未来结果占位符。在 ROS 2 中,当进行很多异步操作时(例如异步地发送服务请求、异步地订阅话题等),不会立刻得到实际的操作结果,而是返回一个 future 对象。这个对象像是一个 “承诺”,表示将来某个时刻操作完成后会在其中存放对应的结果。比如通过客户端异步发送服务请求(client->async_send_request(request) 这样的调用),返回的就是一个 future 对象,后续就可以把这个 future 对象传递给 rclcpp::spin_until_future_complete 函数来等待该服务请求操作最终完成并获取到服务端返回的响应结果。

3. 函数的执行流程和内部机制

当调用 rclcpp::spin_until_future_complete 时,它会进入一个循环等待的状态:

  • 首先,它会检查 future 所代表的异步操作是否已经完成。这是通过查看future的内部状态来判断的,future 内部会有相应的机制来标记其关联的异步操作是否结束,例如服务请求是否已经从服务端收到了回复等情况。
  • 在等待的过程中,它并不会让节点 “僵死”,而是会允许节点的基础接口(也就是传入的第一个参数所关联的节点运行环境)去处理其他已经触发的回调函数。例如,如果节点同时订阅了多个话题,在等待这个 future 对应的异步服务请求完成期间,若有新的话题消息到达,节点依然可以调用相应的话题回调函数进行处理,这就保证了节点整体的事件处理能力不会因为等待某一个异步操作而完全停滞。
  • 一旦 future 对应的异步操作完成,函数就会结束阻塞状态,继续执行后续的代码,此时通常就可以通过 future.get() 这样的操作从 future 对象中获取到具体的结果(比如服务请求对应的服务端响应内容等),然后基于这个结果进行后续的业务逻辑处理,比如判断服务请求是否成功、解析响应数据等操作。

第六章 建模与仿真-创建自己的机器人

1. launch.actions.DeclareLaunchArgument()

launch.actions.DeclareLaunchArgument是 ROS 2 中launch框架里用于声明启动参数的一个类。

1. 作用和用途

在 ROS 2 的启动系统中,很多时候需要在启动时能够灵活地配置一些参数,而不是将所有的配置都写死在代码里。launch.actions.DeclareLaunchArgument的作用就是定义这些可以在启动时传入的参数,它允许用户在启动相关节点或者整个 ROS 系统时,通过命令行、启动配置文件等方式来指定具体的值,从而使系统的启动更加灵活、可配置。

例如,你可能有一个机器人的驱动节点,这个节点需要连接到不同的硬件设备,而硬件设备的 IP 地址或者端口号等信息可以通过声明启动参数的方式,在启动时根据实际情况来设定,而不用每次都去修改代码中的固定值。

2. 构造函数及常用参数

它的构造函数接受多个参数来定义一个启动参数,以下是一些比较常用的参数:

  • name(必选)
    这是启动参数的名称,是一个字符串类型。在后续的启动配置以及启动命令中,会通过这个名称来引用该参数。比如,你定义了一个名为 'my_param' 的参数,之后在其他地方就可以通过 LaunchConfiguration('my_param') 这样的方式来获取它的值。

  • default_value(可选)
    用于指定参数的默认值。其类型根据具体参数的性质而定,可以是字符串、整数、布尔值等各种类型对应的 Python 表示形式(不过在传入时通常都要转换为合适的 Python 类型,比如数值类型传入对应的数字,字符串传入带引号的文本等)。如果在启动时用户没有显式指定该参数的值,那么系统就会采用这个默认值。例如,对于一个表示机器人最大速度的参数,你可以将默认值设为 1.0(假设速度单位是米 / 秒),代码示例如下:

launch.actions.DeclareLaunchArgument(
    name='max_speed',
    default_value='1.0'
)
  • description(可选)
    这是对参数的一个简单描述,用于帮助使用者理解该参数的含义和用途。通常在生成文档或者在命令行提示等场景下会展示这个描述信息,方便用户知道每个参数是做什么的。例如:
launch.actions.DeclareLaunchArgument(
    name='target_ip',
    default_value='127.0.0.1',
    description='The IP address of the target device.'
)

2.  launch.substitutions.LaunchConfiguration()

当使用launch.actions.DeclareLaunchArgument声明了一个启动参数后,就可以使用LaunchConfiguration来获取该参数的值

3. launch.substitutions.Command()

用于执行外部命令并获取其输出结果的工具,相当于在文件中使用终端命令

假设要在启动文件中获取当前目录下的文件列表作为一个参数值(这可能不太符合实际场景,但用于说明用法),可以这样写:

import launch
import launch.substitutions
import launch_ros.parameter_descriptions

file_list_value = launch.substitutions.Command(['ls'])
parameter_value = launch_ros.parameter_descriptions.ParameterValue(file_list_value, value_type = str)

在这个例子中,Command(['ls'])会在启动时执行ls命令,然后ParameterValue将命令的输出结果(文件列表)转换为字符串类型的参数值,用于后续节点的参数配置等操作

4. launch_ros.parameter_descriptions.ParameterValue()

用于定义传递给 ROS 节点的参数的值和类型,在 ROS 系统中,节点的参数可以有多种来源和形式,例如通过用户在启动时指定、从文件读取或者通过计算得到等。ParameterValue类提供了一种统一的方式来处理这些不同类型的参数,确保节点能够正确接收和使用它们

如果你传递的value是一个字符串表示的数字,并且你希望它被当作浮点数处理,可以这样写:ParameterValue('3.14', value_type = float)

5. launch.LaunchDescription()

用于将一系列启动相关的操作、配置以及节点启动信息等组织在一起,形成一个完整的启动描述,告诉ROS2系统在启动时需要执行哪些具体的任务,例如启动哪些节点、配置哪些参数以及遵循怎样的启动顺序等

你可能感兴趣的:(ROS2系列,机器人,c++,linux)