Skip to content

Tracking: next steps ​

Written 11 October 2026, at the end of the algorithm work on branch rtls-algorithms.

This page says what the branch contains, what was stopped before it was finished, what to check on site this week, and what to pick up afterwards. The algorithms themselves are described in Tracking System.

What the branch contains ​

Two commits on top of V9.7.5:

  1. tools/rtls-sim/: the simulator, the algorithm prototypes, the evaluation scripts and the reports of the study.
  2. The algorithms in the server:
    • zone_voting is unchanged and is the default at boot, in the HTTP API and in the admin page. Its file is byte-identical to V9.7.5, and a differential test (tools/rtls-sim/port_diff/) shows identical decisions on 566,000 steps.
    • Brutus and trilateration are removed from code, tests, docs and the website copy.
    • Nine algorithms are selectable next to it: zone_voting_max, zone_voting_v2, zone_voting_v2_fast, zone_voting_v3, geo_bayes, fingerprint_nb, ref_beacons, centroid_snap, zone_voting_motion_gate.
    • Three defects fixed on the way: an unknown algorithm name no longer leaves tracking "running" with no timer; the admin selector preselects the running algorithm (it used to fall on the first entry, Brutus); the defaults that named Brutus now name zone voting.

Checks that pass on the branch: typecheck of lib, server, web, scripts and the simulator; 1,369 server tests; 89 simulator tests; the Zones page browser tests (17).

Deploying the branch changes nothing until somebody selects another algorithm: tracking runs zone_voting exactly as before.

What was stopped ​

The work was cut short to stop spending. These parts are not done:

PartState
Independent review of the server changeThree review passes were planned (the live tracking path, retirement and docs, fidelity of the ported algorithms). None ran. The change was checked by the test suites, by the before/after behaviour digests of every ported algorithm (120 of 120 identical), and by a read of the tracking.ts diff.
RSSI recorder, server sideNot started. No endpoint, no recording file, no replay tool.
RSSI recorder, Theseus appBuilt and tested (559 app tests), on branch rtls-theseus-wip, not merged. It calls endpoints that do not exist yet, so it must not be released. See below.
Fingerprint survey toolingfingerprint_nb reads rtls/fingerprint_survey.json, but nothing produces that file yet (the recorder was going to). Until then it answers like zone_voting.
Hardening of the survey loaderA survey whose timestamps are wrong (a pause of hours inside one zone) could make the model fit slow. Add limits to tracking_alg_inputs.ts before the first real survey is installed.
Bridge and the motion triggerserver/src/bridge.ts reports every advert whose UUID does not end in 1 as a button press. That includes the motion UUID. Fix it before any watch on a Zabbix site gets the motion trigger. A separate task was opened for it.

What to check on site this week ​

The figures in the tracking page are simulation. The two things to judge in reality are zone jumping at rest and how fast a real move is shown.

Before testing

  • Algorithms are switched in Zones → Overview. A switch empties the predictions for a few seconds, and the choice is lost when the server restarts. Switch only while nobody relies on alerts, and switch back to zone_voting when the session ends.
  • After editing zones or gateways, stop and start tracking.
  • Open Zones → Debug for the test watch. The new algorithms print why they kept or changed the zone each cycle.
  • Look at how often gateways report. In the debug output of zone_voting_v2 each link shows its upload gap. With a gap of about 5 s, no algorithm can show a move in much under 10 s. That setting matters more than the choice of algorithm.

Zone jumping at rest

Leave a watch (or sit with it) for 10 minutes in each of: the middle of a room, an open area with several gateways, the line between two open-area zones, a room without a gateway. Count the zone changes per spot under zone_voting, then under zone_voting_v2 and zone_voting_v3. History (Zones → History) shows the changes afterwards.

Expect: far fewer changes with zone_voting_v2. On a boundary line it may sit calmly in the neighbouring zone; that is the same error as today without the jumping. A room without a gateway is never reported by the zone-voting family.

Snappiness

