use crate::{
domain::{Initializable, Key, Keyed, KeyedSpace, Keyring, Reversible, SelfKey, Space},
error::{NoError, ThisError},
graph::Graph,
motion::{
r2::*,
se2::{MaybeOriented, Orientation, StateSE2},
IntegrateWaypoints, MaybeTimed, TimePoint, Timed,
},
};
use std::borrow::Borrow;
#[derive(Debug)]
pub struct DiscreteSpaceTimeR2<Key>(std::marker::PhantomData<Key>);
impl<Key> DiscreteSpaceTimeR2<Key> {
pub fn new() -> Self {
Self(Default::default())
}
}
impl<Key> Clone for DiscreteSpaceTimeR2<Key> {
fn clone(&self) -> Self {
Self::new()
}
}
impl<Key> Copy for DiscreteSpaceTimeR2<Key> {}
impl<Key> Default for DiscreteSpaceTimeR2<Key> {
fn default() -> Self {
Self::new()
}
}
impl<Key> Space for DiscreteSpaceTimeR2<Key> {
type State = StateR2<Key>;
type Waypoint = timed_position::WaypointR2;
type WaypointRef<'a>
= &'a Self::Waypoint
where
Key: 'a;
fn waypoint<'a>(&'a self, state: &'a Self::State) -> &'a Self::Waypoint {
&state.waypoint
}
}
impl<K: Key> Keyed for DiscreteSpaceTimeR2<K> {
type Key = K;
}
impl<K: Key + Clone> Keyring<StateR2<K>> for DiscreteSpaceTimeR2<K> {
type KeyRef<'a>
= &'a Self::Key
where
K: 'a;
fn key_for<'a>(&'a self, state: &'a StateR2<K>) -> &'a Self::Key
where
K: 'a,
{
&state.key
}
}
impl<K: Key + Clone> KeyedSpace<K> for DiscreteSpaceTimeR2<K> {
fn make_keyed_state(&self, key: K, waypoint: Self::Waypoint) -> Self::State {
StateR2 { key, waypoint }
}
fn vertex_of<'a>(&'a self, key: &'a Self::Key) -> &'a K
where
K: 'a,
{
key
}
}
impl<K> Reversible for DiscreteSpaceTimeR2<K> {
type ReversalError = NoError;
fn reversed(&self) -> Result<Self, Self::ReversalError>
where
Self: Sized,
{
Ok(self.clone())
}
}
#[derive(Debug, Clone, Copy)]
pub struct StateR2<K> {
pub key: K,
pub waypoint: timed_position::WaypointR2,
}
impl<K> Positioned for StateR2<K> {
fn point(&self) -> Point {
self.waypoint.point()
}
}
impl<K> MaybePositioned for StateR2<K> {
fn maybe_point(&self) -> Option<Point> {
self.waypoint.maybe_point()
}
}
impl<K> MaybeOriented for StateR2<K> {
fn maybe_oriented(&self) -> Option<Orientation> {
None
}
}
impl<W: From<WaypointR2>, K> IntegrateWaypoints<W> for StateR2<K> {
type IntegratedWaypointIter<'a>
= Option<Result<W, NoError>>
where
W: 'a,
K: 'a;
type WaypointIntegrationError = NoError;
fn integrated_waypoints<'a>(
&'a self,
_initial_waypoint: Option<W>,
) -> Self::IntegratedWaypointIter<'a>
where
Self: 'a,
Self::WaypointIntegrationError: 'a,
W: 'a,
{
Some(Ok(self.waypoint.into()))
}
}
impl<K> Borrow<K> for StateR2<K> {
fn borrow(&self) -> &K {
&self.key
}
}
impl<K> Timed for StateR2<K> {
fn set_time(&mut self, new_time: TimePoint) {
self.waypoint.set_time(new_time);
}
fn time(&self) -> TimePoint {
self.waypoint.time()
}
}
impl<K> MaybeTimed for StateR2<K> {
fn maybe_time(&self) -> Option<TimePoint> {
Some(self.waypoint.time())
}
}
impl<K: Key + Clone> Keyed for StateR2<K> {
type Key = K;
}
impl<K: Key + Clone> SelfKey for StateR2<K> {
type KeyRef<'a>
= &'a Self::Key
where
K: 'a;
fn key<'a>(&'a self) -> &'a Self::Key
where
K: 'a,
{
&self.key
}
}
impl<K, const R: u32> From<StateSE2<K, R>> for StateR2<K> {
fn from(value: StateSE2<K, R>) -> Self {
StateR2 {
key: value.key.vertex,
waypoint: WaypointR2 {
time: value.waypoint.time,
position: value.waypoint.position.point(),
},
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct StartR2<K> {
pub time: TimePoint,
pub key: K,
}
impl<K> From<(TimePoint, K)> for StartR2<K> {
fn from((time, key): (TimePoint, K)) -> Self {
StartR2 { key, time }
}
}
impl<K> From<K> for StartR2<K> {
fn from(key: K) -> Self {
StartR2 {
key,
time: TimePoint::zero(),
}
}
}
#[derive(Debug, Clone)]
pub struct InitializeR2<G>(pub G);
impl<G, Start, Goal> Initializable<Start, Goal, StateR2<G::Key>> for InitializeR2<G>
where
G: Graph,
G::Key: Clone,
G::Vertex: Positioned,
Start: Into<StartR2<G::Key>>,
{
type InitialError = InitializeR2Error<G::Key>;
type InitialStates<'a>
= [Result<StateR2<G::Key>, InitializeR2Error<G::Key>>; 1]
where
Self: 'a,
Start: 'a,
Goal: 'a;
fn initialize<'a>(&'a self, from_start: Start, _to_goal: &Goal) -> Self::InitialStates<'a>
where
Self: 'a,
Self::InitialError: 'a,
Start: 'a,
Goal: 'a,
{
let start: StartR2<G::Key> = from_start.into();
[self
.0
.vertex(&start.key)
.ok_or_else(|| InitializeR2Error::MissingVertex(start.key.clone()))
.map(|v| {
let v: Position = v.borrow().point();
StateR2 {
key: start.key,
waypoint: WaypointR2::new(start.time, v.x, v.y),
}
})]
}
}
impl<G: Reversible> Reversible for InitializeR2<G> {
type ReversalError = G::ReversalError;
fn reversed(&self) -> Result<Self, Self::ReversalError>
where
Self: Sized,
{
Ok(Self(self.0.reversed()?))
}
}
#[derive(Debug, ThisError)]
pub enum InitializeR2Error<K> {
#[error("The graph was missing the start vertex: {0:?}")]
MissingVertex(K),
}