制御対象を連続時間系でモデル化して制御器を設計した場合には、制御器が連続時間系の表現で記述されるため計算機に直接実装することができません。そのため、離散化処理を介して実装可能な形式で表現する必要があります。双一次変換は実現したい連続時間系の入出力伝達関数から離散時間系の入出力伝達関数を導出する際に使用できます。
ラプラス変換によって時間遅れ要素は以下のように線形作用素として表現されました。
L[x(t)]≡X(s)⇒L[x(t−L)]=e−sLX(s)
ここでサンプリング間隔を
Ts 、信号
x(t)の
n ステップ分の時間が遅れた信号を
xn(t) とすると、そのラプラス変換は次のように表現されます。
xn(t)⇔L[xn(t)]≡x(t−nTs)=e−snTsX(s)
計算機で扱える信号はサンプルされた信号のみとなり、離散信号のみから所望の伝達特性を実現しなければなりません。そこで、シフトオペレータ
z≡esTs を導入し、伝達関数を
z を用いて表現することを目指します。
z を用いて伝達関数を表現することは時間遅れ要素のみを用いて伝達関数を表現することであり、過去のサンプルを使用して所望の伝達特性を近似的に実現可能であることを示しています。シフトオペレータの定義より、
s は
z を使用して次のように表現されます。
s=Ts1log(z)=Ts2tanh−1(z+1z−1)=Ts2n=0∑∞2n+11(z+1z−1)2n+1
級数展開を一次で打ち切った場合の結果が双一次変換となります。
s=Ts2z+1z−1+Ts2n=1∑∞2n+11(z+1z−1)2n+1≈Ts2z+1z−1
ここで、実現したい伝達関数
Gc(s) に対して離散化伝達関数
Gd(z) は以下のように導出されます。
Gd(z)=Gc(Ts2z+1z−1)
計算機で実装する場合には過去の信号のみが使用可能であることを考慮して、次の形式で導出することもできます。
Gd(z)=Gc(Ts21+z−11−z−1)
離散化伝達関数は実現したい伝達関数を時間遅れ要素を用いて表現したものとなります。シフトオペレータの定義より以下の式が成立することを利用して、実装方法を確認します。
L−1[z−nX(s)]=xn(t)
入出力伝達特性が次のように表現される場合について考えます。
Y(s)Gd(z)=Gd(z)X(s)=1+a1z−1+⋯+aqz−qb0+b1z−1+⋯+bpz−p
この式を整理することで、次の関係式を得ます。
∴ (1+i=1∑qaiz−i)Y(s)=i=0∑pbiz−iX(s)Y(s)=i=0∑pbiz−iX(s)−i=1∑qaiz−iY(s)
ここで、逆ラプラス変換を用いることで時系列の関係が導出されます。
y(t)=i=0∑pbixi(t)−i=1∑qaiyi(t)
計算機上では上記の式を離散化して実装する必要があります。任意のサンプル点
k を基点として、その点におけるサンプル値を
x[k] および
y[k]、
n ステップ前のサンプル値を
x[k−n] および
y[k−n] と表現すれば、サンプル値には次の関係が成立します。
y[k]=i=0∑pbix[k−i]−i=1∑qaiy[k−i]
ここではシンプルな低域通過フィルタの設計例を示します。以下の低域通過特性を示す伝達関数を考えます。
Gc(s)=s+gg
ここで、
g∈R>0 は遮断周波数
[rad/s] を表します。離散化伝達関数は次のように表現されます。
Gd(z)=Gc(Ts21+z−11−z−1)=(2+gTs)+(−2+gTs)z−1gTs(1+z−1)
このフィルタの入力を
x、出力を
y とすると、以下の関係が成立します。
⇔ ⇔ ((2+gTs)+(−2+gTs)z−1)Y(s)=gTs(1+z−1)X(s)Y(s)=2+gTsgTs(1+z−1)X(s)+2+gTs2−gTsz−1Y(s)y[k]=2+gTsgTs(x[k]+x[k−1])+2+gTs2−gTsy[k−1]
以下に設計した低域通過フィルタのクラスを例示します。
class LowPassFilter {
private:
double Ts;
double g;
double xZ1;
double yZ1;
double coeff[2];
public:
LowPassFilter(double gn, double SmplTime);
~LowPassFilter();
double Output(double x);
void ClearStateVars(void);
};
#include "LowPassFilter.h"
LowPassFilter::LowPassFilter(double gn, double SmplTime): Ts(SmplTime), g(gn) {
xZ1 = 0;
yZ1 = 0;
coeff[0] = g * Ts / (2.0 + g * Ts);
coeff[1] = (2.0 - g * Ts) / (2.0 + g * Ts);
}
LowPassFilter::~LowPassFilter() {
}
double LowPassFilter::Output(double x) {
double y = coeff[0] * (x + xZ1) + coeff[1] * yZ1;
xZ1 = x;
yZ1 = y;
return y;
}
void LowPassFilter::ClearStateVars(void) {
xZ1 = 0;
yZ1 = 0;
}
このクラスの使用例は以下のようになります。
#include "LowPassFilter.h"
int main (void) {
const double Ts = 1e-3; // Sampling time
const double gn = 20.0; // Cutoff frequency
double t = 0.0;
double x = 0.0;
double y = 0.0;
// Instance
static LowPassFilter* LPF = new LowPassFilter(gn, Ts);
for (int i = 0; i < 5e4; i++) {
x = (t > 1.0)? 1.0 : 0.0;
y = LPF -> Output(x);
t += Ts;
}
delete LPF;
return 0;
}