Skip to main content

NeckCompass (neckcompass v1.0.0)

Biophysical Drosophila Central Complex ring-attractor compass and GPS-denied path integrator with natural ferromagnetic spike rejection — in Python and zero-heap, zero-float ANSI C99 (316 B RAM, ~1 us/step).

PyPI Release Python ANSI C99 C99 Self-Tests Pytest License: MIT

30-Second Quick Start · Plastic Harbor Calibration · Zero-Float ANSI C99 MCU Core · Honest Benchmarks · When to Use (and When Not To)

NeckCompass v1.0.0 Ring Attractor & Path Integrator Benchmarks


Why NeckCompass?

Marine USVs, inspection drones, subsea rovers, and factory AGVs operate around steel ship hulls, sheet-pile docks, high-current motor leads, and buried power cables that inject intermittent 70°–150° ferromagnetic heading spikes lasting 0.5–2.0 s. Standard linear-Gaussian estimators break down in this regime:

  • Gyro Dead-Reckoning ignores magnetic anomalies completely, but MEMS gyro bias (~0.8–1.5°/s) drifts unboundedly (50°–100°+ within minutes).
  • 2-State Circular Extended Kalman Filters ([heading, gyro_bias]) are minimum-variance optimal under textbook Gaussian noise, but a 120° ferromagnetic anomaly feeds through the Kalman cross-covariance straight into the gyro bias state, causing both massive heading yanks (45°+ P95) and post-spike bias hangovers.

NeckCompass ports the neural navigation circuit of the fruit-fly (Drosophila melanogaster) Central Complex into a deterministic software and microcontroller library — Product #3 in the NeckLink fruit-fly brain engineering family:

  1. Ellipsoid Body (E-PG) Ring Attractor + Delta7 Inhibition + P-EN Shifters (RingCompass): Maintains a single topological activity bump across N=16 (or N=32) circular wedges with zero -π ↔ +π wrap-around discontinuity (< 10⁻¹⁵ rad harmonic aliasing on even-N rings). Asymmetric Left/Right P-EN projections integrate IMU yaw rate (omega_rad_s * dt), while localized R-neuron sensory cues (mag_heading_rad, sun_heading_rad) undergo cooperative dendritic coincidence gating against the active E-PG bump — smoothly anchoring gyro drift inside the attractor basin while naturally shunting 70°–150° ferromagnetic spikes (10.2× lower RMSE than 2-State EKF).
  2. Associative R-Neuron → E-PG Synaptic Plasticity (PlasticLandmarkRing): Movement-gated Hebbian / anti-Hebbian ring weight matrix that learns warped local soft-iron and hard-iron magnetic distortion tables online around steel harbors or indoor rooms — with or without an external sun/visual reference.
  3. Fan-Shaped Body CPU4 Path Integrator + PFL3/PFL2 Steering (FanBodyNavigator): N=16 push-pull opponent memory columns integrate translational speed along the live E-PG compass bump with common-mode cancellation, computing exact (distance_m, home_bearing_rad) and ±67.5° phase-shifted PFL3 + 180° PFL2 motor yaw commands to steer straight home during complete GPS blackouts (0.84 m miss after a 1,125 m spiky mission).
  4. Zero-Heap, Zero-Float ANSI C99 Core (csrc/): Pure Q15 / int32_t 16-wedge ring attractor + CPU4/PFL3 navigator using 316 bytes of struct RAM (576 bytes total including 260 B Flash LUTs), zero malloc, zero floating-point instructions, and ~1.0 us per update — ready for $4 ESP32, STM32, RP2040, and flight controllers.
flowchart LR
    IMU["IMU Gyro Yaw Rate (omega_rad_s)"] --> PEN["P-EN Left/Right Velocity Shifters"]
    PEN --> EPG["16-Wedge E-PG Ring Attractor + Delta7 Inhibition"]
    MAG["Spiky Magnetometer / Sun Azimuth"] --> RN["R2 / R4d Ring Neurons (Plastic W + Basin Gate)"]
    RN -->|"Coherent cues anchor drift; 70-150 deg spikes shunted"| EPG
    EPG --> CPU4["16 Opponent CPU4 Memory Columns (+ Speed)"]
    CPU4 --> PFL3["PFL3 (+/-67.5 deg) + PFL2 (180 deg) Steering"]
    PFL3 --> HOME["GPS-Denied Homebound Yaw Command"]

⚡ 30-Second Quick Start

1. Python (pip install neckcompass)

pip install neckcompass
# Or directly from source:
pip install git+https://github.com/indian-aman/neckcompass.git

Fuse a biased IMU gyro with a spiky magnetometer and steer home through a complete GPS blackout in 14 lines:

import math
from neckcompass import RingCompass, FanBodyNavigator

compass = RingCompass(n_wedges=16, initial_heading_rad=0.0)
nav = FanBodyNavigator(n_columns=16, compass=compass)

