Skip to content

Controller and steering

The controller genome and the oscillator that drives each joint. The steering command is described in Fitness and tasks.

Controller genome (darwinbot/controller.py)

Length: CTRL_LENGTH = 1 + MAX_NODES * 8 = 161, indexed by the same node slot ids.

Index Gene Range Meaning
0 frequency 0.3 - 1.5 Hz global natural frequency, omega = 2*pi*frequency

Per node slot s, with base b = 1 + 8 * s:

Offset Gene Range Meaning
+0, +1 amp1, phase1 0 - 0.8 rad, 0 - 2*pi first harmonic
+2 offset -0.6 - 0.6 rad joint centre (for a wheel: signed speed, -4.71 - 4.71 rad/s)
+3, +4 amp2, phase2 0 - 0.8 rad, 0 - 2*pi second harmonic
+5 sigma -3 - 3 rad/s load feedback gain (Tegotae)
+6, +7 steer_gain, steer_shift -1 - 1, -0.4 - 0.4 rad effect of the steering command c in [-1, 1]: amplitudes times 1 + c * steer_gain, offset plus c * steer_shift (a wheel: speed plus c * steer_shift, in rad/s)

Every joint has its own phase oscillator, driven by its servo load:

dtheta_i/dt = omega - sigma_i * N_i * cos(theta_i)
target_i    = ramp(t) * (offset_i + amp1_i * sin(theta_i + phase1_i)
                                  + amp2_i * sin(2 * theta_i + phase2_i))

N_i is the servo load divided by the maximum torque, between -1 and 1: the actuator force in simulation and the STS3215 load register on the real robot. Legs that carry weight slow down or speed up their own phase, so coordinated gaits can appear without programmed coupling between legs (Tegotae, Owaki et al.). With sigma = 0 it is an open-loop CPG. ramp fades the gait in over RAMP_TIME = 0.5 s. Genes of absent modules are ignored, and a wheel only uses its offset gene. The total amplitude is clipped so that (amp1 + 2 * amp2) * omega <= 4.71 rad/s, the servo speed limit. The simulation updates the servo targets at 50 Hz and holds them in between, like the ESP32.