Processingでグラフを描画するRTCを実行し、Raspberry Piマウスの移動軌跡をグラフに描画するシステムの作成します。

下記の仕様で、RTCBuilderでdrawGraphコンポーネントを作成します。
| コンポーネント名称 | drawGraph |
| アクティビティ | onActivated、onExecute |
| 言語 | Processing |
| InPort | |
| ポート名 | in |
| 型 | RTC::TimedPose2D |
RTC::CameraImage型は2次元平面状のを位置・姿勢を表現したデータ型です。
struct Point2D
{
/// X coordinate in metres.
double x;
/// Y coordinate in metres.
double y;
};
struct Pose2D
{
/// 2D position.
Point2D position;
/// Heading in radians.
double heading;
};
まずは、ProcessingのIDE(統合開発環境)を起動します。
Processingのリポジトリから開発環境一式をダウンロードしてください。
展開したフォルダのprocessing.exeを実行してください。
Javaのバージョンの問題により、OpenRTM-aistをProcessing 4.0以降の環境では現在のところ実行はできません。
講習会などでUSBメモリの資料を配布している場合は、以下のファイルを実行してください。
実行すると、以下の統合開発環境のGUIが起動します。

ProcessingでOpenRTM-aistの機能が使えるようにライブラリをインストールします。
まず、Processingでスケッチブックの場所を確認します。 「ファイル」->「設定」を選択して表示される画面で確認できます。

スケッチブックの場所のlibrariesフォルダに、以下のOpenRTMUtil.zipを展開したフォルダをコピーします。
※講習会などではUSBメモリ内のProcessing\OpenRTMUtilフォルダを使用します。
コピーすると、以下のようなディレクトリ構成になります。
スケッチブックの場所
├ examples
├ modes
├ templates
├ tools
└ libraries
└ OpenRTMUtil
└ library
├ commons-cli-1.1.jar
├ jna-4.2.2.jar
├ jna-platform-4.2.2.jar
├ LogicalTimeTriggeredEC.jar
├ NameserviceFile.jar
├ OpenRTM-aist-2.1.0.jar
├ OpenRTMUtil.jar
├ rtcd.jar
└ rtcprof.jarグラフ描画用ライブラリのgraficaをインストールします。
Processingで「スケッチ」→「ライブラリをインポート」→「ライブラリを追加」をクリックしてください。


