🧠Personalizing Bots

gayatri kumargayatri kumar
6 min read

🍳 Welcome to Robot Town’s Kitchen!

In a corner of Robot Town, ChefBot has finally opened his food truck. But he doesn’t just cook one thing—he has flavor settings! Like a dial on his chest, you can set preferences: spicy, sweet, salty...

How do we implement this in ROS2?
With parameters.


🔧 What Are Parameters?

In ROS2, parameters are name-value settings stored inside a node.
Think of them as bot configuration knobs. You don’t need to change code to modify behavior—you just tweak a dial!

📦 Example:

flavor: "spicy"

ChefBot reads that value and throws chili flakes into every dish 🌶️


🧩 Real-World Analogy

Imagine each bot has a tiny control panel inside their chest:

[ Mood Dial: 😄 ]
[ Cooking Style: spicy ]
[ Max Speed: 2.0 m/s ]

By reading these parameters at runtime, the bot adapts its behavior.
It’s personality, preferences, and performance—all adjustable!


🏗️ Let’s Build: ChefBot with Flavor Settings

We’ll create a bot that:

  1. Has a parameter for flavor

  2. Reads it at startup

  3. Cooks a dish accordingly


🗂️ Updated Folder Structure

We continue building in our Robot Town workspace:

robot_town_ws/
└── src/
    ├── chef_bot/
    │   ├── chef_bot/
    │   │   └── chef_node.py
    │   ├── package.xml
    │   └── setup.py

🛠️ Step 1: Create the Package

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

🧠 Step 2: Write the ChefBot Node

In chef_bot/chef_bot/chef_node.py:

import rclpy
from rclpy.node import Node

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

        # 🧂 Declare a ROS2 parameter named 'flavor' with a default value of 'neutral'
        # This makes the parameter accessible to external tools (like ros2 param set)
        self.declare_parameter('flavor', 'neutral')

        # 🍜 Retrieve the parameter value:
        # - get_parameter('flavor') gets a Parameter object
        # - get_parameter_value() extracts the underlying value container
        # - string_value fetches the actual string (e.g. "spicy", "sweet", etc.)
        self.flavor = self.get_parameter('flavor').get_parameter_value().string_value

        # 🧾 Log the bot's startup message and its cooking style
        self.get_logger().info(f'👨‍🍳 ChefBot activated! Cooking style: {self.flavor}')

        # 🍽️ Start cooking based on flavor
        self.cook()

    def cook(self):
        # 🍛 Determine dish based on flavor
        if self.flavor == 'spicy':
            dish = 'Spicy Curry 🌶️'
        elif self.flavor == 'sweet':
            dish = 'Chocolate Cake 🍰'
        elif self.flavor == 'salty':
            dish = 'Salted Fries 🍟'
        else:
            dish = 'Plain Rice 🍚'

        # 🗒️ Log the dish being served
        self.get_logger().info(f'🍽️ Serving today: {dish}')

def main(args=None):
    rclpy.init(args=args)  # Initialize the ROS2 Python client library
    node = ChefBot()       # Create an instance of ChefBot
    rclpy.spin(node)       # Keep the node alive to process callbacks (none in this case)
    node.destroy_node()    # Clean up the node when shutting down
    rclpy.shutdown()       # Shutdown the ROS2 system

📝 Step 3: Update setup.py

In setup.py, ensure you include:

entry_points={
    'console_scripts': [
        'chef_node = chef_bot.chef_node:main',
    ],
},

⚙️ Step 4: Build and Source

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

🚀 Step 5: Run with Default Flavor

ros2 run chef_bot chef_node

📤 Output:

[chef_bot]: 👨‍🍳 ChefBot activated! Cooking style: neutral
[chef_bot]: 🍽️ Serving today: Plain Rice 🍚

✨ Change the Flavor with Parameters

Let’s tell ChefBot what to cook using a parameter override:

ros2 run chef_bot chef_node --ros-args -p flavor:=spicy

Output:

[chef_bot]: 👨‍🍳 ChefBot activated! Cooking style: spicy
[chef_bot]: 🍽️ Serving today: Spicy Curry 🌶️

