🧰The Robot Help Desk : How Bots Ask for Help

gayatri kumargayatri kumar
6 min read

πŸ™οΈ Scene: Robot Town’s Help Desk Opens

In the heart of Robot Town, a new booth opens:
β€œThe Robot Help Desk – Need a Fix? Ask RepairBot!” πŸ”§

So far, bots have:

  • Published news on the town radio (topics) πŸ“’

  • Tuned in and reacted (subscribers) 🎧

  • Logged their days (logging) πŸ““

  • Launched together (launch files) πŸš€

But now… they want to ask specific questions and get personal responses.


🧠 What Are Services in ROS2?

Let’s break it down:

ConceptROS2 TermAnalogy in Robot Town
Service ServerThe helperRepairBot sitting at the help desk πŸ› οΈ
Service ClientThe requesterA bot asking for help πŸ™‹β€β™€οΈ
RequestThe questionβ€œCan you update my mood?” πŸ’Œ
ResponseThe answerβ€œDone! You're now happy πŸ˜„β€

πŸ’‘ Unlike topics (fire-and-forget), services are request–response:
A bot asks β†’ waits β†’ gets a reply.


πŸ—ƒοΈ Our Custom Service File: FixMood.srv

Like topics have messages (.msg), services have .srv files:

Inside:
robot_interfaces/srv/FixMood.srv

string bot_name
string new_mood
---
string confirmation

Explanation:

  • The first section is the request: the bot name + the new mood.

  • The line with --- separates it from the response: a confirmation message.

βœ… Don’t forget: After creating this file, update CMakeLists.txt and package.xml like we did for custom messages.


πŸ“ Folder Structure Update

Your updated workspace now looks like this:

robot_town_ws/
└── src/
    β”œβ”€β”€ robot_interfaces/
    β”‚   └── srv/
    β”‚       └── FixMood.srv
    β”œβ”€β”€ mayor_bot/
    β”œβ”€β”€ door_bot/
    β”œβ”€β”€ weather_bot/
    β”œβ”€β”€ umbrella_bot/
    β”œβ”€β”€ emoji_bot/
    β”œβ”€β”€ mood_listener/
    └── repair_bot/           ← πŸ”§ New bot

πŸ”¨ Step-by-Step: Create the RepairBot Package

cd ~/robot_town_ws/src
ros2 pkg create repair_bot --build-type ament_python --dependencies rclpy robot_interfaces

Inside repair_bot/repair_bot/repair_node.py, we’ll create a Service Node.


πŸ› οΈ Writing RepairBot (Service Server)

Here’s the repair desk node that listens for help requests:

import rclpy
from rclpy.node import Node
from robot_interfaces.srv import FixMood  # Import the custom service type FixMood

class RepairBot(Node):
    def __init__(self):
        super().__init__('repair_bot')  # Initialize the node with the name 'repair_bot'

        # Create a service named 'fix_mood' using the FixMood service type
        # - self.srv holds the service server instance
        # - Requests to 'fix_mood' will be handled by self.fix_mood_callback
        self.srv = self.create_service(FixMood, 'fix_mood', self.fix_mood_callback)

        # Log to the console that RepairBot is up and running
        self.get_logger().info("πŸ”§ RepairBot ready at the help desk!")

    def fix_mood_callback(self, request, response):
        # Log the request details using get_logger().info()
        # - request.bot_name: the name of the bot needing repair
        # - request.new_mood: the new mood we're setting
        self.get_logger().info(
            f"Request received: Change {request.bot_name}'s mood to {request.new_mood}"
        )

        # Set the response message (confirmation is a field from FixMood.srv)
        response.confirmation = f"{request.bot_name} is now feeling {request.new_mood}!"

        # Return the populated response object
        return response

πŸ§ͺ Test the Service Manually (for now)

Build the workspace:

cd ~/robot_town_ws
colcon build
source install/setup.bash

Then run RepairBot:

ros2 run repair_bot repair_node

In another terminal:

ros2 service call /fix_mood robot_interfaces/srv/FixMood "{bot_name: 'EmojiBot', new_mood: 'πŸ˜„'}"

You’ll see output like:

response:
  confirmation: EmojiBot is now feeling πŸ˜„!

πŸŽ‰ Success! Your bots can now ask for help and get real-time replies.


πŸ“š Recap

So far we introduced:

βœ… What ROS2 services are
βœ… The .srv format (request/response)
βœ… The RepairBot service server
βœ… How to call services from the terminal


πŸ€– Meet EmojiBot (Again!)

