Control Library for Ducks
 
Loading...
Searching...
No Matches
PuddleDuck

Introduction

PuddleDuck provides a safe, extensible, hardware-aware API for controlling high-torque robotic actuators. It is the foundation layer for Duckling droids and related projects, handling everything from bus management to motor safety.

PuddleDuck

Key features

  • Safety framework for high-torque motors
  • Joints described declaratively in YAML
  • Normalized joint position interface (-1.0, 0.0, 1.0)
  • Support for degrees/radians position
  • Support for inverted joints
  • Runtime updates of joint limits
  • Protection against invalid or dangerous commands
  • Built-in motion capture support

Supported motors

  • Unitree Go series (Go1, Go2)
  • Unitree Uki series (A1, B1)
  • Cybeargear (in progress)
  • Dynamixel

Host utilities and Teensy firmware targets live under src/tools and are built via the top-level Makefile:

  • CMake + Ninja for host tools (macOS, Linux)
  • PlatformIO for Teensy 4.0 firmware

Quick start

Host utilities (macOS/Linux)

git clone https://github.com/openbiped/PuddleDuck
cd PuddleDuck
make
# Binaries: .build/<triple>/<BUILD>/

Teensy firmware (build + upload)

git clone https://github.com/openbiped/PuddleDuck
cd PuddleDuck
make puddleduck UPLOAD=1 VERBOSE=1

Prerequisites

  • CMake (≥ 3.20 recommended)
  • Ninja
  • Python 3
  • PlatformIO Core CLI (pio)
  • C/C++ toolchain:
    • macOS: Xcode/clang
    • Linux: gcc or clang
  • (Optional) Google Chrome for auto-opening docs
  • (Optional) For building protoc libtools and autoconf are required
  • (Optional) For building documentation doxygen is required

Build variables

  • BUILDdebug (default) or release
  • VERBOSE=1 — pass -v to Ninja/PlatformIO
  • UPLOAD=1 — upload firmware after a successful build
  • DUCK_CONFIG=<name> — select a non-default duck configuration
  • MAIN=<symbol> — define -DPUDDLEDUCK_MAIN=<symbol> for firmware
  • Cross-compile host utilities with TOOLCHAIN=<path/to/toolchain.cmake>

Examples:

make BUILD=release
make VERBOSE=1
make puddleduck UPLOAD=1
make TOOLCHAIN=toolchains/linux-armv7.cmake

Host build outputs:

.build/<triple>/<BUILD>/
e.g. .build/x86_64-unknown-linux-gnu/debug/

Teensy / PuddleDuck firmware

PuddleDuck uses PlatformIO for Teensy 4.0 targets. The Makefile patches Teensy USB headers when needed.

Common targets:

  • make teensy — minimal Teensy environment build
  • make puddleduck — full firmware (builds runtime wheels, patches Teensy, compiles)
  • make puddleduck-usb — USB-oriented firmware
  • make puddleduck-v1-usb — revision 1 USB firmware

Flash after build:

make teensy UPLOAD=1 VERBOSE=1
make puddleduck-usb UPLOAD=1 VERBOSE=1

Duckling install over SSH

  • SSH_UPLOAD_USER — defaults to duck
  • SSH_UPLOAD_HOST — defaults to duckling

Example:

SSH_UPLOAD_USER=duck SSH_UPLOAD_HOST=duckling.local \
make puddleduck UPLOAD=1 VERBOSE=1

Runtime wheels (Python)

Build both CPU and GPU wheels:

make runtime

Or individually:

make runtime-cpu
make runtime-gpu

Artifacts are written to runtime/dist .

Selecting a custom duck configuration

Using local.ini (recommended)

cp configs/puddleduck/default.ini configs/puddleduck/local.ini
cp configs/puddleduck/default.yaml configs/puddleduck/myduck.yaml
sed -i 's/default/myduck/g' configs/puddleduck/local.ini
make puddleduck VERBOSE=1

Using DUCK_CONFIG

cp configs/puddleduck/default.ini configs/puddleduck/myduck.ini
cp configs/puddleduck/default.yaml configs/puddleduck/myduck.yaml
sed -i 's/default/myduck/g' configs/puddleduck/myduck.ini
DUCK_CONFIG=myduck make puddleduck VERBOSE=1

Configuration (default)

The YAML defines buses, joints (safe ranges & gains), sensors, and scripts:

  • Control loop: frequency (Hz), optional dt, cutoff
  • Buses: RS485, SBUS, I2C, TTL (baud, adapter, timeouts)
  • Armatures with joints:
    • type (e.g., Go1, UkiA1, Dynamixel)
    • id and optional bus override
    • Safe range (e.g., [!deg -118, !deg 118])
    • Gains: kp, kd (and ki for Dynamixel)
    • Optional start or zero; optional:true for headless testing
  • Sensors: e.g., QuackHead, BN085 IMU, GoBMS
  • Policy: named joint groupings
  • Scripts: named step sequences (name, target pos, duration)

Example Duck configuration

# Go1/Uki Duckling
frequency: 400
cutoff: 37.5
...

This example shows buses, joint definitions with safe ranges and gains, policies grouping joints, and a simple script (stand) with step timings.

Motion mapping cheatsheet

Normalized command conventions (from default config):

  • head_neck_pitch: 0→1 back, 0→−1 front
  • head_pitch: 0→1 down, 0→−1 up
  • head_yaw: 0→1 left, 0→−1 right
  • head_roll: 0→1 list left, 0→−1 list right
  • hip_rotation_left: 0→1 inward, 0→−1 outward
  • hip_abduction_left: 0→1 outward, 0→−1 inward
  • hip_flexion_left: 0→1 backward, 0→−1 forward
  • thigh_joint_left: 0→1 knee contracts, 0→−1 knee extends
  • toe_joint_left: 0→1 heel up, 0→−1 heel down
  • hip_rotation_right: 0→1 outward, 0→−1 inward
  • hip_abduction_right: 0→1 inward, 0→−1 outward
  • hip_flexion_right: 0→1 forward, 0→−1 backward
  • thigh_joint_right: 0→1 knee extends, 0→−1 knee contracts
  • toe_joint_right: 0→1 heel up, 0→−1 heel down

Makefile targets

Documentation

Generate Doxygen:

make documentation

Cleaning

Clean artifacts:

make clean