Bird
Raised Fist0
ROSframework~7 mins

Creating a service server in ROS

Choose your learning style10 modes available
Introduction

A service server in ROS lets your robot answer questions or perform tasks when asked. It waits for requests and sends back replies.

When your robot needs to perform a task only when asked, like turning on a light.
When you want to get specific information from your robot, like its current position.
When you need a quick response from your robot without continuous data streaming.
When coordinating actions that depend on a request and a reply, like opening a door.
When you want to keep your robot's tasks organized by separating requests and responses.
Syntax
ROS
def handle_request(request):
    # process the request
    return response

service = rospy.Service('service_name', ServiceType, handle_request)
rospy.spin()

The handle_request function processes incoming requests and returns responses.

rospy.Service creates the service server with a name, type, and handler.

Examples
This example creates a service server that adds two integers sent in the request and returns the sum.
ROS
def add_two_ints(req):
    sum = req.a + req.b
    return AddTwoIntsResponse(sum)

service = rospy.Service('add_two_ints', AddTwoInts, add_two_ints)
rospy.spin()
This server turns a light on or off based on the request's state and confirms success.
ROS
def toggle_light(req):
    if req.state:
        turn_on_light()
    else:
        turn_off_light()
    return ToggleLightResponse(True)

service = rospy.Service('toggle_light', ToggleLight, toggle_light)
rospy.spin()
Sample Program

This complete ROS Python node creates a service server named 'add_two_ints'. It waits for requests with two integers, adds them, and sends back the sum. It logs the operation and stays running to serve requests.

ROS
import rospy
from beginner_tutorials.srv import AddTwoInts, AddTwoIntsResponse

def handle_add_two_ints(req):
    sum = req.a + req.b
    rospy.loginfo(f"Adding {req.a} + {req.b} = {sum}")
    return AddTwoIntsResponse(sum)

def add_two_ints_server():
    rospy.init_node('add_two_ints_server')
    service = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
    rospy.loginfo("Ready to add two ints.")
    rospy.spin()

if __name__ == '__main__':
    add_two_ints_server()
OutputSuccess
Important Notes

Always call rospy.spin() to keep the service server running and ready to handle requests.

Service names should be unique and descriptive to avoid confusion.

Use rospy.loginfo() to print helpful messages for debugging and monitoring.

Summary

A service server waits for requests and sends back replies in ROS.

Define a handler function to process requests and return responses.

Create the server with rospy.Service and keep it running with rospy.spin().

Practice

(1/5)
1. What is the main role of a service server in ROS?
easy
A. To publish messages continuously
B. To wait for requests and send back replies
C. To subscribe to topics and process data
D. To log information to the console

Solution

  1. Step 1: Understand the service server role

    A service server in ROS waits for incoming requests from clients and sends back replies after processing.
  2. Step 2: Differentiate from other ROS nodes

    Unlike publishers or subscribers, a service server handles request-response communication, not continuous data streams.
  3. Final Answer:

    To wait for requests and send back replies -> Option B
  4. Quick Check:

    Service server = request and reply [OK]
Hint: Service servers handle requests and replies, not continuous data [OK]
Common Mistakes:
  • Confusing service servers with publishers
  • Thinking service servers subscribe to topics
  • Assuming service servers only log data
2. Which of the following is the correct way to create a service server in ROS using rospy?
easy
A. server = rospy.Client('service_name', ServiceType, handler_function)
B. server = rospy.Publisher('service_name', ServiceType, handler_function)
C. server = rospy.Subscriber('service_name', ServiceType, handler_function)
D. server = rospy.Service('service_name', ServiceType, handler_function)

Solution

  1. Step 1: Identify the correct rospy function

    The function to create a service server is rospy.Service, which takes the service name, service type, and handler function.
  2. Step 2: Exclude other ROS communication methods

    Publisher and Subscriber are for topics, Client is not a rospy function for servers.
  3. Final Answer:

    server = rospy.Service('service_name', ServiceType, handler_function) -> Option D
  4. Quick Check:

    Service server creation = rospy.Service [OK]
