MH-FLOCKE MH-FLOCKE
HomeDocsGitHubBlogPaperYouTubeReddit𝕏

Reflexes & Terrain Adaptation

Spinal Reflexes and Terrain Adaptation

Below the cognitive brain and even below the CPG, MH-FLOCKE implements a spinal reflex system that provides fast, automatic responses to perturbations. These reflexes operate without any learning — they are hardwired emergency responses.

Spinal Segments

Each joint is governed by a spinal segment that implements three mechanisms:

  • Muscle Tone — Baseline stiffness that prevents joints from collapsing under gravity
  • Stretch Reflex — Resists unexpected perturbations. When a joint is displaced from its commanded position, the stretch reflex generates a corrective torque proportional to the displacement. Biology: muscle spindles → Ia afferents → α-motoneurons (Sherrington 1906)
  • Golgi Tendon Organ — Limits excessive force. When torque exceeds a threshold, the GTO inhibits the motoneuron to prevent tendon damage. This acts as a safety limiter.

Crossed Extension Reflex

When one leg loses contact with the ground (detected via foot contact sensors), the contralateral leg extends to maintain balance. This is implemented as a direct coupling between diagonal leg pairs.

Righting Reflex

A 4-phase recovery sequence when the creature falls:

  1. Tuck — Pull all limbs in to reduce moment of inertia
  2. Roll — Use asymmetric limb extension to rotate to prone position
  3. Crouch — Extend limbs to ground contact, low center of gravity
  4. Push — Extend fully to standing position

Terrain Reflex

Proprioceptive terrain adaptation modulates the CPG based on slope detection:

  • Foot Contact — Binary detection per foot (FL, FR, RL, RR). Loss of expected contact triggers corrective responses.
  • Slope Estimation — Pitch and roll estimated from IMU data via exponential moving average
  • CPG Modulation — Frequency decreases on steep slopes (cautious), amplitude increases on rough terrain (higher steps)

Dynamic Reflex Scaling

Reflex intensity scales with instability:

instability = max(0, 1 − upright)
urgency = min(1, instability² / 0.49)
reflex_scale = scale_standing + (scale_fallen − scale_standing) × urgency

When perfectly upright, reflexes are gentle. As the creature tilts, reflexes become increasingly aggressive. This prevents the reflexes from fighting the CPG during normal walking while providing strong corrections during balance crises.

References

  • Sherrington, C.S. (1906). The Integrative Action of the Nervous System. Yale University Press
  • Pearson, K.G. (2004). Generating the walking gait: role of sensory feedback. Progress in Brain Research
  • Duysens, J. et al. (2000). Neural control of locomotion. Physical Therapy

API Reference

SpinalReflexes(n_actuators, config: ReflexConfig)

Posture-aware reflex chain sequencer. Tracks 9 posture states, activates appropriate reflexes per state.

compute(sensor_data, is_fallen, sim_dt) → np.ndarray

Compute reflex commands based on current posture state. Updates state machine, dispatches to posture-specific handler.

  • sensor_data — dict with upright, forward_velocity, height, orientation_euler, joint_positions
  • Returns: [n_actuators] added to motor commands

Posture States (PostureState enum)

SUPINE → ROLLING → PRONE → PUSHING_UP → CROUCHING → RISING → STANDING → WALKING
                                                                    ↓
                                                              DESTABILIZED

SpinalSegments(n_actuators, config: SpinalSegmentConfig)

Per-joint spinal reflexes. Always active, runs AFTER reflex chains.

process(motor_commands, joint_positions, sim_dt) → np.ndarray

Full pipeline: muscle tone + stretch reflex + Golgi tendon organ + clip. This is the LAST biological layer before actuators.

TerrainReflex(config, n_actuators)

Proprioceptive slope compensation and force balancing.

compute(sensor_data) → np.ndarray

Slope compensation (pitch/roll → leg adjustment), contact force balancing, and CPG modulation (freq_scale, amp_scale). Added to motor commands after CPG + cerebellum.

RightingReflex(n_actuators)

4-phase vestibular righting: Tuck (0–80 steps) → Roll (80–160) → Crouch (160–250) → Push (250+). Active only when is_fallen=True.

FootContactSensor

initialize(model)

Find foot geom IDs (FL, FR, RL, RR) in MuJoCo model.

update(model, data, step)

Read MuJoCo contact array. Outputs: contacts[4], forces[4], contact_onset[4], contact_offset[4].

VisualOrientingResponse(config: VORConfig)

Brainstem reflex: PD controller turns body toward visual target.

compute(target_heading, target_distance, upright, cpg_weight) → float

Steering signal (-0.25 to +0.25). P-term: sqrt(heading) for gentle small / assertive large corrections. D-term: heading change rate damping. CPG-weight compensation for SNN dilution. EMA smoothed.