Spatial
Xi::Spatial is an embedded-first real-time 3D orientation tracker and IMU (Inertial Measurement Unit) fusion engine.
Architectural Overview: Madgwick Sensor Fusion
When calculating the 3D orientation (Pitch, Roll, Yaw) of a drone or IoT device, most systems rely on simple Complementary Filters or computationally exorbitant Kalman Filters. Xi::Spatial provides an ultra-fast, floating-point optimized implementation of the Madgwick AHRS (Attitude and Heading Reference System) filter.
By aggressively processing raw Accelerometer, Gyroscope, and Magnetometer streams through an algorithmic gradient descent, Xi::Spatial resolves a perfectly stable quaternion—completely immune to the notorious Gimbal Lock problem inherent in Euler angle math—while maintaining execution times well within a 1kHz embedded RTOS interrupt loop.
Core Features
Singleton Architecture: The Spatial engine acts as a unified
Xi::Spatial::getInstance()block, holding the entire physical state of the device in memory for instant querying.I2C/SPI Hardware Agnosticism: While natively pre-configured for the MPU6050 and MPU9250 on Arduino, the
madgwickUpdate()method accepts purely dimensionless floating-point inputs, making it instantly portable to any proprietary hardware sensors tracking across a Linux/Python pipeline via UART or UDP.GPS & PPS Synchronization: Beyond rotation, the
Spatialmodule integrates deeply with Pulse-Per-Second (PPS) interrupts to establish coordinate timestamps bound to the Earth's atomic clock.Environmental Tracking: Central hub for altitude, humidity, geolocation, and precise timezone logic.
📖 Complete API Reference
1. Orientation & Environmental State
Properties are exposed directly on the Spatial singleton for immediate zero-cost access:
Orientation (Euler Angles)
float roll, pitch, yawThe current 3D Eulerian rotation in degrees (°).
IMU Sensor Data
float ax, ay, azRaw Accelerometer G-forces (g).float gx, gy, gzRaw Gyroscope angular velocities (deg/s).float mx, my, mzRaw Magnetometer flux density (uT).
Environmental Data
float temp(Celsius°C)float humidity(%)float pressure(hPa)float altitude(Meters)
Geolocation
double lat, lngCurrent Latitude and Longitude from an attached GPS.int gmtOffsetCalculated or manually enforced timezone offset (in hours).bool hasFixIs the GPS actively tracking satellites.
2. Sensor Fusion Engine
static Spatial& getInstance()Retrieves the global spatial singleton.void madgwickUpdate(float dt)The core fusion engine. Pass in the delta time (dt) since the last loop iteration in seconds. This method automatically derives gradients based on the currently loadedax, ay, az, gx, gy, gzandmx, my, mzvariables and calculates the updated inner quaternion.void computeAngles()A mathematical utility. It takes the current internal Madgwick quaternion state and immediately projects it out into human-readableroll,pitch, andyawvariables (converted automatically to degrees viaSP_RAD_TO_DEG).void update()A high-level wrapper. It sequentially callsreadSensors(), determinesdt, runsmadgwickUpdate(dt), computes the angles, and conditionally auto-updates the GMT offset.
3. Hardware Interoperability
void setMPUI2C(u8 addr = 0x68)Attaches the internalSpatialengine to a specific I2C MPU sensor natively on Arduino variants.void initMPU()Fires the necessary I2C wire commands to wake up the sensor hardware.void readSensors()Polls the I2C bus and populates the acceleration and gyro data.
4. Spatiotemporal Configuration
The precise physical coordinate requires synchronous atomic time (Xi::Time).
void setPPS(int pin)Configures an external Pulse-Per-Second hardware interrupt (commonly from a GPS module) to continuously discipline the internal microsecond clock precisely on the rising edge.void setGMT(int offset)Forces the system timezone offset logic perfectly.int getGMT() constRetrieves the target GMT hours offset.void autoGMT()Automatically calculates the GMT offset mechanically (round(lng / 15.0)) based on the current GPS coordinates ifhasFixis active.
💻 Example: 500Hz RTOS Sensor Loop
Last updated