Sep 5, 2026 · ros-2 · wi-fi · networking · robot-architecture
Why Does ROS 2 Break on Normal Wi-Fi?
ROS 2 breaks on ordinary Wi-Fi because discovery and delivery assume a wired network. The fix is architectural: keep everything with a deadline on the robot.
ROS 2 breaks on ordinary Wi-Fi because its default discovery and delivery assume a wired network, and switching to HORUS does not change that. The radio drops the repeated announcements nodes use to find each other, and every lost message turns into a retransmission on a link that is already full, so the graph never settles. The verdict flips only when the wireless hop carries nothing the robot depends on second to second. This post is for anyone whose robot works on the bench with a cable and falls apart the moment the cable comes out.
The symptoms get described the same way every time. On the bench, with a cable, the topic list is complete and teleop moves the wheels. On the floor, on Wi-Fi, the list is different every time you run it. Nodes appear, vanish, and come back a minute later. The camera topic is listed but nothing arrives, or one frame arrives and then nothing for a long stretch. Teleop works until you walk across the room, and then the robot keeps driving in the direction you last told it. Somebody suggests a different DDS vendor, so you try that, and the failure changes shape without going away. Somebody suggests best-effort delivery, and the camera comes back but the odometry starts skipping. You buy a better router. It helps for a day. Then a second robot joins the network and both get worse, and now you are reading forum threads about multicast and IGMP snooping at midnight, which is not what you meant to be doing. The part that stings is that nothing is broken on the bench.
Is ROS 2 on Wi-Fi something I can fix, or something I have to design around?
ROS 2 on ordinary Wi-Fi is something you design around, not something you fix. You can improve it — a static list of peers instead of group-addressed discovery, a discovery server, smaller queues, best-effort delivery on the streams that can afford to lose data — and each of those buys back some stability. None of them changes the underlying situation, which is that a shared radio delivers packets in bursts with gaps between them, and a middleware built for a switched wired network treats every gap as something to recover from. Recovery means sending more, and sending more on a full link widens the next gap. The design that works puts the boundary in a different place: everything the robot needs in order to keep itself upright, stop before it hits the table, or hold a wheel speed lives on the robot's own computer, and the wireless link carries only things a person looks at. Once that split exists, ROS 2 over Wi-Fi stops being a problem, because nothing on the wireless side has a deadline.
What does robotics middleware actually do on a network?
Middleware moves a message from the code that produced it to the code that needs it, and decides what happens when that fails. On one machine, the job is mostly bookkeeping. Across a network, it becomes three jobs at once: finding the other side, agreeing on what a message looks like, and deciding whether a lost message should be resent, skipped, or waited for. ROS 2 does all three through DDS, which was designed for the networks that industrial and defence systems run on — wired, switched, and quiet. On that kind of network the three jobs are nearly invisible. Announcements arrive. Retransmission is rare. Queues drain faster than they fill. Put the same three jobs on a shared radio in an apartment with a microwave and two laptops streaming video, and every assumption underneath them is now wrong at unpredictable intervals. The middleware is not misbehaving. Middleware is doing exactly what it was told to do on a network that no longer matches the description it was given.
Why does Wi-Fi drop exactly the packets ROS 2 depends on?
Wi-Fi handles the traffic ROS 2 uses to find nodes worse than any other traffic it carries. Those announcements are usually sent to a group address rather than to one recipient, and an access point treats group traffic as something it can send slowly, send once, and never confirm. Traffic addressed to a single device gets acknowledged and resent; group traffic often does not. Many access points discard it, and several mesh systems drop it between units on purpose. So the announcements that let two nodes find each other disappear first, which is why the failure looks like nodes that do not exist rather than data that is late.
Large messages fail a second way. A camera frame does not fit in one packet, so the frame is cut into many pieces, and losing any single piece throws away the whole frame. That is why video over a marginal link does not go grainy the way a video call does. Video over a marginal link stops.
What are my actual options when the robot has to be wireless?
There are five real options, and most projects end up combining two of them. You can keep ROS 2 everywhere and tune it — static peers or a discovery server, best-effort on the lossy streams, shallow queues — which is the least disruptive change and helps most on a quiet network. You can keep ROS 2 on the robot and put a purpose-built bridge on the wireless hop, so the radio carries one connection designed for lossy links instead of a full participant graph. You can move the timing-critical part of the graph onto the robot's own computer and let it talk to itself through shared memory rather than through a network at all, which is what HORUS is built for and what ROS 2's composed-node containers approximate. You can replace the wireless transport with something designed for the open internet rather than a LAN. Or you can accept a cable during development and treat Wi-Fi as a demo-day risk. The right answer depends less on which middleware you run than on what your robot stops doing when a message is late.
Which option fits which kind of robot?
The option that fits is the one matching how much your robot depends on the wireless link.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| ROS 2 with default settings | Bench work and wired setups | ROS 2 basics only | The machines share a switch | Anything at all crosses a radio |
| ROS 2 with static peers or a discovery server | Teams keeping the graph wireless | Transport config, clean restarts | The node list is known in advance | Nodes and robots come and go |
| ROS 2 plus a bridge on the wireless hop | Anyone streaming to a laptop | Which topics a person needs | The robot is autonomous, the link is for watching | An operator closes the loop by hand |
| HORUS on the robot's own computer | Builders whose timing-critical graph fits one machine | Rust, Python or C++, and life outside the ROS package set | Sensing, control and actuation share a machine | You need ROS drivers, or a graph spanning machines |
| A wide-area transport instead of DDS | Robots reachable from elsewhere | Networking and certificates | The link is genuinely unreliable | A quiet LAN would have done |
| A wired tether while developing | Everyone, at some point | Nothing | Finding out whether the radio is at fault | The robot must move to reproduce the bug |
| Whole graph on the robot, browser UI | Solo builders and small teams | A little web tooling | The robot should run unwatched | Someone must drive continuously |
Two rows are usually the answer together: the work stays on the robot, and one connection carries a view of it to a person.
What should I try first if I am one person with one robot?
Put the cable back in and prove which half of the problem you have. One person with one robot has no reason to debug two failures at once, and a wired run separates them in a minute: if the graph is complete and steady over Ethernet, your code is fine and the radio is the whole story. Then change one thing — move every node that touches a motor, a wheel encoder or a stop button onto the robot's own computer, and leave only the things you watch on the laptop. That single move fixes most solo setups, because most solo setups put the planner or the teleop node on the laptop early for convenience and never revisit the decision once the robot starts moving on its own. If you still need the laptop inside the loop, add a bridge rather than tuning discovery: a bridge is one connection you can reason about, and discovery tuning is a pile of settings you will have forgotten by the next time the robot misbehaves.
What should I do if my robot is a single small board with one radio?
Turn off the radio's power saving first, then stop asking the board to be a router. A small board with one radio is doing two jobs at once — competing for airtime as a Wi-Fi client, and running your control loop — and the two interfere in ways that look exactly like software bugs. Power saving is the common one: the radio sleeps between packets to save battery, and every sleep becomes a gap the middleware reads as loss. The second is the board advertising addresses it cannot be reached on, because it has an Ethernet port, a Wi-Fi interface and sometimes a USB network device, and discovery announces all of them. Pinning the middleware to the one interface that works removes a whole category of intermittent failure. After that, keep the sensor-to-actuator path on the board itself; fusing wheel odometry with an IMU is a good example of work that has no business crossing a radio. A small board can usually run the whole loop. What it cannot do is run half the loop and negotiate for airtime for the other half.
What if I need this working by the end of the month?
Stop tuning and move the boundary, because moving the boundary takes an afternoon and tuning does not converge. With a deadline, the cheapest dependable change is to run the entire graph on the robot and give yourself a read-only view of it: a browser dashboard, a log you pull afterwards, a video stream that is allowed to stutter. Every tuning path you might take instead has the same shape — a setting improves one symptom, a different symptom appears, and you cannot tell whether the last change helped, because the radio environment differs from hour to hour. That is a bad thing to have on a schedule. If a person must be in the loop for the demo, make that person's input the only thing crossing the link, and make the robot safe when the input stops arriving, so the robot slows and stops rather than continuing on the last command it heard. Demo rooms are the worst radio environments most robots ever see, and a robot that stops safely reads far better than one that drives into a table.
What if I have never configured a network before?
You do not need to. The change that works for most people is architectural rather than a network setting: put the parts with deadlines on the robot, keep the parts you watch on your laptop, and let the link carry only the second kind. That takes no router settings, no multicast knowledge and no certificates. If you want exactly one piece of network knowledge, make it this — traffic addressed to a single machine is treated better by Wi-Fi than traffic addressed to a group, and discovery uses the second kind by default. That one sentence explains most of what you will read in forum threads about this. Beyond that, resist learning access point configuration in the middle of a robot project: you spend a week on it, end up with a network tuned for one apartment, and then take the robot to a different building. The architectural change travels. The router configuration stays home.
What do I give up by moving the timing-critical work off the network?
You give up the ability to inspect and replace pieces of the loop from your laptop while the robot is running, and that is a genuine loss. When every node is a separate process on the network, you can kill the planner, start a new one with a changed parameter, and watch the robot respond without stopping anything else. Collapse that graph onto the robot and you get a build-and-restart cycle instead. You also give up some tooling that assumes a network graph — visualisers that find topics on their own, recording tools that sit anywhere on the network and subscribe to everything. Most of that comes back through a bridge, but it comes back deliberately rather than for free. The trade is worth making when late messages have physical consequences, and not worth making when they do not. An arm that must stop before it hits the table sits on one side of that line. A weather station sits comfortably on the other.
When is ROS 2 the better choice?
ROS 2 is the better choice whenever your robot's real problem is coverage rather than timing, and for most robots it is. If you need a mapping stack, a navigation stack, a driver for a particular lidar, an arm planner, a simulator that already speaks the same message types, and the ability to hire someone who has seen all of it before, ROS 2 gives you those and the alternatives do not. ROS 2 is also the better choice when the graph genuinely has to span two machines — an onboard computer plus a workstation doing perception, or a fleet reporting to a base station — because distributing work across machines is a first-class part of what ROS 2 does. HORUS is not the answer there: shared memory is a single-machine idea, and a middleware that removes the cost of passing messages between processes on one computer has nothing to offer a link between two computers. And if a late message is merely a late message in your loop, the wired-network assumptions never bite you, and ecosystem size is the only thing left to compare.
Will switching middleware fix my Wi-Fi problem?
No, and here is why: the packets are being dropped by the radio before any middleware sees them. Every messaging layer sits above the wireless link, and none of them can retrieve a frame the access point never sent. What a different middleware changes is how loss gets handled — retries, waiting, queue depth, how it finds the other side — and those choices do matter at the margins. They stop mattering when the link is saturated, when group traffic is being discarded, or when the robot has simply walked out of range. This is the most common wrong turn in the topic: a team spends a month migrating to a different transport, gets a week of relief because the new defaults queue less, then meets the same wall with less documentation and fewer people to ask. Prove the link can carry what you are asking it to carry before changing anything above the link. If a plain file copy over the same connection stalls, no middleware choice is going to rescue the robot.
Does a better router or a mesh network solve this?
Partly, but not the way you think. Better equipment does help — not because of the number printed on the box, but because better equipment handles group traffic more honestly, keeps one client from starving while another streams video, and hands a device between units without dropping the connection long enough for the middleware to declare a node dead. Those are the properties worth shopping for, and none of them is the property being advertised. Mesh systems can make things worse: several isolate clients from each other by default, which is right for a coffee shop and wrong for a robot that needs to reach a laptop on the same network. The other half of the answer is that a good network moves the failure instead of removing it. You will walk further from the access point. You will add a second robot. You will demo in a room with two hundred phones in it. The architecture that survives all three is the one where the radio carries nothing the robot is waiting for.
How do I decide what to change first?
Run three tests in order and let them tell you which problem you actually have. First, run the whole system over a cable: if it is steady, your code is not the cause, and every hour spent rereading it is wasted. Second, run it over Wi-Fi with the robot beside the access point and nothing else on the network: if that is steady and it falls apart across the building, you have a coverage and airtime problem rather than a configuration problem. Third, start the parts one at a time and watch which one breaks the others: if everything holds until the camera starts, the link is saturated, and no amount of discovery tuning will change that. From there the decision is nearly automatic. Coverage and saturation problems are fixed by moving work onto the robot. Discovery problems are fixed by making discovery explicit instead of leaving it to the radio. Problems that persist over a cable are ordinary software bugs that Wi-Fi was taking the blame for.
A short version, by situation:
- If you are debugging with a cable within reach -> keep the cable until the graph is steady, because a wired run answers in a minute what a week of forum threads will not.
- If you are one person with one robot on a home network -> move every node with a deadline onto the robot, because the radio then carries nothing that has to arrive on time.
- If a person must stay in the loop -> send only that person's input and stop safely when it stops arriving, because operators walk out of range mid-run.
- If your graph must span two machines by design -> keep ROS 2 and give the wireless hop a transport built for lossy links, because that is a distribution problem.
- If everything with a deadline already fits on one computer -> keep it there, because the network problem you deleted is the one you never debug again.
When you are weighing the options rather than chasing symptoms, the HORUS Fit Framework compares them on five things that are not numbers: ecosystem size, setup effort, team size fit, deployment target, and licence. If you are making this call as a one- or two-person team, those axes decide it faster than any benchmark, and a small graph written as plain Python shows what the on-robot half looks like once the network is out of the picture.
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.