Technical Reference
Deep technical detail for instructors and technically knowledgeable reviewers: ROS 2 concepts, the motion node, full servo controller mapping, power architecture, audio architecture, and RealSense reference. For a lighter overview see the public Robot page.
ROS 2 concepts
Node — a program that does one part of the robot's work: a camera node reads vision data, a motion node controls joint movement, a demo script decides what behavior to run.
Topic — a named stream of information that one part of the robot publishes and another subscribes to.
Publisher / Subscriber — a publisher sends information onto a topic; a subscriber listens for it and reacts.
Service — a request-and-response interaction, such as requesting a safe motion or checking system status.
Launch file — starts multiple nodes together in one workflow instead of many manual terminals.
Behavior script — decides what the robot should do, such as the Wave demo sending a sequence of arm movements to the motion system.
Motion node
The motion node is the single software layer permitted to send final commands to the servo controllers and base motor system — see the full architecture on the Safety page. A behavior does not throw raw values at every servo; it requests safe poses, joint groups, or controlled movement sequences, and the motion node enforces limits before anything moves.
If two behaviors try to control the same arm at once, motion can become confusing or unsafe. A motion lock prevents this: a Wave script can request the right arm; a Handshake script can request the same arm; the system does not allow both to command it at the same time.
Servo controller mapping
SwayForm uses two Adafruit PCA9685 16-channel PWM controllers on the I²C bus (12-bit resolution, 50Hz default). Controller 0x40 uses all 16 of its channels; controller 0x41 uses 4 of its 16, leaving 12 free for future expansion. The waist rotation is not a PCA9685 channel — it is a DC motor with encoder feedback, powered directly from the 12V bus.
| Joint | ROS name | Controller | Ch | Min | Max | Neutral | Servo |
|---|---|---|---|---|---|---|---|
| Neck Yaw | neck_yaw | 0x40 | 0 | −45° | +45° | 0° | MG996R |
| Neck Pitch | neck_pitch | 0x40 | 1 | −20° | +25° | 0° | MG90S |
| R. Shoulder Pitch | right_shoulder_pitch | 0x40 | 2 | −10° | +90° | 0° | MG996R |
| R. Shoulder Roll | right_shoulder_roll | 0x40 | 3 | −30° | +20° | 0° | MG996R |
| R. Elbow | right_elbow | 0x40 | 4 | −120° | 0° | −10° | MG996R |
| R. Wrist | right_wrist | 0x40 | 5 | −45° | +45° | 0° | MG90S |
| R. Thumb | right_thumb | 0x40 | 6 | 0° | +70° | 15° | MG90S |
| R. Index | right_index | 0x40 | 7 | 0° | +90° | 15° | MG90S |
| R. Middle | right_middle | 0x40 | 8 | 0° | +90° | 15° | MG90S |
| R. Ring | right_ring | 0x40 | 9 | 0° | +90° | 15° | MG90S |
| R. Pinky | right_pinky | 0x40 | 10 | 0° | +80° | 15° | MG90S |
| L. Shoulder Pitch | left_shoulder_pitch | 0x40 | 11 | −10° | +90° | 0° | MG996R |
| L. Shoulder Roll | left_shoulder_roll | 0x40 | 12 | −20° | +30° | 0° | MG996R |
| L. Elbow | left_elbow | 0x40 | 13 | 0° | +120° | 10° | MG996R |
| L. Wrist | left_wrist | 0x40 | 14 | −45° | +45° | 0° | MG90S |
| L. Thumb | left_thumb | 0x40 | 15 | 0° | +70° | 15° | MG90S |
| L. Index | left_index | 0x41 | 0 | 0° | +90° | 15° | MG90S |
| L. Middle | left_middle | 0x41 | 1 | 0° | +90° | 15° | MG90S |
| L. Ring | left_ring | 0x41 | 2 | 0° | +90° | 15° | MG90S |
| L. Pinky | left_pinky | 0x41 | 3 | 0° | +80° | 15° | MG90S |
| Waist Rotation | waist_yaw | — (12V direct) | — | −60° | +60° | 0° | DC+encoder |
A wrong mapping can make the wrong joint move — edit servo mapping carefully, and re-verify against this table after any repair.
Power architecture
One 12V/50A power supply feeds a central bus bar with four outgoing paths:
- A buck converter stepping down to 5V for the Raspberry Pi
- A direct 12V line to the base-rotation DC motor (no converter)
- A buck converter to 6V servo rail A (includes the neck motors)
- A buck converter to 6V servo rail B
The two 6V servo rails are separately regulated — not galvanically isolated — so current spikes from motors are dampened before they reach the Pi's dedicated 5V rail. Both PCA9685 controllers draw power from the two 6V rails and receive position commands over a separate I²C signal path.
Final current protection, fuse sizing, and conductor ratings will be validated before classroom release. This is not yet an absolute current-safety claim.
Audio architecture
The Raspberry Pi 5 has no built-in analog audio output. The signal path is: Raspberry Pi 5 → USB audio adapter → 3.5mm analog connection → PAM8403 amplifier (separately powered) → 3W speaker. Software uses pyttsx3 for text-to-speech and pygame.mixer for clips, triggered via the /swayform/audio_command topic.
RealSense camera
The Intel RealSense D435i publishes synchronized color and depth image streams (color at 640×480, depth per pixel in millimeters, minimum range roughly 0.3m) over USB. Learning Hub use cases: detecting that someone is in front of the robot, checking whether an object is in a target zone, turning the head toward a left/center/right region, and starting a behavior when a condition is met.
Camera-assisted does not mean perfect. Students should learn how vision can fail, why thresholds matter, and why robots should move conservatively near people.