Controlpp
Loading...
Searching...
No Matches
controlpp::Bode< T > Class Template Reference

Frequency response data. More...

#include <controlpp/Bode.hpp>

Public Member Functions

 Bode ()=default
 
 Bode (const Eigen::Vector< T, Eigen::Dynamic > &freqs_rad, const Eigen::Vector< std::complex< T >, Eigen::Dynamic > &values)
 Constructs a bode from frequencies and complex magnitudes.
 
 Bode (Eigen::Vector< T, Eigen::Dynamic > &&freqs_rad, Eigen::Vector< std::complex< T >, Eigen::Dynamic > &&values)
 
 Bode (const Eigen::Vector< T, Eigen::Dynamic > &freqs_rad, Eigen::Vector< std::complex< T >, Eigen::Dynamic > &&values)
 
 Bode (Eigen::Vector< T, Eigen::Dynamic > &&freqs_rad, const Eigen::Vector< std::complex< T >, Eigen::Dynamic > &values)
 
const Eigen::Vector< T, Eigen::Dynamic > & frequencies () const
 Returns a const-reference to the frequency vector in rad.
 
Eigen::Vector< T, Eigen::Dynamic > & frequencies ()
 Returns a reference to the frequency vector in rad.
 
T & frequency (std::size_t n)
 Returns a reference to the frequency in rad at the index n.
 
const T & frequency (std::size_t n) const
 Returns a reference to the frequency in rad at the index n.
 
void prewarp_tustin (const T &Ts)
 Applies tustin pre-warping to the frequency axis.
 
void unwarp_tustin (const T &Ts)
 Unwarps the pre-warping. Or calculates how system frequencies will shift after tustin discretisation.
 
const Eigen::Vector< std::complex< T >, Eigen::Dynamic > & values () const
 Returns a const-reference to the complex magnitued vector.
 
Eigen::Vector< std::complex< T >, Eigen::Dynamic > & values ()
 Returns a reference to the complex magnitued vector.
 
const std::complex< T > & value (std::size_t n) const
 Returns a reference to the complex magnitue at the n-th position.
 
std::complex< T > & value (std::size_t n)
 Returns a reference to the complex magnitue at the n-th position.
 
size_t size () const
 
bool empty () const
 
std::complex< Tvalue_at (const T &frequency) const
 returns the complex value at the given frequency using interpolation
 
T phase_at (const T &frequency) const
 Returns the phase at the passed frequency.
 
T phase_deg_at (const T &frequency) const
 return the phase at the given frequency in degree
 
T magnitude_at (const T &frequency) const
 Returns the magnitude at the passed frequency.
 
T magnitude_dB_at (const T &frequency) const
 Returns the magnitude at the passed frequency.
 

Detailed Description

template<class T = double>
class controlpp::Bode< T >

Frequency response data.

This class holds frequency response data and can be used to either plot a transfer function or to do data driven design.

It holds frequencies and complplex magnitudes and allows arithmetic calculations like transfer functions do.

Template Parameters
TThe data type of the class. Typically float, double or a custom fixpoint type
See also
Bode Utilities

Constructor & Destructor Documentation

◆ Bode() [1/5]

template<class T = double>
controlpp::Bode< T >::Bode ( )
default

◆ Bode() [2/5]

template<class T = double>
controlpp::Bode< T >::Bode ( const Eigen::Vector< T, Eigen::Dynamic > &  freqs_rad,
const Eigen::Vector< std::complex< T >, Eigen::Dynamic > &  values 
)
inline

Constructs a bode from frequencies and complex magnitudes.

Parameters
freqs_radOrdered (ascending) frequency vector in rad
magsComplex Magnitudes Vector that corresponds to the frequencies

◆ Bode() [3/5]

template<class T = double>
controlpp::Bode< T >::Bode ( Eigen::Vector< T, Eigen::Dynamic > &&  freqs_rad,
Eigen::Vector< std::complex< T >, Eigen::Dynamic > &&  values 
)
inline

◆ Bode() [4/5]

template<class T = double>
controlpp::Bode< T >::Bode ( const Eigen::Vector< T, Eigen::Dynamic > &  freqs_rad,
Eigen::Vector< std::complex< T >, Eigen::Dynamic > &&  values 
)
inline

◆ Bode() [5/5]

