craigm26 / craigm26/OpenCastor

The bigger robot: Pi 5 host with a pair of SO-ARM101s (bimanual)

Open
#946 0 comments 0 reactions 0 assignees View on GitHub
intelligence marathon-2026-08-15
Dominant language
Python
Stars
28
Forks
5
PR merge metrics
No merged PRs in 30d

Description

## The fleet, as the operator named it (2026-08-17)
- **Rover v2 (small)**: ESP32-C6 host + Maestro (ordered, Pololu #1350) + RC car + mounted iPhone running a LOCAL on-device model, always listening. No Pi anywhere. The phone is the brain; the board is the contract. (#941 carries the build.)
- **The bigger robot (this issue)**: a new platform hosting the Pi 5 and a PAIR of SO-ARM101 arms — bimanual manipulation on the full OpenCastor host (castor up, console, local Ollama brains, memory recall, gap rail).

## What the Pi 5 brings that the MCU class cannot
Local models (qwen chat, gemma vision, nomic memory), the console with recall-grounded chat, the gap rail, SmolVLA serving when #940 matures — the intelligence tier. The rover donates its Pi when v2 ships.

## Known constraints, written down before they bite
- **The multi-actuator rule (standing, from the host-config rail):** do NOT flip the gateway to multi-actuator dispatch before clients send `actuator_name` — it 422s every existing caller. Two arms means two actuators; the migration order is: app sends `actuator_name` first, gateway accepts-and-ignores, THEN the flip.
- Two arms on one servo-bus story needs deciding: two Feetech buses vs one bus with ID ranges; the safety bridge (castor/hardware/so_arm101/safety_bridge.py) currently assumes one arm's joint map.
- Bimanual is where SmolVLA (#940) stops being optional — teleop demo recording for two arms, phase 1 unchanged.
- Bob's wrist/OAK-D cameras are still physically unplugged; the bigger robot inherits that checklist.

## First milestones
1. Second SO-ARM101 acquired + both arms enumerated on the bench
2. `actuator_name` threading end to end (app -> gateway -> dispatch), single-arm behavior byte-identical until the flip
3. Dual-arm manifest: capabilities namespaced per arm (arm.left.* / arm.right.* or actuator-qualified), declared via the gap rail
4. One signed action moving each arm independently, receipts distinguishing them

Contributor guide

Open the contributing guide

Research direction

Start with castor/hardware/so_arm101/safety_bridge.py and the host-config rail, then trace actuator_name through the app, gateway, and dispatch paths. The work is done when both arms are enumerated, single-arm behavior remains unchanged, capabilities are namespaced in the gap rail, and signed actions produce distinct receipts for each arm.

Written by the indexing model from the issue text.

Assessment

Tech stack
ollama, python, raspberry-pi
Domain
ai, embedded-iot, robotics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.