MPL_ROS与ROS 2迁移指南:从ROS Kinetic到ROS 2 Foxy的完整迁移方案

MPL_ROS与ROS 2迁移指南:从ROS Kinetic到ROS 2 Foxy的完整迁移方案

MPL_ROS与ROS 2迁移指南:从ROS Kinetic到ROS 2 Foxy的完整迁移方案

【免费下载链接】mpl_rosA ROS wrapper for trajectory planning based on motion primitives项目地址: https://gitcode.com/gh_mirrors/mp/mpl_ros

欢迎来到MPL_ROS(Motion Primitive Library ROS)的ROS 2迁移完整指南!🚀 本文将详细介绍如何将基于运动基元的轨迹规划库从传统的ROS Kinetic平滑迁移到现代化的ROS 2 Foxy环境。无论您是机器人开发者还是ROS迁移新手,这篇指南都将为您提供清晰的步骤和实用的技巧。

MPL_ROS是一个强大的ROS包装器,专门用于基于运动基元(Motion Primitives)的轨迹规划。该项目在ROS 1生态系统中已经相当成熟,但随着ROS 2的普及,迁移到新平台成为了必然趋势。本文将带您了解从ROS Kinetic到ROS 2 Foxy的完整迁移方案。

📊 ROS 1与ROS 2架构对比

在开始迁移之前,让我们先了解两个版本的核心差异:

特性ROS 1 (Kinetic)ROS 2 (Foxy)
通信机制TCPROS/UDPROSDDS (Data Distribution Service)
节点生命周期简单启动/关闭完善的状态机管理
参数系统基于XML动态参数服务
构建系统catkincolcon + ament
Python版本Python 2.7Python 3.8+

MPL_ROS在2D占用网格地图中的轨迹规划效果

🔧 迁移准备与工具链

1. 环境配置检查

在开始迁移前,请确保您的系统满足以下要求:

  • Ubuntu 20.04 (ROS 2 Foxy官方支持)
  • ROS 2 Foxy Fitzroy已安装
  • Python 3.8或更高版本
  • CMake 3.5+
  • 必要的依赖包:libsdl1.2-dev,libsdl-image1.2-dev

2. 项目结构分析

MPL_ROS项目包含以下关键包,每个都需要单独迁移:

  1. motion_primitive_library- 核心轨迹规划算法
  2. planning_ros_msgs- ROS消息定义
  3. planning_ros_utils- ROS工具和插件
  4. mpl_external_planner- 外部规划器
  5. mpl_test_node- 测试节点和示例

MPL_ROS在3D体素地图中的轨迹规划效果

📝 消息定义迁移

ROS 1消息文件分析

planning_ros_msgs/msg/目录中,MPL_ROS定义了多个自定义消息类型:

  • VoxelMap.msg- 体素地图数据
  • PrimitiveArray.msg- 运动基元数组
  • PathArray.msg- 路径数组
  • Trajectory.msg- 轨迹数据

ROS 2消息迁移步骤

步骤1:创建新的package.xml

ROS 2使用不同的package.xml格式:

<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package format="3"> <name>planning_ros_msgs</name> <version>0.0.0</version> <description>ROS 2 messages for MPL planning library</description> <maintainer email="sikang@seas.upenn.edu">sikang</maintainer> <license>Apache-2.0</license> <buildtool_depend>ament_cmake</buildtool_depend> <depend>std_msgs</depend> <depend>geometry_msgs</depend> <depend>nav_msgs</depend> <depend>sensor_msgs</depend> <member_of_group>rosidl_interface_packages</member_of_group> <test_depend>ament_lint_auto</test_depend> <test_depend>ament_lint_common</test_depend> </package>
步骤2:更新CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(planning_ros_msgs) # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() find_package(ament_cmake REQUIRED) find_package(rosidl_default_generators REQUIRED) find_package(std_msgs REQUIRED) find_package(geometry_msgs REQUIRED) find_package(nav_msgs REQUIRED) find_package(sensor_msgs REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "msg/VoxelMap.msg" "msg/PrimitiveArray.msg" "msg/PathArray.msg" "msg/Trajectory.msg" DEPENDENCIES std_msgs geometry_msgs nav_msgs sensor_msgs ) ament_export_dependencies(rosidl_default_runtime) ament_export_include_directories(include) ament_package()

VoxelMap消息的类结构图

🔄 节点代码迁移

ROS 1节点示例分析

mpl_test_node/src/map_planner_node.cpp为例,ROS 1代码结构:

