103 lines
3.6 KiB
C++
103 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include "fgc/Geometry.h"
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace fgc {
|
|
|
|
// Typed application configuration. Replaces the ad-hoc std::map<string,string>
|
|
// lookups that were scattered through main.cpp.
|
|
|
|
struct GeneralConfig {
|
|
std::string tower_name = "Unnamed";
|
|
int image_interval = 5; // seconds between captures
|
|
bool debug = false; // print motor telemetry each loop tick
|
|
};
|
|
|
|
struct NetworkConfig {
|
|
std::string broker_ip = "127.0.0.1"; // MQTT broker / ZKMS server
|
|
std::string mqtt_user; // see secrets note below
|
|
std::string mqtt_pw;
|
|
};
|
|
|
|
struct SerialConfig {
|
|
std::string device = "/dev/ttyACM0";
|
|
unsigned int baud = 115200;
|
|
};
|
|
|
|
struct CameraConfig {
|
|
std::vector<std::string> ids; // GigE IP or USB DEV_ id, in order
|
|
std::vector<std::string> labels = {"RGB", "ACR", "NIR"}; // index -> output subfolder
|
|
};
|
|
|
|
struct PathsConfig {
|
|
// Where captured .jxl images are written. Supports leading ~ and $ENV
|
|
// expansion. Empty => resolved to a sensible default at load time.
|
|
std::string output_dir;
|
|
};
|
|
|
|
struct FeaturesConfig {
|
|
bool enable_mqtt = true;
|
|
bool enable_camera = true;
|
|
bool enable_serial = true;
|
|
bool mock_camera = false; // use a simulated camera instead of Vimba X
|
|
bool mock_serial = false; // use a simulated motor controller
|
|
};
|
|
|
|
struct LoggingConfig {
|
|
std::string level; // trace|debug|info|warn|error|off; empty => default (CLI overrides)
|
|
std::string trace; // verbatim wire-trace categories: serial,mqtt,camera,control,all,none
|
|
};
|
|
|
|
struct UiConfig {
|
|
bool enable_tui = false; // false => headless line console (default); CLI --tui/--no-tui override
|
|
};
|
|
|
|
// [Scan]: source of the capture scan grid (the (yaw,pitch) waypoints the
|
|
// auto-sweep steps through). If grid_file is set, the CSV is loaded verbatim;
|
|
// otherwise a grid is generated from the parameters below (see ScanGrid).
|
|
struct ScanConfig {
|
|
std::string grid_file; // path to an editable yaw_deg,pitch_deg CSV; empty => generate
|
|
int yaw_intervals = 56; // generated: yaw positions across [yaw_min_deg, yaw_max_deg]
|
|
double yaw_min_deg = -90.0;
|
|
double yaw_max_deg = 90.0;
|
|
std::string pitch_levels = "0"; // generated: comma list of pitch elevations (deg)
|
|
};
|
|
|
|
struct AppConfig {
|
|
GeneralConfig general;
|
|
NetworkConfig network;
|
|
SerialConfig serial;
|
|
CameraConfig camera;
|
|
PathsConfig paths;
|
|
FeaturesConfig features;
|
|
LoggingConfig logging;
|
|
UiConfig ui; // [UI] terminal dashboard toggle
|
|
Geometry geometry; // [Motor] degrees<->counts maps (yaw + pitch)
|
|
ScanConfig scan; // [Scan] grid source
|
|
|
|
// Capture rate in images/second (derived from general.image_interval).
|
|
double image_rate() const;
|
|
};
|
|
|
|
// Loads and validates configuration.
|
|
//
|
|
// Secrets: mqtt_user / mqtt_pw are taken from the environment variables
|
|
// FGC_MQTT_USER / FGC_MQTT_PW when present; the INI values are a fallback.
|
|
class ConfigLoader {
|
|
public:
|
|
// Reads the INI file at `path` (via the bundled inih parser), maps it into
|
|
// a typed AppConfig, applies environment overrides, and validates it.
|
|
// Throws std::runtime_error with a clear message on failure.
|
|
static AppConfig loadFromFile(const std::string& path);
|
|
|
|
// Same mapping/validation logic, but from an already-parsed key->value map
|
|
// ("Section.name" => value). Exposed for unit testing without file IO.
|
|
static AppConfig fromMap(const std::map<std::string, std::string>& kv);
|
|
};
|
|
|
|
} // namespace fgc
|