1#![warn(missing_docs)]
20#![cfg_attr(not(feature = "std"), no_std)]
21#[cfg(feature = "std")]
22use alloc::sync::Arc;
23#[cfg(feature = "std")]
24use std::sync::{Mutex, RwLock};
25#[cfg(feature = "alloc")]
26extern crate alloc;
27#[cfg(feature = "alloc")]
28use alloc::rc::Rc;
29#[cfg(feature = "alloc")]
30use alloc::vec::Vec;
31#[cfg(any(feature = "alloc", feature = "devices"))]
34use core::cell::RefCell;
35use core::fmt::Debug;
36use core::marker::PhantomData;
37use core::ops::{
38    Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Not, Sub, SubAssign,
39};
40mod command;
41mod datum;
42#[cfg(feature = "devices")]
43pub mod devices;
44pub mod dimensions;
45pub use dimensions::*;
46mod motion_profile;
47pub mod reference;
48mod state;
49pub mod streams;
50pub use command::*;
51pub use datum::*;
52pub use motion_profile::*;
53#[cfg(feature = "alloc")]
54pub use reference::rc_ref_cell_reference;
55pub use reference::Reference;
56#[cfg(feature = "std")]
57pub use reference::{arc_mutex_reference, arc_rw_lock_reference};
58pub use state::*;
59#[derive(Clone, Copy, Debug, PartialEq)]
63#[non_exhaustive]
64pub enum Error<O: Copy + Debug> {
65    FromNone,
68    Other(O),
71}
72#[derive(Clone, Copy, Debug, PartialEq)]
74pub enum PositionDerivative {
75    Position,
77    Velocity,
79    Acceleration,
81}
82#[cfg(any(
84    feature = "dim_check_release",
85    all(debug_assertions, feature = "dim_check_debug")
86))]
87impl TryFrom<Unit> for PositionDerivative {
88    type Error = ();
89    fn try_from(was: Unit) -> Result<Self, ()> {
90        Ok(match was {
91            MILLIMETER => PositionDerivative::Position,
92            MILLIMETER_PER_SECOND => PositionDerivative::Velocity,
93            MILLIMETER_PER_SECOND_SQUARED => PositionDerivative::Acceleration,
94            _ => return Err(()),
95        })
96    }
97}
98impl From<Command> for PositionDerivative {
99    fn from(was: Command) -> Self {
100        match was {
101            Command::Position(_) => Self::Position,
102            Command::Velocity(_) => Self::Velocity,
103            Command::Acceleration(_) => Self::Acceleration,
104        }
105    }
106}
107impl TryFrom<MotionProfilePiece> for PositionDerivative {
108    type Error = ();
109    fn try_from(was: MotionProfilePiece) -> Result<Self, ()> {
110        match was {
111            MotionProfilePiece::BeforeStart | MotionProfilePiece::Complete => Err(()),
112            MotionProfilePiece::InitialAcceleration | MotionProfilePiece::EndAcceleration => {
113                Ok(PositionDerivative::Acceleration)
114            }
115            MotionProfilePiece::ConstantVelocity => Ok(PositionDerivative::Velocity),
116        }
117    }
118}
119#[derive(Clone, Copy, Debug, PartialEq)]
121pub struct PIDKValues {
122    pub kp: f32,
124    pub ki: f32,
126    pub kd: f32,
128}
129impl PIDKValues {
130    pub const fn new(kp: f32, ki: f32, kd: f32) -> Self {
132        Self {
133            kp: kp,
134            ki: ki,
135            kd: kd,
136        }
137    }
138    #[inline]
141    pub fn evaluate(&self, error: f32, error_integral: f32, error_derivative: f32) -> f32 {
142        self.kp * error + self.ki * error_integral + self.kd * error_derivative
143    }
144}
145#[derive(Clone, Copy, Debug, PartialEq)]
147pub struct PositionDerivativeDependentPIDKValues {
148    pub position: PIDKValues,
150    pub velocity: PIDKValues,
152    pub acceleration: PIDKValues,
154}
155impl PositionDerivativeDependentPIDKValues {
156    pub const fn new(position: PIDKValues, velocity: PIDKValues, acceleration: PIDKValues) -> Self {
158        Self {
159            position: position,
160            velocity: velocity,
161            acceleration: acceleration,
162        }
163    }
164    #[inline]
166    pub fn get_k_values(&self, position_derivative: PositionDerivative) -> PIDKValues {
167        match position_derivative {
168            PositionDerivative::Position => self.position,
169            PositionDerivative::Velocity => self.velocity,
170            PositionDerivative::Acceleration => self.acceleration,
171        }
172    }
173    #[inline]
176    pub fn evaluate(
177        &self,
178        position_derivative: PositionDerivative,
179        error: f32,
180        error_integral: f32,
181        error_derivative: f32,
182    ) -> f32 {
183        self.get_k_values(position_derivative)
184            .evaluate(error, error_integral, error_derivative)
185    }
186}
187pub type Output<T, E> = Result<Option<Datum<T>>, Error<E>>;
190pub type TimeOutput<E> = Result<Time, Error<E>>;
192pub type NothingOrError<E> = Result<(), Error<E>>;
194pub trait TimeGetter<E: Copy + Debug>: Updatable<E> {
196    fn get(&self) -> TimeOutput<E>;
198}
199pub trait History<T, E: Copy + Debug>: Updatable<E> {
201    fn get(&self, time: Time) -> Option<Datum<T>>;
203}
204pub trait Updatable<E: Copy + Debug> {
206    fn update(&mut self) -> NothingOrError<E>;
209}
210pub trait Getter<G, E: Copy + Debug>: Updatable<E> {
217    fn get(&self) -> Output<G, E>;
219}
220pub struct SettableData<S, E: Copy + Debug> {
222    following: Option<Reference<dyn Getter<S, E>>>,
223    last_request: Option<S>,
224}
225impl<S, E: Copy + Debug> SettableData<S, E> {
226    pub const fn new() -> Self {
228        Self {
229            following: None,
230            last_request: None,
231        }
232    }
233}
234pub trait Settable<S: Clone, E: Copy + Debug>: Updatable<E> {
237    fn impl_set(&mut self, value: S) -> NothingOrError<E>;
241    fn set(&mut self, value: S) -> NothingOrError<E> {
244        self.impl_set(value.clone())?;
245        let data = self.get_settable_data_mut();
246        data.last_request = Some(value);
247        Ok(())
248    }
249    fn get_settable_data_ref(&self) -> &SettableData<S, E>;
254    fn get_settable_data_mut(&mut self) -> &mut SettableData<S, E>;
259    fn follow(&mut self, getter: Reference<dyn Getter<S, E>>) {
262        let data = self.get_settable_data_mut();
263        data.following = Some(getter);
264    }
265    fn stop_following(&mut self) {
267        let data = self.get_settable_data_mut();
268        data.following = None;
269    }
270    fn update_following_data(&mut self) -> NothingOrError<E> {
276        let data = self.get_settable_data_ref();
277        match &data.following {
278            None => {}
279            Some(getter) => {
280                let new_value = getter.borrow().get()?;
281                match new_value {
282                    None => {
283                        return Ok(());
284                    }
285                    Some(datum) => {
286                        self.set(datum.value)?;
287                    }
288                }
289            }
290        }
291        Ok(())
292    }
293    fn get_last_request(&self) -> Option<S> {
295        let data = self.get_settable_data_ref();
296        data.last_request.clone()
297    }
298}
299pub struct TimeGetterFromGetter<T: Clone, G: Getter<T, E> + ?Sized, E: Copy + Debug> {
302    elevator: streams::converters::NoneToError<T, G, E>,
303}
304impl<T: Clone, G: Getter<T, E> + ?Sized, E: Copy + Debug> TimeGetterFromGetter<T, G, E> {
305    pub const fn new(stream: Reference<G>) -> Self {
307        Self {
308            elevator: streams::converters::NoneToError::new(stream),
309        }
310    }
311}
312impl<T: Clone, G: Getter<T, E> + ?Sized, E: Copy + Debug> TimeGetter<E>
313    for TimeGetterFromGetter<T, G, E>
314{
315    fn get(&self) -> TimeOutput<E> {
316        let output = self.elevator.get()?;
317        let output = output.expect("`NoneToError` made all `Ok(None)`s into `Err(_)`s, and `?` returned all `Err(_)`s, so we're sure this is now an `Ok(Some(_))`.");
318        return Ok(output.time);
319    }
320}
321impl<T: Clone, G: Getter<T, E> + ?Sized, E: Copy + Debug> Updatable<E>
322    for TimeGetterFromGetter<T, G, E>
323{
324    fn update(&mut self) -> NothingOrError<E> {
325        Ok(())
326    }
327}
328pub struct GetterFromHistory<'a, G, TG: TimeGetter<E>, E: Copy + Debug> {
332    history: &'a mut dyn History<G, E>,
333    time_getter: Reference<TG>,
334    time_delta: Time,
335}
336impl<'a, G, TG: TimeGetter<E>, E: Copy + Debug> GetterFromHistory<'a, G, TG, E> {
337    pub fn new_no_delta(history: &'a mut impl History<G, E>, time_getter: Reference<TG>) -> Self {
340        Self {
341            history: history,
342            time_getter: time_getter,
343            time_delta: Time::default(),
344        }
345    }
346    pub fn new_start_at_zero(
349        history: &'a mut impl History<G, E>,
350        time_getter: Reference<TG>,
351    ) -> Result<Self, Error<E>> {
352        let time_delta = -time_getter.borrow().get()?;
353        Ok(Self {
354            history: history,
355            time_getter: time_getter,
356            time_delta: time_delta,
357        })
358    }
359    pub fn new_custom_start(
362        history: &'a mut impl History<G, E>,
363        time_getter: Reference<TG>,
364        start: Time,
365    ) -> Result<Self, Error<E>> {
366        let time_delta = start - time_getter.borrow().get()?;
367        Ok(Self {
368            history: history,
369            time_getter: time_getter,
370            time_delta: time_delta,
371        })
372    }
373    pub fn new_custom_delta(
375        history: &'a mut impl History<G, E>,
376        time_getter: Reference<TG>,
377        time_delta: Time,
378    ) -> Self {
379        Self {
380            history: history,
381            time_getter: time_getter,
382            time_delta: time_delta,
383        }
384    }
385    pub fn set_delta(&mut self, time_delta: Time) {
387        self.time_delta = time_delta;
388    }
389    pub fn set_time(&mut self, time: Time) -> NothingOrError<E> {
392        let time_delta = time - self.time_getter.borrow().get()?;
393        self.time_delta = time_delta;
394        Ok(())
395    }
396}
397impl<G, TG: TimeGetter<E>, E: Copy + Debug> Updatable<E> for GetterFromHistory<'_, G, TG, E> {
398    fn update(&mut self) -> NothingOrError<E> {
399        self.history.update()?;
400        self.time_getter.borrow_mut().update()?;
401        Ok(())
402    }
403}
404impl<G, TG: TimeGetter<E>, E: Copy + Debug> Getter<G, E> for GetterFromHistory<'_, G, TG, E> {
405    fn get(&self) -> Output<G, E> {
406        let time = self.time_getter.borrow().get()?;
407        Ok(match self.history.get(time + self.time_delta) {
408            Some(datum) => Some(Datum::new(time, datum.value)),
409            None => None,
410        })
411    }
412}
413pub struct ConstantGetter<T: Clone, TG: TimeGetter<E> + ?Sized, E: Copy + Debug> {
415    settable_data: SettableData<T, E>,
416    time_getter: Reference<TG>,
417    value: T,
418}
419impl<T: Clone, TG: TimeGetter<E> + ?Sized, E: Copy + Debug> ConstantGetter<T, TG, E> {
420    pub const fn new(time_getter: Reference<TG>, value: T) -> Self {
422        Self {
423            settable_data: SettableData::new(),
424            time_getter: time_getter,
425            value: value,
426        }
427    }
428}
429impl<T: Clone, TG: TimeGetter<E> + ?Sized, E: Copy + Debug> Getter<T, E>
430    for ConstantGetter<T, TG, E>
431{
432    fn get(&self) -> Output<T, E> {
433        let time = self.time_getter.borrow().get()?;
434        Ok(Some(Datum::new(time, self.value.clone())))
435    }
436}
437impl<T: Clone, TG: TimeGetter<E> + ?Sized, E: Copy + Debug> Settable<T, E>
438    for ConstantGetter<T, TG, E>
439{
440    fn get_settable_data_ref(&self) -> &SettableData<T, E> {
441        &self.settable_data
442    }
443    fn get_settable_data_mut(&mut self) -> &mut SettableData<T, E> {
444        &mut self.settable_data
445    }
446    fn impl_set(&mut self, value: T) -> NothingOrError<E> {
447        self.value = value;
448        Ok(())
449    }
450}
451impl<T: Clone, TG: TimeGetter<E> + ?Sized, E: Copy + Debug> Updatable<E>
452    for ConstantGetter<T, TG, E>
453{
454    fn update(&mut self) -> NothingOrError<E> {
456        self.update_following_data()?;
457        Ok(())
458    }
459}
460pub struct NoneGetter;
462impl NoneGetter {
463    pub const fn new() -> Self {
466        Self
467    }
468}
469impl<T, E: Copy + Debug> Getter<T, E> for NoneGetter {
470    fn get(&self) -> Output<T, E> {
471        Ok(None)
472    }
473}
474impl<E: Copy + Debug> Updatable<E> for NoneGetter {
475    fn update(&mut self) -> NothingOrError<E> {
476        Ok(())
477    }
478}
479impl<E: Copy + Debug> TimeGetter<E> for Time {
480    fn get(&self) -> TimeOutput<E> {
481        Ok(*self)
482    }
483}
484impl<E: Copy + Debug> Updatable<E> for Time {
485    fn update(&mut self) -> NothingOrError<E> {
486        Ok(())
487    }
488}
489#[cfg(feature = "devices")]
491pub struct Terminal<'a, E: Copy + Debug> {
492    settable_data_state: SettableData<Datum<State>, E>,
493    settable_data_command: SettableData<Datum<Command>, E>,
494    other: Option<&'a RefCell<Terminal<'a, E>>>,
495}
496#[cfg(feature = "devices")]
497impl<E: Copy + Debug> Terminal<'_, E> {
498    pub const fn new_raw() -> Self {
501        Self {
502            settable_data_state: SettableData::new(),
503            settable_data_command: SettableData::new(),
504            other: None,
505        }
506    }
507    pub const fn new() -> RefCell<Self> {
511        RefCell::new(Self::new_raw())
512    }
513    pub fn disconnect(&mut self) {
516        match self.other {
517            Some(other) => {
518                let mut other = other.borrow_mut();
519                other.other = None;
520                self.other = None;
521            }
522            None => (),
523        }
524    }
525}
526#[cfg(feature = "devices")]
527impl<E: Copy + Debug> Settable<Datum<State>, E> for Terminal<'_, E> {
528    fn get_settable_data_ref(&self) -> &SettableData<Datum<State>, E> {
529        &self.settable_data_state
530    }
531    fn get_settable_data_mut(&mut self) -> &mut SettableData<Datum<State>, E> {
532        &mut self.settable_data_state
533    }
534    fn impl_set(&mut self, _state: Datum<State>) -> NothingOrError<E> {
536        Ok(())
537    }
538}
539#[cfg(feature = "devices")]
540impl<E: Copy + Debug> Settable<Datum<Command>, E> for Terminal<'_, E> {
541    fn get_settable_data_ref(&self) -> &SettableData<Datum<Command>, E> {
542        &self.settable_data_command
543    }
544    fn get_settable_data_mut(&mut self) -> &mut SettableData<Datum<Command>, E> {
545        &mut self.settable_data_command
546    }
547    fn impl_set(&mut self, _command: Datum<Command>) -> NothingOrError<E> {
548        Ok(())
549    }
550}
551#[cfg(feature = "devices")]
552impl<E: Copy + Debug> Getter<State, E> for Terminal<'_, E> {
553    fn get(&self) -> Output<State, E> {
554        let mut addends: [core::mem::MaybeUninit<Datum<State>>; 2] =
555            [core::mem::MaybeUninit::uninit(); 2];
556        let mut addend_count = 0usize;
557        match self.get_last_request() {
558            Some(state) => {
559                addends[0].write(state);
560                addend_count += 1;
561            }
562            None => (),
563        }
564        match self.other {
565            Some(other) => match other.borrow().get_last_request() {
566                Some(state) => {
567                    addends[addend_count].write(state);
568                    addend_count += 1;
569                }
570                None => (),
571            },
572            None => (),
573        }
574        unsafe {
575            match addend_count {
576                0 => return Ok(None),
577                1 => return Ok(Some(addends[0].assume_init())),
578                2 => {
579                    return Ok(Some(
580                        (addends[0].assume_init() + addends[1].assume_init()) / 2.0,
581                    ))
582                }
583                _ => unimplemented!(),
584            }
585        }
586    }
587}
588#[cfg(feature = "devices")]
589impl<E: Copy + Debug> Getter<Command, E> for Terminal<'_, E> {
590    fn get(&self) -> Output<Command, E> {
591        let mut maybe_command: Option<Datum<Command>> = None;
592        match self.get_last_request() {
593            Some(command) => {
594                maybe_command = Some(command);
595            }
596            None => {}
597        }
598        match self.other {
599            Some(other) => {
600                match <Terminal<'_, E> as Settable<Datum<Command>, E>>::get_last_request(
601                    &other.borrow(),
602                ) {
603                    Some(gotten_command) => match maybe_command {
604                        Some(command_some) => {
605                            if gotten_command.time > command_some.time {
606                                maybe_command = Some(gotten_command);
607                            }
608                        }
609                        None => {
610                            maybe_command = Some(gotten_command);
611                        }
612                    },
613                    None => (),
614                }
615            }
616            None => (),
617        }
618        Ok(maybe_command)
619    }
620}
621#[cfg(feature = "devices")]
622impl<E: Copy + Debug> Getter<TerminalData, E> for Terminal<'_, E> {
623    fn get(&self) -> Output<TerminalData, E> {
624        let command = self.get().expect("Terminal get cannot return Err");
625        let state = self.get().expect("Terminal get cannot return Err");
626        let (mut time, command) = match command {
627            Some(datum_command) => (Some(datum_command.time), Some(datum_command.value)),
628            None => (None, None),
629        };
630        let state = match state {
631            Some(datum_state) => {
632                time = Some(datum_state.time);
633                Some(datum_state.value)
634            }
635            None => None,
636        };
637        Ok(match time {
638            Some(time) => Some(Datum::new(
639                time,
640                TerminalData {
641                    time: time,
642                    command: command,
643                    state: state,
644                },
645            )),
646            None => None,
647        })
648    }
649}
650#[cfg(feature = "devices")]
651impl<E: Copy + Debug> Updatable<E> for Terminal<'_, E> {
652    fn update(&mut self) -> NothingOrError<E> {
653        <Terminal<'_, E> as Settable<Datum<Command>, E>>::update_following_data(self)?;
654        <Terminal<'_, E> as Settable<Datum<State>, E>>::update_following_data(self)?;
655        Ok(())
656    }
657}
658#[cfg(feature = "devices")]
663pub fn connect<'a, E: Copy + Debug>(
664    term1: &'a RefCell<Terminal<'a, E>>,
665    term2: &'a RefCell<Terminal<'a, E>>,
666) {
667    let mut term1_borrow = term1.borrow_mut();
668    let mut term2_borrow = term2.borrow_mut();
669    term1_borrow.disconnect();
670    term2_borrow.disconnect();
671    term1_borrow.other = Some(term2);
672    term2_borrow.other = Some(term1);
673}
674#[cfg(feature = "devices")]
676#[derive(Clone, Copy, Debug, PartialEq)]
677pub struct TerminalData {
678    pub time: Time,
680    pub command: Option<Command>,
682    pub state: Option<State>,
684}
685#[cfg(feature = "devices")]
686impl TryFrom<TerminalData> for Datum<Command> {
687    type Error = ();
688    fn try_from(value: TerminalData) -> Result<Datum<Command>, ()> {
689        match value.command {
690            Some(command) => Ok(Datum::new(value.time, command)),
691            None => Err(()),
692        }
693    }
694}
695#[cfg(feature = "devices")]
696impl TryFrom<TerminalData> for Datum<State> {
697    type Error = ();
698    fn try_from(value: TerminalData) -> Result<Datum<State>, ()> {
699        match value.state {
700            Some(state) => Ok(Datum::new(value.time, state)),
701            None => Err(()),
702        }
703    }
704}
705#[cfg(feature = "devices")]
707pub trait Device<E: Copy + Debug>: Updatable<E> {
708    fn update_terminals(&mut self) -> NothingOrError<E>;
711}
712pub fn latest<T>(dat1: Datum<T>, dat2: Datum<T>) -> Datum<T> {
714    if dat1.time >= dat2.time {
715        dat1
716    } else {
717        dat2
718    }
719}