#include <ros/ros.h> int main(int argc, char **argv) { ros::init(argc, argv, "test"); ros::NodeHandle nh("~"); ros::Publisher map_pub = nh.advertise<planning_ros_msgs::VoxelMap>("voxel_map", 1, true); // ROS 1参数获取 double goal_x; nh.param("goal_x", goal_x, 2.4); ros::spin(); return 0; }

ROS 2节点迁移版本

#include "rclcpp/rclcpp.hpp" #include "planning_ros_msgs/msg/voxel_map.hpp" class MapPlannerNode : public rclcpp::Node { public: MapPlannerNode() : Node("map_planner_node") { // ROS 2参数声明 this->declare_parameter("goal_x", 2.4); this->declare_parameter("goal_y", 16.6); this->declare_parameter("goal_z", 0.05); // 获取参数值 double goal_x = this->get_parameter("goal_x").as_double(); // 创建发布者(ROS 2风格) map_pub_ = this->create_publisher<planning_ros_msgs::msg::VoxelMap>( "voxel_map", rclcpp::QoS(10).reliable().transient_local() ); // 定时器回调 timer_ = this->create_wall_timer( std::chrono::milliseconds(100), std::bind(&MapPlannerNode::timer_callback, this) ); } private: void timer_callback() { auto message = planning_ros_msgs::msg::VoxelMap(); // 填充消息... map_pub_->publish(message); } rclcpp::Publisher<planning_ros_msgs::msg::VoxelMap>::SharedPtr map_pub_; rclcpp::TimerBase::SharedPtr timer_; }; int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node = std::make_shared<MapPlannerNode>(); rclcpp::spin(node); rclcpp::shutdown(); return 0; }

PrimitiveArray消息的类结构图

🚀 Launch文件迁移

ROS 1 Launch文件示例

mpl_test_node/launch/map_planner_node/test.launch

<launch> <node pkg="mpl_test_node" type="map_planner_node" name="test_primitive" output="screen"> <param name="goal_x" value="2.4"/> <param name="goal_y" value="16.6"/> </node> </launch>

ROS 2 Launch文件迁移

创建对应的Python launch文件:

from launch import LaunchDescription from launch_ros.actions import Node from launch.substitutions import LaunchConfiguration from launch.actions import DeclareLaunchArgument def generate_launch_description(): return LaunchDescription([ DeclareLaunchArgument( 'goal_x', default_value='2.4', description='Goal X coordinate' ), DeclareLaunchArgument( 'goal_y', default_value='16.6', description='Goal Y coordinate' ), Node( package='mpl_test_node', executable='map_planner_node', name='test_primitive', output='screen', parameters=[{ 'goal_x': LaunchConfiguration('goal_x'), 'goal_y': LaunchConfiguration('goal_y'), 'goal_z': 0.05, 'v_max': 2.0, 'a_max': 1.0 }] ) ])

🛠️ 构建系统迁移

ROS 1构建配置

ROS 1使用catkin构建系统,CMakeLists.txt示例:

cmake_minimum_required(VERSION 2.8.3) project(mpl_test_node) find_package(catkin_simple REQUIRED) find_package(motion_primitive_library REQUIRED) catkin_simple() cs_add_executable(map_planner_node src/map_planner_node.cpp) target_link_libraries(map_planner_node ${catkin_LIBRARIES})

ROS 2构建配置

ROS 2使用ament_cmake,CMakeLists.txt需要更新:

cmake_minimum_required(VERSION 3.5) project(mpl_test_node) # 默认使用C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) find_package(planning_ros_msgs REQUIRED) find_package(motion_primitive_library REQUIRED) # 添加可执行文件 add_executable(map_planner_node src/map_planner_node.cpp) ament_target_dependencies(map_planner_node rclcpp std_msgs planning_ros_msgs ) # 链接库 target_link_libraries(map_planner_node ${motion_primitive_library_LIBRARIES} ) # 安装目标 install(TARGETS map_planner_node DESTINATION lib/${PROJECT_NAME} ) # 导出依赖 ament_export_dependencies(rclcpp std_msgs planning_ros_msgs) ament_package()

📊 迁移检查清单

代码层面检查

  1. 头文件更新

    • #include <ros/ros.h>#include "rclcpp/rclcpp.hpp"
    • 消息头文件路径更新
  2. 命名空间迁移

    • ros::rclcpp::
    • 消息类型:planning_ros_msgs::VoxelMapplanning_ros_msgs::msg::VoxelMap
  3. 参数系统更新

    • nh.param()declare_parameter()+get_parameter()
  4. 发布者/订阅者

    • advertise()create_publisher()
    • QoS配置需要显式设置

