|
1 | 1 | use std::{ |
| 2 | + any::TypeId, |
2 | 3 | error::Error, |
| 4 | + fmt, |
3 | 5 | marker::PhantomData, |
4 | 6 | ops::{ |
5 | 7 | Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign, |
6 | 8 | }, |
7 | 9 | }; |
8 | 10 |
|
9 | | -use crate::utils::traits::Time; |
| 11 | +use crate::{Continuous, Discrete, utils::traits::Time}; |
10 | 12 | extern crate nalgebra as na; |
11 | 13 | use na::DMatrix; |
12 | 14 |
|
@@ -593,6 +595,27 @@ macro_rules! impl_scalar_math_operator_ss { |
593 | 595 |
|
594 | 596 | impl_scalar_math_operator_ss!([(Add, add), (Sub, sub), (Mul, mul), (Div, div)]); |
595 | 597 |
|
| 598 | +impl<U: Time + 'static> fmt::Display for Ss<U> { |
| 599 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 600 | + write!( |
| 601 | + f, |
| 602 | + "\nA = {} B = {} C = {} D = {}", |
| 603 | + self.a(), |
| 604 | + self.b(), |
| 605 | + self.c(), |
| 606 | + self.d() |
| 607 | + )?; |
| 608 | + let time_domain = if TypeId::of::<U>() == TypeId::of::<Continuous>() { |
| 609 | + "Continuous" |
| 610 | + } else if TypeId::of::<U>() == TypeId::of::<Discrete>() { |
| 611 | + "Discrete" |
| 612 | + } else { |
| 613 | + "Unknown" |
| 614 | + }; |
| 615 | + write!(f, "{}-time state-space model\n\n", time_domain) |
| 616 | + } |
| 617 | +} |
| 618 | + |
596 | 619 | #[cfg(test)] |
597 | 620 | mod tests { |
598 | 621 | use core::f64; |
@@ -857,4 +880,18 @@ mod tests { |
857 | 880 | assert_abs_diff_eq!(tf_fb, ss_fb, epsilon = 1e-1); |
858 | 881 | } |
859 | 882 | } |
| 883 | + |
| 884 | + #[test] |
| 885 | + fn ss_display() { |
| 886 | + let sys = (1.0 / Tf::s()).to_ss().unwrap(); |
| 887 | + println!("1: {}", sys); |
| 888 | + |
| 889 | + let sys = Ss::<Discrete>::new_from_scalar(2.0); |
| 890 | + println!("2: {}", sys); |
| 891 | + |
| 892 | + let sys = ((1.0 + Tf::s()) / ((Tf::s() - 1.0) * Tf::s()).powi(2)) |
| 893 | + .to_ss() |
| 894 | + .unwrap(); |
| 895 | + println!("3: {}after", sys); |
| 896 | + } |
860 | 897 | } |
0 commit comments