ROS

ROS之通讯类型

Posted by 试墨临池 on October 3, 2024

前言

本文整理ROS中常用通讯类型

Topic话题

Topic是传递message信息的一种通讯类型,需要发布节点和订阅节点

发布节点写法

#include<ros/ros.h>
#include<std_msgs/String.h>
int main(int argc ,*argv[]){
    ros::init(argc, argv, "node_name");
    ros::NodeHandle nh;
    ros::Publishger pub = nh.advertise<std_msgs::String>("topic_name", 10);//10指缓存长度
    while(ros::ok()){
        std_msgs::String msg;
        msg.data = "msg_to_publish";
        pub.publish(msg);
    }
}

订阅节点写法

#include<ros/ros.h>
#include<std_msgs/String.h>
void callback_function(std_,msgs::String msg){
    ROS_INFO(msg.data.c.str());
}
int main(int argc ,*argv[]){
    ros::init(argc, argv, "node_name");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("topic_name", 10, callbach_function);//10指缓存长度
    while(ros::ok()){
        std_msgs::String msg;
        ros::spinOnce();// 用于查看消息包的接收
    }
}

自定义message消息

  1. 在软件包下建立msg文件夹
  2. 文件夹下放置文件:message_name.msg
  3. 在文件中按如下方式定义变量
string name
uint8 sex

uint8 unknown = 0
uint8 male = 1
uint female = 2
  1. 在package.xml中添加依赖
<build_depend>message_generation</build_depend>
<exec_denpend>message_runtime</exec_depend>
  1. 在CmakeList中添加编译选项
find_package(message_generation)

add_message_files(FILES message_name.msg)
generate_message(DEPENDENCIES std_msgs) 

catkin_package(CATKIN_DEPENDS......message_runtime)
  1. 编译文件
catkin_make
  1. 在对应的publish与subscribe节点文件中引用编译出的文件
#include message_name.h

rostopic工具使用

列出所有话题名称:

rostopic list

查看话题发布的内容:

rostopic echo topic_name

查看话题每秒发送消息个数:

rostopic hz topic_name

Service服务

定义服务类型

定义服务类型需要按照如下步骤

  • 在软件包下建立srv文件夹
mkdir srv
  • 在文件夹下创建.srv文件
touch service_name.srv
  • 在文件中添加数据结构
string name
uint8 age
uint8 sex 
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
---
string result
//在---上方是request, 下方是response

  • 在package.xml与CmakeList中添加的与message中类似:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
  message_generation  #added
)
....

add_service_files(FILES Person.srv)  #added
generate_messages(DEPENDENCIES std_msgs)  #added

################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
....

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES learning_service
   CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime #注释取消掉,加上message_runtime
#  DEPENDS system_lib
)
  • 编译
  • 在server与client节点引用头文件

    server服务端写法

#include <ros/ros.h>
#include "pkg_name/service_name.h"

bool Callback(pkg_name::service_name::Request &req,
                    pkg_name::service_name::Response &res) {
   ROS_INFO("name:%s age:%d sex:%d", req.name.c_str(), req.age, req.sex);
   res.result = "OK";
   return true;
}

int main(int argc, char** argv) {
   ros::init(argc, argv, "service_name");
   ros::NodeHandle nh;
   ros::ServiceServer person_service = nh.advertiseService("/service_name", Callback);
   ros::spin();
}

client客户端写法

#include <ros/ros.h>
#include "pkg_name/service_name.h"
int main(int argc, char **argv){
    ros::init(argc, argv, "node_name");
    ros::NodeHandle nh;
    ros::service::waitForService("/service_name");
    ros::ServiceClient client = nh.serviceClient<my_srv>("/service_name");
    my_srv srv;
    while(ros::ok()){
        srv.request.x = 2;
        srv.request.name = "request_name";
        client.call(srv);
        ROS_INFO("%s",srv.response.name.c_str());
    }
}