Demo: Wave
The robot performs a coordinated greeting gesture: one arm raises and the wrist waves side to side using a timed servo sequence. The behavior is simple on purpose, so 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
- Wrist servo
- Motion controller node
Concepts covered
- Joint targets
- Servo angles
- Timed motion
- Smooth movement
- Safe limits
- Running a script from terminal
Run command
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: 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 Lab 01: Hello Robot Motion.