本文主要通过使用C 程序作为控制工具,并演示了如何加载到 AMEsim 模型中进行独立仿真,该模式能够大大简化控制逻辑的建模难度。
Microsoft Visual Studio 12.0 中文版
AMEsim 14
新建一个空 project 文件,加载空白 C++文件模板;
配置项目属性:右键点击解决方案资源管理器中的项目名,选择属性菜单,出现对话框,切换到“C/C++”目录项,点击“常规”条目,在右侧的“附加包含目录”中添加“D:\AMESim\v1300\lib”路径,即AMESIM 的安装目录。
切换到“高级”条目,在“编译为”选项中选择“编译为 C 代码(/TC)”,如下图所示。
切换到“ 链接器” 目录项, 点击“ 常规” 条目, 在“ 附加库目录” 中添加“D:\AMESim\v1300\lib\win32”路径。
切换到“输入”条目,在“附加依赖项”中添加“AME.lib”,在“忽略特定默认库”中添加“MSVCRTD.lib”
通过上述步骤完成项目配置。
DYNEXE0是一个用于与外部应用程序进行交互的接口模块。模块的左侧端口和右侧端口分别代表其输入和输出。在库中选择该模块时,便可对输入和输出数量以及外部应用程序的整型参数和实型参数的数量进行定义,如下图所示。
一般的控制连��都包含多个输入和输出,因此必须采用 DYNMUX2 和 DYNDMUX2 与DYNEXE0 进行连接,如下图所示即为一个 5 输入 5 输出系统。
AMESIM 必须采用 C++编译器才能使用 DYNEXE0 模块;
修改 AME 参数必须在参数模式下修改,再次运行时才会被 C 程序采集;
最好将编译目录和 amesim 目录放置到同一目录。
头文件
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ameutils.h>
前 4 个是 VS 自带的,后面一个是外部加载的。
添加主要常量
#defineNUM_IP1//整型参数数量
#defineNUM_RP1//实型参数数量
#defineNUM_INPUTS 2//输入数量
#defineNUM_OUTPUTS2//输出数量
注意:此处定义的数量必须和模型中保持一致,否则就错了。
连接 AMESIM 模型
connec_(file, &num_rp, rparam, &num_ip, iparam, &num_inputs, &num_outputs); a1 = iparam[0];
a2 = rparam[0];
将 AMESIM 模型 DYNEXE0 模块中定义的实型参数读入到 rparam 数组中,整型参数和实型参数分别读入到 iparam、rparam 数组中。
获取输入参数
getinp_(&(file[0]), &num_inputs, input, &flag); x1=input[0];
x2=input[1];
从 AMESIM 获取输入,并将其存储到数组 input 中。
输出参数
output[0] =x1+a1;
output[1] =x2+a2;
senout_(&(file[1]), &num_outputs, output);
向 AMESIM 发送输出。
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <ameutils.h>
/*TODO:添加需要包含的额外头文件*/
/*例如:*/
/*注意:此处定义的参数及变量数量必须与AMESIM模型中DYNEXE0模块定义的数量保持一致*/ #define NUM_IP1//整型参数数量
#define NUM_RP1//实型参数数量#define NUM_INPUTS2//输入数量#define NUM_OUTPUTS 2//输出数量
/*TODO:添加需要定义的其它常量*/
/*例如:*/
/*主函数*/ int main()
{
intnum_rp = NUM_RP; /*对实型参数数量定义为整数型,方便后文调用*/
intnum_ip = NUM_IP;/*对整型参数数量定义为整数型,方便后文调用*/
intnum_inputs = NUM_INPUTS;/*对输入参数数量定义为整数型,方便后文调用*/
intnum_outputs = NUM_OUTPUTS;/*对输出参数数量定义为整数型,方便后文调用*/
intfile[2], iparam[NUM_IP], flag;/*数组iparam用于存储整型参数,file[2]分别作为输入和输出组,flag作为读取成功标记*/
double rparam[NUM_RP], input[NUM_INPUTS], output[NUM_OUTPUTS];/*数组rparam用于存储实型参数,数组input用于存储控制策略的输入,数组output用于存储控制策略的输出*/
inta1;//定义整型参数变量
double a2;//定义实型参数变量
double x1, x2;//定义输入参数变量,后文使用,也可以直接用input[0]等数组形式使用,只是显得太麻烦,如果有需求可以定义输出变量
/*连接AMESIM模型*/
connec_(file, &num_rp, rparam, &num_ip, iparam, &num_inputs, &num_outputs);/*将AMESIM模型DYNEXE0模块中定义的实型参数读入到rparam数组中,整型参数读入到iparam数组中*/
a1 = iparam[0];//获取整形参数
a2 = rparam[0];//获取实型参数
while (1)
{
getinp_(&(file[0]), &num_inputs, input, &flag);/*从AMESIM获取输入,并将其存储到数组input
中*/
x1=input[0];/*TODO:将input数组中的元素赋值给内部变量,以便从变量名即可获知变量的意义*/
x2=input[1];/*TODO:将input数组中的元素赋值给内部变量,以便从变量名即可获知变量的意义*/
output[0] =x1+a1;/*将计算输出赋值output数组中的元素*/
output[1] =x2+a2;/*将计算输出赋值output数组中的元素*/
senout_(&(file[1]), &num_outputs, output);/*向AMESIM发送输出*/
}
return 0;
}
AMESIM 采用的是变步长仿真机制,每个仿真步长内,外部程序中的控制算法逻辑都会被执行一次。但是实际电液控制系统中,控制算法逻辑具有固定的控制周期,比如 0.01s, 即控制算法每 0.01s 才执行一次,输出也是每 0.01s 即更新一次。如果仿真步长与控制周期不一致(绝对会不一致),就极有可能导致仿真结果出现谬误。
为了解决上述问题,必须从 AMESIM 建模和控制策略实现两方面进行改进。首先,为DYNEXE0 模块增加一个仿真时间采样输入(必须使用零阶保持器),如下图所示。
并将采样器的采样时间设置为与控制周期一致。这样一来,AMESIM 的仿真步长就会被限制在控制周期以内(仿真步长不大于控制周期),且必然有一部分仿真时刻与控制时刻重合。
增加如下代码在每个循环里面进行判断。
double time = -1;
if(input[0] == time)//input[0]为仿真时间采样输入
{
senout_(&(file[1]), &num_outputs, output); //仿真时间与控制时间一致才发送输出。
continue; //跳过此次循环的剩余部分代码,进入下一次循环
}
time = input[0]; //将输入数据重新加载到 time 值里面