template<class T = double>
controlpp::Bode< T >::Bode ( Eigen::Vector< T, Eigen::Dynamic > &&  freqs_rad,
const Eigen::Vector< std::complex< T >, Eigen::Dynamic > &  values 
)
inline

Member Function Documentation

◆ empty()

template<class T = double>
bool controlpp::Bode< T >::empty ( ) const
inline

◆ frequencies() [1/2]

template<class T = double>
Eigen::Vector< T, Eigen::Dynamic > & controlpp::Bode< T >::frequencies ( )
inline

Returns a reference to the frequency vector in rad.

Returns
const-reference to an eigen vector
See also
frequencies_hz(const Bode<T>& bode)

◆ frequencies() [2/2]

template<class T = double>
const Eigen::Vector< T, Eigen::Dynamic > & controlpp::Bode< T >::frequencies ( ) const
inline

Returns a const-reference to the frequency vector in rad.

Returns
const-reference to an eigen vector
See also
frequencies_hz(const Bode<T>& bode)

◆ frequency() [1/2]

template<class T = double>
T & controlpp::Bode< T >::frequency ( std::size_t  n)
inline

Returns a reference to the frequency in rad at the index n.

Parameters
nThe index at which to return the frequency
Returns
reference to the frequency at the n-th position

◆ frequency() [2/2]

template<class T = double>
const T & controlpp::Bode< T >::frequency ( std::size_t  n) const
inline

Returns a reference to the frequency in rad at the index n.

Parameters
nThe index at which to return the frequency
Returns
reference to the frequency at the n-th position

◆ magnitude_at()

template<class T = double>
T controlpp::Bode< T >::magnitude_at ( const T frequency) const
inline

Returns the magnitude at the passed frequency.

Uses linear interpolation

Parameters
frequencyThe frequency (in hz) at which to get the magnitude at
Returns
The interpolated magnitude (in absolute) at the given frequency

◆ magnitude_dB_at()

template<class T = double>
T controlpp::Bode< T >::magnitude_dB_at ( const T frequency) const
inline

Returns the magnitude at the passed frequency.

Uses linear interpolation

Parameters
frequencyThe frequency (in hz) at which to get the magnitude at
Returns
The interpolated magnitude (in absolute) at the given frequency

◆ phase_at()

template<class T = double>
T controlpp::Bode< T >::phase_at ( const T frequency) const
inline

Returns the phase at the passed frequency.

Uses linear interpolation.

Internally uses value_at(const T& frequency).

Parameters
frequencyThe frequency (in rad/s) at which to get the phase at
Returns
The interpolated phase (in rad) at the given frequency
See also
value_at(const T& frequency)

◆ phase_deg_at()

template<class T = double>
T controlpp::Bode< T >::phase_deg_at ( const T frequency) const
inline

return the phase at the given frequency in degree

Uses linear interpolation

Parameters
frequencyThe frequency (in hz) at which to get the phase at
Returns
The interpolated phase (in deg) at the given frequency
See also
phase_at()
value_at()

◆ prewarp_tustin()

template<class T = double>
void controlpp::Bode< T >::prewarp_tustin ( const T Ts)
inline

Applies tustin pre-warping to the frequency axis.

The tustin transformation

\[ s = \frac{2}{T} \frac{z-1}{z+1} \]

warps the frequency axis with

\[ \omega_d = \frac{2}{T_s} \text{atan}\left( \frac{\omega_c T_s}{2} \right). \]

So if you design, for example a notch filter to match a specific resonance in the bode and then use the tustin transformation to get a digital filter, the filter will be at a slightly different frequency then intended.

In order to prevent that and make controller design easy, we can pre-warp the frequency axis of the bode:

\[ \omega_\text{pre} = \frac{2}{T_s} \text{tan}\left( \frac{\omega_\text{target} T_s}{2} \right) \]

The pre-warping will move the resonance in the bode so that if you design notch filter (or any other filter) for that warped frequency it will then match the real system exactly after the tustin discretisation.

A typical workflow for controller design could then look like:

  1. Measure bode
  2. Apply pre-warping to bode
  3. Design a controller for the pre-warped bode features
  4. a) Discretise the controller. b) Unwarp the simulation to see real crossover frequency.
