Skip to content

2.2.3 Service Communication Custom srv Call

Requirement:

Write a service communication where the client submits two integers to the server, the server sums them and responds with the result to the client.

Analysis:

In the model implementation, the ROS master does not need to be implemented, and the connection establishment is already encapsulated. The key points to focus on are three:

  1. Server
  2. Client
  3. Data

Process:

  1. Write the server implementation;
  2. Write the client implementation;
  3. Add execute permissions to the Python files;
  4. Edit the configuration file;
  5. Compile and execute.

0. vscode configuration

It is necessary to configure the settings.json file as was done previously for the custom msg implementation. If it was already configured and the workspace hasn't changed, this can be skipped. If configuration is needed, the method is the same as before:

json
{
    "python.autoComplete.extraPaths": [
        "/opt/ros/noetic/lib/python3/dist-packages",
    ]
}

1. Server

python
#!/usr/bin/env python
"""
    Requirement:
        Write two nodes to implement service communication. The client node needs to submit two integers to the server.
        The server needs to parse the data submitted by the client, add them, and send the result back to the client,
        which then parses it.

    Server Implementation:
        1. Import libraries
        2. Initialize ROS node
        3. Create service object
        4. Callback function processes the request and generates a response
        5. Spin function

"""
# 1. Import libraries
import rospy
from demo03_server_client.srv import AddInts, AddIntsRequest, AddIntsResponse

# The callback function's parameter is the request object, and the return value is the response object.
def doReq(req):
    # Parse the submitted data
    sum = req.num1 + req.num2
    rospy.loginfo("Submitted data: num1 = %d, num2 = %d, sum = %d", req.num1, req.num2, sum)

    # Create response object, assign value, and return
    # resp = AddIntsResponse()
    # resp.sum = sum
    resp = AddIntsResponse(sum)
    return resp

if __name__ == "__main__":
    # 2. Initialize ROS node
    rospy.init_node("addints_server_p")
    # 3. Create service object
    server = rospy.Service("AddInts", AddInts, doReq)
    # 4. Callback function processes the request and generates a response
    # 5. Spin function
    rospy.spin()

2. Client

python
#!/usr/bin/env python

"""
    Requirement:
        Write two nodes to implement service communication. The client node needs to submit two integers to the server.
        The server needs to parse the data submitted by the client, add them, and send the result back to the client,
        which then parses it.

    Client Implementation:
        1. Import libraries
        2. Initialize ROS node
        3. Create request object
        4. Send request
        5. Receive and process response

    Optimization:
        Incorporate dynamic data acquisition.

"""
# 1. Import libraries
import rospy
from demo03_server_client.srv import *
import sys

if __name__ == "__main__":

    # Optimization implementation
    if len(sys.argv) != 3:
        rospy.logerr("Please submit parameters correctly.")
        sys.exit(1)

    # 2. Initialize ROS node
    rospy.init_node("AddInts_Client_p")
    # 3. Create request object (Service Proxy)
    client = rospy.ServiceProxy("AddInts", AddInts)
    # Before requesting, wait for the service to be ready
    # Method 1:
    # rospy.wait_for_service("AddInts")
    # Method 2:
    client.wait_for_service()
    # 4. Send request, receive and process response
    # Method 1:
    # resp = client(3, 4)
    # Method 2:
    # resp = client(AddIntsRequest(1, 5))
    # Method 3:
    req = AddIntsRequest()
    # req.num1 = 100
    # req.num2 = 200

    # Optimization: Use command line arguments
    req.num1 = int(sys.argv[1])
    req.num2 = int(sys.argv[2])

    resp = client.call(req)
    rospy.loginfo("Response result: %d", resp.sum)

3. Set Permissions

Navigate to the scripts directory in a terminal and execute: chmod +x *.py

4. Configure CMakeLists.txt

CMakeLists.txt

cmake
catkin_install_python(PROGRAMS
  scripts/AddInts_Server_p.py
  scripts/AddInts_Client_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

5. Execution

Process:

  • First, start the server: rosrun package_name server_script.py
  • Then call the client: rosrun package_name client_script.py arg1 arg2

Result:

It will respond with the sum based on the submitted data.