接下来我们将要学习一个更方便理解ROS运行本质的例子:发布者程序
我们前面已经了解了节点,也知道节点之间通过“消息”来实现通信,接下来将用一个简单的例子进行学习。这个例子是海龟软件的一个简单拓展,我们将会给小海龟发送一个随机的速度来控制它的运动。
(零):创建软件包
在常用目录下创建一个名为pubvel的软件包(具体操作请看我的另一篇博客《ROS:Hello ROS程序》)
(一):编写C++代码
添加一个名为pubvel.cpp的文件,编辑代码
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
ros::init(argc, argv, "publish_velocity");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise <geometry_msgs::Twist>
("turtle1/cmd_vel", 1000);
srand(time(0));
ros:Rate rate(2);
while (ros::ok())
{
geometry_msgs::Twist msg;
msg.linear.x = double(rand()) / double(RAND_MAX);
msg.angular.z = 2 * double(rand()) / double(RAND_MAX) - 1;
pub.publish(msg);
ROS_INFO_STREAM("Sending random velocity command:"
<< "linear=" << msg.linear.x
<< "angular=" << msg.angular.z);
rate.sleep();
}
}
(一.二)代码的具体解释
前三行声明了三个头文件
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <stdlib.h>
其中<ros/ros.h>是每个ros程序首先要声明的库,不然就无法使用库里的内容
<geometry_msgs/Twist.h>是跟消息传递有关的头文件
<stdlib.h>不解释,c语言中见多了
主函数中
ros::init(argc, argv, "publish_velocity");
ros::NodeHandle nh;
第二句是实例化了一个句柄对象
ros::Publisher pub = nh.advertise <geometry_msgs::Twist>
("turtle1/cmd_vel", 1000);
这一句声明了一个Publisher对象,这个对象实际承担了发布消息的任务,我们调用了nh对象的advertise方法来初始化,geometry_msgs::Twist表示消息的类型,"turtle1/cmd_vel"表示我们想要发布的主题的名称,最后1000表示消息序列的大小,超过这个序列大小的消息会被丢弃。
srand(time(0));
产生随机数种子。由于随机数函数是一个伪随机数函数,相同的种子产生的数是一样的,因此为了获得真正的随机数,我们需要使用不同的随机数种子,一个办法是使用当前时间time(0),这个函数帮助获取当前的时间,这样每一秒随机数的种子都不一样,产生的随机数也就不一样。
ros:Rate rate(2);
//不是很清楚,似乎是保证每秒运行两次函数
while (ros::ok())
{}
ros::ok()的意思是,这个节点还存活,只要这个节点运行良好就一直调用循环
循环内
geometry_msgs::Twist msg;
msg.linear.x = double(rand()) / double(RAND_MAX);
msg.angular.z = 2 * double(rand()) / double(RAND_MAX) - 1;
实例化了一个消息对象,并且对这个对象里的两个变量进行了赋值
//消息内部的数据结构怎么看?
pub.publish(msg);
发送消息出去
ROS_INFO_STREAM("Sending random velocity command:"
<< "linear=" << msg.linear.x
<< "angular=" << msg.angular.z);
rate.sleep();
//母鸡啊
(二):声明依赖库
和hello ROS程序类似,打开包目录下的"CMakeLists.txt"文件,找到
find_package(catkin REQUIRED)
修改为
find_package(catkin REQUIRED COMPONENTS roscpp geometry_msgs)
因为比上一个程序使用了更多的库,所以这里依赖库要多写
打开包目录下的"package.xml",添加
<build_export_depend>message_runtime</build_export_depend>
<exec_depend>message_runtime</exec_depend>
以及
<build_export_depend>geometry_msgs</build_export_depend>
<exec_depend>geometry_msgs</exec_depend>
(三):声明可执行文件
打开"CMakeLists.txt"文件,添加
add_executable(pubvel pubvel.cpp)
target_link_libraries(hello ${catkin_LIBRARIES})
(四):修改路径
同hello ROS程序
(五):编译
同hello ROS程序
(六):执行程序
先打开节点管理器,在命令窗输入
roscore
然后打开小海龟结点
rosrun turtlesim turtlesim_node
最后打开pubvel结点
rosrun pubvel pubvel
如果一切正常,我们将会看到小海龟随机游动。