# Outbound step @ 50 Hz (dt = 0.02 s): 125-deg hull spike is rejected automatically!
heading_rad, dist_m, home_bearing_rad = nav.step_with_compass(
    omega_rad_s=0.15,
    speed_m_s=1.5,
    dt=0.02,
    mag_heading_rad=math.radians(125.0),  # Transient ferromagnetic spike -> gated out
)

# During GPS blackout, generate bounded [-0.8, +0.8] rad/s yaw command back to (0, 0):
yaw_rate_cmd = nav.steering_cmd(max_turn_rate=0.8)

Run the built-in CLI demo or head-to-head quick benchmark from your terminal:

neckcompass demo
neckcompass benchmark-quick

2. Online Soft-Iron / Harbor Distortion Learning (PlasticLandmarkRing)

When operating repeatedly inside a steel marina slip or indoor robot bay with static nonlinear magnetic warp (+20° sin(ψ) + 16° sin(2ψ)), PlasticLandmarkRing learns the R-neuron → E-PG unwarping matrix online:

from neckcompass import PlasticLandmarkRing

plastic = PlasticLandmarkRing(n_wedges=16, n_ring_neurons=32)

# Self-supervised during normal turns (or pass reference_heading_rad=sun_rad when sky is visible)
corrected_heading = plastic.update(
    omega_rad_s=imu_gz,
    dt=0.02,
    raw_mag_heading_rad=raw_mag_rad,
    learn=True,
)
unwarped_mag_rad, confidence = plastic.map_raw_heading(raw_mag_rad)

3. Zero-Heap, Zero-Float ANSI C99 Core (csrc/)

Drop csrc/neckcompass.h and csrc/neckcompass.c into any ESP32, STM32, RP2040, ArduPilot, or bare-metal firmware project (-std=c99 -Wall -Wextra -pedantic -Werror, zero FPU, zero malloc):

make -C csrc clean all test
#include "neckcompass.h"

nc_compass_t comp;
nc_navigator_t nav;

void autopilot_init(void) {
    nc_compass_init(&comp);
    nc_compass_reset(&comp, nc_cdeg_to_bam(0));
    nc_navigator_init(&nav, 1500); /* 1.5 m smooth arrival taper */
}

/* 50 Hz deterministic fixed-point loop (~1.0 us on desktop, < 8 us on ESP32) */
int32_t autopilot_step_50hz(int32_t gyro_cdeg_s, int32_t mag_cdeg, int32_t speed_mm_s) {
    nc_bam_t heading = nc_compass_update(
        &comp,
        nc_cdeg_to_bam(gyro_cdeg_s),
        20u,                           /* dt = 20 ms */
        nc_cdeg_to_bam(mag_cdeg), 1u, NC_Q15_ONE,
        0, 0u, 0                       /* optional sun/sky sensor */
    );
    nc_navigator_update(&nav, speed_mm_s, 20u, heading);
    return nc_navigator_steering_cmd(&nav, heading, nc_cdeg_to_bam(4500));
}

📊 Honest Empirical Benchmarks (5 Seeds @ 50 Hz)

Reproduce all numbers and regenerate assets/neckcompass_benchmarks.png + results/benchmark_summary.json locally:

python scripts/benchmark_neckcompass.py

All four estimators receive the exact same 50 Hz sensor streams across 5 seeds (101–105): realistic MEMS gyro bias (~0.9°/s initial offset + 0.08°/s/√s random walk + 1.5°/s white noise) and 3.0° Gaussian magnetometer noise. The 2-State Circular EKF is given the exact true clean discrete-time process and measurement noise covariances (Q, R) with zero handicap.

1. Heading Accuracy: Clean Gaussian Noise vs. 70°–150° Ferromagnetic Spikes

Mean ± std across 5 seeds (180 s trajectories @ 50 Hz):

Estimator Scenario A: Clean Gaussian RMSE Scenario A: P95 Scenario B: Spiky Mag RMSE Scenario B: Spiky Mag P95 Scenario B: Max Error
NeckCompass (E-PG 16w) 0.43° ± 0.02° 0.86° ± 0.03° 1.70° ± 0.18° 4.27° ± 0.37° 10.55° ± 1.88°
2-State Circular EKF 0.39° ± 0.02° (wins) 0.77° ± 0.03° 17.42° ± 0.93° 45.28° ± 2.63° 82.53° ± 7.50°
Complementary IMU+Mag 3.64° ± 1.54° 5.34° ± 1.80° 11.80° ± 0.54° 27.77° ± 1.30° 47.45° ± 4.87°
Gyro Dead-Reckoning 90.22° ± 32.41° 141.70° ± 46.28° 84.80° ± 30.74° 139.91° ± 53.31° 145.98° ± 55.90°

2. Scenario C: 600 s Outbound Survey + Blind GPS-Blackout Return (~1,125 m Total Path)

