15. ROS programming learning: service communication to generate turtles

Table of contents

Preparation

C++ generates turtles through service communication

Python generates turtles through service communication


Preparation

First write the launch file before starting

roslaunch wugui_ttest wugui_start.launch

List all ROS services

rosservice list
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosservice list
/clear
/key/get_loggers
/key/set_logger_level
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/turtle1/get_loggers
/turtle1/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/wugui_pose/get_loggers
/wugui_pose/set_logger_level

To find the corresponding service, the service name must be found, because in the service communication, the server and the client must have the same service name to communicate, and list the details of the service

rosservice info
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosservice info /spawn 
Node: /turtle1
URI: rosrpc://rosmelodic-virtual-machine:54625
Type: turtlesim/Spawn
Args: x y theta name

Node node name, Type service data type name, Args service received request parameter name.

To query a specific service data type, remember that when querying a custom service data type, you must enter the workspace where it is located to query.

rossrv info
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rossrv info turtlesim/Spawn
float32 x
float32 y
float32 theta
string name
---
string name

(2 messages) 6. ROS Programming Learning : Service Communication——Custom Service Data

The request and response data are separated by ---, and the service details viewed by rosservice info are found at the same time, only the requested data type is displayed.

Try to generate a new turtle through the command in the console terminal

rosservice call
rosservice call /spawn "x: 2.0
y: 2.0
theta: 3.14
name: 'turtle2'"

 Because there is a logical relationship in practical applications, it is not satisfied with generating turtles through commands in the terminal.

C++ generates turtles through service communication

Because the c++ header file of the program and the python library need to use the turtlesim package, it is necessary to determine whether the turtlesim package is imported.

Check the package.xml file

<build_depend>turtlesim</build_depend>
<exec_depend>turtlesim</exec_depend>

Check CMakeList.txt

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  std_msgs
  turtlesim
)

 Create the file wugui_service_client.cpp

 wugui_service_client.cpp

Refer to the following to write the client. (2 messages) 7. ROS programming learning: custom service data c++ call_mechanical computer novice blog-CSDN blog https://blog.csdn.net/wzfafabga/article/details/127383302

#include "ros/ros.h"
#include "turtlesim/Spawn.h"

/* 
    乌龟生成的服务端已经有了,需要客户端给其发布消息
    服务名称:/spawn 通过rosservice list查询到的
    服务通信的消息数据类型:turtlesim/Spawn 通过rosservice info查询到的

    1.头文件
    2.初始化ROS节点
    3.初始化节点句柄
    4.创建客户端
    5.组织与发布数据
    6.处理响应
*/

int main(int argc, char *argv[])
{
    // 防止控制台中文乱码
    setlocale(LC_ALL,"");
    // 初始化ROS节点
    ros::init(argc,argv,"wugui_service_call");
    // 初始化节点句柄
    ros::NodeHandle n;
    // 创建客户端
    ros::ServiceClient client = n.serviceClient<turtlesim::Spawn>("/spawn");
    // 组织数据
    turtlesim::Spawn wugui_xiaoxi;
    wugui_xiaoxi.request.x = 3.0;
    wugui_xiaoxi.request.y = 3.0;
    wugui_xiaoxi.request.theta = 3.14;
    wugui_xiaoxi.request.name = "turtle2";
    // 等待服务端启动,客户端挂起
    client.waitForExistence();
    // 发布数据,并返回一个发布成功与否的布尔类型值
    bool tiaojian = client.call(wugui_xiaoxi);
    // 根据返回的布尔值,按照条件输出字符串
    if(tiaojian)
    {
        ROS_INFO("乌龟已经生成,名字是:%s",wugui_xiaoxi.response.name.c_str());
    }
    else
    {
        ROS_INFO("乌龟消息接收失败,乌龟生成失败!!!");
    }
    return 0;
}

 The point to note is that the string output by the console must be a string of c, otherwise an error will be reported and the data type is wrong!

ROS_INFO("乌龟已经生成,名字是:%s",wugui_xiaoxi.response.name.c_str());

Another point to note is that after the client is created, the waitForExistence function under the client is called, and the client suspend function is added to prevent the client from starting the server first and then starting to report an error.

client.waitForExistence();

Configure the CMakeList.txt file

