× Overview The Robot Learning Hub Curriculum Safety For Schools Contact Sales
Learning Hub/Demo Code/Interactive Exchange

Demo: Interactive Exchange

Status Available
Level Intermediate
Time 15–20 minutes

The robot accepts an item from a user and gives another item back. The reference implementation uses a dollar-bill-to-snack example: the user places a bill near the robot, the robot sets it aside, then presents a small snack item.

Classroom demo only

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

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. The same state machine works for any give-one-item, get-one-item exchange — a token, a card, or a classroom object — the bill and snack are simply the reference example.

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 interactive_exchange

State machine

  • IDLE
  • WAIT_FOR_ITEM
  • ACCEPT_ITEM
  • PLACE_ITEM_ASIDE
  • PICK_GIVE_ITEM
  • HAND_ITEM_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 — interactive_exchange.py
"""
Demo: Interactive Exchange

Purpose:
A classroom interaction demo where the user gives the robot an item,
the robot accepts it, sets it aside, then presents a different item
in return. The reference example uses a $1 bill exchanged for a snack.

Important:
This is not real payment processing or currency validation.
The robot assumes every received 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


ITEM_WAIT_TIMEOUT = 15.0
ITEM_HOLD_SECONDS = 0.6
HANDOFF_HOLD_SECONDS = 1.5


class ExchangeState(enum.Enum):
    WAIT_FOR_ITEM      = "wait_for_item"
    ACCEPT_ITEM        = "accept_item"
    PLACE_ITEM_ASIDE   = "place_item_aside"
    PICK_GIVE_ITEM     = "pick_give_item"
    HAND_ITEM_TO_USER  = "hand_item_to_user"
    RETURN_HOME        = "return_home"


def wait_for_item(camera: RealSenseInput, timeout: float) -> bool:
    """Poll until an item is detected in the exchange area, or timeout."""
    start = time()
    while time() - start < timeout:
        if camera.object_in_zone("exchange_area"):
            return True
        sleep(0.1)
    return False


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

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

        if state == ExchangeState.ACCEPT_ITEM:
            motion.safe_pose("item_pickup")
            motion.set_hand_pose("right_hand", "gentle_close")
            sleep(ITEM_HOLD_SECONDS)
            state = ExchangeState.PLACE_ITEM_ASIDE

        elif state == ExchangeState.PLACE_ITEM_ASIDE:
            motion.safe_pose("item_side_drop")
            motion.set_hand_pose("right_hand", "open")
            sleep(0.3)
            state = ExchangeState.PICK_GIVE_ITEM

        elif state == ExchangeState.PICK_GIVE_ITEM:
            motion.safe_pose("give_item_pickup")
            sleep(0.4)
            state = ExchangeState.HAND_ITEM_TO_USER

        elif state == ExchangeState.HAND_ITEM_TO_USER:
            motion.safe_pose("give_item_handoff")
            audio.say("Here you go.")
            sleep(HANDOFF_HOLD_SECONDS)
            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 item on the table.")

    item_detected = wait_for_item(camera, ITEM_WAIT_TIMEOUT)

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

    try:
        motion.lock_behavior("interactive_exchange")
        run_exchange(motion, audio)
    finally:
        motion.unlock_behavior("interactive_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_item
Same timeout pattern as Handshake. 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. The print(f"State: {state.value}") line shows students the state machine running live.
audio.say checkpoints
Spoken words mark each major step, making the demo easier for observers to follow and helping 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 given-back item.
  • Add a thank-you sound.
  • Change the timeout if no item is detected.
  • Make the robot wave after completing the exchange.
Safety

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

Next step

After Interactive Exchange, try Lab 09: Behavior Priority and Motion Locking.