Learn robotics by running a real humanoid system.

SwayForm Learning Hub gives students demos, labs, setup guides, and code walkthroughs for learning Python, ROS 2-style architecture, RealSense vision, servo control, and physical robot behavior.

Start by running a safe provided demo. Then inspect the code, modify it, and build your own robot interaction.

Recommended first
New Students
Start here if this is your first time using SwayForm. Learn what the hub is, how the robot is controlled, and how to move from demos into editable labs.
Begin Orientation →
5 ready demos
Demo Code
Run finished example behaviors like waving, vision-assisted handshake, look-and-point, rock-paper-scissors, and the tabletop snack exchange demo.
Browse Demos →
10 ready labs
Student Labs
Use guided activities to edit motion code, test safe joint limits, create gestures, use camera triggers, and build simple robot behaviors.
Open Labs →
Setup guide
Setup & Troubleshooting
Connect through VS Code and SSH, open the robot workspace, run ROS 2 commands, and fix common beginner issues.
View Setup →

SwayForm Learning Hub

The Learning Hub is the student-facing home for SwayForm demos, labs, setup guides, and code walkthroughs. It is designed so students can go from running a provided robot behavior to understanding how that behavior works, editing it safely, and building their own interaction.

Instead of learning robotics only through slides or simulations, students work with code that creates real motion. A script can turn the head, move an arm, open a hand, respond to camera input, or run a complete tabletop demo. Every activity connects a programming idea to something the robot physically does.

Current hub status

5 ready demo programs
5 future demo placeholders
10 ready student labs
10 future lab placeholders
VS Code and SSH setup workflow
RealSense, motion, and servo-control examples

Recommended first path

If you are opening the Learning Hub for the first time, follow this order.

1
Read
2
Complete
3
Run
4
Complete
5
Try

For instructors

Instructors can use the ready labs as structured classroom activities and use the coming-soon slots as placeholders for future course material. The hub is built so a class can begin with safe provided demos, then move toward editable code and student-created behaviors.

The goal is not to memorize robotics terms. The goal is to understand what the system is doing.
/Start Here/What SwayForm Teaches

What SwayForm Teaches

SwayForm is built around the idea that robotics makes more sense when students can see code turn into physical motion. The Learning Hub introduces programming, control, vision, and system design through real robot behaviors.

Programming through robot behavior

Students use Python to define poses, trigger motions, adjust timing, and create behavior sequences. Instead of writing code that only prints output to a terminal, students write code that moves a physical system.

ROS 2-style system thinking

The hub introduces robotics software concepts such as nodes, topics, publishers, subscribers, services, launch files, and motion commands. These ideas are explained through SwayForm examples, not as abstract definitions.

Motion and safe control

Students learn that robot joints cannot be commanded randomly. Every motion has to respect safe limits, timing, physical spacing, and the difference between a smooth behavior and a sudden unsafe movement.

Vision and interaction

SwayForm uses a RealSense camera for demos and labs that connect perception to behavior. Students can explore simple user detection, target zones, and camera-assisted interaction without pretending the robot has perfect human-level understanding.

Debugging real systems

Students learn that robotics is not only about writing code. They also learn to read terminal output, check whether a process is running, source a workspace, stop a motion safely, and understand why hardware may not behave exactly as expected.

Key idea

SwayForm teaches robotics as a connected system: code, motion, sensors, timing, safety, and debugging all working together.

/Start Here/How Students Use This Hub

How Students Use This Hub

The Learning Hub is meant to be used directly by students. A teacher or club lead can introduce the activity, but students should be able to open the hub, follow the steps, and understand what they are changing.

The basic student workflow

1
Open the Learning Hub. Students begin from this page instead of searching through the public website. The hub is the home base for demos, labs, setup, and reference material.
2
Connect to the robot. Students use VS Code and SSH to open the robot workspace from their laptop. This keeps the workflow close to what students will see in real robotics and engineering environments.
3
Run a provided demo. The first step is usually running a finished demo, such as Wave or Vision Handshake. This shows what the robot can do before students start editing code.
4
Read the walkthrough. Each ready demo includes a code walkthrough explaining what the script is doing, which hardware is involved, and what students should pay attention to.
5
Modify a small part. Students change one controlled part of the code, such as the number of wave cycles, a delay value, a target angle, or a pose name.
6
Complete a guided lab. Labs are more structured than demos. They ask students to edit code, test a result, answer a reflection question, and try an extension challenge.
7
Build a small behavior. After students understand the basics, they combine motion, timing, and optional camera input into a small custom robot interaction.
Important

Students should not be guessing randomly. The hub is designed to move them from running code, to reading code, to editing code, to designing behavior.

/Start Here/File Structure

File Structure

SwayForm examples are organized so students can tell the difference between official demo programs, editable lab files, and supporting robot code.

Demo programs

Demo programs are finished examples. Students can run them to see what the robot does, then read the walkthrough to understand how the behavior works.

Example demo folder
~/ros2_ws/src/swayform_demos/
├── wave_demo.py
├── vision_handshake.py
├── look_and_point.py
├── rock_paper_scissors.py
└── dollar_snack_exchange.py

Student labs

Student labs are guided activities. These are the files students are expected to open, edit, test, and improve.

Example lab folder
~/ros2_ws/src/swayform_labs/
├── lab_01_hello_motion.py
├── lab_02_servo_limits.py
├── lab_03_gesture_sequence.py
├── lab_04_head_tracking.py
├── lab_05_button_motion.py
├── lab_06_realsense_detection.py
├── lab_07_hand_pose_timing.py
├── lab_08_base_rotation.py
├── lab_09_motion_locking.py
└── lab_10_mini_demo_challenge.py

Recommended editing rule

Students should not rewrite official demos during the first session. Run the demo first, read the code, then copy the important idea into a lab file or student workspace.

/Start Here/Safety Notes

Safety Notes

SwayForm is designed for classroom robotics learning, but it is still a physical robot. Students should treat every moving part with care.

Safety

The goal of the labs is controlled learning, not seeing how far the robot can be pushed.

Keep hands clear while a demo is running.
Stop the running script before repositioning objects near the robot.
Do not force the robot's arms, hands, head, or base by hand.
Use safe joint limits instead of testing random servo angles.
Keep tabletop objects light and easy to move.
Make sure the robot is stable before running arm or base motions.
If a motion looks wrong, stop the script before trying again.
/Setup/VS Code + SSH

