实验三离散化方法研究
一、实验目的
1.学习并掌握数字控制器的设计方法(按模拟系统设计方法与按离散设计方法);
2.熟悉将模拟控制器D(S)离散为数字控制器的原理与方法(按模拟系统设计方法);
3.通过数模混合实验,对D(S)的多种离散化方法作比较研究,并对D(S)离散化前后闭环系统的性能进行比较,以加深对计算机控制系统的理解。
二、实验设备
1.THBDC-1型控制理论·计算机控制技术实验平台
2.PCI-1711数据采集卡一块
3.PC机1台(安装软件“VC++”及“THJK_Server”)
三、实验原理
由于计算机的发展,计算机及其相应的信号变换装置(A/D和D/A)取代了常规的模拟控制。在对原有的连续控制系统进行改造时,最方便的办法是将原来的模拟控制器离散化。在介绍设计方法之前,首先应该分析计算机控制系统的特点。图3-1为计算机控制系统的原理框图。
图3-1 计算机控制系统原理框图
由图3-1可见,从虚线I向左看,数字计算机的作用是一个数字控制器,其输入量和输出量都是离散的数字量,所以,这一系统具有离散系统的特性,分析的工具是z变换。由虚线II向右看,被控对象的输入和输出都是模拟量,所以该系统是连续变化的模拟系统,可以用拉氏变换进行分析。通过上面的分析可知,计算机控制系统实际上是一个混合系统,既可以在一定条件下近似地把它看成模拟系统,用连续变化的模拟系统的分析工具进行动态分析和设计,再将设计结果转变成数字计算机的控制算法。也可以把计算机控制系统经过适当变换,变成纯粹的离散系统,用z变化等工具进行分析设计,直接设计出控制算法。
按模拟系统设计方法进行设计的基本思想是,当采样系统的采样频率足够高时,采样系统的特性接近于连续变化的模拟系统,此时忽略采样开关和保持器,将整个系统看成是连续变化的模拟系统,用s域的方法设计校正装置D(s),再用s域到z域的离散化方法求得离散传递函数D(z)。为了校验计算结果是否满足系统要求,求得D(z)后可把整个系统闭合而成离散的闭环系统。用z域分析法对系统的动态特性进行最终的检验,离散后的D(z)对D(s)的逼真度既取决于采样频率,也取决于所用的离散化方法。离散化方法虽然有许多,但各种离散化方法有一共同的特点:采样速率低,D(z)的精度和逼真度越低,系统的动态特性与预
定的要求相差就越大。由于在离散化的过程中动态特性总要变坏,人们将先设计D(s)再进行离散化的方法称为“近似方法”。
按离散设计方法设计的基本思想是,直接在z 域中用z 域频率响应法、z 域根轨迹法等方法直接设计数字控制器D(z)。由于离散设计方法直接在z 域设计,不存在离散化的问题,所以只要设计时系统是稳定的,即使采样频率再低,闭环系统仍然是稳定的。这种设计方法被称为“精确方法”。 本次实验使用按模拟系统设计方法进行设计。下面以一个具体的二阶系统来说明D(S)控制器的离散化方法。
1、二阶系统的原理框图如图3-2所示。
图3-2 二阶对象控制系统方框图
图3-3 二阶对象的模拟电路图
2、系统性能指标要求
系统的速度误差系数2≥v K ,超调量%10%≤δ,系统的调整时间1≤s t s
令校正后的开环传递函数为
)
2()(2
n n S S S G ξωω+=
根据公式2
1%100%e ζδ-
-=?,为满足%10%≤δ,取2
ζ=
可以满足要求。 根据公式3
s n
t ζω≈
,取5?=,为满足1≤s t s ,取32n ω=。
则校正后的开环传递函数为3
()(0.1671)
G s s s =
+,已知二阶对象传递函数为
05
()(0.51)
G s s s =
+,可用零极点抵消的方法来设计校正网络D(s),
所以校正网络s
s
S D 167.015.016.0)(++?
= 。
此时0
3
lim ()lim 32(0.1671)
v s s K s G s s
s s →→=?==>+,满足速度误差系数2≥v
K 的条件。
利用Simulink 对校正前后系统进行仿真,并记录阶跃响应曲线。
3、)(S D 的离散化算法
图3-4 数—模混合控制的方框图
图3-4中)(S D 的离散化可通过数据采集卡的采样开关来实现。 下面介绍几种按模拟系统设计的几种设计方法。 1)后向矩形规则法
后向矩形规则S 与Z 之间关系为
T
z S 1
1--=,代入D(S)表达式中得 111
1
167.0167.015.05.0167.06.01167
.0115
.016.0)(----+--+?+=-+-+?=Z T Z T T T
Z
T Z Z D 于是得
)1(167
.03
.0)(167.05.06.0)1(167.0167.0)(-+-++?+-+=
k e T k e T T k U T k U
2)双线性变换法
此时的转换关系为1
1
1121122
121--+-?=+-?=?-+
≈z z T S Z Z T S s T s T Z 或,代入D(s)得 )
1(334.0)1()1()1(6.011T 20.167111T 20.516.0D(Z)1
1111
111
---------++++-?=+-?
?++-??+=Z Z T T Z Z Z Z Z Z
1
1
1
1334.0334.01)1()1(334.06.0)334.0()334.0()1()1(6.0)(----+----+?+=--+--+?=Z T
T Z T T T Z
T T Z T T Z D
即 )1(334.016.0)(334.016.0)1(334.0334.0)(-+-?-++?+-+-=k e T
T
k e T T k U T T k U
3)冲激不变转换法 如果用零阶保持器,则
1()[()]sT
e D z D s s
--=Z
1()
()(1)[
]D s D z z s
-=-Z 根据前面已知10.5()0.610.167s
D s s
+=?+
则1
10.5()0.6(1)[
](10.167)
s
D z z s s -+=?-Z +
11 1.94
()0.6(1)[]5.88
D z z s s -=?-Z ++
5.881
5.881
2.94(1.94)()0.61T T e z D z e z -----+=?-
即 1)]-)e(k (1.94-2.94e(k)[6.01)-U(k U(k)88.588.5T T e e --+?+=
4)零极点匹配法
已知10.5()0.610.167s
D s s
+=?
+
极点16S =-,零点22S =-,
对应到Z 域,极点61T Z e -=,零点22T
Z e -=,
由于零点数等于极点数,故可省略匹配零点与极点相等这一步骤。
则在离散域传递函数变为26()
()T T
K z e D z z e ---=-
由10()|()|z s D z D s ===
得2610.61T T e K e ---?=-,求得6210.61T
T
e K e ---=?-,则
62621
26261
111()0.60.6111T T T T T T T T e z e e e z D z e z e e e z --------------?=??=??----? 即66221()(1)0.6[()(1)]1T
T
T T
e U k e U k e k e e k e
-----=-+??-?--
四、实验步骤
1、仔细阅读“PCI-1711数据采集卡驱动函数说明.doc ”和“THJK-Server 软件使用说明.doc ”文档,掌握PCI-1711数据采集卡的数据输入输出方法和THJK-Server 软件(及相关函数)的使用方法。
2、模拟电路接线图如图3-5所示:
图3-5 模拟电路接线图
下面解释硬件电平匹配电路存在的原因,由于PCI-1711卡的DA 输出只能为0~10V 的正电压,而实验中则需要输出-10~10V 的电压,故先将-10~10V 的输出电压o U 进行软件电压匹配,将其转换为0~10V 的正电压由DA1通道输出,转换关系为11
(10)2
DA o U U =+,如表3-1所示:
U 。 -10V -7.5V -5.0V -2.5V 0V 2.5V 5V 7.5V 10V DA1
0V
1.25V
2.5V
3.75V
5.0V
6.25V
7.5V
8.75V
10V
表3-1 o U (范围为-10V~10V )与1DA U (范围为0~10V )的对应关系
这样就把-10~10V 电压转换为0~10V 电压通过DA1通道输出了,然后再将此电压通过图3-5中的硬件电平匹配电路,还原为-10~10V 的电压,不难看出,此硬件电平匹配电路的转换关系为112(5)DA DA U U '=-,1DA U '为1DA U 在通过硬件匹配电路后的输出电压。
此电平匹配方法实际作用是克服了PCI-1711卡只能输出0~10V 单极性电压的不足。 3、用导线将系统的输入端连接到PCI-1711数据采集卡的“DA1”输出端,系统的输出端与数据采集卡的“AD1”输入端相连;
4、用导线将阶跃信号发生器输出端连接到PCI-1711数据采集卡的“AD2”输入端,作为阶跃触发使用,阶跃幅度由软件设定。初始时,+5V 电源开关处于“关”状态;
5、根据给定的性能指标要求,根据不同的方法设计离散化数字控制器(此步可在预习过程中做完)。
6、打开离散化实验文件夹下.dsw 工程文件,源程序中缺少数字控制器算法程序。请同学用设计好的数字控制器算法编写程序。
7、源程序编译通过后,先启动“THJK_Server”图形显示软件,再执行程序代码,在显示界面出现的曲线并稳定后(初始化后),把+5V电源打到“开”状态,观测并记录系统的阶跃响应曲线。在实验结束后,在键盘上先按下“e”,再按下“Enter(回车键)”键,程序退出。
8、采用不同的离散化方法,重复步骤6、7,比较采用各种离散化方法后的阶跃响应曲线。
9、利用Simulink对校正前后的系统进行仿真,并记录阶跃响应曲线,将校正前后曲线进行比较,并把校正后曲线与前面步骤7、8中采用数字控制器的实验曲线相比较;
五、实验报告要求
1、根据所给性能指标和对象传递函数,设计模拟系统中的控制器D(s)。
2、按模拟系统设计方法设计离散化数字控制器(需推导过程)。
3、编写按各种离散化方法设计的数字控制器的C++程序。
4、绘出二阶被控对象在采用不同离散化方法设计的数字控制器后的响应曲线,将它们相比较分析,并分析采样周期Ts的减小或增大对系统阶跃响应的影响。
5、绘出实验中二阶被控对象在加入模拟控制器前后的阶跃响应曲线(Simulink仿真),并与采用数字控制器的实验曲线相比较分析。
附录1
选取零极点匹配离散化方法之后的系统阶跃响应曲线:
附录2(源程序)
// discrete.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include "TH_Scope.h"
#include "driver.h"
//函数声明
void ErrorHandler( DWORD dwErrCde ); //通过错误代码来获取相应的错误信息函数
void ErrorStop( long*, DWORD ); //出错处理函数
bool init_1711(); //初始化设备函数
void expexit(); //退出函数
float ADinput(unsigned char chan); //模拟量输入函数
bool DAoutput(unsigned char chan,double DAdata); //模拟量输出函数
DWORD dwErrCde; //错误代码
ULONG lDevNum=0; //设备号
long lDriverHandle; //设备句柄
float fV oltage=0; //返回电压参数
PT_AIV oltageIn ptAIV oltageIn;
PT_AIConfig ptAIConfig;
PT_AOConfig ptAOConfig;
PT_AOV oltageOut ptAOV oltageOut;
float temp;
void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2);
double sv=0; //设定值
double output=0; //u(k)
double ei=0; //e(k)
const double Ts=0.1; //采样时间,即定时器的运行周期,实验时应与TH_SetTimer定时器的定时周期保持一致
char c;
//主函数
int main(int argc, char* argv[])
{
init_1711();
TH_Init();//与服务器端建立通讯
TH_SetTimer(100,(LPTIMECALLBACK) TimeProc, NULL); //控制程序的运行;100为控制器的控制周期100ms
printf("Press 'e' key to exit!\n"); //当控制算法没有正常运行时,可按下键盘上的字母“e”,再按回车,退出主程序
while (c=getc(stdin)!='e')
{
Sleep(10);
}
expexit();
return 0;
}
void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2) //控制函数
{
static double eix=0; //e(k-1)
static double opx=0; //u(k-1)
ADinput(1);
temp=fVoltage;
if(temp<4.9) //若开始信号未送出,即AD1的输入电压没达到5V,则不给阶跃信号输入,初始给定值为0V
{
ADinput(0);
sv=0;
}
else //若开始信号送出,则给定0V到4V的阶跃信号
{
ADinput(0);
sv=4;
}
// /*********控制器的编程
// 控制器的编程*********/
if (output>9.5) {output=9.5;} //控制量限幅,具体限幅值根据对象与给定值进行改变
if (output<-9.5) {output=-9.5;}
//AD采集值与控制给定值在服务器端的显示
TH_ChartY1(1,1,0.1,fV oltage); //示波器蓝线,表示系统输出值,即AD1通道电压值
TH_ChartY1(1,2,0.1,sv); //示波器红线,表示阶跃给定值
//在WIN32 控制台上显示变量值
printf("AD1:%.3f\n",fVoltage);
printf("DA1:%.3f\n",output); //控制台上显示控制量值
printf("ei:%.3f\n",ei); //控制台上显示误差计算值
//采集卡DA输出
DAoutput(0,(10+output)/2); //(10+output)/2为软件电平匹配
}
void ErrorHandler ( DWORD dwErrCde ) //通过错误代码来获取相应的错误信息函数
{
char szErrMsg[ 180 ];
DRV_GetErrorMessage( dwErrCde, szErrMsg );
printf( "\n Error( %d ): %s\n", dwErrCde& 0xffff, szErrMsg );
}
void ErrorStop( long *pDrvHandle, DWORD dwErrCde ) //出错处理函数
{
//取得错误信息
ErrorHandler( dwErrCde );
printf( "Program terminated!\n" );
//关闭设备
DRV_DeviceClose( pDrvHandle );
exit( 0 );
}
bool init_1711() //初始化设备函数
{
dwErrCde = DRV_DeviceOpen( lDevNum,&lDriverHandle ); //设备打开函数,并取得设备句柄
if ( dwErrCde != SUCCESS ) //检测是否打开成功,如果打不开,他会提供原因
{
ErrorHandler( dwErrCde );
printf("Program terminated!\n" );
return false;
}
DAoutput(0,5);
DAoutput(1,5); //DA通道输出置0
printf("设备号:%d\n",lDevNum);
printf("设备句柄:%d\n",&lDriverHandle);
printf("\n");
return true;
}
float ADinput(unsigned char chan) /* chan是通道号*/
{
ptAIConfig.DasChan = chan;
ptAIConfig.DasGain = 0;
dwErrCde = DRV_AIConfig(lDriverHandle,(LPT_AIConfig)&ptAIConfig);
if( dwErrCde != SUCCESS)//检测是否打开成功
{
ErrorStop( &lDriverHandle, dwErrCde );
return false;
}
ptAIVoltageIn.chan = chan; // 输入通道
ptAIVoltageIn.gain = 0; // 增益代码,可参考手册的电压范围,0为+/-10V
ptAIVoltageIn.TrigMode = 0; // 触发方式0: 内触发器,1: 外触发器
ptAIVoltageIn.voltage = &fV oltage; // 返回的电压
dwErrCde = DRV_AIV oltageIn(lDriverHandle, &ptAIVoltageIn);
if ( dwErrCde != SUCCESS )
{
ErrorStop( &lDriverHandle, dwErrCde );
return false;
}
return (fVoltage);
}
bool DAoutput(unsigned char chan,double DAdata)/* chan是通道号*/
{
ptAOConfig.chan = chan;
ptAOConfig.RefSrc = 0;
ptAOConfig.MaxValue=10;
ptAOConfig.MinValue=-10;
dwErrCde = DRV_AOConfig(lDriverHandle,(LPT_AOConfig)&ptAOConfig);
if( dwErrCde != SUCCESS)//检测是否打开成功
{
ErrorStop( &lDriverHandle, dwErrCde );
return false;
}
ptAOVoltageOut.chan = chan;
ptAOVoltageOut.OutputValue = DAdata;
dwErrCde = DRV_AOV oltageOut(lDriverHandle, &ptAOV oltageOut);
if ( dwErrCde != SUCCESS )
{
ErrorStop( &lDriverHandle, dwErrCde );
return false;
}
return true;
}
void expexit() //退出函数
{
DAoutput(0,5);
DAoutput(1,5);
TH_KillTimer();
dwErrCde = DRV_DeviceClose( &lDriverHandle );
if ( dwErrCde!=SUCCESS ) //监测是否关闭成功
{
ErrorStop(&lDriverHandle, dwErrCde );
return;
}
TH_Realese();
printf("系统退出!\n");
}