Try others too:

-p flavor:=sweet
-p flavor:=salty

📁 Recap So Far

Last time in Robot Town, ChefBot served dishes based on the flavor parameter you gave him at launch:

ros2 run chef_bot chef_node --ros-args -p flavor:=sweet

But now, let’s go further:

  • Use YAML files to manage preferences cleanly

  • Update parameters at runtime like turning the mood dial on the fly

  • Pass parameters using launch files


📦 Organizing Preferences with YAML

Instead of typing parameters every time, we can use a config file.

🗂️ Create chef_config.yaml

In chef_bot/chef_bot/chef_config.yaml:

chef_bot:
  ros__parameters:
    flavor: salty

🧪 Run ChefBot with the YAML

ros2 run chef_bot chef_node --ros-args --params-file src/chef_bot/chef_bot/chef_config.yaml

📤 Output:

[chef_bot]: 👨‍🍳 ChefBot activated! Cooking style: salty
[chef_bot]: 🍽️ Serving today: Salted Fries 🍟

Boom. Cleaner, reusable, and easy to version control!


🔄 Changing Parameters at Runtime

Yes—ROS2 allows live updates to declared parameters!

In one terminal, run:

ros2 run chef_bot chef_node

Then, in another terminal, try this magic:

ros2 param set /chef_bot flavor sweet

📤 Output (in first terminal):

[chef_bot]: Parameter 'flavor' changed: sweet
[chef_bot]: 🍽️ Serving today: Chocolate Cake 🍰

✨ ChefBot re-cooks instantly!

✅ You can use on_parameter_event to react when a value changes dynamically.


🧠 Optional: Add Live Reaction to Parameter Change

Here’s an enhanced version of cook() that reacts when flavor changes:

# Register a callback that gets triggered whenever a parameter is changed at runtime
self.add_on_set_parameters_callback(self.param_callback)

def param_callback(self, params):
    # This function is called automatically whenever a parameter is updated
    # 'params' is a list of parameter objects containing the new values

    for param in params:
        # Check if the updated parameter is the one we're interested in
        if param.name == "flavor":
            # Update the local flavor variable to the new value
            self.flavor = param.value

            # Log the change so we know something happened
            self.get_logger().info(f"👨‍🍳 Flavor changed: {self.flavor}")

            # Call the cooking function again with the new flavor
            self.cook()

    # Return a result object to let ROS2 know the parameter update was handled successfully
    return rclpy.parameter.ParameterEventHandler.Result(successful=True)

This makes the bot instantly respond to your flavor changes like a real-time cooking show!


🚀 Bonus: Use Launch Files with Parameters

Let’s build a launch file that starts ChefBot with preferences!

Create chef_launch.py in chef_bot/launch/:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='chef_bot',
            executable='chef_node',
            name='chef_bot',
            parameters=['../chef_bot/chef_config.yaml']
        )
    ])

Run with:

ros2 launch chef_bot chef_launch.py

📦 Multi-Bot Personalities?

You can now assign each bot their own mood/settings in separate YAML files or pass them in via launch files. This is your configuration control center. 💡

Imagine:

mayor_bot:
  mood: cheerful

guard_bot:
  alert_level: 5

chef_bot:
  flavor: spicy

🎉 Mini Project: Cooking for a Crowd

  1. Use the chef_bot with launch and a parameter file

  2. Change flavor on the fly

  3. Watch the dish change live in the logs

  4. Try creating more parameters like dish_size, cook_time, etc.


🧾 What You’ve Learned

✅ Declaring and using parameters
✅ Launch-time and runtime parameter control
✅ Parameter files for neat configuration
✅ Triggering behavior with parameter updates


🪄 What’s Next: Robots With Schedules (ROS2 Timers)

Next time, we’ll give bots alarm clocks and routines.
No more infinite while-loops—they’ll know when to act.

In Robot Town, timing is everything. ⏰
ChefBot will cook on time. TrafficBot will blink on time. DanceBot will move on cue.

Let’s teach them all… scheduling magic!


See you next time! 🍜🤖

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