EmojiBot is backβ€”but this time with feelings problems 🫀
Let’s give him the ability to request help from RepairBot when he’s feeling off.


🎯 Objective

  • Create a service client inside EmojiBot

  • It will request a mood change from RepairBot

  • RepairBot will reply with a confirmation


πŸ“¦ Folder Structure (Growing City)

Let’s update our layout again:

robot_town_ws/
└── src/
    β”œβ”€β”€ repair_bot/               ← Service server
    └── emoji_client_bot/         ← Service client (new)

πŸ”¨ Step-by-Step: Create EmojiBot Client Package

cd ~/robot_town_ws/src
ros2 pkg create emoji_client_bot --build-type ament_python --dependencies rclpy robot_interfaces

Create this file:

emoji_client_bot/
└── emoji_client_bot/
    └── mood_changer.py

Inside mood_changer.py:

import rclpy
from rclpy.node import Node
from robot_interfaces.srv import FixMood  # Import the FixMood custom service type

class MoodClient(Node):
    def __init__(self):
        super().__init__('emoji_client')  # Initialize the node with the name 'emoji_client'

        # Create a service client for the 'fix_mood' service using the FixMood type
        self.cli = self.create_client(FixMood, 'fix_mood')

        # Wait until the service becomes available (poll every 1 second)
        while not self.cli.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('⏳ Waiting for RepairBot to be available...')

        # Prepare the request object using FixMood.Request (auto-generated from .srv file)
        self.request = FixMood.Request()
        self.request.bot_name = "EmojiBot"      # Set the bot name in the request
        self.request.new_mood = "😎"            # Set the new mood for the bot

        # Send the service request asynchronously and store the future (promise-like object)
        self.future = self.cli.call_async(self.request)

        # Log that the request has been sent
        self.get_logger().info(f"πŸ“¨ Request sent to fix EmojiBot’s mood to {self.request.new_mood}")

def main(args=None):
    rclpy.init(args=args)  # Initialize ROS 2 communication
    mood_client = MoodClient()  # Create an instance of MoodClient node

    # Keep spinning (processing events) until the service call is complete
    while rclpy.ok():
        rclpy.spin_once(mood_client)  # Process incoming/outgoing data once

        # Check if the service response has been received
        if mood_client.future.done():
            try:
                # Get the result from the future
                response = mood_client.future.result()
                # Log the confirmation from the server
                mood_client.get_logger().info(f"βœ… Confirmation: {response.confirmation}")
            except Exception as e:
                # Log any error that occurred during the service call
                mood_client.get_logger().error(f'Service call failed: {e}')
            break  # Exit the loop once the response has been handled

    # Clean up the node and shutdown ROS 2
    mood_client.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

πŸ› οΈ Build and Source

As always, go back to the root of your workspace and rebuild:

cd ~/robot_town_ws
colcon build
source install/setup.bash

πŸš€ Launching the Scene

Open two terminals:

Terminal 1 – Start the help desk:

ros2 run repair_bot repair_node

Terminal 2 – Send EmojiBot to the help desk:

ros2 run emoji_client_bot mood_changer

🧾 Output:

[repair_bot]: Request received: Change EmojiBot's mood to 😎
[emoji_client]: βœ… Confirmation: EmojiBot is now feeling 😎!

It’s working! EmojiBot requested help, RepairBot replied with a friendly fix. βœ…


🧩 Mini Project: Add Some Spice!

Upgrade EmojiBot so it randomly requests moods every few seconds using a launch file, or even reacts to logs. You can even build a web dashboard later that sends service calls!

Want ideas?

  • TrafficBot asks for reset after traffic jam.

  • WeatherBot updates its reporting region via service.

  • EmojiBot asks to cycle moods randomly every minute.


🧠 What We Learned

ConceptDescription
.srv FileDescribes request and response formats
Service Server NodeThe node that handles incoming requests
Service Client NodeThe node that sends a request
create_service()Defines a server in code
create_client()Lets your bot call a service
call_async()Sends a request and waits for response

🧳 What’s Next?

Now that bots can ask for help, it’s time to give them personal preferences and settings.

πŸ“¦ Next Up:
πŸ§ͺ Personalizing Bots (Parameters in ROS2)

Give each bot its own quirks and behaviors through parameters.

Get ready to make each bot in Robot Town uniquely weird and wonderful. πŸŽ­πŸ€–

0
Subscribe to my newsletter

Read articles from gayatri kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

gayatri kumar
gayatri kumar