VS Code + SSH

Students use VS Code and SSH so they can work with the robot like a real development system. Code runs on the robot, but students can edit and launch it from their laptop.

What SSH means

SSH lets a laptop open a secure terminal session on the robot. Instead of plugging in a monitor and keyboard, students connect remotely and run commands from their own computer.

Why VS Code is used

VS Code gives students a familiar editor, file browser, terminal, and remote connection workflow. It lets students open the robot workspace, inspect files, edit lab code, and run commands without switching tools constantly.

Example connection

Terminal
ssh swayform@swayform.local

Open the workspace

Terminal
cd ~/ros2_ws

Source the workspace

Terminal
source install/setup.bash

Run a first demo

Terminal
ros2 run swayform_demos wave_demo
Note

These commands are example defaults. The exact hostname, username, or workspace path can be adjusted for the final classroom image.

/Setup/Connecting to the Robot

Connecting to the Robot

Before students run demos, they need to make sure their laptop can communicate with SwayForm.

1
Power on the robot. Make sure the robot is powered and sitting in a stable position. Do not place hands or objects near the arms while software is starting.
2
Connect to the correct network. Use the classroom network or direct robot network setup provided by the instructor. The laptop and robot need to be able to see each other.
3
Open VS Code. Use the remote SSH workflow to open a terminal and file browser on the robot.
4
Open the workspace. The main workspace is usually located at ~/ros2_ws. This is where demos, labs, and robot packages are stored.
5
Run a safe demo first. Start with Demo 01: Wave. It is simple, visible, and easier to understand than a camera-based interaction.
/Setup/Running a Demo

Running a Demo

Demos are finished example behaviors. They are meant to show students what the robot can do before students start editing lab code.

Basic run flow

Terminal
cd ~/ros2_ws source install/setup.bash ros2 run swayform_demos wave_demo

Before running

The robot is stable.
The table area is clear.
No one is holding the robot arm.
The correct demo command is being used.
The previous behavior has stopped.
/Setup/Stopping Motion Safely

Stopping Motion Safely

Students should know how to stop a behavior before they start changing code. A safe stop is part of the workflow, not an emergency-only action.

Normal stop

If the demo is running in a terminal, use the normal keyboard interrupt.

Terminal
Ctrl + C

After stopping

Wait for the robot to finish or relax its current movement.
Do not immediately grab the arm or hand.
Check the terminal output for errors.
Only restart the demo when the area is clear.

If the robot does not move correctly

Stop the script first. Then check whether the correct file was edited, the workspace was sourced, and another behavior is not already controlling the robot.

/Demo Code Library

Demo Code Library

The Demo Code Library contains finished example behaviors that students can run before they start writing their own. Each ready demo includes what the robot does, what students learn, the hardware involved, a run command, and a small code walkthrough.

Ready demos

These demos are intended to be run, inspected, and lightly modified.

01
Wave
Arm wave using a timed servo sequence. Simple and visible.
02
Vision Handshake
Camera-assisted user detection triggers a handshake pose.
03
Look and Point
Robot turns head toward a detected target, then points.
04
Rock Paper Scissors
Robot plays rock-paper-scissors with hand pose presets.
05
Dollar Bill Snack Exchange
State machine tabletop demo: receive bill, place aside, give snack.

Coming soon

These slots are reserved for future classroom demos. They should appear in the hub, but should not pretend to be finished.

06
Follow the Face
07
Classroom Attendance Greeting
08
Object Sorting Starter
09
Voice Prompt Motion
10
Custom Student Demo
//Demo 01

Demo 01: Wave

Status Ready
Level Beginner
Time 5–10 minutes

The robot raises one arm and performs a simple wave motion using a timed servo sequence. The behavior is simple on purpose: students can clearly see how a few target positions become a physical gesture.

What it does

Students learn how a script can move a joint group, pause between poses, repeat a motion, and return the robot to a neutral position.

Hardware used

  • Shoulder servo
  • Elbow servo
  • Optional wrist or hand motion
  • Motion controller node

Concepts covered

  • Joint targets
  • Servo angles
  • Timed motion
  • Smooth movement
  • Safe limits
  • Running a script from terminal

Run command

Terminal
ros2 run swayform_demos wave_demo

Starter code

The complete starter file below is structured the same way a real robotics script is structured. Read through it before running it so you understand what each section does.

Note: These examples are written as classroom starter code. Final hardware APIs can be adjusted to match the installed SwayForm software image.
python — wave_demo.py
"""
Demo 01: Wave

Purpose:
Run a simple waving behavior using safe arm poses.

What this teaches:
- How a behavior script connects to the motion layer
- How joint targets create physical motion
- Why safe poses and delays matter
- How to return the robot to idle after a demo
"""

from time import sleep
from swayform.motion import MotionClient


# -----------------------------
# Student-adjustable settings
# -----------------------------

WAVE_CYCLES = 3
WAVE_DELAY_SECONDS = 0.35

RIGHT_ARM_RAISED = {
    "shoulder_pitch": 42,
    "shoulder_roll": 18,
    "elbow_pitch": 70,
}

WRIST_LEFT = -25
WRIST_RIGHT = 25


def move_to_wave_start(motion: MotionClient) -> None:
    """
    Move the robot from idle into a safe raised-arm position.
    This should happen before the wrist starts waving.
    """
    motion.safe_pose("idle")
    sleep(0.5)

    motion.move_joint_group("right_arm", RIGHT_ARM_RAISED)
    sleep(0.8)


def perform_wave(motion: MotionClient, cycles: int) -> None:
    """
    Move the wrist left and right several times.
    The arm stays raised while the wrist creates the wave motion.
    """
    for _ in range(cycles):
        motion.move_joint("right_wrist_yaw", WRIST_LEFT)
        sleep(WAVE_DELAY_SECONDS)

        motion.move_joint("right_wrist_yaw", WRIST_RIGHT)
        sleep(WAVE_DELAY_SECONDS)


def return_to_idle(motion: MotionClient) -> None:
    """
    Always return the robot to a known safe pose after the demo.
    """
    motion.safe_pose("idle")


