HORUS/blog

Sep 5, 2026 · ros2 · mobile-robots · middleware · robot-navigation

Do You Need ROS 2 for a Mobile Robot That Just Drives Around?

No. A mobile robot that follows a route and reacts to obstacles runs fine without ROS 2, and ROS 2 wins the moment the robot must find its own way.

No, a mobile robot that only drives, avoids obstacles and answers a joystick does not need ROS 2, HORUS, or any middleware at all. Driving is a short loop, read a sensor, pick a speed, send it to the motors, and one program does that with nothing between the pieces to configure. The verdict flips the moment the robot has to know where it is on a map. The rest of this post is for someone with a working chassis, a lidar in a drawer, and a nagging sense that they are installing more than they need.

The job description was one sentence. Drive down the aisle, do not hit the shelving, stop when somebody steps in front, come back when the battery gets low. You could explain the whole behaviour to a colleague in fifteen seconds, and you have written harder things than that before lunch.

Then you asked what to build it on, the answer came back as ROS 2, and you started there. Now there is a workspace, a build tool, a launch file, a parameter file, a coordinate frame you are not certain you defined correctly, and a folder of packages you did not write. The wheels have turned twice, both times on the bench with the robot up on blocks.

What bothers you is not that any of it is bad. It is that you cannot point at the part of it that is doing your one sentence. Every tutorial assumes the robot is about to build a map of an unfamiliar building and plan a path across it, and yours is about to drive down an aisle it has driven a thousand times. You are starting to suspect you are paying for a problem you do not have, and you would like somebody to say that out loud.

Does a robot that only drives need ROS 2?

No, a robot whose entire job is driving does not need ROS 2, and the trouble people hit on such robots is nearly always in the setup rather than in the driving. Be precise about what "just drives around" means, because the phrase covers two different machines wearing the same chassis.

The first takes a route or a joystick command and reacts to whatever is directly ahead: follow the tape, keep the wall on the right, stop before the pallet. That robot has a short loop and no memory of the building it is in. Everything it needs to know arrives from a sensor in the last fraction of a second.

The second is given a destination and works out the way there alone. That robot holds a map, decides where on the map it currently sits, and replans when a forklift is parked across the corridor.

The first robot needs no framework. The second needs most of what ROS 2 offers. The most useful thing you can do this week is decide out loud which of the two you are actually building, because every later argument follows from that.

What does middleware actually do on a driving robot?

Middleware is the wiring between separate programs on one robot: the thing that carries a message from the program reading the lidar to the program turning the wheels. Without middleware, those two live in one file and talk by passing a variable. With middleware, they are separate programs that find each other by name, and each can be restarted, replaced or written in a different language from the others.

That buys real things. A camera process that dies does not take the motors down with it. A colleague rewrites the obstacle logic without touching your motor driver. You record everything that crossed the wiring during a bad run and replay it at your desk on Monday instead of chasing the robot around the building with a laptop.

It costs bookkeeping. Every program has to be declared, named, built and started in the right order, and the connections between them stop being visible in code and start living in configuration files. On a robot small enough to fit in one file, you pay that bookkeeping and collect none of the benefits, because there is only one program and it never crashes independently of itself.

What can you actually run a driving robot on?

There are six honest options, and for a robot that only drives, two of them cover most cases. The first is one program on one Linux board: a loop in Python or C++ that reads the sensors, picks a speed and writes to the motor driver. The second is the drive base manufacturer's own SDK, which hands you a velocity command and wheel odometry on the first afternoon.

Underneath both sits microcontroller firmware, with no operating system at all, which is the right answer when the robot only ever reacts to what its sensors see.

Above them sit the message-passing systems. ROS 2 is the professional default and brings mapping, navigation, visualisation, recording, simulators and vendor-written drivers, in exchange for a build system and a vocabulary. HORUS is an open-source real-time robotics middleware for Rust, Python and C++ in which all three share the same shared-memory ring buffers, so messages between processes on one machine are never serialised; the project is Apache-2.0, validated in simulation, and suited to a robot whose programs already crowd each other rather than one that has not driven yet. The sixth is a plain broker such as MQTT, right for telling a dashboard where the robot is and wrong for anything inside the loop that steers it.

How do the options compare side by side?

Read the last column first and cross out every row that describes your robot. For a machine that only drives, this table usually collapses to two candidates inside a minute.

