An end-to-end hexapod robotics project — full mechanical CAD, autonomous Arduino-Mega firmware with closed-loop IMU heading hold, and a Python central-pattern-generator simulation built on six Kuramoto-coupled phase oscillators where wave / ripple / tripod gaits emerge from a single parameter rather than being hard-coded.
The hexapod, fielded at the Great Sand Dunes for a robotics challenge. 18-DoF body, fully 3-D-printed chassis, autonomous Arduino-Mega firmware with closed-loop IMU heading hold and bump-avoidance.
The CPG simulator dashboard — left: 3-D body and per-leg foot trails; top right: the phase wheel; middle right: a rolling gait diagram; bottom right: a live status panel. All four panels are driven from one ``FuncAnimation`` loop at 30 fps.
- Overview
- Highlights
- The robot in the field
- Simulator gallery
- Mathematical foundations
- Repository layout
- Quick start
- Reproducing every figure & animation
- Firmware overview
- Hardware overview
- Testing
- Roadmap
- References
- Citation
- License
This repository documents a hexapod robot built from the ground up: a fully 3-D-printed chassis (~75 printed parts, all included as STL), an Arduino-Mega-2560 firmware stack with closed-loop IMU heading hold + bump-avoidance + scripted performance routines, and a Python central-pattern-generator (CPG) simulation that turns a network of six coupled Kuramoto oscillators into smooth, gait-correct locomotion.
The interesting bit is the CPG: rather than hard-coding the wave / ripple / tripod gait patterns, the simulation lets them emerge from the dynamics of the oscillator network as a single parameter — the natural-frequency drive ω — is varied. Watch a phase wheel collapse from random initial conditions into the tripod attractor and you get an unusually clean intuition for why bio-inspired locomotion controllers work.
Why this matters. Hexapod gait is usually presented as a fixed set of phase tables ("five down, one up" for wave; "three down, three up" for tripod). This project shows that all three patterns are stable attractors of the same coupled-oscillator network — the gait you observe is a continuous function of ω, and the transition between gaits is something the CPG handles for free.
| Capability | Implementation | Verified to |
|---|---|---|
| 6-oscillator Kuramoto CPG with smooth wave⇄tripod blending | hexapod_cpg.cpg.CPGNetwork |
high-ω locks to coherence > 0.85 in < 5 s; survives π perturbation kicks |
| 18-DoF analytical inverse kinematics with reach + servo-limit checks | hexapod_cpg.geometry.ik |
round-trip IK→FK exact at neutral pose for every leg |
| Foot-trajectory generator (cosine stance, smoothstep swing, sin-arc lift) | hexapod_cpg.cpg.CPGNetwork._feet_from_phases |
ω-dependent duty factor 0.50–0.72 |
| Real-time 4-panel matplotlib dashboard (3-D, phase wheel, gait diagram, status) | hexapod_cpg.viz.CPGViz |
30 fps on a stock laptop |
| Closed-loop IMU heading hold (P + complementary filter) on the real robot | firmware/hexapod_full/ |
gyro-bias auto-cal + mag fusion; field-tunable K_p and α in config.h |
| Bump-avoidance state machine (walk → backup → turn → walk) | firmware/hexapod_full/ |
1.5 s debounce, ramped speed transitions |
| 6 scripted performance routines (wave, sway, pump, twist, stomp, full) | firmware/hexapod_full/ |
open-loop time-varying foot-position offsets |
| Programmatic CAD bill-of-materials (≈75 printed parts) | hardware/cad/ |
STL + SolidWorks + STEP + Fusion archive |
34 pytest tests running on every push across Python 3.10/3.11/3.12 on Ubuntu and macOS via GitHub Actions. The suite is < 1 s wall-clock.
The whole controller pipeline collapses to three layered ideas; skip if familiar.
Each leg is one phase oscillator
with
The phase-offset matrix
-
$\theta^{\mathrm{wave}}$ — even 60° spacing front-to-back (LF=0°, LM=60°, LB=120°, RF=180°, RM=240°, RB=300°); -
$\theta^{\mathrm{tripod}}$ — two anti-phase groups (group A: LF, LB, RM at 0°; group B: RF, LM, RB at 180°).
The blend coefficient is
Integration is explicit midpoint (RK2) at the visualiser frame rate
(
Phase
The duty factor itself decreases with
The stride vector
For a target foot position
with reach checks against the femur+tibia 2-link chain and servo-range checks before the result is marked valid.
The Arduino firmware runs a fixed-rate (50 Hz) yaw P-controller fed by a complementary filter that fuses the IMU's gyro Z and magnetometer:
where
hexapod-cpg/
├── sim/ # Python CPG simulation (the package)
│ ├── hexapod_cpg/ # importable Python package
│ │ ├── __init__.py # public API
│ │ ├── geometry.py # 18-DoF IK + body geometry
│ │ ├── cpg.py # 6-oscillator Kuramoto network
│ │ ├── gait.py # wave / ripple / tripod taxonomy
│ │ ├── colors.py # palette + ω → colour map
│ │ ├── viz.py # 4-panel matplotlib dashboard
│ │ └── py.typed
│ ├── scripts/ # one-shot rendering and demo drivers
│ │ ├── run_interactive.py # launch the dashboard
│ │ ├── render_coupling_graph.py
│ │ ├── render_omega_sweep.py
│ │ ├── render_workspace_map.py
│ │ ├── render_oscillator_timeseries.py
│ │ ├── render_gait_comparison.py
│ │ ├── render_foot_trajectories.py
│ │ ├── render_phase_wheel_animation.py
│ │ ├── render_3d_walk_animation.py
│ │ └── render_all.py # regenerates the entire gallery
│ └── tests/ # 34 pytest tests
│
├── firmware/ # Arduino-Mega 2560 firmware
│ ├── hexapod_full/ # IMU heading-hold + bump-avoid + dance routines
│ │ ├── hexapod_full.ino
│ │ └── config.h # all field-tunable constants
│ ├── legacy_ps2/ # original PS2-controller firmware (multi-gait)
│ │ └── legacy_ps2.ino
│ ├── ps2_test/ # diagnostic for the PS2 receiver
│ │ └── ps2_test.ino
│ └── README.md # firmware architecture, gain tuning, state machines
│
├── hardware/ # mechanical CAD
│ ├── cad/
│ │ ├── stl/ # 22 STL files (printable parts)
│ │ ├── sldprt/ # 12 SolidWorks part files
│ │ └── assembly/ # full-robot assembly + STEP + Fusion archive
│ └── README.md # printed-parts list + electronics BOM
│
├── docs/ # supplemental documentation
│ ├── wiring.md # full Arduino-Mega pin map
│ └── printing_instructions.docx
│
├── figures/ # static PNGs emitted by the renderers
├── animations/ # animated GIFs + dashboard MP4
├── pyproject.toml # PEP 517/518 build + tooling
├── requirements.txt
├── requirements-dev.txt
├── Makefile # `make install`, `make test`, `make gallery`
├── .github/workflows/ci.yml # multi-OS / multi-Python CI
├── CITATION.cff
├── LICENSE # MIT
└── README.md # you are here
git clone https://github.com/Janga786/hexapod-cpg.git
cd hexapod-cpg
python -m venv .venv && source .venv/bin/activate
make dev # editable install + dev tools
make test # 34 passed in < 1 s
make sim # launch the live dashboard
make gallery # regenerate every figure + animation (≈3 minutes)Dependencies are intentionally light: numpy, matplotlib, pillow. Tested on Python 3.10, 3.11, 3.12.
import numpy as np
from hexapod_cpg import CPGNetwork
cpg = CPGNetwork(omega=5.0, rng=np.random.default_rng(42))
cpg.set_walking(direction_deg=0.0) # walk forward
for _ in range(int(5.0 / 0.02)): # 5 s @ 50 Hz
feet = cpg.step(0.02)
print(f"locked-in coherence : {cpg.phase_coherence():.2f}")
print(f"flange of LF leg : {feet['LF']}")make gallery # one shot — regenerates /figures and /animationsOr call the renderers individually:
| Renderer | Outputs |
|---|---|
python sim/scripts/render_coupling_graph.py |
figures/coupling_graph.png |
python sim/scripts/render_omega_sweep.py |
figures/omega_sweep.png |
python sim/scripts/render_workspace_map.py |
figures/leg_workspace.png |
python sim/scripts/render_oscillator_timeseries.py |
figures/oscillator_timeseries.png |
python sim/scripts/render_gait_comparison.py |
figures/gait_comparison.png |
python sim/scripts/render_foot_trajectories.py |
figures/foot_trajectories.png |
python sim/scripts/render_phase_wheel_animation.py |
animations/phase_wheel_lockin.gif |
python sim/scripts/render_3d_walk_animation.py |
animations/walk_{wave,ripple,tripod}.gif |
All renderers are seeded → re-running on the same machine always produces byte-identical artefacts.
firmware/hexapod_full/hexapod_full.ino is the flagship sketch. A
3-bit binary command interface (latched on the rising edge of a confirm
pin) selects between eight behaviours; the truth table lives in
firmware/README.md. The 010 command engages
forward walk with an IMU heading-hold P-controller, a complementary
filter for gyro/mag fusion, and a bump-avoidance state machine that
backs up + rotates 90° away from any obstacle the front feet hit.
All field-tunable constants — HEADING_KP, COMP_ALPHA, the bump
timings, and per-axis servo-calibration offsets — live in
firmware/hexapod_full/config.h,
not scattered through the .ino.
The legacy legacy_ps2.ino sketch is preserved as the simplest path
to a working hexapod (PS2-controller piloted; tripod / ripple / wave /
tetrapod gaits selectable from the d-pad), useful for first-light
testing of a new build.
The chassis is fully 3-D-printed (PLA + TPU foot bumpers). All
22 STL files, the SolidWorks source, the full-robot STEP export, and
a Fusion-360 archive are under hardware/cad/.
Total: ≈ 75 printed parts.
The electronics:
- 1 × Arduino Mega 2560
- 18 × hobby servos (~7-9 kg·cm)
- 1 × SparkFun ICM-20948 9-DoF IMU
- 2 × foot-pad bump switches
- 8 × dual-colour LEDs (battery-status bar)
- 1 × LiPo (2S/3S) + SBEC
Full pinout is in docs/wiring.md.
make test # 34 tests, < 1 s
python -m pytest sim/tests/test_cpg.py -v # one module, verbose
python -m pytest --cov=hexapod_cpg # with coverageThe test suite covers:
- IK reachability + IK→FK round-trip for every leg at neutral pose
- Workspace boundary handling (unreachable targets marked invalid)
- Coupling-matrix invariants (symmetry, no self-coupling)
- Tripod target offsets are exactly π for every cross-group pair
- High-ω lock-in convergence to coherence > 0.85 in < 5 s
- Low-ω wave-gait coherence > 0.6 in < 8 s
- Pattern coherence drops on a π perturbation and recovers afterwards
- Stop / start / clamp behaviour on the speed setter
- Smoothstep gait-blend monotonicity and clamping
- Duty-factor monotonic decrease with ω
- Hardware-in-the-loop bridge. Pipe the Python CPG's foot trajectories straight to the Arduino over serial so the real robot walks under simulator control — closing the loop between the research-grade controller and the production firmware.
- Sensor-feedback CPG. Couple ground-contact sensors (currently only the front bump switches) into the oscillator network so a missed footfall locally re-tunes phase, mimicking insect proprioception.
- MuJoCo / Mujoco-py port. Re-target the geometry module onto MuJoCo for contact-rich rigid-body simulation. The kinematics are already factored cleanly enough that this is mostly a matter of generating the XML.
- Closed-form gait optimisation. Search ω, K, σ jointly to minimise cost-of-transport on rough terrain — a small reinforcement-learning loop on top of the existing CPG.
- Y. Kuramoto. Chemical Oscillations, Waves, and Turbulence. Springer, 1984.
- A. Ijspeert. "Central pattern generators for locomotion control in animals and robots: a review." Neural Networks 21(4), 2008.
- J. Schmitz et al. "Behaviour-based modelling of hexapod locomotion: linking biology and technical application." Arthropod Structure & Development 33, 2004.
- R. D. Quinn & R. E. Ritzmann. "Construction of a hexapod robot with cockroach kinematics benefits both robotics and biology." Connection Science 10(3-4), 1998.
- Mark W., Hexapod skeleton design, projectsofdan.com (mechanical design + PS2 firmware origin).
- SparkFun Electronics. ICM-20948 Arduino Library.
- Bill Porter. PS2X Arduino Library. http://www.billporter.info/
If you reference this code, please cite via the
CITATION.cff file or BibTeX below:
@software{janga2026hexapod,
author = {Janga, Bliss},
title = {Hexapod CPG: Bio-inspired Locomotion on a Custom 18-DoF Robot},
year = {2026},
version = {1.0.0},
url = {https://github.com/Janga786/hexapod-cpg},
license = {MIT}
}MIT — software is free for commercial, academic and educational use.
The mechanical chassis design derives from the open-source
Mark W. hexapod skeleton (see LICENSE).
"Six legs. Six oscillators. Synchronisation does the rest."