// Read bode
if(bode_err.has_value() == false){
//error handling
}
// pre-warp for controller design
// ------------------------- Start Warped Design ----------------------------
const double Fs = 1000; // sample frequency
const double Ts = 1/Fs;
G.prewarp_tustin(Ts);
// design the controller R here
// display open loop L_warped
Bode L = R * G;
// plot L (tryout my other library plotpp)
// calculate the actual open loop L, transfer Try and sensitivity function Tdy
// ------------------------- End Warped Design ----------------------------
Bode Try = L / (1 + L);
Bode Tdy = 1 / (1 + L);
Frequency response data.
Definition Bode.hpp:43
void unwarp_tustin(const T &Ts)
Unwarps the pre-warping. Or calculates how system frequencies will shift after tustin discretisation.
Definition Bode.hpp:260
const std::complex< T > & value(std::size_t n) const
Returns a reference to the complex magnitue at the n-th position.
Definition Bode.hpp:285
T & frequency(std::size_t n)
Returns a reference to the frequency in rad at the index n.
Definition Bode.hpp:151
Eigen::Vector< T, Eigen::Dynamic > frequencies_hz(const Bode< T > &bode)
Converts and returns the frequency vector in Hz.
Definition Bode.hpp:476
Eigen::Vector< T, Eigen::Dynamic > magnitudes_dB(const Bode< T > &bode)
Creates a vector of magnitudes in dB.
Definition Bode.hpp:555
Eigen::Vector< T, Eigen::Dynamic > phases_deg(const Bode< T > &bode)
Creates a vector of phases in degree.
Definition Bode.hpp:591
tl::expected< Bode< double >, std::variant< EBodeCsvReadError, csvd::ReadError > > read_bode_from_csv(std::istream &stream, const csvd::Settings &csv_settings, EFrequencyInterpretation freq_interp, EMagnitudeInterpretation mag_interp, EPhaseInterpretation phase_interp)
Loads bode data from csv data.
Definition Bode.cpp:61
Parameters
TsThe sample time that also the tustin discretisation is using.
See also
unwarp_tustin

◆ size()

template<class T = double>
size_t controlpp::Bode< T >::size ( ) const
inline

◆ unwarp_tustin()

template<class T = double>
void controlpp::Bode< T >::unwarp_tustin ( const T Ts)
inline

Unwarps the pre-warping. Or calculates how system frequencies will shift after tustin discretisation.

Applies the following function to the frequency axis:

\[ \omega_d = \frac{2}{T_s} \text{atan}\left( \frac{\omega_c T_s}{2} \right). \]

Parameters
TsThe sample time that also the tustin discretisation is using
See also
prewarp_tustin()

◆ value() [1/2]

template<class T = double>
std::complex< T > & controlpp::Bode< T >::value ( std::size_t  n)
inline

Returns a reference to the complex magnitue at the n-th position.

Parameters
nThe n-th position to get from the magnitude vector
Returns
reference to an complex magnitude

◆ value() [2/2]

template<class T = double>
const std::complex< T > & controlpp::Bode< T >::value ( std::size_t  n) const
inline

Returns a reference to the complex magnitue at the n-th position.

Parameters
nThe n-th position to get from the magnitude vector
Returns
reference to an complex magnitude

◆ value_at()

template<class T = double>
std::complex< T > controlpp::Bode< T >::value_at ( const T frequency) const
inline

returns the complex value at the given frequency using interpolation

If the passed frequency is not within the bode plot, data will not be extrapolated. Instead the first or last available value will be returned, depending weather or not the value is below or above the spectrum.

Uses linear interpolation in polar coordinates

Parameters
frequencyThe frequency (in rad/s) at which to read the complex amplitudes.
Returns
Interpolated complex value for the passed frequency value

◆ values() [1/2]

template<class T = double>
Eigen::Vector< std::complex< T >, Eigen::Dynamic > & controlpp::Bode< T >::values ( )
inline

Returns a reference to the complex magnitued vector.

Returns
reference to an complex magnitude vector

◆ values() [2/2]

template<class T = double>
const Eigen::Vector< std::complex< T >, Eigen::Dynamic > & controlpp::Bode< T >::values ( ) const
inline

Returns a const-reference to the complex magnitued vector.

Returns
const-reference to an complex magnitude vector

The documentation for this class was generated from the following file: