#include "camera_pipeline.hpp" #include "config.hpp" #include "stop_signals.hpp" #include "visualizer.hpp" #include #include #include #include int main(int argc,char** argv)try { auto root=std::filesystem::canonical("/proc/self/exe").parent_path().parent_path(); auto configPath=root/"config/camera.json"; cms::OutputOptions output;output.directory=root/"output"; bool visualize=true,disableCan=false; std::filesystem::path recordSession,replaySession; std::map> arguments{ {"--record-session",[&](int&i){if(++i>=argc)throw std::invalid_argument("--record-session needs a directory");recordSession=argv[i];}}, {"--replay-session",[&](int&i){if(++i>=argc)throw std::invalid_argument("--replay-session needs a directory");replaySession=argv[i];}}, {"--save-original",[&](int&){output.original=true;}}, {"--save-annotated",[&](int&){output.annotated=true;}}, {"--save-results",[&](int&){output.results=true;}}, {"--no-can",[&](int&){disableCan=true;}}, {"--visualize",[&](int&){visualize=true;}}, {"--no-visualize",[&](int&){visualize=false;}}, {"--config",[&](int&i){if(++i>=argc)throw std::invalid_argument("--config needs a file");configPath=argv[i];}}, {"--help",[](int&){std::cout<<"camera_risk [--record-session NEW_DIR] [--replay-session DIR] [--save-original] [--save-annotated] [--save-results] [--config FILE] [--no-can] [--visualize|--no-visualize]\nLive CAN/CANFD reception on CH0 and change-triggered 0x1F6 binary risk transmission on CH1 are enabled by default.\nRisk: clear/watch/unavailable=0, warning/danger/unknown=1; send initial state once, then only binary changes. No automatic retries. --no-can disables reception and transmission.\nReplay uses recorded CAN only and never transmits.\nVisualization is enabled by default for live inference, recording and replay.\nContinuous camera inference; replay runs to EOF without a camera.\nH.264 sessions require a new recording directory. Stop with Ctrl+C or SIGTERM to finalize video.\n";std::exit(0);}} }; for(int i=1;isecond(i);} auto config=cms::loadConfig(configPath);config.output=output;config.record_session=recordSession;config.replay_session=replaySession; if(disableCan)config.can.enabled=false; cms::CameraPipeline pipeline(config); cms::StopSignals signals(pipeline); pipeline.start(); /* * 下游使用示例:在下游自己的线程/调用位置读取最新结果。 * 首帧尚未完成时 result 为空;读取不会影响取图和推理。 * * auto result = pipeline.latest(); * if (result) { * const auto& risk = result->risk; * const auto& people = result->persons; * // result->frame_index / track_ids / boxes * // result->image / door_mask_pixels / capture / timing * // people[i].selected / smoothed / temporal:各 133 个关键点 * } */ // Optional observer. Closing/failing the window never requests inference stop. if(visualize) { auto display=std::getenv("DISPLAY");auto wayland=std::getenv("WAYLAND_DISPLAY"); if((!display||!*display)&&(!wayland||!*wayland))std::cerr<<"No display session; inference continues without visualization.\n"; else try {cms::runLocalVisualization(pipeline);} catch(std::exception const& e){std::cerr<<"Visualization unavailable; inference continues: "<