Hint: Use rospy.Service to create service servers, not Publisher or Subscriber [OK]
Common Mistakes:
  • Using rospy.Publisher instead of rospy.Service
  • Confusing service server with subscriber
  • Trying to use a non-existent rospy.Client
3. Given the following ROS service server code snippet, what will be the output when a client sends a request with data=5?
import rospy
from beginner_tutorials.srv import AddTwoInts, AddTwoIntsResponse

def handle_add_two_ints(req):
    return AddTwoIntsResponse(req.a + req.b)

rospy.init_node('add_two_ints_server')
service = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
rospy.spin()
medium
A. The server returns the sum of req.a and req.b
B. The server returns the product of req.a and req.b
C. The server returns the difference of req.a and req.b
D. The server returns an error because of missing return statement

Solution

  1. Step 1: Analyze the handler function

    The function handle_add_two_ints returns the sum of req.a and req.b wrapped in AddTwoIntsResponse.
  2. Step 2: Understand the server behavior on request

    When a client sends a request with data=5 (assuming req.a=5 and req.b is provided), the server replies with their sum.
  3. Final Answer:

    The server returns the sum of req.a and req.b -> Option A
  4. Quick Check:

    Handler returns sum = The server returns the sum of req.a and req.b [OK]
Hint: Handler returns sum of inputs; check return statement carefully [OK]
Common Mistakes:
  • Assuming multiplication instead of addition
  • Forgetting to return a response object
  • Confusing request fields names
4. Identify the error in this ROS service server code snippet:
import rospy
from beginner_tutorials.srv import AddTwoInts, AddTwoIntsResponse

def handle_add(req):
    sum = req.a + req.b

rospy.init_node('add_two_ints_server')
service = rospy.Service('add_two_ints', AddTwoInts, handle_add)
rospy.spin()
medium
A. The handler function does not return a response object
B. The service name is invalid
C. The node is not initialized
D. The service type is incorrect

Solution

  1. Step 1: Check the handler function

    The handler function calculates sum but does not return AddTwoIntsResponse, which is required.
  2. Step 2: Verify other parts of the code

    The service name, node initialization, and service type are correct and valid.
  3. Final Answer:

    The handler function does not return a response object -> Option A
  4. Quick Check:

    Handler must return response [OK]
Hint: Always return a response object from the handler function [OK]
Common Mistakes:
  • Forgetting to return AddTwoIntsResponse
  • Misnaming the handler function
  • Not calling rospy.init_node
5. You want to create a ROS service server that returns the maximum of two integers sent by the client. Which handler function correctly implements this behavior?
hard
A. def handle_max(req): return MaxIntsResponse(max(req.a, req.b))
B. def handle_max(req): return MaxIntsResponse(req.a + req.b)
C. def handle_max(req): if req.a > req.b: return MaxIntsResponse(req.a) else: return MaxIntsResponse(req.b)
D. def handle_max(req): return MaxIntsResponse(min(req.a, req.b))

Solution

  1. Step 1: Understand the requirement

    The server must return the maximum of two integers sent by the client.
  2. Step 2: Evaluate each handler function

    def handle_max(req): return MaxIntsResponse(max(req.a, req.b)) uses max() but assumes MaxIntsResponse accepts a single argument correctly; def handle_max(req): if req.a > req.b: return MaxIntsResponse(req.a) else: return MaxIntsResponse(req.b) explicitly returns the max value using if-else and returns response properly; def handle_max(req): return MaxIntsResponse(req.a + req.b) returns sum, which is incorrect; def handle_max(req): return MaxIntsResponse(min(req.a, req.b)) returns minimum, which is wrong.
  3. Final Answer:

    def handle_max(req): if req.a > req.b: return MaxIntsResponse(req.a) else: return MaxIntsResponse(req.b) -> Option C
  4. Quick Check:

    Correct max logic with proper return = def handle_max(req): if req.a > req.b: return MaxIntsResponse(req.a) else: return MaxIntsResponse(req.b) [OK]
Hint: Use if-else to return max value wrapped in response [OK]
Common Mistakes:
  • Returning sum instead of max
  • Returning min instead of max
  • Incorrectly using max() without proper response
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard