Skip to content

Releases: andreagenovese/quacknav

v0.3.0-rc3

v0.3.0-rc3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 27 Oct 12:58

quack-nav v0.3.0-rc3 — release notes

2026-10-27. Italian copy: release-notes-v0.3.0-rc3.it.md.
The full list of changes is in CHANGELOG.md; the previous
candidate's notes are in release-notes-v0.3.0-rc2.md.

What this is

A fifth release candidate, validated on the twins only — the MuJoCo
twin of the Microduck (Pollen's daemons v0.16.1 and v0.17.6 and
microduck_rl's body) and the paper twin — not yet on a real duck.
The physical duck arrives in December 2026; until a first session on it,
every number below is the twin's.

rc2 was about what the 2D map does not have. rc3 is about Pollen's new
daemon line and about not falling: the daemon 0.17 line with its own
walk numbers and its own pilot, a look at the floor before a step the
map cannot vouch for, and a turn in place that stops where it was told
to. It also brings people walking through the house on the twin and the
bench alike, and a bug in how far away things were booked.

Before installing

  • Nothing new to set. The config of rc2 works as it is. A new
    optional key daemon ("auto", the default: robotd says which daemon
    it is at start; "0.16" or "0.17" to name it) picks the walk's
    numbers for Pollen's line (README, The daemon).
  • Built against daemon-v0.17.6; the same build runs on every daemon
    from v0.14.4.
  • The maps and the places saved by rc2 load as they are.
  • The install package carries one more pilot, pilots/0.17/velstand/,
    which quack-navd takes on the 0.17 line when QK_RL_POLICY names the
    pilots' directory. Unset, the stick drives, as before.

What changed since rc2

  • The daemon 0.17 line. From daemon-v0.16.2 the duck runs policy set
    v8: velstand walks slower forward (0.095 m/s at vx 0.3) and turns about
    twice as fast (a turn in place at 1.0 is about 65°/s). One file per
    line holds velstand's numbers; daemon = "auto" picks the line. On
    that line the exploration's turns in place stop short by the learned
    coast too.
  • A look at the floor before a step onto what the map does not know.
    The depth sensor cannot see the floor nearer than 0.4–0.6 m, and a
    stairwell against a wall hides a second way. Every reckless fall on the
    bench was that: a turn taken too far, then straight steps into a
    stairwell no frame had seen. Before a step whose stride runs onto cells
    the map holds as neither floor nor wall, or the first after a turn in
    place of 0.5 rad or more, quack-navd now pitches the head at the floor
    0.30 m ahead for 0.45 s and hands it back; what it sees goes through
    the guards and on the books. QK_LOOK_DOWN=0 switches it off.
  • A turn in place stops where it was told to. A timed move ended
    without a stop and robotd held the last command to its deadman, 500 ms:
    a third of a right angle at set v8's rate, on every turn. The explorer
    now sends a stop at the end of every turn in place (QK_TURN_STOP=0
    for the old way). The turns land 12–16° past what was asked instead of
    43–44°, and the coast the next turns stop short by learns the gait's
    own, not the hold.
  • Pilot v8l-s3 for velstand on the 0.17 line, trained on the twin's
    traces and houses with the simulator's sensor made to see as the
    twin's: the first pilot on that line not slower than the stick. The
    handover between the pilot and the stick is firmer: the stick takes the
    legs from a pilot that gets no nearer and keeps them until the body is
    0.3 m from where it took over; within 0.5 m of a booked rim the stick
    walks the legs.
  • Things seen were booked 7.8 cm nearer the body than they are.
    kinematics measures a hit's range from the sensor, not from the trunk
    axis its doc names (pollen-robotics/microduck#430); the books now use
    the trunk's distance, and a thing seen is booked from the pose of the
    frame that saw it.
  • People walking between the rooms, on the twin and on the bench
    alike: casa_gente (four people on paths between the rooms, a cat),
    movers that wait for the duck within 0.35 m and step aside, the same
    rule with the same numbers in the twin and in the simulator.
  • The simulator's houses are the twin's (--families twin:<house>), a
    tip-over gets up after 4 s on the 0.17 line, the sensor's rows follow
    the head's pitch, and the simulator holds a spin's last command to the
    deadman unless stopped, as robotd does.
  • The twin: twin.sh down cleans the sockets a lost pid file left; a map
    loaded at boot is placed once the pose is confirmed; explore_ab.sh
    starts each house from an empty state.

Measured against the version before

Each change against the main before it, on the MuJoCo twin with
velstand on daemon-v0.17.6, four rounds a house, two twins at a time
(the houses: casa_ingombra, casa_arredata; 24 journeys an arm and house):

before after
the daemon key and the line's numbers, run on daemon-v0.16.1: reach, falls, wake-ups main no regression
pilot v8l-s3 against frozen main's stick: journeys 48/48 48/48, 4.2 and 3.9 s a journey faster, no fall
the look at the floor: journeys 48/48 48/48, no fall, 6.2 and 2.7 s a journey more (4.4 and 3.4 looks a journey)
the look at the floor: houses explored from nothing, floor mapped after two sessions 63 / 69 % 76 / 78 %, no fall
the look at the floor: reckless brains on the bench, 25 200 journeys 13 falls into a hole 0
the turn's stop: journeys 48/48 48/48, no fall, 2.0 s slower in the cluttered house, 5.9 s faster in the furnished one
the turn's stop: where a turn lands past what was asked (median) 43–44° 12–16°
people in the house (bench, casa_gente, 192 journeys): arrivals, contacts with people a journey stick 84 %, 8.0 pilot 89 %, 2.2

Details: results.md, "Round two on the 0.17 line", "The
sensor's blind zone", "The turn in place's overshoot".

Known limits

  • The twins only. The deadman, the sensor's rows and the walk's
    numbers are measured on the twin; the duck's own are the first
    session's job (first-duck-session.md).
  • A walking leg's hold to the deadman is not modelled: about 5 cm at
    set v8's pace after a leg's last chunk, inside the speed fitted from
    the traces. And a turn asked through robot.move (quack-control's
    manual move) still goes on to the deadman, about 33° at 1.0: only the
    explorer's own turns send the stop.
  • The look covers the stride ahead, not the house. The sensor's blind
    zone under 0.4–0.6 m stays; a hole beside the body, or one reached
    sideways or backwards, is on the books or nowhere.
  • The learned coast lives in the process: at every restart a turn's
    coast starts again from the line's prior (17°) and converges in a few
    turns. Keeping it, and the walk's other numbers, beside the map is the
    next work (the todo's gait ledger).
  • A rim is booked where the pose had it: about 1 in 50 drops lands
    20–35 cm from the true rim (results.md, "Known limits").
  • robotd's own teleop still has no drop protection
    (study/upstream-asks.md §8).

v0.3.0-rc2

v0.3.0-rc2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Oct 10:44

quack-nav v0.3.0-rc2 — release notes

2026-10-18. Italian copy: release-notes-v0.3.0-rc2.it.md.
The full list of changes is in CHANGELOG.md; the previous
candidate's notes are in release-notes-v0.3.0-rc1.md.

What this is

A fourth release candidate, validated on the twins only — the MuJoCo
twin of the Microduck (Pollen's released daemon-v0.16.1 and
microduck_rl's body) and the paper twin — not yet on a real duck.
The physical duck arrives in December 2026; until a first session on it,
every number below is the twin's.

rc1 was about the duck as Pollen ships it and about stepping better. rc2
is about what the 2D map does not have: things that move, and things the
duck walks under or into at its own height. It also brings a first,
experimental 3D house with the camera's colours, built off board.

Before installing

Nothing new to set. The config, the walk profile ([gait] profile) and
daemon-v0.16.1 are as in rc1, and the maps saved by rc1 load as they are:
their band starts empty and fills as the duck stands and looks.

What changed since rc1

  • Things that move: four rules, on by default. Something in the lane
    is booked from 0.35 m (0.30 before), and from 0.6 m when it comes nearer
    faster than the body walks; after a bump or a touch the duck steps back
    before turning away, only onto floor the map knows; what a journey
    booked leaves the books when the sensor sees the floor where it stood
    (drops never do). Each is a knob (knobs.md); 0 gives rc1's
    behaviour.
  • The band: 2.5D at the duck's height. Per 5 cm cell, ten slices from
    0.05 to 0.30 m, filled by the depth sensor's returns and emptied by the
    beams that cross them. The navigation reads it as wall: a coffee
    table's top, a bed's frame, a tub, which the 2D map read as free floor,
    are now in the way. It is saved beside the map (<map>.band) and rides
    map.frame as band. QK_BAND=0 turns it off. Returns within 10 cm of
    a wall the 2D map already has are left to the map, so the band does not
    thicken the walls and narrow the passages.
  • A textured 3D house, off board (experimental). scripts/map3d
    records the head camera beside an exploring duck, builds a 3D house with
    its colours on a Mac or a PC, and send.sh puts it on the duck, where
    quack-control v0.1.0-rc2's 3D tab draws it. Nothing new runs on the
    duck. On the twin: walls and furniture 2.6 cm from the truth (median).
  • The twin: people and pets that move (TWIN_MOVERS), two houses with
    them, and a head camera that faces forward.
  • CI: actions on Node 24, tried on ubuntu-26.04.

Measured against the version before

Each change against the main before it, on the MuJoCo twin with
velstand, four rounds a house, two twins at a time:

before after
moving obstacles: journeys, apartment / casa_arredata / casa_ingombra 24/24, 24/24, 12/12 24/24, 24/24, 12/12
moving obstacles: casa_viva (three movers) / casa_porta (a person in a door) 24/24, 24/24 24/24, 24/24
moving obstacles: exploring from nothing, three houses one fall no fall
the band: journeys after exploring, apartment / casa_arredata 24/24, 24/24 24/24, 24/24
the band: exploration declared done (of four sessions) casa_arredata at 4, the apartment never both at 3

No fall in the band's runs on either side. Details: results.md,
"Moving obstacles" and "The band".

Known limits

  • The twins only. The twin's depth sensor casts one ray per zone; the
    real one sees a zone about 5.6° wide, and how a wide zone grazing a wall
    lands in the band is unmeasured until the duck.
  • The 3D house is a preview. The camera's axes and intrinsics must be
    checked on the duck; on the twin its textures are synthetic.
  • A person booked as a few points never seals a door: the forgetting
    rule has not fired on the twin yet (its gain is the bench's).
  • robotd's own teleop still has no drop protection
    (study/upstream-asks.md §8).

v0.3.0-rc1

v0.3.0-rc1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 09 Oct 23:20

quack-nav v0.3.0-rc1 — release notes

2026-10-09. Italian copy: release-notes-v0.3.0-rc1.it.md.
The full list of changes is in CHANGELOG.md; the previous
candidate's notes are in release-notes-v0.2.0-rc2.md.

What this is

A third release candidate, validated on the twins only — the MuJoCo
twin of the Microduck (Pollen's released daemon-v0.16.1 and
microduck_rl's body, with both of Pollen's walking policies) and the
paper twin — not yet on a real duck. The physical duck arrives in
December 2026; until a first session on it, every number below is the
twin's.

rc2 made the duck rest, get carried and be driven by hand. rc3 is about
the duck as Pollen ships it — its default walk, its newest daemon — and
about stepping better: a stick that meets things the map does not have,
and a neural navigation model that can take its place.

Before installing

  1. Say which walk the duck runs, in /etc/robot/quack-nav.toml:

    [gait]
    profile = "velstand"   # Pollen's default; "alpha" for alpha_walking + alpha_stand

    Left out, it means velstand. A duck on alpha whose config has no
    [gait] section must add profile = "alpha" (the installer keeps an
    existing config as it is).

  2. Pollen's daemon-v0.16.1 is the daemon validated.

What changed since rc2

  • Both walks. velstand (Pollen's default since policy set v5: one
    network that walks and stands) did not work before: robotd labels a
    standing velstand duck "walk", so quack-nav never saw it still, and since
    0.16.1 robotd's idle glancing took the head. Now the applied twist
    decides, the duck counts as still 0.6 s after it (its body goes on that
    long) and stands are that much longer. Measured on the twin: the same
    journeys as alpha, the pose closer (6–7 cm median), about 10 % slower.
  • The pilot, a neural navigation model, one per walk. An MLP
    (351 inputs, 9 moves) chooses each step of a journey in place of the
    stick's rules, never the route, with hard shields around it. The
    package installs pilots/alpha/ and pilots/velstand/ (pilot.json
    for quack-navd, pilot.onnx for anything else) in
    /var/lib/quack-nav/pilots/; off until
    QK_RL_POLICY=/var/lib/quack-nav/pilots (knobs.env), then the pilot of
    the walk. Bench: 97.1 % against the stick's 93.3 % (alpha), 95.2 % against
    94.8 % (velstand); on the twin with velstand, 12/12 with no fall.
  • The stick, on a journey: a nose against something for two steps is a
    stall (apartment's coffee table, where the body pushed for minutes and
    the pose slid 0.3 m); what the sensor keeps seeing within 0.30 m goes on
    the books before the bump; a turn in place stops short by the coast it
    learns (232 dithers to 5, journeys 9–22 % faster). A walked lane yields to
    a booked drop within 0.20 m, which keeps the route off a stairwell's
    corner.
  • The hole guard by a wall. A hole set against a wall read as a box's
    edge; a brain choosing at random stepped in once on the bench. Fixed in
    the guard only; 0 holes in 7,560 random journeys since.
  • daemon-v0.16.1 (API 41): the pin moved; the head sweep now takes the
    head back from robotd's idle glancing.

Measured against main

Four rounds a house on the MuJoCo twin, the same books, two twins at a
time:

main v0.3.0-rc1
journeys, velstand 48/48 + casa_ingombra 11/12 48/48 + 12/12
journeys, alpha 48/48 + 11/12 48/48 + 12/12
exploration, velstand (three houses) coverage, no phantom, 34/34 after the same
falls into a hole 0 0

Details: results.md, "v0.3.0-rc1: the verifications against
main".

Known limits

  • The twins only. Calibrate the pilot on the duck's own traces
    before trusting it (docs/rl-pilot.md, "Calibration on the duck").
  • velstand explores slower in a house's first session (its stands are
    longer): about one session more to finish a house.
  • Things that move (people, pets) are booked only within 0.30 m and
    stay on the books until a "no way" clears them: the next work, after
    this release.
  • robotd's own teleop still has no drop protection
    (docs/study/upstream-asks.md §8).

v0.2.0-rc2

v0.2.0-rc2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Oct 14:30

quack-nav v0.2.0-rc2 — release notes

2026-10-03. Italian copy: release-notes-v0.2.0-rc2.it.md.
The full list of changes is in CHANGELOG.md; the previous
candidate's notes are in release-notes-v0.2.0-rc1.md.

What this is

A second release candidate, still validated on the twins only — the
MuJoCo twin of the Microduck (now Pollen's released robotd daemon-v0.15.0
and microduck_rl's body) and the paper twin — not yet on a real duck.
The physical duck arrives in December 2026. Until a first session on it,
take every number below as the twin's, not a promise.

rc1 made the duck map, come home and navigate. rc2 is about the hours in
between, when the duck stands, gets picked up, or is driven by hand — and
about what a control page needs from it.

What changed since rc1

  • Rest, and finding itself before a job. A duck left standing for a
    minute with nothing to do now rests: odometry carries the pose, nothing
    is corrected, and every two minutes one window (the head sweeping once)
    is judged against the map. If the map disagrees twice, or the duck is
    carried, sat down or falls, the pose becomes untrusted. The duck does
    not wander off to look for itself: the next go_to or map_explore
    first walks and looks until it knows where it is (relocalizing), then
    sets out — or fails with nothing walked toward the goal.
  • The creep fix. A standing duck's pose no longer walks along a long
    wall: at a stand the corrections kept stacking on each other along the
    direction the wall barely pins; now they are anchored where the stand
    began.
  • Places belong to their map. A named place is tied to the map it was
    taught on, so a power-on no longer makes every place stale ("go to the
    kitchen" refused after each boot). A place is usable, pending (the
    duck has not found itself on that map yet), other_map or stale (its
    map is gone). places.json moves to version 2 and migrates by itself.
  • robotd 0.15.0. Pollen's crates are pinned to daemon-v0.15.0 (API 37,
    additive); quack-navd runs the same against a board on 0.14.4.
  • The control contract. What a client that manages quack-navd uses —
    first of all quack-control,
    the local web page that shows the map and drives the duck — written down
    in control-contract.md: the two sockets, the map
    stream, places from a map view (at, a place taught at a tapped point),
    nav.knobs (the knobs' env file the unit reads at every start) and
    nav.restart. The twin's viewer now serves the head camera with
    mediad's own call, so the page reads the twin and the duck alike.
  • Move guards and self-started motion. robot.move from a caller (the
    voice agent's "go forward", quack-control's Advanced tab) keeps the depth
    sensor's cliff guard always on: a hole within 0.40 m ahead stops it, map
    or no map. robot.map_step on an uncertain pose judges by the sensor
    alone. When the duck moves on its own (the homecoming's search, its
    exploring, a relocalization) it says so (self_started), and the user's
    STOP stops all of it within a tick and holds until a job is asked for.
    Driving the duck by hand — including Pollen's teleop — keeps its
    position.
  • A done map stays frozen, turned maps are counted right. A house
    declared done is frozen as soon as it is loaded or adopted, so a power-on
    in stop_and_scan no longer inks the map it navigates. A map started
    where the duck stood, turned from the house, no longer counts the
    unknown beyond its walls as house ("55 %, stuck" became 83 %).
  • The README opens with a GIF of a go_to on the MuJoCo twin.

Headline results

On the MuJoCo twin (casa_grande unless said otherwise); sources in
todo-map.md §2d, its entries of 2026-10-01 to 2026-10-03.

  • Coming home, the navigation's way. The wake bench booting as the
    navigation does (WAKE_MODE=localize; 14 spawns on casa_grande and
    casa_arredata, then the same turned 180°): 28 of 28 wakes confirmed
    right
    , none wrong, median 87 s (75–141 s), 0.01–0.15 m from the
    truth, 0 falls.
  • The stand creep. The recording where a fourteen-minute stand walked
    the pose 1.56 m along a wall, replayed: the pose stays within 9.4 cm
    of where it stopped (1.62 m before). Forty replayed sessions: ATE as
    before (noise).
  • Rest. A thirty-minute rest after a go_to, the twin's standing duck
    turning and sliding by itself: pose error mean 10.0 cm, worst 17.2
    (awake, ten minutes at the same spot: mean 12.0, worst 18.2); a go_to woke it 0.13 s
    after the call. quack-navd 2.0–2.35 % of a Mac core resting against
    2.72 % awake.
  • Moved while resting. Carried 3.3 m into another room and turned 86°:
    untrusted at once, found in 70 s, arrived 0.02 m off. After ~16 h
    standing, the pose 1.38 m off and untrusted, a go_to to the kitchen
    relocalized in 97 s (6 steps) and arrived 0.21 m from the true
    kitchen.
  • The map (x26, the final-house protocol explored from nothing, both
    houses): walls on the truth 98 %, floor known 94–96 %, 0 phantom
    drops
    .
  • A stop_and_scan life (boot on the saved done map, "explore from
    scratch" from the kitchen, complete, then two reboots elsewhere):
    9/9 go_to arrived (0.09–0.30 m from the goal), 0 falls, the
    exploration declared the house done on its own at 86 %. With the done
    map frozen, two boots kept 495 submaps through 16 minutes and two
    go_to.
  • The guards. Facing a hole from 1.15 m, a robot.move stopped with the
    trunk 0.56 m short of the rim; nine calls over open floor, no false stop.
    A STOP during the boot's search answers in 0.15 s with 3 cm of coasting
    (7–8 s and up to 0.33 m before).
  • The paper twin gate (CI, fixed seeds): the same to the byte as rc1 —
    explore 40 runs, 0 falls, mean coverage 53.2 %; go_to 30/30. 182 tests
    pass (1 ignored).

Build, install, run

The board's binary is attached to this release (quack-navd-aarch64-linux,
with its sha256), built by CI with scripts/cross-build.sh.

Follow the README. For the board (Radxa Zero 3,
aarch64, Debian 13): Building for the duck,
then scripts/install-on-duck.sh microduck@<duck> installs or upgrades it
with its systemd unit (Installing on the duck;
the board image's account is microduck since Pollen's #340) — tried in a
systemd container, not yet on a board. The MuJoCo twin is in
scripts/twin/README.md.

Upgrading from rc1

  • robotd: pinned to daemon-v0.15.0 (API 37). A board still on 0.14.4
    works the same.
  • The unit: rerun scripts/install-on-duck.sh — the new unit reads
    /var/lib/quack-nav/knobs.env (EnvironmentFile=-; the config's new
    knobs_env names the same file).
  • Places: places.json is rewritten as version 2 on first use (a
    version-1 file migrates: current places wait for the first saved map the
    duck is confirmed on). rc1 refuses a version-2 file: keep a copy if you
    may go back. robot.list_places adds state, map, live_map and
    at; the old stale flag now also means other_map.
    robot.remember_place takes x, y and is refused while the live map
    is unknown.
  • robot.move (callers): a forward move may end early or be refused at
    a drop — "done": false, stopped, walked_s; every reply carries
    cliff_guard, and stopped_own when it stopped the duck's own motion.
  • robot.map_step: on a lost or untrusted pose only the sensor's
    checks apply (checks, clearance null); refused while a job the user
    asked for runs.
  • robot.go_to / robot.map_explore: on an untrusted pose the answer
    carries relocalizing: true and the job starts after the pose is
    confirmed; {"stop": true} also stops the duck's own motion and holds
    until a job is asked for.
  • Status fields: robot.map_status and map.frame add resting,
    rest_watch and untrusted; explore.state can be relocalizing or
    searching; explore adds self_started and stopped_by_user.
  • robot.map_load / robot.map_adopt freeze a house declared done and
    answer frozen; robot.map_explore on it is refused as before, a
    session under another save_as thaws it.
  • Rust API: places::Place::generation became map; the registry's
    generation() and observe() are gone.

Known limitations

  • A STOP with nothing running still holds the homecoming: it starts
    nothing on its own until a job is asked for.
  • The stick retries a step that returned at once (refused, robotd lost,
    the user's hold): it reads it as a stall, three as a bump, and books an
    obstacle at the nose.
  • An untrusted pose stays untrusted until a job, even when the duck is
    put back where it was: the next go_to searches first.
  • Steps instead of holes are untested: a step down or up was never
    tried on the twin.
  • Temporary obstacles need re-measuring on the current journey path,
    and what happens when one is taken away again.
  • robotd has no drop stop: Pollen's teleop drives through robotd, so it
    bypasses quack-nav's cliff guard and can walk off a stair (asked
    upstream, [study/upstream-asks.md](ht...
Read more

v0.2.0-rc1

v0.2.0-rc1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Oct 11:17

quack-nav v0.2.0-rc1 — release notes

2026-10-01. Italian copy: release-notes-v0.2.0-rc1.it.md.
The full list of changes is in CHANGELOG.md.

What this is

A release candidate validated on the twins — the MuJoCo twin of the
Microduck (Pollen's released robotd daemon-v0.14.4 and microduck_rl's
body) and the paper twin — not yet on a real duck. The physical duck
arrives in December 2026; then the numbers that only hardware can give
(cell pitch, map extent, CPU cost on the RK3566) get measured
(todo-map). Until a first session on
the real duck, take every number below as the twin's, not a promise.

Since 0.1.0 the mapper runs inside quack-navd against the released robotd,
the pose goes out at 20 Hz, the duck comes home to a saved map faster and
never wrongly, explores a house a charge at a time, and every journey runs
one loop. The knobs went from 169 to 122.

Headline results

On the MuJoCo twin unless said otherwise; sources in
results.md and todo-map.md §2d.

  • No fall. 0 falls in 11 exploration sessions (5 h 30) and 51 journeys
    on three houses (the release's protocol); none since, on casa_grande
    (four sessions, 16 journeys, 8 wakes) and in the five final-house runs
    that validated the loop-closure cap.
  • Journeys arrive. 46/51 (90 %) at the release's A/B, where the
    earlier build arrived 32/51 (63 %); since then every journey arrived: 16/16
    on casa_grande, and 6/6 and 8/8 per round in the final-house runs.
  • The map. Walls on the truth 95–100 % in the final-house runs, floor
    known 94–96 %; casa_grande 99 % of its walls on the truth, 0 phantom
    drops. Mean wall error 3.1–4.5 cm on house2 and casa_libera at the
    release.
  • Coming home. On the wake bench (12 spawns across two houses, then the
    same turned 180°) 23 of 24 wakes confirmed right, none wrong, medians
    87–123 s (126–192 s before the shadow map); casa_grande 8/8, median 84 s
    (72–111 s), 2–16 cm from the truth. At the release every confirmed pose
    was 0.07–0.17 m from the truth.
  • The heading. With loop closures capped at 4° the heading's median
    error was 0.63–0.92° in all five runs, against 0.97–1.26° in all four
    without; 20 replayed sessions, mean ATE 0.0946 → 0.0891 m.
  • The paper twin gate (CI, fixed seeds): explore 40 runs, 0 falls, mean
    coverage 53.2 %; go_to 30/30. 153 tests pass (1 ignored).

Build, install, run

The board's binary is attached to this release (quack-navd-aarch64-linux,
with its sha256), built by CI with scripts/cross-build.sh.

Follow the README: build, the configuration,
the systemd unit, and the paper twin. For the board (Radxa Zero 3,
aarch64, Debian 13), scripts/cross-build.sh cross-builds quack-navd
from a Mac or a Linux machine without Docker
(Building for the duck), and
scripts/install-on-duck.sh microduck@<duck> installs or upgrades it with its
systemd unit (Installing on the duck) —
tried in a systemd container, not yet on a board. The MuJoCo twin is in
scripts/twin/README.md.

Upgrading from 0.1.0

  • Knobs: every QUACKSAT_* environment variable is read only as
    QK_* — there is no alias. The knobs of concluded experiments are gone
    (removed names at the top of todo-map.md); a removed knob
    that is still set is ignored silently. The ones that exist are in
    knobs.md.
  • Sockets: quack-navd listens on /run/quack-nav/nav.sock (was
    /run/quack-nav.sock); with [maploc] enabled the map is on
    /run/quack-nav/map.sock. Callers (quacksat included) must follow.
  • Places: places_path defaults to /var/lib/quack-nav/places.json,
    and the old /var/lib/quacksat/places.json is not read any more: move it
    (scripts/install-on-duck.sh copies it across; the README has the command).
  • robotd: pinned to daemon-v0.14.4 (API 34). daemon-v0.15.0 is validated
    on the twin only on the branch microduck-015.
  • Config: [map] explore_turn still loads and does nothing.
  • Rust API: maploc::Mapper::boot_search, ExploreHandle::forget_ground,
    Grid::unknown_around, Control::request_method, the head limits in
    quack_duck::body and frontier::waypoint are gone; explore::Job::new
    is Job::new(known, max_s, ask, now), and to_goal, start and
    start_goto lost their turning-hand argument too.
  • Logs: maploc's status line has no boot field.
  • Twin viewer: QUACK_NAV_MCP / QUACK_NAV_MCP_TOKEN are gone; it asks
    QUACK_NAV_SOCKET.

Known limitations

  • Pose stalls in fast spins: during a fast spin in place the map pose
    can stay still for up to ~1.5 s, then catch up (seen on casa_arredata).
  • Phantom drops near holes: a rim booked with a bad pose lands 20–35 cm
    off the true one (about 1 in 50 drops); beside a hole that narrows a
    passage for the planner.
  • Slow wakes east of the apartment's stairwell: the windows refute a
    right seed for minutes.
  • The covariance is not an alarm yet: honest in the mean on a fresh map,
    too sure on a resumed one, and it did not flag a 0.35 m drift (σ 0.08 m).
  • Stop-and-scan mapping needs a guided tour: somebody has to walk the
    duck around with pauses; the tour is still to be designed.
  • CPU on the RK3566 is unmeasured, as are cell pitch and map extent on
    hardware; maploc is the most CPU-hungry thing the duck can do.
  • Journeys are slower than the earlier build's (median 106–111 s against
    66–101 s); "how far along" errs low; everything is twin-only. See
    results.md, known limits.

What v0.2.0 final needs

A first session on the real duck: the stack running on the RK3566 against
the released robotd, with the guards on and someone beside it, its numbers
written down beside the twin's.