kontrol.regulator

Primary modules

kontrol.regulator.feedback

Algorithmic designs for feedback control regulators.

kontrol.regulator.feedback.add_integral_control(plant, regulator=None, integrator_ugf=None, integrator_time_constant=None, **kwargs)

Match and returns an integral gain.

This function finds an integral gain such that the UGF of the integral control matches that of the specified regulator. If integrator_ugf or integrator_time_constant is specified instead, these will be matched instead.

Parameters
  • plant (TransferFunction) – The transfer function representation of the system to be feedback controlled.

  • regulator (TransferFunction, optional) – The pre-regulator Use kontrol.regulator.feedback.proportional_derivative() or kontrol.regulator.feedback.critical_damping() to make one for oscillator-like systems.

  • integrator_ugf (float, optional) – The unity gain frequency (Hz) of the integral control. This is the inverse of the integration time constant. If integrator_time_constant is not None, then this value will be ignored. If set to None, it’ll be set to match the first UGF of the derivative control. Defaults to None.

  • integrator_time_constant (float, optional,) – The integration time constant (s) for integral control. Setting this will override the integrator_ugf argument. Defaults to None.

Returns

ki – The integral control gain.

Return type

float

kontrol.regulator.feedback.add_proportional_control(plant, regulator=None, dcgain=None, **kwargs)

Match and returns proportional gain.

This function finds a proportional gain such that the proportional control UGF matches the first UGF of the specified regulator (typically a derivative control regulator). If dcgain is specified, the DC gain is matched instead.

Parameters
  • plant (TransferFunction) – The transfer function representation of the system to be feedback controlled. The plant must contain at least one pair of complex poles.

  • regulator (TransferFunction, optional) – The pre-regulator. If not specified, then dcgain must be specified. Defaults to None.

  • dcgain (float, optional) – The desired DC gain of the open-loop transfer function. If not specified, the portional gain is tuned such that the portional control’s first UGF matches that of the derivative control. Defaults to None.

Returns

kp – The proportional control gain.

Return type

float

kontrol.regulator.feedback.critical_damp_calculated(plant, nmode=1, **kwargs)

Find dominant mode and returns the approximate critical regulator.

Parameters
  • plant (TransferFunction) – The transfer function representation of the system to be feedback controlled. The plant must contain at least one pair of complex poles.

  • nmode (int, optional) – The ``nmode``th dominant mode to be damped. This number must be less than the number of modes in the plant. Defaults 1.

Returns

kd – The derivative gain for critically damping the dominant mode.

Return type

float

Notes

The plant must contain at least one complex pole pair. The plant must have a non-zero DC gain.

The critical regulator is approximated by

\[K(s) \approx \frac{2}{\omega_n K_\mathrm{DC}}\,,\]

where \(\omega_n\) is the resonance frequency of the dominant mode and \(K_\mathrm{DC}\) is the sum of DC gains of the mode and that of the other higher-frequency modes..

kontrol.regulator.feedback.critical_damp_optimize(plant, gain_step=1.1, ktol=1e-06, **kwargs)

Optimize derivative damping gain and returns the critical regulator

Parameters
  • plant (TransferFunction) – The transfer function representation of the system to be feedback controlled. The plant must contain at least one pair of complex poles.

  • gain_step (float, optional) – The multiplicative factor of the gain for finding the gain upper bound. It must be greater than 1. Defaults to 1.1.

  • ktol (float, optional) – The tolerance for the convergence condition. The convergence condition is (kd_max-kd_min)/kd_min > ktol. It must be greater than 0. Defaults to 1e-6.

Returns

kd – The derivative gain for critically damping the dominant mode.

Return type

float

Notes

Update on 2021-12-04: Use carefully. It only critically damps the mode that has the highest peak when multiplied by an differentiator. Note for myself: only 2 complex poles can become simple poles for plants with second-order rolloff.

Only works with plants that contain at least one complex pole pair. Works best with plants that only contain complex zeros/poles. If it returns unreasonably high gain, try lowering gain_step.

The algorithm goes as follows.

1. Find the minimum damping gain k_min such that the open-loop transfer function k_min*s*plant has maxmimum gain at unity gain frequency.

  1. Iterate i: k_i=k_min*i*gain_step for i=1,2,3…

3. Terminate when 1/(1+k_i*s*plant) has less complex pole pairs than the plant itself, i.e. one mode has been overdamped. Then, define k_max=k_i.

4. Iterate: Define k_mid as the logarithmic mean of k_max and k_min. If 1/(1+k_mid*s*plant) has less complex pole pairs than plant, i.e. overdamps, then set k_max=k_mid. Otherwise, set k_min=k_mid.

  1. Terminate when (k_max - k_min)/k_min < ktol, i.e. converges.

kontrol.regulator.feedback.critical_damping(plant, method='calculated', **kwargs)

Returns the critical damping derivative control gain.

This functions calls kontrol.regulator.feedback.critical_damp_calculated() or kontrol.regulator.feedback.cricical_damp_optimized() and returns the derivative control gain.

