基于STM32F103的树莓派ROS小车——发布订阅话题基础解析

编写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

roscore
启动新的发布器节点(从一个新的终端输入)

$ rosrun autorc lidarpub

注:$ rosrun package_name(程序包名) executable_name(可执行文件名)
pub
查看新发布话题信息(先执行前两步)

$ rostopic info chatter

注:$ rostopic info topic(话题名)
info
打印话题消息(先执行前两步)

$ rostopic echo chatter

注:$ rostopic echo topic(话题名)
echo

规划时间节点

调整发布器数据更新频率
在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

roscore
启动新的发布器节点(从一个新的终端输入)

$ rosrun autorc lidarpub

pub
启动新的订阅器节点(从一个新的终端输入)

$ rosrun autorc lidarsub

sub
生成运行系统的图形显示(从一个新的终端输入)

$ rqt_graph

rqt

猜你喜欢

转载自blog.csdn.net/weixin_63861197/article/details/125457828