声明一个ros::NodeHandle对象n,并用n生成一个广播对象vel_pub,调用的参数里指明了vel_pub将会在主题“/cmd_vel”里广播geometry_msgs::Twist类型的数据。我们对机器人的控制,就是通过这个广播形式实现的。
这里就有一个疑问:为什么是往主题“/cmd_vel”里广播数据而不是其他的主题?机器人怎么知道哪个主题里是要执行的速度?
答案是:在ROS里有很多约定俗成的习惯,比如激光雷达数据发布主题通常是“/scan”,坐标系变换关系的发布主题通常是“/tf”,所以这里的机器人速度控制主题“/cmd_vel”也是这样一个约定俗成的情况。
为了连续不断的发送速度,使用一个while(ros::ok())循环,以ros::ok()返回值作为循环结束条件可以让循环在程序关闭时正常退出。
速度赋值:
vel_cmd.linear.x是机器人前后平移运动速度,正值往前,负值往后,单位是“米/秒”;
vel_cmd.linear.y是机器人左右平移运动速度,正值往左,负值往右,单位是“米/秒”;
vel_cmd.angular.z(注意angular)是机器人自转速度,正值左转,负值右转,单位是“弧度/秒”;
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
//运动速度结构体类型geometry_msgs::Twist的定义文件;
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);
while(ros::ok())
{
geometry_msgs::Twist vel_cmd;
//为了发送速度值,声明一个geometry_msgs::Twist类型的对象vel_cmd,并将速度值赋值到这个对象里。
vel_cmd.linear.x = 0.1;
vel_cmd.linear.y = 0.0;
vel_cmd.linear.z = 0.0;
vel_cmd.angular.x = 0;
vel_cmd.angular.y = 0;
vel_cmd.angular.z = 0;
vel_pub.publish(vel_cmd);
//vel_cmd赋值完毕后,使用广播对象vel_pub将其发布到主题“/cmd_vel”上去。机器人的核心节点会从这个主题接收我们发过去的速度值,并转发到硬件底盘去执行。
ros::spinOnce();
//调用ros::spinOnce()函数给其他回调函数得以执行
}
return 0;
}