【ROS入门篇·三】ROS通讯架构-Topic

快速链接:【ROS入门篇】ROS学习简介

一、ROS中Topic通讯机制

【ROS入门篇·三】ROS通讯架构-Topic_第1张图片

Topic: 异步通讯机制,topic可以同时有多个subscribers,也可以有多个publishers;

Publisher: 向指定话题,发布对应类型的消息;

Sublisher: 订阅话题,一旦话题消息存在,调用回调函数对消息进行处理。

二、Publisher节点示例

  • C++实现(古月居案例)
/**
    * pub_demo.cpp, 发布turtle/cmd_vel话题,消息类型为geometry_msgs::Twist
    */

#include 
#include 

int main(int argc, char **argv)
{
    // ROS节点初始化
    ros::init(argc, argv, "pub_demo_node");

    // 创建ROS节点句柄
    ros::NodeHandle n_;

    // 创建一个Publisher,发布turtle/cmd_vel话题,消息类型为geometry_msgs::Twist,队列长度为10
    ros::Publisher pub_ = n_.advertise("/turtle1/cmd_vel", 10);

    // 设置循环频率
    ros::Rate loop_rate(10);

    int count=0;
    while(ros::ok())
    {
        // 初始化类型为geometry_msgs::Twist的消息
        geometry_msgs::Twist vel_msg;
        vel_msg.linear.x=0.5;
        vel_msg.linear.z=0.2;

        // 发布消息
        pub_.publish(vel_msg);
        ROS_INFO("Publish turtle velocity command[%0.2f m/s, %0.2f rad/s]", vel_msg.linear.x, vel_msg.linear.z);

        // 按照循环频率执行
        loop_rate.sleep();
    }

    return 0;
}
  • 修改CMakeLists.txt,配置可执行.cpp文件信息

三、Subscriber节点示例

  • C++实现(古月居案例)
/**
 * sub_demo.cpp, 订阅/turtle1/pose话题,消息类型为turtlesim::Pose
 */

#include 
#include 

void Callback(const turtlesim::Pose::ConstPtr& msg)
{
    ROS_INFO("Turtle pose  x: %0.6f,  y: %0.6f", msg->x, msg->y);
}

int main(int argc, char **argv)
{
    // ROS节点初始化
    ros::init(argc, argv, "sub_demo_node");

    // 创建ROS节点句柄
    ros::NodeHandle n_;

    // 创建一个Subscriber,订阅/turtle1/pose话题,消息类型为turtlesim::Pose,队列长度为10,注册回调函数Callback()
    ros::Subscriber sub_ = n_.subscribe("/turtle1/Pose", 10, Callback);

    // 主程序阻塞在这里,循环等待回调函数
    ros::spin();
}
  • 修改CMakeLists.txt,配置可执行.cpp文件信息

四、自定义消息

  • 生成.msg文件,放在msg文件夹内
  • 修改CMakeLists.txt和Package.xml文件
/* .msg文件示例,定义了一个表示people的消息类型  */

string name
uint8 sex
uint8 age

uint8 unknow=0
uint8 male=1
uint8 female=2

五、PubAndSub节点示例

  • 同一节点内订阅一个话题,并发布一个话题
/**
    * SubAndPub_demo.cpp
    * 订阅/velodyne_points话题,消息类型为sensor_msgs::PointCloud2
    * 发布/processed_velodyne_points话题,消息类型为sensor_msgs::PointCloud2
    */

#include 
#include 
#include 
#include 
#include 

using namespace std; 

class SubAndPub
{
private:
  ros::NodeHandle n_; 
  ros::Publisher pub_;
  ros::Subscriber sub_;
  std::string frame_id_;
 
public:
  SubAndPub();
  void callback(const sensor_msgs::PointCloud2& velodyne_sub);
  void pub_cloud(ros::Publisher pub_, const pcl::PointCloud::Ptr cloud_out);
};// End of class SubscribeAndPublish
 
SubAndPub::SubAndPub()
{
  // Topic you want to publish
  pub_ = n_.advertise("/processed_velodyne_points",1);

  // Topic you want to subscribe
  sub_ = n_.subscribe("/velodyne_points", 1, &SubAndPub::callback,this);
}

void SubAndPub::callback(const sensor_msgs::PointCloud2& cloud_in)
{
  // do something with the input and generate the output...
  frame_id_ = cloud_in.header.frame_id;
  pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
  pcl::fromROSMsg(cloud_in,*cloud);
  pub_cloud(pub_,cloud);
}

void SubAndPub::pub_cloud(ros::Publisher pub_, const pcl::PointCloud::Ptr cloud_out)
{
    sensor_msgs::PointCloud2 out;
    pcl::toROSMsg(*cloud_out,out);
    out.header.frame_id = frame_id_;
    pub_.publish(out);
}

int main(int argc, char **argv)
{
  // Initiate ROS
  ros::init(argc, argv, "SubAndPub_demo_node");
 
  // Create an object of class SubscribeAndPublish that will take care of everything
  SubAndPub velodyne;
 
  ros::spin();
  return 0;
}
  • 修改CMakeLists.txt和package.xml,配置可执行.cpp文件信息

你可能感兴趣的:(ROS入门篇,自动驾驶,人工智能,机器学习)