• 【ROS2初级知识10】: ROS2的参数(Python)


    前言

            本篇是一个在python下实现ROS2的参数例子,其主贴已经在ROS2初级知识(5):参数如何管理?中叙述,这篇文章只是一个继续演练的样例。通过这个练习,可以熟悉在python下的编程方式。

    1.创建功能包

            在dev_ws工作空间的src文件夹中,创建一个功能包cpp_parameters:

    ros2 pkg create --build-type ament_python python_parameters --dependencies rclpy

    要点: 

            1)在生成包的时候,需要指明几个方面

    命令意义
    ros2 pkg create生成包的指令
    --build-type 指定编译工具,这里是:   ament_python
    python_parameters包的名称
    --dependencies 依赖项,这里是:rclpy

            2) 创建功能包时,使用了 --dependencies参数,会自动添加一些依赖项在 package.xml和 CMakeLists.txt文件中,所以就不需要特意设置了。但是我们最好还是打开package.xml文件,在其中填写完整以下这些描述信息。

    1. <description>Python parameter tutorialdescription>
    2. <maintainer email="huchunxu@guyuehome.com">Hu Chunxumaintainer>
    3. <license>Apache License 2.0license>

    2.编写Python代码

            在dev_ws/src/python_parameters/python_parameters路径下,创建一个名为python_parameters_node.py的代码文件,然后复制粘贴如下代码内容:

    1. import rclpy
    2. import rclpy.node
    3. from rclpy.exceptions import ParameterNotDeclaredException
    4. from rcl_interfaces.msg import ParameterType
    5. class MinimalParam(rclpy.node.Node):
    6. def __init__(self):
    7. super().__init__('minimal_param_node')
    8. timer_period = 2 # seconds
    9. self.timer = self.create_timer(timer_period, self.timer_callback)
    10. self.declare_parameter('my_parameter', 'world')
    11. def timer_callback(self):
    12. my_param = self.get_parameter('my_parameter').get_parameter_value().string_value
    13. self.get_logger().info('Hello %s!' % my_param)
    14. my_new_param = rclpy.parameter.Parameter(
    15. 'my_parameter',
    16. rclpy.Parameter.Type.STRING,
    17. 'world'
    18. )
    19. all_new_parameters = [my_new_param]
    20. self.set_parameters(all_new_parameters)
    21. def main():
    22. rclpy.init()
    23. node = MinimalParam()
    24. rclpy.spin(node)
    25. if __name__ == '__main__':
    26. main()

    2.1 代码解析

            我们来解释一下以上代码的关键部分。

    1. import rclpy
    2. import rclpy.node
    3. from rclpy.exceptions import ParameterNotDeclaredException
    4. from rcl_interfaces.msg import ParameterType

            首先导入一些后续要用到的模块,这里需要注意一个ParameterNotDeclaredException,在未来使用参数之前,需要先声明,否则可以使用这个来触发异常。

    1. class MinimalParam(rclpy.node.Node):
    2. def __init__(self):
    3. super().__init__('minimal_param_node')
    4. timer_period = 2 # seconds
    5. self.timer = self.create_timer(timer_period, self.timer_callback)
    6. self.declare_parameter('my_parameter', 'world')

            这段代码是MinimalParam类的构造函数,其中先是创建了一个2s周期的定时器,触发timer_callback函数。,然后声明一个ROS参数,参数名为my_parameter,参数值为“world”。

    1. def timer_callback(self):
    2. my_param = self.get_parameter('my_parameter').get_parameter_value().string_value
    3. self.get_logger().info('Hello %s!' % my_param)
    4. my_new_param = rclpy.parameter.Parameter(
    5. 'my_parameter',
    6. rclpy.Parameter.Type.STRING,
    7. 'world'
    8. )
    9. all_new_parameters = [my_new_param]
    10. self.set_parameters(all_new_parameters)

            在timer_callback函数中,第一行会查询“my_parameter”参数,并且保存在my_param中,紧接着第二行就把查询到的参数值打印出来了,之后又将“world”保存回“my_parameter”参数中。

    1. def main():
    2. rclpy.init()
    3. node = MinimalParam()
    4. rclpy.spin(node)
    5. if __name__ == '__main__':
    6. main()

            main函数是以上定义类的具体实例化调用过程,先是初始了节点,接下来就开始处理类的构建和启动定时器。

    2.2 添加参数描述(可选)

    我们还可以给参数添加一个描述,通过字符串的形式描述参数的作用,修改代码如下即可:

    1. # ...
    2. class MinimalParam(rclpy.node.Node):
    3. def __init__(self):
    4. super().__init__('minimal_param_node')
    5. timer_period = 2 # seconds
    6. self.timer = self.create_timer(timer_period, self.timer_callback)
    7. from rcl_interfaces.msg import ParameterDescriptor
    8. my_parameter_descriptor = ParameterDescriptor(description='This parameter is mine!')
    9. self.declare_parameter('my_parameter',
    10. 'default value for my_parameter',
    11. my_parameter_descriptor)

            在之后运行代码时,使用如下指令即可查询参数的描述:

    ros2 param describe /minimal_param_node my_parameter

    2.3 添加程序入口

            接下来打开setup.py文件,先按照package.xml的内容补充如下信息:

    1. maintainer='Hu Chunxu',
    2. maintainer_email='huchunxu@guyuehome.com',
    3. description='Python parameter tutorial',
    4. license='Apache License 2.0',

            然后在entry_points之后添加如下内容,让终端知道从何处启动python程序:

    1. entry_points={
    2. 'console_scripts': [
    3. 'param_talker = python_parameters.python_parameters_node:main',
    4. ],
    5. },

    3.编译运行

    首先确认功能包的依赖是否有安装完成,如果又缺少的依赖则会自动安装:

    rosdep install -i --from-path src --rosdistro foxy -y

    在终端中回到dev_ws工作空间的根目录下,使用如下命令编译工作空间:

    colcon build --packages-select python_parameters

            打开一个新的终端,还是进入到dev_ws工作空间根目录下,先设置工作空间的环境变量,接下来就可以运行编译完成的节点了。

    1. . install/setup.bash
    2. ros2 run python_parameters param_talker

            在终端中就可以看到每秒会有一个参数值的输出日志了。

            这个值是我们在程序中设置的参数默认值,如果我们想修改它,该如何做呢?

    3.1 通过终端修改参数值

            不要关闭刚才运行的参数功能节点,打开一个新终端,使用如下命令查询当前所有参数列表。

    ros2 param list

            在列表中可以看到my_parameter这个参数,接下来就可以通过如下命令行来修改这个参数的值了。

    ros2 param set /minimal_param_node my_parameter earth

            这样,我们就将my_parameter参数的值修改为“earth”了,此时刚才运行节点的终端中,也会变成如下日志输出,因为主程序中还会周期重设参数为“world”,所以看到的日志信息会有参数的变化.

     3.2 通过Launch文件修改参数值

            在ROS2中也可以通过Launch文件来设置参数值。在python_parameters功能包中,创建一个launch文件夹,并在其中创建python_parameters_launch.py,复制粘贴如下内容:

    1. from launch import LaunchDescription
    2. from launch_ros.actions import Node
    3. def generate_launch_description():
    4. return LaunchDescription([
    5. Node(
    6. package='python_parameters',
    7. executable='param_talker',
    8. name='custom_parameter_node',
    9. output='screen',
    10. emulate_tty=True,
    11. parameters=[
    12. {'my_parameter': 'earth'}
    13. ]
    14. )
    15. ])

            在以上launch文件的最后几行,可以看到我们依然是把my_parameter设置为了“earth”。

            要运行launch文件,还需要在setup.py文件中配置一下。

    1. import os
    2. from glob import glob
    3. # ...
    4. setup(
    5. # ...
    6. data_files=[
    7. # ...
    8. (os.path.join('share', package_name), glob('launch/*_launch.py')),
    9. ]
    10. )

            在终端中回到dev_ws工作空间根目录下,然后重新编译一下。

    colcon build --packages-select python_parameters

            接下来一样的操作,设置工作空间环境变量,再运行launch文件。

    1. . install/setup.bash
    2. ros2 launch python_parameters python_parameters_launch.py

    终端中就可以看到参数修改之后的日志输出了。

  • 相关阅读:
    Selenium-元素操作、浏览器操作方法
    12 Synchronized与锁升级
    Android Termux安装MySQL,内网穿透实现公网远程访问
    gorm操作数组
    浅说一下 import.meta.glob()
    SQL Server如何建表
    怎样优雅劝退他人做自媒体?
    动手学深度学习-深度学习基础
    读《中国省级移动政务服务报告2023》
    27.EI文章复现《高比例清洁能源接入下计及需求响应的配电网重构》
  • 原文地址:https://blog.csdn.net/gongdiwudu/article/details/125895261