Resonant controller

Toolbox for a standard resonant controller. The ideal transfer function is:

\[\frac{Y(s)}{E(s)}= K_R \cdot \frac{s}{s^2 + \omega_R^2}\]

with the resonant frequency \(\omega_R\) [1].

The implemented discrete time transfer function is created by impulse invariant discretization with delay compensation [1 p. 1700] and is:

\[G_R(s) = K_R T_{s} \frac{\cos(2\omega_R T_{s}) - z^{-1}\cos(\omega_R T_{s}) }{1-2 z^{-1} \cos(\omega_R T_{s} )+ z^{-2} }\]

The resonant frequency is specified by \(\omega_R = h \cdot \omega_{el}\), with the order of the harmonic \(h\) to be controlled and the fundamental frequency \(\omega_{el}\). This method of discretization is chosen, as it is the most optimal among the methods discussed in [1 p. 1710 f.] with reduced phase lag, improved stability and accurate location of the resonant peaks even for high frequencies.


typedef struct uz_resonantController_t uz_resonantController_t

Struct definition for uz_resonantController.


Struct to create a resonant controller instance.

struct uz_resonantController_config

Configuration struct for PI-Controller. Pass to init function. Accessible by the user.

Public Members

float sampling_time

SamplingTime of the PI-Controller in seconds. Must be greater than 0.0f

float gain

Gain of the resonant Controller

float harmonic_order

Order of harmonic to be controlled

float fundamental_frequency

Fundamental Frequency in rad/s

float lower_limit

Lower limit for the output limitation

float upper_limit

Upper limit for the output limitation. Must be greater than lower limit

float antiwindup_gain

Gain of anti-windup feedback

float in_reference_value

Input reference value

float in_measured_value

Input measured value


Struct for the configuration of the resonant controller.

Init function

uz_resonantController_t *uz_resonantController_init(struct uz_resonantController_config config)

init function for the resonant controller

  • struct – uz_resonantController_config, config for the resonant controller


uz_resonant_controller*, pointer to the resonant controller


Listing 65 Example to create and initialize a resonant controller instance.
 1int main(void) {
 3  const struct uz_resonantController_config config_R = {
 4      .sampling_time = 0.0001f,
 5      .gain = 52.5f,
 6      .harmonic_order = 2.0f,
 7      .fundamental_frequency = 10.0f,
 8      .lower_limit = -4.0f,
 9      .upper_limit = 4.0f,
10      .antiwindup_gain = 10.0f,
11      .in_reference_value = 0.0f,
12      .in_measured_value = 0.0f,
13  };
14  uz_resonantController_t* R_controller_instance= uz_resonantController_init(config_R);

Step function

float uz_resonantController_step(uz_resonantController_t *self, float in_reference_value, float in_measured_value, float fundamental_frequency)

step function of the resonant controller, steps the controller once

  • self – pointer to uz_resonantController_t* object

  • float – in_reference_value, input reference value for the controller

  • float – in_measured_value, input measured value for the controller

  • float – fundamental_frequency, current angular velocity for the controller


float outputvalue of the resonant controller


Listing 66 Example function call to step the resonant controller once
1int main(void) {
2  // step once
3  output = uz_resonantController_step(R_controller_instance, in_ref_value, in_measured_value, fundamental_fequency);


Steps the resonant-controller. First the input values of the controller for the current time-step have to been set. With the step-function the new output value is calculated.


The step-function has to be called with the same sample time as specified in the input-struct of the resonant controller.

Get output function

float uz_resonantController_get_output(uz_resonantController_t *self)

returns output of the resonant controller

  • self – pointer to uz_resonantController_t* object


float output value


Function to get the output of the resonant controller after each step.

Reset function

void uz_resonantController_reset(uz_resonantController_t *self)

reset function of the resonant controller

  • self – pointer to uz_resonantController_t* object




Listing 67 Example function call to reset the resonant controller.
1int main(void) {
2   uz_resonantController_reset(R_controller_instance);


Resets the Resonant-Controller. The initial condition for the integrator and the output after the reset is 0.0f.

Set-Config function

void uz_resonantController_set_config(uz_resonantController_t *self, struct uz_resonantController_config config)

sets config of resonant controller

  • self – pointer to uz_resonantController_t* object

  • struct – uz_resonantController_config, new config for the resonant controller




Listing 68 Example to change the config of the resonant controller.
1int main(void) {
2  config.lower_limit = -10.0f;
3  config.upper_limit = 10.0f;
4  config.harmonic_order= 7.0f;
5  uz_resonantController_set_config(R_controller_instance, config);


Function to change the configuration of the resonant controller by passing a new or changed config struct to the controller.

Saturation and Anti-Windup

The output of the controller is limited by the input values upper_limit and lower_limit. As an anti-windup strategy the back calculation method is used. The gain of the anti-windup feedback is given by the input value antiwindup_gain. To disable the anti-windup strategy the feedback can be set to 0.


  1. Yepes, F. D. Freijedo, J. Doval-Gandoy, Ó. López, J. Malvar, and P. Fernandez-Domesaña , “Effects on Discretization Methods on the Performance of Resonant Controllers,” IEEE Transactions on Power Electronics, vol. 25, no. 7, pp. 1692-1712, Jul. 2010