1use clap::Parser;
36
37use maliput::api::{LanePosition, RoadNetwork};
38use std::collections::HashMap;
39
40enum MaliputQuery {
42 PrintAllLanes,
43 GetNumberOfLanes,
44 GetTotalLengthOfTheRoadGeometry,
45 GetLaneLength(String),
46 GetLaneBounds(String, f64), GetSegmentBounds(String, f64), ToRoadPosition(f64, f64, f64), ToLanePosition(String, f64, f64, f64), ToSegmentPosition(String, f64, f64, f64), ToInertialPosition(String, f64, f64, f64), GetOrientaiton(String, f64, f64, f64), OpenScenarioRoadPositionToMaliputRoadPosition(String, f64, f64), OpenScenarioLanePositionToMaliputRoadPosition(String, f64, i64, f64), MaliputRoadPositionToOpenScenarioRoadPosition(String, f64, f64, f64), MaliputRoadPositionToOpenScenarioLanePosition(String, f64, f64, f64), OpenScenarioRelativeRoadPositionToMaliputRoadPosition(String, f64, f64, f64, f64), OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition(String, i64, f64, f64, f64, f64), OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition(String, i64, f64, f64, f64, f64), GetRoadOrientationAtOpenScenarioRoadPosition(String, f64, f64), Invalid,
62}
63
64impl MaliputQuery {
65 fn to_backend_custom_command_format(&self) -> Option<String> {
70 match self {
71 MaliputQuery::OpenScenarioRoadPositionToMaliputRoadPosition(xodr_road_id, xodr_s, xodr_t) => Some(format!(
72 "OpenScenarioRoadPositionToMaliputRoadPosition,{},{},{}",
73 xodr_road_id, xodr_s, xodr_t
74 )),
75 MaliputQuery::OpenScenarioLanePositionToMaliputRoadPosition(xodr_road_id, xodr_s, xodr_lane_id, offset) => {
76 Some(format!(
77 "OpenScenarioLanePositionToMaliputRoadPosition,{},{},{},{}",
78 xodr_road_id, xodr_s, xodr_lane_id, offset
79 ))
80 }
81 MaliputQuery::MaliputRoadPositionToOpenScenarioRoadPosition(lane_id, s, r, h) => Some(format!(
82 "MaliputRoadPositionToOpenScenarioRoadPosition,{},{},{},{}",
83 lane_id, s, r, h
84 )),
85 MaliputQuery::MaliputRoadPositionToOpenScenarioLanePosition(lane_id, s, r, h) => Some(format!(
86 "MaliputRoadPositionToOpenScenarioLanePosition,{},{},{},{}",
87 lane_id, s, r, h
88 )),
89 MaliputQuery::OpenScenarioRelativeRoadPositionToMaliputRoadPosition(
90 xodr_road_id,
91 xodr_s,
92 xodr_t,
93 xodr_ds,
94 xodr_dt,
95 ) => Some(format!(
96 "OpenScenarioRelativeRoadPositionToMaliputRoadPosition,{},{},{},{},{}",
97 xodr_road_id, xodr_s, xodr_t, xodr_ds, xodr_dt
98 )),
99 MaliputQuery::OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition(
100 xodr_road_id,
101 xodr_lane_id,
102 xodr_s,
103 d_lane,
104 xodr_ds,
105 offset,
106 ) => Some(format!(
107 "OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition,{},{},{},{},{},{}",
108 xodr_road_id, xodr_lane_id, xodr_s, d_lane, xodr_ds, offset
109 )),
110 MaliputQuery::OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition(
111 xodr_road_id,
112 xodr_lane_id,
113 xodr_s,
114 d_lane,
115 xodr_ds_lane,
116 offset,
117 ) => Some(format!(
118 "OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition,{},{},{},{},{},{}",
119 xodr_road_id, xodr_lane_id, xodr_s, d_lane, xodr_ds_lane, offset
120 )),
121 MaliputQuery::GetRoadOrientationAtOpenScenarioRoadPosition(xodr_road_id, xodr_s, xodr_t) => Some(format!(
122 "GetRoadOrientationAtOpenScenarioRoadPosition,{},{},{}",
123 xodr_road_id, xodr_s, xodr_t
124 )),
125 _ => None,
126 }
127 }
128}
129
130impl From<Vec<&str>> for MaliputQuery {
131 fn from(args: Vec<&str>) -> Self {
132 match args.as_slice() {
133 ["PrintAllLanes"] => MaliputQuery::PrintAllLanes,
134 ["GetNumberOfLanes"] => MaliputQuery::GetNumberOfLanes,
135 ["GetTotalLengthOfTheRoadGeometry"] => MaliputQuery::GetTotalLengthOfTheRoadGeometry,
136 ["GetLaneLength", lane_id] => MaliputQuery::GetLaneLength(lane_id.to_string()),
137 ["GetLaneBounds", lane_id, s] => MaliputQuery::GetLaneBounds(lane_id.to_string(), s.parse().unwrap()),
138 ["GetSegmentBounds", lane_id, s] => MaliputQuery::GetSegmentBounds(lane_id.to_string(), s.parse().unwrap()),
139 ["ToRoadPosition", x, y, z] => {
140 MaliputQuery::ToRoadPosition(x.parse().unwrap(), y.parse().unwrap(), z.parse().unwrap())
141 }
142 ["ToLanePosition", lane_id, x, y, z] => MaliputQuery::ToLanePosition(
143 lane_id.to_string(),
144 x.parse().unwrap(),
145 y.parse().unwrap(),
146 z.parse().unwrap(),
147 ),
148 ["ToSegmentPosition", lane_id, x, y, z] => MaliputQuery::ToSegmentPosition(
149 lane_id.to_string(),
150 x.parse().unwrap(),
151 y.parse().unwrap(),
152 z.parse().unwrap(),
153 ),
154 ["ToInertialPosition", lane_id, s, r, h] => MaliputQuery::ToInertialPosition(
155 lane_id.to_string(),
156 s.parse().unwrap(),
157 r.parse().unwrap(),
158 h.parse().unwrap(),
159 ),
160 ["GetOrientation", lane_id, s, r, h] => MaliputQuery::GetOrientaiton(
161 lane_id.to_string(),
162 s.parse().unwrap(),
163 r.parse().unwrap(),
164 h.parse().unwrap(),
165 ),
166 ["OpenScenarioRoadPositionToMaliputRoadPosition", xodr_road_id, xodr_s, xodr_t] => {
167 MaliputQuery::OpenScenarioRoadPositionToMaliputRoadPosition(
168 xodr_road_id.to_string(),
169 xodr_s.parse().unwrap(),
170 xodr_t.parse().unwrap(),
171 )
172 }
173 ["OpenScenarioLanePositionToMaliputRoadPosition", xodr_road_id, xodr_s, xodr_lane_id, offset] => {
174 MaliputQuery::OpenScenarioLanePositionToMaliputRoadPosition(
175 xodr_road_id.to_string(),
176 xodr_s.parse().unwrap(),
177 xodr_lane_id.parse().unwrap(),
178 offset.parse().unwrap(),
179 )
180 }
181 ["MaliputRoadPositionToOpenScenarioRoadPosition", lane_id, s, r, h] => {
182 MaliputQuery::MaliputRoadPositionToOpenScenarioRoadPosition(
183 lane_id.to_string(),
184 s.parse().unwrap(),
185 r.parse().unwrap(),
186 h.parse().unwrap(),
187 )
188 }
189 ["MaliputRoadPositionToOpenScenarioLanePosition", lane_id, s, r, h] => {
190 MaliputQuery::MaliputRoadPositionToOpenScenarioLanePosition(
191 lane_id.to_string(),
192 s.parse().unwrap(),
193 r.parse().unwrap(),
194 h.parse().unwrap(),
195 )
196 }
197 ["OpenScenarioRelativeRoadPositionToMaliputRoadPosition", xodr_road_id, xodr_s, xodr_t, xodr_ds, xodr_dt] => {
198 MaliputQuery::OpenScenarioRelativeRoadPositionToMaliputRoadPosition(
199 xodr_road_id.to_string(),
200 xodr_s.parse().unwrap(),
201 xodr_t.parse().unwrap(),
202 xodr_ds.parse().unwrap(),
203 xodr_dt.parse().unwrap(),
204 )
205 }
206 ["OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition", xodr_road_id, xodr_lane_id, xodr_s, d_lane, xodr_ds, offset] => {
207 MaliputQuery::OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition(
208 xodr_road_id.to_string(),
209 xodr_lane_id.parse().unwrap(),
210 xodr_s.parse().unwrap(),
211 d_lane.parse().unwrap(),
212 xodr_ds.parse().unwrap(),
213 offset.parse().unwrap(),
214 )
215 }
216 ["OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition", xodr_road_id, xodr_lane_id, xodr_s, d_lane, xodr_ds_lane, offset] => {
217 MaliputQuery::OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition(
218 xodr_road_id.to_string(),
219 xodr_lane_id.parse().unwrap(),
220 xodr_s.parse().unwrap(),
221 d_lane.parse().unwrap(),
222 xodr_ds_lane.parse().unwrap(),
223 offset.parse().unwrap(),
224 )
225 }
226 ["GetRoadOrientationAtOpenScenarioRoadPosition", xodr_road_id, xodr_s, xodr_t] => {
227 MaliputQuery::GetRoadOrientationAtOpenScenarioRoadPosition(
228 xodr_road_id.to_string(),
229 xodr_s.parse().unwrap(),
230 xodr_t.parse().unwrap(),
231 )
232 }
233 _ => MaliputQuery::Invalid,
234 }
235 }
236}
237
238impl MaliputQuery {
239 fn print_available_queries() {
240 println!("-> Available commands:");
241 println!("\t* General commands:");
242 println!("\t\t1. PrintAllLanes");
243 println!("\t\t2. GetNumberOfLanes");
244 println!("\t\t3. GetTotalLengthOfTheRoadGeometry");
245 println!("\t\t4. GetLaneLength <lane_id>");
246 println!("\t\t5. GetLaneBounds <lane_id> <s>");
247 println!("\t\t6. GetSegmentBounds <lane_id> <s>");
248 println!("\t\t7. ToRoadPosition <x> <y> <z>");
249 println!("\t\t8. ToLanePosition <lane_id> <x> <y> <z>");
250 println!("\t\t9. ToSegmentPosition <lane_id> <x> <y> <z>");
251 println!("\t\t10 ToInertialPosition <lane_id> <s> <r> <h>");
252 println!("\t\t11. GetOrientation <lane_id> <s> <r> <h>");
253 println!("\t* Commands particular to maliput_malidrive / OpenDRIVE specification:");
254 println!("\t\t1. OpenScenarioRoadPositionToMaliputRoadPosition <xodr_road_id> <xodr_s> <xodr_t>");
255 println!(
256 "\t\t2. OpenScenarioLanePositionToMaliputRoadPosition <xodr_road_id> <xodr_s> <xodr_lane_id> <offset>"
257 );
258 println!("\t\t3. MaliputRoadPositionToOpenScenarioRoadPosition <lane_id> <s> <r> <h>");
259 println!("\t\t4. MaliputRoadPositionToOpenScenarioLanePosition <lane_id> <s> <r> <h>");
260 println!("\t\t5. OpenScenarioRelativeRoadPositionToMaliputRoadPosition <xodr_road_id> <xodr_s> <xodr_t> <xodr_ds> <xodr_dt>");
261 println!("\t\t6. OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition <xodr_road_id> <xodr_lane_id> <xodr_s> <d_lane> <xodr_ds> <offset>");
262 println!("\t\t7. OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition <xodr_road_id> <xodr_lane_id> <xodr_s> <d_lane> <xodr_ds_lane> <offset>");
263 println!("\t\t8. GetRoadOrientationAtOpenScenarioRoadPosition <xodr_road_id> <xodr_s> <xodr_t>");
264 }
265}
266
267struct RoadNetworkQuery<'a> {
268 rn: &'a RoadNetwork,
269}
270
271impl<'a> RoadNetworkQuery<'a> {
272 fn new(rn: &'a RoadNetwork) -> Self {
273 RoadNetworkQuery { rn }
274 }
275
276 fn execute_query(&self, query: MaliputQuery) {
277 let rg = self.rn.road_geometry();
278 let start_time = std::time::Instant::now();
279 match query {
280 MaliputQuery::PrintAllLanes => {
281 let mut lanes = rg.get_lanes();
283 lanes.sort_by(|a, b| b.length().partial_cmp(&a.length()).unwrap());
284 print_elapsed_time(start_time);
285 println!("-> All lanes in the road geometry: {} lanes", lanes.len());
286 for lane in lanes {
287 println!(
288 "\t* Lane ID: {}\t Length: {} meters \t InertiaPos at (s=0,r=0,h=0): {}",
289 lane.id(),
290 lane.length(),
291 lane.to_inertial_position(&LanePosition::new(0., 0., 0.))
292 );
293 }
294 }
295 MaliputQuery::GetNumberOfLanes => {
296 let len = rg.get_lanes().len();
297 print_elapsed_time(start_time);
298 println!("-> Number of lanes: {}", len);
299 }
300 MaliputQuery::GetTotalLengthOfTheRoadGeometry => {
301 let lanes_num = rg.get_lanes().len();
302 let total_length = rg.get_lanes().iter().map(|lane| lane.length()).sum::<f64>();
303 print_elapsed_time(start_time);
304 println!("-> Total length of the road geometry: {} meters along {} lanes. The average lane length is {} meters.",
305 total_length,
306 lanes_num,
307 total_length / lanes_num as f64);
308 }
309 MaliputQuery::GetLaneLength(lane_id) => {
310 if let Some(lane) = rg.get_lane(&lane_id) {
311 let lane_length = lane.length();
312 print_elapsed_time(start_time);
313 println!("-> Length of lane {}: {} meters", lane_id, lane_length);
314 } else {
315 println!("-> Lane with ID {} not found.", lane_id);
316 }
317 }
318 MaliputQuery::GetLaneBounds(lane_id, s) => {
319 if let Some(lane) = rg.get_lane(&lane_id) {
320 let lane_bounds = lane.lane_bounds(s);
321 print_elapsed_time(start_time);
322 println!(
323 "-> Bounds of lane {} at s={}: max: {}, min: {}",
324 lane_id,
325 s,
326 lane_bounds.max(),
327 lane_bounds.min()
328 );
329 } else {
330 println!("-> Lane with ID {} not found.", lane_id);
331 }
332 }
333 MaliputQuery::GetSegmentBounds(lane_id, s) => {
334 if let Some(lane) = rg.get_lane(&lane_id) {
335 let segment_bounds = lane.segment_bounds(s);
336 print_elapsed_time(start_time);
337 println!(
338 "-> Segment bounds of lane {} at s={}: max: {}, min: {}",
339 lane_id,
340 s,
341 segment_bounds.max(),
342 segment_bounds.min()
343 );
344 } else {
345 println!("-> Lane with ID {} not found.", lane_id);
346 }
347 }
348 MaliputQuery::ToRoadPosition(x, y, z) => {
349 let road_position_result = rg.to_road_position(&maliput::api::InertialPosition::new(x, y, z));
350 print_elapsed_time(start_time);
351 println!("-> Road Position Result:");
352 println!("\t* Road Position:");
353 println!("\t\t* lane_id: {}", road_position_result.road_position.lane().id());
354 println!("\t\t* lane_position: {}", road_position_result.road_position.pos());
355 println!("\t* Nearest Position:");
356 println!("\t\t* inertial_position: {}", road_position_result.nearest_position);
357 println!("\t* Distance:");
358 println!("\t\t* distance: {}", road_position_result.distance);
359 }
360 MaliputQuery::ToLanePosition(lane_id, x, y, z) => {
361 if let Some(lane) = rg.get_lane(&lane_id) {
362 let lane_position_result = lane.to_lane_position(&maliput::api::InertialPosition::new(x, y, z));
363 print_elapsed_time(start_time);
364 println!("-> Lane Position Result for lane {}:", lane_id);
365 println!("\t* Lane Position:");
366 println!("\t\t* lane_position: {}", lane_position_result.lane_position);
367 println!("\t* Nearest Position:");
368 println!("\t\t* inertial_position: {}", lane_position_result.nearest_position);
369 println!("\t* Distance:");
370 println!("\t\t* distance: {}", lane_position_result.distance);
371 } else {
372 println!("Lane with ID {} not found.", lane_id);
373 }
374 }
375 MaliputQuery::ToSegmentPosition(lane_id, x, y, z) => {
376 if let Some(lane) = rg.get_lane(&lane_id) {
377 let lane_position_result = lane.to_segment_position(&maliput::api::InertialPosition::new(x, y, z));
378 print_elapsed_time(start_time);
379 println!("-> Segment Position Result for lane {}:", lane_id);
380 println!("\t* Lane Position:");
381 println!("\t\t* lane_position: {}", lane_position_result.lane_position);
382 println!("\t* Nearest Position:");
383 println!("\t\t* inertial_position: {}", lane_position_result.nearest_position);
384 println!("\t* Distance:");
385 println!("\t\t* distance: {}", lane_position_result.distance);
386 } else {
387 println!("Lane with ID {} not found.", lane_id);
388 }
389 }
390 MaliputQuery::ToInertialPosition(lane_id, s, r, h) => {
391 if let Some(lane) = rg.get_lane(&lane_id) {
392 let inertial_position = lane.to_inertial_position(&maliput::api::LanePosition::new(s, r, h));
393 print_elapsed_time(start_time);
394 println!("-> Inertial Position Result for lane {}:", lane_id);
395 println!("\t* inertial_position: {}", inertial_position);
396 } else {
397 println!("-> Lane with ID {} not found.", lane_id);
398 }
399 }
400 MaliputQuery::GetOrientaiton(lane_id, s, r, h) => {
401 if let Some(lane) = rg.get_lane(&lane_id) {
402 let orientation = lane.get_orientation(&maliput::api::LanePosition::new(s, r, h));
403 print_elapsed_time(start_time);
404 println!("-> Orientation Result for lane {}:", lane_id);
405 println!("\t* orientation:");
406 println!(
407 "\t\t* roll: {}, pitch: {}, yaw: {}",
408 orientation.roll(),
409 orientation.pitch(),
410 orientation.yaw()
411 );
412 } else {
413 println!("-> Lane with ID {} not found.", lane_id);
414 }
415 }
416 MaliputQuery::OpenScenarioRoadPositionToMaliputRoadPosition(..) => {
417 let command = query
418 .to_backend_custom_command_format()
419 .expect("Invalid query command format for OpenScenarioRoadPositionToMaliputRoadPosition");
420 let res = rg.backend_custom_command(&command);
421 print_elapsed_time(start_time);
422 let res: Vec<&str> = res.split(',').collect();
423 println!("-> OpenScenarioRoadPositionToMaliputRoadPosition Result:");
424 if res.len() == 4 {
425 println!("\t* Maliput Road Position:");
426 println!("\t\t* lane_id: {}", res[0]);
427 println!("\t\t* s: {}", res[1]);
428 println!("\t\t* r: {}", res[2]);
429 println!("\t\t* h: {}", res[3]);
430 } else {
431 println!("-> Invalid response from backend custom command: {}", res.join(", "));
432 }
433 }
434 MaliputQuery::OpenScenarioLanePositionToMaliputRoadPosition(..) => {
435 let command = query
436 .to_backend_custom_command_format()
437 .expect("Invalid query command format for OpenScenarioLanePositionToMaliputRoadPosition");
438 let res = rg.backend_custom_command(&command);
439 print_elapsed_time(start_time);
440 let res: Vec<&str> = res.split(',').collect();
441 println!("-> OpenScenarioLanePositionToMaliputRoadPosition Result:");
442 if res.len() == 4 {
443 println!("\t* Maliput Road Position:");
444 println!("\t\t* lane_id: {}", res[0]);
445 println!("\t\t* s: {}", res[1]);
446 println!("\t\t* r: {}", res[2]);
447 println!("\t\t* h: {}", res[3]);
448 } else {
449 println!("-> Invalid response from backend custom command: {}", res.join(", "));
450 }
451 }
452 MaliputQuery::MaliputRoadPositionToOpenScenarioRoadPosition(..) => {
453 let command = query
454 .to_backend_custom_command_format()
455 .expect("Invalid query command format for MaliputRoadPositionToOpenScenarioRoadPosition");
456 let res = rg.backend_custom_command(&command);
457 print_elapsed_time(start_time);
458 let res: Vec<&str> = res.split(',').collect();
459 println!("-> MaliputRoadPositionToOpenScenarioRoadPosition Result:");
460 if res.len() == 3 {
461 println!("\t* OpenScenario Road Position:");
462 println!("\t\t* xodr_road_id: {}", res[0]);
463 println!("\t\t* xodr_s: {}", res[1]);
464 println!("\t\t* xodr_t: {}", res[2]);
465 } else {
466 println!("-> Invalid response from backend custom command: {}", res.join(", "));
467 }
468 }
469 MaliputQuery::MaliputRoadPositionToOpenScenarioLanePosition(..) => {
470 let command = query
471 .to_backend_custom_command_format()
472 .expect("Invalid query command format for MaliputRoadPositionToOpenScenarioLanePosition");
473 let res = rg.backend_custom_command(&command);
474 print_elapsed_time(start_time);
475 let res: Vec<&str> = res.split(',').collect();
476 println!("-> MaliputRoadPositionToOpenScenarioLanePosition Result for lane:");
477 if res.len() == 4 {
478 println!("\t* OpenScenario Lane Position:");
479 println!("\t\t* xodr_road_id: {}", res[0]);
480 println!("\t\t* xodr_s: {}", res[1]);
481 println!("\t\t* xodr_lane_id: {}", res[2]);
482 println!("\t\t* offset: {}", res[3]);
483 } else {
484 println!("-> Invalid response from backend custom command: {}", res.join(", "));
485 }
486 }
487 MaliputQuery::OpenScenarioRelativeRoadPositionToMaliputRoadPosition(..) => {
488 let command = query
489 .to_backend_custom_command_format()
490 .expect("Invalid query command format for OpenScenarioRelativeRoadPositionToMaliputRoadPosition");
491 let res = rg.backend_custom_command(&command);
492 print_elapsed_time(start_time);
493 let res: Vec<&str> = res.split(',').collect();
494 println!("-> OpenScenarioRelativeRoadPositionToMaliputRoadPosition Result:");
495 if res.len() == 4 {
496 println!("\t* Maliput Road Position:");
497 println!("\t\t* lane_id: {}", res[0]);
498 println!("\t\t* s: {}", res[1]);
499 println!("\t\t* r: {}", res[2]);
500 println!("\t\t* h: {}", res[3]);
501 } else {
502 println!("-> Invalid response from backend custom command: {}", res.join(", "));
503 }
504 }
505 MaliputQuery::OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition(..) => {
506 let command = query.to_backend_custom_command_format().expect(
507 "Invalid query command format for OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition",
508 );
509 let res = rg.backend_custom_command(&command);
510 print_elapsed_time(start_time);
511 let res: Vec<&str> = res.split(',').collect();
512 println!("-> OpenScenarioRelativeLanePositionWithDsToMaliputRoadPosition Result:");
513 if res.len() == 4 {
514 println!("\t* Maliput Road Position:");
515 println!("\t\t* lane_id: {}", res[0]);
516 println!("\t\t* s: {}", res[1]);
517 println!("\t\t* r: {}", res[2]);
518 println!("\t\t* h: {}", res[3]);
519 } else {
520 println!("-> Invalid response from backend custom command: {}", res.join(", "));
521 }
522 }
523 MaliputQuery::OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition(..) => {
524 let command = query.to_backend_custom_command_format().expect(
525 "Invalid query command format for OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition",
526 );
527 let res = rg.backend_custom_command(&command);
528 print_elapsed_time(start_time);
529 let res: Vec<&str> = res.split(',').collect();
530 println!("-> OpenScenarioRelativeLanePositionWithDsLaneToMaliputRoadPosition Result:");
531 if res.len() == 4 {
532 println!("\t* Maliput Road Position:");
533 println!("\t\t* lane_id: {}", res[0]);
534 println!("\t\t* s: {}", res[1]);
535 println!("\t\t* r: {}", res[2]);
536 println!("\t\t* h: {}", res[3]);
537 } else {
538 println!("-> Invalid response from backend custom command: {}", res.join(", "));
539 }
540 }
541 MaliputQuery::GetRoadOrientationAtOpenScenarioRoadPosition(..) => {
542 let command = query
543 .to_backend_custom_command_format()
544 .expect("Invalid query command format for GetRoadOrientationAtOpenScenarioRoadPosition");
545 let res = rg.backend_custom_command(&command);
546 print_elapsed_time(start_time);
547 let res: Vec<&str> = res.split(',').collect();
548 println!("-> GetRoadOrientationAtOpenScenarioRoadPosition Result:");
549 if res.len() == 3 {
550 println!("\t* Orientation:");
551 println!("\t\t* roll: {}", res[0]);
552 println!("\t\t* pitch: {}", res[1]);
553 println!("\t\t* yaw: {}", res[2]);
554 } else {
555 println!("-> Invalid response from backend custom command: {}", res.join(", "));
556 }
557 }
558 MaliputQuery::Invalid => {
559 println!("-> Invalid query command. Please try again.");
560 println!();
561 MaliputQuery::print_available_queries();
562 }
563 }
564 fn print_elapsed_time(start_time: std::time::Instant) {
566 let elapsed = start_time.elapsed();
567 println!("-> Query executed in {:.2?}.", elapsed);
568 }
569 }
570}
571
572#[derive(Parser, Debug)]
573#[command(author, version, about)]
574struct Args {
575 road_network_xodr_file_path: String,
576
577 #[arg(short, long, default_value_t = 0.05)]
581 linear_tolerance: f64,
582
583 #[arg(short, long)]
584 max_linear_tolerance: Option<f64>,
585
586 #[arg(short, long, default_value_t = 0.01)]
587 angular_tolerance: f64,
588
589 #[arg(long, default_value_t = false)]
590 allow_non_drivable_lanes: bool,
591
592 #[arg(long, default_value_t = false)]
593 disable_parallel_builder_policy: bool,
594
595 #[arg(long, default_value_t = maliput::common::LogLevel::Error)]
596 set_log_level: maliput::common::LogLevel,
597}
598
599use std::path::PathBuf;
603fn parse_xodr_file_path(path: &str) -> PathBuf {
604 let mut path_buf = PathBuf::from(path);
605 if !path_buf.is_absolute() {
606 if let Ok(current_dir) = std::env::current_dir() {
608 path_buf = current_dir.join(path_buf);
609 }
610 }
611 path_buf
612}
613
614fn main() -> Result<(), Box<dyn std::error::Error>> {
615 println!("Welcome to maliput_query app:");
616 println!("\t* This application allows you to query a road network built from an OpenDRIVE file.");
617 println!("\t* Usage: maliput_query <XODR_FILE_PATH> [OPTIONS]");
618 println!();
619 let args = Args::parse();
620
621 let xodr_path = parse_xodr_file_path(args.road_network_xodr_file_path.as_str());
623 let linear_tolerance: String = args.linear_tolerance.to_string();
624 let max_linear_tolerance = args.max_linear_tolerance;
625 let angular_tolerance = args.angular_tolerance.to_string();
626 let omit_non_drivable_lanes = if args.allow_non_drivable_lanes { "false" } else { "true" };
627 let parallel_builder_policy = !args.disable_parallel_builder_policy;
628
629 let mut road_network_properties = HashMap::from([
630 ("road_geometry_id", "maliput_query_rg"),
631 ("opendrive_file", xodr_path.to_str().unwrap()),
632 ("linear_tolerance", linear_tolerance.as_str()),
633 ("omit_nondrivable_lanes", omit_non_drivable_lanes),
634 ("angular_tolerance", angular_tolerance.as_str()),
635 (
636 "build_policy",
637 if parallel_builder_policy {
638 "parallel"
639 } else {
640 "sequential"
641 },
642 ),
643 ]);
644 let max_linear_tolerance_str;
645 if let Some(max_tolerance) = max_linear_tolerance {
646 max_linear_tolerance_str = max_tolerance.to_string();
647 road_network_properties.insert("max_linear_tolerance", max_linear_tolerance_str.as_str());
648 }
649
650 println!();
651 println!("-> Setting maliput log level to: {}", args.set_log_level);
652 maliput::common::set_log_level(args.set_log_level);
653 println!("-> Road network builder options: {:?}", road_network_properties);
654 println!("->");
655 println!(
656 "-> Building Maliput Road Network from OpenDRIVE file: {}",
657 xodr_path.display()
658 );
659 println!("-> This may take a while, depending on the size of the OpenDRIVE file and the complexity of the road network...");
660 println!("-> ...");
661 let now = std::time::Instant::now();
662 let road_network = RoadNetwork::new("maliput_malidrive", &road_network_properties)?;
663 let elapsed = now.elapsed();
664 println!("-> Road network loaded in {:.2?}.", elapsed);
665
666 println!();
668 MaliputQuery::print_available_queries();
669 println!("To exit the application, type 'exit'.");
670
671 loop {
672 println!();
673 let mut input = String::new();
674 println!("-> Enter a query command (or 'exit' to quit):");
675 std::io::stdin().read_line(&mut input)?;
676 let input = input.trim();
677
678 if input == "exit" {
679 break;
680 }
681
682 let query: MaliputQuery = input.split_whitespace().collect::<Vec<&str>>().into();
683 let query_handler = RoadNetworkQuery::new(&road_network);
684 query_handler.execute_query(query);
685 }
686
687 Ok(())
688}