ROS2,工作空间中新建了一个python脚本,需要之后作为节点运行。告诉我步骤?
提问
ROS2,工作空间中新建了一个python脚本,需要之后运行。告诉我步骤?
大概要包括而不限于:chmod给可执行权限、setup.py中entry point的配置,如果在launch文件中要使用,还涉及到launch.py文件的配置。最后还要编译(选择功能包编译的执行命令是什么?)
详细步骤提供一下
回答
在 ROS2 中,向工作空间中新建一个 Python 脚本并能够运行它,通常涉及以下几个主要步骤:
🧱 假设前提
- 使用的是 ROS2(如 Foxy、Humble、Iron 等)
- 使用
colcon
构建系统 - 工作空间名为
ros2_ws
,功能包名为my_package
✅ 步骤详解
1️⃣ 在功能包中创建 Python 脚本
路径:ros2_ws/src/my_package/my_package/hello.py
#!/usr/bin/env python3def main():print("Hello from my Python node!")if __name__ == '__main__':main()
2️⃣ 赋予执行权限
在终端中执行:
chmod +x ros2_ws/src/my_package/my_package/hello.py
3️⃣ 配置 setup.py
在 ros2_ws/src/my_package/setup.py
中添加 entry_points
:
from setuptools import setuppackage_name = 'my_package'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='Your Name',maintainer_email='your@email.com',description='Example Python node',license='MIT',tests_require=['pytest'],entry_points={'console_scripts': ['hello_node = my_package.hello:main',],},
)
这一步很关键,hello_node
是你之后在终端运行的命令。
4️⃣ 编译功能包(而不是整个工作空间)
cd ros2_ws
colcon build --packages-select my_package
构建成功后记得 source:
source install/setup.bash
5️⃣ 验证运行
现在可以直接运行:
ros2 run my_package hello_node
6️⃣ 在 Launch 文件中调用(可选)
如果你希望通过 Launch 文件来启动该脚本,需要:
创建 launch/my_launch.py
文件:
from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='my_package',executable='hello_node',name='hello_node',output='screen')])
然后运行:
ros2 launch my_package my_launch.py
✅ 小结流程概览
1. 创建 Python 脚本并加入可执行权限
2. 修改 setup.py 添加 entry_points
3. 使用 colcon 编译指定功能包:--packages-select
4. source 环境
5. 使用 ros2 run 或 ros2 launch 启动
需要我根据你的包结构帮你检查 setup.py
或 Launch 文件吗?可以贴出相关内容我来帮你确认。
继续提问
launch.py 文件里:
usv_sim = Node(
package=‘control_planner’, executable=‘usv_Simulation’, name=‘usv_Simulation’,
output=‘screen’
)
和setup.py文件里:
‘usv_Simulation = control_planner.usvSimV3:main’,
共出现了三次的usv_Simulation ,分别解释其含义
回答
很好的问题,usv_Simulation
在这两处文件中出现的含义不同,涉及 Python 函数名、可执行名、ROS2 节点名。下面分别解释:
🔹 1. setup.py
中的 'usv_Simulation = control_planner.usvSimV3:main'
这是 Python 的 entry point 配置,用于告诉 ROS2 如何从命令行启动这个脚本。
-
'usv_Simulation'
:
这是将来你运行时输入的可执行命令名,例如:ros2 run control_planner usv_Simulation
-
control_planner.usvSimV3
:
表示 Python 模块路径,等价于control_planner/usvSimV3.py
-
main
:
是usvSimV3.py
文件中定义的主入口函数名。
🔹 2. launch.py
中的 executable='usv_Simulation'
这里的 executable
是指要运行的节点程序的名字,也就是上面在 setup.py
中定义的 'usv_Simulation'
,本质上是指令:
ros2 run control_planner usv_Simulation
在 launch 文件中不需要写路径或 .py
后缀,它就是调用你通过 console_scripts
注册的命令名。
🔹 3. name='usv_Simulation'
这个是 ROS2 节点的实际名字,也就是你在 ros2 node list
中看到的名字。
你可以自由设置,比如改成 'my_usv_node'
也可以:
Node(package='control_planner',executable='usv_Simulation',name='my_usv_node',output='screen'
)
✅ 总结对比表
文件位置 | 字段 | 含义 |
---|---|---|
setup.py | 'usv_Simulation = ...' | CLI 命令名 |
launch.py | executable='usv_Simulation' | 执行的 CLI 命令(来源于 setup.py) |
launch.py | name='usv_Simulation' | 节点在 ROS2 网络中的名称 |
如果你需要设置多个脚本或节点启动,只需在 setup.py
中添加更多的 entry points 即可。需要我帮你示例多个节点的 entry point 配置吗?
继续提问
我记得ROS1里面,python文件如果要作为节点,需要在脚本里面就指定节点的名称。在ROS2里,是不是脚本里不需要指定节点名称?而是直接在setup.py里面指定?
回答
这是一个关键区别点,确实 ROS2 与 ROS1 在节点命名上有很大不同。下面我详细解释一下:
✅ ROS1 中节点命名方式
在 ROS1 中,节点名称是必须在 Python 脚本内部通过 rospy.init_node()
指定的:
import rospyrospy.init_node('my_node_name') # 这里显式命名
所以,节点名是在脚本中硬编码的。
✅ ROS2 中节点命名方式
在 ROS2 中,使用 rclpy
时:
- 节点名称通常是在创建
Node
类实例时传入。 - 可以在 Python 脚本中指定默认节点名,但它不是强制的,可以通过 Launch 文件动态覆盖。
示例 1:在 Python 脚本中指定默认名称(可覆盖)
import rclpy
from rclpy.node import Nodeclass MyNode(Node):def __init__(self):super().__init__('default_node_name') # 默认节点名称def main(args=None):rclpy.init(args=args)node = MyNode()rclpy.spin(node)node.destroy_node()rclpy.shutdown()
你可以在 launch 文件中使用:
Node(package='my_package',executable='my_executable',name='override_name', # 会覆盖上面 default_node_name
)
➡️ 这个覆盖行为是 ROS2 支持的核心能力之一,因此推荐你在脚本中提供默认节点名,在 launch 文件中灵活覆盖。
🔍 那 setup.py
呢?
setup.py
中并不指定 ROS 节点名,它只做:
- 注册命令行入口
- 将
.py
脚本打包可执行
节点名永远不会在 setup.py
中设置,它属于运行时的东西(由 Python 脚本或 launch 文件设置)。
✅ 总结
项目 | ROS1 | ROS2 |
---|---|---|
节点名称设置 | rospy.init_node('name') | Node('name') ,可被 launch 覆盖 |
launch 覆盖 | 不支持 | 支持 |
setup.py | 不涉及节点名 | 只管 CLI 命令名,不涉及节点名 |
需要我帮你改造某个 Python 脚本,让它更符合 ROS2 节点规范吗?可以贴代码我来帮你。