Skip to content

Commit 5a49270

Browse files
committed
wip
1 parent 4af533d commit 5a49270

File tree

13 files changed

+335
-9
lines changed

13 files changed

+335
-9
lines changed

openrr-nav-viewer/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@ edition = "2021"
77

88
[dependencies]
99
arci = "0.1"
10+
arci-urdf-viz = "0.1"
1011
bevy = "0.10"
1112
bevy_egui = "0.20"
1213
egui = "0.20"
1314
nalgebra = "0.30"
1415
parking_lot = "0.12"
1516
grid_map = { path = "../grid_map" }
1617
openrr-nav = { path = "../openrr-nav" }
18+
yaml-rust = "0.4"
1719

1820
[dev-dependencies]
1921
arci-ros = "0.1"
20-
arci-urdf-viz = "0.1"
2122
tokio = "1"
2223
rand = "0.8"
2324
rrt = "0.7"
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
navigation_app_config:
2+
init_pose_2d: [0.0, 0.0, 0.0]
3+
map: ""
4+
localization_client: "UrdfViz"
5+
move_base_client: "UrdfViz"
6+
7+
local_plan_executor_config:
8+
planner_type: "dwa"
9+
frame_id: "frame"
10+
11+
dwa_planner_config:
12+
max_velocity: [0.5, 2.0]
13+
max_acceleration: [2.0, 5.0]
14+
min_velocity: [0.0, -2.0]
15+
min_accleration: [-2.0, -5.0]
16+
distance_map_weight:
17+
path: 0.8
18+
goal: 0.9
19+
obstacle: 0.3
20+
controller_dt: 0.1
21+
simulation_duration: 1.0
22+
number_of_velocity_sample: 5

