Look at the commanded movement

The nod was too abrupt. The original gesture code could move its pulse target by 40 microseconds every 40 milliseconds, and it started and stopped at that full rate. A focused nod test reproduced the abrupt first command. Changing only the timer period didn't remove it.

Ease into each move

The revised development code follows an eased trajectory at a nominal 20-millisecond interval. The curve starts and ends with zero velocity and zero acceleration. What actually goes out is still a series of rounded commands to a hobby servo, not measured shaft positions.

Account for imperfect timing

A second test added small delays to the callbacks, because real timers are never perfectly on time. Scheduling each new sample from the moment the callback arrived let the drift pile up. Holding the intended timer phase within a small tolerance let the greeting complete all six of its targets in the test.

What the tests don't show

The tests check commanded trajectories, limits, stops, and returns to neutral. They don't measure how the real head accelerates; power, mechanical load, and the servo's own controller all have a say. When I wrote the development note, this change hadn't yet been tried on the assembled robot.