编写简单的发布者(C++) [ROS1和ROS2对比]

分别在ROS1和ROS2中创建工作空间和功能包

mkdir -p ~/dev_ws/src
cd ~/dev_ws/src

ROS1:话题发布

源码下载:

mkdir -p ~/dev_ws/src
cd ~/dev_ws/src
wget -O publisher_member_function.cpp https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/talker/talker.cpp

首先是头文件:

   #include "ros/ros.h"
   #include "std_msgs/String.h"
   #include <sstream>

"ros/ros.h"是一个方便的工具,其中包括使用ROS系统最常见的公共部分所需的所有头文件。
“std_msgs/String.h” 这包括std_msgs / String消息,该消息驻留在std_msgs包中。这是从该程序包中的String.msg文件自动生成的头文件

初始化:

包括节点初始化、句柄初始化

ros :: init(argc,argv,“ talker ”);
ros::NodeHandle n;

NodeHandle :: advertise()返回ros :: Publisher对象,该对象有两个作用:1)它包含一个publish()方法,该方法可让您将消息发布到其创建的主题上; 2)当它超出范围时,它将自动取消广告。

发布话题

ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
ros::Rate loop_rate(10);

告诉Master,将在话题chatter_pub 上发布一条std_msgs/string类型的消息。这样,Master就可以告诉监听chatter_pub 的节点,将发布有关该话题的数据。第二个参数是发布队列的大小。在这种情况下,如果我们发布得太快,节点则开始丢弃数据中之前缓冲下来的最旧的1000条数据消息。

rate表示指定希望循环的频率,这里指定为10HZ。

int count = 0;
 while (ros::ok())
  {

默认情况下,roscpp将安装SIGINT处理程序,该处理程序提供Ctrl-C处理,如果发生这种情况,将导致ros::OK()返回false。
如果满足以下条件,ROS::OK()将返回False:
收到SIGINT(Ctrl-C)。
我们已被另一个同名节点踢出网络。
ROS::Shutdown()已被应用程序的另一部分调用。
所有ros::NodeHandle都已销毁。
一旦ros::OK()返回false,所有ROS调用都将失败。

消息类型

 std_msgs::String msg;
 std::stringstream ss;
 ss << "hello world " << count;
  msg.data = ss.str();

我们使用消息适配类在ROS上广播消息,该类通常从msg文件生成。更复杂的数据类型也是可能的,但目前我们将使用标准字符串消息,它有一个成员:“data”。

话题发布

chatter_pub.publish(msg);

现在将消息广播给任何订阅该话题的节点

打印信息

ROS_INFO("%s", msg.data.c_str());

ros::spinOnce()

loop_rate.sleep();

这个简单的程序不需要在这里调用ros::spinOnce(),因为我们没有收到任何回调。如果程序中有回调函数的话,没有添加ros::spinOnce(),回调函数将不会被调用。

ROS2:话题发布

源码下载:

mkdir -p ~/dev_ws/src
cd ~/dev_ws/src
wget -O publisher_member_function.cpp https://raw.githubusercontent.com/ros2/examples/master/rclcpp/topics/minimal_publisher/member_function.cpp

头文件:

#include <chrono>
#include <functional>
#include <memory>
#include <string>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

因为在ROS 2架构下变为了“rclcpp/rclcpp.hpp“

初始化:

包括节点初始化、句柄初始化

class MinimalPublisher : public rclcpp::Node
{
  public:
    MinimalPublisher()
    : Node("minimal_publisher"), count_(0)
    {
      publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
      timer_ = this->create_wall_timer(
      500ms, std::bind(&MinimalPublisher::timer_callback, this));
    }

公共构造函数命名该节点MinimalPublisher ,并将其初始化count_为0。在构造函数内部,使用String消息类型,话题命名为topic和所需的队列大小为10,初始化发布者,以限制备份时的消息。接下来,timer_进行初始化,这会使该timer_callback函数每秒执行两次。
该timer_callback功能是设置消息数据并实际发布消息的位置。

发布话题

private:
  void timer_callback()
  {
    auto message = std_msgs::msg::String();
    message.data = "Hello, world! " + std::to_string(count_++);
    RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
    publisher_->publish(message);
  }
  

最后是计时器,发布者和计数器字段的声明。

打印信息

 RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());

需要注意,ROS2的打印输出函数和ROS1的打印函数不一样,

参考官网教程:
http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29
https://index.ros.org/doc/ros2/Tutorials/Writing-A-Simple-Cpp-Publisher-And-Subscriber/

猜你喜欢

转载自blog.csdn.net/Feizhai2/article/details/114086892
今日推荐