179 identity switches, and why the SOTA fix costs too much
A diagnostic reported "id switches: 0" for months. It was a clean-looking zero produced by a tool measuring nothing — and the real number, once measured, explained why a bigger tracker wasn't the answer.
continuity.py reported "id switches: 0" — a clean result, and wrong for a boring reason: it was scoring /detections, a topic that carries no identity field at all. Zero wasn't a measurement. It was the absence of one, dressed as a number. A second tool, check_tracker.py, made the same mistake more loudly — it read d.tracking_id, a field vision_msgs/Detection2D does not have, and raised AttributeError on the first track of every run. Because that code path only executes when tracks exist, the crash stayed invisible in every quiet run and every piece of documentation kept asserting the field was there.
Scored correctly, on /tracks, with the field that actually carries identity: 179 identity switches in 253 seconds — one person, in one room. That is the real number the project had been building on top of for however long "0" went unquestioned.
Why the obvious fix doesn't apply
A motion tracker cannot close this gap by definition. ByteTrack and OC-SORT — the trackers actually in play here, not the more famous one people assume — associate detections on IoU plus a Kalman prediction. Across a real occlusion gap the prediction decays and the overlap disappears, so a target that returns can't be matched back to the track it came from. That's the boundary of what motion-only association can say. It isn't a bug in either tracker; it's what they're built to not do.
The state of the art names the fix, and also the price.
BoT-SORT closes exactly this gap by fusing motion with appearance modelling and camera-motion compensation to hold identity across a break. Naming it is the easy part — it also names a cost this platform can't pay today: appearance re-identification at the frame rates this vehicle runs is compute the perception budget doesn't have free. So the honest status isn't "fixed" or "ignored." It's a priced, deferred trade: the 179-switch number stays in the README as the reason the next perception cycle should spend its budget on identity, not on a faster detector.