Skip to content
SoftwareOfficial source

MicroDuck 0.17.1: UDP Gamepad, New Defaults and Recovery

On October 13, GitHub marked daemon 0.17.1 as the latest stable MicroDuck release; it was published October 12. From 0.16.2 onward, X/Y/LB/RB are unbound by default; 0.17.0 adds an optional UDP gamepad for a trusted LAN, and duckctl can run from a laptop through uvx. Check your running version, overrides and policy slot before changing anything.

Pollen Robotics released stable daemon 0.16.2 at 12:28 UTC, 0.16.3 at 12:35, 0.17.0 at 13:11 and 0.17.1 at 14:22 on October 12, 2026. GitHub latest pointed to 0.17.1 at this October 13 review. This site checked the releases and fixed source; it did not update or drive a physical robot.

Which release brought which change?

Stable changes after 0.16.1
ReleaseUser-visible changeWhat to verify
Official stable daemon 0.16.2 · October 12 ↗LB/RB kicks are no longer default bindings; X/Y/LB/RB are free for skills. The default forward/back command range becomes ±0.4 m/s, yaw ±1.0 rad/s; fall limp is enabled by default. The seed script points at policy-set v8.Those are configuration defaults and command bounds, not measured speed or proof that your installed policy changed. Local overrides persist.
Official stable daemon 0.16.3 · October 12 ↗Corrects a PyPI package classifier for duckctl.This is a packaging correction, not an additional motion feature.
Official stable daemon 0.17.0 · October 12 ↗Adds opt-in netpadd: a laptop gamepad can send pad state over UDP on a trusted LAN.It is disabled by default and switches off the Bluetooth pad daemon while enabled.
Official stable daemon 0.17.1 · October 12 ↗Suppresses the alert for a sub-second pad drop. duckctl udp-pad can discover a named robot without an IP; macOS Y is flipped by default.A sustained loss still follows the deadman/sit path. Check the running daemon version and pad orientation.

The older 0.16.1 guide accurately describes that release, when LB/RB were kicks. On 0.16.2 and later, inspect robotctl pad bindings before expecting any bumper action; manually set bindings can differ. The 0.16.2 velocity values are requested command limits, not a measured top speed. Pinned 0.17.1 gamepad and update reference ↗ Pinned robotd defaults and safety parameters ↗.

Save the running state before an upgrade.

Read-only robot baseline
robotctl version
robotctl update status
robotctl update check daemon
robotctl configure --list
robotctl pad bindings
robotctl policy list
robotctl policy check
robotctl health

update check daemon checks the stable source without installing. Keep the board-specific version, local configuration, actual pad bindings and the policy list together. A preorder with no robot has no daemon to update. Pinned 0.17.1 gamepad and update reference ↗.

Use duckctl from the laptop when useful.

Pollen Robotics publishes duckctl 0.17.1 for Linux, macOS and Windows. With uv already installed, uvx duckctl --name ROBOT_NAME info runs the packaged client; this is a laptop command, not a daemon install on the robot. The optional UDP pad can use a literal robot IP without Bluetooth discovery:

On the laptop, replace the example IP
uvx duckctl udp-pad 192.168.1.42

Without an IP, uvx duckctl --name ROBOT_NAME udp-pad resolves the robot through Bluetooth; DUCK_ROBOT can select a robot too. On macOS 0.17.1 already flips Y by default; add --invert-y only if the actual stick direction is still wrong. This site verified package publication and source, not a pad connection. Pinned duckctl installation and laptop commands ↗ Published duckctl package and platform wheels ↗.

Enable UDP only on an official compatible robot and a trusted LAN.

UDP control is off by default. Its port 4210 binds IPv4 on all interfaces when enabled, without authentication or encryption. Anyone who can reach it may drive or power off the robot. It is not a remote-internet control path. On the robot, use sudo robotctl configure to set netpad.enabled = true, save and accept its plan to restart both pad daemons. If you edited the file manually or skipped that apply step, run the restart yourself; do not interrupt the pad twice without a reason: Pinned robotctl configure apply and service restart behavior ↗.

Only if configure did not apply: restart, then check
sudo systemctl restart padd netpadd
systemctl is-active padd netpadd

In the check output, padd should be inactive and netpadd active. If configure already applied its restart, run systemctl is-active padd netpadd without the extra restart. The setting survives reboot and software update until switched off. To restore Bluetooth, set netpad.enabled = false with sudo robotctl configure and accept the two-service apply plan (or manually restart both only if it was skipped); expect active/inactive in that order. If neither service starts, inspect the journal:

Diagnose the pad daemons
systemctl is-active padd netpadd
journalctl -u netpadd -b -n 80

CONNECTED means this sender is accepted; REFUSED means another sender owns the robot. With no pad, duckctl sends nothing. Ctrl-C ends sending; the robot stops after the configured deadman timeout and then attempts to sit about a second later if standing. That is delayed software behavior, not an instant physical stop guarantee. The network timeout defaults to 250 ms and must be below the robot deadman setting; avoid changing it without reading the documented bounds. Pinned 0.17.1 UDP pad setup, trust boundary and recovery ↗.

Update the daemon and the policy set as separate decisions.

If the stable checker offers a board-compatible daemon, support the robot, keep power stable and allow services to restart. Install intentionally, then compare the running version, bindings, policies and health with the saved baseline:

Install an available stable daemon
sudo robotctl update apply daemon
Check what is actually running
robotctl version
robotctl pad bindings
robotctl policy list
robotctl health
robotctl update log
robotctl update show

The seed script switched its default policy tag to v8 in 0.16.2, but the official policy set versions independently. Check robotctl policy check and policy list; a manually loaded walk slot remains an override after an official set update. The v8 velstand manifest reports smoother fall recovery and better yaw tracking, while the RL author still reports weak or bursty turning at 0.3 rad/s. Neither statement is a measurement by this site. Pinned official policy seed script ↗ Official policy-set manifest at fixed v8 revision ↗ Pinned RL velstand v8 development and limits ↗.

If the daemon update fails, read update show and update log first. Manual rollback requires a previous daemon release already installed on that board; it does not restore a separately updated policy set:

Rollback only when a previous daemon is installed
sudo robotctl update rollback daemon
robotctl version
robotctl health

Where to go next.

CONTINUE THE CONVERSATION

What would you like to understand next?

Keep the source, your environment and your observations together.