openrr-nav-viewer/examples/urdf_viz_client.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ fn main() {
3030
let localization_client = Arc::new(Mutex::new(UrdfVizWebClient::default()));
3131

3232
let mut nav = NavigationVizLite::new(move_base_client, localization_client);
33-
nav.start = Arc::new(Mutex::new(Position::new(-0.8, -0.9)));
34-
nav.goal = Arc::new(Mutex::new(Position::new(2.5, 0.5)));
3533
nav.grid_map = Arc::new(Mutex::new(new_square_map()));
3634

3735
let cloned_nav = nav.clone();
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
use arci::Localization;
2+
use arci_urdf_viz::UrdfVizWebClient;
3+
use grid_map::*;
4+
use openrr_nav::*;
5+
use openrr_nav_viewer::*;
6+
use parking_lot::Mutex;
7+
use rand::distributions::{Distribution, Uniform};
8+
use std::sync::Arc;
9+
10+
fn new_square_map() -> GridMap<u8> {
11+
let mut map =
12+
grid_map::GridMap::<u8>::new(Position::new(-5.0, -5.0), Position::new(5.0, 5.0), 0.05);
13+
14+
for i in 0..200 {
15+
map.set_obstacle(&Grid { x: 0, y: i });
16+
map.set_obstacle(&Grid { x: 199, y: i });
17+
map.set_obstacle(&Grid { x: i, y: 0 });
18+
map.set_obstacle(&Grid { x: i, y: 199 });
19+
}
20+
21+
map
22+
}
23+
24+
fn main() {
25+
let move_base_client = Arc::new(Mutex::new({
26+
let client = UrdfVizWebClient::default();
27+
client.run_send_velocity_thread();
28+
client
29+
}));
30+
let localization_client = Arc::new(Mutex::new(UrdfVizWebClient::default()));
31+
32+
let mut nav = NavigationVizLite::new(move_base_client, localization_client);
33+
nav.grid_map = Arc::new(Mutex::new(new_square_map()));
34+
35+
let cloned_nav = nav.clone();
36+
37+
std::thread::spawn(move || loop {
38+
if cloned_nav.is_run.lock().clone() {
39+
let (x_range, y_range) = {
40+
let map = cloned_nav.grid_map.lock();
41+
(
42+
Uniform::new(map.min_point().x, map.max_point().x),
43+
Uniform::new(map.min_point().y, map.max_point().y),
44+
)
45+
};
46+
47+
let goal = {
48+
let locked_goal = cloned_nav.goal.lock();
49+
[locked_goal.x, locked_goal.y]
50+
};
51+
52+
let start = {
53+
let pose = cloned_nav.localization.lock().current_pose("").unwrap();
54+
[pose.translation.x, pose.translation.y]
55+
};
56+
57+
let result = rrt::dual_rrt_connect(
58+
&start,
59+
&goal,
60+
|p: &[f64]| {
61+
let map = cloned_nav.grid_map.lock();
62+
!matches!(
63+
map.cell(&map.to_grid(p[0], p[1]).unwrap()).unwrap(),
64+
Cell::Obstacle
65+
)
66+
},
67+
|| {
68+
let mut rng = rand::thread_rng();
69+
vec![x_range.sample(&mut rng), y_range.sample(&mut rng)]
70+
},
71+
0.05,
72+
1000,
73+
)
74+
.unwrap();
75+
76+
let path_grid = result
77+
.iter()
78+
.map(|p| {
79+
let map = cloned_nav.grid_map.lock();
80+
map.to_grid(p[0], p[1]).unwrap()
81+
})
82+
.collect::<Vec<_>>();
83+
84+
{
85+
let mut grid_map = cloned_nav.grid_map.lock();
86+
*grid_map = new_square_map();
87+
}
88+
89+
for p in result {
90+
let mut locked_map = cloned_nav.grid_map.lock();
91+
let grid = locked_map.to_grid(p[0], p[1]).unwrap();
92+
locked_map.set_value(&grid, 0).unwrap();
93+
}
94+
95+
let (path_distance_map, goal_distance_map, obstacle_distance_map) = {
96+
let map = cloned_nav.grid_map.lock();
97+
98+
let goal_grid = map.to_grid(goal[0], goal[1]).unwrap();
99+
100+
(
101+
path_distance_map(&map, &path_grid).unwrap(),
102+
goal_distance_map(&map, &goal_grid).unwrap(),
103+
obstacle_distance_map(&map).unwrap(),
104+
)
105+
};
106+
107+
let mut layered_grid_map = LayeredGridMap::default();
108+
layered_grid_map.add_layer(PATH_DISTANCE_MAP_NAME.to_owned(), path_distance_map);
109+
layered_grid_map.add_layer(GOAL_DISTANCE_MAP_NAME.to_owned(), goal_distance_map);
110+
layered_grid_map
111+
.add_layer(OBSTACLE_DISTANCE_MAP_NAME.to_owned(), obstacle_distance_map);
112+
113+
let mut current_pose;
114+
let goal_pose = Pose::new(Vector2::new(goal[0], goal[1]), 0.0);
115+
116+
let move_base_client = cloned_nav.move_base.clone();
117+
let localization_client = cloned_nav.localization.clone();
118+
119+
let mut executor = local_plan_executor_from_yaml_config(
120+
"./config/example_app.yaml",
121+
move_base_client,
122+
localization_client,
123+
)
124+
.unwrap();
125+
executor.set_cost_maps(layered_grid_map);
126+
127+
for i in 0..1000 {
128+
executor.exec_once().unwrap();
129+
130+
current_pose = executor.current_pose();
131+
132+
std::thread::sleep(std::time::Duration::from_millis(50));
133+
const GOAL_THRESHOLD: f64 = 0.1;
134+
if (goal_pose.translation.vector - current_pose.translation.vector).norm()
135+
< GOAL_THRESHOLD
136+
{
137+
println!("GOAL! count = {i}");
138+
break;
139+
}
140+
}
141+
executor.stop();
142+
{
143+
let mut is_run = cloned_nav.is_run.lock();
144+
*is_run = false;
145+
}
146+
}
147+
});
148+
149+
let bevy_cloned_nav = nav.clone();
150+
let mut app = BevyAppLite::new();
151+
app.setup(bevy_cloned_nav);
152+
app.run();
153+
}

openrr-nav-viewer/src/bevy_app.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ use bevy_egui::{
44
EguiContexts, EguiPlugin,
55
};
66
use grid_map::Position;
7+
use openrr_nav::{GOAL_DISTANCE_MAP_NAME, OBSTACLE_DISTANCE_MAP_NAME, PATH_DISTANCE_MAP_NAME};
78

89
use crate::*;
910

10-
pub const PATH_DISTANCE_MAP_NAME: &str = "path";
11-
pub const GOAL_DISTANCE_MAP_NAME: &str = "goal";
12-
pub const OBSTACLE_DISTANCE_MAP_NAME: &str = "obstacle";
1311
pub const DEFAULT_PATH_DISTANCE_WEIGHT: f64 = 0.8;
1412
pub const DEFAULT_GOAL_DISTANCE_WEIGHT: f64 = 0.9;
1513
pub const DEFAULT_OBSTACLE_DISTANCE_WEIGHT: f64 = 0.3;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use arci::{Localization, MoveBase};
2+
use arci_urdf_viz::UrdfVizWebClient;
3+
use parking_lot::Mutex;
4+
use std::{fs, sync::Arc};
5+
use yaml_rust::YamlLoader;
6+
7+
use crate::{Error, NavigationVizLite};
8+
9+
pub fn navigation_viz_lite_from_yaml_config<M: MoveBase, L: Localization>(
10+
path: &str,
11+
) -> Result<NavigationVizLite<M, L>, Error> {
12+
let yaml_file = match fs::read_to_string(path) {
13+
Ok(s) => s,
14+
Err(_) => return Err(Error::FailedToLoadConfigFile),
15+
};
16+
let config_vec = YamlLoader::load_from_str(&yaml_file).unwrap();
17+
let config = &config_vec[0];
18+
19+
let move_base;
20+
let localization;
21+
22+
match config["move_base_client"].as_str().unwrap() {
23+
"UrdfViz" => {
24+
move_base = Arc::new(Mutex::new({
25+
let client = UrdfVizWebClient::default();
26+
client.run_send_velocity_thread();
27+
client
28+
}));
29+
}
30+
_ => {}
31+
}
32+
33+
let mut nav = NavigationVizLite::new(move_base, localization);
34+
35+
Ok(nav)
36+
}
37+
38+
#[cfg(test)]
39+
mod test {
40+
use super::*;
41+
42+
const SAMPLE_YAML_CONFIG_PATH: &str = "./config/example_app.yaml";
43+
44+
#[test]
45+
fn test_navigation_viz_lite_yaml_config() {
46+
// let _ = navigation_viz_lite_from_yaml_config(SAMPLE_YAML_CONFIG_PATH);
47+
}
48+
}

openrr-nav-viewer/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub enum Error {
2+
FailedToLoadConfigFile,
3+
}

openrr-nav-viewer/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
mod bevy_app;
22
mod bevy_app_lite;
3+
mod config_reader;
34
mod converter;
5+
mod error;
46
mod map_type;
57
mod nav_viz;
68

79
pub use bevy_app::*;
810
pub use bevy_app_lite::*;
11+
pub use config_reader::*;
912
pub use converter::*;
13+
pub use error::*;
1014
pub use map_type::*;
1115
pub use nav_viz::*;

openrr-nav/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ grid_map = "0.1"
1111
arci = "0.1"
1212
thiserror = "1"
1313
parking_lot = "0.12"
14+
yaml-rust = "0.4"
1415

1516
[dev-dependencies]
1617
rand = "0.8"

openrr-nav/src/config_reader.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
use arci::{Localization, MoveBase};
2+
use grid_map::LayeredGridMap;
3+
use parking_lot::Mutex;
4+
use std::{collections::HashMap, fs, sync::Arc};
5+
use yaml_rust::YamlLoader;
6+
7+
use crate::*;
8+
9+
pub fn local_plan_executor_from_yaml_config<M: MoveBase, L: Localization>(
10+
path: &str,
11+
move_base: Arc<Mutex<M>>,
12+
localization: Arc<Mutex<L>>,
13+
) -> Result<LocalPlanExecutor<M, L>> {
14+
let yaml_file = match fs::read_to_string(path) {
15+
Ok(s) => s,
16+
Err(_) => return Err(Error::FailedToLoadConfigFile("No such file".to_owned())),
17+
};
18+
let config_vec = YamlLoader::load_from_str(&yaml_file).unwrap();
19+
let config = &config_vec[0];
20+
21+
let local_plane_executor_config = &config["local_plan_executor_config"];
22+
let local_planner;
23+
match local_plane_executor_config["planner_type"]
24+
.as_str()
25+
.unwrap()
26+
{
27+
"dwa" => {
28+
let dwa_config = &config["dwa_planner_config"];
29+
30+
let max_vel = dwa_config["max_velocity"].as_vec().unwrap();
31+
let max_accel = dwa_config["max_acceleration"].as_vec().unwrap();
32+
let min_vel = dwa_config["min_velocity"].as_vec().unwrap();
33+
let min_accel = dwa_config["min_acceleration"].as_vec().unwrap();
34+
35+
let limits = Limits {
36+
max_velocity: Velocity {
37+
x: max_vel[0].as_f64().unwrap(),
38+
theta: max_vel[1].as_f64().unwrap(),
39+
},
40+
max_accel: Acceleration {
41+
x: max_accel[0].as_f64().unwrap(),
42+
theta: max_accel[1].as_f64().unwrap(),
43+
},
44+
min_velocity: Velocity {
45+
x: min_vel[0].as_f64().unwrap(),
46+
theta: min_vel[1].as_f64().unwrap(),
47+
},
48+
min_accel: Acceleration {
49+
x: min_accel[0].as_f64().unwrap(),
50+
theta: min_accel[1].as_f64().unwrap(),
51+
},
52+
};
53+
54+
let mut map_name_weight = HashMap::new();
55+
map_name_weight.insert(
56+
PATH_DISTANCE_MAP_NAME.to_owned(),
57+
dwa_config[PATH_DISTANCE_MAP_NAME].as_f64().unwrap(),
58+
);
59+
map_name_weight.insert(
60+
GOAL_DISTANCE_MAP_NAME.to_owned(),
61+
dwa_config[GOAL_DISTANCE_MAP_NAME].as_f64().unwrap(),
62+
);
63+
map_name_weight.insert(
64+
OBSTACLE_DISTANCE_MAP_NAME.to_owned(),
65+
dwa_config[OBSTACLE_DISTANCE_MAP_NAME].as_f64().unwrap(),
66+
);
67+
68+
local_planner = DwaPlanner::new(
69+
limits,
70+
map_name_weight,
71+
dwa_config["controller_dt"].as_f64().unwrap(),
72+
dwa_config["simulation_duration"].as_f64().unwrap(),
73+
dwa_config["number_of_velocity_sample"].as_i64().unwrap() as i32,
74+
);
75+
}
76+
_ => {
77+
todo!()
78+
}
79+
}
80+
81+
let local_plan_executor = LocalPlanExecutor::new(
82+
move_base,
83+
localization,
84+
local_plane_executor_config["frame_id"]
85+
.as_str()
86+
.unwrap()
87+
.to_owned(),
88+
local_planner,
89+
LayeredGridMap::default(),
90+
);
91+
92+
Ok(local_plan_executor)
93+
}

0 commit comments

Comments
 (0)