在本文将看到自己编写publish函数给turtle话题发我们设置的消息使小海龟自动运行
本节我们将看到如何发送随机生成的速度指令到一个turtlesim海龟,使它漫无目的地巡游。
生成文件
I、生成结构
在和hello功能包的同级目录下生成pubvel功能包并自动导入依赖。
catkin_create_pkg pubvel roscpp
打开pubvel下的src(test_ws/src/pubvel/src)目录来编写我们的cpp源文件,这个程序的cpp源文件称为pub_vel.cpp。
touch pub_vel.cpp
II、编写程序
打开pub_vel.cpp文件,代码贴出:
#include <ros / ros.h>
#include <geometry_msgs / Twist . h>
#include <stdlib.h> // For rand() and RAND_MAX
int main ( int argc , char ** argv )
{
ros::init ( argc , argv , " pub_node_cpp " ) ;
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 ( ) ;
}
return 0 ;
}
对程序做如下解读:
#include <包名/消息类型名>
#include<geometry_msgs/Twist.h>
- 包含消息类型声明,即包含头文件(官方给出)。(这里的包名指的是包含消息的包),比如,这句话定义一个C++类。
ros::Publisher pub = node_handle.advertise<message_type>(
topic_name, queue_size);
ros::Publisher pub = nh . advertise <geometry_msgs::Twist >( " turtle1 /cmd_vel" , 1000) ;
- 实例化发布者:node_handle是一个对象,将调用这个对象的advertise方法。
- message_type:模板参数,即为消息的数据类型,使用geometry_msgs::Twist(::表示范围解析运算符)。
- topic是一个字符串,表示想发布去的话题名称,它应该和rqt_graph或者rostopic中展示的话题名称一致,但通常没有(/),丢掉(/)使话题名成为一个相对名称,详见第5章。
- advertise:是一个证书,表示要发布的消息序列的大小,大多数情况下,一个相对较大的值是合适的。如果程序发布的消息比队列容纳的多的消息,最早进入队列的未发送的消息将会被丢弃。
------publish 方法(见下文)只负责在“发件箱”中存储这条消息,而后台有一个单独的线程负责实际发送
消息。此处的整数值为消息的数目,并不是你可能认为的字节数。
------建议为每一个话题创建一个发布者,并且在你程序执行的全过程中一直使用那个发布者。
geometry_msgs::Twist msg;
msg.linear.x = double(rand())/double(RAND_MAX);
msg.angular.z = 2*double(rand())/double(RAND_MAX) - 1;
- 创建消息对象,设置消息内容。根据前文查看消息的结构和内容,对应设置。
- 这段代码设置线速度为 0 到 1 之间的某个值,角速度为-1 到1 之间的某个值。因为 turtlesim 忽略了其他四个域(msg.linear.y、msg.linear.z、msg.angular.x 和 msg.angular.y),我们让它们保持为默认值,即 0。
pub.publish(msg);
- 发布消息,这个方法将所给的消息添加到发布者的输出消息队列中,从这里,它会尽快被发送到相同话题的订阅者那里。
ROS_INFO_STREAM
- 定义输出格式。
ros::ok()
这个函数检查ros节点是否运行良好,如下几种原因会返回false:
- rosnode kill
- Ctrl-C( 可以被用来使 ros::ok()返回 false,但不会立刻终止程序。如果在程序退出前完成有一些必要的收尾工作(写日志文件、保存结果、说再见等)的话,这个设计是很重要的。)
- ros::shutdown()(这个函数是在你的代码中发送节点工作已经完成信号的一个很有用的方法。)
- 同名节点出现
ros::Rate rate(2);
- 控制消息发布频率,每秒两次。rate.sleep();用来产生延迟来达到我们设置的2s。
- 可以用rostopic hz来查看会看到2.
修改配置
声明消息类型依赖库
I、cmakelist文件
find_package(catkin REQUIRED COMPONENTS roscpp geometry_msgs)
- 前文的基本配置在这里就不再赘述,这里是新增加的。
II、package.xml文件
<build_depend>geometry_msgs</build_depend>
<build_export_depend>geometry_msgs</build_export_depend>
<exec_depend>geometry_msgs</exec_depend>
-我们修改新加的项,而不是完全重来一遍。
运行程序
用catkin编译完成之后,再打开roscore和乌龟界面。
再键入如下代码:
rosrun pubvel pubvell
- 再cmakelist中我将project_nodename设置为了pubvell作为默认节点名。
就可以看到小乌龟在漫无目的的散步啦。。◕‿◕。