mex file execution of my model gives wrong result!!!

1 view (last 30 days)
Hello community,
I hope you are doing good you all. I'm working on a project were I want to generated c code for a motor speed control model using simulink coder and matlab coder. The code has already been generated and some modifications were also did according to what a I want to do: I want to run simulation (executable mex file of code version of the model) by varying my control parameters.
Main goal is to use mex function inside the callback function of the genetic algorithm in matlab in order to calculate best accurate control parameter for my motor speed control model.
to generate my mex file i have done as follow:
function r_sim=simulation_test(KR,KI)
%#codegen
r_sim= zeros(size(0:0.01:0.25));
coder.ceval('simulation',KR,KI, coder.wref(r_sim));
end
codegen simulation_test -args {1,2} speed_control.c simulation.c simulation.h -report
the function simulation called the generated step function (void speed_control_step(real_T KR,real_T KI, real_T* r_sim)) function:
#include "simulation.h"
void simulation(double KR,double KI,double* r_sim)
{
speed_control_initialize();
/* Simulating the model step behavior (in non real-time) to
* simulate model behavior at stop time.
*/
while ((rtmGetErrorStatus(speed_control_M) == (NULL)) && !rtmGetStopRequested
(speed_control_M)) {
speed_control_step(KR,KI,r_sim);
}
speed_control_terminate();
}
Inside the function speed_control_step() i added these two instructions to write into r_sim array and just one data is being written into r_sim.
*r_sim=speed_control_Y.ysim;
r_sim++;
The generated code use ode4(Runge Kutta) solver algorithm which I cannot understand as it is working with the model step function and inversely:
/// this function is called from model step function
rt_ertODEUpdateContinuousStates(&speed_control_M->solverInfo,KR,KI,ptr);
Something wrong is maybe happening when writing into r_sim pointer. I checked my output vector after mex file excecution and just one value is being written into r_sim.
/* Model step function */
void speed_control_step(real_T KR,real_T KI, real_T* r_sim)
{
real_T rtb_KR;
ptr=r_sim;
if (rtmIsMajorTimeStep(speed_control_M)) {
/* set solver stop time */
if (!(speed_control_M->Timing.clockTick0+1)) {
rtsiSetSolverStopTime(&speed_control_M->solverInfo,
((speed_control_M->Timing.clockTickH0 + 1) *
speed_control_M->Timing.stepSize0 * 4294967296.0));
} else {
rtsiSetSolverStopTime(&speed_control_M->solverInfo,
((speed_control_M->Timing.clockTick0 + 1) *
speed_control_M->Timing.stepSize0 + speed_control_M->Timing.clockTickH0 *
speed_control_M->Timing.stepSize0 * 4294967296.0));
}
} /* end MajorTimeStep */
/* Update absolute time of base rate at minor time step */
if (rtmIsMinorTimeStep(speed_control_M)) {
speed_control_M->Timing.t[0] = rtsiGetT(&speed_control_M->solverInfo);
}
/* Integrator: '<S2>/Integrator1_M' */
speed_control_B.Integrator1_M = speed_control_X.Integrator1_M_CSTATE;
/* Outport: '<Root>/ysim' */
speed_control_Y.ysim = speed_control_B.Integrator1_M;
*r_sim=speed_control_Y.ysim;
r_sim++;
/* Gain: '<Root>/KR' incorporates:
* Step: '<Root>/Step w_ref [rad//s]'2.5
*
* Sum: '<Root>/Add2'
*/
rtb_KR = ((real_T)!(speed_control_M->Timing.t[0] < 0.0) -
speed_control_B.Integrator1_M) * KR;
/* Gain: '<S1>/one_over_L' incorporates:
* Gain: '<S1>/K_M'
* Gain: '<S1>/R'
* Integrator: '<Root>/Integrator'
* Integrator: '<S1>/Integrator_Ak'
* Sum: '<Root>/Add6'
* Sum: '<S1>/add'
*/
speed_control_B.one_over_L = (((speed_control_X.Integrator_CSTATE + rtb_KR) -
1 * speed_control_B.Integrator1_M) - 3.0 *
speed_control_X.Integrator_Ak_CSTATE) * 100.0;
/* Gain: '<S2>/one_over_J' incorporates:
* Gain: '<S2>/K_M'
* Integrator: '<S1>/Integrator_Ak'
*/
speed_control_B.one_over_J = 1 * speed_control_X.Integrator_Ak_CSTATE *
100.0;
/* Gain: '<Root>/KI' */
speed_control_B.KI = KI * rtb_KR;
// if (rtmIsMajorTimeStep(speed_control_M)) {
// /* Matfile logging */
// rt_UpdateTXYLogVars(speed_control_M->rtwLogInfo, (speed_control_M->Timing.t));
// } /* end MajorTimeStep */
if (rtmIsMajorTimeStep(speed_control_M)) {
/* signal main to stop simulation */
{ /* Sample time: [0.0s, 0.0s] */
if ((rtmGetTFinal(speed_control_M)!=-1) &&
!((rtmGetTFinal(speed_control_M)-(((speed_control_M->Timing.clockTick1
+speed_control_M->Timing.clockTickH1* 4294967296.0)) * 0.01)) >
(((speed_control_M->Timing.clockTick1+
speed_control_M->Timing.clockTickH1* 4294967296.0)) * 0.01) *
(DBL_EPSILON))) {
rtmSetErrorStatus(speed_control_M, "Simulation finished");
}
}
rt_ertODEUpdateContinuousStates(&speed_control_M->solverInfo,KR,KI,ptr);
/* Update absolute time for base rate */
/* The "clockTick0" counts the number of times the code of this task has
* been executed. The absolute time is the multiplication of "clockTick0"
* and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
* overflow during the application lifespan selected.
* Timer of this task consists of two 32 bit unsigned integers.
* The two integers represent the low bits Timing.clockTick0 and the high bits
* Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
*/
if (!(++speed_control_M->Timing.clockTick0)) {
++speed_control_M->Timing.clockTickH0;
}
speed_control_M->Timing.t[0] = rtsiGetSolverStopTime
(&speed_control_M->solverInfo);
{
/* Update absolute timer for sample time: [0.01s, 0.0s] */
/* The "clockTick1" counts the number of times the code of this task has
* been executed. The resolution of this integer timer is 0.01, which is the step size
* of the task. Size of "clockTick1" ensures timer will not overflow during the
* application lifespan selected.
* Timer of this task consists of two 32 bit unsigned integers.
* The two integers represent the low bits Timing.clockTick1 and the high bits
* Timing.clockTickH1. When the low bit overflows to 0, the high bits increment.
*/
speed_control_M->Timing.clockTick1++;
if (!speed_control_M->Timing.clockTick1) {
speed_control_M->Timing.clockTickH1++;
}
}
}/* end MajorTimeStep */
}
Please have a look on the code and tell me what I'm doing wrong.
I hope with your experience I will get some good inputs.
  2 Comments
Walter Roberson
Walter Roberson on 18 May 2022
*r_sim=speed_control_Y.ysim;
r_sim++;
is the only place where you write through the pointer. Why are you expecting more than one value?
ptr=r_sim;
You clone the pointer into ptr before you do the above assignment. Then
rt_ertODEUpdateContinuousStates(&speed_control_M->solverInfo,KR,KI,ptr);
that is the original pointer, not the one after a single value has been written into it. If rt_ertODEUpdateContinuousStates writes through the pointer, it risks overwriting the ysim value that you wrote in.
Emmanuel Walter Djeutsop Sonkoua
Thanks for your reply!
it was absolutly non sense what i did last time. Removing this
ptr=r_sim;
in the step function and place it in the initialisation function. The step function just have a the control parameter as input and i can update data in my global cloned ptr pointer after each MajorTimeStep.
Now i get the correct output but with an error of 10e-5 order. I have to check where it comes.

Sign in to comment.

Answers (0)

Categories

Find more on Simulink Coder in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!