Discrepancy between Built-in Integrator and C-Script Implementation

Hello everyone,

I am currently working on implementing a Discrete Integrator using a C-Script block to compare it with the standard PLECS library block.

For the comparison, I set the integration method of the standard Discrete Integrator to ‘Forward Euler’ and applied both integrators to a PLL (Phase Locked Loop) system.

- Figure 1 shows the simulation results using the standard Discrete Integrator block.

- Figure 2 shows the results using my C-Script based integrator.

As you can see, there is a difference between the two results. In the first figure, i_d and v_d remain at 0, while i_q and v_q stably maintain a constant negative value. However, when the C-Script integrator is applied, the signals oscillate significantly, and eventually, the polarity reverses.

Below is the code I wrote for the Forward Euler method. Logic-wise, it seems correct to me, so I am struggling to understand what causes this significant divergence compared to the built-in block.

< Code declarations >
#define u Input(0)
#define reset Input(1)
#define y Output(0)
#define x DiscState(0)
#define u_prev DiscState(1)

float Ts;
float init_val;

< Start function code >
Ts = 0.0001;
init_val = 0.0;
x = 0;
u_prev = 0;

< Output function code >
y = x;

< Update function code >
if (reset != 0.0) {
  x = init_Val;
}
else {
  x = x + Ts*u_prev;
}
u_prev = u

Could anyone shed some light on what I might be missing here?

I have attached two simulation models for youre reference.

  1. simulation model using the standard discrete integrator

260116_frame_convert_test_with_default_integ.plecs (62.9 KB)
2. simulation model using the C-Script based integrator

260116_frame_convert_test_with_c-script_integ.plecs (69.6 KB)

I would really appreciate it if you could take a look at the models and share your feedback.
Thank you in advance for your help!

Could anyone advise on what might be causing this discrepancy?

Your Update function code introduces a one-step delay on the input signal. You should write this:

if (reset != 0.0) {
  x = init_Val;
}
else {
  x = x + Ts*u;
}

(and eliminate u_prev).

Hi Wolfgang,
thank you very much for your reply.

I updated my C-Script integrator as yo suggested by removing u_prev and using the current input u in the state update.

However, I still observe a discrepancy compared to the built-in Discrete Integrator block configured with Forward Euler. When using the library block, the i_dq and v_dq waveforms remain stable over the entire simulation time. In contrast, when the C-Script integrator is used, the signals start to deviate and their polarity flips after 0.7 sec(in Fig. 2).


Fig.1. simulation results using the default Discrete integrator block


Fig. 2. simulation results using the C-Script integrator

If the built-in Discrete Integrator is set to Forward Euler, shouldn’t it’s behavior be equivalent to y[k] = x[k] + Ts*u[k-1]? The C-Script implementations follows this update equation directly, so I would expect both implementations to behave identically.

Could you please help clarify why this polarity reversal still occuers in the C-Script case?

<for your reference)

260116_frame_convert_test_with_default_integ.plecs (62.9 KB)

frame_convert_test_260116_v02.plecs (68.8 KB) (modified c-script integrator)

Yes, it should - if you have defined Ts correctly.

I just noticed that you have defined it as a single precision floating point number in your Code declarations section:

float Ts;

The single-precision representation of 0.0001 is slightly smaller than the double-precision one, which is what the Pulse Generation uses to execute your Triggered Subsystem that contains the C-Script block. As a result, your C-Script integrator has an effective gain that is slightly smaller than 1.

You should change your code to this:

static double Ts;
static double init_val;

(The static is recommended to avoid linker errors if you ever generate C code for your model.)

Wow, that was exactly the problem! I changed it to static double as you suggested, and the issue is resolved. I appreciate your help!!