2021-07-13

博客作者在MATLAB Simulink中遇到动态链接库(DLL)的问题,尝试生成包含积分器的模型并编译为DLL。在C代码中调用mdl_derivatives()未达到预期效果,导致积分器未正确工作。文章详细展示了模型设置、仿真图、生成的C代码,并指出积分曲线出现异常。作者正寻求解决C代码如何正确调用积分器的方法。
摘要由CSDN通过智能技术生成

MATLAB动态链接库问题

转载

原博主链接https://blog.csdn.net/linkcian/article/details/108637092#comments_17494419。

新的改变

加入了一个积分器

模型设置

在这里插入图片描述
在这里插入图片描述
由于加入了积分,这里需要勾选continuous time
在这里插入图片描述
然后build或者直接Ctrb + B编译模型,生成.dll。

仿真图

现在的.c该怎么写不知道怎么调用,只是在原来的.c上面写了个类似的mdl_derivatives();但没起到作用,不知道哪里的问题。

在这里插入图片描述
上面的scope,只做了加法:
在这里插入图片描述
下面的Scope,加了积分,蓝线是simulink曲线,黄线是经过.c
生成的曲线,看到的是积分没有起到作用,曲线很怪异。在这里插入图片描述

生成的.c代码

/*
 * File: dongtai.c
 *
 * Code generated for Simulink model 'dongtai'.
 *
 * Model version                  : 1.3
 * Simulink Coder version         : 9.2 (R2019b) 18-Jul-2019
 * C/C++ source code generated on : Tue Jul 13 09:57:43 2021
 *
 * Target selection: ert_shrlib.tlc
 * Embedded hardware selection: Intel->x86-64 (Windows64)
 * Code generation objectives: Unspecified
 * Validation result: Not run
 */

#include "dongtai.h"
#include "dongtai_private.h"

/* Block signals (default storage) */
B_dongtai_T dongtai_B;

/* Continuous states */
X_dongtai_T dongtai_X;

/* External inputs (root inport signals with default storage) */
ExtU_dongtai_T dongtai_U;

/* External outputs (root outports fed by signals with default storage) */
ExtY_dongtai_T dongtai_Y;

/* Real-time model */
RT_MODEL_dongtai_T dongtai_M_;
RT_MODEL_dongtai_T *const dongtai_M = &dongtai_M_;

/*
 * This function updates continuous states using the ODE4 fixed-step
 * solver algorithm
 */
static void rt_ertODEUpdateContinuousStates(RTWSolverInfo *si )
{
  time_T t = rtsiGetT(si);
  time_T tnew = rtsiGetSolverStopTime(si);
  time_T h = rtsiGetStepSize(si);
  real_T *x = rtsiGetContStates(si);
  ODE4_IntgData *id = (ODE4_IntgData *)rtsiGetSolverData(si);
  real_T *y = id->y;
  real_T *f0 = id->f[0];
  real_T *f1 = id->f[1];
  real_T *f2 = id->f[2];
  real_T *f3 = id->f[3];
  real_T temp;
  int_T i;
  int_T nXc = 1;
  rtsiSetSimTimeStep(si,MINOR_TIME_STEP);

  /* Save the state values at time t in y, we'll use x as ynew. */
  (void) memcpy(y, x,
                (uint_T)nXc*sizeof(real_T));

  /* Assumes that rtsiSetT and ModelOutputs are up-to-date */
  /* f0 = f(t,y) */
  rtsiSetdX(si, f0);
  dongtai_derivatives();

  /* f1 = f(t + (h/2), y + (h/2)*f0) */
  temp = 0.5 * h;
  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (temp*f0[i]);
  }

  rtsiSetT(si, t + temp);
  rtsiSetdX(si, f1);
  dongtai_step();
  dongtai_derivatives();

  /* f2 = f(t + (h/2), y + (h/2)*f1) */
  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (temp*f1[i]);
  }

  rtsiSetdX(si, f2);
  dongtai_step();
  dongtai_derivatives();

  /* f3 = f(t + h, y + h*f2) */
  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (h*f2[i]);
  }

  rtsiSetT(si, tnew);
  rtsiSetdX(si, f3);
  dongtai_step();
  dongtai_derivatives();

  /* tnew = t + h
     ynew = y + (h/6)*(f0 + 2*f1 + 2*f2 + 2*f3) */
  temp = h / 6.0;
  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + temp*(f0[i] + 2.0*f1[i] + 2.0*f2[i] + f3[i]);
  }

  rtsiSetSimTimeStep(si,MAJOR_TIME_STEP);
}

