rs_opw_kinematics/path_plan/
rrt.rs1use crate::kinematic_traits::{Joints, Kinematics};
2use crate::kinematics_with_shape::KinematicsWithShape;
3use crate::rrt_to::{dual_rrt_connect};
4use crate::utils::dump_joints;
5use std::sync::atomic::{AtomicBool};
6use std::time::Instant;
7
8#[derive(Debug)]
9pub struct RRTPlanner {
12 pub step_size_joint_space: f64,
16
17 pub max_try: usize,
20
21 pub debug: bool,
23}
24
25impl Default for RRTPlanner {
26 fn default() -> Self {
27 Self {
28 step_size_joint_space: 3_f64.to_radians(),
29 max_try: 2000,
30 debug: true,
31 }
32 }
33}
34
35impl RRTPlanner {
36 fn plan_path(
40 &self,
41 kinematics: &KinematicsWithShape,
42 start: &Joints,
43 goal: &Joints,
44 stop: &AtomicBool,
45 ) -> Result<Vec<Vec<f64>>, String> {
46 let collision_free = |joint_angles: &[f64]| -> bool {
49 let joints = &<Joints>::try_from(joint_angles).expect("Cannot convert vector to array");
50 !kinematics.collides(joints)
51 };
52
53 let random_joint_angles = || -> Vec<f64> {
55 return kinematics
57 .constraints()
58 .expect("Set joint ranges on kinematics")
59 .random_angles()
60 .to_vec();
61 };
62
63 let path = dual_rrt_connect(
65 start,
66 goal,
67 collision_free,
68 random_joint_angles,
69 self.step_size_joint_space, self.max_try, &stop,
72 );
73
74 path
75 }
76
77 fn convert_result(&self, data: Result<Vec<Vec<f64>>, String>) -> Result<Vec<Joints>, String> {
78 data.and_then(|vectors| {
79 vectors
80 .into_iter()
81 .map(|vec| {
82 if vec.len() == 6 {
83 Ok([vec[0], vec[1], vec[2], vec[3], vec[4], vec[5]])
85 } else {
86 Err("One of the inner vectors does not have 6 elements.".to_string())
87 }
88 })
89 .collect()
90 })
91 }
92
93 #[allow(dead_code)]
94 fn print_summary(&self, planning_result: &Result<Vec<[f64; 6]>, String>) {
95 match planning_result {
96 Ok(path) => {
97 println!("Steps:");
98 for step in path {
99 dump_joints(&step);
100 }
101 }
102 Err(error_message) => {
103 println!("Error: {}", error_message);
104 }
105 }
106 }
107
108 pub fn plan_rrt(
112 &self,
113 start: &Joints,
114 goal: &Joints,
115 kinematics: &KinematicsWithShape,
116 stop: &AtomicBool,
117 ) -> Result<Vec<Joints>, String> {
118 println!("RRT started {:?} -> {:?}", start, goal);
119 let started = Instant::now();
120 let path = self.plan_path(&kinematics, start, goal, stop);
121 let spent = started.elapsed();
122 let result = self.convert_result(path);
123
124 match &result {
125 Ok(path) => {
126 println!("RRT steps: {}", &path.len());
127 }
128 Err(error_message) => {
129 println!("Direct RRT failed: {}", error_message);
130 }
131 }
132 println!("RRT Took {:?} for {:?} -> {:?}", &spent, start, goal);
134
135 result
136 }
137}