Multi-robot consensus papers usually assume nodes are honest or crashed. Real fleets have a third mode that is worse than either: a robot that is up, responsive, participating in the protocol, and reporting nonsense with full confidence.
A frozen IMU. A camera looking at a wall it thinks is a corridor. A localization filter that diverged twenty seconds ago and has been extrapolating ever since. None of these are attacks. All of them are, from the protocol's point of view, byzantine.
Crash faults are the easy case
A robot that stops talking is a solved problem. Time it out, exclude it, re-form the group, carry on. Every consensus algorithm handles this and it is not where fleets fail.
The failure that hurts is the confident liar, because every mechanism you have for detecting problems relies on the faulty node behaving unusually — and this one does not. It answers on time, in the right format, with plausible values.
Our worst run was not caused by a robot that failed. It was caused by a robot that kept working, kept voting, and kept being wrong in a way the group found convincing.
What Swarm Mesh does about it
Cross-check against physics, not against votes. A robot claiming a position four metres from where it was 200 ms ago is claiming something its own drivetrain cannot do. Kinematic plausibility is cheap to check and catches a large fraction of sensor faults before they ever reach the consensus layer.
Weight by corroboration, not by count. Three robots that all derive position from the same shared beacon are not three independent observations. We track which estimates share upstream sources and discount accordingly. This is the change that mattered most, and it is a bookkeeping change, not an algorithmic one.
Let reputation decay both directions. A node that has been wrong loses weight, and it regains weight slowly as it agrees again. Permanent exclusion is wrong — most sensor faults are transient, and a fleet that permanently exiles every robot that hiccups will shrink to nothing over a long mission.
for peer in mesh.peers:
if not kinematics.plausible(peer.claim, peer.last, dt):
peer.trust *= 0.25 # hard penalty: it broke physics
elif peer.claim.far_from(consensus):
peer.trust *= 0.85 # soft penalty: it disagrees
else:
peer.trust = min(1.0, peer.trust * 1.05)
estimate = weighted_median(
[(p.claim, p.trust / independence[p.source]) for p in mesh.peers]
)
Weighted median rather than weighted mean, deliberately. A single wildly wrong value with residual trust can drag a mean anywhere. It moves a median by one rank.
Packet loss makes it worse in a specific way
Under loss, disagreement and silence become hard to tell apart. A robot that never received the last round's broadcast will report a stale estimate that looks exactly like drift.
Our fix is that every claim carries the round it was formed in. A stale claim is discounted for staleness, not penalized for being wrong. Before we did this, our reputation system was systematically punishing the robots with the worst radio links — which were, of course, the ones furthest out and most in need of the group's help.
What we cannot yet handle
Correlated faults. If half the fleet flies into the same lighting condition and their visual odometry degrades the same way, they will agree with each other, and agreement is the only signal we have. The majority is wrong and confident and mutually corroborating.
We think the answer involves keeping at least one estimator per robot that fails differently from the others — wheel odometry, say, against vision — so that a correlated visual failure still has an uncorrelated dissenter. That is the next set of experiments.