UEC Tokyo Dept. of Mechanical Engineering and Intelligent Systems OpenRTM を使ってみよう! - 基本編 ( コンソール版 )- 電気通信大学情報理工学研究科 知能機械工学専攻 長井隆行 中村友昭
RTM とは Robot Technology Middleware コンポーネント ( モジュール ) を動かす実行環境のこと ミドルウェア上で動作するコンポーネントであれば OS 言語等に関係なく通信が可能 DiGORO ClientNet+ サーバー (DiGORO.net) に相当 RTM 上で動くものであれば 他の人が作成したコンポーネントを使用できる ( 再利用性が高い ) チャットコンポーネント 1 チャットコンポーネント 2 カメラ音声アーム台車 RT ミドルウェア Windows, C# Linux, C++ RT ミドルウェア RTM よるロボットの構成 2
OpenRTM 3 RTMの実装の1つ DiGORO.net, ROS, OpenRTM 等がある DiGORO.net : 長井研ローカル 再利用性低い ROS : Windowsのサポートがいまいち OpenRTM : 国産 様々なOSに対応 資料が日本語 OpenRTM と DiGORO.net の違い DiGORO.net 単純なデータの送信のみをサポート OpenRTM データだけでなく機能を変更するようなクラスも送受信可能 その他いろんな機能があるみたい GUIでコンポーネントを接続( 後述 )
開発言語 OpenRTM-aist オリジナルのOpenRTMで産総研が開発 C++, Python, Javaに対応 なんか使いづらい OpenRTM.Net, PyRTSeam 株式会社セックが改良 (http://www.sec.co.jp/robot/) C#, C++/CLI, Python 非常に使いやすいが C++ が使えない とりあえず OpenRTM.NET の C++/CLI で作ってみよう! C++/CLI C++ と互換性あり この先 どの言語を使うかはご自由に 4
C++/CLI C++ / Common Language Interface C++ と.Net(MS が作った言語 ) が同時に使用可能.Net の概要 関数は存在せず全てクラスになっている int, float, double 等数値 ( 数値型 ) 以外は全てクラス ( 参照クラス ) int, float, double 等数値型も実はクラス ( ボックス化 ).Net のクラスの宣言には ^ を付ける ( 参照クラス = 高機能ポインタ ) C++ : Class c;.net : Class ^c;.net のクラスは gcnew(garbage collection new) しなければならない ( ポインタと同じなので生成が必要 ) Class ^c = gcnew Class(); gcnew は delete の必要はない ( しても良い ) 5
C++/CLI 例 :C++ と.Net を同時使用した例 int arr1[10]; array<int> ^arr2 = gcnew array<int>(10); // C++ 配列の宣言 //.Netの配列クラスの宣言 // 代入 for(int i=0 ; i<10 ; i++ ){ arr1[i] = i; arr2[i] = i; } // 表示 for(int i=0 ; i<10 ; i++ ){ printf("%d %d n", arr1[i], arr2[i] ); } 6
インストール 以下の 2 つを順にインストール OpenRTM-aist-1.1.0-RELEASE_vc9.msi http://www.openrtm.org/openrtm/ja/node/5012 OpenRTM.NET-1.3.0.msi http://www.sec.co.jp/robot/download_rtm.html Java を最新版にする http://www.java.com/ja/ 実験 PC はインストール済みなので必要ない 7
サンプルの起動 ネーミングサービスの開始 [ スタータ ] [ プログラム ] [OpenRTM.Net] [ ツール ] [ ネーミングサービスの開始 ] コンポーネント起動 [ スタータ ] [ プログラム ] [OpenRTM.Net] [ サンプル ] [ バイナリ ] SimpleIO ConsoleIn ConsoleIn.Exe SimpleIO ConsoleOut ConsoleOut.Exe コンポーネント接続プログラムを起動 [ スタータ ] [ プログラム ] [OpenRTM-aist 1.1] [C++] [tools] [RTSystemEditor] 8
RT System Editor コンポーネント同士を接続するための GUI プログラム ON にする 現在起動中のコンポーネント 2 つのコンポネントをドラッグアンドドロップ 9
コンポーネントの接続 1/3 コンポーネント同士の入力ピンと出力ピンの接続 出力ピン 一方のピンをドラッグし もう一方のピンへドロップ 入力ピン 10
コンポーネントの接続 2/3 コンポーネント同士の入力ピンと出力ピンの接続 出力ピン 入力ピン 11
コンポーネントの接続 3/3 コンポーネント同士の入力ピンと出力ピンの接続 出力ピン 右クリック All Activate 入力ピン 12
コンポーネントの通信 ConsoleIn I/F name: ConsoleIn0.out I/F type: IDL:RTC/TimedLong:1.0 Polarity: PROVIDED I/F name: ConsoleIn0.out I/F type: OpenRTM.Core.TimedLong Polarity: PROVIDED Properties port.port_type: DataOutPort dataport.data_type: IDL:RTC/TimedLong:1.0 dataport.dataflow_type: push, pull dataport.subscription_type: flush, new, periodic dataport.interface_type: corba_cdr, local Please Input Number> 10 Please Input Number> ConsoleOut I/F name: ConsoleOut0.in I/F type: IDL:RTC/TimedLong:1.0 Polarity: REQUIRED I/F name: ConsoleOut0.in I/F type: OpenRTM.Core.TimedLong Polarity: REQUIRED Properties port.port_type: DataInPort dataport.data_type: IDL:RTC/TimedLong:1.0 dataport.dataflow_type: push, pull dataport.subscription_type: any dataport.interface_type: corba_cdr, local time = 2012/03/12 9:07:25 data = 10 入力した数字が転送される 13
コンポーネントの作り方 14 ダイアログのテンプレートから作成 DiGOROClientRTC_Con ver1.1 (2012 年 8 月 23 日現在 ) 整数型のデータを受信し その値に100を足して送信するサンプル main 関数内を見れば簡単に理解できる 送受信できる型 ( すべて.Net のクラス ) TimedLong : 整数型 TimedString : 文字列型 TimedDouble : 少数型 TimedLongSeq : 整数配列 TimedStringSeq : 文字列配列 TimedDoubleSeq : 少数配列 これ以外にも Float, Short, ULong 等一般的な型が存在 タイムスタンプとデータから構成 TimedLong ^data = gcnew TimedLong(); data->data = 10; // Data : 整数型 TimeExtension::SetCurrentTime( data->time ); // Time : タイムスタンプ
ロボット向け拡張データ型 TimedVelocity2D data Data double VelocityX, double VelocityY, double VelocityYaw data Time 例 ) double velyaw = 0.0; TimedVelocity2D ^data = gcnew TimedVelocity2D(); m_component->getindata( data ) velyaw = data->data->velocityyaw; // ロボットの移動 // データの受信 15
送受信するデータの定義 PortDefine.h で定義 #define MODULE_NAME "DiGOROTest" // 入力ポートの定義 // INPORT( type, name ) // type : 送信するデータ型 // name : 名前 INPORT( TimedLong^, InData ) INPORT( TimedString^, InData2) // 出力ポートの定義 // OUTPORT( type, name ) // type : 送信するデータ型 // name : 名前 OUTPORT( TimedLong^, OutData ) OUTPORT( TimedFloat^, OutData2 ) モジュールの名前を定義できる 入力ポート ( 受信するデータ ) の定義 TimedLong( 整数型 ) を受信 複数個宣言することも可能 出力ポート ( 送信するデータ ) の定義 TimedLong( 整数型 ) を送信 複数個宣言することも可能 16
受信方法 例 :DiGOROClientRTC.cpp main 関数内 TimedLong ^indata; 途中省略 // 受信データ用メモリ ここでデータを受信して受信できれば if 文に入る // 受信用関数名はGet + [ 変数名 ] ( ただし [ 変数名 ] はPortDefine.hで定義したもの ) if ( m_component->getindata( indata ) ) // データの受信 ( データがあれば戻り値がtrue) { 受信されたデータが indata に入る } 省略 Get + InData ( InData は PortDefine.h に定義されている ) 17
送信方法 例 :DiGOROClientRTC.cpp main 関数内 TimedLong ^indata; // 受信データ用メモリ 途中省略 // 受信用関数名はGet + [ 変数名 ] ( ただし [ 変数名 ] はPortDefine.hで定義したもの ) if ( m_component->getindata( indata ) ) // データの受信 ( データがあれば戻り値がtrue) { outdata->data = indata->data + 100; // 受信したデータに100を足して送信用メモリにコピーしている TimeExtension::SetCurrentTime( outdata->time ); // 現在時刻を代入 m_component->sendoutdata( outdata ); // 送信用の関数名は Send + [ 変数名 ] } outdataの中身を送信する Send + OutData ( OutDataはPortDefine.hに定義されている ) 18
サンプルを動かしてみよう さっき動かした ConsoleIn, ConsoleOut, クライアントのサンプル ( DiGOROClientRTC_Con ver1.1 ) を起動 起動できない場合は (Windows7 の場合 ) 実行ファイルのプロパティで XP 互換モードにする ) 以下のように接続し All Activate サンプルソースと実際の動作を見比べてみましょう ConsoleIn で数値を入力 通信 DiGOROClient でそれを表示し値を変更 (100 を足す ) 通信 ConsoleOut で表示 19
作り方まとめ データ通信関連のクラス m_component 送受信できるデータは Timed** PortDefine.h で型と変数名を定義 Time*** とりあえず宣言には^を付ける 送信するために何か代入したいときはgcnewをする メンバへのアクセスは-> を使用 データの実体は [ 変数名 ]->Data タイムスタンプは [ 変数名 ]->Time 送信 データ送信メンバ関数 m_componet.send+[ 変数名 ] 受信 データ受信メンバ関数 m_componet.get+[ 変数名 ] 20
.Net tips1 : 文字列の相互変換 文字列の相互変換 C++ : CString ( 普通のクラス ).Net : String^ ( 参照クラス ) TimedString ^ts = gcnew TimedString(); CString str; // Window から文字列取得 m_edit.getwindowtext( str ); ts->data = gcnew String( str ); // Data は String^ 型 21
.Net tips2 : 配列の作り方 Timed*Sec TimedLongSec : 整数配列 TimedFloatSec : 小数配列 // 宣言と確保 //.Net のクラスなので とりあえず ^ を付けて gcnew TimedLongSeq ^tls = gcnew TimedLongSeq(); // Add 関数で要素を追加 tls->data->add( 1 ); tls->data->add( 2 ); tls->data->add( 4 ); 22
おわりに RTC を作るためのテンプレート DiGOROClientRTC_Con ver1.1 これをベースにすれば比較的簡単に RTC が作れる C++/CLI は最も簡単に作成できると判断して選びました C#, F#, VB でも開発可能 セックが作成した Python 版も使い易そう オリジナルの OpenRTM では C++ も動きますなので言語は何でもいいです 但し ここでは C++/CLI ( 基本は C++) で作ることを想定します 謝辞 このスライドは 中村友昭博士 ( 長井研ポスドク ) が作成した研究室内向け RTM 講習会のスライドを実験用に修正したものです スライドの使用を許可してくれた中村さんに感謝いたします 23