Python 软件包迁移参考
本页面是关于如何将 Python 软件包从 ROS 1 迁移到 ROS 2 的参考。 如果你是首次迁移 Python 软件包,请先按照此指南迁移一个示例 Python 软件包。
ROS 2 不再使用 catkin_make、catkin_make_isolated 或 catkin build,而是使用命令行工具 colcon 来构建和安装一组软件包。
请参阅 入门教程 来开始使用 colcon。
对于纯 Python 软件包,ROS 2 使用 Python 开发者熟悉的标准 setup.py 安装机制。
更新文件以使用 setup.py
Section titled “更新文件以使用 setup.py”如果 ROS 1 软件包仅使用 CMake 来调用 setup.py 文件,并且不包含 Python 代码以外的任何内容(例如没有消息、服务等),则应将其转换为 ROS 2 中的纯 Python 软件包:
-
更新或在
package.xml文件中添加构建类型:<export><build_type>ament_python</build_type></export> -
删除
CMakeLists.txt文件 -
更新
setup.py文件为标准的 Python setup 脚本
ROS 2 仅支持 Python 3。 虽然每个软件包可以选择同时支持 Python 2,但如果它使用了其他 ROS 2 软件包提供的任何 API,则必须使用 Python 3 来调用可执行文件。
在 ROS 1 中:
rospy.init_node('asdf')
rospy.loginfo('Created node')在 ROS 2 中:
with rclpy.init(args=sys.argv): node = rclpy.create_node('asdf')
node.get_logger().info('Created node')ROS 参数
Section titled “ROS 参数”在 ROS 1 中:
port = rospy.get_param('port', '/dev/ttyUSB0')assert isinstance(port, str), 'port parameter must be a str'
baudrate = rospy.get_param('baudrate', 115200)assert isinstance(baudrate, int), 'baudrate parameter must be an integer'
rospy.logwarn('port: ' + port)在 ROS 2 中:
port = node.declare_parameter('port', '/dev/ttyUSB0').valueassert isinstance(port, str), 'port parameter must be a str'
baudrate = node.declare_parameter('baudrate', 115200).valueassert isinstance(baudrate, int), 'baudrate parameter must be an integer'
node.get_logger().warn('port: ' + port)创建 Publisher
Section titled “创建 Publisher”在 ROS 1 中:
pub = rospy.Publisher('chatter', String)# orpub = rospy.Publisher('chatter', String, queue_size=10)在 ROS 2 中:
pub = node.create_publisher(String, 'chatter', rclpy.qos.QoSProfile())# orpub = node.create_publisher(String, 'chatter', 10)创建 Subscriber
Section titled “创建 Subscriber”在 ROS 1 中:
sub = rospy.Subscriber('chatter', String, callback)# orsub = rospy.Subscriber('chatter', String, callback, queue_size=10)在 ROS 2 中:
sub = node.create_subscription(String, 'chatter', callback, rclpy.qos.QoSProfile())# orsub = node.create_subscription(String, 'chatter', callback, 10)创建 Service
Section titled “创建 Service”在 ROS 1 中:
srv = rospy.Service('add_two_ints', AddTwoInts, add_two_ints_callback)在 ROS 2 中:
srv = node.create_service(AddTwoInts, 'add_two_ints', add_two_ints_callback)创建 Service Client
Section titled “创建 Service Client”在 ROS 1 中:
rospy.wait_for_service('add_two_ints')add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)resp = add_two_ints(req)在 ROS 2 中:
add_two_ints = node.create_client(AddTwoInts, 'add_two_ints')while not add_two_ints.wait_for_service(timeout_sec=1.0): node.get_logger().info('service not available, waiting again...')resp = add_two_ints.call_async(req)rclpy.spin_until_future_complete(node, resp)警告: 不要在 ROS 2 回调中使用
rclpy.spin_until_future_complete。 有关更多详细信息,请参阅同步死锁文章。