GUIツールキットとRTCの連携

はじめに

Pythonのサンプルとして付属しているGUIジョイスティック http://svn.openrtm.org/OpenRTM-aist-Python/trunk/OpenRTM-aist-Python/OpenRTM_aist/examples/TkJoyStick/TkJoyStickComp.py

移動ロボットのシンプルなシミュレータのサンプル http://svn.openrtm.org/OpenRTM-aist-Python/trunk/OpenRTM-aist-Python/OpenRTM_aist/examples/MobileRobotCanvas/TkMobileRobotSimulator.py

などが一例です。

TkJoystickCompの例

TkJoystickCompのサンプルのmain関数ですが、以下のようになっています。

 def main():
   tkJoyCanvas = tkjoystick.TkJoystick() # GUIオブジェクトを作成
   tkJoyCanvas.master.title("TkJoystick")
   mgr = OpenRTM_aist.Manager.init(sys.argv) # RTCマネージャを作成
   mgr.activateManager() #マネージャを活性化
 
   # コンポーネントの登録
   profile = OpenRTM_aist.Properties(defaults_str=tkjoystick_spec)
   mgr.registerFactory(profile,
                       TkJoyStick,
                       OpenRTM_aist.Delete)
   # コンポーネントの生成
   comp = mgr.createComponent("TkJoyStick")
 
   # このコンポーネントにはset_posというメンバ関数があり、
   # GUIジョイスティックの座標をコンポーネントに渡すために使用される。
   # TkJoystickのGUIのupdateイベントが呼ばれるときに、
   # こいつを呼ぶようにコールバックとしてセットする。
   tkJoyCanvas.set_on_update(comp.set_pos)
   mgr.runManager(True) # マネージャのrunManagerの引数にTrueを渡してnon-blockモードでマネージャを起動
   tkJoyCanvas.mainloop() # PythonのGUIのメインループに入る。
 
 if __name__ == "__main__":
   main()

ポイント

コンポーネントの中からGUIのメインループ関数を呼んだり、GUIオブジェクトを生成したりはしないほうが無難

GUIツールキットの中には、mainスレッドから呼ばなければならないものや、 同一のスレッドから呼ばれることを前提としている関数などを持つものがある。RTCはonInitialize/onFinalizeを呼ぶスレッドと、onExecute/onActivated/onDeactivated その他を呼ぶスレッドは異なります。また、onExecute他の関数は複数のスレッドから同時に呼ばれる可能性すらあります。GUIスレッドとRTCとは別に扱ったほうがトラブルは少ないでしょう。

GUIとRTCのデータのやり取りは、RTCにそのための関数を追加することで対応

    • 上記のような理由から、GUIとコンポーネントは切り離したほうがよいのですが、GUI側とRTCとデータのやり取りをしなければならない時に困ります。通常RTCにデータのやり取りをするためのインターフェースを別途継承させて、createComponentで取得したコンポーネントへのポインタを取得してGUI側からデータを取得したり、データを与えたりします。
       class IMyInterface
       {
       public:
           virtual int getData() = 0;
           virtual void setData(double x, double y) = 0;
       };
       
       class MyComponent
        : public IMyInterface,
          public RTC::DataFlowComponentBase
       {
        : コンポーネントの定義
       public:
           virtual int getData()
           {
               coil::Guard guard(m_outdatalock);
               return m_outdata;
            }
          virtual void setData(double x, double y)
           {
               coil::Guard guard(m_indatalock);
               m_indata.x = x;
               m_indata.y = y;
           }
       };
      このようにコンポーネントを実装しておいてから、
        RTObject_impl* rtobj = mgr.createComponent("MyComponent");
        IMyInterface* comp = dynamic_cast<IMyInterface*>(rtobj);
        if (comp == 0) { abort(); }
        mgr.runManager(true);
        gui.mainloop();
      そして、GUIのコントロール内で
        std::cout << "out data: " << comp->getData() << std::endl; // データを取得
        comp->setData(1.0, 2.0); // データを入力
      のようにRTCとデータのやり取りをします。

RTCとGUIのコントロールやウィジェットを1対1対応にしておくとわかりやすい

ただし、GUIコントロールとRTCはそれぞれ生成方法が異なるので、別々に 生成して、上述したようにRTCに実装したデータ入出力関数を通じてGUI コントロールと結びつけたほうがよいでしょう。

 
移動ロボットのシンプルなシミュレータのサンプルでは、移動ロボットオブジェクトと それに対応するRTCを動的に増やしたり減らしたりしています。 http://svn.openrtm.org/OpenRTM-aist-Python/trunk/OpenRTM-aist-Python/OpenRTM_aist/examples/MobileRobotCanvas/TkMobileRobotSimulator.py

最新バージョン

初めての方へ

Windows msi(インストーラ) パッケージ (サンプルの実行ができます。)

C++,Python,Java,
Toolsを含む
1.1.2-RELEASE

RTコンポーネントを開発するためには開発環境のインストールが必要です。詳細はダウンロードページ

統計

Webサイト統計
ユーザ数:1620
プロジェクト統計
RTコンポーネント286
RTミドルウエア21
ツール20
文書・仕様書1

Join our slack

Enter email address for slack invite.

旧Webサイト

OpenRTM.org旧Webサイト

OpenHRP3

動力学シミュレータ

Choreonoid

モーションエディタ/シミュレータ

OpenHRI

対話制御コンポーネント群

OpenRTP

統合開発プラットフォーム

産総研RTC集

産総研が提供するRTC集

TORK

東京オープンソースロボティクス協会

DAQ-Middleware

ネットワーク分散環境でデータ収集用ソフトウェアを容易に構築するためのソフトウェア・フレームワーク

VirCA

遠隔空間同士を接続し、実験を行うことが可能な仮想空間プラットホーム