构建系统检查

  1. package.xml格式

    • format="2" → format="3"
    • 依赖声明更新
  2. CMakeLists.txt

    • find_package(catkin)find_package(ament_cmake)
    • 构建目标配置更新
  3. 依赖管理

    • 确保所有ROS 1依赖都有对应的ROS 2版本

运行时检查

  1. 启动系统

    • .launch文件 → Python launch文件
    • 参数传递方式更新
  2. 工具链

    • roscore→ 不再需要
    • rosrunros2 run
    • rostopicros2 topic

MPL_ROS在SE(3)空间中的椭圆体模型轨迹规划

🚨 常见问题与解决方案

问题1:DDS配置问题

症状:节点无法发现彼此解决方案:设置正确的DDS配置环境变量

export RMW_IMPLEMENTATION=rmw_fastrtps_cpp export FASTRTPS_DEFAULT_PROFILES_FILE=fastdds_config.xml

问题2:QoS配置不匹配

症状:消息丢失或延迟解决方案:确保发布者和订阅者使用相同的QoS配置

auto qos = rclcpp::QoS(10) .reliable() .transient_local() .keep_last(10);

问题3:参数类型转换

症状:参数获取失败解决方案:使用正确的类型转换方法

// ROS 1 double value; nh.param("param_name", value, 0.0); // ROS 2 this->declare_parameter<double>("param_name", 0.0); double value = this->get_parameter("param_name").as_double();

🎯 迁移最佳实践

1. 增量迁移策略

  • 从消息包开始迁移
  • 逐个迁移功能包
  • 保持ROS 1和ROS 2并行运行

2. 测试驱动迁移

  • 为每个组件编写单元测试
  • 使用ROS 2的测试框架
  • 确保功能一致性

3. 性能优化

  • 利用ROS 2的实时特性
  • 优化QoS配置
  • 使用组件化架构

4. 文档更新

  • 更新README和文档
  • 添加ROS 2示例
  • 提供迁移指南

PathArray消息的类结构图

📈 性能对比与优化

通信性能提升

ROS 2的DDS通信机制相比ROS 1的TCPROS/UDPROS提供了更好的实时性和可靠性:

指标ROS 1 (Kinetic)ROS 2 (Foxy)提升幅度
延迟10-50ms2-10ms5倍
吞吐量100MB/s500MB/s5倍
节点发现秒级毫秒级100倍

内存使用优化

ROS 2的内存管理更加精细,通过以下方式优化:

  1. 零拷贝传输:减少消息复制开销
  2. 共享内存:节点间高效数据共享
  3. 内存池:预分配减少动态分配

🔮 未来展望

ROS 2 Humble兼容性

MPL_ROS迁移到ROS 2 Foxy后,可以进一步升级到更新的ROS 2版本:

  1. Humble Hawksbill:LTS版本,支持到2027年
  2. Iron Irwini:最新稳定版本
  3. Jazzy Jalisco:未来版本规划

新特性集成

迁移到ROS 2后,MPL_ROS可以集成更多现代特性:

  1. 生命周期管理:完善的节点状态机
  2. 安全特性:DDS安全层支持
  3. 实时性能:实时Linux支持
  4. 容器化部署:Docker/Kubernetes集成

🎉 总结

MPL_ROS从ROS Kinetic迁移到ROS 2 Foxy是一个系统性的工程,但通过本文提供的完整迁移方案,您可以:

  1. 理解架构差异:掌握ROS 1和ROS 2的核心区别
  2. 逐步迁移组件:从消息到节点,从构建到部署
  3. 解决常见问题:避免迁移过程中的常见陷阱
  4. 优化性能:充分利用ROS 2的新特性

迁移到ROS 2不仅能让MPL_ROS获得更好的性能和可靠性,还能为未来的机器人应用开发奠定坚实的基础。现在就开始您的ROS 2迁移之旅吧!✨

核心建议:采用渐进式迁移策略,保持ROS 1和ROS 2的兼容性,确保业务连续性。在迁移过程中,充分利用ROS 2的测试工具和性能分析工具,确保迁移质量。

MPL_ROS在办公室环境中的地图和规划示例

【免费下载链接】mpl_rosA ROS wrapper for trajectory planning based on motion primitives项目地址: https://gitcode.com/gh_mirrors/mp/mpl_ros

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考