James Harton James Harton

Week Six: Balance Bots and Better State Machines

Teaming up with Protolux on a Nerves balance bot, command categories with concurrency limits arrive, mechanically-linked joints get their own sensor, and the docs get a proper structure.

Holiday's over. Back to the day job. But somehow I still managed to ship two feature releases, a bug fix, and sort out the documentation. Not bad for a short week.

Also, happy Wellington Anniversary Day to me. Nothing says "public holiday" like writing release notes.

Nerves Starter Kit Balance Bot

The most exciting news this week isn't a package release - it's a collaboration.

I've started working with Gus Workman from the Nerves Core Team. He's the founder of Protolux and is finalising the design for the Nerves Starter Kit - think of it as a spiritual successor to those name tag boards from last year's Goatmire/NervesConfEU, but with a larger e-ink display, a much smaller board, and more IO broken out for tinkering.

We're collaborating on a simple add-on: two gear motors and an 18650 battery holder to convert the Starter Kit into a balance bot. The idea is to create something approachable for workshops and getting-started videos. A balance bot is just complex enough to be interesting (sensor fusion! PID control! falling over!) without being overwhelming.

More details as the hardware design solidifies. But if you've ever wanted to see Elixir keeping a robot upright, this should be fun.

Command Categories and Concurrency

BB v0.15.0 introduces command categories with configurable concurrency limits.

The problem: robots often have independent subsystems. Your gripper shouldn't have to wait for the arm to finish moving. But the old system ran one command at a time, full stop.

The solution: define categories inside your commands block, each with its own concurrency limit.

commands do
  category :motion do
    doc "Physical movement commands"
    concurrency_limit 1  # Only one motion at a time
  end

  category :sensing do
    doc "Sensor and data collection"
    concurrency_limit 2  # Can run two sensing ops concurrently
  end

  command :move_to do
    handler MoveCommand
    category :motion
    cancel [:motion]  # New motion cancels previous motion
  end

  command :read_sensor do
    handler ReadSensorCommand
    category :sensing
  end
end

The rules are straightforward:

  • Different categories = parallel: A :motion command and a :sensing command run simultaneously
  • Same category = limited by concurrency_limit: If you try to run a second :motion command (limit 1), it either cancels the first (if cancel: [:motion]) or fails with a "category full" error
  • No category = uses :default: The implicit default category has limit 1, preserving backwards compatibility

This is groundwork for mobile manipulators, multi-arm systems, data collection robots - anything where "one thing at a time" doesn't cut it.

Mimic Sensor for Linked Joints

BB v0.14.0 adds BB.Sensor.Mimic for mechanically-linked joints.

Some robot designs have joints that are physically connected - when one moves, the other follows. The WidowX-200's gripper works this way: two prismatic fingers driven by a single servo. You could model them as separate actuators and hope they stay in sync, but that's asking for trouble.

BB.Sensor.Mimic subscribes to one joint's position and publishes matching JointState messages for the mirrored joint. The kinematic chain stays accurate, and you don't have to pretend the linkage doesn't exist.

sensor :right_finger, {BB.Sensor.Mimic,
  source: :left_finger,
  multiplier: -1.0  # Mirror direction
}

Simple, but necessary.

Feetech Sign-Magnitude Fix

Remember when I said the Feetech driver was buggy? One bug down.

feetech v0.2.1 fixes sign-magnitude encoding for signed registers. Turns out Feetech servos don't use two's complement for negative values - they use a sign bit in the high byte. So when you asked for a negative velocity, you got... not what you expected.

The SO-101 now moves in the directions I tell it to. Progress.

Documentation Gardening

All three packages (bb, bb_kino, bb_liveview) got a documentation tidy-up this week.

We've always used the Diataxis framework - tutorials, how-to guides, reference, explanation - but when you only have a handful of pages it doesn't matter much where things go. As the framework grows, so does the documentation, and keeping it organised becomes like gardening: constant small efforts to stop the weeds taking over.

This round added new tutorials, filled in some reference gaps, and shuffled things into their proper categories. Still plenty of gaps to fill, but at least the beds are tidy.

Proposals Update

The six proposals from last week are now merged into the proposals repo - bb_teleop, bb_policy, bb_dataset, bb_mcp, bb_tui, and bb_motion_planning are all accepted designs waiting for implementation.

Two new proposals are open for discussion:

Proposal 0007: Usage Rules (new) - A standard way to include LLM-friendly documentation in packages. If you've used usage-rules.md files before, this formalises the approach.

Proposal 0008: bb_mavlink (new) - MAVLink protocol integration for drones and other autonomous vehicles. This one's ambitious, but MAVLink is the lingua franca of the drone world.

SO-101 Status

The arm works. The example code exists. But I'm not ready to encourage people to build one just yet.

Feetech servos have some quirks. For instance, they have a tendency to enable torque the moment you write a new configuration. That's... not ideal when you're trying to set limits before powering up. I want to make sure the getting-started experience is smooth before pointing people at it.

Soon.

All The Releases

Since January 12th:

PackageVersionWhat changed
bbv0.15.0Command categories with concurrency limits
bbv0.14.0BB.Sensor.Mimic for mechanically-linked joints
bbv0.13.2Bridge name uniqueness enforcement in DSL verifier
feetechv0.2.1Sign-magnitude encoding fix for signed registers
bb_kinov0.3.3Documentation improvements
bb_liveviewv0.2.4Documentation improvements

What's Next

Getting the SO-101 experience polished remains the priority. Once that's solid, I can start making videos that don't require a $2000 robot arm.

The balance bot collaboration with Gus is exciting, but it's hardware-dependent - we need the Starter Kit design locked down first.