add_executable(wugui_service_client src/wugui_service_client.cpp)
add_dependencies(wugui_service_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(wugui_service_client
  ${catkin_LIBRARIES}
)

compile

catkin_make

Start the launch file of the previous blog post

(2 messages) 14.ROS Programming Learning: Topic Subscription on Turtle Pose_Machinery Professional Computer Xiaobai's Blog-CSDN Blog https://blog.csdn.net/wzfafabga/article/details/127495303

roslaunch wugui_ttest wugui_start.launch

start the client

Note that roscore is not needed, because roslaunch starts roscore (ROS Master) by default

rosrun wugui_ttest wugui_service_client 

result

 Put the client node into the launch file

<!-- 启动乌龟GUI和键盘控制节点 -->
<launch>
    <!-- 乌龟GUI -->
    <node pkg="turtlesim" type="turtlesim_node" name="turtle1" output="screen"/>
    <!-- 键盘控制 -->
    <node pkg="turtlesim" type="turtle_teleop_key" name="key" output="screen"/>
    <!-- 乌龟位姿订阅 -->
    <node pkg="wugui_ttest" type="test01_sub_pose_p.py" name="wugui_pose" output="screen"/>
    <!-- 加一个乌龟 -->
    <node pkg="wugui_ttest" type="wugui_service_client" name="wugui_spawn" output="screen"/>
</launch>

Start the launch file again

rosrun wugui_ttest wugui_service_client 

Python generates turtles through service communication

 Create wugui_service_client_p.py

 wugui_service_client_p.py

#! /usr/bin/env python
# -*- coding: UTF-8 -*-

""" 
    乌龟生成的服务端已经有了,需要客户端给其发布消息
    服务名称:/spawn 通过rosservice list查询到的
    服务通信的消息数据类型:turtlesim/Spawn 通过rosservice info查询到的

    1.导入包
    2.初始化ROS节点
    3.创建客户端
    4.组织与发布请求数据
    5.处理响应
"""

import rospy
from turtlesim.srv import Spawn,SpawnRequest,SpawnResponse
import logging
logging.basicConfig()

if __name__ == "__main__":
    rospy.init_node("wugui_service_call_p")
    client = rospy.ServiceProxy(name="/spawn", service_class=Spawn)
    request = SpawnRequest()
    request.x = 4.0
    request.y = 4.0
    request.theta = 3.14
    request.name = "turtle3"
    client.wait_for_service()
    try:
        response = client.call(request)
        rospy.loginfo("生成乌龟的名字:%s",response.name)
    except Exception as e:
        rospy.logerr("请求失败")
    # response = client.call(request)
    # rospy.loginfo("生成乌龟的名字:%s",response.name)

Note 1: Add client.wait_for_service() before client.call, so that the client hangs before the server is opened.

Note 2:

import logging

logging.basicConfig() prevents rospy.logerr from reporting errors.

Add executable permission

chmod +x *.py

CMakeList.txt configuration (melodic version is not necessary)

catkin_install_python(PROGRAMS
  scripts/wugui_service_client_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Compile (melodic version is not necessary)

catkin_make

The launch file before starting

roslaunch wugui_ttest wugui_start.launch

start the client

rosrun wugui_ttest wugui_service_client_p.py 

result

 Add this client node to the launch file

<!-- 启动乌龟GUI和键盘控制节点 -->
<launch>
    <!-- 乌龟GUI -->
    <node pkg="turtlesim" type="turtlesim_node" name="turtle1" output="screen"/>
    <!-- 键盘控制 -->
    <node pkg="turtlesim" type="turtle_teleop_key" name="key" output="screen"/>
    <!-- 乌龟位姿订阅 -->
    <node pkg="wugui_ttest" type="test01_sub_pose_p.py" name="wugui_pose" output="screen"/>
    <!-- 加一个乌龟 -->
    <node pkg="wugui_ttest" type="wugui_service_client" name="wugui_spawn" output="screen"/>
    <!-- 加另一个乌龟 -->
    <node pkg="wugui_ttest" type="wugui_service_client_p.py" name="wugui_spawn_p" output="screen"/>
</launch>

Note that the startup of the nodes does not start sequentially according to the launch file, and the names of the tortoise nodes must be different, otherwise the service request fails, which is a characteristic of this server.

Guess you like

Origin blog.csdn.net/wzfafabga/article/details/127507114