step_for_discrete_ss

Function step_for_discrete_ss 

Source
pub fn step_for_discrete_ss(
    model: &(impl StateSpaceModel + Discrete),
    duration: f64,
) -> (DMatrix<f64>, DMatrix<f64>, DMatrix<f64>)
Expand description

Generates the step response of a discrete state-space model for a given duration.

§Arguments

  • model - A reference to an object that implements the StateSpaceModel and Discrete traits.
  • duration - The duration for which the step response is to be generated.

§Returns

A tuple containing:

  • response - A matrix containing the output sequence of the step response.
  • input - A matrix containing the input sequence (step input).
  • states - A matrix containing the state sequence during the step response.
Examples found in repository?
examples/step_response.rs (lines 116-121)
109fn main() -> Result<(), Box<dyn std::error::Error>> {
110    let sampling_dt = 0.05;
111    let params = dc_motor::Parameters::default();
112    let model = Rc::new(dc_motor::build_model(params, sampling_dt));
113
114    model.poles();
115
116    let (step_response, step, _) = simulator::step_for_discrete_ss(
117        <Rc<model::DiscreteStateSpaceModel> as Borrow<model::DiscreteStateSpaceModel>>::borrow(
118            &model,
119        ),
120        10.0,
121    );
122
123    // Create a folder for results
124    fs::create_dir("img").unwrap_or_else(|_| {
125        println!("The folder img already exists, no need to create it.");
126    });
127
128    // Draw the step response
129    {
130        let root = BitMapBackend::new("img/step_response.png", (800, 600)).into_drawing_area();
131        root.fill(&WHITE)?;
132
133        let max_y = step_response
134            .iter()
135            .cloned()
136            .fold(f64::NEG_INFINITY, f64::max);
137        let min_y = step_response.iter().cloned().fold(f64::INFINITY, f64::min);
138        let mut chart = ChartBuilder::on(&root)
139            .caption("System Output Y", ("sans-serif", 20))
140            .margin(10)
141            .x_label_area_size(30)
142            .y_label_area_size(40)
143            .build_cartesian_2d(0..step_response.len() as i32, min_y..max_y)?;
144
145        chart.configure_mesh().draw()?;
146
147        // Plot input
148        let series_input: Vec<(i32, f64)> = step
149            .row(0)
150            .iter()
151            .enumerate()
152            .map(|(i, &val)| (i as i32, val as f64))
153            .collect();
154
155        chart
156            .draw_series(LineSeries::new(series_input, &Palette99::pick(0)))?
157            .label(format!("Output {}", 0))
158            .legend(move |(x, y)| PathElement::new([(x, y), (x + 20, y)], &Palette99::pick(0)));
159
160        // Plot system response
161        let series_y: Vec<(i32, f64)> = step_response
162            .iter()
163            .enumerate()
164            .map(|(i, &val)| (i as i32, val as f64))
165            .collect();
166
167        chart.draw_series(LineSeries::new(series_y, &Palette99::pick(1)))?;
168
169        chart
170            .configure_series_labels()
171            .background_style(&WHITE)
172            .border_style(&BLACK)
173            .draw()?;
174    }
175
176    Ok(())
177}