ROS 2最新版Dashing,你尝鲜了么?

  • 内容
  • 评论
  • 相关

ROS 2经过一个快速迭代期后,逐渐进入了稳定更新,目前的最新版是2019年5月31日发布的Dashing Diademata,维护期两年。

image

关于ROS 2的介绍,古月居之前已经有很多篇文章进行了说明,大家可以参考:

今天我们就一起来尝试下Dashing版本的安装和使用。

一、安装ROS 2 Dashing

最新版本的ROS 2安装都比较轻松,和ROS 1的安装过程差异不大,按照命令输入就可以完成安装了。

1. 设置UTF-8编码

  1. $ sudo locale-gen en_US en_US.UTF-8
  2. $ sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
  3. $ export LANG=en_US.UTF-8

2. 更新软件源

  1. $ sudo apt update && sudo apt install curl gnupg2 lsb-release
  2. $ curl http://repo.ros2.org/repos.key | sudo apt-key add -
  3. $ sudo sh -c 'echo "deb [arch=amd64,arm64] http://packages.ros.org/ros2/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list'

3. 安装ros2

  1. $ sudo apt update
  2.  
  3. -- 桌面版安装(包含ROS, RViz, demos, tutorials)
  4. $ sudo apt install ros-dashing-desktop
  5.  
  6. -- 基础版安装(包含通讯库、消息包、命令行工具,没有GUI工具)
  7. $sudo apt install ros-dashing-ros-base

4. 安装自动补全工具

ros2的命令行使用argcomplete工具进行补全,所以需要安装该工具:

  1. $ sudo apt install python3-argcomplete

5. 设置环境变量

和ROS 1一样,为了让系统找到ROS命令,安装完成后需要将以下语句添加到.bashrc中:

  1. $ source /opt/ros/dashing/setup.bash
  2. $ echo "source /opt/ros/dashing/setup.bash" >> ~/.bashrc

6. 安装RWM

ROS 2默认安装的RWM是FastRTPS,也可以使用如下方式安装OpenSplice或RTI Connext的RWM:

  1. $ sudo apt update
  2. $ sudo apt install ros-dashing-rmw-opensplice-cpp # for OpenSplice
  3. $ sudo apt install ros-dashing-rmw-connext-cpp # for RTI Connext (requires license agreement)

在使用的时候通过设置环境变量,即可更换需要的RWM:

RMW_IMPLEMENTATION=rmw_opensplice_cpp
RMW_IMPLEMENTATION=rmw_connext_cpp

7. 安装ROS 1

目前ROS 2的功能还不是很全面,很多功能包需要依赖ROS 1,所以还是需要安装ROS 1的,安装方法可以参考ROS 1 wiki教程。

ROS 2和ROS 1之间通过ros-bridge通信,需要安装:

  1. $ sudo apt update
  2. $ sudo apt install ros-dashing-ros1-bridge

未来如果还有什么包需要安装的话,使用以下命令的形式就OK啦!

  1. $ sudo apt-get install ros-dashing-XXX

image

安装好的ROS 2及其功能包依然是放置在/opt/ros路径下边。

image

二、创建工作空间&编译运行

安装完成后,我们当然要迫不及待的试下ROS 2了,还记不记得ROS 1的wiki教程,第一步要干什么?

没错,创建工作空间!在ROS 2中创建工作空间非常简单,在home下创建一个文件夹即可:

  1. $ mkdir -p ~/ros2_ws/src
  2. $ cd ~/ros2_ws

然后和ROS 1一样,在工作空间下编译,这里使用的可不是catkin_make命令,而是ROS 2全新升级的colcon编译器,使用的编译命令也改成了“colcon build”。

Screenshot from 2018-11-25 18-20-33

因为没有任何功能包,所以编译很快,再看看工作空间下,是不是多出了几个文件夹:

image

其中的build和install大家应该都很熟悉,和ROS 1是一样的,但是多出了一个log文件夹,用来保存编译过程中的日志信息。小伙伴们可以回忆一下,ROS 1中的log文件是放在哪里的呢?

现在我们就可以试试编译功能包了。这里我们直接使用官方提供的example试试,在src中下载功能包源码:

  1. $ git clone https://github.com/ros2/demos.git

然后回到工作空间下使用“colcon build”编译:

Screenshot from 2018-11-25 18-50-36

编译完成的功能包都会放置在install文件夹下,可以偷偷看下有没有顺利生成可执行文件。

接下来就可以运行节点了,当然不能忘记设置环境变量:

  1. $ source install/setup.bash

然后运行talker和listener节点:

  1. $ ros2 run demo_nodes_cpp listener
  2. $ ros2 run demo_nodes_cpp talker

 

image

现在两个节点就开始通信了,有没有发现,我们并没有使用类似roscore的命令启动master,这就是ROS 2最大的改变,真正成为了去中心化的分布式系统。

三、创建功能包&节点编程

以上我们使用官方提供的功能包,那么如何创建自己的功能包呢?同样使用ROS 2提供的命令行工具。比如说我们想创建一个叫learning_ros2的功能包,那么可以直接使用以下命令创建:

  1. $ ros2 pkg create learning_ros2

image

接下来打开创建成功的learning_ros2功能包中的src文件夹,我们尝试写几个ROS 2节点,实现最基本的服务和话题通信。

