Sep 5, 2026 · robotics-middleware · hardware-selection · ros-2 · team-decisions
Should You Pick Middleware Before or After Picking Hardware?
Pick hardware first and middleware second: hardware rules out software far more often than the reverse, unless your team is already fluent in one stack.
Pick hardware first and middleware second on most projects, because the board and the sensor list rule out software far more often than the reverse. Hardware constrains software more than software constrains hardware: a vendor driver or a small board removes options outright. The exception: a team already fluent in ROS 2 or already building on HORUS should let that stack narrow the parts list instead. The rest of this post is for teams making both calls in the same month and worried about which one they will regret.
You are in the third meeting about this and the whiteboard has two columns that keep swapping places. Someone has a quote for a compute module that expires on Friday. Someone else says buying anything before the software is settled is exactly how the last project ended up with a camera nobody could read. Both of them have been burned before, and both are describing something real. Meanwhile the sensor you actually want ships integration for exactly one framework, the motor controller vendor answers questions in a forum in a language nobody on the team reads, and the person who has to write the control loop has already started, in whatever they know best. What makes this hard is that the decision does not feel reversible. Boards get bought. Code gets written against whatever was there. Six months in, the thing everyone assumed was a placeholder is holding up the roof, and the argument you never finished in the third meeting comes back as a rewrite. The question is not which column wins. The question is which one closes doors faster.
Should you pick your middleware before or after you pick your hardware?
Pick the hardware first, then the middleware, unless your team is already committed to a stack that would be expensive to leave. The reason is asymmetry. Hardware removes software options in ways you cannot argue with: a depth camera that ships one driver, a motor controller whose vendor library exists in one language, a compute module whose supported operating system does not carry the framework you wanted. Software almost never removes hardware that cleanly. The worst case is that you write a driver, which is a fortnight nobody enjoys, but a fortnight rather than a year. So the order that loses least is the one where the harder constraint speaks first. There is a caveat that matters more than it sounds: hardware first does not mean hardware alone. Before anyone signs a purchase order, someone should spend an afternoon checking what software already exists for each part on the list. That afternoon is the actual decision, and everything after it is bookkeeping. Teams that skip it are choosing hardware only, and they find out about the software in month three.
What does robotics middleware actually decide for you?
Middleware decides how the separate programs inside your robot talk to each other, and what happens when one of them is slow, missing or dead. That is the whole job, and it is smaller than the argument around it. In practice a middleware also arrives carrying three other things: a way to start and stop many programs together, a way to watch what is flowing while the robot runs, and a catalogue of components other people already wrote. Those three are separable from the message passing, and confusing them is why this decision gets stuck. The catalogue is the part hardware touches. If your lidar, your arm and your depth camera all have maintained drivers inside one ecosystem, that ecosystem has decided much of your project before anyone writes a line. If they do not, the catalogue is a promise about somebody else's robot. What middleware does not decide is your control law, your safety logic, or whether the arm stops before it hits the table. Those stay yours whichever box you tick, and they are where the project is won.
What goes wrong when these two choices are made in the wrong order?
The failure has one shape: you find the constraint after the money is spent or the code is written. Hardware-only teams meet it as a driver that does not exist. The camera arrives, the vendor's integration targets a framework you are not using, and someone spends three weeks reading a protocol document instead of building the robot. Or the compute module runs a Linux that the framework's packages were never built for, and the team learns the phrase build from source the hard way. Software-only teams meet it differently and later. The stack is chosen, the architecture drawn, and then the board that fits the robot's power budget turns out to be too small to run everything that stack assumes is running. Now the choice is a bigger battery, a bigger board, or an unplanned rewrite, and all three land on somebody's schedule at once. In both directions the expensive part is not the mistake itself. The expensive part is that the discovery arrives after other decisions have been stacked on top, so undoing one thing means undoing four.
What middleware options are actually on the table once you know the hardware?
There are five families, and the hardware you have chosen usually eliminates two of them before the discussion starts. First, a full framework: ROS 2, which brings the message layer, the build system, the package catalogue and the tooling as a single decision, and which is the answer whenever your parts list is already covered by its drivers. Second, a single-machine message layer such as HORUS, an open-source middleware where Rust, Python and C++ share the same shared-memory ring buffers, so messages are not serialised between processes on that computer, which suits a robot whose sensing, control and actuation all live on one board and whose code is not all in one language. Third, a general message library of the ZeroMQ or LCM sort, where you get delivery and then define every message contract and supervision rule yourself. Fourth, a broker such as MQTT, which is right for telemetry to a dashboard and wrong for anything the robot waits on. Fifth, the platform vendor's own SDK, which is frequently not optional if you bought the robot rather than built it.
Which option fits which kind of hardware?
The option that fits is the one whose assumptions match the parts already on your bench, not the robot you might build in two years.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| ROS 2, full distribution | Teams whose parts list is covered by its drivers | Linux packaging, its build tool, its message model | Common sensors on a mobile base | The board cannot carry the whole stack |
| ROS 2, trimmed to a few packages | Teams needing one driver or one planner | Which packages you genuinely use | One ecosystem piece is the reason you are here | You end up rebuilding the rest anyway |
| HORUS | One-board robots mixing Rust, Python and C++ | One of those languages, and life outside the ROS package set | Sensing, control and actuation share a computer | You need ROS drivers or a graph across machines |
| A general message library | Teams happy defining their own contracts | Sockets, message shapes, process supervision | Few parts, stable shapes, unusual hardware | You would rebuild tools that already exist |
| A broker for telemetry | Robots reporting to a dashboard or a phone | Topics, retained messages, running a broker | The traffic is status and human commands | Something on the robot waits for it |
| The platform vendor's SDK | Teams on a bought robot or arm | Whatever model the vendor chose | The platform is the robot | You expect to change hardware later |
| A firmware-side stack | Robots with a real-time board underneath | Embedded build tooling | The tight timing lives on a microcontroller | The board can stay simple and the computer clever |
Two rows at once is a normal answer: a stack on the robot, and a broker carrying status to whoever is watching.
What should you do if the robot is already bought and sitting on the bench?
Start from the parts list and let it disqualify things, because a bought robot has already made most of this decision for you. Take every component with a cable on it, camera and lidar and motor controller and inertial sensor and gripper, and search each one by name alongside the word driver. You are looking for one of three answers: a maintained driver inside an ecosystem, a plain library in some language, or nothing but a protocol document and a forum thread from 2019. If most parts land in the first bucket and in the same ecosystem, that ecosystem wins and the meeting is over, because the value sitting there is code you never have to write. If most land in the second, you are freer than you think, since a plain library can be wrapped into any middleware in an afternoon. If several land in the third, your real project this quarter is drivers. Do this before the architecture discussion, not after: it settles arguments that otherwise run for weeks.
What if the computer on the robot has not been chosen yet?
Decide how many computers there will be first, because that single answer removes more options than any other hardware detail. One computer means every message stays on one machine, and the machinery for discovering peers across a network, for network transports, for deciding what to do when a remote peer vanishes, is being paid for and never used. Several computers means the opposite: you want a message layer built for that case, and picking a single-machine option means a migration later that somebody will have to schedule. Then size the board honestly. A small board that also has to run a perception model has less room than the spreadsheet suggests, and a framework whose baseline occupies a real share of that board will make you unhappy in month four. Whether your robot should run one computer or several is a robot question rather than a software question, and answering it first makes the software question much smaller. If the board is genuinely tight, what the standard stack costs on a small single-board computer is worth reading before anyone commits.
What if you need the robot moving before the end of the quarter?
Pick the hardware your team can get delivered and the software your team already knows, then stop optimising. A deadline changes the question from which choice is best to which choice has the fewest unknowns, and those are rarely the same answer. Unknowns compound badly: an unfamiliar board plus an unfamiliar stack plus a sensor nobody has used is three investigations running at once, and each one hides the symptoms of the others. Change one thing at a time. If the team already knows the standard stack, use it even where a leaner option would suit the robot better, because the weeks you save are real and the elegance you gave up is invisible from outside. If the team knows nothing yet, choose by the parts list and take whatever has the most existing drivers, since reading someone else's driver is faster than writing your own under time pressure. Then freeze the decision. Re-litigating it in week six costs more than the wrong choice does, and no demo has ever failed because of which middleware was underneath it.
What if nobody on the team has shipped a robot before?
Choose the boring option in both columns, because a first robot teaches you which constraints are real and you want that lesson to cost as little as possible. Boring hardware means parts many people already use, so that when something behaves strangely there is a chance somebody has written down why. Boring software means the stack with the most tutorials, even where a leaner option looks better on paper, because a first team's bottleneck is not the tool. The bottleneck is not yet knowing what normal looks like, and tutorials are how you learn that. First-time teams tend to make one specific mistake worth naming: they choose for the robot they imagine in year two, then spend year one carrying machinery for a fleet that does not exist. The second mistake is assuming the hard part will be the software. It is usually the physical world, in the form of a mount that flexes, a cable that snags, a wheel that slips on one surface and grips on another. Pick tools that let you spend your attention there.
What do you give up by fixing the software choice before the hardware?
You give up parts. That is the real cost, and it is easy to underestimate right up until one specific sensor is the reason the robot works. Commit to an ecosystem first and your shopping list quietly narrows to what that ecosystem supports well. Commit to a lean stack first and you give up the catalogue, which means the mapping, the navigation and the simulator that already agree with each other on what a message looks like. Both are genuine losses and neither is fatal alone. What makes it expensive is combining the commitment with a purchase: a team that declares software first and then buys a camera because it was cheap has managed the worst version of both orders at once. There is a second thing you give up, quieter than the first, which is the option to change your mind cheaply. Architecture written against one message model does not lift out. Why middleware decisions are so hard to reverse is worth reading before making one, because the answer is not really about the middleware.
When is ROS 2 the better choice?
ROS 2 is the better choice whenever your parts list is already covered by its drivers, and that covers a large share of real robots. A mobile base with a common lidar that must map a building and navigate it: ROS 2, without hesitation, because that stack exists today and writing it yourself is a multi-year project. An arm using an established motion planner. Any robot you want to test in a simulator that already speaks the same message types. Any robot spanning two machines by design, since HORUS is a single-machine middleware and shared memory stops at the edge of the computer. Anything a contractor, a student or a new hire will touch, because the standard stack is the one they already know how to read. And anything whose control loop runs slowly enough that how messages move is simply not the interesting question, which is more robots than the internet suggests. In all those cases the catalogue decides, the hardware agrees, and the ordering argument you were having stops mattering. Buy the parts, install the standard stack, spend your attention on the robot.
Is choosing the middleware first just premature optimisation?
No, and here is why: a middleware is not an optimisation, it is a shape. Optimisations are things you do later to code that already works. A middleware decides how many programs your robot contains, where the boundaries between them sit, which languages can talk to which, and what happens when one part dies while the motors are still turning. Every one of those appears in your first architecture drawing, and every one is expensive to change afterwards. What is genuinely premature is a different thing: choosing for load you do not have, for a fleet you have not built, for a graph across machines that will never exist. That mistake is common and it disguises itself as caution. The test that separates the two is short. Ask whether the decision changes what you write in month one. If the answer is yes, it belongs in month one. If it only changes what happens when there are more sensors, more machines or more people, defer it and go build the thing that moves.
Can you change middleware later if the hardware surprises you?
Partly, but not the way you think. The message passing itself is small, and swapping it on a robot with a handful of components is a weekend. What does not swap is everything grown around it: the message definitions your team argues in, the launch and configuration files, the recordings you collected, the tooling habits, and above all the components you adopted precisely because they were already there. Teams that have migrated report the same shape every time. The transport took days and the ecosystem took months. So the honest answer is that changing is possible, and the price is paid in the parts you did not write yourself. There is a cheap hedge that costs almost nothing at the start: keep your control law, your state machine and your safety logic in plain functions that know nothing about messaging, and let a thin layer at the edge do the publishing and subscribing. Teams who do that can move. Teams whose control law is spread through message callbacks cannot, and they discover this during the quarter they can least afford it.
How do you settle this in one meeting?
Bring three lists and let them decide instead of the loudest person in the room. First, the parts list, with a yes or no beside each item for whether a maintained driver exists and inside which ecosystem. Second, the number of computers the working robot will contain, today and a year out. Third, the languages your team will actually write in, which is a fact about the people present rather than an aspiration. Read them in that order. A parts list mostly covered by one ecosystem ends the meeting: take that ecosystem, buy the parts, move on. A parts list of plain libraries plus one computer means you are free, and the choice should turn on upkeep and on which language your team writes best. Several computers pushes you toward something built for a network whatever else is true. Where the lists disagree, weight the parts list hardest, because drivers are the only item on this page that takes a year to replace. Then write the decision down with its reason attached, so the third meeting never happens again.
A short version, by situation:
- If the robot is already bought -> let the parts list choose the software, because drivers you never have to write beat any property of a transport.
- If the board is unchosen and the robot fits on one computer -> choose the software first, because that choice narrows the board list rather than the reverse.
- If your parts are common sensors on a mobile base -> hardware first, then the standard stack, because the catalogue is the reason to be there.
- If your team already runs one stack fluently -> keep it and let it filter the shopping list, because retraining costs more than an awkward sensor.
- If nothing is decided and a demo is due this quarter -> take what your team knows in both columns and freeze both, because unknowns multiply.
When you want to compare options rather than argue about order, the HORUS Fit Framework lines them up on five things that are not numbers: ecosystem size, setup effort, team size fit, deployment target, and licence. For a team deciding hardware and software in the same month, ecosystem size and deployment target do most of the work, and licence quietly removes a vendor option or two before you start.
HORUS is open source under Apache-2.0 and the repository is linked below. Star it so it is in your list when you start building.