Walk a fixed route with stops of about a minute per zone and note, for each arrival, the seconds from crossing the door to the new zone appearing. Do the same route under zone_voting, zone_voting_v2, zone_voting_v2_fast and zone_voting_v3. Include one case of sitting several minutes and then moving to the directly neighbouring zone: that is where zone_voting_v2 is slowest by design.

Simulated expectation, to confirm or refute: median delay about 6.6 s for zone_voting_v2, 6.0 s for zone_voting_v2_fast, 4.6 s for zone_voting_v3; zone_voting_v3 decides every second and stays close to zone_voting_v2 in calmness.

What decides the rest of the plan

In a room without a gateway, note how many gateways hear a worn watch and how often it is silent (the debug output lists the links). If two or more neighbouring gateways hear it most of the time, geo_bayes and fingerprint_nb can find such rooms. If not, those rooms need a gateway and no software will fix it.

What to pick up afterwards ​

In this order:

  1. Decide from the site results which algorithm becomes the candidate default, and whether the selection should be stored so it survives a restart (a config key; today it always boots zone_voting).
  2. Run the reviews that were skipped on the server change before any site uses a new algorithm unattended.
  3. RSSI recorder, server side. The contract the app was built against is docs/theseus/rssi-recorder-api.md on rtls-theseus-wip: the tester picks watches in Theseus and taps the zone each is in; the server writes the gateway RSSI reports and the labels to one file. Needed: the recorder module and its tap in server/src/events.ts, the routes under the Theseus field guard, tests against the app's fixtures (theseus/test/fixtures/rtls/), and the entries for the two new Theseus pages in docs/.vitepress/config.ts.
  4. Replay tool in tools/rtls-sim: run any algorithm over a recording and print accuracy, zone changes at rest and delay from the labels. With it, one labelled walk scores every algorithm at once, and site time is no longer spent per algorithm.
  5. Fingerprint survey from a recording, with the loader limits above.
  6. Merge rtls-theseus-wip once the server side exists. The app side has a start screen with a sign-in card (the site-pairing QR) and tool cards generated from a registry, the ops inbox kept alive at app level, and the recorder screens. It added a small native keep-awake channel; the Android debug build succeeds, the Swift change type-checks, and nothing has run on a device.
  7. Motion gate, only if jumping at rest is still a problem: bench-test the watch motion trigger on one watch (tools/rtls-sim/reports/field_plan.md, section 6) after the bridge fix.

Known limits of what was shipped ​

  • Not validated on real RSSI. Every dB value and every figure comes from a simulated radio.
  • zone_voting_v2 and zone_voting_v3 do not report rooms without a gateway, and at an open boundary they are calm, not more often right.
  • zone_voting_v3 decides every second, so its debug stream and diagnostics run twice as often. Under slow fading it lost 1.1 to 1.5 points of accuracy against zone_voting_v2 in the simulator.
  • centroid_snap fails with a zone rectangle that encloses other zones and with uploads slower than every 7 s.
  • fingerprint_nb with a survey that covers only some zones shows a watch in the nearest surveyed zone.
  • State is dropped after 60 s of silence for the new algorithms, as for zone_voting. geo_bayes, ref_beacons and the motion gate then start fresh.
  • ref_beacons assumes reference beacons transmit 12 dB louder than a watch. A different beacon needs a change in the catalog. The candidate report under tools/rtls-sim/reports/ states the calibration rule with the wrong sign: a positive excess in the debug output means the offset is too high.

Where things are ​

WhatWhere
Algorithm modules, catalog, runner, site inputsserver/src/algs/
Their testsserver/tests/tracking_alg_*.test.ts, tracking_registry.test.ts, api/tracking_control.test.ts
Simulator and how to run a registered algorithm in ittools/rtls-sim/README.md
Comparison of the candidates, and its audittools/rtls-sim/results/EVALUATION.md, tools/rtls-sim/reports/audit.md
Delay study behind zone_voting_v3tools/rtls-sim/results/SNAPPINESS.md
On-site protocol in more detailtools/rtls-sim/reports/field_plan.md
Theseus app workbranch rtls-theseus-wip