对于节点发布源码的理解,我选用wpr_simulation包中的demo_vel_ctrl作为参考对象
https://github.com/6-robot/wpr_simulation.githttps://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内循环速率