def main() -> None:
    motion = MotionClient()

    try:
        motion.lock_behavior("wave_demo")
        move_to_wave_start(motion)
        perform_wave(motion, WAVE_CYCLES)
    finally:
        return_to_idle(motion)
        motion.unlock_behavior("wave_demo")


if __name__ == "__main__":
    main()

Code walkthrough

Student-adjustable settings
The values at the top are the safest place for beginners to start experimenting. Students can change the number of wave cycles or the delay without rewriting the entire behavior.
Wave start pose
The robot moves to idle first, then raises the arm. This prevents the wave from starting from an unknown or awkward position.
Wave loop
The loop repeats the same wrist movement several times. This shows how a small repeated motion can become a recognizable gesture.
Return to idle
Every demo should end by returning to a known safe pose. This makes the next test easier and safer.
Motion lock
The motion lock prevents another behavior from trying to control the same robot parts while the wave is running.

Try changing this

  • Change the number of wave cycles.
  • Make the wave slower or faster.
  • Try the left arm instead of the right arm.
  • Add a small head turn during the wave.
Safety

Do not test random shoulder or elbow angles. Use the provided safe ranges and return to idle before trying a new version.

Next step

After running Wave, open

//Demo 02

Demo 02: Vision Handshake

Status Ready
Level Beginner+
Time 10–15 minutes

The robot uses the RealSense camera to detect that a user is in front of it, moves its arm into a handshake pose, waits briefly, and then returns to idle.

Honest note

This is a vision-assisted classroom demo. It should not be described as perfect hand detection or full human understanding. The first version can use simple user presence, an approximate interaction zone, or a manual trigger while students learn how perception can start a behavior.

What students learn

Students learn how camera input can trigger robot motion and why robots need conservative movement when interacting near people.

Hardware used

  • RealSense camera
  • Arm servos
  • Optional hand servo
  • Motion node

Concepts covered

  • RealSense camera input
  • User presence detection
  • Perception-triggered behavior
  • Human-robot interaction
  • Motion locking
  • Returning to neutral pose

Run command

Terminal
ros2 run swayform_demos vision_handshake

Starter code

This version uses a timeout so the demo does not wait forever. Read the function names before running to understand the flow: wait, detect, execute, return home.

Note: These examples are written as classroom starter code. Final hardware APIs can be adjusted to match the installed SwayForm software image.
python — vision_handshake.py
"""
Demo 02: Vision Handshake

Purpose:
Use a simple RealSense-based presence check to trigger a handshake pose.

Important:
This is a vision-assisted classroom demo. It does not claim perfect hand
detection or human-level understanding.
"""

from time import sleep, time
from swayform.motion import MotionClient
from swayform.vision import RealSenseInput


DETECTION_TIMEOUT_SECONDS = 10
HANDSHAKE_HOLD_SECONDS = 2.0

HANDSHAKE_POSE = {
    "shoulder_pitch": 38,
    "shoulder_roll": 10,
    "elbow_pitch": 82,
    "wrist_yaw": 0,
}


def wait_for_user(camera: RealSenseInput, timeout: float) -> bool:
    """
    Wait until the camera reports a user inside the interaction zone.
    Returns True if a user is found, otherwise False.
    """
    start_time = time()

    while time() - start_time < timeout:
        if camera.user_in_interaction_zone():
            return True

        sleep(0.1)

    return False


def run_handshake(motion: MotionClient) -> None:
    """
    Move into a conservative handshake pose, wait briefly,
    then return to idle.
    """
    motion.move_joint_group("right_arm", HANDSHAKE_POSE)
    sleep(HANDSHAKE_HOLD_SECONDS)
    motion.safe_pose("idle")


def main() -> None:
    motion = MotionClient()
    camera = RealSenseInput()

    motion.safe_pose("idle")
    print("Waiting for user...")

    user_detected = wait_for_user(camera, DETECTION_TIMEOUT_SECONDS)

    if not user_detected:
        print("No user detected. Returning to idle.")
        motion.safe_pose("idle")
        return

    try:
        motion.lock_behavior("vision_handshake")
        run_handshake(motion)
    finally:
        motion.unlock_behavior("vision_handshake")
        motion.safe_pose("idle")


if __name__ == "__main__":
    main()

Code walkthrough

Detection timeout
The robot should not wait forever. A timeout keeps the demo predictable and helps students understand that robot behaviors need exit conditions.
wait_for_user
This function checks the camera repeatedly until a user is detected or the timeout ends. Students can adjust the detection distance later.
Handshake pose
The handshake pose is a controlled arm position, not a fast reach. Human-facing demos should move slowly and conservatively.
Failure path
If no user is detected, the robot does nothing dramatic. It prints a message and stays safe.
finally block
The finally block makes sure the robot unlocks the behavior and returns to idle even if something interrupts the script.

Try changing this

  • Change how long the robot holds the handshake pose.
  • Add a small head nod before the arm moves.
  • Add a spoken prompt if speakers are connected.
  • Adjust the detection distance.
Safety

Keep the handshake motion slow and predictable. Do not make the arm snap toward the user.

Next step

After Vision Handshake, try

//Demo 03

Demo 03: Look and Point

Status Ready
Level Beginner+
Time 10–15 minutes

The robot turns its head toward a detected target zone, then points one arm in that direction. This teaches students how perception can trigger a physical response.

Honest note

The target can be a simple left/center/right camera zone, a colored object, an AprilTag, or placeholder detection logic. The goal is to teach vision-to-motion mapping, not advanced object recognition.

What students learn

Students learn that robot behavior often happens in stages: sense something, decide where it is, move the head, then move the arm.

Hardware used

  • RealSense camera
  • Neck yaw and pitch servos
  • Shoulder and elbow servos
  • Motion node

Concepts covered

  • Camera frame coordinates
  • Head yaw and pitch
  • Mapping vision to motion
  • Pointing gesture
  • Behavior sequencing

Run command

Terminal
ros2 run swayform_demos look_and_point

Starter code

This version separates look and point into two functions so students can test each step individually. The robot always looks before it points.

