๐ฐ๏ธRobots With Schedules

Table of contents
- ๐๏ธ Welcome to a Timely Town
- โฐ Timers in ROS2: What Are They?
- ๐ง How ROS2 Timers Work (Simple Mental Model)
- ๐ค Introducing WaterBot
- ๐ง water_node.py
- ๐จ Build & Run WaterBot
- ๐งญ Whatโs Happening Behind the Scenes?
- ๐๏ธ Folder Structure Recap
- ๐งน Enter TrashBot: Evening Cleanup Duty
- ๐ ๏ธ Folder Setup (Inside robot_town_ws/src/trash_bot/)
- โป๏ธ trash_node.py
- ๐ Launching WaterBot + TrashBot Together
- ๐งช Build and Launch It
- ๐ Expected Output
- ๐๏ธ Robot Town So Far
- ๐ง What You Learned
- โ Mini Project: Build a Chore Scheduler
- ๐ฐ Coming Up Next:

๐๏ธ Welcome to a Timely Town
In Robot Town, not all bots act on commands.
Some bots operate on daily schedules โ like:
WaterBot watering gardens at sunrise โ๏ธ
TrashBot collecting garbage every evening ๐๏ธ
DanceBot performing hourly groove sessions ๐บ
These bots donโt wait for messages or user input โ they use timers to trigger actions periodically.
Today, weโll learn to give our bots their own alarm clocks using ROS2 Timers.
โฐ Timers in ROS2: What Are They?
In simple terms, a timer tells your bot:
โHey! Every x seconds, do this thing.โ
Timers are perfect for:
Repeating actions at intervals
Scheduling routines
Looping without using
while True
๐ง How ROS2 Timers Work (Simple Mental Model)
Think of it like this:
Timer = A robotโs digital alarm clock.
Every few seconds โ โRing!โ โ Run a task.
You set:
The interval (e.g., every 2 seconds)
The callback function (what to do when the alarm rings)
๐ค Introducing WaterBot
Letโs build WaterBot, who waters plants every 5 seconds.
๐ Folder Prep (Inside robot_town_ws/src/water_bot/
)
water_bot/
โโโ water_bot/
โ โโโ __init__.py
โ โโโ water_node.py
โโโ package.xml
โโโ setup.py
โโโ resource/
โโโ water_bot
Make sure CMakeLists.txt
and setup.cfg
are set up (like in previous bots).
๐ง water_
node.py
Hereโs a simple timer-powered ROS2 node.
import rclpy
from rclpy.node import Node
class WaterBot(Node):
def __init__(self):
super().__init__('water_bot') # Initialize the node with the name 'water_bot'
self.counter = 0 # Keeps track of how many times the plants have been watered
# ๐ Create a timer that triggers the water_plants method every 5 seconds
# - 5.0 is the interval in seconds
# - self.water_plants is the callback function to call every interval
self.timer = self.create_timer(5.0, self.water_plants)
# ๐ Log startup message to indicate the bot is active
self.get_logger().info('WaterBot is on duty!')
def water_plants(self):
# ๐งฎ Increment the watering counter
self.counter += 1
# ๐ฃ Log each watering action with round number
self.get_logger().info(f'๐ฑ Watering plants... round {self.counter}')
def main(args=None):
rclpy.init(args=args) # ๐ Initialize the ROS 2 system
node = WaterBot() # ๐ค Create an instance of WaterBot
rclpy.spin(node) # ๐ Keep the node alive and processing timer callbacks
rclpy.shutdown() # ๐ด Shutdown the ROS 2 system when done
if __name__ == '__main__':
main() # ๐ Run the main function if this file is executed directly
๐จ Build & Run WaterBot
Build your workspace:
colcon build
source install/setup.bash
Then run:
ros2 run water_bot water_node
Expected output:
[INFO] [water_bot]: WaterBot is on duty!
[INFO] [water_bot]: ๐ฑ Watering plants... round 1
[INFO] [water_bot]: ๐ฑ Watering plants... round 2
...
๐งญ Whatโs Happening Behind the Scenes?
create_timer(interval, callback)
- Calls
callback()
everyinterval
seconds.
rclpy.spin(node)
Keeps the bot running and waiting for timer events.
Like a power grid that lets timers tick.
๐๏ธ Folder Structure Recap
Hereโs how your WaterBot package should now look:
robot_town_ws/
โโโ src/
โโโ water_bot/
โ โโโ water_bot/
โ โ โโโ water_node.py
โ โโโ package.xml
โ โโโ setup.py
โ โโโ setup.cfg
โ โโโ resource/
โ โโโ water_bot
If you've built mayor_bot
, door_bot
, chatter_bot
, etc., your workspace may now look like:
src/
โโโ mayor_bot/
โโโ door_bot/
โโโ chatter_bot/
โโโ weather_bot/
โโโ umbrella_bot/
โโโ chef_bot/
โโโ water_bot/
One big bustling bot community!
๐งน Enter TrashBot: Evening Cleanup Duty
Letโs build a second bot: TrashBot, who takes out the trash every 3 seconds.
๐ ๏ธ Folder Setup (Inside robot_town_ws/src/trash_bot/
)
trash_bot/
โโโ trash_bot/
โ โโโ __init__.py
โ โโโ trash_node.py
โโโ package.xml
โโโ setup.py
โโโ resource/
โโโ trash_bot
โป๏ธ trash_
node.py
import rclpy
from rclpy.node import Node
class TrashBot(Node):
def __init__(self):
super().__init__('trash_bot')
self.counter = 0
# Timer: every 3 seconds
self.timer = self.create_timer(3.0, self.take_out_trash)
self.get_logger().info('TrashBot reporting for duty!')
def take_out_trash(self):
self.counter += 1
self.get_logger().info(f'๐๏ธ Taking out trash... trip {self.counter}')
def main(args=None):
rclpy.init(args=args)
node = TrashBot()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == '__main__':
main()
๐ Launching WaterBot + TrashBot Together
Now letโs create a launch file to wake both bots up together, like setting multiple alarms in one clock.
๐ Create a New Package: daily_schedule
tcd ~/robot_town_ws/src
ros2 pkg create --build-type ament_python daily_schedule
Inside daily_schedule/launch/
, create:
daily_schedule/
โโโ daily_schedule/
โ โโโ __init__.py
โโโ launch/
โ โโโ morning_routine.launch.py
โโโ package.xml
โโโ setup.py
โโโ resource/
โโโ daily_schedule
๐ morning_
routine.launch.py
from launch import LaunchDescription # ๐ฆ Import the LaunchDescription object from the 'launch' module
from launch_ros.actions import Node # ๐ Import the Node action from the ROS 2 launch system
def generate_launch_description():
return LaunchDescription([ # ๐ Create and return a list of launch actions
# ๐ Launch WaterBot
Node(
package='water_bot', # The ROS 2 package containing the node
executable='water_node', # The executable name defined in setup.py or entry_points
name='water_bot' # The name the node will use in the ROS graph
),
# ๐๏ธ Launch TrashBot
Node(
package='trash_bot', # Package where the trash bot's code lives
executable='trash_node', # The actual ROS 2 executable for TrashBot
name='trash_bot' # Node name used for logging, namespace, etc.
),
])
๐งช Build and Launch It
Step 1: Build Everything
cd ~/robot_town_ws
colcon build
source install/setup.bash
Step 2: Run the Routine
ros2 launch daily_schedule morning_routine.launch.py
๐ Expected Output
[INFO] [water_bot]: WaterBot is on duty!
[INFO] [trash_bot]: TrashBot reporting for duty!
[INFO] [water_bot]: ๐ฑ Watering plants... round 1
[INFO] [trash_bot]: ๐๏ธ Taking out trash... trip 1
[INFO] [trash_bot]: ๐๏ธ Taking out trash... trip 2
[INFO] [water_bot]: ๐ฑ Watering plants... round 2
...
๐๏ธ Robot Town So Far
Hereโs how your workspace might look now:
robot_town_ws/
โโโ src/
โโโ mayor_bot/
โโโ door_bot/
โโโ chatter_bot/
โโโ weather_bot/
โโโ umbrella_bot/
โโโ chef_bot/
โโโ water_bot/
โโโ trash_bot/
โโโ daily_schedule/
Each bot lives in its own home, and daily_schedule acts like the Town Planner, coordinating routines.
๐ง What You Learned
ROS2 Timers let bots perform tasks at scheduled intervals.
create_timer()
is used to register periodic callbacks.Launch files can activate multiple bots together like synchronized clocks.
โ Mini Project: Build a Chore Scheduler
Create more bots with timers:
๐งฝ CleanBot: cleans every 10 sec
๐ PatrolBot: patrols every 7 sec
๐ฝ๏ธ ServeBot: serves food every 4 sec
Add them to your morning_
routine.launch.py
!
๐ฐ Coming Up Next:
Silent Conversations (Actions in ROS2)
Bots will now make requests that take time, and wait for replies โ like ordering parts or requesting repairs.
Ready to turn bots into helpful collaborators instead of just time-based task machines?
Letโs build silent action bots in the next issue of Robot Town! ๐ ๏ธ๐ค
Subscribe to my newsletter
Read articles from gayatri kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by