#include "fgc/Application.h" #include "fgc/Config.h" #include "fgc/Logger.h" #include "fgc/Paths.h" #include #include namespace po = boost::program_options; using namespace fgc; int main(int argc, char* argv[]) { po::options_description desc("Fire Gimbal Control options"); desc.add_options() ("help,h", "show this help") ("config,c", po::value(), "path to config.ini") ("init,i", po::bool_switch(), "run the endstop-finding init sequence") ("start,s", po::bool_switch(), "start capture automatically") ("demo,d", po::bool_switch(), "demo mode (copy placeholder image instead of encoding)") ("no-mqtt", po::bool_switch(), "disable MQTT (use a null control channel)") ("mock-camera", po::bool_switch(), "use a simulated camera (no hardware)") ("mock-serial", po::bool_switch(), "use a simulated motor controller (no hardware)") ("tui", po::bool_switch(), "show the full-screen terminal dashboard") ("no-tui", po::bool_switch(), "force the headless line console (overrides config)") ("log-level", po::value(), "trace|debug|info|warn|error|off") ("trace", po::value(), "verbatim wire trace, comma list: serial,mqtt,camera,control,all,none"); po::variables_map vm; try { po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); } catch (const std::exception& e) { std::cerr << "Argument error: " << e.what() << "\n"; return 1; } if (vm.count("help")) { std::cout << desc << "\n"; return 0; } const std::string cli_cfg = vm.count("config") ? vm["config"].as() : ""; auto cfg_path = paths::resolveConfigPath(cli_cfg); if (!cfg_path) { std::cerr << "No config.ini found. Searched:\n"; for (const auto& p : paths::configSearchPaths(cli_cfg)) std::cerr << " - " << p << "\n"; std::cerr << "Copy config/config.example.ini to one of these, pass --config, " "or set $FGC_CONFIG.\n"; return 1; } AppConfig cfg; try { cfg = ConfigLoader::loadFromFile(*cfg_path); } catch (const std::exception& e) { std::cerr << "Config error (" << *cfg_path << "): " << e.what() << "\n"; return 1; } LOG_INFO << "Loaded config: " << *cfg_path; RuntimeOptions opts; opts.init = vm["init"].as(); opts.start = vm["start"].as(); opts.demo = vm["demo"].as(); if (vm["no-mqtt"].as()) opts.use_mqtt = false; if (vm["mock-camera"].as()) opts.mock_camera = true; if (vm["mock-serial"].as()) opts.mock_serial = true; if (vm["tui"].as()) opts.use_tui = true; if (vm["no-tui"].as()) opts.use_tui = false; // --no-tui wins if (vm.count("log-level")) opts.log_level = vm["log-level"].as(); if (vm.count("trace")) opts.trace_categories = vm["trace"].as(); Application app(std::move(cfg), std::move(opts)); return app.run(); }