#[cfg(feature = "windloads")]
pub mod windloads;
#[cfg(feature = "fem")]
pub mod fem;
#[cfg(feature = "mount-ctrl")]
pub mod mount;
#[cfg(feature = "m1-ctrl")]
pub mod m1;
#[cfg(feature = "apache-arrow")]
pub mod arrow_client;
#[cfg(feature = "fsm")]
pub mod fsm;
#[cfg(feature = "asm")]
pub mod asm;
#[cfg(feature = "crseo")]
pub mod ceo;
#[cfg(feature = "lom")]
pub mod lom;
#[cfg(feature = "dta")]
pub mod dta;
pub mod gmt_state;
#[cfg(feature = "ceo")]
mod dome_seeing;
use crate::{
io::{Data, Read, Write},
UniqueIdentifier, Update,
};
use linya::{Bar, Progress};
use std::{
any::type_name,
fmt::Display,
marker::PhantomData,
mem::take,
ops::{Add, Mul, Sub, SubAssign},
sync::{Arc, Mutex},
};
mod signals;
#[doc(inline)]
pub use signals::{OneSignal, Signal, Signals};
#[derive(Debug)]
pub(crate) struct ProgressBar {
progress: Arc<Mutex<Progress>>,
bar: Bar,
}
pub struct Timer {
tick: usize,
progress_bar: Option<ProgressBar>,
}
impl Timer {
pub fn new(duration: usize) -> Self {
Self {
tick: 1 + duration,
progress_bar: None,
}
}
pub fn progress(self) -> Self {
let mut progress = Progress::new();
let bar: Bar = progress.bar(self.tick, "Timer:");
Self {
progress_bar: Some(ProgressBar {
progress: Arc::new(Mutex::new(progress)),
bar,
}),
..self
}
}
pub fn progress_with(self, progress: Arc<Mutex<Progress>>) -> Self {
let bar: Bar = progress.lock().unwrap().bar(self.tick, "Timer:");
Self {
progress_bar: Some(ProgressBar { progress, bar }),
..self
}
}
}
impl Update for Timer {
fn update(&mut self) {
if let Some(pb) = self.progress_bar.as_mut() {
pb.progress.lock().unwrap().inc_and_draw(&pb.bar, 1)
}
self.tick -= 1;
}
}
pub enum Tick {}
pub type Void = ();
impl UniqueIdentifier for Tick {
type Data = Void;
}
impl Write<Tick> for Timer {
fn write(&mut self) -> Option<Arc<Data<Tick>>> {
if self.tick > 0 {
Some(Arc::new(Data::new(())))
} else {
None
}
}
}
pub(crate) trait TimerMarker {}
impl<T: TimerMarker> Read<Tick> for T {
fn read(&mut self, _: Arc<Data<Tick>>) {}
}
#[derive(Debug)]
pub struct Logging<T> {
data: Vec<T>,
n_sample: usize,
n_entry: usize,
}
impl<T> std::ops::Deref for Logging<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T> Default for Logging<T> {
fn default() -> Self {
Self {
n_entry: 1,
data: Vec::new(),
n_sample: 0,
}
}
}
impl<T> Logging<T> {
pub fn n_entry(self, n_entry: usize) -> Self {
Self { n_entry, ..self }
}
pub fn capacity(self, capacity: usize) -> Self {
Self {
data: Vec::with_capacity(capacity),
..self
}
}
pub fn len(&self) -> usize {
self.n_sample / self.n_entry
}
pub fn n_data(&self) -> usize {
self.data.len() / self.len()
}
pub fn is_empty(&self) -> bool {
self.n_sample == 0
}
pub fn chunks(&self) -> impl Iterator<Item = &[T]> {
self.data.chunks(self.n_data())
}
}
impl<T> Display for Logging<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(
f,
"Logging: ({}x{})={}",
self.n_data(),
self.len(),
self.data.len()
)
}
}
impl<T> Update for Logging<T> {}
impl<T: Clone, U: UniqueIdentifier<Data = Vec<T>>> Read<U> for Logging<T> {
fn read(&mut self, data: Arc<Data<U>>) {
log::debug!("receive {} input: {:}", type_name::<U>(), data.len(),);
self.data.extend((**data).clone());
self.n_sample += 1;
}
}
#[derive(Debug)]
pub struct Sampler<T, U: UniqueIdentifier<Data = T>, V: UniqueIdentifier<Data = T> = U> {
input: Arc<Data<U>>,
output: PhantomData<V>,
}
impl<T, U: UniqueIdentifier<Data = T>, V: UniqueIdentifier<Data = T>> Sampler<T, U, V> {
pub fn new(init: T) -> Self {
Self {
input: Arc::new(Data::new(init)),
output: PhantomData,
}
}
}
impl<T: Default, U: UniqueIdentifier<Data = T>, V: UniqueIdentifier<Data = T>> Default
for Sampler<T, U, V>
{
fn default() -> Self {
Self {
input: Arc::new(Data::new(T::default())),
output: PhantomData,
}
}
}
impl<T, U: UniqueIdentifier<Data = T>, V: UniqueIdentifier<Data = T>> Update for Sampler<T, U, V> {}
impl<T, U: UniqueIdentifier<Data = T>, V: UniqueIdentifier<Data = T>> Read<U> for Sampler<T, U, V> {
fn read(&mut self, data: Arc<Data<U>>) {
self.input = data;
}
}
impl<T: Clone, U: UniqueIdentifier<Data = T>, V: UniqueIdentifier<Data = T>> Write<V>
for Sampler<T, U, V>
{
fn write(&mut self) -> Option<Arc<Data<V>>> {
Some(Arc::new(Data::new((**self.input).clone())))
}
}
pub struct Concat<T>(Vec<T>);
impl<T: Default> Default for Concat<T> {
fn default() -> Self {
Self(Vec::new())
}
}
impl<T> Update for Concat<T> {}
impl<T: Clone + Default, U: UniqueIdentifier<Data = T>> Read<U> for Concat<T> {
fn read(&mut self, data: Arc<Data<U>>) {
self.0.push((*data).clone());
}
}
impl<T: Clone, U: UniqueIdentifier<Data = Vec<T>>> Write<U> for Concat<T> {
fn write(&mut self) -> Option<Arc<Data<U>>> {
Some(Arc::new(Data::new(take(&mut self.0))))
}
}
#[derive(Default)]
pub struct Integrator<U: UniqueIdentifier> {
gain: U::Data,
mem: U::Data,
zero: U::Data,
uid: PhantomData<U>,
}
impl<T, U> Integrator<U>
where
T: Default + Clone,
U: UniqueIdentifier<Data = Vec<T>>,
{
pub fn new(n_data: usize) -> Self {
Self {
gain: vec![Default::default(); n_data],
mem: vec![Default::default(); n_data],
zero: vec![Default::default(); n_data],
uid: PhantomData,
}
}
pub fn gain(self, gain: T) -> Self {
Self {
gain: vec![gain; self.mem.len()],
..self
}
}
pub fn gain_vector(self, gain: Vec<T>) -> Self {
assert_eq!(
gain.len(),
self.mem.len(),
"gain vector length error: expected {} found {}",
gain.len(),
self.mem.len()
);
Self { gain, ..self }
}
pub fn zero(self, zero: Vec<T>) -> Self {
Self { zero, ..self }
}
}
impl<T, U> Update for Integrator<U> where U: UniqueIdentifier<Data = Vec<T>> {}
impl<T, U> Read<U> for Integrator<U>
where
T: Copy + Mul<Output = T> + Sub<Output = T> + SubAssign,
U: UniqueIdentifier<Data = Vec<T>>,
{
fn read(&mut self, data: Arc<Data<U>>) {
self.mem
.iter_mut()
.zip(&self.gain)
.zip(&self.zero)
.zip(&**data)
.for_each(|(((x, g), z), u)| *x -= *g * (*u - *z));
}
}
impl<T, V, U> Write<V> for Integrator<U>
where
T: Copy + Add<Output = T>,
V: UniqueIdentifier<Data = Vec<T>>,
U: UniqueIdentifier<Data = Vec<T>>,
{
fn write(&mut self) -> Option<Arc<Data<V>>> {
let y: Vec<T> = self
.mem
.iter()
.zip(&self.zero)
.map(|(m, z)| *m + *z)
.collect();
Some(Arc::new(Data::new(y)))
}
}
pub struct Source<T> {
n: usize,
data: Vec<T>,
}
impl<T> Source<T> {
pub fn new(data: Vec<T>, n: usize) -> Self {
Source { n, data }
}
}
impl<T> Update for Source<T> {}
impl<T, V> Write<V> for Source<T>
where
V: UniqueIdentifier<Data = Vec<T>>,
{
fn write(&mut self) -> Option<Arc<Data<V>>> {
if self.data.is_empty() {
None
} else {
let y: Vec<T> = self.data.drain(..self.n).collect();
Some(Arc::new(Data::new(y)))
}
}
}
pub struct Smooth {
weight: f64,
data: Vec<f64>,
data0: Option<Vec<f64>>,
}
impl Smooth {
pub fn new() -> Self {
Self {
weight: 0f64,
data: Vec::new(),
data0: None,
}
}
}
impl Update for Smooth {}
use uid_derive::UID;
#[derive(UID)]
#[uid(data = "f64")]
pub enum Weight {}
impl Read<Weight> for Smooth {
fn read(&mut self, data: Arc<Data<Weight>>) {
let w: &f64 = &data;
self.weight = *w;
}
}
impl<U: UniqueIdentifier<Data = Vec<f64>>> Read<U> for Smooth {
fn read(&mut self, data: Arc<Data<U>>) {
let u: &[f64] = &data;
self.data = u.to_vec();
if self.data0.is_none() {
self.data0 = Some(self.data.clone());
}
}
}
impl<U: UniqueIdentifier<Data = Vec<f64>>> Write<U> for Smooth {
fn write(&mut self) -> Option<Arc<Data<U>>> {
let y: Vec<_> = self.data.iter().map(|&u| u * self.weight).collect();
Some(Arc::new(Data::new(y)))
}
}
#[cfg(feature = "nalgebra")]
mod gain {
use super::{Arc, Data, Read, UniqueIdentifier, Update, Write};
use nalgebra as na;
pub struct Gain {
u: na::DVector<f64>,
y: na::DVector<f64>,
mat: na::DMatrix<f64>,
}
impl Gain {
pub fn new(mat: na::DMatrix<f64>) -> Self {
Self {
u: na::DVector::zeros(mat.ncols()),
y: na::DVector::zeros(mat.nrows()),
mat,
}
}
}
impl Update for Gain {
fn update(&mut self) {
self.y = &self.mat * &self.u;
}
}
impl<U: UniqueIdentifier<Data = Vec<f64>>> Read<U> for Gain {
fn read(&mut self, data: Arc<Data<U>>) {
self.u = na::DVector::from_row_slice(&data);
}
}
impl<U: UniqueIdentifier<Data = Vec<f64>>> Write<U> for Gain {
fn write(&mut self) -> Option<Arc<Data<U>>> {
Some(Arc::new(Data::new(self.y.as_slice().to_vec())))
}
}
}
#[cfg(feature = "nalgebra")]
pub use gain::Gain;