OptionWho it is forWhat it assumes you knowWhen to pick itWhen not to
One program on one boardRobots with one job and one authorPython or C++, and how to read a sensorThe robot follows a route and reacts to what is aheadRuns must be recorded and replayed later
The drive base vendor SDKTeams who bought a ready-made baseThe vendor examples and its command formatYou want the robot moving this weekYou expect to change the base later
Microcontroller firmwareRobots that react and never planC on a small board, and wiringThere is no camera and no map involvedA laptop or a camera sits inside the loop
ROS 2Robots that must find their own way somewhereLinux, packages, launch files, a build toolThe robot is given a destination, not a routeThe route never changes and nobody wants replay
HORUSRobots where programs on one board crowd each otherPython, Rust or C++, and how your programs splitThe loop stutters once vision runs beside controlNothing on the robot has stuttered yet
A plain broker such as MQTTFleets reporting to a dashboardTopics, a broker, and your networkStatus has to leave the robotThe messages steer the wheels

Two rows deserve a warning. The vendor SDK is the fastest start and the stickiest choice, because the driving code you write against it assumes that base forever. And the last row tempts people who see messaging and think any messaging will do; a broker on the network is a fine way to report a battery level and a poor way to close a loop around a motor.

What does it look like when this decision goes wrong?

A wrong choice here shows up in one of three ways, and each has a different cure. The first is a robot that never leaves the bench. Weeks disappear into an operating system version, a build error nobody on the internet has in quite your form, and a tutorial written against a release you cannot install. Nothing broke. The project simply stopped moving, and the chassis collects dust beside the desk.

The second is a robot that drives beautifully in the lab and behaves strangely on site. Programs that found one another instantly on your bench take an age to notice each other on the building's network, or discover a second robot they were never meant to talk to. That is a network shape problem more than a code problem, and it is common enough to have a recognisable set of symptoms.

The third is a robot that worked fine until a camera was added, and now the wheels answer late and the machine weaves where it used to hold a line. Nothing has crashed and every log looks healthy. That third pattern is the only one of the three that is genuinely about how messages move between programs.

Are you a hobbyist, a researcher, or shipping a product?

Skip ROS 2 as a hobbyist until the robot needs a map, use ROS 2 as a researcher regardless, and decide as a product team by how long the robot must stay supported. For a hobby build, the only measure that matters is whether the robot did something new this weekend, and anything that costs three weekends before the wheels turn is working against you.

In a lab, the calculation is different because your output is not the robot. Your collaborators, your supervisor's existing code, the dataset format your field expects and the reviewers of your paper all speak the same vocabulary, and stepping outside it costs you people rather than time.

For a product, ask who fixes this robot in four years when you have moved on. A custom stack is cheaper this quarter and more expensive every quarter after, because every new hire has to learn a system that exists nowhere else and has no documentation but yours. That said, a fleet doing one narrow job is where a small custom stack stays small, and plenty of shipping machines run on a base SDK and a state machine.

Is the robot driven by a microcontroller or a Linux board?

If a microcontroller turns the wheels, ROS 2 is not running there, and the question only applies to whatever Linux board sits above it. That distinction removes most of the argument for a lot of robots. A small board with no operating system runs a loop and some interrupts, which is precisely what a motor controller wants, and no framework is going to live inside it.

The arrangement most mobile robots converge on is two-part: a Linux board doing the thinking and a microcontroller doing the tight wheel loop, joined by a serial link or a CAN bus. That split is worth understanding early, because it takes almost all of the timing pressure off the Linux side. The board upstairs can be late occasionally without the robot lurching, since the motor loop downstairs keeps running.

If your robot is a single Linux board doing everything down to the motor signals, you have signed up for timing trouble later, whatever framework you pick, and the trade-offs between the common boards are worth reading before you buy the next one.

How soon does the robot have to be driving?

If the robot must drive this week, do not install a framework this week. Spend the week on the base SDK or one script, and end it with a machine that moves down an aisle and stops before it touches anything. A robot that moves changes every conversation you have about the project afterwards, including the conversation about what to build it on.

With a month of working days you can learn ROS 2 properly, and that is a reasonable way to spend a month. Just be honest about what the month buys: it buys ROS 2, not a finished robot, and the robot arrives after that.

With a quarter, build the simple version first and rebuild it with structure once you know what the robot does in the building. The second build is always better, because the first one told you requirements nobody could have written down in advance.

The outcome to avoid is half-learning a framework, which costs the whole setup and delivers almost none of the packages.

How much ROS 2 does your team already know?

If your team already knows ROS 2, use ROS 2, even for a robot that only drives. Existing knowledge is the cheapest asset on the project, and the cost of any framework is almost entirely in the first climb. A team that has already paid that cost gets the recording tools, the visualiser and the vendor drivers for nothing, and those tools are pleasant to have even on a simple machine.

If nobody has used it and the robot follows a fixed route, you are proposing to buy the climb and use none of the view. That is a bad trade, and it is the single most common way a simple robot turns into a six-month project.

There is a trap in the middle worth naming. Knowing ROS 2 and knowing autonomous navigation are two different climbs. Plenty of engineers are comfortable with nodes, topics and launch files, and have never tuned a costmap or debugged a localisation estimate that drifts down a featureless corridor. If your plan depends on navigation, budget for the second climb separately, because it is the larger of the two.