Note: These examples are written as classroom starter code. Final hardware APIs can be adjusted to match the installed SwayForm software image.
python — look_and_point.py
"""
Demo 03: Look and Point

Purpose:
Detect a rough target zone (left / center / right) from the camera,
turn the head toward it, then point one arm in that direction.

Important:
The target zone is a simplified classroom abstraction.
This demo teaches vision-to-motion mapping, not production-level
object detection.
"""

from time import sleep
from swayform.motion import MotionClient
from swayform.vision import RealSenseInput


HEAD_TURN_DEGREES = 25
HEAD_PITCH = 5
POINT_HOLD_SECONDS = 1.5

ZONE_HEAD_ANGLES = {
    "left":   {"neck_yaw": -HEAD_TURN_DEGREES, "neck_pitch": HEAD_PITCH},
    "center": {"neck_yaw":  0,                 "neck_pitch": HEAD_PITCH},
    "right":  {"neck_yaw":  HEAD_TURN_DEGREES, "neck_pitch": HEAD_PITCH},
}

ZONE_ARM_POSES = {
    "left":   "point_left",
    "center": "point_center",
    "right":  "point_right",
}


def look_at_zone(motion: MotionClient, zone: str) -> None:
    """Turn the head toward the detected zone."""
    head_angles = ZONE_HEAD_ANGLES.get(zone, ZONE_HEAD_ANGLES["center"])
    motion.move_joint_group("head", head_angles)
    sleep(0.4)


def point_at_zone(motion: MotionClient, zone: str) -> None:
    """Move the arm into the pointing pose for the detected zone."""
    arm_pose = ZONE_ARM_POSES.get(zone, "point_center")
    motion.safe_pose(arm_pose)
    sleep(POINT_HOLD_SECONDS)


def main() -> None:
    motion = MotionClient()
    camera = RealSenseInput()

    motion.safe_pose("idle")

    target_zone = camera.get_target_zone()
    print(f"Detected zone: {target_zone}")

    try:
        motion.lock_behavior("look_and_point")
        look_at_zone(motion, target_zone)
        point_at_zone(motion, target_zone)
    finally:
        motion.safe_pose("idle")
        motion.unlock_behavior("look_and_point")


if __name__ == "__main__":
    main()

Code walkthrough

Zone constants
The head angles and arm poses are stored in dictionaries. Students can change numbers in one place without hunting through the rest of the code.
look_at_zone first
The robot looks before it points. This is intentional — it makes the behavior easier for a person to follow and understand.
point_at_zone second
After the head settles, the arm moves into the matching pointing pose. The hold pause gives observers time to see the result.
get_target_zone
This returns a rough left/center/right classification. Students can later replace it with more specific detection — colored object, AprilTag, or depth threshold.
finally block
Returns the robot to idle and unlocks the behavior even if something goes wrong mid-sequence.

Try changing this

  • Change the target zone thresholds.
  • Point with the left arm instead of the right arm.
  • Add a short pause before pointing.
  • Make the robot look back at the user after pointing.
Safety

Keep pointing motions away from faces and people. Pointing should be a gesture, not a fast reach.

Next step

After Look and Point, try

//Demo 04

Demo 04: Rock Paper Scissors

Status Ready
Level Intermediate
Time 15–20 minutes

The robot plays rock-paper-scissors with the user. It counts down, chooses rock, paper, or scissors, moves its hand into the selected pose, and compares the result.

Honest note

This demo can run in keyboard mode first, where the user enters their choice. A camera-assisted version can be added later using simple gesture detection. Do not describe the current version as perfect hand-gesture recognition unless that is actually implemented.

What students learn

Students learn how robot behaviors can include randomness, user input, hand pose presets, branching logic, and a repeated game loop.

Hardware used

  • Hand and finger servos
  • Optional speaker for countdown
  • Optional RealSense camera for camera-assisted mode

Concepts covered

  • Random choice
  • Hand pose presets
  • Branching logic
  • User interaction
  • Game loop
  • Optional vision classification

Run command

Terminal
ros2 run swayform_demos rock_paper_scissors

Starter code

This version uses a game loop so students can run multiple rounds without restarting. Each round is a clean sequence: countdown, choose, move, judge.

Note: These examples are written as classroom starter code. Final hardware APIs can be adjusted to match the installed SwayForm software image.
python — rock_paper_scissors.py
"""
Demo 04: Rock Paper Scissors

Purpose:
Play a round of rock-paper-scissors with the user. The robot picks randomly.

Important:
This version uses keyboard input for the user's choice.
A camera-assisted version can be added later using gesture detection.
Do not describe this as perfect hand-recognition unless that is implemented.
"""

import random
from time import sleep
from swayform.motion import MotionClient
from swayform.audio import AudioPrompt


VALID_CHOICES = ["rock", "paper", "scissors"]
COUNTDOWN_SECONDS = 1.0
POSE_HOLD_SECONDS = 1.5
ROUNDS_TO_PLAY = 3

WINS_AGAINST = {
    "rock": "scissors",
    "scissors": "paper",
    "paper": "rock",
}


def countdown(audio: AudioPrompt) -> None:
    """Say rock, paper, scissors aloud before the reveal."""
    for word in ["Rock", "Paper", "Scissors", "Shoot!"]:
        audio.say(word)
        sleep(COUNTDOWN_SECONDS)


def get_user_choice() -> str:
    """Prompt the user and validate their choice."""
    while True:
        raw = input("Your move (rock / paper / scissors): ").strip().lower()
        if raw in VALID_CHOICES:
            return raw
        print(f"Please enter one of: {', '.join(VALID_CHOICES)}")


def judge(robot: str, user: str) -> str:
    """Return 'robot', 'user', or 'tie'."""
    if robot == user:
        return "tie"
    if WINS_AGAINST[robot] == user:
        return "robot"
    return "user"


def play_round(motion: MotionClient, audio: AudioPrompt) -> str:
    """Run one complete round. Returns winner: 'robot', 'user', or 'tie'."""
    robot_choice = random.choice(VALID_CHOICES)
    user_choice = get_user_choice()

    countdown(audio)

    motion.set_hand_pose("right_hand", robot_choice)
    sleep(POSE_HOLD_SECONDS)

    result = judge(robot_choice, user_choice)
    print(f"Robot: {robot_choice}  |  You: {user_choice}  |  Result: {result}")

    motion.set_hand_pose("right_hand", "relaxed")
    return result


