oxmpl_js/base/
compound_state_space.rs1use std::sync::{Arc, Mutex};
6
7use oxmpl::base::space::{AnyStateSpace, CompoundStateSpace, StateSpace};
8use rand::rng;
9use wasm_bindgen::prelude::*;
10
11use crate::base::{
12 JsCompoundState, JsRealVectorStateSpace, JsSE2StateSpace, JsSE3StateSpace, JsSO2StateSpace,
13 JsSO3StateSpace,
14};
15
16#[wasm_bindgen(js_name = CompoundStateSpace)]
17pub struct JsCompoundStateSpace {
18 #[wasm_bindgen(skip)]
19 pub inner: Arc<Mutex<CompoundStateSpace>>,
20}
21
22#[wasm_bindgen(js_class = CompoundStateSpace)]
23impl JsCompoundStateSpace {
24 #[wasm_bindgen(js_name = sample)]
25 pub fn sample(&self) -> Result<JsCompoundState, String> {
26 let mut rng = rng();
27 match self.inner.lock().unwrap().sample_uniform(&mut rng) {
28 Ok(state) => Ok(JsCompoundState {
29 inner: Arc::new(state),
30 }),
31 Err(e) => Err(e.to_string()),
32 }
33 }
34
35 #[wasm_bindgen(js_name = distance)]
36 pub fn distance(&self, state1: &JsCompoundState, state2: &JsCompoundState) -> f64 {
37 self.inner
38 .lock()
39 .unwrap()
40 .distance(&state1.inner, &state2.inner)
41 }
42
43 #[wasm_bindgen(js_name = satisfiesBounds)]
44 pub fn satisfies_bounds(&self, state: &JsCompoundState) -> bool {
45 self.inner.lock().unwrap().satisfies_bounds(&state.inner)
46 }
47
48 #[wasm_bindgen(js_name = enforceBounds)]
49 pub fn enforce_bounds(&self, state: &JsCompoundState) -> JsCompoundState {
50 let mut new_state = (*state.inner).clone();
51 self.inner.lock().unwrap().enforce_bounds(&mut new_state);
52 JsCompoundState {
53 inner: Arc::new(new_state),
54 }
55 }
56
57 #[wasm_bindgen(js_name = interpolate)]
58 pub fn interpolate(
59 &self,
60 from: &JsCompoundState,
61 to: &JsCompoundState,
62 t: f64,
63 ) -> JsCompoundState {
64 let mut result_state = (*from.inner).clone();
65 self.inner
66 .lock()
67 .unwrap()
68 .interpolate(&from.inner, &to.inner, t, &mut result_state);
69 JsCompoundState {
70 inner: Arc::new(result_state),
71 }
72 }
73
74 #[wasm_bindgen(js_name = getLongestValidSegmentLength)]
75 pub fn get_longest_valid_segment_length(&self) -> f64 {
76 self.inner
77 .lock()
78 .unwrap()
79 .get_longest_valid_segment_length()
80 }
81}
82
83#[wasm_bindgen(js_name = CompoundStateSpaceBuilder)]
84pub struct JsCompoundStateSpaceBuilder {
85 subspaces: Vec<Box<dyn AnyStateSpace>>,
86 weights: Vec<f64>,
87}
88
89impl Default for JsCompoundStateSpaceBuilder {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95#[wasm_bindgen(js_class = CompoundStateSpaceBuilder)]
96impl JsCompoundStateSpaceBuilder {
97 #[wasm_bindgen(constructor)]
98 pub fn new() -> Self {
99 Self {
100 subspaces: Vec::new(),
101 weights: Vec::new(),
102 }
103 }
104
105 #[wasm_bindgen(js_name = addRealVectorStateSpace)]
106 pub fn add_real_vector_state_space(&mut self, space: &JsRealVectorStateSpace, weight: f64) {
107 self.subspaces
108 .push(Box::new(space.inner.lock().unwrap().clone()));
109 self.weights.push(weight);
110 }
111
112 #[wasm_bindgen(js_name = addSO2StateSpace)]
113 pub fn add_so2_state_space(&mut self, space: &JsSO2StateSpace, weight: f64) {
114 self.subspaces
115 .push(Box::new(space.inner.lock().unwrap().clone()));
116 self.weights.push(weight);
117 }
118
119 #[wasm_bindgen(js_name = addSO3StateSpace)]
120 pub fn add_so3_state_space(&mut self, space: &JsSO3StateSpace, weight: f64) {
121 self.subspaces
122 .push(Box::new(space.inner.lock().unwrap().clone()));
123 self.weights.push(weight);
124 }
125
126 #[wasm_bindgen(js_name = addSE2StateSpace)]
127 pub fn add_se2_state_space(&mut self, space: &JsSE2StateSpace, weight: f64) {
128 self.subspaces
129 .push(Box::new(space.inner.lock().unwrap().clone()));
130 self.weights.push(weight);
131 }
132
133 #[wasm_bindgen(js_name = addSE3StateSpace)]
134 pub fn add_se3_state_space(&mut self, space: &JsSE3StateSpace, weight: f64) {
135 self.subspaces
136 .push(Box::new(space.inner.lock().unwrap().clone()));
137 self.weights.push(weight);
138 }
139
140 #[wasm_bindgen(js_name = addCompoundStateSpace)]
141 pub fn add_compound_state_space(&mut self, space: &JsCompoundStateSpace, weight: f64) {
142 self.subspaces
143 .push(Box::new(space.inner.lock().unwrap().clone()));
144 self.weights.push(weight);
145 }
146
147 pub fn build(self) -> JsCompoundStateSpace {
148 let space = CompoundStateSpace::new(self.subspaces, self.weights);
149 JsCompoundStateSpace {
150 inner: Arc::new(Mutex::new(space)),
151 }
152 }
153}