Bootstrap

ROS发布者节点源码理解- for C++

对于节点发布源码的理解,我选用wpr_simulation包中的demo_vel_ctrl作为参考对象

https://github.com/6-robot/wpr_simulation.giticon-default.png?t=N7T8https://github.com/6-robot/wpr_simulation.git

参考书籍:《机器人操作系统(ROS)及仿真应用》

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "demo_vel_ctrl");

  ros::NodeHandle n;
  ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel", 10);

  geometry_msgs::Twist vel_msg;
  vel_msg.linear.x = 0.1;
  vel_msg.linear.y = 0.0;
  vel_msg.linear.z = 0.0;
  vel_msg.angular.x = 0;
  vel_msg.angular.y = 0;
  vel_msg.angular.z = 0;

  ros::Rate r(30);
  while(ros::ok())
  {
    vel_pub.publish(vel_msg);
    r.sleep();
  }

  return 0;
}

节点介绍

demo_vel_ctrl是一个简单的ROS机器人速度控制程序,实现了使机器人以0.1m/s的速度在x轴正方向前进

源码理解

头文件

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

两个头文件,分别是ROS系统头文件和运动速度结构体类型geometry_msgs/Twist的定义文件

节点初始化

ros::init(argc, argv, "demo_vel_ctrl");

调用init函数,前两个输入参数后期给节点传值会有用,第三个参数为节点名称(唯一)

实例化NodeHandel

ros::NodeHandle n;

声明一个ros:NodeHandle对象n,n为NodeHandel类的实例化

Handle有管理的意思,所以我对NodeHandel的理解是节点管理员

而n作为节点管理员的实例化,具有节点管理员这个身份所对应的一切权力(功能)

话题初始化

ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel", 10);

话题的初始化可以分为两部分:

(1)实例化Publisher

ros::Publisher vel_pub

声明一个ros::Publisher对象vel_pub,vel_pub拥有Publisher类的一切功能

(2)初始化vel_pub并赋值

n.advertise<geometry_msgs::Twist>("/cmd_vel", 10)

调用NodeHandle的advertise函数,advertise函数用于创建一个发布者,会返回一个发布者对象,最终完成对vel_pub的初始化与赋值

它接受三个参数:        消息类型        话题(topic)名称        消息缓存队列大小

实例化geometry_msgs::Twist

geometry_msgs::Twist vel_msg;

声明一个geometry_msgs::Twist对象vel_msg,vel_msg拥有Twist类的一切声明变量

对vel_msg对象的值操作(即设置所发消息内容)

  vel_msg.linear.x = 0.1;
  vel_msg.linear.y = 0.0;
  vel_msg.linear.z = 0.0;
  vel_msg.angular.x = 0;
  vel_msg.angular.y = 0;
  vel_msg.angular.z = 0;

设置消息中机器人xzy平移线速度及绕轴角速度值,正负遵循右手坐标系定则

循环发布消息

设置循环频率

ros::Rate r(30);

声明一个ros::Rate对象r,r接受一个参数作为每秒循环次数(频率)

循环主体

while(ros::ok())
  {
    vel_pub.publish(vel_msg);
    r.sleep();
  }

while循环判断条件为ros::ok(),当执行ctrl+c时,ros::ok()为假,退出循环

发布消息通过调用Publisher内函数publish()实现,输入参数为已实例化并赋值的vel_msg

调用已经声明的实例对象r中的sleep()函数,根据声明时参数设定值,控制while内循环速率

;