def main() -> None:
    motion = MotionClient()
    audio = AudioPrompt()

    scores = {"robot": 0, "user": 0, "tie": 0}

    motion.safe_pose("idle")

    for round_num in range(1, ROUNDS_TO_PLAY + 1):
        print(f"\n--- Round {round_num} ---")
        winner = play_round(motion, audio)
        scores[winner] += 1

    print(f"\nFinal score — Robot: {scores['robot']}  You: {scores['user']}  Ties: {scores['tie']}")
    motion.safe_pose("idle")


if __name__ == "__main__":
    main()

Code walkthrough

WINS_AGAINST dictionary
The win rule is stored as a lookup table instead of nested if-statements. This makes the logic easier to read and change.
Input validation loop
get_user_choice loops until the user enters a valid move. This prevents the demo from crashing on a typo.
countdown function
The countdown says each word aloud before the reveal. Students can replace this with a visual LED countdown or a different audio cue.
play_round returns the winner
Each round returns who won. The main loop collects these and prints a final score, making it easy to extend into best-of-five.
judge function
Separating the win logic into its own function makes it easy to test. Students can call judge("rock","scissors") in the Python shell and verify the result without running the full demo.

Try changing this

  • Make the game best of three rounds.
  • Add sound effects or a countdown.
  • Add head movement when the robot wins or loses.
  • Add a scoreboard variable.
Safety

Hand poses should use tested finger positions. Do not over-close the fingers around a person's hand.

Next step

After Rock Paper Scissors, try

//Demo 05

Demo 05: Dollar Bill Snack Exchange

Status Ready
Level Intermediate
Time 15–20 minutes
Classroom demo only

This demo assumes any received bill is a $1 bill and is only for classroom interaction. It is not real payment processing or currency validation.

A classroom interaction demo where the user gives the robot a bill, the robot assumes the bill is $1, places it to the side, then gives or pushes a small snack item toward the user.

Example setup

Place a light snack item, such as a small chip packet, on the table near the robot. The user places a bill in front of the robot. The robot moves the bill to one side, reaches toward the snack item, and presents or pushes it toward the user.

What students learn

Students learn how a larger robot behavior can be broken into states. The robot is not doing one magic action; it is moving through a controlled sequence.

Hardware used

  • RealSense camera
  • Arm servos
  • Hand servos
  • Small tabletop object
  • Optional speaker

Concepts covered

  • Human-robot interaction
  • Sequenced manipulation
  • Simple object handoff
  • Vision or manual trigger
  • Safe arm movement
  • State machine thinking

Run command

Terminal
ros2 run swayform_demos dollar_snack_exchange

State machine

  • IDLE
  • WAIT_FOR_BILL
  • ACCEPT_BILL
  • PLACE_BILL_ASIDE
  • PICK_SNACK
  • HAND_SNACK_TO_USER
  • RETURN_HOME

Starter code

This version uses an enum.Enum state machine so every stage of the interaction is named. Students can add print statements to each state transition to see the sequence in the terminal.

Note: These examples are written as classroom starter code. Final hardware APIs can be adjusted to match the installed SwayForm software image.
python — dollar_snack_exchange.py
"""
Demo 05: Dollar Bill Snack Exchange

Purpose:
A classroom interaction demo where the user places a bill near the robot,
the robot accepts it, sets it aside, then presents a snack item.

Important:
This is not real payment processing or currency validation.
The robot assumes every bill is a $1 bill.
This demo is for supervised classroom interaction only.
"""

import enum
from time import sleep, time
from swayform.motion import MotionClient
from swayform.vision import RealSenseInput
from swayform.audio import AudioPrompt


BILL_WAIT_TIMEOUT = 15.0
BILL_HOLD_SECONDS = 0.6
SNACK_HANDOFF_HOLD = 1.5


class ExchangeState(enum.Enum):
    WAIT_FOR_BILL      = "wait_for_bill"
    ACCEPT_BILL        = "accept_bill"
    PLACE_BILL_ASIDE   = "place_bill_aside"
    PICK_SNACK         = "pick_snack"
    HAND_SNACK_TO_USER = "hand_snack_to_user"
    RETURN_HOME        = "return_home"


def wait_for_bill(camera: RealSenseInput, timeout: float) -> bool:
    """Poll until a bill is detected in the bill area, or timeout."""
    start = time()
    while time() - start < timeout:
        if camera.object_in_zone("bill_area"):
            return True
        sleep(0.1)
    return False


def run_exchange(motion: MotionClient, audio: AudioPrompt) -> None:
    state = ExchangeState.ACCEPT_BILL

    while state != ExchangeState.RETURN_HOME:
        print(f"State: {state.value}")

        if state == ExchangeState.ACCEPT_BILL:
            motion.safe_pose("bill_pickup")
            motion.set_hand_pose("right_hand", "gentle_close")
            sleep(BILL_HOLD_SECONDS)
            state = ExchangeState.PLACE_BILL_ASIDE

        elif state == ExchangeState.PLACE_BILL_ASIDE:
            motion.safe_pose("bill_side_drop")
            motion.set_hand_pose("right_hand", "open")
            sleep(0.3)
            state = ExchangeState.PICK_SNACK

        elif state == ExchangeState.PICK_SNACK:
            motion.safe_pose("snack_pickup")
            sleep(0.4)
            state = ExchangeState.HAND_SNACK_TO_USER

        elif state == ExchangeState.HAND_SNACK_TO_USER:
            motion.safe_pose("snack_handoff")
            audio.say("Here you go.")
            sleep(SNACK_HANDOFF_HOLD)
            state = ExchangeState.RETURN_HOME

    motion.safe_pose("idle")


def main() -> None:
    motion = MotionClient()
    camera = RealSenseInput()
    audio  = AudioPrompt()

    motion.safe_pose("idle")
    audio.say("Ready. Place your bill on the table.")

    bill_detected = wait_for_bill(camera, BILL_WAIT_TIMEOUT)

    if not bill_detected:
        audio.say("No bill detected. Returning to idle.")
        motion.safe_pose("idle")
        return

    try:
        motion.lock_behavior("dollar_snack_exchange")
        run_exchange(motion, audio)
    finally:
        motion.unlock_behavior("dollar_snack_exchange")
        motion.safe_pose("idle")


