#pragma once #include "fgc/MtiProtocol.h" // ImuSample #include namespace fgc { // Abstraction over the orientation/inertial sensor (Xsens MTi). Implemented by // MtiImuSource (RS-232/UART binary stream) and MockImuSource (synthetic). Runs // on its own thread; start() must not block the control loop. class IImuSource { public: virtual ~IImuSource() = default; virtual void start() = 0; virtual void stop() = 0; // Whether a valid, recent reading is available. virtual bool connected() const = 0; // Latest reading, or nullopt if none/stale. virtual std::optional sample() = 0; // Device configuration read back during start-up (output mode/settings, // sample rate, identity, XKF scenario). nullopt if not yet known or the // backend cannot report it. virtual std::optional config() const { return std::nullopt; } // Re-read the device configuration (e.g. after the XKF profile was changed // externally). May briefly pause the measurement stream. Blocking; after it // returns config() reflects the device's current settings. virtual void refreshConfig() {} // Run the "no rotation" gyro-bias update for `seconds`: the device must be // held perfectly still while it estimates and cancels gyro bias, which cuts // heading drift (important in no-magnetometer use). Non-blocking: it sends the // command; the caller is responsible for keeping the unit still that long. virtual void noRotation(int seconds) { (void)seconds; } // Redefine the *current* heading as yaw = 0 (bore-sighting / heading reset). // Subsequent yaw is measured relative to this pose. Non-blocking. virtual void headingReset() {} // Select the XKF profile/scenario by its `type` number (from config()'s // available_profiles). Applied in the device's Config state, so it persists to // non-volatile memory. Briefly pauses the stream; blocking. Returns true if the // device reports the new profile afterwards. Default: not supported. virtual bool setFilterProfile(int type) { (void)type; return false; } }; } // namespace fgc