Welcome to RoboCity! A Beginner’s Guide to Robotics and ROS2
Table of contents
- Introduction: Building the Blueprint
- Setting Up the Foundation
- ROS2 Concept - Constructing the Blueprint
- Understanding the Workspace: The City’s Main Hub
- Introduction to Nodes - Building the Landmarks in RoboCity
- Project 1: “City Blueprint Simulation”
- Expanding the City
- Nodes as City Structures - Introducing Namespaces
- Project 2 - “Robot Registration”
- Project Summary and Flowchart: “Robot Registration”
- Wrap-Up and Conclusion
- Deepening Our City’s Connections
Introduction: Building the Blueprint
Imagine a city, vibrant and complex, where every building, road, and public park has a unique purpose, connected by a hidden network that keeps the city functioning. In robotics, ROS2 (Robot Operating System 2) is like the blueprint and infrastructure of this city—linking all parts, orchestrating tasks, and ensuring smooth communication.
In this introductory article, we’re going to start building our city’s blueprint by setting up ROS2 (using ROS2 Humble Hawksbill) and diving into its fundamentals. This will be your foundation for building robots capable of navigating, sensing, and eventually thinking for themselves.
Let’s lay the groundwork for our city’s key structures: a workspace where we organize our projects and nodes that serve as the buildings or landmarks in RoboCity. By the end of this article, you’ll be ready to launch your own mini city!
Setting Up the Foundation
The Role of Robotics
In simple terms, robotics is about creating machines that can perform tasks, often mimicking human capabilities. Whether in factories or our homes, robots rely on intricate software and hardware combinations to execute commands, interact with their environments, and even make decisions.
Where Does ROS2 Fit In?
Just as a city’s infrastructure is essential for connecting different parts, ROS2 acts as the central software framework that allows the various components of a robot to communicate. ROS2 handles everything from basic data exchange to complex commands, serving as the main bridge between hardware and software in robotics.
Analogy: Think of ROS2 as the digital city planner. It coordinates traffic (data), ensures utilities (code functions) are running smoothly, and keeps the infrastructure robust and adaptable as the city (robot system) grows.
ROS2 Concept - Constructing the Blueprint
What is ROS2, and Why Use It?
ROS2 is an upgraded, open-source robotics framework that allows you to create, test, and deploy robots in a flexible environment. The power of ROS2 lies in its modular approach, allowing different components to be built independently yet communicate effectively.
Analogy: Imagine if every building in a city could be designed by different architects but still fit perfectly into the city’s layout. ROS2 ensures each “building” or function works harmoniously, no matter who “constructed” it.
Understanding the Workspace: The City’s Main Hub
Before diving into creating nodes, let’s first understand where they’ll “live.” The ROS2 workspace is like the central hub or planning office of RoboCity, where all the construction plans (project files) are stored and organized.
What is a ROS2 Workspace?
In ROS2, the workspace is essentially a directory on your computer where all the code, nodes, and packages related to your project will be organized.
The workspace allows for easy management, reuse, and deployment of components, making it ideal for complex projects.
Creating Your ROS2 Workspace
- To start building RoboCity, we’ll set up our workspace. Let’s walk through the setup step-by-step.
Step-by-Step Guide: Setting Up Your ROS2 Workspace
Flowchart: Workspace Setup Process
Start --> Open Terminal --> Create Workspace Directory --> Navigate to Directory --> Initialize Workspace with colcon --> Workspace Ready!
Open Your Terminal
ROS2 uses the command line interface to execute commands, so start by opening your terminal. (If you’re on Windows, I recommend using the Windows Subsystem for Linux or a virtual machine with Linux installed.)Create the Workspace Directory
Think of this directory as the main planning office for our city.mkdir -p ~/robocity_ws/src
mkdir -p
is the command to create a directory.~/robocity_ws/src
specifies the workspace and source folder.
Navigate to the Workspace
cd ~/robocity_ws
Initialize the Workspace
ROS2 needs some setup files to understand this workspace. We’ll use thecolcon
tool for this, which helps build and manage the workspace.colcon build
This command will compile the workspace and generate the necessary files for ROS2.
Tip: Each time you modify files or add new nodes to the workspace, remember to run
colcon build
to compile these changes.
Introduction to Nodes - Building the Landmarks in RoboCity
Now that our workspace (planning office) is ready, it’s time to build some structures! Nodes in ROS2 are like the buildings or landmarks of RoboCity, each with a unique function. Some nodes may “talk” to others by sending data (messages), while others “listen” to instructions or commands.
What is a Node?
A node is essentially a program that performs a specific function in the robot’s system. In a robot’s city, nodes can represent:
Sensors collecting data (like security cameras in a city),
Actuators moving parts (like a traffic signal),
Controllers orchestrating tasks (like a traffic control center).
Each node operates independently, meaning you can create and test them individually without affecting other parts of the city.
Analogy: Imagine each node as a small shop, office, or utility building in RoboCity, all connected by the same infrastructure. Just like a city, you can expand or upgrade nodes as needed!
Project 1: “City Blueprint Simulation”
Objective:
Create a simple city with nodes representing different city sectors, like a park, office, and house. Each node will function independently, simulating the modular nature of ROS2.
Setting Up the Project
Flowchart: Project Setup and Execution
Setup Workspace --> Create Node Directories --> Write Node Code --> Build Workspace --> Execute Nodes
File Structure
Here’s how to organize your files in the workspace for this project:
robocity_ws/
└── src/
├── park_node/
├── office_node/
└── house_node/
Creating the Nodes
Navigate to the
src
Foldercd ~/robocity_ws/src
Create Directories for Each Node
These directories represent different sectors of the city.mkdir park_node office_node house_node
Create the Node Files
Each node will be a simple Python script that simulates activity in its sector.Navigate into each folder and create a file named
node.py
:cd park_node touch node.py
Node Code: Simulating City Sectors
Here’s an example code for park_node/
node.py
to represent the park:
# park_node/node.py
# Importing the rclpy library, which is essential for working with ROS2 in Python.
import rclpy
# Importing the Node class from rclpy.node. This Node class provides the basic framework
# for creating nodes, allowing us to use ROS2 functions like logging, publishers, and subscribers.
from rclpy.node import Node
# Define a class 'ParkNode' that inherits from 'Node'. Think of this as creating a "building blueprint"
# in our robotic city (RoboCity) where each node represents a specific landmark or function.
class ParkNode(Node):
def __init__(self):
# Initialize the node with the name 'park_node'.
# 'super().__init__('park_node')' tells ROS2 to register this node with the name 'park_node'.
# This is like giving our "park building" an official name within the city.
super().__init__('park_node')
# Use the node's logger to display a welcome message in the console.
# This acts as a virtual "sign" outside the park, letting anyone know it's open and ready.
self.get_logger().info('Welcome to the Park! Trees and benches await you.')
# Define the main function, which initializes and runs our node.
# This is like turning on the power to bring our park to life within RoboCity.
def main(args=None):
# Initialize ROS2, setting up the necessary framework for the node to operate.
rclpy.init(args=args)
# Create an instance of 'ParkNode' named 'park_node'.
# This is like constructing our park using the blueprint we created in the class definition.
park_node = ParkNode()
# Keep the node active and responsive, allowing it to continue running.
# 'rclpy.spin()' is like keeping the park open and accessible, with the node constantly active.
rclpy.spin(park_node)
# When the node is done, clean it up properly.
# Destroy the node, which is like closing and removing all resources of the park.
park_node.destroy_node()
# Shut down the ROS2 system for this node, ending all processes cleanly.
rclpy.shutdown()
# Standard Python practice to check if this script is being run directly.
# If it is, it will call the main function to execute the code.
if __name__ == '__main__':
main()
This code introduces a simple ROS2 node that simulates a park. When you run the node, it displays a message, “Welcome to the Park! Trees and benches await you.”
Explanation: Park Setup in RoboCity
Creating the Blueprint (Class Definition)
TheParkNode
class is like creating a blueprint for a new park in RoboCity. This blueprint outlines what the park will be called (park_node
) and defines the message displayed when the park opens (a greeting message). By naming the node"park_node"
, we ensure it has a unique identity within the city.Constructing the Park (Instantiating the Node in
main
)
In themain
function, we initialize ROS2 withrclpy.init()
, which is like powering up the city. We then create the actual park building by making an instance ofParkNode
, represented by the variablepark_node
. This step takes our blueprint and constructs the physical "park" in RoboCity.Opening the Park (Spinning the Node)
By callingrclpy.spin(park_node)
, we "open the park" to the city, allowing it to stay active. The node will keep running, and the message"Welcome to the Park! Trees and benches await you."
will be displayed to signal that the park is accessible.Closing the Park (Cleanup)
When the park is no longer needed, we close it by callingpark_node.destroy_node()
to free up resources. Finally,rclpy.shutdown()
completely powers down ROS2 for this node, ensuring a clean exit from RoboCity.
Step-by-Step Code Explanation
Imports
rclpy
andNode
are essential ROS2 components.rclpy
provides the ROS2 tools, whileNode
gives us a framework to define a functional ROS2 node.
Class Definition: ParkNode
The
ParkNode
class, which inherits fromNode
, is initialized with the name'park_node'
.The
get_logger().info()
function logs a message when the node starts, acting as a greeting from the park.
The main() Function
rclpy.init()
: Initializes ROS2, making it ready for nodes to be created and activated.park_node = ParkNode()
: Creates an instance of theParkNode
class, making our park "building" operational.rclpy.spin(park_node)
: Keeps the node active, so it’s ready for interactions or further processes.park_node.destroy_node()
: Cleans up the node resources when it’s no longer needed.rclpy.shutdown()
: Shuts down the ROS2 process for this node, ending its activity.
Explanation: Each node is like a different building in the city, with the
ParkNode
simulating the park’s activities. Theget_logger().info()
line outputs messages, which you’ll see in the terminal.
Expanding the City
With our RoboCity blueprint established and initial landmarks (nodes) in place, it’s time to expand! So far, each “building” or node has functioned independently, but a true city thrives on connection and communication. Now, we’ll register our nodes and establish a communication network across RoboCity, making the nodes aware of each other in a structured environment.
To do this, we’ll introduce namespaces to help organize the nodes within ROS2 and create a setup where each node has a unique identity, allowing it to communicate seamlessly within our city.
Nodes as City Structures - Introducing Namespaces
In ROS2, namespaces allow us to organize nodes so they’re easy to manage and don’t overlap in functionality. Imagine namespaces as the districts of RoboCity, where each node (building) has a unique address, making it easy to locate and interact with.
What is a Namespace?
A namespace in ROS2 works like an address prefix, grouping nodes logically so they don’t interfere with one another. For example, imagine a namespace as a specific street in our city, and each node on that street has a unique building number.
Analogy: Think of namespaces as neighborhoods in a city. Just as two houses can have the same number if they’re on different streets, two nodes can share a name as long as they’re in separate namespaces.
Project 2 - “Robot Registration”
Our goal is to expand RoboCity by assigning unique addresses to each node and simulating a simple registration process where nodes check in and register their location in the city using namespaces.
Objective
In this project, each node will “register” itself as a unique part of the city, with its own address in a specific namespace. This will introduce the concept of namespaces, allowing us to organize the nodes systematically and ensuring smooth communication.
File Structure: Organizing Nodes by Namespaces
Let’s expand our robocity_ws
workspace to group nodes in namespaces. The structure should look like this:
robocity_ws/
└── src/
├── park/
│ └── park_node.py
├── office/
│ └── office_node.py
└── house/
└── house_node.py
Each directory (e.g., park/
, office/
) represents a unique namespace for a specific sector of the city.
Flowchart: Node Creation and Registration Process
Create Workspace --> Create Namespaced Node Directories --> Add Code for Registration --> Build and Run --> Nodes Registered in Namespaces
Step 1: Creating the Namespaced Nodes
Navigate to the
src
Foldercd ~/robocity_ws/src
Create Directories Representing Namespaces
mkdir park office house
Add Node Files for Each Namespace
Each directory contains a uniquenode.py
file that registers itself when launched. Navigate into each folder and create anode.py
file as follows:cd park touch node.py
Step 2: Coding the Namespaced Nodes
Code Example: Registering the Park Node
Let’s create the park_
node.py
code. This node will register itself as part of the “park” namespace and log a custom welcome message.
# park/park_node.py
import rclpy # Import the ROS2 Python client library
from rclpy.node import Node # Import the Node class for ROS2 nodes
# Define a ParkNode class inheriting from Node
class ParkNode(Node):
def __init__(self):
# Initialize the node with the name 'park_node' in the 'park' namespace
super().__init__('park_node', namespace='park')
# Log a message indicating this node is active in the 'park' namespace
self.get_logger().info('Park Node Registered in the Park Namespace!')
# Define the main function to initialize and run the node
def main(args=None):
rclpy.init(args=args) # Initialize ROS2
park_node = ParkNode() # Create an instance of ParkNode
rclpy.spin(park_node) # Keep the node running and active
park_node.destroy_node() # Clean up the node after shutdown
rclpy.shutdown() # Shut down ROS2 for this node
# Run the main function if this script is executed directly
if __name__ == '__main__':
main()
This code creates a node that registers itself within the park namespace and logs a message confirming its location in RoboCity.
Explanation
Node Class: The
ParkNode
class inherits from theNode
class, initializing the node in the “park” namespace.Logger: When initialized, the
get_logger().info()
method outputs the message “Park Node Registered in the Park Namespace!” simulating a simple registration.In
super().__init__('park_node', namespace='park')
, we specifiednamespace='park'
. This registerspark_node
under thepark
namespace within ROS2 each time it runs.The node name is still
park_node
, but now it exists within thepark
namespace, making it accessible under/park/park_node
.
Code Example: Registering the Office Node
The code for the office node is similar, but logs a unique message for its namespace.
# office/office_node.py
# Import the ROS2 Python client library to access ROS2 functionality
import rclpy
# Import the Node class from ROS2, which provides the framework for creating a node
from rclpy.node import Node
# Define a class OfficeNode that inherits from Node, representing a unique node in the system
class OfficeNode(Node):
def __init__(self):
# Initialize the node with the name 'office_node'
super().__init__('office_node')
# Log a message to indicate that the node is active in the 'office' namespace
self.get_logger().info('Office Node Registered in the Office Namespace!')
# Define the main function to initialize and run the OfficeNode
def main(args=None):
# Initialize ROS2, setting up the framework for nodes to operate
rclpy.init(args=args)
# Create an instance of OfficeNode
office_node = OfficeNode()
# Keep the node active, allowing it to run continuously
rclpy.spin(office_node)
# Once the node is shut down, destroy the node to free resources
office_node.destroy_node()
# Shut down ROS2 for this specific node
rclpy.shutdown()
# Standard Python practice to check if this script is executed directly
# If true, it will run the main function to execute the node
if __name__ == '__main__':
main()
Step 3: Building and Running the Nodes in Namespaces
Now that our nodes are coded, let’s build and run them.
Navigate to the Workspace Root
cd ~/robocity_ws
Build the Workspace
colcon build
Source the Setup File
This allows ROS2 to recognize the workspace files.source install/setup.bash
Launch Each Node Individually with Namespaces
Launch the nodes with their specific namespaces using the
--ros-args --namespace
option:ros2 run park park_node ros2 run office office_node --ros-args --namespace office ros2 run house house_node --ros-args --namespace house
Step 4: Verifying the Namespace
To confirm the node is running in their respective namespace, you can use the following command to list active nodes:
ros2 node list
You should see the node listed as:
/park/park_node
/office/office_node
/house/house_node
Project Summary and Flowchart: “Robot Registration”
This flowchart shows the Robot Registration Process across namespaces.
Initialize Workspace --> Write Node Code in Namespaces --> Build and Source --> Launch Nodes with Namespaces --> Nodes Registered and Logging Messages
By organizing each node in a unique namespace, we’ve created a more structured city where every “building” knows its address. This setup will make it easier for nodes to interact with each other as RoboCity grows.
Wrap-Up and Conclusion
In this part, we expanded RoboCity by introducing the concept of namespaces, which act as districts within the city. By grouping each node under a specific namespace, we’ve ensured that RoboCity has a clear and organized structure, setting up each node as a unique part of the city.
As we progress, we’ll begin connecting these nodes so they can “talk” to each other, creating an interconnected city ready for more complex tasks and collaborative behaviors.
Deepening Our City’s Connections
In the next article, we’ll dive deeper into ROS2 nodes by introducing publishers and subscribers, the foundation of data exchange in ROS2. Get ready to make RoboCity a bustling, connected network!
Subscribe to my newsletter
Read articles from gayatri kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by