if __name__ == "__main__":
    main()

Code walkthrough

ExchangeState enum
Each stage of the interaction is a named state. Using an enum prevents typos and lets students see the full sequence before the code runs.
wait_for_bill
Same timeout pattern as Demo 02. The robot waits a fixed window, then gives up cleanly if nothing is detected.
while loop drives the sequence
Each iteration handles one state, then advances to the next. Adding print(f"State: {state.value}") (already there) shows students the state machine running live.
audio.say checkpoints
Spoken words mark each major step. This makes the demo easier for observers to follow and helps students identify which state is executing.
finally block
The motion lock releases and the robot returns to idle even if an error interrupts mid-sequence. Never leave a behavior lock open.

Try changing this

  • Change the snack position.
  • Add a thank-you sound.
  • Add a timeout if no bill is detected.
  • Make the robot wave after completing the exchange.
Safety

Use only light tabletop objects. This demo is for classroom interaction, not real vending, payment, or unattended operation.

Next step

After Dollar Bill Snack Exchange, try

/Demo 06

Demo 06: Follow the Face

Coming soon

This demo slot is reserved for future SwayForm classroom examples.

It is shown here so instructors and students can see where future material will fit inside the Learning Hub.

/Demo 07

Demo 07: Classroom Attendance Greeting

Coming soon

This demo slot is reserved for future SwayForm classroom examples.

It is shown here so instructors and students can see where future material will fit inside the Learning Hub.

/Demo 08

Demo 08: Object Sorting Starter

Coming soon

This demo slot is reserved for future SwayForm classroom examples.

It is shown here so instructors and students can see where future material will fit inside the Learning Hub.

/Demo 09

Demo 09: Voice Prompt Motion

Coming soon

This demo slot is reserved for future SwayForm classroom examples.

It is shown here so instructors and students can see where future material will fit inside the Learning Hub.

/Demo 10

Demo 10: Custom Student Demo

Coming soon

This demo slot is reserved for future SwayForm classroom examples.

It is shown here so instructors and students can see where future material will fit inside the Learning Hub.

/Student Labs

Student Labs

Student labs are guided activities where students edit code, run the robot, observe the result, and answer a short reflection question. Labs are more structured than demos, but still focused on real robot behavior.

Ready labs

These labs are ready to use as classroom or robotics club activities.

01
Hello Robot Motion
Run your first safe motion and confirm the robot responds to your code.
02
Servo Angles & Safe Limits
Learn why joints have angle limits and what safe testing looks like.
03
Build a Gesture Sequence
Create a gesture by combining safe poses with timing delays.
04
Head Tracking Basics
Move the robot head toward a simple target zone.
05
Button-to-Motion Control
Connect keyboard input to safe robot actions.
06
RealSense Detection Basics
Use camera zone data to trigger a robot behavior.
07
Hand Pose Timing
Adjust timing to see how small delays affect gestures.
08
Base Rotation Basics
Command the robot's rotating base to turn left and right safely.
09
Behavior Priority & Motion Locking
Learn why one behavior should not interrupt another at the wrong time.
10
Mini Demo Challenge
Build a small custom demo combining motion, timing, and optional perception.

Coming soon

These slots are reserved for future SwayForm curriculum material.

11
Simple State Machines
12
Custom Motion Presets
13
Camera-Based User Greeting
14
Object Position Mapping
15
Two-Arm Coordination
16
Speaker Prompts and Timing
17
Classroom Challenge: Helpful Robot
18
Intro to Robot Debug Logs
19
Build Your Own Interaction
20
Final Showcase Demo
//Lab 01

Lab 01: Hello Robot Motion

Status Ready
Level Beginner
Time 20–30 minutes

Goal: Run your first safe robot motion and understand that code sends target positions to robot joints.

What students edit: Students change a small motion value or timing value after running the starter version.

Concepts

  • Motion commands
  • Neutral pose
  • Safe movement
  • Terminal command
  • Observation before editing

Starter command

Terminal
ros2 run swayform_labs lab_01_hello_motion

Steps

  1. Connect to the robot through VS Code and SSH.
  2. Open the lab file.
  3. Run the starter command without editing anything.
  4. Observe which part of the robot moves.
  5. Change one allowed value.
  6. Run the lab again.
  7. Return the robot to idle.

Expected result

The robot performs a small safe motion, such as moving an arm or head, then returns to a neutral pose.

Reflection question

What changed physically when you changed the code value?

Extension challenge

Add a second safe motion after the first one, then return the robot to idle.

/Lab 02

Lab 02: Servo Angles and Safe Limits

Status Ready
Level Beginner
Time 25–35 minutes

Goal: Understand that each joint has safe angle limits and that robot motion should stay inside tested ranges.

What students edit: Students adjust allowed servo target values inside a provided safe range.

Concepts

  • Servo range
  • Joint limits
  • Mechanical safety
  • Angle values
  • Safe testing

Starter command

Terminal
ros2 run swayform_labs lab_02_servo_limits

Steps

  1. Open the lab file and find the safe angle range.
  2. Run the starter motion.
  3. Change the angle slightly within the allowed range.
  4. Run the motion again.
  5. Compare small changes to larger changes.
  6. Return the joint to neutral.
  7. Write down why random angles are unsafe.

Expected result

Students see that small code changes can create visible joint movement, but only within safe mechanical limits.

Reflection question

Why should a robot program use safe limits instead of sending any angle directly to a servo?

Extension challenge

Create a helper function that rejects values outside the safe range.

/Lab 03

Lab 03: Build a Gesture Sequence

Status Ready
Level Beginner+
Time 30–40 minutes

Goal: Create a small gesture by combining multiple safe poses with timing delays.

What students edit: Students reorder poses, adjust delays, and add one extra gesture step.

Concepts

  • Sequences
  • Timing
  • Poses
  • Reusable functions
  • Human-readable robot behavior

Starter command

Terminal
ros2 run swayform_labs lab_03_gesture_sequence

Steps

  1. Run the starter gesture.
  2. Identify each pose in the sequence.
  3. Change one delay value.
  4. Add one new pose from the provided safe pose list.
  5. Run the new sequence.
  6. Check whether the gesture still looks smooth.
  7. Return the robot to idle.

Expected result

