DoubleFixedRateAsynchronousSource.java

/*
 * Created on 2010/01/04
 * Copyright (C) 2010 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.tool.control.system.source;

import org.mklab.nfc.matrix.DoubleMatrix;


/**
 * 等間隔のサンプリングを行うソースです。
 * 
 * @author Yuhi Ishikura
 * @version $Revision$, 2010/01/04
 */
public abstract class DoubleFixedRateAsynchronousSource extends DoubleAsynchronousSource {

  /** 全出力データです。 */
  private double[] outputData;
  /** 出力データ配列中の次に記録するインデックスです。 */
  private int outputIndex;
  /** 次に記録するデータの時間です。 */
  private double time;
  /** データの時間の間隔、サンプリングインターバルです。 */
  private double interval;

  /**
   * {@link DoubleFixedRateAsynchronousSource}オブジェクトを構築します。
   * 
   * @param size サイズ
   * @param interval データの時間の間隔、サンプリングインターバル
   */
  public DoubleFixedRateAsynchronousSource(int size, double interval) {
    super(1);
    this.outputData = new double[size];
    this.interval = interval;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected final DoubleMatrix getOutput(double t) {
    if (isReadyFor(t) == false) {
      throw new IllegalStateException(Messages.getString("FixedRateAsynchronousSource.1")); //$NON-NLS-1$
    }

    final int index = (int)(t / this.interval);
    if (index >= this.outputData.length) {
      throw new IndexOutOfBoundsException(Messages.getString("FixedRateAsynchronousSource.0")); //$NON-NLS-1$
    }

    return new DoubleMatrix(new double[] {this.outputData[index]});
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected final boolean isReadyFor(double t) {
    return t < this.time;
  }

  /**
   * 出力データがいっぱいであるかを調べます。
   * 
   * @return これ以上記録できない場合はtrue,そうでなければfalse
   */
  protected final boolean isOutputDataFilled() {
    return this.outputIndex >= this.outputData.length;
  }

  /**
   * 出力を追加します。
   * 
   * @param output 出力
   */
  protected final void publish(double output) {
    if (isOutputDataFilled()) {
      throw new IllegalStateException();
    }
    this.outputData[this.outputIndex] = output;
    this.outputIndex++;
    this.time += this.interval;

    bufferChanged();
  }

}