Несколько экземпляров c_block в одном моделировании Scilab/Xcos

Я столкнулся с проблемой использования Xcos c_block. Я разработал c_block со следующим кодом C:

#include <machine.h>
#include <math.h>

void Ramp(flag,nevprt,t,xd,x,nx,z,nz,tvec,
             ntvec,rpar,nrpar,ipar,nipar
      ,u1,nu1,y1,ny1)
 
 
      double *t,xd[],x[],z[],tvec[];
      int *flag,*nevprt,*nx,*nz,*ntvec,*nrpar,ipar[],*nipar,*nu1,*ny1;
      double rpar[],u1[],y1[];
/* modify below this line */
{

static double target     = 0;
static double inputDelta = 0;
static double out        = 0;

if(u1[0] != target)
{
        target = u1[0];

        if(target - y1[0] < 0)
        {
                inputDelta = y1[0] - target;
        }
        else
        {
                inputDelta = target - y1[0];
        }
}

if(target > y1[0])
{
        out += inputDelta*rpar[2]/rpar[0];
        if(out > target)
        {
                out = target;
        }
}
else if(target < y1[0])
{
        out -= inputDelta*rpar[2]/rpar[1];
        if(out < target)
        {
                out = target;
        }
}
       
y1[0] = out;

}

Моделирование Xcos, содержащее этот блок, работает:

введите здесь описание изображения

Моя проблема в том, что мне нужно иметь несколько экземпляров этого блока в одном моделировании Xcos (каждый экземпляр с другим набором параметров). Я попытался сделать несколько копий этого блока и установить разные значения параметров для каждой копии. Такой наивный подход приводил к неправильному поведению всех экземпляров (все экземпляры давали абсолютно одинаковый результат, но этот вывод не соответствовал ни одному набору параметров).

Мой вопрос заключается в том, возможно ли когда-либо иметь несколько экземпляров одного c_block в одной симуляции? Если да, то может ли кто-нибудь дать мне совет, как это сделать?


person Steve    schedule 26.09.2020    source источник


Ответы (1)


Ответ заключается в том, что возможно иметь несколько экземпляров одного блока, содержащего код c, в данном моделировании. Я запустил это с помощью блока CBLOCK4 и использования указателя work в структуре scicos_block. Этот указатель содержит адрес где-то в куче, где хранятся постоянные данные CBLOCK4. Ниже приведена модификация кода выше

#include "scicos_block4.h"

#define U  ((double *)GetRealInPortPtrs(block, 1))
#define Y  ((double *)GetRealOutPortPtrs(block, 1))

// parameters
#define Tu (GetRparPtrs(block)[0])
#define Td (GetRparPtrs(block)[1])
#define T  (GetRparPtrs(block)[2])

typedef struct
{
    double target;
    double inputDelta;
    double out;
}Ramp_work;

void Ramp(scicos_block *block, int flag)
{
 
  Ramp_work *work;

  if(flag == 4) 
  {
    /* init */
    if((*(block->work) = (Ramp_work*)scicos_malloc(sizeof(Ramp_work))) == NULL)
    {
        set_block_error(-16);
        return;
    }
    work = *(block->work);          
    work->target      = 0;
        work->inputDelta  = 0;
    work->out         = 0;

  }
  else if(flag == 1) 
  {

    work = *(block->work);  

    /* output computation */ 
    if(U[0] != work->target)
    {
        work->target = U[0];
        
        if(work->target - Y[0] < 0)
        {
            work->inputDelta = Y[0] - work->target;
        }
        else
        {
            work->inputDelta = work->target - Y[0];
        }
    }
    
    if(work->target > Y[0])
    {
        work->out += work->inputDelta*T/Tu;
        if(work->out > work->target)
        {
            work->out = work->target;
        }
    }
    else if(work->target < Y[0])
    {
        work->out -= work->inputDelta*T/Td;
        if(work->out < work->target)
        {
            work->out = work->target;
        }
    }
    
    Y[0] = work->out;  

  } 
  else  if (flag == 5) 
  {
    /* ending */
    scicos_free(*(block->work));
  }

}
 
person Steve    schedule 06.10.2020