2 创建编译执行发布者程序
1写在开头的话
首先确保自己已经有工作区间,且已经将该工作区间的setup.bash加入当前用户的环境变量中,若是则直接看第二章节,否则继续往下看。
若没有工作区间则查看顺序为:1.1——>1.2——>2——>1.3——》3
若有工作区间但是没有将setup.bash加入当前用户的环境变量中,则查看顺序为:1.2——》1.3——》2——》3
若是已经有工作区间且已经将该工作区间的setup.bash加入当前用户的环境变量中,则查看顺序1.2—》2—》3
1.1新建工作区间
在当前用户home目录下调用mkdir命令新建文件夹test,cd进入该文件夹,再次调用mkdir新建文件夹src,如下
1.2创建功能包
在工作区间的src目录下,调用创建功能包。如下
调用ls查看是否创建成功,成功会在src下出现文件夹
注意:下图中的amin文件夹和.txt文件都是由于本人之前已经有工作区才会存在,若初次创建工作区间和功能包则不会出现这两项,即只有文件夹;若已经有工作区间则会出现这两项;
cd进入文件夹,同时调用ls查看pubve文件夹,此时可以看到里面包含2个文件,如下
注意:.cpp文件是由于本人已经做过所以才会出现,此时应该是没有的】
第一个配置文件,叫做.xml
第二个文件,叫做.txt,是一个Cmake的脚本文件,Cmake是一个符合工业标准的跨平台编译系统。
1.3 添加环境变量
执行此部分需要两个条件(满足其一即可),条件为:其一,在查看本文前已经有工作区间但是没有将该工作区间的setuo.bash配置到当前用户的环境变量中;其二,已经执行了本文的第二部分
添加环境变量到当前目录步骤如下:
a.在当前用户目录的工作区目录下,即test目录下【此时的test为本人的工作区名称,若查阅本文者查看此文前已经有自己的工作区间,则此步骤的test为查阅者的工作区间名称】,调用ls查看此目录下内容,如下:
b.调用cd进入devel目录,调用ls查看此目录下内容:
c.注意:a、b步骤只是为了确保该工作区间中存在该工作区间环境变量的配置文件setup.bash,没有做任何实质性的工作
d。再次进入当前用户的home目录,调用ls -a查看该目录下包含隐藏文件的全部文件,如下
可以看到,上图中有隐藏文件.
e。调用vim编辑此文件,如下
在最后加入一行: ~/test/devel/setup.bash,注意此处的test是工作区间的名字,根据需要修改,如下
按esc退出编辑,继而输入:wq保存退出
2 创建编译执行发布者程序 2.1创建发布者程序 2.1.1添加代码
cd进入工作区目录下的src,再调用cd进入文件夹中,如下
在文件夹下调用vim创建发布者程序.cpp,并添加如下代码
2.1.2关于代码内容详细说明
2.1.2.1关于头文件说明
头文件ros/ros.h包含了标准ROS类的声明,你将会在每一个你写的ROS程序中包含它。
在程序中,我们想发布一条类型为/Twist的消息(名为的包所拥有的类型为Twist的消 息),我们应该这样:#
头文件.h则是因为什么在main函数中调用了srand函数和rand函数
2.1.2.2关于main函数内代码说明
A.ros::init函数初始化ROS客户端库。请在你程序的起始处调用一次该函数3。函数最后的参数是一个包含节点默认名的字符串。
B.ros::(节点句柄)对象是你的程序用于和ROS系统交互的主要机制4。创建此对象会将你的程序注册为ROS节点管 理器的节点。最简单的方法就是在整个程序中只创建一个对象。
C..创建发布者对象:发布消息的实际工作是由类名为ros::的一个对象来完成的。创建格式如下: ros:: pub = .(, ); 上述格式中参数说明如下: 是ros::类的一个对象,是你在程序的开始处创建的,即ng。我们将调用这个对象的方法;
在尖括号中的部分,其正式名称为模板参数,是我们要发布的消息的数据类型。这个应该是上面讨论过的头文件中定义的类名。在例程中,我们使用::Twist类。
是一个字符串,它包含了我们想发布的话题的名称。
函数最后的参数是一个整数,表示这个发布者发布的消息序列的大小。在大多数情况下,一个相对比较大的值,比方说1000,是合适的。如果你的程序迅速发布比队列可以容纳的更多的消息,最早进入队列的未发送的消息将被丢弃。如果你想从同一个节点发布关于多个话题的消息,你需要为每个话题创建一个独立的ros::对象。
D.srand(time(0)):计算机没有办法产生真正的随机数的,是用算法模拟,所以你只调用rand,每次出来的东西是一样的。设置一个种子后,根据种子的不同,就可以产生不同的数了。而怎么保证种子的不同呢?最简单的办法当然是用永远在向前的时间。srand(time(0));//先设置种子rand();//然后产生随机数。Srand是种下随机种子数,你每回种下的种子不一样,用Rand得到的随机数就不一样。为了每回种下一个不一样的种子,所以就选用Time(0),Time(0)是得到当前时时间值(因为每时每刻时间是不一样的了)。
E.创建并填充消息对象,::Twist msg; msg..x = (rand())/(); msg..z = 2*(rand())/() - 1;
F.发布消息 。使用ros::对象的方法可以很简单地发布消息。例如下面所示:pub.(msg);这个方法将所给的消息添加到发布者的输出消息队列中,从这里,它会尽快被发送到相同话题的订阅者那里。
G.消息发布循环。 我们的例程在while循环中重复发布消息的步骤,随着时间的推移发布不同的消息。程序在这个循环中使用了两个附加的构造函数。 其一为节点是否停止工作的检查 的while循环的条件是:ros::ok() 通俗地说,这个函数检查我们的程序作为ROS节点是否仍处于运行良好的状态。它会一直返回true,除非这个节点有某种原因使其停止工作。 有如下几个原因会使ros::ok()返回false:你可能对节点使用了 kill命令;你可能给程序发送了一个终止信号(Ctrl-C);你可能在程序的某个位置调用了ros::()这个函数是在你的代码中发送节点工作已经完成信号的一个很有用的方法;你可能以相同的名字启动了其他节点,经常是因为你启动了一个相同程序的新实例。 其二为控制消息发布频率。的最后一个新知识点是它使用了ros::Rate对象ros::Rate rate(2);这个对象控制循环运行速度,其构造函数中的参数以赫兹(Hz)为单位,即每秒钟的循环数。 这个例子创建了旨在规范每秒钟执行两个迭代循环的速率对象。邻近每次循环迭代的结尾,我们调用此对象的sleep方法:
rate.sleep();每次调用此方法时就会在程序中产生延迟。延迟的持续时间被用来阻止循环的迭代速率超过指定的速率。没有这种控制,程序会以计算机允许的最快速度发布消息,这样会占满发布和订阅的序列,并且浪费计算和网络资源(在作者的电脑上,一个不加控制的程序会每秒发布大约6300条消息。)。
H.定义输出格式:行尽管和发布速度命令不是直接相关的,但还是值得一看的。这是关于宏可以做什么的一个更加完整的例证,因为它演示了在输出中除了插入字符串还可以插入其他数据的能力
2,2编译 2.2.1在.txt文件中声明消息类型依赖库
因为使用了来自包的消息类型和中的ros.h头文件,我们必须声明对这两个包的依赖关系
进入工作区间目录下的src目录,cd再次进入功能包,vim打开该目录下的.txt
.txt文件的默认版本含有如下行:( )
所依赖的其他包可以添加到这一行的关键字后面,如下所示:
( -names)
对于例程,我们需要添加名为和的依赖库。因此,修改后的行如下所示:
2.2.2在.xml文件中声明消息类型依赖库
我们同样需要在包的清单文件中列出依赖库,通过使用 (编译依赖)和(运行依赖)两个关键字实现【注意:格式有2种,具体见中的3.2】:
-name
-name
打开.xml文件后,找到文件偏下方的绿色字体,在其后添加我们的依赖库,添加后效果如下
在清单文件中声明的依赖库并没有在编译过程中用到;如果你在此处忽略它们,你可能不会看到任何错误消息,直到发布你的包给其他人,他们可能在没有安装所需包的情况下编译你发布的包而导致报错。