DoubleDiscreteObserverDesigner.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.DoubleComplexMatrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.tool.control.C2d;
import org.mklab.tool.control.system.DoubleLinearSystemOperator;
import org.mklab.tool.control.system.DoubleSystemOperator;
import org.mklab.tool.control.system.discrete.DoubleDiscreteLinearDynamicSystem;


/**
 * 連続時間オブザーバを離散化した離散時間オブザーバを求めるクラスです。
 * 
 * @author koga
 * @version $Revision: 1.4 $, 2004/05/31
 */
public class DoubleDiscreteObserverDesigner {

  /** サンプリング周期[s] */
  private double samplingInterval;
  /** 連続時間オブザーバーの設計器 */
  private DoubleObserverDesigner observerDesigner;
  /** サンプリング周期が設定済みならばtrue、そうでなければfalse */
  private boolean samplingIntervalAvailable;
  /** 離散時間オブザーバー */
  private DoubleDiscreteLinearDynamicSystem observer;

  /**
   * コンストラクター
   * 
   * @param plant 状態推定の対象(連続時間線形システム)
   */
  public DoubleDiscreteObserverDesigner(DoubleSystemOperator plant) {
    this.observerDesigner = new DoubleObserverDesigner(plant);
  }

  /**
   * 離散時間オブザーバを返します。
   * 
   * @return 離散時間オブザーバ
   */
  public DoubleDiscreteLinearDynamicSystem getObserver() {
    design();
    return this.observer;
  }

  /**
   * 連続時間オブザーバを離散化した離散時間オブザーバを求めます。
   */
  private void design() {
    final DoubleLinearSystemOperator cObserver = this.observerDesigner.getObserver();
    final List<DoubleMatrix> ab = C2d.c2d(cObserver.getA(), cObserver.getB(), this.samplingInterval);
    this.observer = new DoubleDiscreteLinearDynamicSystem(ab.get(0), ab.get(1), cObserver.getC(), cObserver.getD());
    this.observer.setSamplingInterval(this.samplingInterval);
  }

  /**
   * サンプリング周期を設定します。
   * 
   * @param samplingInterval サンプリング周期
   */
  public void setSamplingInterval(double samplingInterval) {
    this.samplingInterval = samplingInterval;
    this.samplingIntervalAvailable = true;
  }

  /**
   * 連続時間オブザーバーの極を設定します。
   * 
   * @param continuousObserverPoles 連続時間オブザーバーの極
   */
  public void setContinuousObserverPoles(DoubleComplexMatrix continuousObserverPoles) {
    this.observerDesigner.setObserverPoles(continuousObserverPoles);
  }

  /**
   * オブザーバの係数行列を表示します。
   */
  @SuppressWarnings("nls")
  public void showObserver() {
    design();

    final int inputSize = this.observerDesigner.getPlantInputSize();
    final int outputSize = this.observerDesigner.getPlantOutputSize();

    final DoubleMatrix Ahd = this.observer.getA();
    final DoubleMatrix Jhd = this.observer.getB().getColumnVectors(1, inputSize);
    final DoubleMatrix Bhd = this.observer.getB().getColumnVectors(inputSize + 1, inputSize + outputSize);
    final DoubleMatrix Chd = this.observer.getC();
    final DoubleMatrix 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) {
  // DoubleMatrix 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();
  }

}