ROS:发布者程序

接下来我们将要学习一个更方便理解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程序都应该在第一句调用

第二句是实例化了一个句柄对象

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);
在命令窗中显示,类似于GUI,没有也不影响本程序运行

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

如果一切正常,我们将会看到小海龟随机游动。

猜你喜欢

转载自blog.csdn.net/buaazyp/article/details/80662086