A USV / rover executes a 10-minute (900 m) multi-leg survey in complete GPS blackout (2% wheel/water-speed noise + biased MEMS gyro + intermittent 70°–150° ferromagnetic spikes), then autonomously steers back to (0, 0):

Navigation Stack Return-to-Home Miss (m) Miss % of 1.12 km Path RAM / State Footprint Step Latency
NeckCompass (C99 Q15 Core) 0.32 m (158 m selftest) 0.20% 316 B RAM (576 B w/ LUT) ~1.04 us / step
NeckCompass (Python E-PG + CPU4) 0.84 ± 0.23 m 0.07% ± 0.02% 3,143 B 171.26 us / step
Complementary IMU+Mag + DR 13.31 ± 3.08 m 1.19% ± 0.28% ~256 B ~6.5 us / step
2-State Circular EKF + DR 14.29 ± 6.95 m 1.28% ± 0.63% 5,792 B (Py) 13.58 us / step (Py)
Gyro Dead-Reckoning 256.74 ± 52.38 m 24.16% ± 5.69% ~128 B ~2.0 us / step

🎯 When to Use NeckCompass — and When Not To


🗂️ Repository Layout

Path Contents
neckcompass/ring_attractor.py RingCompass (N=16/32 E-PG ring attractor + P-EN shifters + multi-cue basin gating) & PlasticLandmarkRing (R-neuron → E-PG Hebbian/anti-Hebbian distortion learner)
neckcompass/path_integrator.py FanBodyNavigator (N=16 opponent CPU4 vector memory + PFL3/PFL2 GPS-denied homebound steering)
neckcompass/cli.py neckcompass CLI (neckcompass demo, neckcompass benchmark-quick)
csrc/ Zero-heap, zero-float ANSI C99 fixed-point Q15 core (neckcompass.h, neckcompass.c, Makefile, and 6/6 neckcompass_selftest.c)
scripts/benchmark_neckcompass.py Reproducible 5-seed empirical benchmark & 3-panel hero chart generator
results/benchmark_summary.json Exact 5-seed benchmark metrics and C99/Python latency & memory measurements
tests/test_neckcompass.py 19-test pytest suite covering wrap-around continuity, spike rejection, soft-iron plasticity, GPS-denied return, and CLI

📚 Scientific Foundations

  1. Seelig, J. D. & Jayaraman, V. (2015). Neural dynamics for landmark orientation and angular path integration. Nature, 521, 186–191.
  2. Stone, T. et al. (2017). An anatomically constrained model for path integration in the bee brain. Current Biology, 27(20), 3069–3085.
  3. Turner-Evans, D. et al. (2017). Angular velocity integration in a fly heading circuit. eLife, 6, e23496.
  4. Fisher, Y. E., Lu, J., D'Alessandro, I. & Wilson, R. I. (2019). Sensorimotor experience remaps visual input to a heading network. Nature, 576, 121–125.
  5. Kim, S. S., Hermundstad, A. M., Romani, S., Abbott, L. F. & Jayaraman, V. (2019). Generation of stable heading representations in diverse visual scenes. Nature, 576, 126–131.
  6. Lyu, C., Abbott, L. F. & Maimon, G. (2022). Building an allocentric travelling direction signal via vector computation. Nature, 601, 92–97.
  7. Westeinde, E. A. et al. (2024). Transforming a head direction signal into a goal-oriented steering command. Nature, 626, 819–826.

License

Released under the MIT License. Copyright (c) 2026 Amandeep Singh Bains.

Metadata

Release files for neckcompass 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for neckcompass 1.0.0
File Size Uploaded Provenance Actions
neckcompass-1.0.0.tar.gz 38.0 kB Without provenance Details for neckcompass-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for neckcompass 1.0.0
File Interpreter ABI Platform Actions
neckcompass-1.0.0-py3-none-any.whl Python 3 none any Details for neckcompass-1.0.0-py3-none-any.whl

Total release size: 61.2 kB

Release files / neckcompass-1.0.0.tar.gz

Download URL neckcompass-1.0.0.tar.gz
Size 38.0 kB
Tags Source
SHA-256 checksum
How to use checksums
bd008c8a0eaef551e1e7098713afb4a9912b7722b88bfebc75272144cc40f1ec
BLAKE2b-256 checksum
How to use checksums
0e317078fb9c88fb262534c4b1d78efad8e2f364a8d2f382503ecf40b4352892
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / neckcompass-1.0.0-py3-none-any.whl

Download URL neckcompass-1.0.0-py3-none-any.whl
Size 23.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
18587731837ce0c45fb0a1febb3aa78810414497a5df927221fd5c47f1d92d5d
BLAKE2b-256 checksum
How to use checksums
0b11e09ae43c8320ef772313071813294deb5bc81d4324a2fd2bc54a1a599aa7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for neckcompass 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page