The robot performs a short custom gesture using multiple poses.

Reflection question

How does timing change the way a robot gesture feels to a person watching it?

Extension challenge

Create two versions of the same gesture: one that looks calm and one that looks excited.

/Lab 04

Lab 04: Head Tracking Basics

Status Ready
Level Beginner+
Time 30–45 minutes

Goal: Move the robot head left, center, or right based on a simple target position.

What students edit: Students adjust zone thresholds and head yaw values.

Concepts

  • Neck yaw
  • Neck pitch
  • Camera target position
  • Mapping input to motion
  • Simple tracking behavior

Starter command

Terminal
ros2 run swayform_labs lab_04_head_tracking

Steps

  1. Run the starter head tracking script.
  2. Move the target between left, center, and right zones.
  3. Observe how the head responds.
  4. Change one threshold value.
  5. Change one head yaw value within the safe range.
  6. Run the script again.
  7. Return the head to center.

Reflection question

What is the difference between detecting where something is and deciding how far the robot should move?

Extension challenge

Add a small delay so the head movement feels smoother and less twitchy.

/Lab 05

Lab 05: Button-to-Motion Control

Status Ready
Level Beginner+
Time 25–40 minutes

Goal: Connect a keyboard input or simple button event to a robot motion.

What students edit: Students map different inputs to different safe robot actions.

Concepts

  • Events
  • Input handling
  • Calling robot actions
  • Safety stop
  • Simple control interface

Starter command

Terminal
ros2 run swayform_labs lab_05_button_motion

Steps

  1. Run the starter input script.
  2. Press the provided key to trigger a motion.
  3. Find where the input is checked in the code.
  4. Add a second input option.
  5. Map the second input to a different safe pose.
  6. Test both inputs.
  7. Use the stop key before ending the lab.

Reflection question

Why is it useful to separate input handling from the actual robot motion function?

Extension challenge

Add a simple menu that shows which keys trigger which motions.

/Lab 06

Lab 06: RealSense Detection Basics

Status Ready
Level Intermediate
Time 35–45 minutes

Goal: Use RealSense camera data as a trigger for a simple robot behavior.

What students edit: Students adjust a detection zone or distance threshold.

Concepts

  • Camera input
  • Detection zones
  • Depth and distance
  • Perception-triggered motion
  • False positives

Starter command

Terminal
ros2 run swayform_labs lab_06_realsense_detection

Steps

  1. Start the camera-based lab.
  2. Place a target or user inside the detection area.
  3. Observe when the robot triggers a response.
  4. Adjust the detection distance or zone.
  5. Run the test again.
  6. Compare reliable and unreliable trigger conditions.
  7. Return the robot to idle.

Reflection question

Why should camera-based triggers be conservative when the robot is near people?

Extension challenge

Add a timeout so the robot returns to idle if the target disappears.

/Lab 07

Lab 07: Hand Pose Timing

Status Ready
Level Intermediate
Time 30–45 minutes

Goal: Adjust hand and finger timing to understand how small delays affect robot gestures.

What students edit: Students change finger pose timing, open/close delays, or gesture order.

Concepts

  • Finger servo poses
  • Timing
  • Grip and release
  • Gesture realism
  • Small motion changes

Starter command

Terminal
ros2 run swayform_labs lab_07_hand_pose_timing

Steps

  1. Run the starter hand pose.
  2. Observe how quickly the fingers move.
  3. Change one timing delay.
  4. Run the gesture again.
  5. Change the order of two finger movements.
  6. Compare which version looks more natural.
  7. Return the hand to relaxed pose.

Reflection question

Why can timing make a robot motion feel more natural even if the final pose is the same?

Extension challenge

Create a small hand gesture that looks like a count-in or signal.

/Lab 08

Lab 08: Base Rotation Basics

Status Ready
Level Intermediate
Time 30–45 minutes

Goal: Command the robot's rotating base to turn left or right safely.

What students edit: Students adjust direction, duration, or speed values inside safe limits.

Concepts

  • Base yaw
  • Motor control
  • Direction
  • Speed
  • Stop command

Starter command

Terminal
ros2 run swayform_labs lab_08_base_rotation

Steps

  1. Make sure the robot base area is clear.
  2. Run the starter base rotation command.
  3. Observe direction and stopping behavior.
  4. Change the direction.
  5. Change the duration slightly.
  6. Run the test again.
  7. Send the stop command.

Reflection question

Why should base motion always include a clear stop condition?

Extension challenge

Create a turn-left, pause, turn-right sequence.

/Lab 09

Lab 09: Behavior Priority and Motion Locking

Status Ready
Level Intermediate
Time 35–45 minutes

Goal: Understand why one robot behavior should not interrupt another motion at the wrong time.

What students edit: Students test simple behavior priority rules and see how a motion lock protects a running action.

Concepts

  • Motion lock
  • Behavior priority
  • State control
  • Safe cancellation
  • Competing commands

Starter command

Terminal
ros2 run swayform_labs lab_09_motion_locking

Steps

  1. Run the starter behavior.
  2. Trigger a second behavior while the first is active.
  3. Observe whether the second behavior is blocked or delayed.
  4. Find the motion lock in the code.
  5. Change the priority of one behavior.
  6. Run the test again.
  7. Return the robot to idle.

Reflection question

What could go wrong if two scripts tried to control the same arm at the same time?

Extension challenge

Add a low-priority idle behavior that pauses when a higher-priority demo starts.

/Lab 10

Lab 10: Mini Demo Challenge

Status Ready
Level Intermediate
Time 40–60 minutes

Goal: Combine motion, timing, and optional perception into a small custom robot demo.

What students edit: Students create their own short behavior using safe poses and at least one idea from earlier labs.

Concepts

  • Project planning
  • Code reuse
  • Debugging
  • Demo presentation
  • Behavior design

Starter command

Terminal
ros2 run swayform_labs lab_10_mini_demo_challenge

Steps

  1. Choose a simple demo idea.
  2. Pick which robot parts will move.
  3. Start from a provided safe template.
  4. Add two or more motion steps.
  5. Add timing between steps.
  6. Test one part at a time.
  7. Prepare a short explanation of how the demo works.

Expected result

Students build and run a short custom robot behavior that they can explain.

Reflection question

