セック ロボットサイト - 機能拡張

機能拡張

実行コンテキストの拡張

OpenRTM.NETでは、標準で用意されているPeriodicExecutionContext、ExtTriggerExecutionContext、EmptyExecutionContextに加え、 コンポーネント開発者が新たに実行コンテキストを実装することができます。 実行コンテキストを実装するためには、PeriodicExecutionContextやExecutionContextBaseなどのクラスを継承し、 OpenRTM.Core.ExecutionContextAttributeカスタム属性を付与します。

実行コンテキストの実装

using System;
using OpenRTM.Core;

namespace Examples
{
    [ExecutionContext("SingleExecutionContext", InstanceMode = InstanceMode.Single)]
    public class SingleExecutionContext : PeriodicExecutionContext
    {
    }
}

InstanceModeを指定すると、実行コンテキストのインスタンスの生成方式を指定することができます。

実行コンテキストのインスタンスモード
モード 説明
PerComponent コンポーネントのインスタンス1つごとに実行コンテキストのインスタンスを1つ生成する。(デフォルト)
PerThread スレッドごとに実行コンテキストのインスタンスを1つ生成する。
Single プロセスで1つだけ実行コンテキストのインスンタスを生成する。

拡張した実行コンテキストを利用するためには、ComponentAttributeで名前もしくは型を指定します。

実行コンテキストの指定方法(文字列で指定)

using System;
using OpenRTM.Core;

namespace Examples
{
    [Component(ExecutionContext = "SingleExecutionContext")]
    public class SingleECComponent : DataFlowComponent
    {
    }

}

実行コンテキストの指定方法(型で指定)

using System;
using OpenRTM.Core;

namespace Examples
{
    [Component(ExecutionContextType = typeof(SingleExecutionContext))]
    public class SingleECComponent : DataFlowComponent
    {
    }

}

また、rtc.configで使用する実行コンテキストを指定することもできます。

バッファの拡張

OpenRTM.NETのデータポートでは、データを保持するためのバッファを拡張することができます。 デフォルトでは、RingBufferとNullBufferが利用されていますが、必要に応じて固定長のバッファや、キューのような機能を持つバッファを実装することができます。 バッファを拡張する場合には、BufferBaseクラスを継承したクラスを作成することになります。 BufferBaseクラスは抽象クラスであり、継承先のクラスは以下に示すメソッドをすべてオーバーライドする必要があります。

BufferBaseのメソッド定義
メソッド 説明
public int Length バッファの長さを取得するプロパティ
public Boolean Create( int length ) バッファを生成するメソッド
public Boolean IsFull() バッファが一杯かどうかを返すメソッド
public Boolean IsEmpty() バッファが空かどうかを返すメソッド
public void Put( TDataType data ) バッファにデータを書き込むメソッド
public TDataType Get() バッファからデータを取得するメソッド

拡張バッファの実装例を以下に示します。この例では、キューを実装しています。

バッファ拡張の実装例

public class FifoBuffer<TDataType> : BufferBase<TDataType>
{
    private Queue<TDataType> buffer;
    private int capasity;

    public override int Length
    {
        get { return buffer.Count; }
    }

    public override bool Create(int length)
    {
        buffer = new Queue<TDataType>(length);
        capasity = length;
        return true;
    }

    public override bool Put(TDataType value)
    {
        if (IsFull) return false;
        buffer.Enqueue(value);
        return true;
    }

    public override bool Get(out TDataType value)
    {
        value = buffer.Dequeue();
        return true;
    }

    public override bool IsFull
    {
        get { return buffer.Count == capasity - 1; }
    }

    public override bool IsEmpty
    {
        get { return buffer.Count == 0; }
    }

    public void Clear()
    {
        buffer.Clear();
    }
}

拡張したバッファを利用するためには、OutPortまたはInPortの2番目の型パラメータに、バッファの型を指定します。

拡張バッファの利用

[InPort]
InPort<TimedString,FifoBuffer<TimedString>> inport
    = new InPort<TimedString, FifoBuffer<TimedString>>(10);

また、Bufferプロパティを経由すれば、バッファ独自のメソッドをデータポートから利用することが可能になります。

拡張バッファの独自メソッドの利用

inport.Buffer.Clear();

さらに拡張メソッドを用意すると、inport.Clear()と呼び出すことができます。 RingBufferにおけるIsNewメソッドやGetNewDataListメソッドなどは、拡張メソッドとして実装されています。

バッファの拡張メソッド

public static class FifoBufferExtension
{
    public static bool Clear<TDataType>(
            this InPort<TDataType, FifoBuffer<TDataType>> buff)
    {
        return buff.Buffer.Clear();
    }
}