忍者ブログ
ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
[15]  [16]  [17]  [18]  [19]  [20]  [21]  [22]  [23]  [24]  [25
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

実行コンテキストの自作の方法について説明しておきたいと思います。

まずはPythonで作成してみます。
前にも言った通り1.1.0-RC1以前と1.1.0-RELEASEでは仕様が大きく変わっています。


とりあえずTestEC.pyという名前のファイルを作成してください。

まずOpenRTM-aistをインポートします。

import OpenRTM_aist


そしてPeriodicExecutionContextを継承したクラスを作成します。


class TestEC(OpenRTM_aist.PeriodicExecutionContext):
       def __init__(self):
       OpenRTM_aist.PeriodicExecutionContext.__init__(self)


そしてsvc関数に実行コンテキストのスレッドで何を実行するかを記述します。

def svc(self):
       while self.threadRunning():
              OpenRTM_aist.ExecutionContextBase.invokeWorkerPreDo(self)
              OpenRTM_aist.ExecutionContextBase.invokeWorkerDo(self)
              OpenRTM_aist.ExecutionContextBase.invokeWorkerPostDo(self)



次に実行コンテキストの初期化関数を記述してください。
ファイル名+Initという名前の関数から実行コンテキストを動的にロードするようになるので、関数名には注意してください。

def TestECInit(manager):
OpenRTM_aist.ExecutionContextFactory.instance().addFactory("TestEC", TestEC, OpenRTM_aist.ECDelete)





あとはrtc.confに以下のように記述すれば使えるようになります。


manager.modules.load_path: TestEC.pyの存在するディレクトリへのパス
manager.modules.preload:TestEC.py
exec_cxt.periodic.type:TestEC



ここで注意すべきなのはTestEC.pyまでのパスで、これはRTCを実行したフォルダからのパスになります。
例えば、

python TestRTC.py -f conf/rtc.conf

とした場合、rtc.confの存在するconfフォルダではなく現在のフォルダからのパスを指定しなければならないので注意してください。


以前作成したrtc.conf設定用ツール複合コンポーネント作成支援ツールを使えばファイルを開くダイアログでファイルを選ぶだけで上記の設定を記述した設定ファイルを作成することができます。



次にC++版の作成方法を説明します。
TestEC.h、TestEC.cppというファイルを作成してください。

TestEC.hから編集します。

まずは必要なヘッダーファイルを読み込みます。


#include <rtm/RTC.h>
#include <rtm/Manager.h>
#include <rtm/PeriodicExecutionContext.h>



そしてPeriodicExecutionContextを継承したクラスを作成して、コンストラクタとsvc関数を宣言しておきます。



classTestEC : public virtual PeriodicExecutionContext
{
public:
       TestEC();
       virtual int svc();
};



そして外部からTestECInit関数を明示的リンクできるように以下の記述を追加します。


extern "C"
{
DLL_EXPORT void TestECInit(RTC::Manager* manager);
};



次にTestEC.cppを編集します。

まずはTestEC.hをインクルードします。

#include "TestEC.h"


次にコンストラクタ、スレッド実行関数を記述してください。

TestEC::TestEC() : PeriodicExecutionContext()
{

}

int TestEC::svc(void)
{
       do
       {
              std::for_each(m_comps.begin(), m_comps.end(), invoke_worker());
       }while (m_svc);
}


最後に実行コンテキストの初期化関数を定義します。


extern "C"
{
       void TestECInit(RTC::Manager* manager)
       {
              manager->registerECFactory("PeriodicExecutionContext", RTC::ECCreate, RTC::ECDelete);
       }
};



次にビルドするためにVC++のプロジェクトを作成してみるわけですが、ここではCMakeからプロジェクトを作成するためのCMakeLists.txtを作成してみます。


cmake_minimum_required (VERSION 2.6)

#プロジェクト名
project(TestEC)

#OpenRTM-aistのパッケージ検索find_package(OpenRTM REQUIRED)

#インクルードするヘッダーファイルの存在するディレクトリへのパスを設定

include_directories(${OPENRTM_INCLUDE_DIRS})
include_directories(${OMNIORB_INCLUDE_DIRS})

#/dオプションの設定add_definitions(${OPENRTM_CFLAGS})
add_definitions(${OMNIORB_CFLAGS})

#リンクライブラリの存在するディレクトリへのパスを設定

link_directories(${OPENRTM_LIBRARY_DIRS})
link_directories(${OMNIORB_LIBRARY_DIRS})

#Test#C.cppから動的ライブラリを作成するように指定ADD_LIBRARY(TestEC SHARED TestEC.cpp)

#リンクするライブラリの指定
target_link_libraries(TestEC ${OPENRTM_LIBRARIES} )



他にも必要なライブラリがある場合は前回の記事のように追加してください。


後はCMakeしてプロジェクトを作成後、VC++で開いてビルドしてください。
Linuxの場合は以下のコマンドを入力してください。

cmake .
make


単純にビルドするだけであればこれで良いのですが、統合開発環境で開発した方が僕はやりやすいので、

cmake . -G "CodeBlocks - Unix Makefiles"

と入力してCode::Blocksで開発した方が良いかもしれないです。




そして先ほどと同じようにrtc.confを編集します。


manager.modules.load_path: TestEC.dll、soの存在するディレクトリへのパス
manager.modules.preload:TestEC.dll(.so)
exec_cxt.periodic.type:TestEC



これで使えるようになるはずですが、配布する場合はビルド済みのdllも付属させた方が使いやすいと思います。ダウンロード先でビルドが失敗する可能性もありますし、そもそもCMakeがインストールされていない可能性もあります。違う環境で使いたい場合のみビルドしてもらうぐらいなら事故も少ないと思います。




ライセンスには注意する必要はあるわけですが、OpenRTM-aist、OmniORBはLGPLなのでこれだけなら大丈夫だと思います。
前回のRTMコンテストで実行ファイルを付属させているにもかかわらず、必要なDLL(64bit用OpenRTM-aistのDLL等)を付属させていない作品が多かったように思います。
ライセンスを気にしたのであれば、そもそもヘッダーファイルを読み込んだビルド済み実行ファイルを付属させている時点でアウトの可能性があるので考える意味はありません。ライセンスを記述したtxtファイルを付属させてください
追記:そういえばRTCの配布に関してはライセンスは自由に決めて良いとかだったと思うので問題はありませんでした。








そういえばOpenRTM-aistの公式サイトが更新されています。
どうにもRTCビルダの動作確認が不十分だと思うのですけど大丈夫なのでしょうかね?
一度更新されると何年も更新されないので不安です。LibreOfficeみたいに2か月に1回更新するぐらいの更新頻度なら問題ありませんが、そもそも開発に関わっている人数が少ないので無理だと思います。
まあ生成したコードをこちらで修正すれば大丈夫な場合がほとんどみたいなので大丈夫か。

メーリングリストでRTCビルダで生成した***impl.h、****impl.cppに関する不具合が幾つか報告されているみたいです。

RC4以前から発生していた現象のように思うのですけど、どうなんでしょうね?

ManipulatorCommonInterface_Common.idl、ManipulatorCommonInterface_DataTypes.idl、ManipulatorCommonInterface_MiddleLevel.idlを使ってimplファイルを生成した時ですが、相当な数のエラーが出て何か所も修正した記憶があります。


まあこちらで生成したコードを修正すれば対応できるので仕様かどうかが判断しづらいところではあるとは思います。開発者サイドが仕様と言えば仕様、バグと言えばバグになる程度だと思います。


今更ですが、僕はRC4で生成したコードはCMakeが通らなかったので今までRC3を使っていました。本当に今更なのでどうでもいいのですけど。













にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
PR
CMakeでFine~.cmakeファイルや~Config.cmakeファイルを作るのが難しいのかと思っていましたが、そんな事なかったみたいです。
単純にインクルードパス、ライブラリパス、ライブラリ名を変数に設定しているだけでした。
何を勘違いしていたのでしょうね?

例えば、OpenRTM-aistでは、



インクルードパス:OPENRTM_INCLUDE_DIRS
ライブラリパス:OPENRTM_LIBRARY_DIRS
ライブラリ名:OPENRTM_LIBRARIES
プリプロセッサシンボル:OPENRTM_CFLAGS


という変数を設定していて、

include_directories(${OPENRTM_INCLUDE_DIRS})
link_directories(${OPENRTM_LIBRARY_DIRS})
target_link_libraries(プロジェクト名 ${OPENRTM_LIBRARIES})
add_definitions(${OPENRTM_CFLAGS})

のようにCMakeファイルに記述すれば使うことができるというわけですね。



とは言っても環境変数等を設定していないと使えないライブラリもあるので、具体的に色々なライブラリを使いながら試してみます。

以前作成した実行順序設定可能な実行コンテキストのビルドを自動化するためのCMakeファイルを作成したので、これを例にして説明してみます。


まず、この例ではOpenRTM-aist、Lua5.1、Qt5、Boost、Luabindを使用しています。
パッケージの検索は以下のようにして行います。

find_package(Qt5Widgets REQUIRED)
find_package(OpenRTM REQUIRED)
find_package(Boost REQUIRED)
find_package(Lua51 REQUIRED)



Luabindは調べた限りはですがCMakeに対応していないみたいなので、

set(LUABIND_PATH "luabind-0.9.1")

include_directories(${LUABIND_PATH})
set(luabind_srcs ~)

ADD_LIBRARY(プロジェクト名 SHARED  ${srcs} ${luabind_srcs})

自分でパスを設定して、こちらでソースコードからビルドするようにしています。
なのでluabind-0.9.1をダウンロードしてきてCMakeLists.txtと同じフォルダにコピーしてください。


Boost、Luaに関してはCMakeをインストールしたフォルダのshare/cmake-3.2/ModulesにFindBoost.cmakeとFindLua51.cmakeがあるのでこれを使えます。

ここでBoostはBOOST_ROOT、LuaはLUA_DEVという環境変数にインストールしたディレクトリへのパスを設定しておく必要があります。
Luaはインストーラーでインストールした場合は自動的に設定されます。


OpenRTM-aist、Qtは環境変数PATHから検索します。
具体的には、
  • C:\Program Files (x86)\OpenRTM-aist\1.1\bin、C:\Qt\Qt5.4.1\5.4\msvc2013\binにパスを通す
  • binという名前のディレクトリの親ディレクトリからcmake、libフォルダを検索
  • OpenRTM-aistはcmakeフォルダにOpenRTMConfig.cmakeがあるのでこれを使う
  • Qtの場合はさらにlibフォルダ内のcmakeフォルダを検索
  • cmakeフォルダ内のパッケージ名(Qt5Widgets)という名前のフォルダを検索
  • Qt5WidgetsフォルダにQt5WidgetsConfig.cmakeがあるのでこれを使う
という手順で検索できるのでパスを通しておいてください。多分インストールしたときに自動的に設定されるとは思います。


ここで問題なのはOpenRTM-aistはRTM_ROOT、OpenRTM-aistで使用しているOmniORBではOMNI_ROOTという環境変数を設定しておく必要があると言うことです。



後は以下のようにCMakeファイルに記述してください。
include_directories(${OPENRTM_INCLUDE_DIRS})
include_directories(${OMNIORB_INCLUDE_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${LUA_INCLUDE_DIR})

add_definitions(${OPENRTM_CFLAGS})
add_definitions(${OMNIORB_CFLAGS})

link_directories(${OPENRTM_LIBRARY_DIRS})
link_directories(${OMNIORB_LIBRARY_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
target_link_libraries(プロジェクト名 ${OPENRTM_LIBRARIES} ${LUA_LIBRARIES} ${Boost_LIBRARIES})


Qtだけは使い方が大きく異なります。
まずQtではシグナルやスロットを動作させるために、mocによるコンパイルを行いmocファイルを生成する必要があるわけですがそのために、

set(CMAKE_AUTOMOC ON)

・・・・

qt5_wrap_cpp(moc_ファイル名.cpp ファイル名.h)

と記述しておく必要があります。


あとリソースファイルの設定は、

qt5_add_resources(QRC ファイル名.qrc)

add_library(プロジェクト名 SHARED ${srcs} ${QRC})



のようにqt5_add_resourcesでリソースファイル追加後、コンパイルするファイルを追加すれば使用できるようになります。



そして最後に、


QT5_USE_MODULES(プロジェクト名 Widgets)


と記述すればインクルードパス、ライブラリパスが設定されるみたいです。




確かにCMakeは使いこなせば便利なツールだと思います。
ただ非常に使いづらいのが問題ですが。








にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
C++版のRTCをインストールすると/usr/local/components/libにインストールされるのは前から言っている通りですが、Python版の場合は

/usr/share/openrtm-1.1/components/python/RTC名バージョン番号

にインストールされるみたいですね。
これだけインストールされる場所が違うと分かりづらいとは思いました。



あとサービスポートを使ったRTCでmake installと入力したときに、C++版では前回の記事のようにCMakeLists.txtの編集が必要になるわけですが、Python版でもそのままではインストールさせてくれません。
サービスポートを使った場合IDLファイルが/usr/share/openrtm-1.1/components/python/RTC名バージョン名/srcにコピーされるみたいなのですが、何故かIDLファイルをidlフォルダではなく直下のフォルダから探してしまいます。

なのでidlフォルダにあるIDLファイルを一つ上のディレクトリにコピーしておいてください。


あとmakeと入力すればIDLファイルをコンパイルできるはずですが、これもIDLファイルを直下のフォルダから探します。通常通りidlcompile.shを使えばIDLファイルのコンパイルはできるので問題はないのですが、こちらでやりたい人は同じように直下のフォルダにIDLファイルをコピーしてください。


  • C++版ではIDLファイルのコピーが問題なくできる
  • idl/CMakeLists.txtの内容はC++、Python版どちらも同じ

ということを考えると、どうにも直下のフォルダのCMakeLists.txtが怪しいですね。

そう思ってCMakeLists.txtを読んでみると、そもそもPython版ではidlフォルダのCMakeLists.txtは使っていないみたいです。


まずは、

set(IDL_FILES ""
              test.idl
)

という感じでIDL_FILESという変数にIDLファイルの名前を入力します。


そして以下のコードでインストールするように指定しているみたいです。

install(FILES ${IDL_FILES} ${EXEC_FILES} ${OTHER_SRCS}
        DESTINATION "${INSTALL_PREFIX}/src"
        COMPONENT "sources")

ここでインストールするファイルは先ほど指定したIDL_FILESをそのまま指定しているためidlフォルダではなく直下のフォルダからIDLファイルを探してしまったみたいです。



IDLのコンパイルするときも同じです。

つまり変数IDL_FILESを指定するところで、

set(IDL_FILES ""
              idl/test.idl
)

と修正すればインストールもIDLコンパイルも出来るようになるはずです。


・・・と思いきやインストールは成功しましたけど、makeでIDLのコンパイルをすると何故かbinという名前のフォルダにファイルが生成されてしまいます。まあ別にidlcompile.shを使えば良いので全く問題はないのですが、気になる人はメーリングリストで報告でもしてください。








にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
例のツールの一部を修正しました。
少しは使いやすくなったかなと思います。










とりあえず動作例を作ろうと思ってOpenRTM-aist-1.1.1-Releaseをインストールしたときに付いてくるRTCビルダでRTCを作っているのですが、少し引っかかる点がありました。



LinuxでRTCをビルド後にmake installと入力すると/usr/local/components/libにRTCがインストールされるわけですが、何故かサービスポートを使用したRTCはインストールに失敗しました。

エラーの内容はこんな感じです。

CMake Error at include/ArmController/cmake_install.cmake:36 (FILE):
  file INSTALL cannot find
  "/root/RobotArmController/include/ArmController/PARENT_SCOPE".
Call Stack (most recent call first):
  include/cmake_install.cmake:37 (INCLUDE)
  cmake_install.cmake:39 (INCLUDE)





include/ArmController/CMakeLists.txtで、


set(hdrs ArmController.h
    PARENT_SCOPE
    ManipulatorCommonInterface_CommonSVC_impl.h
    ManipulatorCommonInterface_MiddleLevelSVC_impl.h
    )


のPARENT_SCOPEはオプションなので最後に付加する必要があるわけですが、サービスポートを使うと間に入ってしまってPARENT_SCOPEという名前のファイルを探してしまうみたいですね。

とりあえずこちらで編集して対応することにします。



というかRTCビルダの以前のバージョンだとPARENT_SCOPEのオプション自体がなかったのでエラーが出なかったみたいなのですけど、何でこんな変更をしたのでしょうね?














にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
とりあえず例のツールに機能を追加しました。
これで欲しかった機能はほぼ実装できたと思います。


これを使えば複合コンポーネントの利用が多少楽になるかもしれないです。



あらかじめ、Python2.7、pyQt4、OpenRTM-aist-Python-1.1.0-Release、rtctree、rtcprofile、rtshellをインストールしておいてください。


動作手順としては、

まずはSettingRTSystem.pyをダブルクリックして実行してください。

ツールが起動したら、新規作成ボタンを押してプロジェクトを新規作成します。



次にCPP、Pythonタブを選択→RTコンポーネントをファイルから読み込みボタンを押下して、起動したいRTCのDLL、Pythonファイルを選択します。

※この時モジュールの存在するディレクトリへのパスは相対パスで入力されるので作成したプロジェクトとモジュール、ツールを解凍したフォルダとの位置関係は変更しないでください、
今のところツールを解凍したフォルダのprojectフォルダにプロジェクトを作成してモジュールも同梱することを推奨しています。
ただし/usr/local/components/libに存在するモジュールを指定した場合のみ絶対パスで入力されるようになっています。Linuxの場合、RTCをビルド後make installと入力するとこのフォルダにモジュールがコピーされるので、それを利用させてもらっています。




次にRTCDタブに戻ってrtcd起動ボタンを押すことで選択したRTCを起動できます。



そしてRTシステムエディタでデータポート、サービスポートの接続、コンフィギュレーションパラメータの設定を行い、必要であれば複合コンポーネント作成します(必要でない場合はしなくてもかまいません)。



複合コンポーネントを起動するマネージャはツールと同時に起動したmanager_compositeをしていしてください。


そしてFile→Saveを選択して任意の場所にプロジェクトを保存してください。



すると作成したプロジェクトのフォルダ内にバッチファイルが生成されています。
この中のstart.bat(Linuxではstart.sh)を実行すると先ほど選択したRTCの起動、複合コンポーネントの起動、RTシステムの復元までを行います。




複合コンポーネント内で実行順序を設定したい場合は実行順序設定可能な実行コンテキストを指定する事もできます。
実行コンテキストタブから実行コンテキストをファイルから読み込みボタンを押下して、C++の場合はExecutionContext/MultipleOrderedEC/MultipleOrderedEC.dll、Pythonの場合はExecutionContext/MultipleOrderedEC-Python/MultipleOrderedEC.pyを指定します。


また別のマシン上でプロジェクトを作成したい場合、GUIを起動する側のマシンでは上記の通りツールを起動して、プロジェクトを作成する側のマシンではrtcConfSet/rtcConfSet.pyを起動してください。
そして以下のようにプロジェクトを作成する側のIPアドレスを指定することで作業ができます。




RTシステムの復元も行えるようになっていますが、通常の設定では先ほどの作業で指定したRTCとそれに接続されたRTCに関してのみ保存されるようになっています。
別プロセスでRTCを起動して、そのRTCに関しても保存したい場合はRTCのツリーから選択して外部のRTCをシステムに追加ボタンを押してください。
ツリーはRTCツリー更新ボタンを押すと表示されます。







まあこんなところか。

複合コンポーネントを作成する際にmanager_composite.mgrというマスターマネージャを指定してありますが、プロジェクト保存後に起動するとC++、もしくはPythonのrtcdで複合コンポーネントを起動するようにしています。C++のRTCが1つでも含まれているとC++のrtcdで複合コンポーネントを起動します。子RTCと同一プロセスで複合コンポーネントを起動することで子コンポーネントのコールバックを呼び出す際のオーバーヘッドを多少は軽減しています。


まだ使いづらい部分があるので改善していきたいとは思います。











にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
カレンダー
04 2024/05 06
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
フリーエリア
最新CM
[08/31 ysuga]
[08/31 Nobu]
[08/31 ysuga]
[12/11 Nobu]
[12/11 Kanamura]
最新TB
プロフィール
HN:
Nobu
年齢:
35
性別:
男性
誕生日:
1988/09/22
職業:
あれ
趣味:
妄想、自堕落
バーコード
ブログ内検索
P R
カウンター
忍者ブログ [PR]