一次 Scilab/Xcos 模拟中 c_block 的多个实例
Multiple instances of c_block in one Scilab/Xcos simulation
我遇到了关于 Xcos c_block 用法的问题。我开发了
具有以下 C 代码的 c_block:
#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 在一次模拟中?如果是这样,有人可以给我建议怎么做吗?
答案是,在给定的模拟中,一个包含 c 代码的块可能有多个实例。我已经起床 运行 使用 CBLOCK4 块和 scicos_block
结构中 work
指针的用法。该指针包含堆上某处的地址,其中存储了 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));
}
}
我遇到了关于 Xcos c_block 用法的问题。我开发了 具有以下 C 代码的 c_block:
#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 在一次模拟中?如果是这样,有人可以给我建议怎么做吗?
答案是,在给定的模拟中,一个包含 c 代码的块可能有多个实例。我已经起床 运行 使用 CBLOCK4 块和 scicos_block
结构中 work
指针的用法。该指针包含堆上某处的地址,其中存储了 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));
}
}