ROS2 相对于 ROS1 做了哪些改动、有什么不同点

 一、ROS2 中做了哪些改动

1. 支持的平台不同
   ROS1 支持 ubuntu 进行 CI 测试。
   ROS2 支持 Ubuntu Xenial、OS X El Capitan 以及 Win10 上进行 CI 测试。
 
2. C++语言标准不同
   ROS1 使用 C++03 标准,其 API 中不使用 C++11 功能。
   ROS2 使用 C++11 标准,部分使用 C++14 功能。

3. 中间件的实现方式不同
   ROS1 采用自定义序列化格式、自定义传输协议以及自定义中央发现机制。
   ROS2 基于 DDS 标准,有抽象的中间件接口,通过接口提供序列化、传输和发现。

4. 编译方式多样化
   ROS1 使用 CMake 编译,每个 ROS 包其实都是一个 CMake 项目。
   ROS2 支持其他编译方式。
 
5. 环境设置升级
   ROS1 编译工具生成必须来自脚本,以便在能够在 build 功能包之前设置环境。
   ROS2 环境设置被分为功能包脚本和工作目录脚本。
        每个包都提供必要的脚本,使其在 build 之后可以运行。
        编译工具仅调用工作目录特定脚本,然后调用功能包特定脚本。
 
6. 使用独立编译
   ROS1 中多个包可以使用同一个 CMake 编译。
   ROS2 仅支持孤立的编译,每个包都是单独编译的。但安装目录可以独立或合并。
 
7. 取消了 devel 目录
   ROS1 中编译包是不需要安装目录的。将源码和 devel 目录相结合使用。
   ROS2 中在编译功能包之后、必须安装功能包后、才能使用。
 
8. 支持 catkin_simple
   ROS1 中 catkin_simple 的功能使编写 ROS 功能包的 CMake 代码更加容易。
   ROS2 对 CMake API 进行了重构,以支持此 catkin 的使用。

9. 对无 manifest 包的最小支持
   ROS1 中编译系统会考虑仅具有 manifest 文件的包。
   ROS2 中无需显式文件即可在文件夹中检测带有支持编译系统的软件包。
 
A. 消息与服务改进
   ROS1 中 .msg 和 .srv 可以具有相同的名称,但生成的代码会发生碰撞而报错。
   ROS2 中,生成的代码使用单独的命名目录来保证它无碰撞。
 
   ROS1 中,客户端库中定义了 duration 和 time 的类型。
   ROS2 中,duration 和 time 被定义为消息,因此跨语言一致。
 
   ROS1 中,全局参数和节点特定动态配置参数是两个独立的概念。
   ROS2 中,消息中的原始值现在可以具有默认值,当消息编译时设置。
   ROS2 中,支持数组和字符串的最大长度定义。
 
   ROS1 中,Topic 只能在启动时重新映射 remap。
   ROS2 中,可以在运行时进行话题的重映射和别名。
   ROS2 中,不支持 Topic 名称中的命名目录。这是由于 DDS Topic 名称中有字符的限制。
 
B. 通知 Notifications 改变
   ROS1 中,有关 ROS graph 的所有信息必须从 Master 节点获取。
   ROS2 中使用广播的方式取代,例如,某个参数发生了改变,则会发出通知。
 
C. 线程模式
   ROS1 中,开发人员只能在单线程执行或多线程执行之间进行选择。
   ROS2 中,C++(例如跨多个节点)中提供了更精细的执行模型,自定义执行器可以轻松实现。
 
D. C/C++ 支持实时代码
   ROS1 中,不支持编写实时代码,需要依赖于外部框架,如 Orocos。
   ROS2 中,使用适当的 RTOS 编写实时节点。
 
E. C++ 库的加载方式变化
   ROS1 中,API 用于节点和节点的方案不同,需要开发人员决定在编程时间对节点的映射以进行处理。
   ROS2 中,建议将每个组件编译到共享库中,可以单独加载或与其他组件、共享相同的过程。
 
F. 一个进程里允许有多个节点
   ROS1 中,不可能在过程中创建多个节点。这是由于 API 本身,但也因为内部的逻辑所决定的。
   ROS2 中,可以在过程中创建多个节点。

 二、ROS2 编译配置的改动

1. CMake 的最低版本不同
   ROS1: cmake_minimum_required(VERSION 2.8.3)
   ROS2: cmake_minimum_required(VERSION 3.5)

2. ROS2 开启 C++14 标准。
   ROS1 使用 C++03 标准,其 API 中不使用 C++11 功能。
   ROS2 使用 C++11 标准,默认情况下可能不启用 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()

  2.1  ROS2 的 CMakeLists.txt 模板

cmake_minimum_required(VERSION 3.5)
project(project_name)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()


#################################################
# 手动添加的
find_package(rosidl_default_generators REQUIRED)


# add ros2 node application here !


#################################################
ament_package()  # 文件的结束位置

  2.2  ROS2 的 package.xml 模板




  unitree_msgs
  0.0.0
  TODO: Package description
  root
  TODO: License declaration

  ament_cmake

  
  rosidl_default_generators
  rosidl_default_runtime
  rosidl_interface_packages
  

  rclcpp
  std_msgs

  ament_lint_auto
  ament_lint_common

  
    ament_cmake
  

三、ROS2 使用过程中碰到的问题及解决方法

time
-----------------------------------------------------
在 ROS1 中默认的消息类型中有 time,用于表示时间信息。
在 ROS2 中默认类型类型中取消了 time 这个类型。

  定义一个 time 类型的变量 stamp :
  1. ROS1 中的表示方法: time stamp
  2. ROS2 中的表示方法: builtin_interfaces/Time stamp


ros::init
-----------------------------------------------------
ROS1 : ros::init(argc, argv, "my_node");
ROS2 : rclcpp::init(argc, argv);
       auto my_node = rclcpp::Node::make_shared("my_node");
       # 在 ROS2 中需要两行代码来实现,spin 需要用到 my_node 节点


ros::spin
-----------------------------------------------------
ROS1 : ros::spin();
ROS2 : rclcpp::spin(my_node);


ros::spinOnce
-----------------------------------------------------
ROS1 : ros::spinOnce();
ROS2 : rclcpp::spin_some(my_node);

你可能感兴趣的:(ROS,编程开发,机器人,arm开发,linux)