/* Model step function */
void dongtai_step(void)
{
  if (rtmIsMajorTimeStep(dongtai_M)) {
    /* set solver stop time */
    rtsiSetSolverStopTime(&dongtai_M->solverInfo,((dongtai_M->Timing.clockTick0+
      1)*dongtai_M->Timing.stepSize0));
  }                                    /* end MajorTimeStep */

  /* Update absolute time of base rate at minor time step */
  if (rtmIsMinorTimeStep(dongtai_M)) {
    dongtai_M->Timing.t[0] = rtsiGetT(&dongtai_M->solverInfo);
  }

  /* Outport: '<Root>/shuchu1' incorporates:
   *  Integrator: '<Root>/Integrator'
   */
  dongtai_Y.shuchu1 = dongtai_X.Integrator_CSTATE;

  /* Sum: '<Root>/Add' incorporates:
   *  Inport: '<Root>/shuru1'
   *  Inport: '<Root>/shuru2'
   */
  dongtai_B.Add = dongtai_U.shuru1 + dongtai_U.shuru2;
  if (rtmIsMajorTimeStep(dongtai_M)) {
    rt_ertODEUpdateContinuousStates(&dongtai_M->solverInfo);

    /* 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.
     */
    ++dongtai_M->Timing.clockTick0;
    dongtai_M->Timing.t[0] = rtsiGetSolverStopTime(&dongtai_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.
       */
      dongtai_M->Timing.clockTick1++;
    }
  }                                    /* end MajorTimeStep */
}

/* Derivatives for root system: '<Root>' */
void dongtai_derivatives(void)
{
  XDot_dongtai_T *_rtXdot;
  _rtXdot = ((XDot_dongtai_T *) dongtai_M->derivs);

  /* Derivatives for Integrator: '<Root>/Integrator' */
  _rtXdot->Integrator_CSTATE = dongtai_B.Add;
}

/* Model initialize function */
void dongtai_initialize(void)
{
  /* Registration code */
  {
    /* Setup solver object */
    rtsiSetSimTimeStepPtr(&dongtai_M->solverInfo, &dongtai_M->Timing.simTimeStep);
    rtsiSetTPtr(&dongtai_M->solverInfo, &rtmGetTPtr(dongtai_M));
    rtsiSetStepSizePtr(&dongtai_M->solverInfo, &dongtai_M->Timing.stepSize0);
    rtsiSetdXPtr(&dongtai_M->solverInfo, &dongtai_M->derivs);
    rtsiSetContStatesPtr(&dongtai_M->solverInfo, (real_T **)
                         &dongtai_M->contStates);
    rtsiSetNumContStatesPtr(&dongtai_M->solverInfo,
      &dongtai_M->Sizes.numContStates);
    rtsiSetNumPeriodicContStatesPtr(&dongtai_M->solverInfo,
      &dongtai_M->Sizes.numPeriodicContStates);
    rtsiSetPeriodicContStateIndicesPtr(&dongtai_M->solverInfo,
      &dongtai_M->periodicContStateIndices);
    rtsiSetPeriodicContStateRangesPtr(&dongtai_M->solverInfo,
      &dongtai_M->periodicContStateRanges);
    rtsiSetErrorStatusPtr(&dongtai_M->solverInfo, (&rtmGetErrorStatus(dongtai_M)));
    rtsiSetRTModelPtr(&dongtai_M->solverInfo, dongtai_M);
  }

  rtsiSetSimTimeStep(&dongtai_M->solverInfo, MAJOR_TIME_STEP);
  dongtai_M->intgData.y = dongtai_M->odeY;
  dongtai_M->intgData.f[0] = dongtai_M->odeF[0];
  dongtai_M->intgData.f[1] = dongtai_M->odeF[1];
  dongtai_M->intgData.f[2] = dongtai_M->odeF[2];
  dongtai_M->intgData.f[3] = dongtai_M->odeF[3];
  dongtai_M->contStates = ((X_dongtai_T *) &dongtai_X);
  rtsiSetSolverData(&dongtai_M->solverInfo, (void *)&dongtai_M->intgData);
  rtsiSetSolverName(&dongtai_M->solverInfo,"ode4");
  rtmSetTPtr(dongtai_M, &dongtai_M->Timing.tArray[0]);
  dongtai_M->Timing.stepSize0 = 0.01;

  /* InitializeConditions for Integrator: '<Root>/Integrator' */
  dongtai_X.Integrator_CSTATE = 0.0;
}

/* Model terminate function */
void dongtai_terminate(void)
{
  /* (no terminate code required) */
}

/*
 * File trailer for generated code.
 *
 * [EOF]
 */

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值