Microduck: the Rust daemon stack behind a 25 cm biped robot
A Tiny biped duck robot 🦆
At a glance
- What is it?
- Microduck is a small biped robot whose brain lives in a Rust workspace of daemons on a Rockchip RK3566. This looks at what the repository actually contains, how the pieces talk to each other, and who should think twice before adopting it.
- Who is it for?
- Microduck is for people who already have the hardware or want to build on Pollen Robotics' daemon architecture: the workspace, the JSON-RPC contract and the simulation path are all in the repository. It is not for anyone looking for a general-purpose robot framework or a software-only project, since the README points buyers to the product page and the code assumes a specific board, fifteen servos and a trained ONNX policy.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Microduck solves, and for whom
The README is blunt about scope: "This repo is the duck's brain." That is the whole product definition. Microduck is about 25 cm and 800 g, and the repository is the software that runs on it, not a library you drop into another robot. The target reader is someone who owns a duck, or is building on one, and needs to drive it, configure it, update it, or replace the policy it runs.
The problem it addresses is a familiar one in small robotics: a control loop, a motor bus, radios, a camera and an update path that all have to coexist on one constrained board without turning into a monolith. The repository's answer is a workspace of one crate per service. robotd owns the 50 Hz control loop and the motor bus, driving fifteen servos from neural policies. updaterd installs signed releases and rolls them back when a robot comes up unhealthy. configd owns wifi and identity. btd is the Bluetooth path a phone uses. padd reads the gamepad. mediad streams the camera over WebRTC, and tofd serves the depth sensor.
That split is the interesting part, and it is the reason to read this repository even if you never buy the robot. Each concern is a separate binary with its own failure mode, and the update machinery treats an unhealthy boot as a rollback trigger rather than a support ticket.
One JSON-RPC contract across every daemon
The daemons talk over one JSON-RPC contract on Unix sockets. The README states that every client, whether it is the app, the console, the gamepad or your own script, sends exactly the same calls. That is a deliberate constraint, and it has a visible consequence: there is no privileged internal API that only the official app can reach. If you can write a client that speaks the contract, you have the same access as the shipped tooling.
The workspace layout reflects the service split. Cargo.toml lists members such as btd, configd, duck-ble, duck-control, duck-detect, duck-ether, duck-ipc-proto, duckctl, kinematics, mediad, odometry, pad-imu, padd, pet-detect, sounds, tof, updater, robotctl, robotd, robotd-params, test-support, uyvy and xtask. duck-ipc-proto is the shared contract crate, and duckctl is the Bluetooth client that talks to the robot from a laptop with no network and no ssh.
One detail in the root Cargo.toml is worth reading in full, because the comment explains a decision that would otherwise look arbitrary. The default-members list contains every crate except duckctl, and the comment says that exception "is the whole reason this key exists." The build command cargo board --bins, used in dev-push.sh and in the release workflow, builds every default member for aarch64. That is correct for a robot's daemons and wrong for a client a developer runs on their own machine, because it would cross-compile a Bluetooth stack for a board that must never see one, on the release path. The alternative was naming binaries explicitly at each --bins call site, and the comment notes there are two of them that would have to be kept in step by hand. Whether or not you agree with the choice, this is the kind of reasoning that is usually missing from robotics repositories.
Installing robotctl and driving the duck
The README does not present a single install command for a general-purpose machine. It points at the product page for buying a duck, and at docs/robot/install-dev.md for going "from a blank board to a robot that takes branch builds." The cheatsheet at docs/robot/cheatsheet.md is described as covering every robotctl command: drive, configure, voice, chorale, theremin, wifi, updates and logs. Start there rather than in the source tree.
For development, the documented workflow is to build on your own machine and install over ssh, which docs/robot/dev-push.md describes as taking about a minute. The workspace uses Cargo with resolver 3, so a normal build looks like this:
cargo build --workspaceA release build for the robot's aarch64 target is what the release workflow does, and the repository exposes it through the cargo board subcommand referenced in the Cargo.toml comment. Building every default member for the board is the intended path for daemons:
cargo board --binsThe root manifest also references ONNX Runtime, which robotd dlopens to run a policy. The comment states that xtask package bakes the ONNX Runtime sources into the release's preinstall hook, and that a test asserts scripts/setup-board.sh agrees with them, so that there is one source of truth rather than two copies that drift.
If you have no robot on the desk, the README points at scripts/duck-sim, which runs the real daemons against a body in MuJoCo. The documentation describes two modes: one duck in a window, or four as machines you log into. That is the cheapest way to confirm the daemons start and the contract answers before touching hardware.
Updates are health-gated, and that shapes everything else
The update path is the most opinionated part of the design. updaterd installs signed releases and rolls them back when a robot comes up unhealthy. The README's summary of the updates documentation is that every update is verified, health-gated and reversible, and it lists install, roll back and pin as the operations that matter.
That health gate is not a nicety. A robot that walks on two legs has a narrow window between "booted" and "useful," and a bad policy or a bad daemon can leave it unable to stand, let alone accept a new image. Making rollback automatic turns a bricked duck into a reboot. The dev cheat sheet is said to cover restart traps after an update, which suggests that the boundary between a healthy and an unhealthy boot is not always obvious in practice, and that the documentation treats those traps as a known category rather than an edge case.
The design pages live under docs/design/, and the README frames them as why things are the way they are, while docs/project/ is "what has gone wrong and what would close it." That second directory is unusual to see in a public robotics repository, and it is the honest half of the documentation. If you are evaluating whether to build on this stack, read docs/project/ before docs/design/, because the open problems tell you more about the current state than the architecture diagrams do.
Where Microduck is the wrong tool
The repository is not a general robotics framework, and treating it as one will waste your time. The control loop is built around fifteen servos and a specific body. The policies come from microduck_rl, which the README describes as MuJoCo and PPO, a sim2real recipe, and an export to ONNX that this repository loads. If your robot has a different kinematic chain or a different number of joints, the kinematics crate and the policy interface are written for this duck, not for a family of robots.
The hardware dependency is real. The daemons run on a Rockchip RK3566, and the build configuration targets aarch64 for the board. Nothing in the README suggests the stack is meant to run on a desktop as a product, only that scripts/duck-sim lets you run the daemons against a simulated body for development. If you want a software-only reinforcement learning project, microduck_rl is the closer fit, since that is where training happens.
There is also a question the README does not answer: what happens to a robot whose owner wants to run a policy the project has not trained. The ONNX export path is documented as the interface, and the simulation path exists, but the README does not walk through replacing a shipped policy with your own on real hardware. That gap is worth confirming with the documentation before committing to the platform.
How it differs from a monolithic robot stack
The obvious alternative is a single-process robot application: one binary that owns the control loop, the camera, the radios and the update logic, with internal function calls instead of a wire protocol. That design is simpler to start and much harder to reason about once one subsystem stalls. Microduck takes the opposite approach, and the cost is visible in the workspace: twenty-odd crates, a shared protocol crate, and a build configuration that has to know which members belong on the board and which belong on a laptop.
The payoff is that each daemon can fail, restart or be replaced on its own terms, and the same JSON-RPC contract serves the app, the console, the gamepad and your script. A monolith would not give you duckctl, the Bluetooth client that reaches the robot from a laptop with no network and no ssh, because there would be no stable interface to reach it through.
If you are comparing this to a framework like ROS, the difference is scope rather than mechanism. Microduck does not try to be a middleware layer for arbitrary robots. It is one robot's software, written down in enough detail that you can read the reasoning. The trade is that you get a coherent system with real documentation, and you give up generality.
Maintenance, licensing and what to verify
The repository is not archived, and the last push was on 2026-09-17. The most recent release listed is daemon-v0.14.0, dated the same day, alongside a dev-main build and a dev branch build for a typed policy spec. That release cadence, with tagged releases and separate dev channels, is the practical answer to upgrade cost: you can track a stable tag or a branch build, and the dev cheat sheet is documented as covering branch builds and release candidates.
The licence is Apache-2.0, which is permissive and includes an explicit patent grant. That matters if you intend to ship a product containing this code. It does not, however, tell you anything about the hardware, the trained policies, or the Microduck name, and the repository does not address those. If you plan to redistribute a modified daemon, read the LICENSE file and, where the stakes are high, get proper advice rather than treating a licence identifier as a complete answer.
Before adopting, verify three things in this order. Read docs/design/architecture.md for the daemon split and the bus, since that is the document the README calls the whole system on one page. Confirm which release tag you are tracking and whether the dev channel is appropriate for your hardware. Then check microduck_rl for the ONNX export interface, because that is the boundary between the policy you train and the daemon that runs it.
Editorial conclusion
Microduck is for people who already have the hardware or want to build on Pollen Robotics' daemon architecture: the workspace, the JSON-RPC contract and the simulation path are all in the repository. It is not for anyone looking for a general-purpose robot framework or a software-only project, since the README points buyers to the product page and the code assumes a specific board, fifteen servos and a trained ONNX policy. Before adopting it, read docs/design/architecture.md for the daemon split, confirm which release tag you are tracking, and check whether microduck_rl exposes the policy export you need.
Frequently asked questions
What are micro ducks for?
Microduck is a small biped robot, about 25 cm and 800 g, that moves using reinforcement learning policies. The repository is the software that runs on it: a 50 Hz control loop driving fifteen servos, plus radios, a camera and the update machinery. The README points people who want one at the Pollen Robotics product page.
Who are the big 4 in robotics?
The repository does not discuss robotics companies or market rankings. It covers one robot: its daemons, its build configuration and its release workflow.
How much does a lifelike robot cost?
The repository does not list a price. The README directs readers to the Pollen Robotics product page for Microduck, and that is the only place the material points for purchasing information.
Are microbots a real thing?
Microduck is a real product rather than a concept: the README describes a robot of about 25 cm and 800 g running on a Rockchip RK3566, and the repository contains the daemons, the build configuration and the release workflow. The README also links to a page where you can buy one.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pollen-robotics-microduck)