๐Ÿ“ปThe Town Radio System

gayatri kumargayatri kumar
6 min read

๐ŸŽฏ The Big Idea

In Robot Town so far:

  • ๐Ÿค– Each bot could speak, but to no one in particular.

  • ๐Ÿ“ข Now weโ€™re building a public radio system โ€” a topic โ€” where a bot can announce things.

  • ๐Ÿง Any bot that wants to listen just needs to tune in to the topic.

Now, weโ€™ll only build the broadcaster โ€” the publisher.


๐Ÿ—๏ธ What Are Topics in ROS2?

Imagine a radio station in the town square:

  • A bot publishes (announces) something to a topic

  • Anyone subscribed to that topic hears it

In ROS2:

  • Topics are named message channels

  • Bots publish messages to these channels

  • Others can subscribe to them (we'll do that in the next article!)


๐Ÿ“ฆ Letโ€™s Build WeatherBot

Our new robot will:

  • Live in its own house (weather_bot)

  • Publish temperature updates to a topic called /weather

  • Use ROS2 messages (std_msgs.msg.String)


๐Ÿ  Step 1: Create the weather_bot Package

Navigate to your workspace:

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

New workspace layout:

robot_town_ws/
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ mayor_bot/
    โ”œโ”€โ”€ door_bot/
    โ”œโ”€โ”€ chatter_bot/
    โ”œโ”€โ”€ greeter_bot/
    โ””โ”€โ”€ weather_bot/
        โ””โ”€โ”€ weather_bot/

๐Ÿ“ Step 2: Create the Publisher Node

Create a new Python file:

touch ~/robot_town_ws/src/weather_bot/weather_bot/weather_publisher.py

And paste this code:

import rclpy
from rclpy.node import Node
from std_msgs.msg import String
import random

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

        # Create a publisher object to send messages on the 'weather' topic
        # Parameters explained:
        #   - String: the type of message we will publish (std_msgs/String)
        #   - 'weather': the name of the topic where messages are published
        #   - 10: the queue size or history depth for outgoing messages; 
        #         if messages are sent faster than the receiver can handle, 
        #         this limits how many messages are buffered before dropping
        self.publisher = self.create_publisher(String, 'weather', 10)

        # Create a timer that triggers the publish_weather method every 2 seconds
        # Parameters explained:
        #   - 2.0: interval in seconds between timer callbacks
        #   - self.publish_weather: the callback function to execute on timer
        self.timer = self.create_timer(2.0, self.publish_weather)

        # Log an informational message that WeatherBot has started broadcasting
        # Explanation of chained function:
        #   self.get_logger() returns the node's logging interface
        #   .info() sends an info-level message to the console/output
        self.get_logger().info("WeatherBot is now broadcasting on /weather")

    def publish_weather(self):
        # Generate a random integer temperature between 15 and 35 (inclusive)
        temp = random.randint(15, 35)

        # Create a new String message instance to hold our temperature data
        message = String()

        # Set the 'data' field of the message with a formatted temperature string
        message.data = f"Current temperature: {temp}ยฐC"

        # Publish the message to the 'weather' topic using the publisher
        # Explanation: The publisher sends the message so any subscribers
        # listening on 'weather' will receive this update
        self.publisher.publish(message)

        # Log the announcement using the node's logger (similar chaining as above)
        self.get_logger().info(f"๐Ÿ“ป Announced: {message.data}")

def main(args=None):
    rclpy.init(args=args)
    node = WeatherBot()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

๐Ÿง  Code Breakdown (In Plain Town-Speakโ„ข)

CodeWhat It Does
self.publisher = create_publisher(...)Installs a loudspeaker in the town square
self.timer = create_timer(...)Says something every 2 seconds
random.randint(...)Fakes a temperature sensor
String()ROS2 message that holds simple text
publisher.publish(message)Shouts on the /weather topic
rclpy.spin(node)Keeps the bot alive and running

๐Ÿ”ง Step 3: Update setup.py

Open weather_bot/setup.py, and add this to entry_points:

entry_points={
    'console_scripts': [
        'weather_publisher = weather_bot.weather_publisher:main',
    ],
},

This gives us an easy terminal command to run the bot.


๐Ÿ”จ Step 4: Build the Town Again

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

Why source again? It refreshes your terminal with the latest commands from the new build โ€” like reloading a new map in the control center.


๐Ÿงช Step 5: Run WeatherBot

Make sure your workspace is built and sourced:

cd ~/robot_town_ws
source install/setup.bash

Then run the bot using its entry point:

ros2 run weather_bot weather_publisher

You should see something like:

[INFO] [weather_bot]: WeatherBot is now broadcasting on /weather
[INFO] [weather_bot]: ๐Ÿ“ป Announced: Current temperature: 21ยฐC
[INFO] [weather_bot]: ๐Ÿ“ป Announced: Current temperature: 19ยฐC
...

๐ŸŽ‰ Congratulations!
Your bot is now shouting into the town square every few seconds, broadcasting weather reports!


๐Ÿ” Step 6: Spy on the Radio (Without a Listener)

Even without a subscriber bot, we can eavesdrop using ros2 topic echo.

Open a new WSL terminal, source the workspace again:

cd ~/robot_town_ws
source install/setup.bash

Now run:

ros2 topic echo /weather

Youโ€™ll see live messages:

data: 'Current temperature: 25ยฐC'
---
data: 'Current temperature: 30ยฐC'
---

๐Ÿง  This is like a radio technician tuning into the broadcast, just to see whatโ€™s being aired.


๐Ÿ“ก Step 7: Explore Other Topic Commands

Letโ€™s explore a few more diagnostic tools ROS2 gives us:

๐Ÿงพ List All Topics

ros2 topic list

Output:

/weather
/parameter_events
/rosout

/weather is your broadcast. The others are ROS2 internals โ€” like system logs and configs.


๐Ÿ“ฆ Check the Message Type of a Topic

ros2 topic info /weather

Output:

Type: std_msgs/msg/String
Publisher count: 1
Subscriber count: 0

You can see how many bots are publishing or listening.


๐Ÿงฐ Folder Recap: Robot Town So Far

Hereโ€™s how your Robot Town is shaping up:

robot_town_ws/
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ mayor_bot/       --> Greets citizens
    โ”œโ”€โ”€ door_bot/        --> Opens/closes the door
    โ”œโ”€โ”€ greeter_bot/     --> Friendly greeter
    โ”œโ”€โ”€ chatter_bot/     --> Chatty bot, says hi
    โ””โ”€โ”€ weather_bot/     --> Publishes weather updates

Each folder is a house for a bot, and each bot does its job as part of town life.


๐Ÿ—๏ธ Mini Project: Expand WeatherBot

Hereโ€™s your challenge! ๐Ÿงช

  • ๐Ÿ’ก Add humidity to the broadcast!

  • ๐Ÿ“ฆ Format: "Current temperature: 28ยฐC | Humidity: 56%"

  • ๐Ÿ“ป Then run ros2 topic echo /weather and see the full broadcast message!

๐ŸŒŸ Bonus: Try making the bot publish every random interval instead of a fixed 2 seconds. Use random.uniform(1.0, 5.0) for delays!


๐ŸŽ“ What Weโ€™ve Learned

ConceptTown AnalogyROS2 Term
Public radio systemTown square loudspeakerTopic
Bot speaking on radioAnnouncing infoPublisher
Message formatRadio sentencestd_msgs/msg/String
Peeking into messagesTuning into radioros2 topic echo

๐Ÿ‘‚ Coming Up Next: Listening Ears (Subscribing to Topics)

What if your bots had ears to hear the town radio? In this next article, weโ€™ll give our bots the power to listen by subscribing to ROS2 topics. Meet ListenerBot, tuning in to WeatherBotโ€™s broadcasts to stay informed.
Our fun mini project features UmbrellaBot, which springs into action and opens its umbrella whenever rain is announced. Get ready to make your bots truly reactive! โ˜”๐Ÿ‘‚


Ready to give robots ears as well as voices? ๐Ÿ‘‚๐Ÿ”Š
Letโ€™s build our first listener bot next!

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