Introduction to ROS2 Nodes, Topics, and Services
The first time I really understood how the pieces of a robot's software talk to each other was not in a lecture hall; it was while building the Puzzlebot during my sixth semester at Tecnologico de Monterrey. I had already worked with ROS2 before that, on the @HOME service robot with RoBorregos, so the words node, topic, and service were not new to me. But it took building something smaller and more contained, with more time to sit with the confusion, for the whole system to finally click. If you are starting out in robotics and ROS2 feels like a wall of unfamiliar vocabulary, this is exactly the blog I wish someone had handed me before I opened the documentation for the first time.
The Puzzlebot, the ROS2 mobile robot from my sixth semester project referenced throughout this blog.
ROS2, short for Robot Operating System 2, is not an operating system in the traditional sense. It is a framework that gives you a common language and set of tools so that many separate programs can work together as one robot. Almost every robotics project you will build, from a line-following robot to a full-service robot with an arm and a camera, is really a collection of small programs cooperating through the exact ideas this blog covers: nodes, topics, and services.
The ROS2 Graph: A Network of Independent Programs
Picture a robot that has to see the world through a camera, decide where to move, and drive its wheels. You could write all of that as one giant program, but that quickly becomes a nightmare to maintain, test, and debug. ROS2 solves this by encouraging you to split the work into small, independent programs, each responsible for one job, and then giving those programs a reliable way to exchange information. The entire network of these programs and their connections is called the ROS2 graph.
Thinking of your robot as a graph instead of a single script changes how you design software. Instead of asking, "What does my one program need to do?" you start asking, "What are the separate jobs in this robot, and how do they need to share information?" That second question is exactly what nodes, topics, and services exist to answer.

