Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions FORKING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# MicroDuck 2.0 proposal and fork policy

MicroDuck 2.0 is intended as an Apache-2.0 open-source derivative of
[`pollen-robotics/microduck`](https://github.com/pollen-robotics/microduck). Preserve upstream
copyright notices, the Apache-2.0 license, attribution in this file and an obvious distinction
between upstream MicroDuck and the proposed `microduck2` hardware family.

## Recommended repository arrangement

Create an organization-owned fork named `Magnexis/microduck` to retain a visible relationship with
upstream. Develop 2.0 on the `microduck2` branch and add the sister RL fork as
`Magnexis/microduck-rl`, also on a `microduck2` branch. Do not rename the upstream project in the
fork metadata; use the description “Magnexis proposal: MicroDuck 2.0 larger-body research branch.”

Keep `upstream` pointed at `https://github.com/pollen-robotics/microduck.git` and keep the fork's
default branch aligned with upstream. The `microduck2` branch then carries the new CAD, simulator,
hardware-profile and brain work without implying that it is maintained or endorsed by Pollen
Robotics.

## Before publishing

- Confirm the exact Magnexis GitHub organization slug and that it has a GitHub App installation
authorized to create repositories/forks.
- Review every uncommitted change, remove generated binaries and verify all license notices.
- Add `UPSTREAM.md` with the pinned upstream revision and a per-directory provenance table.
- Replace concept CAD and the primitive MuJoCo body with reviewed engineering artifacts before
describing the project as build-ready.
- Open a draft proposal issue or discussion upstream only after the public fork is available; link
it as an invitation for feedback, not as an endorsement claim.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ It also sits, kicks a ball, rolls forward on command, and quacks in a voice that
| [Cheat sheet](docs/robot/cheatsheet.md) | Every `robotctl` command: drive, configure, voice, chorale, theremin, wifi, updates, logs. Start here. |
| [Gamepad](docs/robot/cheatsheet.md#gamepad-configd) | The full button mapping, and pairing a pad — [once per pad](docs/robot/pair-a-gamepad.md), plus what to do when it will not bond. |
| [`duckctl`](docs/robot/duckctl.md) | The robot from a laptop over Bluetooth, with no network and no ssh. |
| `robotctl support bundle <directory>` | A read-only support bundle with health, versions and update history. Add `--include-logs` only after reviewing the privacy warning. |
| [Updates](docs/robot/cheatsheet.md#updates-updaterd) | Install, roll back, pin. Every update is verified, health-gated and reversible. |

### You are building on it
Expand All @@ -82,6 +83,7 @@ It also sits, kicks a ball, rolls forward on command, and quacks in a voice that
|---|---|
| [microduck_rl](https://github.com/pollen-robotics/microduck_rl) | Where the policies come from: MuJoCo, PPO, domain randomisation, and the ONNX export this repo loads. |
| [How it works](docs/design/architecture.md) | The whole system on one page — the daemons, the bus, how an update reaches a robot — then a page per part. |
| [MicroDuck 2.0 embodiment](docs/design/microduck-2-embodiment.md) | Proposed 15–20 in reference body, its new hardware profile, simulation and staged bring-up. Not a retrofit guide for the current duck. |
| [Set up a dev board](docs/robot/install-dev.md) | From a blank board to a robot that takes branch builds. |
| [Dev cheat sheet](docs/robot/cheatsheet-dev.md) | Branch builds, release candidates, driving from a laptop, and the restart traps after an update. |
| [Push your branch](docs/robot/dev-push.md) | Build on your machine, install over ssh, about a minute. |
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ own the mechanism is the bug.
| | |
|---|---|
| [`architecture.md`](design/architecture.md) | The service split, the IPC contract, state ownership, safety and authority. |
| [`microduck-2-embodiment.md`](design/microduck-2-embodiment.md) | Proposed 15–20 in reference body: mechanics, STM32WB55 safety/BLE supervisor, constrained NFC/RF design, hardware profile and staged validation. |
| [`robotd-design.md`](design/robotd-design.md) | The control loop: the Dynamixel bus and who owns the port, the model, sensing, observations, policy, safety — and what else hangs off the tick. |
| [`updater-design.md`](design/updater-design.md) | The update engine: verification, atomic swap, health gate, rollback, release format. |
| [`policy-channel-design.md`](design/policy-channel-design.md) | Where the ONNX policies come from: the `policies` component, trying someone else's, and what `reset` puts back. |
Expand Down
57 changes: 57 additions & 0 deletions docs/design/brain-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# MicroDuck 2.0 local behaviour brain

The existing neural policies are motor skills, not a general reasoning system. The 2.0 brain is a
separate, local deliberation layer that chooses goals and expressions from explicit evidence; it
may request an installed named skill but never writes joints, changes safety limits, or supersedes
a person holding the controller.

Initial expressions are `resting`, `curious`, `warm`, `recovering`, and `yielding`. The first
deployable body-language skills are episodic ONNX policies: `polite-bow`, `curious-tilt`,
`happy-bob`, and `settle`. Each must retain the 61D observation contract, be trained and exported
through `microduck_rl`, pass simulation rehearsal, and be added with `robotctl policy add`.

The brain must remain disabled from autonomous actuation until a perception adapter supplies
consented, local evidence and the authority gate confirms no human is controlling the robot.

## Mobility learning from mistakes

`robotd` now keeps a separate, persistent mobility memory at
`/var/lib/robot/mobility-memory.json` (override it with `--brain-memory`). A detected fall is
recorded immediately as an **unknown** incident with a non-blocking lock; saving happens once a
minute and on clean shutdown. An unreadable or schema-incompatible memory makes `robotd` refuse
to start rather than erase or replace the duck's prior evidence.

A future local perception adapter can label an incident or a verified safe passage as one of:
`low_obstacle`, `uneven_surface`, or `slippery_surface`. The learning rule is deliberately small
and auditable:

- one incident changes nothing;
- two matching incidents recommend `slow_and_scan`;
- three incidents plus two verified safe passages may only **consider** a separately reviewed
step-over policy.

The learner never modifies policy weights, gait gains, safety limits, or joint targets. In
particular, it cannot turn an unlabelled fall into a step-over attempt. That last step requires a
validated locomotion policy, simulation rehearsal, a current perception frame, and the normal
human-authority gate.

### Companion progress readout

The memory JSON is a local-first, read-only companion data contract. Its
`learning_readiness_percent` is derived from cue coverage (45 points), repeated observations
(35), and safe-passage reliability (20). It is a **mobility-evidence readiness** indicator, not
an intelligence, consciousness, or safety score. A mobile companion should display it as
“Mobility learning readiness” with the raw per-cue incidents and safe passages next to it; this
prevents a reassuring percentage from hiding thin or poor-quality evidence. No network listener
is opened by this feature, so a future phone app must use the existing authenticated/LAN robot
transport rather than exposing the memory file directly.

## Voice vocabulary

The voice bank is an expressive channel alongside body language, not a human-language model.
MicroDuck 2.0 adds `whistle` (a clean high contact call) and `warble` (a short three-note
conversational trill), plus `signal` (an original electronic companion call), to the existing
`robot.sound` tags. All are synthesized locally with the
same per-duck personality and randomized variants as every existing call. The behavior brain may
eventually select an affect-to-voice suggestion, but it cannot speak arbitrary text, transmit
audio, change volume limits, or bypass the normal `robot.sound` authority path.
11 changes: 11 additions & 0 deletions docs/design/cad/BOM-preliminary.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
assembly,part,quantity,status,notes
torso,structural torso shell,1,concept,Material and fastening method require mechanical review
pelvis,load-bearing pelvis frame,1,concept,Must carry both hip modules and protected battery bay
leg,leg cartridge,2,concept,Actuator/reduction family intentionally unselected
foot,compliant replaceable foot,2,concept,210 x 120 x 45 mm envelope; tread and force sensing TBD
compute,Linux compute module,1,architecture,Owns perception policy audio and robotd
supervisor,STM32WB55RG board,1,architecture,Safety IO BLE pairing signed supervisor firmware
nfc,ST25R3916 reader board,1,architecture,Signed owner/service tag reader only
rf,CC1101 receive-only regional daughterboard,0,optional,No transmit/replay/access-control functions
power,fused low-central battery pack,1,selection required,Electrical chemistry capacity and protection TBD
safety,physical emergency-stop chain,1,selection required,Must interrupt motor enable independent of Linux
25 changes: 25 additions & 0 deletions docs/design/cad/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# MicroDuck 2.0 CAD reference package

`microduck2_reference.scad` is the reviewable, parametric envelope model for the 45 cm reference
body. It has a switchable assembly, torso, leg, foot, head and electronics-tray view. It is useful
for checking scale, clearances, component placement and early enclosure discussions in OpenSCAD.

It is **not a fabrication release**. The geometry uses conservative primitives because there is no
approved actuator family, fastener stack, material specification, wiring harness, CAD mass model,
FEA result or physical qualification. The companion MuJoCo body is equally an integration model;
neither authorizes a build or a locomotion policy.

Before generating manufacturing drawings or STL/STEP releases, complete this package:

1. Select and bench-characterize the actuator and reduction system.
2. Replace every primitive with source-controlled CAD assemblies, mass properties and collision
geometry.
3. Freeze battery chemistry, BMS, fusing, service disconnect, emergency-stop and enclosure ingress
design.
4. Complete an electrical schematic/PCB layout with antenna keep-outs, regulatory review and EMC
test plan.
5. Produce drawing sheets with material, finish, tolerance, fastener torque, cable route and
inspection requirements.
6. Re-export the physical MuJoCo model and retrain all 2.0 policies from scratch.

`BOM-preliminary.csv` deliberately labels unresolved items instead of inventing purchasable parts.
109 changes: 109 additions & 0 deletions docs/design/cad/microduck2_reference.scad
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* MicroDuck 2.0 reference CAD
* SPDX-License-Identifier: Apache-2.0
*
* Parametric envelope and service-clearance model for the 450 mm reference chassis.
* This is deliberately NOT production geometry: it cannot be used to manufacture a walking robot
* until the structural frame, actuator selection, fasteners and every inertia value are approved.
* Open in OpenSCAD; set `part` to export an individual module for review.
*/

part = "assembly"; // [assembly:torso:left_leg:right_leg:foot:head:electronics_tray]

// ── design envelope, all dimensions mm ──────────────────────────────────────
standing_height = 450;
torso_l = 240;
torso_w = 170;
torso_h = 190;
hip_height = 285;
thigh_l = 150;
shin_l = 150;
foot_l = 210;
foot_w = 120;
foot_h = 45;
wall = 3.0;
clearance = 1.0;
mount_pitch = 50;

assert(standing_height >= 380 && standing_height <= 500, "Reference height must remain 380–500 mm");
assert(foot_w >= 110, "Foot support polygon is below the approved preliminary minimum");

$fn = 48;

module rounded_box(size, radius=10) {
hull() for (x=[radius, size[0]-radius], y=[radius, size[1]-radius], z=[radius, size[2]-radius])
translate([x,y,z]) sphere(radius);
}

module hole(d=4, h=20) { cylinder(d=d, h=h, center=true); }

module torso_shell() {
difference() {
color("gold") rounded_box([torso_l, torso_w, torso_h], 24);
translate([wall,wall,wall]) rounded_box([torso_l-2*wall,torso_w-2*wall,torso_h], 21);
// Removable electronics/service hatch on the back face.
translate([torso_l-45, torso_w/2-45, torso_h/2]) cube([60,90,110], center=true);
// Four supervisor-board standoffs: 50 mm square, M2.5 clearance.
for (y=[torso_w/2-mount_pitch/2, torso_w/2+mount_pitch/2], z=[70,120])
translate([20,y,z]) rotate([0,90,0]) hole(2.8, 20);
}
}

module pelvis_frame() {
color("dimgray") translate([35, 15, 0]) difference() {
cube([150,140,20]);
translate([25,20,-1]) cube([100,100,24]);
for (y=[25,115]) translate([75,y,10]) hole(5,30);
}
}

module leg(side=1) {
y = side * (foot_w/2 - 22);
// Segment axes are vertical in the neutral inspection pose. Actual joint stack is pending CAD.
color("silver") translate([85,y,hip_height-thigh_l]) cube([34,44,thigh_l]);
color("silver") translate([85,y,hip_height-thigh_l-shin_l]) cube([30,40,shin_l]);
color("black") translate([102,y,hip_height]) rotate([90,0,0]) cylinder(d=58,h=54,center=true);
color("black") translate([100,y,hip_height-thigh_l]) rotate([90,0,0]) cylinder(d=52,h=50,center=true);
color("black") translate([100,y,hip_height-thigh_l-shin_l]) rotate([90,0,0]) cylinder(d=48,h=48,center=true);
translate([0, y-foot_w/2+22, hip_height-thigh_l-shin_l-foot_h]) foot();
}

module foot() {
difference() {
color("goldenrod") rounded_box([foot_l,foot_w,foot_h], 14);
// Compliant sole pocket; leaves a 3 mm skin for an interchangeable tread.
translate([8,8,-1]) rounded_box([foot_l-16,foot_w-16,foot_h-3], 10);
// Toe/heel load-cell cavity; routing, connector and actual sensor are not yet specified.
for (x=[45,165]) translate([x,foot_w/2,foot_h/2]) hole(8, foot_h+2);
}
}

module head() {
color("gold") translate([85,torso_w/2,torso_h+85]) scale([1.25,1,1]) sphere(68);
color("orange") translate([175,torso_w/2,torso_h+78]) rotate([0,90,0]) cylinder(r1=18,r2=7,h=55);
// Head NFC loop and BLE antenna keep-out are indicated, not conductive geometry.
color("deepskyblue", 0.35) translate([100,torso_w/2,torso_h+85]) rotate([90,0,0]) cylinder(d=58,h=2,center=true);
}

module electronics_tray() {
color("seagreen") translate([20,35,35]) cube([110,100,3]);
// Keep RF parts away from power and motor harness. Blue = STM32WB supervisor, purple = NFC.
color("royalblue") translate([35,55,39]) cube([50,50,12]);
color("purple") translate([105,55,39]) cube([28,50,8]);
}

module assembly() {
torso_shell(); pelvis_frame(); electronics_tray();
translate([0,0,0]) leg(1); leg(-1); head();
// Floor and height datum make the 450 mm review envelope unambiguous.
color([0.18,0.2,0.24,0.35]) translate([-60,-110,0]) cube([360,390,3]);
color("red") translate([280,0,0]) cube([2,2,standing_height]);
}

if (part == "assembly") assembly();
else if (part == "torso") torso_shell();
else if (part == "left_leg") leg(1);
else if (part == "right_leg") leg(-1);
else if (part == "foot") foot();
else if (part == "head") head();
else if (part == "electronics_tray") electronics_tray();
Loading