Kevin Corvisier
← Hexapod overview

Hexapod, part 2 of 4

Gait & kinematics

How a velocity command becomes twenty servo positions: the geometry of one leg, the equations that place its foot, the path each foot follows, and the timing that keeps three feet on the ground at all times.

The real hexapod walking with the scripted tripod gait described on this page.

One leg, three joints

Each leg is a three-joint chain. The coxa joint swings the leg forward and back around a vertical axis. The femur and tibia joints lift and extend it in a vertical plane. Six of these legs sit around the body: the middle pair points straight out, and the front and rear pairs are angled at 45°.

Side view of one leg: coxa 37.5 mm, femur 100 mm, tibia 149.3 mm, standing about 70 mm below the hip body d θf γ coxa 37.5 mm femur 100 mm tibia 149.3 mm foot r z ≈ 70 mm standing height
Side view of one leg in its standing pose, drawn to scale. The coxa joint turns around a vertical axis; the femur and tibia joints work in the vertical plane shown.

Inverse kinematics

The gait works in foot positions, not joint angles: it decides where each foot should be, and a small solver turns that target (x, y, z), measured from the coxa joint, into three angles. The coxa angle comes straight from the direction of the target. With the coxa set, the femur and tibia form a triangle with the line d from the femur joint to the foot, and the law of cosines gives both angles:

r = √(x² + y²) − Lcoxa d = √(r² + z²) θcoxa = atan2(y, x) θfemur = atan2(z, r) + arccos( (Lfemur² + d² − Ltibia²) / (2 · Lfemur · d) ) γ = arccos( (Lfemur² + Ltibia² − d²) / (2 · Lfemur · Ltibia) ) θtibia = −(π − γ)

If a target is out of reach, d is clamped to the length of the fully stretched leg so the arccosines stay defined, and the leg simply extends as far as it can. The same lengths run the other way in the odometry node, where forward kinematics turns measured joint angles back into foot positions (see part 3).

The path of a foot

Each step has two phases. In stance the foot is on the ground and slides backwards in a straight line relative to the body, which pushes the body forwards. In swing it lifts off, travels forward through the air and lands at the front of its range. The swing follows a cubic Bézier curve. Its four control points make the foot leave and land almost vertically, so it doesn't scuff the ground at either end.

Foot trajectory: a straight stance stroke of 150 mm along the ground and a Bézier swing arc that peaks at 37.5 mm stance: straight line, 70% of the cycle swing: cubic Bézier, 30% of the cycle 37.5 mm clearance step 150 mm rear front
One foot's path relative to the body, with the default parameters. Squares are the Bézier control points: placed 50 mm up, they give a 37.5 mm peak.

To walk in any direction without turning first, the whole stroke is rotated by atan2(vy, vx) before solving the kinematics. To turn, the strokes on the left and right sides run in opposite directions, scaled by the yaw rate, much like a tracked vehicle. When the command contains both, the two strokes are blended.

3D plot of six red dotted arcs: the swing trajectory of each foot, each one rotated to its leg's direction around the body
All six foot trajectories in 3D, in metres around the body centre: the same Bézier arc, rotated to each leg's mounting angle.

Timing the legs

A gait is just a phase offset per leg. The default is the tripod: legs R1, R3 and L2 move together, alternating with R2, L3 and L1, so there are always at least three feet on the ground forming a triangle under the centre of mass. Each stance phase also gets a 20% overlap, so between swings all six feet are on the ground for a moment.

Tripod gait timing over two 3-second cycles: two groups of three legs alternate, with short periods where all six feet are down R1 R2 R3 L3 L2 L1 0 1 2 3 4 5 6 s
Which feet are on the ground (filled bars) over two cycles of the scripted tripod gait. Shaded: the overlap where all six feet are down. Compare with the gait the RL policy found by itself in part 4.

The phase offsets are ROS parameters, so the gait can be changed while the robot runs:

GaitLegs moving at onceCharacter
Tripod3Fastest; always a stable triangle of support
Bipod2Four feet down at any time; slower, sturdier
Ripple1Legs swing one after another around the body; slowest, most stable

Cycle time, step length, step height and body height are live parameters too. With the default 3-second cycle and 150 mm stroke, the body moves at about 7 cm/s. Shortening the cycle makes it walk faster.

Tripod.
Ripple.
Bipod.

From node to servos

The gait controller is a ROS 2 node that listens to a standard cmd_vel velocity command, so a gamepad, a voice command or the Nav2 planner can all drive it the same way. Ten times per second it computes the six foot targets, solves the kinematics and sends each leg a short trajectory goal to reach in 0.15 s.

The same controller driving the robot in Isaac Sim: standing up, walking under keyboard teleoperation, and sitting back down.

Limits of a scripted gait

The gait is open-loop. It doesn't sense when a foot touches the ground, so on uneven terrain a foot can land early or late without the timing adapting. It also assumes all six legs work. Those two limits are what led to the learned controllers in part 4.