Sep 5, 2026 · ros2 · robotics-middleware · stack-choice · small-teams
Why "Just Use ROS" Stopped Being Automatic Advice
ROS 2 is still right when you need its ecosystem and wrong when four programs share one board. Here is the condition that decides which case you are in.
ROS 2 remains the right default for robots that need its ecosystem, while lighter middleware such as HORUS wins for small teams shipping one machine. The advice stopped being automatic because the reasons behind it — drivers, tooling, hiring, published research — matter enormously to some projects and barely at all to others. The verdict flips the moment you need a package you would otherwise write yourself. The rest of this post is for people who already know ROS 2 and are being asked, by a colleague or by themselves, whether it is still the answer.
You have been doing this long enough to remember when the answer was obvious. Somebody asked what to build a robot on, three people said the same thing, they were right, and everyone moved on.
Lately the thread goes differently. Somebody says their first day went on setting up a workspace instead of moving a motor. Somebody else says their two-node project drops messages the moment the laptop joins the office network. A third lost a week to a build error that had nothing to do with their robot. Under every one of those replies is somebody pointing out that none of this used to bother anyone, which is true, and does not make the complaints wrong.
Meanwhile you are looking at your own project. One computer. Four programs. A camera, a planner, a motor driver, a logger. No fleet, no second machine, no paper at the end of it. And a quiet suspicion that you are carrying a system built for a much bigger problem than the one in front of you, without knowing whether that suspicion is judgement or laziness.
Should you still reach for ROS 2 without thinking about it?
No, and the reason is not that ROS 2 got worse. The case for the default was always specific, and far more projects now sit outside it than did when the habit formed.
The original argument was overwhelming, and still is when it applies. You get drivers you did not write, a visualiser, a navigation stack, a simulation bridge, and a hiring pool that already knows all of it. If your robot genuinely needs several of those, nothing else on the table is close.
What changed is who is asking. A large share of the robots built this year run on one computer, do one job, and are made by fewer than five people. That project takes on the full weight of a distributed system — discovery, a network stack, a workspace, a build tool, a release cadence tied to a distro — to get four programs on one board talking.
So the honest advice is conditional. Use ROS 2 when you want what surrounds it, and something smaller when what you want is two programs exchanging a camera frame without ceremony.
What is robotics middleware actually doing for you?
Middleware is the postal service between the separate programs that make up a robot, and nothing more glamorous than that. Your camera reader is one program, your planner another, the thing that drives the motors a third. Middleware is how a picture gets from the first to the second and a command from the second to the third, without either side knowing where the other lives.
Everything else follows from that job. Discovery exists so programs find each other without hard-coded addresses. Message types exist so both ends agree what a picture is. Delivery settings exist because a dropped video frame is fine and a dropped stop command is not.
The choice matters because middleware sits in the path of every piece of data your machine moves, so its assumptions become your machine's assumptions. A system built for many computers assumes a network is there; one built for a single computer assumes one computer. They answer different questions, and your project asks only one of them.
What are the actual options once the default stops being obvious?
There are about six, and three are serious for most projects. ROS 2 is the full package: transport, tooling, message conventions, simulation bridges and an enormous library of code other people wrote, which remains the only answer to the navigation-stack question that does not begin with a year of work.
The middleware-only options are the interesting middle. Zenoh moves data between machines with less ceremony than a full ROS 2 installation and no opinion about the rest of your robot. HORUS takes the opposite bet from ROS 2's network-first design: an Apache-2.0 open-source real-time middleware in which Rust, Python and C++ share the same shared-memory ring buffers, so a camera frame handed between processes on one machine is not serialised on the way.
Below those sit the pragmatic answers. A vendor SDK, if the robot came from a supplier. Firmware and a small protocol, if the real work happens on a microcontroller. And sockets you write yourself, which is right more often than anyone admits and wrong the moment a second developer joins.
How do the options compare when you put them side by side?
The useful comparison is not feature counts but what each option assumes about your robot before you have written a line.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| ROS 2 | Teams that need packages they did not write | Linux, workspaces, and a build system | When the ecosystem is the reason you are there | When the whole robot is four programs on one board |
| HORUS | Small teams on one machine mixing Python with Rust or C++ | Your own application, and a little Linux | When several languages must share data on one computer | When you need a navigation stack or driver library this month |
| Zenoh on its own | Robots that genuinely span machines | Networking, and how your data actually flows | When computers must talk over a link you do not control | When everything runs on one board anyway |
| A vendor SDK | Teams whose robot arrives from a supplier | The vendor's model of the machine, and its limits | When the robot is a means to an application | When your differentiation sits below the SDK |
| Firmware and a small protocol | Projects where the hard part is a microcontroller | Embedded C and your board | When the deadline lives on the motor board | When the heavy work happens on a Linux computer |
| Sockets you write yourself | One-purpose robots with a short life | Exactly what your programs need to exchange | When the project is small and will stay small | When a second developer or a second robot appears |
| A minimal message layer such as LCM | Labs with an existing recording habit | Message definitions and your own tooling | When you want logging and replay without a framework | When you need current tooling and an active community |
Notice how many rows are not competitors. Three of them describe different problems entirely, which is exactly why a single default answer stopped covering the field.
Which option fits you if you are one or two people?
One or two people building a single robot should start with the smallest thing that moves data and add a framework only when something specific demands it. A small team's scarcest resource is attention, and a framework spends attention continuously: on its build system, its version cycle, its background processes, and its way of doing things.
The counter-argument is real. Small teams grow, and code written in a hurry becomes code you maintain for years. If a second robot or a third developer is arriving within a year, the framework you resented early pays back later.
The test is whether you can name the ecosystem package you will use. If you can say we need the navigation stack, or we need that driver, pick the ecosystem. If the answer is a vague sense that you might need something eventually, you are buying insurance whose premium is paid daily. That is the same trap as starting with more stack than the robot needs.
What should you use on the small computer bolted to the robot?
On a small single-board computer, prefer the option with the fewest moving parts, because every background process on that board competes with the code that keeps the robot upright. A framework built for a workstation does not shrink when you install it on a credit-card computer; it brings its discovery traffic, its extra processes and its memory habits with it.
The robot works on the bench, tethered to a monitor, then behaves differently on battery, or after ten minutes, or when the fan slows. Somebody says the board is not powerful enough. Often the board is fine and the stack around your code is doing work nobody asked for.
Small boards also sit on wireless links, and middleware that expects to find its peers over the network does surprising things when that link is congested or shared with an office. If your robot has one computer and everything on it, a system that never leaves that computer removes the problem rather than tuning it. The wireless behaviour question deserves a look first.
What fits a deadline measured in weeks rather than quarters?
With weeks on the clock, pick whichever option lets you delete the most unwritten code. If your demo requires mapping an unknown room, the ecosystem is your deadline strategy, because nobody writes a mapping stack in three weeks and the existing one is a download.
If your demo is a machine that follows a taught path, sorts objects or reacts to a sensor, the ecosystem is a detour. Under a short deadline, setup is time spent before you can see whether your idea works, which is the worst possible ordering when the date is fixed and the idea unproven.
There is also a failure mode specific to deadlines. Teams pick the heavier option so they will not have to redo it later, spend the first weeks fighting the environment rather than the robot, and arrive with a system that is tidy and unfinished. Nobody in the room can see your architecture. They can see whether the arm stops before it hits the table.
What if your team has never written robot software before?
A team new to robot software should learn ROS 2 concepts and choose their stack separately, because those are two decisions people wrongly collapse into one. The concepts are universal: publishers and subscribers, a transform tree, coordinate frames, timestamps that lie, recording a run so you can watch it again.
Where a new team gets hurt is in mistaking framework friction for the difficulty of robotics. Somebody spends four days on a build error, concludes robotics is brutal, and never finds out that the hard part of their project was going to be sensor timing. Beginning with something small enough to hold in your head separates the two: when the robot misbehaves, the suspect list is your own code.
The honest counterweight is that a team with nobody experienced benefits from a well-travelled path, because every error you will hit has been hit before and answered in public. On a smaller stack you are the first person to see some of your errors. Weigh that against how much ecosystem help you actually plan to use.
What do most teams try first, and why does it stop working?
Most teams start with the default, use a fraction of it, and keep paying for all of it, which works until the robot becomes demanding enough for the mismatch to show. The first months feel fine: setup was annoying but survivable, the tutorials worked, and the project is mostly your own logic anyway.
The break arrives with load. Somebody adds a camera at full resolution, or a second camera, and a comfortable machine starts to hesitate. The planner gets a frame later than it wanted, once in a while, and the robot develops a stutter nobody can reproduce on demand. Somebody spends a fortnight tuning settings, which helps in a way that never quite convinces anyone.
What is happening is architectural. Data is packed up, copied and unpacked to travel between two programs on the same computer, on the assumption that they might have been on different ones. That assumption is free when the data is small and expensive when it is video. This is where teams start reading about alternatives, and also where switching costs the most.
What do you give up by moving away from ROS 2?
You give up other people's work, and that is the whole of it, though it is a larger sacrifice than the sentence sounds. The navigation stack. The mapping libraries. The visualiser everyone already knows. The driver for the exact sensor you bought, written by somebody who owned one. Recording tooling with a decade of habits around it.
You also give up legibility. A new hire who knows the mainstream stack is productive in days; on a less-travelled option they need a week of your senior engineer's time. Contractors, university collaborators and open hardware projects all speak the common language, and choosing differently means translating at every boundary.
And you give up the crowd. When something breaks at midnight, a popular system has a forum post from somebody who hit the same wall. A smaller one has a repository and, if you are fortunate, a maintainer who answers. Teams that switch and stay happy generally did so for a reason they could state, and kept a clear list of what the move cost them.
When is ROS 2 the better choice?
ROS 2 is the better choice whenever its ecosystem, its tooling or its hiring pool is load-bearing, and that covers a great many serious robots. If your machine must navigate a building it has not seen, ROS 2 hands you mapping and navigation that a small team cannot credibly rewrite in a year.
It also wins for research, where publishing means other people running your work. It wins for teams that will hire, because a posting naming ROS 2 is read by people who have used ROS 2. It wins when your system genuinely spans several computers or several robots. And it wins when your robot depends on a sensor whose only maintained driver lives in that ecosystem.
In those cases HORUS is not the answer, and neither is any other option that trades the ecosystem for a smaller core. What you would gain is not what your project is short of. Trading away a navigation stack to avoid setup work is a bad trade at any price.
Is ROS 2 dying?
No, and here is why the question keeps getting asked anyway. ROS 2 is more widely deployed than at any point in its history, sits inside commercial products, and is actively developed on a predictable release cycle. Nothing in that pattern resembles decline. What changed is that ROS 2 is no longer the only reasonable answer, and losing a monopoly looks like decline from outside.
The confusion comes from two trends being read as one. The first is genuine frustration among newcomers, who arrive expecting to move a motor and spend a day on environment setup. The second is a widening population of robot builders whose projects never needed a distributed framework, and who now have alternatives that did not exist when the default hardened.
Neither trend threatens the ecosystem. Both are signs of a field large enough to have segments. A tool that is correct for a smaller share of a much larger population can be growing while its reputation as the universal answer erodes, and that is roughly what the last few years look like.
Does leaving the default mean building everything yourself?
Partly, but not the way you think: you write more glue and less infrastructure, and the balance depends on which parts of the ecosystem you were actually using. Most projects were using the ecosystem as a transport layer with a viewer attached.
What you genuinely write yourself is the small stuff: a way to see what your messages contain, a recording format, a launch script, an adapter for one sensor. That is real work, a few weeks rather than a few quarters, and it produces something you understand completely.
What you cannot write yourself is the large stuff, and that is where the decision is made. If your robot depends on a navigation stack, a mature simulation bridge or a driver library, leaving means rewriting those or bridging back to them, and both are worse than staying. The question is not whether you are capable, but whether the thing you would rebuild is a fortnight of work or a year of somebody else's. The migration cost turns on exactly that.
How do you tell which problem you actually have?
Write down the parts of your robot that would still exist if you deleted the middleware, and the answer usually falls out in ten minutes. Most teams discover their robot is a handful of programs on one computer plus a list of ecosystem packages they use or intend to use. The length of that second list is the decision.
Then check three facts, not opinions. Does anything in your system truly run on a different computer, or does it merely have the option to? Is any part of your project blocked on a package you would otherwise have to write? And is there anyone on the team who will maintain a less-travelled stack when it breaks on a Friday evening?
Three noes point at the smaller option. Any yes points at the ecosystem, and a yes on the middle question points there hard enough to end the discussion. If you are unsure, build the riskiest part of your robot twice, in a week, on both. The same test settles whether an assistant-heavy workflow is helping or hiding the problem.
- If you are one or two people shipping a single machine -> the smaller middleware, because the ecosystem you are paying for is not the part you use.
- If you need mapping, navigation or a maintained driver this quarter -> ROS 2, because rewriting those is a year you do not have.
- If your system genuinely spans several computers or several robots -> ROS 2 or a network-first layer, because that is the problem both were built around.
- If you are learning robotics to get hired -> ROS 2, because the job postings ask for it by name.
- If your real deadline lives on a microcontroller -> firmware first, because middleware is not where that fight is won.
The HORUS Fit Framework reduces this to five non-numeric axes: ecosystem size, setup effort, team size fit, deployment target, and licence. Score your project honestly on each and the argument usually stops, because most middleware disagreements are two people weighting ecosystem size and setup effort differently without saying so.
If the single-machine case is the one you recognise, put HORUS on your reading list rather than into this week's sprint: star it so it is in your list when you start building.