🧠Personalizing Bots

Table of contents
- 🍳 Welcome to Robot Town’s Kitchen!
- 🔧 What Are Parameters?
- 🧩 Real-World Analogy
- 🏗️ Let’s Build: ChefBot with Flavor Settings
- 🗂️ Updated Folder Structure
- 🛠️ Step 1: Create the Package
- 🧠 Step 2: Write the ChefBot Node
- 📝 Step 3: Update setup.py
- ⚙️ Step 4: Build and Source
- 🚀 Step 5: Run with Default Flavor
- ✨ Change the Flavor with Parameters
- 📁 Recap So Far
- 📦 Organizing Preferences with YAML
- 🔄 Changing Parameters at Runtime
- 🧠 Optional: Add Live Reaction to Parameter Change
- 🚀 Bonus: Use Launch Files with Parameters
- 📦 Multi-Bot Personalities?
- 🎉 Mini Project: Cooking for a Crowd
- 🧾 What You’ve Learned
- 🪄 What’s Next: Robots With Schedules (ROS2 Timers)

🍳 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:
Has a parameter for
flavor
Reads it at startup
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
Use the
chef_bot
with launch and a parameter fileChange flavor on the fly
Watch the dish change live in the logs
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! 🍜🤖
Subscribe to my newsletter
Read articles from gayatri kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by