ProcessingでRTCのプログラミングを行います。
RTCBuilderで生成したソースコードの、drawGraphMain.pdeをProcessingで開いてください。 drawGraphMain.pdeをprocessing.exeにドラッグアンドドロップすれば開けます。
Processingのエディタから、drawGraphMain.pdeのsetup関数に画面サイズ、フレームレートの設定処理を追加します。
public void setup() {
//ウィンドウサイズを設定
size(300, 300); //追加
frameRate(10); //追加次に、drawGraphImpl.pdeを編集します。 下記のようにgrafinaライブラリのインポート文を追加してください。
import RTC.ReturnCode_t; import grafica.*; //追加
次に、下記の変数dataを宣言します。変数dataに受信した位置姿勢データが格納されます。
protected InPort<TimedPose2D> m_inIn;
//グラフに描画する点のデータを格納する配列を宣言
GPointsArray data; //追加onActivated関数を下記のように編集します。
@Override
protected ReturnCode_t onActivated(int ec_id) {
//配列dataの初期化
data = new GPointsArray();
return super.onActivated(ec_id);
}最後にonExecute関数を下記のように編集します。
@Override
protected ReturnCode_t onExecute(int ec_id) {
//InPortでデータを受信した時の処理
if (m_inIn.isNew())
{
//受信データの読み込み
m_inIn.read();
//配列dataに取得した位置を追加する
data.add((float)m_in.v.data.position.x,
(float)m_in.v.data.position.y);
//配列の大きさが1000を超えた場合、古いデータは捨てる
if (data.getNPoints() > 1000)
{
data.remove(0);
}
}
//グラフをウィンドウの(0,0)から(300,300)の範囲に描画する
GPlot plot = new GPlot(m_applet, 0, 0, 300, 300);
//グラフの縦軸、横軸の上限、下限を設定する
plot.setXLim(-1.0, 1.0);
plot.setYLim(-1.0, 1.0);
plot.setFixedXLim(true);
plot.setFixedYLim(true);
//配列dataをグラフに設定する
plot.addPoints(data);
//グラフの描画を開始する
plot.beginDraw();
//グラフに外枠、座標、折れ線、縦軸、横軸を描画する
plot.drawBox();
plot.drawPoints();
plot.drawLines();
plot.drawXAxis();
plot.drawYAxis();
//グラフの描画を終了する
plot.endDraw();
return super.onExecute(ec_id);
}作成したdrawGraphコンポーネントの動作確認を行います。
Raspberry Piマウスシミュレータ(RaspberryPiSimulator)、もしくはRaspberry Piマウス実機(RaspberryPiMouseRTC)のRTCを使用します。 また、以下のチュートリアルで作成したRobotControllerも使用します。
Processingで作成したdrawGraphコンポーネントを起動します。 Processingの実行ボタンを押してください。


Processing 4.0以降はJavaのバージョンの関係でOpenRTM-aist Javaが動作しませんが、以下の手順でORB実装の代替ライブラリを入手する事で対応可能です。 以下の手順でJARファイルを取得してください。
以下のようにOpenRTMUtil/libraryフォルダにJARファイルをコピーして完了です。
スケッチブックの場所
├ examples
├ modes
├ templates
├ tools
└ libraries
└ OpenRTMUtil
└ library
├ openjdk-orb-10.1.3.Final.jar
└ jakarta.transaction-api-2.0.1.jarOpenRTM-aist 2.0以前にはProcessingのコード生成機能がないため、下記のOpenRTMUtilライブラリを使ったソースコードが必要です。
Processingの開発環境で以下のコードを入力してください。 Processingでは実行開始時に1度だけ呼ばれるsetup関数、一定間隔で呼ばれるdraw関数を使用します。 setup関数でRTCの生成を実行しています。 draw関数でInPortのデータの読み込みとグラフの描画更新処理を実行しています。
import grafica.*;
import jp.go.aist.rtm.OpenRTMUtil;
import jp.go.aist.rtm.RTC.port.InPort;
import jp.go.aist.rtm.RTC.util.DataRef;
import RTC.TimedPose2D;
import RTC.Pose2D;
import RTC.Point2D;
import RTC.Time;
//データ、InPortの変数を宣言
DataRef<TimedPose2D> indata;
InPort<TimedPose2D> inport;
//グラフに描画する点のデータを格納する配列を宣言
GPointsArray data;
public void setup() {
//ウィンドウサイズを設定
size(300, 300);
//RTCを"drawGraph"というインスタンス名で生成
OpenRTMUtil util = new OpenRTMUtil();
util.createComponent("drawGraph");
//データの初期化
TimedPose2D val = new TimedPose2D();
val.tm = new Time();
val.data = new Pose2D();
val.data.position = new Point2D();
indata = new DataRef<TimedPose2D>(val);
//InPortを"pose"という名前で生成
inport = util.addInPort("pose", indata);
//配列dataの初期化
data = new GPointsArray();
}
int count = 0;
public void draw() {
//InPortでデータを受信した時の処理
if (inport.isNew())
{
//受信データの読み込み
inport.read();
//配列dataに取得した位置を追加する
data.add((float)indata.v.data.position.x, (float)indata.v.data.position.y);
//配列の大きさが1000を超えた場合、古いデータは捨てる
if (data.getNPoints() > 1000)
{
data.remove(0);
}
}
//グラフをウィンドウの(0,0)から(300,300)の範囲に描画する
GPlot plot = new GPlot(this, 0, 0, 300, 300);
//グラフの縦軸、横軸の上限、下限を設定する
plot.setXLim(-1.0, 1.0);
plot.setYLim(-1.0, 1.0);
plot.setFixedXLim(true);
plot.setFixedYLim(true);
//配列dataをグラフに設定する
plot.addPoints(data);
//グラフの描画を開始する
plot.beginDraw();
//グラフに外枠、座標、折れ線、縦軸、横軸を描画する
plot.drawBox();
plot.drawPoints();
plot.drawLines();
plot.drawXAxis();
plot.drawYAxis();
//グラフの描画を終了する
plot.endDraw();
}