What Exactly Is a Node?
A node is a single process that performs one specific, modular job inside the larger robot system. In a typical mobile robot, you might have a vision node that processes camera frames, a movement node that converts velocity commands into motor signals, and a line detection node that looks specifically for a line on the floor and reports where it is. Each of these is its own node, running as its own process, and each one only needs to know how to do its own job well.
A service works as a request and response exchange between a client node and a server node.
This separation is not just neat organization; it is what makes robotics software manageable at scale. If your vision node crashes because of a bad camera frame, your movement node can keep running. If you want to swap your line detection algorithm for a better one, you only touch that one node without risking the rest of the system. When something behaves unexpectedly, you already know which node to look at, instead of scrolling through thousands of lines in a single file.
A single executable can technically contain more than one node, but the mental model that helps most beginners is simpler: one node, one job. As your project grows, you will naturally end up with a handful of nodes, each named after what it does, like vision_node, motor_driver_node, or line_follower_node.
rqt_graph output from a real ROS2 project showing the vision and line-following nodes connected through topics.
Topics: Continuous Streams of Data
Nodes are only useful once they can share information, and the most common way they do that in ROS2 is through topics. A topic is a named channel that carries a continuous stream of messages. A node that has data to share, like a camera frame or a distance reading, publishes that data to a topic. Any node that cares about that data can subscribe to the same topic and receive every message as it arrives.
The key idea here is that publishers and subscribers do not know about each other directly. A vision node publishing to a topic called /sign/command has no idea which nodes, if any, are listening. This is what is called a publish and subscribe pattern, and it is what lets you add or remove nodes from a running system without rewriting the ones that are already there.
A subscriber only receives messages when it listens to the exact topic name a publisher is using, as shown by the mismatch above and the fix below.
Message Types and Why Python Makes Them Flexible
Every topic carries one specific message type, which defines the exact structure of the data being sent. ROS2 comes with many standard message types out of the box, things like String, Bool, and Image, and you can also define your own custom messages when a project needs a very specific structure, like a message that carries both a detected object's label and its bounding box coordinates in a single package.
The rqt Topic Monitor listing active topics, their message types, and publish rate for a running ROS2 system.
When you write your nodes in Python using rclpy, working with these message types becomes very approachable. Python's dynamic typing and simple class-based message objects mean you spend your time thinking about your robot's logic instead of fighting with rigid data structures. This is one of the reasons Python has become such a popular first language for learning ROS2, even though C++ is also fully supported and often used for performance-critical nodes.
One Topic, Many Listeners
Topics are not limited to a single publisher and a single subscriber. It is completely normal and often necessary for multiple nodes to publish to the same topic and for multiple nodes to subscribe to it at the same time. Imagine a topic called /robot/state that reports whether the robot is idle, moving, or stopped. A safety node, a logging node, and a user interface node could all subscribe to that same topic independently, each doing something different with the same piece of information.
The /line_follower node subscribes to several line-related topics at once, showing how one topic can have multiple listeners.
Services: When You Need a Direct Answer, Not a Stream
Topics are perfect for continuous data, but sometimes a node just needs one clear answer, not a stream. That is what services are for. A service works as a request and response pair: a client node sends a request, and a server node processes it and sends back a single response.
Example of services, based on a system of grasping for a robot.
A good example is asking a robot arm whether a specific pose is reachable. You do not want a stream of yes-or-no answers; you want to ask once and get a clear reply before moving on. That synchronous, short-lived exchange is what separates a service from a topic. Services show up less often in day-to-day robotics code, but when you need a one-time calculation or a configuration change, they fit better than forcing a topic to do the job.
Putting It Together: A Simple Robot Architecture
Now picture all three ideas working together inside one small robot. A vision node publishes detected traffic signs to a topic called /sign/command. A separate line detection node publishes the position of the line it sees to /line/position. A movement node subscribes to both of those topics, combines the information, and decides how fast and in which direction the wheels should turn. If that movement node also exposes a service to reset its internal state on demand, a supervisor node could call that service once during startup without needing a continuous topic just for that one-time action.
A more complete node and service architecture from a real robot, with perception, manipulation, and navigation nodes communicating through topics, services, and actions.
None of these nodes need to know how the others are implemented internally. The vision node does not care whether the movement node uses a simple if statement or a full state machine to decide what to do with a stop sign. All it needs to guarantee is that it publishes the right message type on the right topic name at a reasonable rate. That contract, the topic name plus the message type, is the entire agreement between nodes, and it is what makes ROS2 systems so modular.
Visualizing the Graph with rqt_graph
Reading about nodes and topics is one thing, seeing them is another, and ROS2 gives you a tool for exactly that called rqt_graph. Running it while your nodes are active draws a live diagram of every node in your system and every topic connecting them, with arrows showing which node publishes and which one subscribes.
rqt_graph output from a real ROS2 project, showing every node and the topics connecting them.
This tool becomes invaluable the moment your project grows past three or four nodes. It is often the fastest way to catch a simple but painful mistake, like a subscriber listening on /sign_command while the publisher is actually sending to /sign/command. Get comfortable running rqt_graph early; it will save you real debugging time later.
A Quick Note on Actions
There is a fourth interface type in ROS2 worth knowing about, called actions, used for long-running tasks that need feedback along the way, like navigating to a distant point on a map. Actions combine the request and response feel of a service with ongoing progress updates similar to a topic. You do not need to master actions to get comfortable with nodes, topics, and services, but knowing the name now will save you a moment of confusion the first time you see it mentioned in someone else's code.
Where to Go From Here
Understanding nodes, topics, and services is the foundation on which everything else in ROS2 is built. Every tutorial you read next, every package you install, and every line of someone else’s robot code you try to understand will assume you already have this mental model in place.
The natural next step is my blog on how to write your first ROS2 publisher and subscriber node, where we move from theory into actual code. For that one, you will need ROS2 installed and a code editor like VSCode, since we will be writing and running Python nodes directly. If you are not on Linux yet, check out Part 3 of my Running ROS on Docker series first to get a working ROS2 environment set up before diving in.
Hector Eduardo Tovar Mendoza, RoBorregos, Tecnologico de Monterrey

