ROS2 Explained Like a Kitchen: Nodes, Topics, Services, and Actions
ROS2 basics: nodes, topics, services, actions, and parameters — explained simply
Robotics Engineer

ROS2 basics: nodes, topics, services, actions, and parameters — explained simply
Robots run on lots of small programs working together, not one giant program doing everything. ROS2 is the system that lets those small programs find each other and talk. This post explains the five words you'll hit in your first week of ROS2 — node, topic, service, action, parameter — in plain language, with real commands you can run, using a real open-source robot as the example: smart_diffbot.
What is a node?

Think of a restaurant kitchen. There's a chef, a dishwasher, a waiter, a cashier — each person has one job, and the kitchen only works because they all do their own piece and coordinate. A node is exactly that: one small program with one job. One node reads the GPS. Another node decides which way the wheels should turn. Another node draws the map on your screen. A robot is really just a bunch of these small "staff members" running at the same time, each doing its own small piece.
Command to see every node currently running:
ros2 node list
Everything else in this post — topics, services, actions, parameters — exists for one reason: to let these separate little programs talk to each other.
Topics: the "keep announcing this forever" way

Imagine a radio station. It just keeps broadcasting, whether or not anyone's listening. Anyone with a radio can tune in. That's a topic.
Some things a robot needs to announce constantly and never stop: where its GPS thinks it is, which way it's currently driving, what its camera is currently seeing. There's no single "answer" to any of these — they just keep happening, over and over, as long as the robot is running.
Commands to try:
ros2 topic list # see every topic currently active
ros2 topic echo /cmd_vel # watch the drive-speed messages as they arrive
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.2}}" # manually publish a "drive forward" command
/cmd_vel is the topic that tells smart_diffbot's wheels how fast to spin — it's being published to constantly while the robot moves, whether anyone's watching it or not. That's the defining feature of a topic: the sender doesn't care who's listening, or if anyone is at all.
Services: the "ask once, get one answer" way

Now imagine picking up the phone and asking one specific question — "what time is it?" — and getting one specific answer back. Then the call ends. That's a service.
Use a service when you need to ask something once and get told once, and it should be fast — think milliseconds, not seconds. A good example: telling the robot's localization system "reset your position to this exact spot."
Commands to try:
ros2 service list # see every service a node offers
ros2 service call /reset_pose ... # call it once, get one reply back
The important limit to know: whatever code calls a service waits for the answer before doing anything else. That's fine for a quick question. It's a bad fit for anything that takes real time — which is exactly why the next pattern exists.
Actions: the "do this task, tell me how it's going, let me cancel it" way

Ordering food delivery is a good comparison. You place one order, but it's not instant — you get updates ("preparing," "on the way"), and you can still cancel before it arrives. That's an action.
Use an action for anything that takes real time and where you want to see progress or be able to stop it. smart_diffbot has two great real examples of this built in: docking_client, which sends the robot to its docking station, and line_follow_client, which tells it to start following a line on the ground. Both are tasks that take time, not an instant reply — exactly what actions are for.
Commands to try:
ros2 action list # see every action a node offers
ros2 run smart_diffbot_clients docking_client # send the "go dock yourself" goal
ros2 run smart_diffbot_clients line_follow_client # send the "follow the line" goal
Clicking the "2D Goal Pose" button in RViz to send the robot somewhere on the map is the same idea — it's sending an action goal to the navigation system, which is why you see the robot's progress live and can send a new goal to override it mid-drive instead of just watching it commit blindly.
Parameters: the settings knobs, not a message

Parameters aren't really about nodes talking to each other — they're about tuning a single node's settings while it's running, without restarting it. Think of it like a volume knob on a single radio, not a message being sent anywhere.
Commands to try:
ros2 param list # see every setting a node has
ros2 param get /my_node some_setting
ros2 param set /my_node some_setting 0.5
A real example: tuning a navigation setting — like how close the robot should get to an obstacle before slowing down — live, while watching it drive, instead of editing a file and restarting everything.
Best way to figure them out is:
- Constantly happening, no single answer? → Topic.
- One quick question, one quick answer? → Service.
- Takes real time, needs updates or the option to cancel? → Action.
- Changing a setting on one node, not sending a message? → Parameter.
Putting it all together: one kitchen, all five ideas
Picture that restaurant kitchen again, all at once, mid-shift.
The chef, the waiter, the dishwasher, the cashier — each one is a node. Separate people, separate jobs, all working in the same kitchen.
The kitchen has an order screen bolted to the wall, constantly updating: "Table 4 — ready," "Table 7 — ready." Nobody asked for that information specifically — it's just always broadcasting, and anyone who glances at it gets the latest update. That screen is a topic.

Now the waiter walks up to the kitchen window and asks the chef directly, "Is order 5 ready?" One question. One answer. The waiter stands there and waits for it before doing anything else. That's a service — quick, direct, one-to-one, and whoever asked is stuck waiting until they get their answer.
Then a customer orders a custom wedding cake. That's not a two-minute job — it's hours of work, and the customer wants updates along the way ("base is done," "decorating now"), plus the option to change their mind and cancel before it's finished. That's an action — a task that takes real time, reports progress as it goes, and can be called off partway through.
And behind the counter, there's a dial for how spicy the kitchen makes things by default. Nobody's sending that dial a message — it's just a setting the kitchen checks and follows, and you can turn it up or down any time without hiring a new chef or reopening the restaurant. That's a parameter.
Same kitchen, same five ideas, no code required. Once this version clicks, the ROS2 version — GPS data on a topic, a pose-reset on a service, docking_client as an action, a costmap setting as a parameter — is just the exact same shapes, wearing robot clothes.
About the robot used in these examples
smart_diffbot is a real, open-source robot project — a simulated two-wheeled ("diff drive") robot that drives around in the Gazebo simulator and navigates outdoors using GPS and the Nav2 navigation stack. It supports running more than one robot at once in the same simulation. It's built by the SMART (Smart Mechatronics And RoboTics) Research Group at Saxion University of Applied Sciences in the Netherlands, with support from a Dutch research project on autonomous agricultural navigation (RAAK-MKB). it's open for anyone to use, study, or build on.

If you want to try it yourself, Check out the code here : GitHub Repository
From there, ros2 node list, ros2 topic list, ros2 service list, and ros2 action list will all show you real, live examples of everything explained above — running on an actual robot, not a toy demo.
