ROS学习笔记(3) Cliet-Server与自定义服务数据类型

创建发送请求的客户端

客户端每执行一次,就发送一个请求,当小海龟模拟器接收到这个spawn请求并解析其中的位置信息时,就会在对应的坐标产生一个小海龟

//turtle_spawn.cpp
#include<ros/ros.h>
#include<turtlesim/Spawn.h>

int main(int argc, char **argv){

    ros::init(argc, argv, "turtle_spawn");
    ros::NodeHandle n;

    //发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service 请求数据类型为turtlesim::Spawn
    ros::service::waitForService("/spawn");
    ros::ServiceClient add_turtle = n.serviceClient<turtlesim::Spawn>("/spawn");

    //初始化请求数据
    turtlesim::Spawn srv;
    srv.request.x = 2.0;
    srv.request.y = 2.0;
    srv.request.name = "turtle2";
    ROS_INFO("Call service to spwan turtle [x:%0.6f, y:%0.6f, name:%s]",
                srv.request.x, srv.request.y, srv.request.name.c_str());
    
    //发送请求
    add_turtle.call(srv);

    ROS_INFO("Spwan turtle successfully [name:%s]", srv.response.name.c_str());

    return 0;

}
创建接收请求的服务端

自定义一个服务器,当向这个服务器发送(空)数据时,就打开或关闭小海龟做圆周运动的运动状态

//turtle_command_server.cpp
#include<ros/ros.h>
#include<geometry_msgs/Twist.h>
#include<std_srvs/Trigger.h>

ros::Publisher turtle_vel_pub;
bool pubCommand = false;

bool commandCallback(std_srvs::Trigger::Request &req,
                    std_srvs::Trigger::Response &resp)
{
    pubCommand = !pubCommand;
    ROS_INFO("Publish turtle velocity command [%s]", pubCommand==true?"Yes":"No");

    resp.success = true;
    resp.message = "turtle state changed";

    return true;
}

int main(int argc, char** argv){
    ros::init(argc, argv, "turtle_command_server");
    ros::NodeHandle n;
    ros::ServiceServer command_service = n.advertiseService("/turtle_command", commandCallback);

    turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);

    ROS_INFO("Ready to receive turtle command");

    ros::Rate loop_rate(10);

    while(ros::ok()){
        //查看一次回调函数队列
        ros::spinOnce();

        if(pubCommand){
            geometry_msgs::Twist vel_msg;
            vel_msg.linear.x = 0.5;
            vel_msg.angular.z = 0.2;
            turtle_vel_pub.publish(vel_msg);
        }

        loop_rate.sleep();
    }
    return 0;
}

向此服务器发送数据:rosservice call /turtle_command "{}"

自定义服务数据类型

在这里插入图片描述
包下面创建一个Person.srv文件,内容将用于自动生成srv数据类型

其中srv注意是有返回值的,用---分割开来

string name
uint8 age
uint8 sex

uint8 unknow = 0
uint8 male = 1
uint8 female = 2

---

string result

package.xml中添加依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_generation</exec_depend>
  <exec_depend>message_runtime</exec_depend>

CMakeLists.txt中添加编译选项

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
  message_generation
)
################################################
## Declare ROS messages, services and actions ##
################################################

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

添加了message_runtime

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES learning_service
   CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
#  DEPENDS system_lib
)

客户端(数据发送端)

//person_client.cpp
#include<ros/ros.h>
#include<learning_service/Person.h>

int main(int argc, char **argv){
    ros::init(argc, argv, "person_client");
    ros::NodeHandle n;

    ros::service::waitForService("/show_person");
    ros::ServiceClient person_client = n.serviceClient<learning_service::Person>("/show_person");

    learning_service::Person p;
    p.request.name = "Tom";
    p.request.age = 18;
    p.request.sex = p.request.male;

    ROS_INFO("Call service to show person [name:%s, age:%d, sex:%d]", p.request.name.c_str(), p.request.age, p.request.sex);

    person_client.call(p);

    ROS_INFO("Show person result : %s", p.response.result.c_str());

    return 0;

}

服务器端

//person_server.cpp
#include<ros/ros.h>
#include<learning_service/Person.h>



bool commandCallback(learning_service::Person::Request &req,
                    learning_service::Person::Response &resp)
{
    
    ROS_INFO("Server got the person info : [name: %s, age: %d, sex: %d]",req.name.c_str(), req.age, req.sex);

    resp.result = "successfully sended the person info";

    return true;
}

int main(int argc, char** argv){
    ros::init(argc, argv, "person_server");
    ros::NodeHandle n;
    ros::ServiceServer command_service = n.advertiseService("/show_person", commandCallback);


    ROS_INFO("Ready to receive person info");

    ros::spin();//一致阻塞住,等待信息的请求
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值