#pragma once #include "fgc/IImuSource.h" #include "fgc/Logger.h" #include #include namespace fgc { // Simulated IMU for development without hardware: synthesizes a slowly varying, // physically plausible full sample (orientation sweeps, ~1 g on accZ, small // gyro/mag) so the Sensors panel and its expanded view animate. class MockImuSource : public IImuSource { public: void start() override { start_ = clock::now(); LOG_INFO << "[mock] IMU started"; } void stop() override { LOG_INFO << "[mock] IMU stopped"; } bool connected() const override { return true; } std::optional sample() override { const double t = std::chrono::duration(clock::now() - start_).count(); ImuSample s; s.valid = true; s.roll_deg = static_cast(15.0 * std::sin(t * 0.5)); s.pitch_deg = static_cast(10.0 * std::sin(t * 0.3 + 1.0)); s.yaw_deg = static_cast(std::fmod(t * 8.0, 360.0)); // slow spin // Gravity tilts with roll/pitch; small free accel noise. const double r = s.roll_deg * M_PI / 180.0, p = s.pitch_deg * M_PI / 180.0; s.acc[0] = static_cast(9.81 * -std::sin(p)); s.acc[1] = static_cast(9.81 * std::sin(r) * std::cos(p)); s.acc[2] = static_cast(9.81 * std::cos(r) * std::cos(p)); s.gyr[0] = static_cast(0.13 * std::cos(t * 0.5)); s.gyr[1] = static_cast(0.05 * std::cos(t * 0.3 + 1.0)); s.gyr[2] = 0.14f; s.mag[0] = static_cast(std::cos(s.yaw_deg * M_PI / 180.0)); s.mag[1] = static_cast(-std::sin(s.yaw_deg * M_PI / 180.0)); s.mag[2] = 0.35f; s.temp_c = static_cast(24.5 + 0.5 * std::sin(t * 0.05)); s.sample_counter = static_cast(static_cast(t * 100.0) & 0xFFFF); return s; } private: using clock = std::chrono::steady_clock; clock::time_point start_ = clock::now(); }; } // namespace fgc