比如一个发布者节点ros2_talker.cpp:

  1. #include "rclcpp/rclcpp.hpp"
  2. #include "rcutils/cmdline_parser.h"
  3.  
  4. #include "std_msgs/msg/string.hpp"
  5.  
  6. using namespace std::chrono_literals;
  7.  
  8. class Talker : public rclcpp::Node
  9. {
  10. public:
  11. 	Talker() : Node("talker")
  12. 	{
  13. 		//ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
  14. 		rclcpp::QoS qos(rclcpp::KeepLast(7));
  15. 		pub_ = this->create_publisher<std_msgs::msg::String>("chatter", qos);
  16.  
  17. 		auto publish_message = [this]() -> void {
  18. 			msg_ = std::make_unique<std_msgs::msg::String>();
  19. 			msg_->data = "Hello World: " + std::to_string(count_++);
  20. 			RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", msg_->data.c_str());
  21.  
  22. 			//chatter_pub.publish(msg);
  23. 			pub_->publish(std::move(msg_));
  24. 		};
  25.  
  26. 		// Use a timer to schedule periodic message publishing.
  27. 		timer_ = this->create_wall_timer(1s, publish_message);
  28. 	}
  29.  
  30. private:
  31. 	size_t count_ = 1;
  32. 	std::unique_ptr<std_msgs::msg::String> msg_;
  33. 	rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_;
  34. 	rclcpp::TimerBase::SharedPtr timer_;
  35. };
  36.  
  37. int main(int argc, char * argv[])
  38. {
  39. 	//ros::init(argc, argv, "talker");
  40. 	rclcpp::init(argc, argv);
  41.  
  42. 	//ros::NodeHandle n;
  43. 	auto node = std::make_shared<Talker>();
  44.  
  45. 	//ros::spin();
  46. 	rclcpp::spin(node);
  47. 	rclcpp::shutdown();
  48.  
  49. 	return 0;
  50. }

再比如一个订阅者节点:

  1. #include <iostream>
  2. #include <memory>
  3.  
  4. #include "rclcpp/rclcpp.hpp"
  5. #include "std_msgs/msg/string.hpp"
  6.  
  7. //void chatterCallback(const std_msgs::String::ConstPtr& msg)
  8. void chatterCallback(const std_msgs::msg::String::SharedPtr msg)
  9. {
  10.     std::cout << "I heard: [" << msg->data << "]" << std::endl;
  11. }
  12.  
  13. int main(int argc, char * argv[])
  14. {
  15.     //ros::init(argc, argv, "listener");
  16.     rclcpp::init(argc, argv);
  17.  
  18.     //ros::NodeHandle n;
  19.     auto node = rclcpp::Node::make_shared("listener");
  20.  
  21.     //ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
  22.     auto sub = node->create_subscription<std_msgs::msg::String>(
  23.     "chatter", 10, chatterCallback);
  24.  
  25.     //ros::spin();
  26.     rclcpp::spin(node);
  27.  
  28.     return 0;
  29. }

* 注释是对应于ROS1的实现API,代码内容较多,完整功能包请参考:

https://github.com/huchunxu/ros2_demos

代码完成之后,还需要修改CMakeLists文件,添加编译规则:

  1. add_executable(ros2_talker src/ros2_talker.cpp)
  2. ament_target_dependencies(ros2_talker rclcpp std_msgs)
  3.  
  4. add_executable(ros2_listerner src/ros2_listerner.cpp)
  5. ament_target_dependencies(ros2_listerner rclcpp std_msgs)
  6.  
  7.  
  8. add_executable(ros2_server src/ros2_server.cpp)
  9. ament_target_dependencies(ros2_server example_interfaces rclcpp)
  10.  
  11. add_executable(ros2_client src/ros2_client.cpp)
  12. ament_target_dependencies(ros2_client example_interfaces rclcpp)

接下来就是在工作空间下编译啦!编译成功后,打开install下的lib文件夹,即可找到编译成功的可执行文件。

image

最激动人心的莫过于运行自己实现的程序啦:

image

image

运行之后,我们不妨理性的分析下ROS 2的代码和ROS 1的代码,到底有什么区别,古月君总结了以下几点:

  • ROS2中的API相比ROS1中发生了较大的变化,ROS2并不是在ROS1的基础上查漏补缺,而是完全从新设计。关于ROS2的API说明,可以参考API文档:

    http://docs.ros2.org/dashing/api/rclcpp/index.html

  • 使用了更多C++的特性,比如auto、make_shared等。

  • 加入了QoS配置,QoS默认的配置rmw_qos_profile_default。

  • 代码的总体架构还是与ROS1极为相似的。

四、URDF&Rviz&Gazebo

ROS 2当然少不了URDF、Rviz、Gazebo等重量级的工具,具体使用方法各位可以参考开头推荐的以往文章,操作过程完全一致。

image

image

image

好啦,今天的尝鲜就到这里,不知各位感觉ROS 2的味道如何呀?


原创文章,转载请注明: 转载自古月居

本文链接地址: ROS 2最新版Dashing,你尝鲜了么?

微信 OR 支付宝 扫描二维码
为本文作者 打个赏
pay_weixinpay_weixin