Parameters
  • plant (TransferFunction) – The transfer function representation of the system to be feedback controlled. The plant must contain at least one pair of complex poles.

  • method (str, optional) –

    The method to be used for setting the gain. Choose from [“optimized”, “calculated”].

    ”optimized”: the gain is optimized until the dominant complex pole pairs become two simple poles.

    ”calculated”: the gain is set to \(2/\omega_n/K_{DC}\), where \(\omega_n\) is the resonance frequency in rad/s of the mode to be damped, and \(K_{DC}\) is the sum of DC gains of the mode and that of the other high-frequency modes.

    Both method assumes that the plant has at least one pair of complex poles.

    Defaults to “calculated”.

  • **kwargs (dict) –

    Method specific keyword arguments.

    See:

    • ”optimized”: kontrol.regulator.feedback.critical_damp_optimized

    • ”calculated”: kontrol.regulator.feedback.critical_damp_calculated

Returns

kd – The derivative gain for critically damping the dominant mode.

Return type

float

kontrol.regulator.feedback.mode_composition(wn, q, k)

Create a plant composed of many modes.

Parameters
  • wn (array) –

  • (rad/s). (Frequencies) –

  • q (array) – Q factors.

  • k (array) – Dcgains of the modes.

Returns

The composed plant.

Return type

TransferFunction

kontrol.regulator.feedback.mode_decomposition(plant)

Returns a list of single mode transfer functions

Parameters

plant (TransferFunction) – The transfer function with at list one pair of complex poles.

Returns

  • wn (array) – Frequencies (rad/s).

  • q (array) – Q factors.

  • k (array) – Dcgains of the modes.

kontrol.regulator.oscillator

Control regulators designs for oscillator-like systems

kontrol.regulator.oscillator.pid(plant, regulator_type='PID', dcgain=None, integrator_ugf=None, integrator_time_constant=None, return_gain=False, **kwargs)

PID-like controller design for oscillator-like systems

Parameters
  • plant (TransferFunction) – The transfer function of the system that needs to be controlled.

  • regulator_type (str, optional) – The type of the contorl regulator. Choose from {"PID", "PD", "PI", "I", "D"} for proportional-integral-derivative, proportional-derivative, proportional-integral, or derivative (velocity) control respectively. Defaults to “PID”.

  • dcgain (float, optional) – The DC gain of the OLTF of the proportional control. If set to None, it will be set automatically depending on the type of the controller. If regulator_type=="PI", then dcgain will be set such that the proportional control UGF matches that of the integral control. If regulator_type=="PD" or "PID", then the dcgain will be set such that it matches the UGF of the derivative control. Defaults to None.

  • integrator_ugf (float, optional) – The unity gain frequency (Hz) of the integral control. This is the inverse of the integration time constant. If integrator_time_constant is not None, then this value will be ignored. If set to None, it’ll be set to match the UGF of the derivative control. For regulator_type=="I", this must be specified. Defaults to None.

  • integrator_time_constant (float, optional,) – The integration time constant (s) for integral control. Setting this will override the integrator_ugf argument. Defaults to None.

  • return_gain (boolean, optional) – Return the PID gain instead.

Returns

  • regulator (TransferFunction, optional) – The regulator. Return only if return_gain is False.

  • kp (float, optional) – Proportional gain. Return only if return_gain is ``True’’.

  • ki (float, optional) – Integral gain. Return only if return_gain is True.

  • kd (float, optional) – Derivative gain. Return only if return_gain is True.

kontrol.regulator.post_filter

Functions for designing post-regulator filters

kontrol.regulator.post_filter.post_low_pass(plant, regulator, post_filter=None, ignore_ugf_above=None, decades_after_ugf=1, phase_margin=45, f_start=None, f_step=1.1, low_pass=None, mtol=1e-06, small_number=1e-06, oscillatory=True, **kwargs)

Add low-pass filter after regulator.

This function lowers/increase the the cutoff frequency of a low-pass filter until the phase margin at a dedicated ugf crosses the specified phase margin. Then, runs a bisection algorithm to poolish the cutoff frequency until the phase margin converges relative to the specified tolerance.

