DiscreteObserverDesigner.java
/*
* $Id: DiscreteObserverDesigner.java,v 1.4 2008/03/30 00:30:47 koga Exp $
*
* Copyright (C) 2004 Koga Laboratory. All rights reserved.
*
*/
package org.mklab.tool.control.system.controller;
import java.util.List;
import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.RealNumericalScalar;
import org.mklab.tool.control.C2d;
import org.mklab.tool.control.system.LinearSystemOperator;
import org.mklab.tool.control.system.discrete.DiscreteLinearDynamicSystem;
/**
* 連続時間オブザーバを離散化した離散時間オブザーバを求めるクラスです。
*
* @author koga
* @version $Revision: 1.4 $, 2004/05/31
* @param <RS> type of real scalar
* @param <RM> type of real matrix
* @param <CS> type of complex scalar
* @param <CM> type of complex matrix
*/
public class DiscreteObserverDesigner<RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> {
/** サンプリング周期[s] */
private RS samplingInterval;
/** 連続時間オブザーバーの設計器 */
private ObserverDesigner<RS,RM,CS,CM> observerDesigner;
/** サンプリング周期が設定済みならばtrue、そうでなければfalse */
private boolean samplingIntervalAvailable;
/** 離散時間オブザーバー */
private DiscreteLinearDynamicSystem<RS,RM,CS,CM> observer;
/** unit of scalar */
private RS sunit;
/**
* コンストラクター
*
* @param plant 状態推定の対象(連続時間線形システム)
*/
public DiscreteObserverDesigner(LinearSystemOperator<RS,RM,CS,CM> plant) {
this.sunit = plant.getA().getElement(1,1).createUnit();
this.observerDesigner = new ObserverDesigner<>(plant);
}
/**
* 離散時間オブザーバを返します。
*
* @return 離散時間オブザーバ
*/
public DiscreteLinearDynamicSystem<RS,RM,CS,CM> getObserver() {
design();
return this.observer;
}
/**
* 連続時間オブザーバを離散化した離散時間オブザーバを求めます。
*/
private void design() {
final LinearSystemOperator<RS,RM,CS,CM> cObserver = this.observerDesigner.getObserver();
final List<RM> ab = C2d.c2d(cObserver.getA(), cObserver.getB(), this.samplingInterval);
this.observer = new DiscreteLinearDynamicSystem<>(ab.get(0), ab.get(1), cObserver.getC(), cObserver.getD(), this.sunit);
this.observer.setSamplingInterval(this.samplingInterval);
}
/**
* サンプリング周期を設定します。
*
* @param samplingInterval サンプリング周期
*/
public void setSamplingInterval(RS samplingInterval) {
this.samplingInterval = samplingInterval;
this.samplingIntervalAvailable = true;
}
/**
* 連続時間オブザーバーの極を設定します。
*
* @param continuousObserverPoles 連続時間オブザーバーの極
*/
public void setContinuousObserverPoles(CM continuousObserverPoles) {
this.observerDesigner.setObserverPoles(continuousObserverPoles);
}
/**
* オブザーバの係数行列を表示します。
*/
@SuppressWarnings("nls")
public void showObserver() {
design();
final int inputSize = this.observerDesigner.getPlantInputSize();
final int outputSize = this.observerDesigner.getPlantOutputSize();
final RM Ahd = this.observer.getA();
final RM Jhd = this.observer.getB().getColumnVectors(1, inputSize);
final RM Bhd = this.observer.getB().getColumnVectors(inputSize + 1, inputSize + outputSize);
final RM Chd = this.observer.getC();
final RM Dhd = this.observer.getD().getColumnVectors(inputSize + 1, inputSize + outputSize);
Ahd.print("Ahd");
System.out.println("");
Jhd.print("Jhd");
System.out.println("");
Bhd.print("Bhd");
System.out.println("");
Chd.print("Chd");
System.out.println("");
Dhd.print("Dhd");
System.out.println("");
}
//
// /**
// * メインメソッド
// *
// * @param args
// * コマンドライン引数
// */
// public static void main(String[] args) {
// RM observerPoles = new DoubleComplexMatrix(new double[] {-20, -20}, new
// double[] {0, 0}).transpose();
// double samplingInterval = 0.005;
// DiscreteObserverDesigner dDesigner = new DiscreteObserverDesigner(new
// LinearSinglePendulum());
// dDesigner.setSamplingInterval(samplingInterval);
// dDesigner.setContinuousObserverPoles(observerPoles);
// dDesigner.showObserver();
// }
/**
* オブザーバーの極とサンプリング周期が設定済みで、オブザーバーが設計可能であるか判定します。
*
* @return オブザーバーが設計可能であればtrue、そうでなければfalse
*/
public boolean isAvailable() {
return this.samplingIntervalAvailable && this.observerDesigner.isAvailable();
}
}