iterative closest points
CEV ICP algorithm library
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1
7#include <iostream>
8extern "C" {
9#include <cmdapp/cmdapp.h>
10#include <config/config.h>
11}
12#include <sdlwrapper/gui/window.h>
13#include <optional>
14#include "view_config.h"
15#include "lidar_view.h"
16#include "icp/impl/vanilla.h"
17#include "icp/impl/trimmed.h"
18#include "parse_scan.h"
19
20void set_config_param(const char* var, const char* data, [[maybe_unused]] void* user_data) {
21 if (strcmp(var, "x_displace") == 0) {
22 view_config::x_displace = std::stod(data);
23 } else if (strcmp(var, "y_displace") == 0) {
24 view_config::y_displace = std::stod(data);
25 } else if (strcmp(var, "window_width") == 0) {
26 view_config::window_width = std::stoi(data);
27 } else if (strcmp(var, "window_height") == 0) {
28 view_config::window_height = std::stoi(data);
29 } else if (strcmp(var, "view_scale") == 0) {
30 view_config::view_scale = std::stod(data);
31 }
32}
33
34void parse_config(const char* path) {
35 FILE* file = fopen(path, "r");
36 if (!file) {
37 perror("parse_config: fopen");
38 std::exit(1);
39 }
40
41 if (conf_parse_file(file, set_config_param, nullptr) != 0) {
42 perror("parse_config: conf_parse_file");
43 std::exit(1);
44 }
45
46 fclose(file);
47}
48
49void assert_opt(bool* opt_result) {
50 if (!opt_result) {
51 std::exit(1);
52 }
53}
54
55void launch_gui(LidarView* view, std::string visualized = "LiDAR scans") {
56 Window window("Scan Matching", view_config::window_width, view_config::window_height);
57
58 window.attach_view(view);
59
60 std::cout << "SCAN MATCHING : ITERATIVE CLOSEST POINT\n";
61 std::cout << "=======================================\n";
62 std::cout << "* Visualizing: " << visualized << '\n';
63 std::cout << "* Press the red <X> on the window to exit\n";
64 std::cout << "* Press SPACE to toggle the simulation\n";
65 std::cout << "* Press D to display the current transform\n";
66 std::cout << "* Press I to step forward a single iteration\n";
67
68 window.present();
69}
70
71int main(int argc, const char** argv) {
72 if (ca_init(argc, argv) != 0) {
73 perror("ca_init");
74 return 1;
75 }
76
77 ca_description("Driver program for CEV's ICP implementation.");
78 ca_author("Ethan Uppal");
79 ca_author("Cornell Electric Vehicles");
80 ca_year(2025);
81 ca_version(0, 0, 0);
82 ca_versioning_info("See LICENSE for details.");
83
84 ca_synopsis("[-h|-v]");
85 ca_synopsis("-S FILE -D FILE [-l]");
86 ca_synopsis("-b METHOD [-l]");
87
88 bool* enable_log = NULL;
89 bool* read_scan_files = NULL;
90 bool* basic_mode = NULL; // for gbody people
91 const char* f_src = NULL;
92 const char* f_dst = NULL;
93 const char* config_file = "view.conf";
94 const char* method = "vanilla";
95
96 assert_opt(read_scan_files = ca_opt('S', "src", ".FILE&D", &f_src,
97 "source scan (pass with -D)"));
98 assert_opt(ca_opt('D', "dst", ".FILE&S", &f_dst, "destination scan (pass with -S)"));
99 assert_opt(ca_opt('c', "config", ".FILE", &config_file,
100 "selects a configuration file (default: view.conf)"));
101 assert_opt(ca_opt('m', "method", ".METHOD", &method, "selects an ICP method"));
102 assert_opt(basic_mode = ca_long_opt("basic-mode", "", NULL, "uses a ligher gui background"));
103 assert_opt(enable_log = ca_opt('l', "log", "", NULL, "enables debug logging"));
104 assert_opt(ca_opt('h', "help", "<h", NULL, "prints this info"));
105 assert_opt(ca_opt('v', "version", "<v", NULL, "prints version info"));
106
107 if (argc == 1) {
108 ca_print_help();
109 return 1;
110 } else if (ca_parse(NULL) != 0) {
111 return 1;
112 }
113
114 Log.is_enabled = *enable_log;
115 parse_config(config_file);
116 if (*basic_mode) {
118 }
119
120 std::optional<std::unique_ptr<icp::ICP>> icp_opt = icp::ICP::from_method(method);
121
122 if (!icp_opt.has_value()) {
123 std::cerr << "error: unknown ICP method '" << method << "'. expected one of:\n";
124 for (const std::string& registered_method: icp::ICP::registered_methods()) {
125 std::cerr << "* " << registered_method << '\n';
126 }
127 std::exit(1);
128 }
129
130 std::unique_ptr<icp::ICP> icp = std::move(icp_opt.value());
131
132 // std::vector<icp::Vector> a = {icp::Vector(0, 0), icp::Vector(100, 100)};
133 // std::vector<icp::Vector> b = {};
134 // double angle = (double)8 * M_PI / 180.0;
135 // icp::Vector center = icp::get_centroid(a);
136 // icp::Matrix rotation_matrix{
137 // {std::cos(angle), -std::sin(angle)}, {std::sin(angle), std::cos(angle)}};
138 // for (const auto& point: a) {
139 // b.push_back(rotation_matrix * (point - center) + center);
140 // }
141 // LidarView* view = new LidarView(a, b, std::move(icp));
142 // launch_gui(view, "test");
143 // return 0;
144
145 if (*read_scan_files) {
146 auto source = parse_lidar_scan(f_src);
147 auto dest = parse_lidar_scan(f_dst);
148
149 icp::ICP::Config config;
150 config.set("overlap_rate", 0.9);
151 LidarView* view = new LidarView(source, dest, std::move(icp));
152
153 launch_gui(view, std::string(f_src) + std::string(" and ") + std::string(f_dst));
154 }
155}
Configuration for ICP instances.
Definition icp.h:81
void set(std::string key, T value)
Associates key with an integer, double, or string value.
Definition icp.h:91
static std::optional< std::unique_ptr< ICP > > from_method(std::string name, const Config &params=Config())
Factory constructor for the ICP method name with configuration config.
Definition icp.cpp:77
static const std::vector< std::string > & registered_methods()
Returns a current list of the names of currently registered ICP methods.
Definition icp.cpp:71
int main(int argc, const char **argv)
Definition main.cpp:71
void assert_opt(bool *opt_result)
Definition main.cpp:49
void launch_gui(LidarView *view, std::string visualized="LiDAR scans")
Definition main.cpp:55
void set_config_param(const char *var, const char *data, void *user_data)
Definition main.cpp:20
void parse_config(const char *path)
Definition main.cpp:34
Definition driver.h:12
double y_displace
double view_scale
bool use_light_mode
double x_displace