use crate::{
domain::{Cost, Reversible, Weighted},
error::NoError,
motion::{Measurable, Timed},
};
#[derive(Debug, Clone, Copy)]
pub struct TravelEffortCost {
pub time: f64,
pub translation: f64,
pub rotation: f64,
}
impl TravelEffortCost {
pub fn save_one_second_with_detour_up_to(meters: f64, radians: f64) -> Self {
Self {
time: 1.0,
translation: 1.0 / meters,
rotation: 1.0 / radians,
}
}
}
const DEFAULT_TRANSLATION_EFFORT_ALLOWANCE: f64 = 5.0;
const DEFAULT_ROTATION_EFFORT_ALLOWANCE: f64 = 360.0 * std::f64::consts::PI / 180.0;
impl Default for TravelEffortCost {
fn default() -> Self {
TravelEffortCost::save_one_second_with_detour_up_to(
DEFAULT_TRANSLATION_EFFORT_ALLOWANCE,
DEFAULT_ROTATION_EFFORT_ALLOWANCE,
)
}
}
impl<State: Timed, Action: Measurable<State>> Weighted<State, Action> for TravelEffortCost {
type Cost = Cost<f64>;
type WeightedError = NoError;
fn cost(
&self,
from_state: &State,
action: &Action,
to_state: &State,
) -> Result<Option<Self::Cost>, Self::WeightedError> {
let duration = (to_state.time() - from_state.time()).as_secs_f64().abs();
let arclength = action.arclength(from_state, to_state);
let cost = self.time * duration
+ self.translation * arclength.translational
+ self.rotation * arclength.rotational;
Ok(Some(Cost(cost)))
}
fn initial_cost(&self, _: &State) -> Result<Option<Self::Cost>, Self::WeightedError> {
Ok(Some(Cost(0.0)))
}
}
impl Reversible for TravelEffortCost {
type ReversalError = NoError;
fn reversed(&self) -> Result<Self, Self::ReversalError>
where
Self: Sized,
{
Ok(*self)
}
}