快速链接:【ROS入门篇】ROS学习简介

一、ROS中Topic通讯机制

Topic: 异步通讯机制,topic可以同时有多个subscribers,也可以有多个publishers;

Publisher: 向指定话题,发布对应类型的消息;

Sublisher: 订阅话题,一旦话题消息存在,调用回调函数对消息进行处理。

二、Publisher节点示例

  • C++实现(古月居案例)
/*** pub_demo.cpp, 发布turtle/cmd_vel话题,消息类型为geometry_msgs::Twist*/#include #include int main(int argc, char **argv){// ROS节点初始化ros::init(argc, argv, "pub_demo_node");// 创建ROS节点句柄ros::NodeHandle n_;// 创建一个Publisher,发布turtle/cmd_vel话题,消息类型为geometry_msgs::Twist,队列长度为10ros::Publisher pub_ = n_.advertise("/turtle1/cmd_vel", 10);// 设置循环频率ros::Rate loop_rate(10);int count=0;while(ros::ok()){// 初始化类型为geometry_msgs::Twist的消息geometry_msgs::Twist vel_msg;vel_msg.linear.x=0.5;vel_msg.linear.z=0.2;// 发布消息pub_.publish(vel_msg);ROS_INFO("Publish turtle velocity command[%0.2f m/s, %0.2f rad/s]", vel_msg.linear.x, vel_msg.linear.z);// 按照循环频率执行loop_rate.sleep();}return 0;}
  • 修改CMakeLists.txt,配置可执行.cpp文件信息

三、Subscriber节点示例

  • C++实现(古月居案例)
/** * sub_demo.cpp, 订阅/turtle1/pose话题,消息类型为turtlesim::Pose */#include #include void Callback(const turtlesim::Pose::ConstPtr& msg){ROS_INFO("Turtle posex: %0.6f,y: %0.6f", msg->x, msg->y);}int main(int argc, char **argv){// ROS节点初始化ros::init(argc, argv, "sub_demo_node");// 创建ROS节点句柄ros::NodeHandle n_;// 创建一个Subscriber,订阅/turtle1/pose话题,消息类型为turtlesim::Pose,队列长度为10,注册回调函数Callback()ros::Subscriber sub_ = n_.subscribe("/turtle1/Pose", 10, Callback);// 主程序阻塞在这里,循环等待回调函数ros::spin();}
  • 修改CMakeLists.txt,配置可执行.cpp文件信息

四、自定义消息

  • 生成.msg文件,放在msg文件夹内
  • 修改CMakeLists.txt和Package.xml文件
/* .msg文件示例,定义了一个表示people的消息类型*/string nameuint8 sexuint8 ageuint8 unknow=0uint8 male=1uint8 female=2

五、PubAndSub节点示例

  • 同一节点内订阅一个话题,并发布一个话题
/*** SubAndPub_demo.cpp* 订阅/velodyne_points话题,消息类型为sensor_msgs::PointCloud2* 发布/processed_velodyne_points话题,消息类型为sensor_msgs::PointCloud2*/#include #include #include #include #include using namespace std; class SubAndPub{private:ros::NodeHandle n_; ros::Publisher pub_;ros::Subscriber sub_;std::string frame_id_; public:SubAndPub();void callback(const sensor_msgs::PointCloud2& velodyne_sub);void pub_cloud(ros::Publisher pub_, const pcl::PointCloud::Ptr cloud_out);};// End of class SubscribeAndPublish SubAndPub::SubAndPub(){// Topic you want to publishpub_ = n_.advertise("/processed_velodyne_points",1);// Topic you want to subscribesub_ = n_.subscribe("/velodyne_points", 1, &SubAndPub::callback,this);}void SubAndPub::callback(const sensor_msgs::PointCloud2& cloud_in){// do something with the input and generate the output...frame_id_ = cloud_in.header.frame_id;pcl::PointCloud::Ptr cloud (new pcl::PointCloud);pcl::fromROSMsg(cloud_in,*cloud);pub_cloud(pub_,cloud);}void SubAndPub::pub_cloud(ros::Publisher pub_, const pcl::PointCloud::Ptr cloud_out){sensor_msgs::PointCloud2 out;pcl::toROSMsg(*cloud_out,out);out.header.frame_id = frame_id_;pub_.publish(out);}int main(int argc, char **argv){// Initiate ROSros::init(argc, argv, "SubAndPub_demo_node"); // Create an object of class SubscribeAndPublish that will take care of everythingSubAndPub velodyne; ros::spin();return 0;}
  • 修改CMakeLists.txt和package.xml,配置可执行.cpp文件信息