What part of your demo was easiest to control, and what part needed the most debugging?

Extension challenge

Add camera input or user input to trigger the demo.

/Lab 11

Lab 11: Simple State Machines

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 12

Lab 12: Custom Motion Presets

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 13

Lab 13: Camera-Based User Greeting

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 14

Lab 14: Object Position Mapping

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 15

Lab 15: Two-Arm Coordination

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 16

Lab 16: Speaker Prompts and Timing

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 17

Lab 17: Classroom Challenge: Helpful Robot

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 18

Lab 18: Intro to Robot Debug Logs

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 19

Lab 19: Build Your Own Interaction

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Lab 20

Lab 20: Final Showcase Demo

Coming soon

Full lab instructions will be added later.

This lesson slot is reserved for future SwayForm classroom material.

/Reference/ROS 2 Concepts

ROS 2 Concepts

The Learning Hub introduces ROS 2-style ideas through SwayForm examples. Students do not need to memorize every term immediately. They should understand how information moves through the robot system.

Node

A node is a program that does one part of the robot's work. A camera node might read vision data. A motion node might control joint movement. A demo script might decide what behavior to run.

Topic

A topic is a named stream of information. One part of the robot can publish information, and another part can listen to it.

Publisher

A publisher sends information onto a topic. For example, a camera node might publish target position data.

Subscriber

A subscriber listens for information from a topic. A behavior script might subscribe to vision data and react when a user is detected.

Service

A service is a request-and-response interaction. A script can ask for something specific, such as requesting a safe motion or checking a system status.

Launch file

A launch file starts multiple parts of the robot system together. Instead of opening many terminals manually, a launch file can start the needed nodes in one workflow.

Motion node

The motion node is the part of the system responsible for receiving movement requests and turning them into safe joint commands.

Behavior script

A behavior script decides what the robot should do. For example, the wave demo is a behavior script that sends a sequence of arm movements to the motion system.

Key idea

In SwayForm, ROS 2 concepts are easier to understand because students can connect each term to something the robot actually does.

/Reference/Motion Node

Motion Node

The motion node is the part of the robot software that helps turn behavior requests into controlled movement.

A demo should not directly throw random values at every servo. Instead, a behavior should ask for safe poses, joint groups, or controlled movement sequences. The motion layer helps keep robot behavior predictable.

Why this matters

If two behaviors try to control the same arm at the same time, the robot can move in a confusing or unsafe way. The motion node and motion lock idea help organize which behavior is allowed to control the robot.

A wave script can request the right arm. A handshake script can request the same arm. The system should not allow both to command the arm at the same time.

/Reference/Servo Mapping

Servo Mapping

Servo mapping connects human-readable joint names to the physical servo channels used by the robot.

Students should not need to memorize every channel number at the beginning. They should learn that a name like right_elbow_pitch points to a real actuator inside the robot.

Example idea

When a script says right_elbow_pitch, the robot software knows which servo controller and channel should receive that command.

Note

Servo mapping should be edited carefully. A wrong mapping can make the wrong joint move.

/Reference/RealSense Camera

RealSense Camera

The RealSense camera gives SwayForm visual input for classroom demos and labs.

Camera data can be used to detect that a user is nearby, estimate where a target appears in the frame, or trigger a robot behavior. Early labs should keep vision simple and reliable instead of pretending the robot understands everything it sees.

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, or right region.
  • Starting a behavior when a condition is met.
Honest note

Camera-assisted does not mean perfect. Students should learn how vision can fail, why thresholds matter, and why robots should move conservatively near people.

/Reference/Troubleshooting

Troubleshooting

Robotics debugging is part software, part hardware, and part workflow. Most beginner issues come from connection problems, workspace setup, wrong commands, or another process already running.

Cannot SSH into the robot+
Likely cause
The laptop is not on the correct network, the robot is not fully powered on, or the hostname is different.
Fix
Check power, network connection, and the correct SSH command. Try using the robot's IP address if the hostname does not resolve.
VS Code cannot connect+
Likely cause
The SSH extension is not configured correctly or the robot is unreachable.
Fix
Test SSH in a normal terminal first. If terminal SSH works, reopen VS Code and reconnect through the remote SSH menu.
Demo command not found+
Likely cause
The workspace was not sourced or the package name is wrong.
Fix
Run source install/setup.bash from the workspace, then try the command again.
Robot does not move+
Likely cause
The motion node is not running, power is not enabled, or the behavior is blocked by a safety condition.
Fix
Check terminal output, confirm the robot is powered, and verify the motion system is active.
Camera not detected+
Likely cause
The RealSense camera is not connected, the camera process is not running, or another process is already using the camera.
Fix
Check the camera connection and restart the camera-related node or demo.
Motion stopped halfway+
Likely cause
A safety stop, software error, motion lock, or timeout interrupted the behavior.
Fix
Read the terminal output before restarting. Do not immediately rerun the same script without checking why it stopped.
Permission denied+
Likely cause
The file is not executable or the user does not have permission for that command.
Fix
Check file permissions and confirm the command is being run from the correct environment.
Wrong file edited+
Likely cause
The student edited a copy, a demo file, or a file outside the active workspace.
Fix
Check the file path and confirm the command is running the same file the student edited.
/Reference/Glossary

Glossary

Quick definitions for terms used throughout the Learning Hub.

Behavior
A robot action or interaction made from code, motion, timing, and sometimes sensor input.
Demo
A finished example behavior that students can run and inspect.
Lab
A guided activity where students edit code, test the robot, and answer a reflection question.
Joint
A part of the robot that can move, such as an elbow, shoulder, neck, hand, or base rotation.
Servo
A motor used to move a robot joint to a commanded position.
Pose
A saved set of joint positions that creates a specific robot position or gesture.
Safe limit
A tested range that keeps a joint from moving too far.
RealSense
A camera used for visual input, depth information, and camera-assisted demos.
SSH
A way to remotely connect to the robot's computer from a laptop.
Workspace
The folder where robot code, packages, demos, and labs are organized.
ROS 2
A robotics software framework that helps organize robot programs into nodes, topics, services, and launch files.
Motion lock
A software rule that prevents two behaviors from trying to control the same robot part at the same time.
Neutral pose
A safe resting position the robot can return to before or after a behavior.