use core::marker::PhantomData;
use core::{
cell::RefCell,
fmt::Debug,
ops::{Deref, DerefMut},
};
use arrayvec::ArrayVec;
use statime_base::{Clock, ClockId, TAI};
use crate::KalmanControllerState;
use crate::filter::BoundType;
pub trait KalmanStorage<C: Clock<TAI>>: KalmanStorageInternal<C> {}
pub trait KalmanStorageInternal<C: Clock<TAI>>: KalmanStorageBase {
type SteeredClockStorage: SteeredClockStorage<C>;
type StateMutex: StateMutex<Self, C>;
}
pub trait KalmanStorageBase: Debug + Clone {
type MatrixStorage: MatrixStorage;
type ExternalClockStorage: ExternalClockStorage;
type InternalClockStorage: InternalClockStorage;
type EstimatorLinkStorage: EstimatorLinkStorage;
type FilterLinkStorage: FilterLinkStorage;
type BoundStorage: BoundStorage;
}
#[cfg(feature = "std")]
pub struct StdKalmanStorage<C>(PhantomData<C>);
#[cfg(feature = "std")]
impl<C> Debug for StdKalmanStorage<C> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("StdKalmanStorage").finish()
}
}
#[cfg(feature = "std")]
impl<C> Clone for StdKalmanStorage<C> {
fn clone(&self) -> Self {
Self(PhantomData)
}
}
#[cfg(feature = "std")]
impl<C> KalmanStorageBase for StdKalmanStorage<C> {
type MatrixStorage = std::boxed::Box<[f64]>;
type ExternalClockStorage = std::vec::Vec<ClockId>;
type InternalClockStorage = std::vec::Vec<crate::estimator::ClockInfo>;
type EstimatorLinkStorage = std::vec::Vec<crate::estimator::LinkInfo>;
type FilterLinkStorage = std::vec::Vec<crate::filter::LinkInfo>;
type BoundStorage = std::vec::Vec<(f64, crate::filter::BoundType)>;
}
#[cfg(feature = "std")]
impl<C: Clock<TAI>> KalmanStorageInternal<C> for StdKalmanStorage<C> {
type SteeredClockStorage = std::vec::Vec<crate::ClockInfo<C>>;
type StateMutex = std::sync::RwLock<crate::KalmanControllerState<StdKalmanStorage<C>, C>>;
}
#[cfg(feature = "std")]
impl<C: Clock<TAI>> KalmanStorage<C> for StdKalmanStorage<C> {}
pub struct NoAllocKalmanStorage<C, const N: usize>(PhantomData<[C; N]>);
impl<C, const N: usize> Debug for NoAllocKalmanStorage<C, N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("NoAllocKalmanStorage").finish()
}
}
impl<C, const N: usize> Clone for NoAllocKalmanStorage<C, N> {
fn clone(&self) -> Self {
Self(PhantomData)
}
}
impl<C, const N: usize> KalmanStorageBase for NoAllocKalmanStorage<C, N> {
type MatrixStorage = [f64; N];
type ExternalClockStorage = ArrayVec<ClockId, N>;
type InternalClockStorage = ArrayVec<crate::estimator::ClockInfo, N>;
type EstimatorLinkStorage = ArrayVec<crate::estimator::LinkInfo, N>;
type FilterLinkStorage = ArrayVec<crate::filter::LinkInfo, N>;
type BoundStorage = ArrayVec<(f64, crate::filter::BoundType), N>;
}
impl<C: Clock<TAI>, const N: usize> KalmanStorageInternal<C> for NoAllocKalmanStorage<C, N> {
type SteeredClockStorage = ArrayVec<crate::ClockInfo<C>, N>;
type StateMutex = RefCell<KalmanControllerState<NoAllocKalmanStorage<C, N>, C>>;
}
impl<C: Clock<TAI>, const N: usize> KalmanStorage<C> for NoAllocKalmanStorage<C, N> {}
pub trait MatrixStorage: AsRef<[f64]> + AsMut<[f64]> + Clone + Debug {
fn new(len: usize, data: impl FnMut(usize) -> f64) -> Self;
}
#[cfg(feature = "std")]
impl MatrixStorage for std::boxed::Box<[f64]> {
fn new(len: usize, data: impl FnMut(usize) -> f64) -> Self {
(0..len).map(data).collect()
}
}
impl<const N: usize> MatrixStorage for [f64; N] {
fn new(len: usize, mut data: impl FnMut(usize) -> f64) -> Self {
assert!(len <= N);
core::array::from_fn(|index| if index < len { data(index) } else { 0.0 })
}
}
pub trait ExternalClockStorage: Deref<Target = [ClockId]> + DerefMut + Clone + Debug {
fn new() -> Self;
fn push(&mut self, id: ClockId);
fn remove(&mut self, index: usize) -> ClockId;
}
#[cfg(feature = "std")]
impl ExternalClockStorage for std::vec::Vec<ClockId> {
fn new() -> Self {
std::vec![]
}
fn push(&mut self, id: ClockId) {
self.push(id);
}
fn remove(&mut self, index: usize) -> ClockId {
self.remove(index)
}
}
impl<const N: usize> ExternalClockStorage for ArrayVec<ClockId, N> {
fn new() -> Self {
ArrayVec::new()
}
fn push(&mut self, id: ClockId) {
self.push(id);
}
fn remove(&mut self, index: usize) -> ClockId {
self.remove(index)
}
}
pub trait InternalClockStorage:
Deref<Target = [crate::estimator::ClockInfo]> + DerefMut + Clone + Debug
{
fn new() -> Self;
fn push(&mut self, info: crate::estimator::ClockInfo);
fn remove(&mut self, index: usize) -> crate::estimator::ClockInfo;
}
#[cfg(feature = "std")]
impl InternalClockStorage for std::vec::Vec<crate::estimator::ClockInfo> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::estimator::ClockInfo) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::estimator::ClockInfo {
self.remove(index)
}
}
impl<const N: usize> InternalClockStorage for ArrayVec<crate::estimator::ClockInfo, N> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::estimator::ClockInfo) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::estimator::ClockInfo {
self.remove(index)
}
}
pub trait EstimatorLinkStorage:
Deref<Target = [crate::estimator::LinkInfo]> + DerefMut + Clone + Debug
{
fn new() -> Self;
fn push(&mut self, info: crate::estimator::LinkInfo);
fn remove(&mut self, index: usize) -> crate::estimator::LinkInfo;
}
#[cfg(feature = "std")]
impl EstimatorLinkStorage for std::vec::Vec<crate::estimator::LinkInfo> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::estimator::LinkInfo) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::estimator::LinkInfo {
self.remove(index)
}
}
impl<const N: usize> EstimatorLinkStorage for ArrayVec<crate::estimator::LinkInfo, N> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::estimator::LinkInfo) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::estimator::LinkInfo {
self.remove(index)
}
}
pub trait FilterLinkStorage:
Deref<Target = [crate::filter::LinkInfo]> + DerefMut + Clone + Debug
{
fn new() -> Self;
fn push(&mut self, info: crate::filter::LinkInfo);
fn remove(&mut self, index: usize) -> crate::filter::LinkInfo;
}
#[cfg(feature = "std")]
impl FilterLinkStorage for std::vec::Vec<crate::filter::LinkInfo> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::filter::LinkInfo) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::filter::LinkInfo {
self.remove(index)
}
}
impl<const N: usize> FilterLinkStorage for ArrayVec<crate::filter::LinkInfo, N> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::filter::LinkInfo) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::filter::LinkInfo {
self.remove(index)
}
}
pub trait BoundStorage:
Deref<Target = [(f64, crate::filter::BoundType)]>
+ DerefMut
+ FromIterator<(f64, crate::filter::BoundType)>
{
}
#[cfg(feature = "std")]
impl BoundStorage for std::vec::Vec<(f64, BoundType)> {}
impl<const N: usize> BoundStorage for ArrayVec<(f64, BoundType), N> {}
pub trait SteeredClockStorage<C>: Deref<Target = [crate::ClockInfo<C>]> + DerefMut {
fn new() -> Self;
fn push(&mut self, info: crate::ClockInfo<C>);
fn remove(&mut self, index: usize) -> crate::ClockInfo<C>;
}
#[cfg(feature = "std")]
impl<C> SteeredClockStorage<C> for std::vec::Vec<crate::ClockInfo<C>> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::ClockInfo<C>) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::ClockInfo<C> {
self.remove(index)
}
}
impl<C, const N: usize> SteeredClockStorage<C> for ArrayVec<crate::ClockInfo<C>, N> {
fn new() -> Self {
Self::new()
}
fn push(&mut self, info: crate::ClockInfo<C>) {
self.push(info);
}
fn remove(&mut self, index: usize) -> crate::ClockInfo<C> {
self.remove(index)
}
}
pub trait StateMutex<Storage: KalmanStorageInternal<C>, C: Clock<TAI>> {
fn new(state: KalmanControllerState<Storage, C>) -> Self;
fn with_ref<R, F: FnOnce(&KalmanControllerState<Storage, C>) -> R>(&self, f: F) -> R;
fn with_mut<R, F: FnOnce(&mut KalmanControllerState<Storage, C>) -> R>(&self, f: F) -> R;
}
#[cfg(feature = "std")]
impl<Storage: KalmanStorageInternal<C>, C: Clock<TAI>> StateMutex<Storage, C>
for std::sync::RwLock<KalmanControllerState<Storage, C>>
{
fn new(state: KalmanControllerState<Storage, C>) -> Self {
std::sync::RwLock::new(state)
}
fn with_ref<R, F: FnOnce(&KalmanControllerState<Storage, C>) -> R>(&self, f: F) -> R {
f(&self.read().unwrap())
}
fn with_mut<R, F: FnOnce(&mut KalmanControllerState<Storage, C>) -> R>(&self, f: F) -> R {
f(&mut self.write().unwrap())
}
}
impl<Storage: KalmanStorageInternal<C>, C: Clock<TAI>> StateMutex<Storage, C>
for RefCell<KalmanControllerState<Storage, C>>
{
fn new(state: KalmanControllerState<Storage, C>) -> Self {
RefCell::new(state)
}
fn with_ref<R, F: FnOnce(&KalmanControllerState<Storage, C>) -> R>(&self, f: F) -> R {
f(&self.borrow())
}
fn with_mut<R, F: FnOnce(&mut KalmanControllerState<Storage, C>) -> R>(&self, f: F) -> R {
f(&mut self.borrow_mut())
}
}