// Headless skeleton app: loads config.json, one reader thread per lidar. // ./lidar_app [config.json] [plugins_dir] #include "lidar_manager.hpp" #include #include #include #include #include #include namespace { std::atomic g_running{true}; void on_signal(int) { g_running = false; } void run_lidar(xlidar::LidarManager& manager, xlidar::DeviceConfig cfg) { std::unique_ptr lidar = manager.create_lidar_device(cfg); if (!lidar) return; xlidar::ErrorCode err = lidar->open(); if (err != xlidar::ErrorCode::Ok) { fprintf(stderr, "[%s] open failed %s (%s)\n", cfg.name.c_str(), cfg.driver_id.c_str(), xlidar::to_string(err)); return; } printf("[%s] opened %s (model=%s, inverted=%d)\n", cfg.name.c_str(), cfg.driver_id.c_str(), cfg.model.c_str(), cfg.inverted); while (g_running) { xlidar::ScanResult result; if (!lidar->recv_scan(result, 1000)) continue; printf("[%s] %zu points | ts=%u ms | model=%s | diag=%s\n", cfg.name.c_str(), result.scan.ranges.size(), result.scan.timestamp_ms, result.info.detected_model.c_str(), xlidar::to_string(lidar->get_diagnostics()).c_str()); } lidar->close(); printf("[%s] closed\n", cfg.name.c_str()); } } // namespace int main(int argc, char** argv) { setvbuf(stdout, nullptr, _IOLBF, 0); const std::string config_path = (argc > 1) ? argv[1] : "config.json"; const std::string plugins_dir = (argc > 2) ? argv[2] : "plugins"; xlidar::LidarManager manager(plugins_dir); printf("%zu driver(s) available\n", manager.load_all_plugins()); xlidar::ManagerConfig cfg = xlidar::load_config(config_path); xlidar::save_config(config_path, cfg); // ensure the file exists (and migrate legacy keys) if (cfg.lidars.empty()) { fprintf(stderr, "no lidars in %s\n", config_path.c_str()); return 1; } std::signal(SIGINT, on_signal); std::signal(SIGTERM, on_signal); // One thread per device — instances are fully independent. The manager // outlives every thread (join below), as the plugin contract requires. std::vector threads; threads.reserve(cfg.lidars.size()); for (const auto& lc : cfg.lidars) threads.emplace_back(run_lidar, std::ref(manager), lc); printf("running %zu lidar(s) from %s. Ctrl-C to stop.\n", cfg.lidars.size(), config_path.c_str()); for (auto& t : threads) t.join(); return 0; }