From 49897c28feb111586ef023e9fb190d1303baa03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20D=C4=85browski?= Date: Wed, 23 Sep 2026 01:42:42 +0200 Subject: [PATCH] lidar_odometry_step_1: fix a crash in single-argument mode, add --dump-default-params Running `lidar_odometry_step_1 ` read argv[3], which does not exist, so the results path was garbage. It now saves into the next free `/lio_result_N`, like the GUI, and exits with an error if the folder holds no Mandeye data. `lidar_odometry_step_1 --dump-default-params ` writes the default parameters to a file and exits, so you can edit them and run headless without opening the GUI. The help text lists both options. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../lidar_odometry_gui.cpp | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp b/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp index ec4f8c60..e7378fef 100644 --- a/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp +++ b/apps/lidar_odometry_step_1/lidar_odometry_gui.cpp @@ -2667,16 +2667,50 @@ int main(int argc, char* argv[]) { std::cout << winTitle << "\n\n" << "USAGE:\n" - << std::filesystem::path(argv[0]).stem().string() << " /?\n\n" + << std::filesystem::path(argv[0]).stem().string() << " /?\n" + << std::filesystem::path(argv[0]).stem().string() << " \n" + << std::filesystem::path(argv[0]).stem().string() << " --dump-default-params \n\n" << "where\n" << " Path where scan files are located (*.csv, *.laz, *.sn)\n" << " Path to TOML parameter file (*.toml)\n" << " Path where processed session should be stored\n" + << " (with alone, default parameters are used and the\n" + << " session is stored in the next free /lio_result_N,\n" + << " as the GUI does)\n" + << " --dump-default-params \n" + << " Write the default parameters to and exit\n" << " -h, /h, --help, /? Show this help and exit\n\n"; return 0; } + for (int i = 1; i < argc; ++i) + { + if (std::string(argv[i]) == "--dump-default-params") + { + if (i + 1 >= argc) + { + std::cerr << "--dump-default-params requires an output file (*.toml)" << std::endl; + return 1; + } + const fs::path out_file(argv[i + 1]); + // Value-initialised, as the static `params` is: the NDT grid members carry no + // initialisers, and a default-initialised local would dump stack garbage. + LidarOdometryParams default_params{}; + set_lidar_odometry_default_params(default_params); + TomlIO toml_io; + toml_io.SaveParametersToTomlFile(out_file.string(), default_params); + std::error_code ec; + if (!fs::exists(out_file, ec) || fs::file_size(out_file, ec) == 0 || ec) + { + std::cerr << "Could not write default parameters to: " << out_file.string() << std::endl; + return 1; + } + std::cout << "Default parameters saved to: " << out_file.string() << std::endl; + return 0; + } + } + if (argc == 2) // running from command line { auto path = fs::path(argv[1]); @@ -2699,7 +2733,16 @@ int main(int argc, char* argv[]) std::cout << "calculations finished computation at " << std::ctime(&end_time) << "Elapsed time: " << formatTime(elapsed_seconds.count()).c_str() << "s\n"; - save_results(false, elapsed_seconds.count(), working_directory, worker_data, params, argv[3]); + // Only the input folder was given: store the session where the GUI would, + // in the next free lio_result_N under the working directory. + if (working_directory.empty()) + { + std::cerr << "No Mandeye data could be loaded from: '" << path.string() << "'" << std::endl; + return 1; + } + const fs::path result_dir = get_next_result_path(working_directory); + save_results(false, elapsed_seconds.count(), working_directory, worker_data, params, result_dir); + std::cout << "Results saved to folder: '" << result_dir.string() << "'" << std::endl; } } else if (argc == 4) // runnning from command line with custom params