Bird
Raised Fist0
ROSframework~8 mins

Request-response communication model in ROS - Performance & Optimization

Choose your learning style10 modes available
Performance: Request-response communication model
MEDIUM IMPACT
This concept affects the responsiveness and latency of message exchanges between nodes in a ROS system.
A node needs to get data from another node and wait for the reply.
ROS
future = client.call_async(request)
future.add_done_callback(handle_response)  # non-blocking async call
The calling node continues working and handles the response when ready, improving responsiveness.
📈 Performance Gainnon-blocking call reduces wait time, improves interaction responsiveness
A node needs to get data from another node and wait for the reply.
ROS
response = client.call(request)  # synchronous call blocks until reply
The calling node is blocked waiting for the response, causing delays and poor responsiveness.
📉 Performance Costblocks node execution until response, increasing latency and reducing throughput
Performance Comparison
PatternNode BlockingLatency ImpactThroughputVerdict
Synchronous request-responseBlocks node executionHigh latency due to waitingLower throughput[X] Bad
Asynchronous request-responseNo blocking, uses callbacksLower latency, faster response handlingHigher throughput[OK] Good
Rendering Pipeline
In ROS, the request-response model involves sending a request message, waiting for processing, and receiving a response. Blocking calls pause node execution, while async calls allow other tasks to proceed.
→Message Sending
→Waiting for Response
→Callback Execution
⚠️ BottleneckWaiting for Response stage causes blocking and delays
Core Web Vital Affected
INP
This concept affects the responsiveness and latency of message exchanges between nodes in a ROS system.
Optimization Tips
1Avoid synchronous request-response calls to prevent node blocking.
2Use asynchronous calls with callbacks to improve interaction responsiveness.
3Monitor service call durations to detect performance bottlenecks.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance drawback of synchronous request-response calls in ROS?
AThey block the calling node until a response is received.
BThey increase the message size significantly.
CThey cause excessive CPU usage due to polling.
DThey require extra network bandwidth.
DevTools: ros2 trace or rqt_graph
How to check: Use ros2 trace to measure service call durations and check if nodes are blocked; use rqt_graph to visualize node communication and delays.
What to look for: Look for long service call durations indicating blocking; check if nodes remain idle during calls showing poor responsiveness.

Practice

(1/5)
1. In ROS, what does the request-response communication model primarily allow?
easy
A. One node sends a request and waits for a reply from another node
B. Nodes continuously publish data without expecting a reply
C. Nodes broadcast messages to all other nodes simultaneously
D. Nodes store data locally without communication

Solution

  1. Step 1: Understand the request-response model in ROS

    This model involves one node sending a request message and waiting for a response from another node.
  2. Step 2: Compare options with this model

    Only One node sends a request and waits for a reply from another node describes this direct ask-and-reply behavior, while others describe different communication types.
  3. Final Answer:

    One node sends a request and waits for a reply from another node -> Option A
  4. Quick Check:

    Request-response = direct ask and reply [OK]
Hint: Request-response means ask first, then wait for answer [OK]
Common Mistakes:
  • Confusing request-response with continuous publishing
  • Thinking request-response is broadcasting
  • Assuming no reply is needed
2. Which of the following is the correct way to define a ROS service server in Python using the request-response model?
easy
A. service = rospy.Service('service_name', ServiceType, handler_function)
B. service = rospy.Publisher('service_name', ServiceType, handler_function)
C. service = rospy.Subscriber('service_name', ServiceType, handler_function)
D. service = rospy.Client('service_name', ServiceType, handler_function)

Solution

  1. Step 1: Recall ROS Python service server syntax

    In ROS, a service server is created using rospy.Service with the service name, type, and handler function.
  2. Step 2: Identify correct function

    Only rospy.Service matches this pattern; Publisher and Subscriber are for topics, Client is not a rospy function.
  3. Final Answer:

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

    Service server uses rospy.Service [OK]
Hint: Service server uses rospy.Service, not Publisher or Subscriber [OK]
Common Mistakes:
  • Using Publisher or Subscriber instead of Service
  • Confusing client and server creation
  • Wrong function names like rospy.Client
