1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Copyright (c) 2025 Junior Sundar
//
// SPDX-License-Identifier: BSD-3-Clause
use pyo3::{exceptions::PyValueError, prelude::*};
use std::sync::{Arc, Mutex};
use oxmpl::base::space::{RealVectorStateSpace as OxmplRealVectorStateSpace, StateSpace as _};
use super::real_vector_state::PyRealVectorState;
/// Defines an N-dimensional space for `RealVectorState` instances.
///
/// This class defines the planning space, including its dimensionality and boundaries.
#[pyclass(name = "RealVectorStateSpace", unsendable)]
#[derive(Clone)]
pub struct PyRealVectorStateSpace(pub Arc<Mutex<OxmplRealVectorStateSpace>>);
#[pymethods]
impl PyRealVectorStateSpace {
/// Creates a new `RealVectorStateSpace`.
///
/// Args:
/// dimension (int): The number of dimensions for the space.
/// bounds (Optional[List[Tuple[float, float]]]): If provided, defines the
/// min and max for each dimension. If `None`, the space is unbounded.
///
/// Raises:
/// ValueError: If the provided inputs are invalid.
#[new]
#[pyo3(signature = (dimension, bounds=None))]
fn new(dimension: usize, bounds: Option<Vec<(f64, f64)>>) -> PyResult<Self> {
match OxmplRealVectorStateSpace::new(dimension, bounds) {
Ok(space) => Ok(Self(Arc::new(Mutex::new(space)))),
Err(e) => Err(PyValueError::new_err(e.to_string())),
}
}
/// Computes the Euclidean (L2) distance between two states.
fn distance(&self, state1: &PyRealVectorState, state2: &PyRealVectorState) -> f64 {
// This calls the real Rust implementation.
self.0.lock().unwrap().distance(&state1.0, &state2.0)
}
/// Returns the maximum possible distance in this space.
fn get_maximum_extent(&self) -> f64 {
self.0.lock().unwrap().get_maximum_extent()
}
/// Sets the fraction used to determine motion checking resolution.
fn set_longest_valid_segment_fraction(&mut self, fraction: f64) {
self.0
.lock()
.unwrap()
.set_longest_valid_segment_fraction(fraction);
}
}