Parameters
  • plant (TransferFunction) – The transfer function of the system that needs to be controlled.

  • regulator (TransferFunction) – The regulator.

  • post_filter (TransferFunction, optional) – Any post filters that will be applied on top of the regulator. Defaults None.

  • ignore_ugf_above (float, optional) – Ignore unity gain frequencies higher than ignore_ugf_above (Hz). If not specified, defaults to 1 decade higher than the last UGF. This value can be overrided by the argument decades_after_ugf Note that there’s no guarantee that the UGF will be lower than this. The priority is to match the target phase margin. Defaults to None.

  • decades_after_ugf (float, optional) – Set ignore_ugf_above some decades higher than the UGF of the OLTF ignore_ugf_above is None. Defaults to 1.

  • phase_margin (float, optional,) – The target phase margin (Degrees). Defaults to 45.

  • f_start (float, optional,) – The cutoff frequency to start iterating with. If not specified, defaults to some decades higher than the highest UGF. “Some decade” is set by decades_after_ugf. Defaults None.

  • f_step (float, optional,) – The gain that is used to multiply (or divide) the cutoff frequency during a coarse search. Defaults 1.1

  • low_pass (func(cutoff, order) -> TransferFunction, optional) – The low-pass filter. If not specified, kontrol.regulator.predefined.lowpass() with order 2 will be used. Defaults to None.

  • mtol (float, optional) – Tolerance for convergence of phase margin. Defaults to 1e-6.

  • small_number (float, optional) – A small number as a delta f to detect whether the gain is a rising or lowering edge at the unity gain frequency. Defaults to 1e-6.

  • oscillatory (boolean, optional) – Use the first mode of the oscillatory system to evaluate the phase margins to avoid having UGFs at steep phase slopes. The benefit of using this is to have a conservative phase margin estimate. The phase response of the first mode is the lower bound of the phase response. If False, use the plant itself to calculate phase margins. If the plant does not contain any complex poles, this option will be overridden to False. Defaults True.

  • **kwargs – Keyword arguments passed to low_pass.

Returns

The low-pass filter.

Return type

TransferFunction

kontrol.regulator.post_filter.post_notch(plant, regulator=None, post_filter=None, target_gain=None, notch_peaks_above=None, phase_margin=45, notch=None, **kwargs)

Returns a list of notch filters that suppress resonance peaks.

This functions finds the resonances peak of the plant/OLTF above certain frequencies and returns a list of notch filters that suppress these peaks to the target gains.

Parameters
  • plant (TransferFunction) – The transfer function of the system that needs to be controlled.

  • regulator (TransferFunction, optional) – The regulator. Defaults to None.

  • post_filter (TransferFunction, optional) – Any post filters that will be applied on top of the regulator. Defaults None.

  • target_gain (float, optional) – The target open-loop gain for the suppressed peak. To ensure a stable system, a value of less than 1 is recommended. If not specified, the notch will fully suppress the peak. Default None.

  • phase_margin (float, optional) – The target phase margin. Defaults to 45.

  • notch_peaks_above (float, optional) – Notch modes that has freqeuncies above notch_peaks_above. If not specified, defaults to the highest unity gain frequency that is above phase_margin Defaults to None.

  • notch (func(frequency, q, depth) -> TransferFunction, optional) – The notch filter. If not specified, kontrol.Notch() will be used. Defaults to None.

  • **kwargs – Keyword arguments passed to notch().

Returns

A list of notch filters.

Return type

list of TransferFunction

Notes

This operation does not guarantee stability. It only finds resonances peaking out of the unity gain above some unity gain frequency and make notch filters to suppress them to a target gain level lower than the unity gain. The stability of the notched OLTF is not checked whatsoever.

Secondary modules

kontrol.regulator.predefined

Predefined regulator library.

kontrol.regulator.predefined.low_pass(cutoff, order=1, **kwargs)

Simple low-pass filter

Parameters
  • cutoff (float) – Cutoff frequency (Hz)

  • order (int, optional) – The order of the filter. Defaults to be 1.

  • **kwargs – Keyword arguments holder. Not passed to anywhere.

Returns

The low-pass filter.

Return type

TransferFunction

Notes

The low-pass filter is defined as

\[L(s) = \left(\frac{2\pi f_c}{s+2\pi f_c}\right)^n\,,\]

where \(f_c\) is the cutoff frequency (Hz), \(n\) is the order of the filter.

kontrol.regulator.predefined.notch(frequency, q, depth=None, depth_db=None, **kwargs)

Notch filter defined in Foton.

Parameters
  • frequency (float) – The notch frequency (Hz).

  • q (float) – The quality factor.

  • depth (float, optional) – The depth of the notch filter (magnitude). If not specified, depth_db will be used. Defaults None.

  • depth_db (float, optional) – The depth of the notch filter (decibel). If not specified, depth will be used instead. Defaults None.

Returns

The notch filter

Return type

TransferFunction

Notes

The notch filter is defined by Foton, as

\[N(s) = \frac{s^2 + (2\pi f_n)/(dQ/2)s + (2\pi f_n)^2} {s^2 + (2\pi f_n)/(Q/2)s + (2\pi f_n)^2}\,,\]

where \(f_n\) is the notch frequency, \(q\) is the quality factor , and \(d\) is the depth.

kontrol.regulator.predefined.pid(kp=0, ki=0, kd=0)

Alias of proportional_integral_derivative()

kontrol.regulator.predefined.proportional_integral_derivative(kp=0, ki=0, kd=0)

PID control build on proportional_derivative().

Parameters
  • kp (float, optional) – The proportional control gain. Defaults to 0.

  • ki (float, optional) – The integral control gain. Defaults to 0.

  • kd (float, optional) – Defaults to 0.

Returns

The PID controller.

Return type

TransferFunction

Notes

The PID controller is defined as

\[K_\mathrm{PID}(s) = K_p + K_i/s + K_d s\,.\]