#pragma once #include namespace fgc { // Telemetry snapshot from the motor controller (was struct motor_info). struct MotorTelemetry { int encoder = 0; // Xenc int encoder_err = 0; // Xerr int sgt_val = 0; // StallGuard value int sgt_stat = 0; // StallGuard status int is_moving = 0; // movement flag (kept as int to preserve firmware semantics) int control_status = 0; // driver/controller status float heading = 0.f; // degrees int deviation_warn = 0; int humidity = 0; int temperature = 0; int fan_pwm = 0; // 0-255 }; // Abstraction over the gimbal's motor controller. Implemented by // SerialMotorController (Boost.Asio serial link) and MockMotorController // (simulated, for development without hardware). class IMotorController { public: virtual ~IMotorController() = default; // Begin/*end* background telemetry reading. virtual void start() = 0; virtual void stop() = 0; // Send a raw command string to the controller (e.g. "p", "kd180"). virtual void sendCommand(const std::string& cmd) = 0; // Latest telemetry snapshot (thread-safe in implementations). virtual MotorTelemetry telemetry() = 0; // Whether the underlying link is usable. virtual bool connected() const = 0; }; } // namespace fgc