What do you give up by skipping ROS 2 here?

You give up maps, navigation, visualisation, replay, simulation and other people's drivers, which is a large pile even for a robot that only drives. The visualiser alone is worth naming: a window on your laptop showing what the robot believes about the world is the best debugging tool in mobile robotics, and nobody appreciates that until they have used one and lost it.

You give up recording a bad run and replaying it at your desk, which means every intermittent fault has to be reproduced live, in the building, with the robot moving and you walking behind it.

You give up the lidar driver written by somebody who read the protocol document so that you never have to, and the simulator that lets you keep working while the battery charges.

You also give up community. An error message pasted into a search box returns results when it comes from a widely used stack, and returns nothing when it comes from yours. Skip ROS 2 because your robot genuinely does not need those things, which is often true, and not because the installation annoyed you on a Tuesday.

When is ROS 2 the better choice?

ROS 2 is the better choice the moment the robot is given a destination rather than a route, and HORUS is not the answer for a robot that has never once run late. If the machine must build or hold a map, work out where it is, and plan a path around whatever appeared in the corridor today, use the packages that exist. Rewriting that is not a project, it is a research programme with a delivery date attached.

Use ROS 2 when your lidar or depth camera ships with a driver and that driver is written for ROS 2, which describes most sensors worth buying. Use it when more than two or three people will touch the code, because the conventions are what stop a team writing four incompatible ways to describe a wheel speed.

Use it when a failure in the field must be replayed at a desk, when a customer or a grant expects it, and when you need to test in simulation before the hardware exists. And use it when your hiring plan assumes candidates who already know the vocabulary. For a mobile robot that must navigate a building on its own, ROS 2 is the right answer and picking anything else needs a very specific reason.

Is ROS 2 too heavy for a robot that only drives?

No, and here is why: the weight is not in the board, it is in the number of moving parts you have to hold in your head and start in the right order. An ordinary Linux board drives a robot under ROS 2 without complaining, and the machine steering down an aisle is not what makes anyone feel the system is heavy.

What people experience as heaviness is operational surface. Things must launch in an order. Configuration lives away from the code that uses it. Discovery behaves one way on your bench and another way on the customer's network. Each of those is a place where a robot that worked yesterday does not work today, and none of them has anything to do with how powerful the computer is.

That distinction matters because it decides the fix. If the board were the problem, a bigger board would help. Since the number of parts is the problem, only a smaller design helps. There is a later stage where the cost does become physical, and it looks quite different when it arrives: a robot that was fine last month and now stutters whenever vision is busy.

Will you have to start over when the robot needs a map?

Partly, but not the way you think: the plumbing gets rewritten and the hard-won knowledge does not. What you throw away is how programs start, how messages are named, and where configuration lives. That is real work, and it is days rather than months for a robot of this size.

What survives is everything that actually took the time. The motor calibration. The discovery that the left wheel slips on the loading ramp. The blind spot the distance sensor has when a wall is close. The safety stop that has to fire before a person can reach the machine. Those facts cost you a season to learn and they move into a new structure in an afternoon, because they are knowledge about your robot rather than code about a framework.

You can make that port cheaper for almost nothing today. Keep sensing, deciding and acting in separate files even inside one program, and give your data proper names rather than passing raw tuples around. Those habits are free now and they are exactly the shape any middleware expects later, whichever one you end up on. If you want the smaller-robot version of this argument, the options below a full stack are worth a look.

How do you decide what to put on the robot this month?

Decide by writing down the single sentence the robot must satisfy at the end of the month, then installing only what that sentence requires. "The robot drives to the end of the aisle and stops before the shelving" needs a loop and a distance sensor. "The robot patrols a fixed loop all shift and reports its battery to a dashboard" needs that loop plus a broker, and nothing more.

"The robot is told to go to bay fourteen and finds its own way there" needs ROS 2, starting today, and the sooner you admit that the sooner the real work begins.

Then keep one habit through the project. At the end of each week, check whether you can still explain every process running on the robot and why it is there. The first week the answer is no, you have installed machinery you are not using, and that machinery will fail on a Friday in a building you cannot get back into.

Here is the whole decision in six lines.

The HORUS Fit Framework reduces that to five axes you can score any option against: ecosystem size, setup effort, team size fit, deployment target, and licence. For a robot that only drives, setup effort usually decides the first version, and deployment target, meaning one board or many and whose network the robot lives on, is the axis that overrules it later.

When your robot does grow past driving, you want that option already on the shelf rather than researched under pressure the week it starts stuttering. Put HORUS on the shelf now: star it so it is in your list when you start building.

Found this useful? Share it:Discuss on HNShare on X