编写lidarpub.cpp文件发布话题
#include "ros/ros.h" //引入核心ROS库头文件
#include "std_msgs/String.h" //引入描述对象类型std_msgs::String的头文件
#include <sstream>
int main(int argc, char **argv)
//argc argument count 保存运行时传递给main函数的参数个数
//argv argument vector 保存运行时传递给main函数的参数
{
ros::init(argc, argv, "lidarpub"); //定义"lidarpub"节点名称
ros::NodeHandle n; //建立节点间的网络通信,通常用于初始化通信对象
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
//实例化名为chatter_pub的对象(名字自定),在名为chatter的话题上发布std_msgs::String类型的消息
ros::Rate loop_rate(10);
int count = 0;
while (ros::ok())
{
std_msgs::String msg;
//创建了一个std_msgs::String类型对象,并命名为msg,相当于int i
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str(); //赋值
ROS_INFO("%s", msg.data.c_str()); //打印
chatter_pub.publish(msg); //将赋值后的数据发布到名为chatter的话题上,以供订阅
ros::spinOnce();
loop_rate.sleep();
++count;
}
return 0;
}
配置CMakeLists.txt文件
执行命令catkin_package_create时已经自动生成以下字段程序:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
)
include_directories(
${catkin_INCLUDE_DIRS}
)
还需添加新节点并链接库
include_directories(include ${catkin_INCLUDE_DIRS})
##发布器新节点
add_executable(lidarpub src/lidarpub.cpp)
target_link_libraries(lidarpub ${catkin_LIBRARIES})
##lidarpub生成的可执行文件自定义名字,这里定为与cpp文件同名
##src/lidarpub.cpp源代码的存放位置目录
##订阅器新节点(编写订阅程序后添加,这里暂时不必添加)
add_executable(lidarsub src/lidarsub.cpp)
target_link_libraries(lidarsub ${catkin_LIBRARIES})
注:配置好CMakeLists.txt文件后,再执行catkin_make编译新代码
运行发布器节点
运行roscore实例,启动核心服务
$ roscore
启动新的发布器节点(从一个新的终端输入)
$ rosrun autorc lidarpub
注:$ rosrun package_name(程序包名) executable_name(可执行文件名)
查看新发布话题信息(先执行前两步)
$ rostopic info chatter
注:$ rostopic info topic(话题名)
打印话题消息(先执行前两步)
$ rostopic echo chatter
注:$ rostopic echo topic(话题名)
规划时间节点
调整发布器数据更新频率
在lidarpub.cpp文件中添加两行新代码
ros::Rate naptime(1);
…
…
naptime.sleep();
注:相当于添加一个延时,用于while循环,调用sleep()函数暂时将节点挂起,延时1s后开启,从而降低CPU消耗时间。
编辑lidarsub.cpp文件订阅话题
#include "ros/ros.h"
#include "std_msgs/String.h"
//回调函数(当关联的话题中有新数据可用时,回调函数会被唤醒,同时已发布的数据会出现在参数msg中)
void chatterCallback(const std_msgs::String::ConstPtr& msg)
//msg为指向std_msgs::String类型对象的引用指针参数(由&符号标识),msg名字在发布器程序中自定义
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
//回调函数做的唯一的事情就是显示接收到的数据
int main(int argc, char **argv)
{
ros::init(argc, argv, "lidarsub");
//初始化,自定义订阅器节点名称lidarsub
ros::NodeHandle n;
ros::Subscriber chatter_sub = n.subscribe("chatter", 1000, chatterCallback);
// chatter订阅的话题名,由发布器命名并发布
//1000为队列大小。如果回调函数无法跟上发布数据的频率,数据就需要排队。队满,则队头消息被新消息覆盖而丢失
ros::spin();
//每当话题上有新消息时,回调函数就被唤醒。可以通过spin()命令让主程序挂起,为回调函数的响应提供一些时间。
return 0;
}
在CMakeLists.txt文件中添加订阅器新节点的引用
##订阅器新节点
add_executable(lidarsub src/lidarsub.cpp)
target_link_libraries(lidarsub ${catkin_LIBRARIES})
配置完成后重新编译autorc程序包
运行订阅器节点
运行roscore实例,启动核心服务
$ roscore
启动新的发布器节点(从一个新的终端输入)
$ rosrun autorc lidarpub
启动新的订阅器节点(从一个新的终端输入)
$ rosrun autorc lidarsub
生成运行系统的图形显示(从一个新的终端输入)
$ rqt_graph