3. Given this ROS Python service client code snippet, what will be printed if the service responds with response.result = 42?
import rospy
from example.srv import AddTwoInts

def call_service():
    rospy.wait_for_service('add_two_ints')
    try:
        add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
        response = add_two_ints(20, 22)
        print(response.result)
    except rospy.ServiceException as e:
        print("Service call failed", e)

call_service()
medium
A. Service call failed
B. 42
C. 20
D. None

Solution

  1. Step 1: Understand the service client call

    The client waits for the service, calls it with 20 and 22, and expects a response with a 'result' attribute.
  2. Step 2: Analyze the response printing

    The code prints response.result, which is given as 42 in the question.
  3. Final Answer:

    42 -> Option B
  4. Quick Check:

    Print response.result = 42 [OK]
Hint: Prints the response.result value returned by the service [OK]
Common Mistakes:
  • Confusing request parameters with response
  • Expecting print of input values instead of response
  • Assuming exception without error
4. What is wrong with this ROS Python service server code snippet?
import rospy
from example.srv import Multiply

def handle_multiply(req):
    return req.a * req.b

rospy.init_node('multiply_server')
service = rospy.Service('multiply', Multiply, handle_multiply)
rospy.spin()
medium
A. The service type Multiply is not imported correctly
B. The service name cannot be 'multiply'
C. The handler must return a response object, not just a number
D. rospy.spin() is missing

Solution

  1. Step 1: Check the handler function return type

    In ROS services, the handler must return a response message object, not a raw value.
  2. Step 2: Identify the error in return statement

    Returning req.a * req.b (a number) is incorrect; it should return MultiplyResponse(req.a * req.b) or equivalent.
  3. Final Answer:

    The handler must return a response object, not just a number -> Option C
  4. Quick Check:

    Handler returns response object, not raw value [OK]
Hint: Handler must return response message object, not raw data [OK]
Common Mistakes:
  • Returning raw values instead of response objects
  • Forgetting to import response message class
  • Missing rospy.spin() (though present here)
5. You want to implement a ROS service that returns the sum of two integers only if both are positive; otherwise, it returns zero. Which handler function correctly implements this request-response logic?
hard
A. def handle_sum(req): return SumTwoIntsResponse(req.a + req.b)
B. def handle_sum(req): return SumTwoIntsResponse(req.a + req.b if req.a > 0 or req.b > 0 else 0)
C. def handle_sum(req): if req.a > 0 or req.b > 0: return SumTwoIntsResponse(req.a + req.b) else: return SumTwoIntsResponse(0)
D. def handle_sum(req): if req.a > 0 and req.b > 0: return SumTwoIntsResponse(req.a + req.b) else: return SumTwoIntsResponse(0)

Solution

  1. Step 1: Understand the condition for sum

    The sum should be returned only if both req.a and req.b are positive (greater than zero).
  2. Step 2: Check each option's condition logic

    def handle_sum(req): if req.a > 0 and req.b > 0: return SumTwoIntsResponse(req.a + req.b) else: return SumTwoIntsResponse(0) uses 'and' to check both positive, returning sum or zero correctly. def handle_sum(req): return SumTwoIntsResponse(req.a + req.b if req.a > 0 or req.b > 0 else 0) uses 'or' incorrectly and missing parentheses in ternary. def handle_sum(req): if req.a > 0 or req.b > 0: return SumTwoIntsResponse(req.a + req.b) else: return SumTwoIntsResponse(0) uses 'or' which is wrong logic. def handle_sum(req): return SumTwoIntsResponse(req.a + req.b) always returns sum ignoring condition.
  3. Final Answer:

    def handle_sum(req): if req.a > 0 and req.b > 0: return SumTwoIntsResponse(req.a + req.b) else: return SumTwoIntsResponse(0) -> Option D
  4. Quick Check:

    Both positive check with 'and' = def handle_sum(req): if req.a > 0 and req.b > 0: return SumTwoIntsResponse(req.a + req.b) else: return SumTwoIntsResponse(0) [OK]
Hint: Use 'and' to check both positive before summing [OK]
Common Mistakes:
  • Using 'or' instead of 'and' for both positive check
  • Returning sum without condition
  • Incorrect ternary syntax in return
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