Month 6 Box - Build TARS

Motion Programming: Poses, Gaits, and Gestures

Motion Programming: Poses, Gaits, and Gestures

TARS can think and speak; now you teach it to move with intent. This lesson is Month 1 programming pointed straight at a robot: you describe poses as data, wrap moves in functions, sequence them into a walk and gestures, and manage what TARS is doing with a state machine, all while clamping every motion to safe limits so nothing strains. The TARS-AI software already includes a motion system, so much of this may be provided for you, but understanding how it works is what lets you customize it and give your TARS its own character.

A pose is just a set of angles

The simplest way to describe how TARS stands or gestures is as a pose: one target angle for every servo. Because you mapped each servo to a channel during assembly, a pose is nothing more than a list of channel-and-angle pairs. Storing poses as data, a dictionary or array of angles, is the Month 1 idea of using a data structure to keep related values organized. To strike a pose you set each servo to its angle; to move between poses, you change those angles over time.

Functions, gaits, and safe limits in code

You do not want to rewrite raw servo commands every time TARS waves or steps, so you wrap each move in a function, exactly the functions-and-modularity lesson from Month 1. A gait, TARS's walk, is then a sequence of poses played in order and repeated, and you step the angles gradually between poses so motion is smooth rather than a jerk that strains the servos. Crucially, you build the servo's safe range into your move function so a bad pose can never drive a joint past its limits and crack a printed part:

import time

STAND  = {0: 90, 1: 90, 2: 90, 3: 90}
STEP_L = {0: 70, 1: 110, 2: 90, 3: 90}
STEP_R = {0: 110, 1: 70, 2: 90, 3: 90}
SAFE = {ch: (30, 150) for ch in range(4)}   # min, max per joint

def clamp(ch, angle):
    lo, hi = SAFE[ch]
    return max(lo, min(hi, angle))          # never exceed the safe range

def go_to(pose):
    for ch, angle in pose.items():
        servos[ch].angle = clamp(ch, angle)

def walk(steps=4):
    for _ in range(steps):                  # a gait is a repeated sequence
        go_to(STEP_L); time.sleep(0.4)
        go_to(STAND);  time.sleep(0.2)
        go_to(STEP_R); time.sleep(0.4)
        go_to(STAND);  time.sleep(0.2)

Poses are data, go_to is a reusable move that clamps every angle to a safe range, and walk sequences poses into a gait. That is Month 1 data structures, functions, and loops driving a physical robot, with safety built in so a typo in a pose cannot damage TARS.

Tying gestures to what TARS is doing

TARS feels alive when its body matches its words. Using a state machine, the Month 1 concept, you track what TARS is doing, idle, listening, thinking, speaking, and trigger a gesture for each state: a small nod while it listens, a gesture while it talks. Because speaking and moving both run on the Pi, you coordinate them so a gesture plays as TARS delivers a line, which is where its AI mind and its physical body finally act as one. This is exactly the kind of behavior you will shape in the capstone to make TARS distinctly yours.

The TARS-AI software provides the motion framework

The TARS-AI project includes a motion system with the servo mappings and movements already worked out, so you often extend or tune it rather than write it from scratch. Explore their code and docs to see how their motion is structured, and their Discord is where builders share custom gaits and gestures:

Docs and code: docs-tars-ai.vercel.app · GitHub: github.com/TARS-AI-Community/TARS-AI · Discord: discord.gg/AmE2Gv9EUt

Whether you write motion yourself or tune what TARS-AI provides, the ideas are the ones you already own: poses as data, moves as functions, a gait as a loop, a state machine to coordinate it with speech, and safe limits so the robot never hurts itself. That is programming from Month 1, now walking across your desk.