# Module Reference Per-file reference for the refactored tree, plus the shared data structures. ## Core (`fgc_core` — SDK-independent, unit-tested) | File | Contents | |------|----------| | [include/fgc/Config.h](../include/fgc/Config.h), [src/core/Config.cpp](../src/core/Config.cpp) | Typed `AppConfig` (General/Network/Serial/Camera/Paths/Features) + `ConfigLoader` (INI parse, env overrides, validation) | | [include/fgc/Paths.h](../include/fgc/Paths.h), [src/core/Paths.cpp](../src/core/Paths.cpp) | `~`/`$ENV` expansion, executable dir, config search order, default output dir | | [include/fgc/Logger.h](../include/fgc/Logger.h), [src/core/Logger.cpp](../src/core/Logger.cpp) | Leveled, thread-safe logger; `LOG_TRACE..LOG_ERROR` macros | | [include/fgc/TelemetryParser.h](../include/fgc/TelemetryParser.h), [src/core/TelemetryParser.cpp](../src/core/TelemetryParser.cpp) | `parseTelemetryLine` → `std::optional` | | [include/fgc/CommandParser.h](../include/fgc/CommandParser.h), [src/core/CommandParser.cpp](../src/core/CommandParser.cpp) | `parseCommand` whitespace tokenizer → `Command` | | [include/fgc/CaptureScheduler.h](../include/fgc/CaptureScheduler.h), [src/core/CaptureScheduler.cpp](../src/core/CaptureScheduler.cpp) | Capture state machine over the interfaces; injectable clock | | [include/fgc/Application.h](../include/fgc/Application.h), [src/core/Application.cpp](../src/core/Application.cpp) | Factory (real vs mock), wiring, control loop, console commands | | [ini.c](../ini.c), [ini.h](../ini.h) | Bundled third-party inih INI parser | ## Interfaces | File | Interface | Shared structs | |------|-----------|----------------| | [include/fgc/IMotorController.h](../include/fgc/IMotorController.h) | `IMotorController` | `MotorTelemetry` | | [include/fgc/IControlChannel.h](../include/fgc/IControlChannel.h) | `IControlChannel` | `ControlCommand`, `CamEvent` | | [include/fgc/ICameraSource.h](../include/fgc/ICameraSource.h) | `ICameraSource` | `Frame` | ## Real implementations (SDK-gated) | File | Implements | Built when | |------|-----------|-----------| | [src/serial/SerialMotorController.cpp](../src/serial/SerialMotorController.cpp) | `IMotorController` over Boost.Asio serial (pImpl) | always | | [src/mqtt/MqttControlChannel.cpp](../src/mqtt/MqttControlChannel.cpp) | `IControlChannel` over Eclipse Paho | `WITH_MQTT` | | [src/camera/VimbaCameraSource.cpp](../src/camera/VimbaCameraSource.cpp) | `ICameraSource` over Vimba X (pImpl) | `WITH_VIMBA` | | [src/camera/JpegXlEncoder.cpp](../src/camera/JpegXlEncoder.cpp) | libjxl encode-to-file | always | | [src/camera/ImagePipeline.cpp](../src/camera/ImagePipeline.cpp) | frame → rotate → encode → write → CamEvent (worker thread) | always | ## Mock / null implementations | File | Implements | |------|-----------| | [include/fgc/mock/MockMotorController.h](../include/fgc/mock/MockMotorController.h) | Simulated sweeping gimbal | | [include/fgc/mock/NullControlChannel.h](../include/fgc/mock/NullControlChannel.h) | No-op channel; auto-sweep | | [include/fgc/mock/MockCameraSource.h](../include/fgc/mock/MockCameraSource.h) | Synthetic gradient frames | ## Entry point & scripts | File | Role | |------|------| | [main.cpp](../main.cpp) | CLI parsing → `AppConfig` + `RuntimeOptions` → `Application::run()` | | [scripts/run.sh](../scripts/run.sh) | Path-independent launcher | | [scripts/fire-gimbal-control.service](../scripts/fire-gimbal-control.service) | systemd unit template | ## Data structures ### `MotorTelemetry` ([IMotorController.h](../include/fgc/IMotorController.h)) `encoder`, `encoder_err`, `sgt_val`, `sgt_stat`, `is_moving`, `control_status`, `heading` (float), `deviation_warn`, `humidity`, `temperature`, `fan_pwm`. Parsed from the `$;...;` line (humidity is field 9, temperature field 10 — see [known-issues.md](known-issues.md)). ### `ControlCommand` ([IControlChannel.h](../include/fgc/IControlChannel.h)) `control_code` (0 = auto sweep, 1 = directed) + `target_heading`, each with an `*_available` flag. ### `CamEvent` ([IControlChannel.h](../include/fgc/IControlChannel.h)) `tower`, `camera` (RGB/ACR/NIR), `heading_decideg` (heading×10), `timestamp_ms`. Serialized to the CamEvent JSON payload (see [mqtt-api.md](mqtt-api.md)). ### `Frame` ([ICameraSource.h](../include/fgc/ICameraSource.h)) Owned pixel buffer + `width`, `height`, `channels` (1 or 3), `timestamp_ms`, `cam_id`. ## On-disk artifacts | Artifact | Path | Format | |----------|------|--------| | Captured images | `//.jxl` | JPEG XL, rotated 90° CCW | | Demo placeholder | `bin/x64/Release/test_smoke.jxl` | copied verbatim in demo mode | State otherwise lives in memory; diagnostics go to stdout/stderr (no log files, no database).