DDS(Data Distribution Service)はOMGが策定した出版・購読型モデルの通信ミドルウェア仕様です。 ドメイン内のDomain Participantがデータ配信を行うDDS Publisher、データ受信を行うDDS Subscriberにより他のDomain Participantと相互通信を行います。 Publisherは指定のトピック向けにデータを配信し、Subscriberは指定のトピック向けのデータを受信することができます。
DDSの概念図は上の図のようになっていますが、内部的にはUDP/IPによるマルチキャスト通信とユニキャスト通信によって通信しています。
ParticipantはPDP(Participant Discovery Protocol)で互いのParticipantを検出します。この時、マルチキャスト通信でユニキャストアドレスなどのメッセージを送信します。 次にSEDP(Endpoint Discovery Protocol)でユニキャスト通信によりDataWriterとDataReaderの情報を共有します。トピックとデータ型が一致した場合はエンドポイントが一致していると判定してデータの送受信を開始します。
この他にDDSには通信のQoS(Quality of Service)制御の機能があります。
現状、以下のDDS実装に対応している。
Fast DDS(以前のバージョンではFast RTPS)はeProsima社が開発しているOMG DDS 2.0、RTPS 2.2仕様の通信ミドルウェアです。
以下ではOpenRTM-aistのFast RTPSプラグインのインストール手順、使用方法を説明します。
※ROS2通信機能がインストール済みの場合、Fast DDS通信機能も利用可能になっているため以下の手順は不要です。
C++版のみの対応です。
以下のサイトからインストーラーをダウンロードしてインストールしてください。
CMake実行時にFASTRTPS_ENABLEのオプションをONにします。
cmake -DORB_ROOT=C:/workspace/omniORB-4.2.3-win64-vc16 -G "Visual Studio 16 2019" -DFASTRTPS_ENABLE=ON ..
その他の手順は通常と同じです。
適当な場所にインストールしてください。
インストールするディレクトリはCMAKE_INSTALL_PREFIXのオプションで設定します。
cmake .. -DCMAKE_INSTALL_PREFIX=C:/workspace/OpenRTM-aist/build/install cmake --build . --config Release --target install
{インストールしたパス}\2.0.0\Components\C++\Examples\vc16のサンプルコンポーネントを実行します。
以下の内容のrtc.confを作成してください。
manager.modules.load_path: {インストールしたパス}\\2.0.0\\ext\\transport manager.modules.preload: FastRTPSTransport.dll manager.components.preconnect: ConsoleOut0.in?interface_type=fast-rtps, ConsoleIn0.out?interface_type=fast-rtps manager.components.preactivation: ConsoleOut0, ConsoleIn0
まずFastRTPSTransport.dllのロードが必要になります。 この設定はmanager.modules.preloadのオプションで設定できます。
次にコネクタ生成時にインターフェース型をfast-rtpsに設定する必要があります。 コネクタの生成はmanager.components.preconnectオプションにより設定します。 この例ではConsoleOut0コンポーネントのinのポート、ConsoleIn0コンポーネントのoutのポートにそれぞれコネクタを生成しています。
ConsoleInComp.exe、ConsoleOutComp.exeを実行すると通信ができるようになります。
asio、TinyXML-2をインストールします。
sudo apt install libasio-dev libtinyxml2-dev
Fast-CDRをビルド、インストールします。
export $OPENRTM_INSTALL_DIR=~/fastdds_install export FASTCDR_VERSION=1.0.23 wget https://github.com/eProsima/Fast-CDR/archive/refs/tags/v${FASTCDR_VERSION}.tar.gz tar xf v${FASTCDR_VERSION}.tar.gz cd Fast-CDR-${FASTCDR_VERSION}/ mkdir build cd build/ cmake .. -DCMAKE_INSTALL_PREFIX=${OPENRTM_INSTALL_DIR} cmake --build . --config Release -- -j$(nproc) cmake --build . --config Release --target install
foonathan/memoryをビルド、インストールします。
export FOONATHAN_MEMORY_VERSION=1.2.1 wget https://github.com/eProsima/foonathan_memory_vendor/archive/refs/tags/v${FOONATHAN_MEMORY_VERSION}.tar.gz tar xf v${FOONATHAN_MEMORY_VERSION}.tar.gz cd foonathan_memory_vendor-${FOONATHAN_MEMORY_VERSION}/ mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=${OPENRTM_INSTALL_DIR} cmake --build . --config Release -- -j$(nproc) cmake --build . --config Release --target install
Fast DDSのビルドにはCMake 3.11以上のバージョンが必要です。 Ubuntu 18.04環境ではaptでインストールされるCMakeのバージョンが3.10のため、新しいバージョンのCMakeをダウンロードしてPATHを設定してください。
wget https://github.com/Kitware/CMake/releases/download/v3.22.3/cmake-3.22.3-linux-x86_64.tar.gz tar xf cmake-3.22.3-linux-x86_64.tar.gz export PATH=~/cmake-3.22.3-linux-x86_64/bin:$PATH
以下のコマンドでFast DDSをビルド、インストールしてください。
export FASTDDS_VERSION=2.5.1 wget https://github.com/eProsima/Fast-DDS/archive/refs/tags/v${FASTDDS_VERSION}.tar.gz tar xf v${FASTDDS_VERSION}.tar.gz cd Fast-DDS-${FASTDDS_VERSION}/ mkdir build cd build cmake .. -Dfastcdr_DIR=${OPENRTM_INSTALL_DIR}/lib/cmake -Dfoonathan_memory_DIR=${OPENRTM_INSTALL_DIR}/lib/foonathan_memory -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=${OPENRTM_INSTALL_DIR} cmake --build . --config Release -- -j$(nproc) cmake --build . --config Release --target install
CMake実行時にFASTRTPS_ENABLEのオプションをONにします。
cmake .. -DFASTRTPS_ENABLE=ON -Dfastrtps_DIR=${OPENRTM_INSTALL_DIR}/share/fastrtps/cmake
その他の手順は通常と同じです。
適当な場所にインストールしてください。
インストールするディレクトリはCMAKE_INSTALL_PREFIXのオプションで設定します。
cmake .. -DCMAKE_INSTALL_PREFIX=${OPENRTM_INSTALL_DIR} cmake --build . --config Release --target install
{インストールしたパス}/share/openrtm-2.0/components/c++/examplesのサンプルコンポーネントを実行します。
以下の内容のrtc.confを作成してください。
manager.modules.load_path: {インストールしたパス}/lib/openrtm-2.0/transport manager.modules.preload: FastRTPSTransport.so manager.components.preconnect: ConsoleOut0.in?interface_type=fast-rtps, ConsoleIn0.out?interface_type=fast-rtps manager.components.preactivation: ConsoleOut0, ConsoleIn0
まずFastRTPSTransport.soのロードが必要になります。 この設定はmanager.modules.preloadのオプションで設定できます。
次にコネクタ生成時にインターフェース型をfast-rtpsに設定する必要があります。 コネクタの生成はmanager.components.preconnectオプションにより設定します。 この例ではConsoleOut0コンポーネントのinのポート、ConsoleIn0コンポーネントのoutのポートにそれぞれコネクタを生成しています。
ConsoleInComp、ConsoleOutCompを実行すると通信ができるようになります。
rtc.confでOpenRTM-aistのマネージャ起動時に以下のオプションを設定可能です。 ※開発中のOpenRTM-aistでは使用可能ですが、リリースしたバージョンでは未実装の場合があります。
オプション名 | 設定例 | 内容 |
fast-rtps.xmlprofile.filename | C:/openrtminstall/2.0.0/ext/transport/FastRTPsQoSExample.xml | Fast DDSの設定ファイルを指定する。 |
fast-rtps.participant.name | participant_openrtm | ロードするDomainParticipantのプロファイル名 |
fast-rtps.domain.id | 0 | ドメインのID |
fast-rtps.dds.sec.auth.plugin | builtin.PKI-DH | 認証プラグインの名前 |
fast-rtps.dds.sec.auth.*** | 認証プラグインの設定 | |
fast-rtps.dds.sec.access.plugin | builtin.Access-Permissions | アクセス制御プラグインの名前 |
fast-rtps.dds.sec.access.*** | アクセス制御プラグインの設定 | |
fast-rtps.dds.sec.crypto.plugin | builtin.AES-GCM-GMAC | 暗号化プラグインの名前 |
fast-rtps.dds.sec.crypto.*** | 暗号化プラグインの設定 | |
fast-rtps.dds.sec.log.plugin | builtin.DDS_LogTopic | セキュリティロギングプラグインの名前 |
fast-rtps.dds.sec.log.*** | セキュリティロギングプラグインの設定 |
以下に設定例を記載します。
fast-rtps.xmlprofile.filename: ${OPENRTM_INSTALL_DIR}/transport/FastRTPsQoSExample.xml fast-rtps.participant.name: participant_openrtm
データポート接続時のコネクタプロファイルに設定できるオプションは以下の通りです。
オプション名 | デフォルト値 | オプション | 内容 |
fast-rtps.topic | chatter | DDSトピックの名前。ROS2シリアライザを使う場合は先頭にrt/を付けた名前に自動的に変更する。 | |
fast-rtps.subscriber.name | ロードするSubscriberのプロファイル名 | ||
fast-rtps.subscriber.qos.deadline.period.seconds | 2147483647 | 受信側の最小周期 | |
fast-rtps.subscriber.qos.deadline.period.nanosec | 4294967295 | ||
fast-rtps.subscriber.qos.destinationOrder | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
fast-rtps.subscriber.qos.disablePositiveACKs.enabled | NO | YES, NO | |
fast-rtps.subscriber.qos.disablePositiveACKs.duration.seconds | 2147483647 | ||
fast-rtps.subscriber.qos.disablePositiveACKs.duration.nanosec | 4294967295 | ||
fast-rtps.subscriber.qos.durability.kind | VOLATILE_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | 受信側の堅牢性(VOLATILE_DURABILITY_QOS:変わりやすい、TRANSIENT_LOCAL_DURABILITY_QOS:一時的なローカル設定) |
fast-rtps.subscriber.qos.durabilityService.history_depth | 1 | ||
fast-rtps.subscriber.qos.durabilityService.history_kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
fast-rtps.subscriber.qos.durabilityService.max_instances | -1 | ||
fast-rtps.subscriber.qos.durabilityService.max_samples | -1 | ||
fast-rtps.subscriber.qos.durabilityService.max_samples_per_instance | -1 | ||
fast-rtps.subscriber.qos.durabilityService.service_cleanup_delay.seconds | 0 | ||
fast-rtps.subscriber.qos.durabilityService.service_cleanup_delay.nanosec | 0 | ||
fast-rtps.subscriber.qos.latencyBudget.duration.seconds | 0 | ||
fast-rtps.subscriber.qos.latencyBudget.duration.nanosec | 0 | ||
fast-rtps.subscriber.qos.lifespan.duration.seconds | 2147483647 | ||
fast-rtps.subscriber.qos.lifespan.duration.nanosec | 4294967295 | ||
fast-rtps.subscriber.qos.liveliness.announcement_period.seconds | 2147483647 | ||
fast-rtps.subscriber.qos.liveliness.announcement_period.nanosec | 4294967295 | ||
fast-rtps.subscriber.qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
fast-rtps.subscriber.qos.liveliness.lease_duration.seconds | 2147483647 | 受信側のハートビートの周期 | |
fast-rtps.subscriber.qos.liveliness.lease_duration.nanosec | 4294967295 | ||
fast-rtps.subscriber.qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
fast-rtps.subscriber.qos.presentation.access_scope | INSTANCE_PRESENTATION_QOS | INSTANCE_PRESENTATION_QOS, TOPIC_PRESENTATION_QOS, GROUP_PRESENTATION_QOS | |
fast-rtps.subscriber.qos.presentation.coherent_access | NO | YES, NO | |
fast-rtps.subscriber.qos.presentation.ordered_access | NO | YES, NO | |
fast-rtps.subscriber.qos.reliability.kind | BEST_EFFORT_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | 受信側の信頼性(RELIABLE_RELIABILITY_QOS:高信頼、BEST_EFFORT_RELIABILITY_QOS:最高速度) |
fast-rtps.subscriber.qos.reliability.max_blocking_time.seconds | 0 | ||
fast-rtps.subscriber.qos.reliability.max_blocking_time.nanosec | 100000000 | ||
fast-rtps.subscriber.qos.timeBasedFilter.minimum_separation.seconds | 0 | ||
fast-rtps.subscriber.qos.timeBasedFilter.minimum_separation.nanosec | 0 | ||
fast-rtps.subscriber.qos.type_consistency.force_type_validation | NO | YES, NO | |
fast-rtps.subscriber.qos.type_consistency.ignore_member_names | NO | YES, NO | |
fast-rtps.subscriber.qos.type_consistency.ignore_sequence_bounds | YES | YES, NO | |
fast-rtps.subscriber.qos.type_consistency.ignore_string_bounds | YES | YES, NO | |
fast-rtps.subscriber.qos.type_consistency.kind | ALLOW_TYPE_COERCION | DISALLOW_TYPE_COERCION, ALLOW_TYPE_COERCION | |
fast-rtps.subscriber.qos.type_consistency.prevent_type_widening | NO | YES, NO | |
fast-rtps.subscriber.history_memory_policy | PREALLOCATED_WITH_REALLOC_MEMORY_MODE | PREALLOCATED_MEMORY_MODE, PREALLOCATED_WITH_REALLOC_MEMORY_MODE, DYNAMIC_RESERVE_MEMORY_MODE, DYNAMIC_REUSABLE_MEMORY_MODE | |
fast-rtps.subscriber.topic.historyQos.depth | 1 | ||
fast-rtps.subscriber.topic.historyQos.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
fast-rtps.subscriber.times.heartbeatResponseDelay.seconds | 0 | ||
fast-rtps.subscriber.times.heartbeatResponseDelay.nanosec | 5000000 | ||
fast-rtps.subscriber.times.initialAcknackDelay.seconds | 0 | ||
fast-rtps.subscriber.times.initialAcknackDelay.nanosec | 70000000 | ||
fast-rtps.publisher.name | ロードするPublisherのプロファイル名 | ||
fast-rtps.publisher.qos.deadline.period.seconds | 2147483647 | 送信側の最小周期 | |
fast-rtps.publisher.qos.deadline.period.nanosec | 4294967295 | ||
fast-rtps.publisher.qos.destinationOrder | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
fast-rtps.publisher.qos.disablePositiveACKs.enabled | NO | YES, NO | |
fast-rtps.publisher.qos.disablePositiveACKs.duration.seconds | 2147483647 | ||
fast-rtps.publisher.qos.disablePositiveACKs.duration.nanosec | 4294967295 | ||
fast-rtps.publisher.qos.durability.kind | VOLATILE_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | 送信側の堅牢性(VOLATILE_DURABILITY_QOS:変わりやすい、TRANSIENT_LOCAL_DURABILITY_QOS:一時的なローカル設定) |
fast-rtps.publisher.qos.durabilityService.history_depth | 1 | ||
fast-rtps.publisher.qos.durabilityService.history_kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
fast-rtps.publisher.qos.durabilityService.max_instances | -1 | ||
fast-rtps.publisher.qos.durabilityService.max_samples | -1 | ||
fast-rtps.publisher.qos.durabilityService.max_samples_per_instance | -1 | ||
fast-rtps.publisher.qos.durabilityService.service_cleanup_delay.seconds | 0 | ||
fast-rtps.publisher.qos.durabilityService.service_cleanup_delay.nanosec | 0 | ||
fast-rtps.publisher.qos.latencyBudget.duration.seconds | 0 | ||
fast-rtps.publisher.qos.latencyBudget.duration.nanosec | 0 | ||
fast-rtps.publisher.qos.lifespan.duration.seconds | 2147483647 | 送信側の未送信データの保持時間 | |
fast-rtps.publisher.qos.lifespan.duration.nanosec | 4294967295 | ||
fast-rtps.publisher.qos.liveliness.announcement_period.seconds | 2147483647 | ||
fast-rtps.publisher.qos.liveliness.announcement_period.nanosec | 4294967295 | ||
fast-rtps.publisher.qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
fast-rtps.publisher.qos.liveliness.lease_duration.seconds | 2147483647 | 送信側のハートビートの周期 | |
fast-rtps.publisher.qos.liveliness.lease_duration.nanosec | 4294967295 | ||
fast-rtps.publisher.qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
fast-rtps.publisher.qos.presentation.access_scope | INSTANCE_PRESENTATION_QOS | INSTANCE_PRESENTATION_QOS, TOPIC_PRESENTATION_QOS, GROUP_PRESENTATION_QOS | |
fast-rtps.publisher.qos.presentation.coherent_access | NO | YES, NO | |
fast-rtps.publisher.qos.presentation.ordered_access | NO | YES, NO | |
fast-rtps.publisher.qos.publishMode.kind | SYNCHRONOUS_PUBLISH_MODE | SYNCHRONOUS_PUBLISH_MODE, ASYNCHRONOUS_PUBLISH_MODE | |
fast-rtps.publisher.qos.reliability.kind | BEST_EFFORT_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | 送信側の信頼性(RELIABLE_RELIABILITY_QOS:高信頼、BEST_EFFORT_RELIABILITY_QOS:最高速度、SYSTEM_DEFAULT) |
fast-rtps.publisher.qos.reliability.max_blocking_time.seconds | 0 | ||
fast-rtps.publisher.qos.reliability.max_blocking_time.nanosec | 100000000 | ||
fast-rtps.publisher.qos.timeBasedFilter.minimum_separation.seconds | 0 | ||
fast-rtps.publisher.qos.timeBasedFilter.minimum_separation.nanosec | 0 | ||
fast-rtps.publisher.qos.type_consistency.force_type_validation | NO | YES, NO | |
fast-rtps.publisher.qos.type_consistency.ignore_member_names | NO | YES, NO | |
fast-rtps.publisher.qos.type_consistency.ignore_sequence_bounds | YES | YES, NO | |
fast-rtps.publisher.qos.type_consistency.ignore_string_bounds | YES | YES, NO | |
fast-rtps.publisher.qos.type_consistency.kind | ALLOW_TYPE_COERCION | DISALLOW_TYPE_COERCION, ALLOW_TYPE_COERCION | |
fast-rtps.publisher.qos.type_consistency.prevent_type_widening | NO | YES, NO | |
fast-rtps.publisher.history_memory_policy | PREALLOCATED_WITH_REALLOC_MEMORY_MODE | PREALLOCATED_MEMORY_MODE, PREALLOCATED_WITH_REALLOC_MEMORY_MODE, DYNAMIC_RESERVE_MEMORY_MODE, DYNAMIC_REUSABLE_MEMORY_MODE | |
fast-rtps.publisher.topic.historyQos.depth | 1 | 送信側の保持するデータ数 | |
fast-rtps.publisher.topic.historyQos.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | 送信データの保持方法(KEEP_LAST_HISTORY_QOS:すべてのデータを保持、KEEP_LAST_HISTORY_QOS:depthで指定したデータ数だけ保持) |
fast-rtps.publisher.times.heartbeatPeriod.seconds | 3 | ||
fast-rtps.publisher.times.heartbeatPeriod.nanosec | 0 | ||
fast-rtps.publisher.times.initialHeartbeatDelay.seconds | 0 | ||
fast-rtps.publisher.times.initialHeartbeatDelay.nanosec | 12000000 | ||
fast-rtps.publisher.times.nackResponseDelay.seconds | 0 | ||
fast-rtps.publisher.times.nackResponseDelay.nanosec | 5000000 | ||
fast-rtps.publisher.times.nackSupressionDuration.seconds | 0 | ||
fast-rtps.publisher.times.nackSupressionDuration.nanosec | 0 |
以下に設定例を記載します。
manager.components.preconnect: ConsoleOut0.in?interface_type=fast-rtps&fast-rtps.subscriber.name=subscriber_openrtm
Fast DDSはDDS Security仕様のセキュア通信機能を提供しています。
OpenRTM-aistのFast DDSプラグインでセキュア通信機能を使用するためには起動時のオプションを設定する必要があります。 以下に設定例を記載します。
fast-rtps.dds.sec.auth.plugin: builtin.PKI-DH fast-rtps.dds.sec.auth.builtin.PKI-DH.identity_ca: file://C:/workspace/openrtm_test/build/install/2.0.0/ext//transport/mainexamplecacert.pem fast-rtps.dds.sec.auth.builtin.PKI-DH.identity_certificate: file://C:/workspace/openrtm_test/build/install/2.0.0/ext//transport/appexamplecert.pem fast-rtps.dds.sec.auth.builtin.PKI-DH.private_key: file://C:/workspace/openrtm_test/build/install/2.0.0/ext//transport/appexamplekey.pem fast-rtps.dds.sec.crypto.plugin: builtin.AES-GCM-GMAC
Fast DDSのマニュアルの手順で秘密鍵、証明書を作成します。
以下で秘密鍵、自己署名証明書を作成するコマンドを掲載します。 maincaconf.cnfはFast DDSのマニュアルのものを使用します。 出力するファイル名を変更したい場合は適宜maincaconf.cnfの以下の項目を変更してください。
certificate = $dir/mainexamplecacert.pem private_key = $dir/mainexamplecakey.pem
また、req_distinguished_nameの項目は変更して、その内容に応じて変更したappconf.cnfを用意してください。
以下のコマンドを実行します。
type nul > index.txt openssl ecparam -name prime256v1 > ecdsaparam openssl req -nodes -x509 -days 3650 -newkey ec:ecdsaparam -keyout mainexamplecakey.pem -out mainexamplecacert.pem -config maincaconf.cnf openssl ecparam -name prime256v1 > ecdsaparam openssl req -nodes -new -newkey ec:ecdsaparam -config appconf.cnf -keyout appexamplekey.pem -out appexamplereq.pem openssl ca -batch -create_serial -config maincaconf.cnf -days 3650 -in appexamplereq.pem -out appexamplecert.pem
秘密鍵appexamplekey.pem、証明書mainexamplecacert.pem、appexamplecert.pemを使用します。
Vortex OpenspliceはADLINK社が開発しているOMG DDS 1.4、DDSI-RTPS 2.3仕様の通信ミドルウェアです。
以下ではOpenRTM-aistのOpenSpliceプラグインのインストール、使用手順を説明します。以下からOpenSpliceをダウンロードして適当な場所に展開してください。
以下からRapidXmlをダウンロードして適当な場所に展開してください。
展開したら新たにrapidxmlフォルダを作成してヘッダーファイル(.hpp)をそこに移動させてください。 この時、展開したパスは以下のようになっています。
rapidxml-1.13 |- rapidxml |- rapidxml.hpp |- rapidxml_iterators.hpp |- rapidxml_print.hpp |- rapidxml_utils.hpp
OpenRTM-aistをビルドする前に、OpenSpliceのrelease.batを実行します。
%OpenSplice_DIR%\x86.win32\release.bat
CMake実行時にOPENSPLICE_ENABLEオプションをONに設定し、RAPIDXML_DIRオプションにRapidXmlを展開したパスを指定します。
cmake -DORB_ROOT=C:/workspace/omniORB-4.2.3-win64-vc16 -G "Visual Studio 16 2019" -DOPENSPLICE_ENABLE=ON -DRAPIDXML_DIR=%RAPIDXML_DIR% ..
その他の手順は通常と同じです。
適当な場所にインストールしてください。
インストールするディレクトリはCMAKE_INSTALL_PREFIXのオプションで設定します。
cmake .. -DCMAKE_INSTALL_PREFIX=C:/workspace/OpenRTM-aist/build/install cmake --build . --config Release --target install
{インストールしたパス}\2.0.0\Components\C++\Examples\vc16のサンプルコンポーネントを実行します。 RTC起動前にOpenSpliceのrelease.batを実行してください。
以下の内容のrtc.confを作成してください。
manager.modules.load_path: {インストールしたパス}\\2.0.0\\ext\\transport manager.modules.preload: OpenSpliceTransport.dll manager.components.preconnect: ConsoleOut0.in?interface_type=opensplice, ConsoleIn0.out?interface_type=opensplice manager.components.preactivation: ConsoleOut0, ConsoleIn0
まずOpenSpliceTransport.dllのロードが必要になります。 この設定はmanager.modules.preloadのオプションで設定できます。
次にコネクタ生成時にインターフェース型をopenspliceに設定する必要があります。 コネクタの生成はmanager.components.preconnectオプションにより設定します。 この例ではConsoleOut0コンポーネントのinのポート、ConsoleIn0コンポーネントのoutのポートにそれぞれコネクタを生成しています。
ConsoleInComp.exe、ConsoleOutComp.exeを実行すると通信ができるようになります。
以下からOpenSpliceをダウンロードして適当な場所に展開してください。
wget https://github.com/ADLINK-IST/opensplice/releases/download/OSPL_V6_9_210323OSS_RELEASE/PXXX-VortexOpenSplice-6.9.210323OSS-HDE-x86_64.linux-gcc7-glibc2.27-installer.tar tar xf PXXX-VortexOpenSplice-6.9.210323OSS-HDE-x86_64.linux-gcc7-glibc2.27-installer.tar
以下のコマンドでRapidXmlをインストールしてください。
sudo apt install librapidxml-dev
OpenRTM-aistをビルドする前に、OpenSpliceのrelease.comを実行します。
source ${OPENSPLICE_DIR}/x86_64.linux/release.com
CMake実行時にOPENSPLICE_ENABLEオプションをONに設定します。
cmake -DOPENSPLICE_ENABLE=ON ..
その他の手順は通常と同じです。
適当な場所にインストールしてください。
インストールするディレクトリはCMAKE_INSTALL_PREFIXのオプションで設定します。
cmake .. -DCMAKE_INSTALL_PREFIX=~/workspace/OpenRTM-aist/build/install cmake --build . --config Release --target install
{インストールしたパス}/share/openrtm-2.0/components/c++/examplesのサンプルコンポーネントを実行します。 RTC起動前にOpenSpliceのrelease.comを実行してください。
以下の内容のrtc.confを作成してください。
manager.modules.load_path: {インストールしたパス}/lib/openrtm-2.0 manager.modules.preload: OpenSpliceTransport.so manager.components.preconnect: ConsoleOut0.in?interface_type=opensplice, ConsoleIn0.out?interface_type=opensplice manager.components.preactivation: ConsoleOut0, ConsoleIn0
まずOpenSpliceTransport.soのロードが必要になります。 この設定はmanager.modules.preloadのオプションで設定できます。
次にコネクタ生成時にインターフェース型をopenspliceに設定する必要があります。 コネクタの生成はmanager.components.preconnectオプションにより設定します。 この例ではConsoleOut0コンポーネントのinのポート、ConsoleIn0コンポーネントのoutのポートにそれぞれコネクタを生成しています。
ConsoleInComp、ConsoleOutCompを実行すると通信ができるようになります。
まずはOpenSpliceのPythonラッパーライブラリをインストールする必要があります。
適当な場所にビルド済みのOpenSpliceを展開してください。
次に展開したフォルダのHDE\x86_64.win64\tools\python\srcで以下のコマンドを実行するとインストールされます。
{OpenSpliceを展開したディレクトリ}\HDE\x86_64.win64\release.bat python setup.py build python setup.py install
Cythonをインストールしていない場合は以下のコマンドを実行してください。
pip install cython
※上記のsetup.pyによるビルドにはPythonをビルドしたVisual Studioと同じバージョンのVisual Studioがインストールされている必要があります。 Python 2.7ではVisual Studio 2008、Python 3.7ではVisual Studio 2017が必要になります。
OpenRTM-aist 1.2等をインストーラーでインストールしておいてください。 OpenRTM-aist Python版のソースコードを入手してください。
以下のコマンドでOpenRTM-aist Python版をインストールしてください。
python setup.py build python setup.py install
動作前に以下のコマンドを実行してください。
{OpenSpliceを展開したディレクトリ}\HDE\x86_64.win64\release.bat
以下のようなrtc.confを作成し、OpenSpliceTransport.pyをロード後、インターフェース型にopenspliceを指定してRTCを起動します。
manager.modules.load_path: C:\\Python37\\Lib\\site-packages\\OpenRTM_aist\\ext\\transport\\OpenSplice manager.modules.preload: OpenSpliceTransport.py manager.components.preconnect: ConsoleOut0.in?interface_type=opensplice&marshaling_type=opensplice, ConsoleIn0.out?interface_type=opensplice&marshaling_type=opensplice
まずはOpenSpliceのPythonラッパーライブラリをインストールする必要があります。 以下からOpenSpliceをダウンロードして適当な場所に展開してください。
wget https://github.com/ADLINK-IST/opensplice/releases/download/OSPL_V6_9_210323OSS_RELEASE/PXXX-VortexOpenSplice-6.9.210323OSS-HDE-x86_64.linux-gcc7-glibc2.27-installer.tar tar xf PXXX-VortexOpenSplice-6.9.210323OSS-HDE-x86_64.linux-gcc7-glibc2.27-installer.tar
次に展開したフォルダのHDE/x86_64.linux/tools/python/srcで以下のコマンドを実行するとインストールされます。
source ${OPENSPLICE_DIR}/x86_64.linux/release.com python3 setup.py build sudo su # source ${OPENSPLICE_DIR}/x86_64.linux/release.com # python3 setup.py install # exit
Cythonをインストールしていない場合は以下のコマンドを実行してください。
sudo apt install python3-pip pip3 install cython
omniORBのPython版をインストールします。
sudo su # echo "deb http://openrtm.org/pub/Linux/ubuntu/ $code_name main" >> /etc/apt/sources.list # wget -O- --secure-protocol=TLSv1_2 --no-check-certificate https://openrtm.org/pub/openrtm.key | apt-key add - # apt update # apt install python3-omniorb python3-omniorb-omg omniidl-python3 # exit
OpenRTM-aist 1.2等をインストーラーでインストールしておいてください。 OpenRTM-aist Python版のソースコードを入手してください。
以下のコマンドでOpenRTM-aist Python版をインストールしてください。
sudo apt install doxygen python3 setup.py build sudo python3 setup.py install
動作前にrelease.comを実行してください。
以下のようなrtc.confを作成し、OpenSpliceTransport.pyをロード後、インターフェース型にopenspliceを指定してRTCを起動します。
manager.modules.load_path: /usr/local/lib/python3.6/dist-packages/OpenRTM_aist/ext/transport/OpenSplice manager.modules.preload: OpenSpliceTransport.py manager.components.preconnect: ConsoleOut0.in?interface_type=opensplice&marshaling_type=opensplice, ConsoleIn0.out?interface_type=opensplice&marshaling_type=opensplice
rtc.confでOpenRTM-aistのマネージャ起動時に以下のオプションを設定可能です。 ※開発中のOpenRTM-aistでは使用可能ですが、リリースしたバージョンでは未実装の場合があります。
オプション名 | 設定例 | オプション | 内容 |
opensplice.uri | file://OpenSpliceQoSExample.xml | OpenSpliceのQoS設定ファイルを指定する。 | |
opensplice.profile | testProfile | QoSのプロファイル名を指定する。 | |
opensplice.participant_qos.name | testParticipant | ロードするDomainParticipantのプロファイル名 | |
opensplice.participant_qos.entity_factory.autoenable_created_entities | YES | YES,NO | |
opensplice.participant_qos.listener_scheduling.scheduling_class.kind | SCHEDULE_DEFAULT | SCHEDULE_DEFAULT,SCHEDULE_TIMESHARING,SCHEDULE_REALTIME | |
opensplice.participant_qos.listener_scheduling.scheduling_priority | 1 | ||
opensplice.participant_qos.listener_scheduling.scheduling_priority_kind.kind | PRIORITY_RELATIVE | PRIORITY_RELATIVE,PRIORITY_ABSOLUTE | |
opensplice.participant_qos.watchdog_scheduling.scheduling_class.kind | SCHEDULE_DEFAULT | SCHEDULE_DEFAULT,SCHEDULE_TIMESHARING,SCHEDULE_REALTIME | |
opensplice.participant_qos.watchdog_scheduling.scheduling_priority | 1 | ||
opensplice.participant_qos.watchdog_scheduling.scheduling_priority_kind.kind | PRIORITY_RELATIVE | PRIORITY_RELATIVE,PRIORITY_ABSOLUTE | |
opensplice.publisher_qos.entity_factory.autoenable_created_entities | YES | YES,NO | |
opensplice.publisher_qos.presentation.access_scope | INSTANCE_PRESENTATION_QOS | INSTANCE_PRESENTATION_QOS,TOPIC_PRESENTATION_QOS,GROUP_PRESENTATION_QOS | |
opensplice.publisher_qos.presentation.coherent_access | YES | YES,NO | |
opensplice.publisher_qos.presentation.ordered_access | YES | YES,NO | |
opensplice.publisher_qos.id | testPublisher | ロードするPublisherのプロファイル名 | |
opensplice.subscriber_qos.entity_factory.autoenable_created_entities | YES | YES,NO | |
opensplice.subscriber_qos.presentation.access_scope | INSTANCE_PRESENTATION_QOS | INSTANCE_PRESENTATION_QOS,TOPIC_PRESENTATION_QOS,GROUP_PRESENTATION_QOS | |
opensplice.subscriber_qos.presentation.coherent_access | YES | YES,NO | |
opensplice.subscriber_qos.presentation.ordered_access | YES | YES,NO | |
opensplice.subscriber_qos.share.enable | YES | YES,NO | |
opensplice.subscriber_qos.id | testSubscriber | ロードするSubscriberのプロファイル名 |
以下に記述例を記載します。
opensplice.uri: file://OpenSpliceQoSExample.xml opensplice.profile: testProfile
オプション名 | 設定例 | オプション | 内容 |
opensplice.uri | file://OpenSpliceQoSExample.xml | OpenSpliceのQoS設定ファイルを指定する。 | |
opensplice.profile | testProfile | QoSのプロファイル名を指定する。 | |
opensplice.publisher_qos.presentation.access_scope | |||
opensplice.publisher_qos.presentation.coherent_access | |||
opensplice.publisher_qos.presentation.ordered_access | |||
opensplice.subscriber_qos.presentation.access_scope | |||
opensplice.subscriber_qos.presentation.coherent_access | |||
opensplice.subscriber_qos.presentation.ordered_access |
以下に記述例を記載します。
opensplice.uri: file://OpenSpliceQoSExample.xml opensplice.profile: testProfile
データポート接続時のコネクタプロファイルに設定できるオプションは以下の通りです。
オプション名 | デフォルト値 | オプション | 内容 |
opensplice.topic | chatter | DDSトピックの名前 | |
opensplice.reader_qos.id | ロードするReaderのプロファイル名 | ||
opensplice.writer_qos.id | ロードするWriterのプロファイル名 | ||
opensplice.topic_qos.id | ロードするTopicのプロファイル名 | ||
opensplice.reader_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | |
opensplice.reader_qos.deadline.period.sec | 2147483647 | ||
opensplice.reader_qos.deadline.period.nanosec | 2147483647 | ||
opensplice.reader_qos.latency_budget.duration.sec | 0 | ||
opensplice.reader_qos.latency_budget.duration.nanosec | 0 | ||
opensplice.reader_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
opensplice.reader_qos.liveliness.lease_duration.sec | 2147483647 | ||
opensplice.reader_qos.liveliness.lease_duration.nanosec | 2147483647 | ||
opensplice.reader_qos.reliability.kind | BEST_EFFORT_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | |
opensplice.reader_qos.reliability.max_blocking_time.sec | 2147483647 | ||
opensplice.reader_qos.reliability.max_blocking_time.nanosec | 2147483647 | ||
opensplice.reader_qos.reliability.synchronous | NO | YES, NO | |
opensplice.reader_qos.destination_order.kind | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
opensplice.reader_qos.history.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.reader_qos.history.depth | 1 | ||
opensplice.reader_qos.resource_limits.max_samples | -1 | ||
opensplice.reader_qos.resource_limits.max_instances | -1 | ||
opensplice.reader_qos.resource_limits.max_samples_per_instance | -1 | ||
opensplice.reader_qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
opensplice.reader_qos.time_based_filter.minimum_separation.sec | 0 | ||
opensplice.reader_qos.time_based_filter.minimum_separation.nanosec | 0 | ||
opensplice.reader_qos.reader_data_lifecycle.autopurge_disposed_samples_delay.sec | 2147483647 | ||
opensplice.reader_qos.reader_data_lifecycle.autopurge_disposed_samples_delay.nanosec | 2147483647 | ||
opensplice.reader_qos.reader_data_lifecycle.autopurge_dispose_all | NO | YES, NO | |
opensplice.reader_qos.reader_data_lifecycle.autopurge_nowriter_samples_delay.sec | 2147483647 | ||
opensplice.reader_qos.reader_data_lifecycle.autopurge_nowriter_samples_delay.nanosec | 2147483647 | ||
opensplice.reader_qos.reader_data_lifecycle.enable_invalid_samples | YES | YES, NO | |
opensplice.reader_qos.reader_data_lifecycle.invalid_sample_visibility.kind | MINIMUM_INVALID_SAMPLES | NO_INVALID_SAMPLES, MINIMUM_INVALID_SAMPLES, ALL_INVALID_SAMPLES | |
opensplice.writer_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | |
opensplice.writer_qos.deadline.period.sec | 2147483647 | ||
opensplice.writer_qos.deadline.period.nanosec | 2147483647 | ||
opensplice.writer_qos.latency_budget.duration.sec | 0 | ||
opensplice.writer_qos.latency_budget.duration.nanosec | 0 | ||
opensplice.writer_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
opensplice.writer_qos.liveliness.lease_duration.sec | 2147483647 | ||
opensplice.writer_qos.liveliness.lease_duration.nanosec | 2147483647 | ||
opensplice.writer_qos.reliability.kind | RELIABLE_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | |
opensplice.writer_qos.reliability.max_blocking_time.sec | 2147483647 | ||
opensplice.writer_qos.reliability.max_blocking_time.nanosec | 2147483647 | ||
opensplice.writer_qos.reliability.synchronous | NO | YES, NO | |
opensplice.writer_qos.destination_order.kind | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
opensplice.writer_qos.history.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.writer_qos.history.depth | 1 | ||
opensplice.writer_qos.resource_limits.max_samples | -1 | ||
opensplice.writer_qos.resource_limits.max_instances | -1 | ||
opensplice.writer_qos.resource_limits.max_samples_per_instance | -1 | ||
opensplice.writer_qos.transport_priority.value | 0 | ||
opensplice.writer_qos.lifespan.duration.sec | 2147483647 | ||
opensplice.writer_qos.lifespan.duration.nanosec | 2147483647 | ||
opensplice.writer_qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
opensplice.writer_qos.ownership_strength.value | 0 | ||
opensplice.writer_qos.writer_data_lifecycle.autodispose_unregistered_instances | YES | YES, NO | |
opensplice.writer_qos.writer_data_lifecycle.autopurge_suspended_samples_delay.sec | 2147483647 | ||
opensplice.writer_qos.writer_data_lifecycle.autopurge_suspended_samples_delay.nanosec | 2147483647 | ||
opensplice.writer_qos.writer_data_lifecycle.autounregister_instance_dela.sec | 2147483647 | ||
opensplice.writer_qos.writer_data_lifecycle.autounregister_instance_dela.nanosec | 2147483647 | ||
opensplice.topic_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | |
opensplice.topic_qos.deadline.period.sec | 2147483647 | ||
opensplice.topic_qos.deadline.period.nanosec | 2147483647 | ||
opensplice.topic_qos.latency_budget.duration.sec | 0 | ||
opensplice.topic_qos.latency_budget.duration.nanosec | 0 | ||
opensplice.topic_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
opensplice.topic_qos.liveliness.lease_duration.sec | 2147483647 | ||
opensplice.topic_qos.liveliness.lease_duration.nanosec | 2147483647 | ||
opensplice.topic_qos.reliability.kind | RELIABLE_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | |
opensplice.topic_qos.reliability.max_blocking_time.sec | 2147483647 | ||
opensplice.topic_qos.reliability.max_blocking_time.nanosec | 2147483647 | ||
opensplice.topic_qos.reliability.synchronous | NO | YES, NO | |
opensplice.topic_qos.destination_order.kind | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
opensplice.topic_qos.history.kind | KEEP_ALL_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.topic_qos.history.depth | 1 | ||
opensplice.topic_qos.resource_limits.max_samples | -1 | ||
opensplice.topic_qos.resource_limits.max_instances | -1 | ||
opensplice.topic_qos.resource_limits.max_samples_per_instance | -1 | ||
opensplice.topic_qos.transport_priority.value | 0 | ||
opensplice.topic_qos.lifespan.duration.sec | 2147483647 | ||
opensplice.topic_qos.lifespan.duration.nanosec | 2147483647 | ||
opensplice.topic_qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
opensplice.topic_qos.transport_priority.value | 0 | ||
opensplice.topic_qos.durability_service.history_depth | 1 | ||
opensplice.topic_qos.durability_service.history_kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.topic_qos.durability_service.max_instances | -1 | ||
opensplice.topic_qos.durability_service.max_samples | -1 | ||
opensplice.topic_qos.durability_service.max_samples_per_instance | -1 | ||
opensplice.topic_qos.durability_service.service_cleanup_delay.sec | 0 | ||
opensplice.topic_qos.durability_service.service_cleanup_delay.nanosec | 0 |
以下に設定例を記載します。
manager.components.preconnect: ConsoleOut0.in?interface_type=opensplice&opensplice.topic=testtopic
オプション名 | デフォルト値 | オプション | 内容 |
opensplice.topic | chatter | DDSトピックの名前 | |
opensplice.reader_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | |
opensplice.reader_qos.deadline.period.sec | 2147483647 | ||
opensplice.reader_qos.deadline.period.nanosec | 2147483647 | ||
opensplice.reader_qos.latency_budget.duration.sec | 0 | ||
opensplice.reader_qos.latency_budget.duration.nanosec | 0 | ||
opensplice.reader_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
opensplice.reader_qos.liveliness.lease_duration.sec | 2147483647 | ||
opensplice.reader_qos.liveliness.lease_duration.nanosec | 2147483647 | ||
opensplice.reader_qos.reliability.kind | BEST_EFFORT_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | |
opensplice.reader_qos.reliability.max_blocking_time.sec | 2147483647 | ||
opensplice.reader_qos.reliability.max_blocking_time.nanosec | 2147483647 | ||
opensplice.reader_qos.destination_order.kind | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
opensplice.reader_qos.history.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.reader_qos.history.depth | 1 | ||
opensplice.reader_qos.resource_limits.max_samples | -1 | ||
opensplice.reader_qos.resource_limits.max_instances | -1 | ||
opensplice.reader_qos.resource_limits.max_samples_per_instance | -1 | ||
opensplice.reader_qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
opensplice.reader_qos.time_based_filter.minimum_separation.sec | 0 | ||
opensplice.reader_qos.time_based_filter.minimum_separation.nanosec | 0 | ||
opensplice.reader_qos.autopurge_disposed_samples_delay.sec | 2147483647 | ||
opensplice.reader_qos.autopurge_disposed_samples_delay.nanosec | 2147483647 | ||
opensplice.reader_qos.reader_data_lifecycle.autopurge_nowriter_samples_delay.sec | 2147483647 | ||
opensplice.reader_qos.reader_data_lifecycle.autopurge_nowriter_samples_delay.nanosec | 2147483647 | ||
opensplice.writer_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | |
opensplice.writer_qos.deadline.period.sec | 2147483647 | ||
opensplice.writer_qos.deadline.period.nanosec | 2147483647 | ||
opensplice.writer_qos.latency_budget.duration.sec | 0 | ||
opensplice.writer_qos.latency_budget.duration.nanosec | 0 | ||
opensplice.writer_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
opensplice.writer_qos.liveliness.lease_duration.sec | 2147483647 | ||
opensplice.writer_qos.liveliness.lease_duration.nanosec | 2147483647 | ||
opensplice.writer_qos.reliability.kind | BEST_EFFORT_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | |
opensplice.writer_qos.reliability.max_blocking_time.sec | 2147483647 | ||
opensplice.writer_qos.reliability.max_blocking_time.nanosec | 2147483647 | ||
opensplice.writer_qos.destination_order.kind | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
opensplice.writer_qos.history.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.writer_qos.history.depth | 1 | ||
opensplice.writer_qos.resource_limits.max_samples | -1 | ||
opensplice.writer_qos.resource_limits.max_instances | -1 | ||
opensplice.writer_qos.resource_limits.max_samples_per_instance | -1 | ||
opensplice.writer_qos.transport_priority.value | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
opensplice.writer_qos.lifespan.duration.sec | 0 | ||
opensplice.writer_qos.lifespan.duration.nanosec | 0 | ||
opensplice.writer_qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
opensplice.writer_qos.ownership_strength.value | 0 | ||
opensplice.writer_qos.writer_data_lifecycle.autodispose_unregistered_instances | YES | YES, NO | |
opensplice.topic_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, TRANSIENT_DURABILITY_QOS, PERSISTENT_DURABILITY_QOS | |
opensplice.topic_qos.deadline.period.sec | 2147483647 | ||
opensplice.topic_qos.deadline.period.nanosec | 2147483647 | ||
opensplice.topic_qos.latency_budget.duration.sec | 0 | ||
opensplice.topic_qos.latency_budget.duration.nanosec | 0 | ||
opensplice.topic_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_PARTICIPANT_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS | |
opensplice.topic_qos.liveliness.lease_duration.sec | 2147483647 | ||
opensplice.topic_qos.liveliness.lease_duration.nanosec | 2147483647 | ||
opensplice.topic_qos.reliability.kind | RELIABLE_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS | |
opensplice.topic_qos.reliability.max_blocking_time.sec | 2147483647 | ||
opensplice.topic_qos.reliability.max_blocking_time.nanosec | 2147483647 | ||
opensplice.topic_qos.destination_order.kind | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS | BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS, BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS | |
opensplice.topic_qos.history.kind | KEEP_ALL_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.topic_qos.history.depth | 1 | ||
opensplice.topic_qos.resource_limits.max_samples | -1 | ||
opensplice.topic_qos.resource_limits.max_instances | -1 | ||
opensplice.topic_qos.resource_limits.max_samples_per_instance | -1 | ||
opensplice.topic_qos.transport_priority.value | 0 | ||
opensplice.topic_qos.lifespan.duration.sec | 2147483647 | ||
opensplice.topic_qos.lifespan.duration.nanosec | 2147483647 | ||
opensplice.topic_qos.ownership.kind | SHARED_OWNERSHIP_QOS | SHARED_OWNERSHIP_QOS, EXCLUSIVE_OWNERSHIP_QOS | |
opensplice.topic_qos.transport_priority.value | 0 | ||
opensplice.topic_qos.durability_service.history_depth | 1 | ||
opensplice.topic_qos.durability_service.history_kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS | |
opensplice.topic_qos.durability_service.max_instances | -1 | ||
opensplice.topic_qos.durability_service.max_samples | -1 | ||
opensplice.topic_qos.durability_service.max_samples_per_instance | -1 | ||
opensplice.topic_qos.durability_service.service_cleanup_delay.sec | 0 | ||
opensplice.topic_qos.durability_service.service_cleanup_delay.nanosec | 0 |
manager.components.preconnect: ConsoleOut0.in?interface_type=opensplice&opensplice.topic=testtopic
OpenSpliceのコンフィギュレーションファイルは環境変数${OSPL_URI}で設定している。
デフォルトでは${OSPL_URI}/etc/config/ospl.xmlが設定されている。
例えば、ドメインIDを変更するためにはospl.xmlの以下の部分を変更する。
<OpenSplice> <Domain> <Name>ospl_sp_ddsi</Name> <!-- 以下を変更する --> <Id>1</Id> <SingleProcess>true</SingleProcess>
詳細なログを出力するためには以下の部分を追加する。
<DDSI2Service name="ddsi2"> <!-- 以下を追加する --> <Tracing> <Verbosity>FINEST</Verbosity> </Tracing> <!-- ここまで --> <General>
このページではSSM(Streaming-data-Sharing-Manager )との通信プラグインの導入手順を説明します。
以降の作業はUbuntu 18.04環境を想定しています。
以下のコマンドでSSMをインストールします。
git clone https://github.com/sitRyo/Distributed-Streaming-data-Sharing-Manager -b 32-64bit cd Distributed-Streaming-data-Sharing-Manager/ ./configure --prefix=${OPENRTM_INSTALL_DIR} sudo autoreconf -i -f make make install
CMake実行時にSSM_ENABLEのオプションをONにします。SSMのインストール先を指定する場合はSSM_ROOTを設定します。
cmake -DSSM_ENABLE=ON -DSSM_ROOT=${OPENRTM_INSTALL_DIR} ..
その他の手順は通常と同じです。
ビルド後にインストールしてください。
cmake --build . --config Release --target install
以下のrtc.confを作成します。
manager.modules.load_path: /usr/local/lib/openrtm-2.0/transport/ manager.modules.preload: SSMTransport.so manager.components.preconnect: ConsoleOut0.in?interface_type=ssm&ssm.stream_name=test_stream&dataflow_type=pull, ConsoleIn0.out?interface_type=ssm&ssm.stream_name=test_stream manager.components.preactivation: ConsoleOut0, ConsoleIn0
RTCを起動する前にssm-coordinatorを起動します。
ssm-coordinator
ConsoleInComp、ConsoleOutCompをそれぞれ別のターミナルで起動するとデータの転送が確認できます。
データポート接続時のコネクタプロファイルに設定できるオプションは以下の通りです。
オプション名 | デフォルト値 | 内容 |
ssm.stream_name | sensor_test | |
ssm.stream_size | 0 | |
ssm.life_ssm_time | 5.0 | |
ssm.cycle_ssm_time | 0.05 | |
ssm.stream_id | 0 |
OpenRTM-aistをビルド、インストールすると、ROSTransportの簡単な動作確認用の設定ファイルがインストールされます。
${SSM_INSTALL_DIR}/bin/ssm-coordinator
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/transport/rtc.ssm.conf
Fluentd、Fluent Bitはログの処理や転送を行うオープンソースのソフトウェアライブラリです。
Fluentd、Fluent Bitはデータを収集するInputプラグイン、データを送信するOutputプラグインを設定できます。 Fluentd、Fluent Bitの概要図は以下のようになっています。
Inputは外部プロセスから受信、プロセス内部からのログ書き込み、CPU使用率やディスク使用率等を取得するなどで収集したデータをOutputに渡します。 Outputは受け取ったデータを外部プロセスへ送信、ファイルへ書き込み、標準出力等します。 Input、Outputはプラグインとして実装されており、プラグインを変更することでデータの収集方法や送信方法を変更できるため、以下のような様々なデータの収集方法、送信方法を選択できます。
またInputからOutputにデータを渡す前にFilterでデータの変換、追加、除外等を実行できます。
Inputにはタグが設定でき、Output、Filterにはマッチングルールを設定できます。 Output、Filerはマッチングルールに一致したタグのデータを受け取ることができます。
このページではOpenRTM-aistのFluent Loggerプラグインの使用方法を説明します。
Fluent BitのビルドにBison/Flexが必要なため適当な場所に展開して環境変数PATHに設定します。
set PATH=%WORKDIR%\win_flex_bison-2.5.24;%PATH%
OpenSSLを適当な場所に展開してください。
Windows用に修正したFluent Bitのソースコードを適当な場所に展開してPowerShellでそのフォルダに移動してください。
PowerShellで以下のコマンドを実行するとFluent Bitをビルドします。
cmake -DFLB_RELEASE=On -DFLB_TRACE=Off -DFLB_SHARED_LIB=On -DFLB_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release -DOPENSSL_ROOT_DIR=${OpenSSL_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${FLUENTBIT_INSTALL_DIR} cmake --build . --config Release cmake --build . --target install --config Release
以下のコマンドで必要なヘッダーファイルをコピーします。
$FLUENTBIT_BUILD_DIR = "${FLUENTBIT_SOURCE_DIR}\build"
Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\include\monkey\mk_core\external -destination $FLUENTBIT_INSTALL_DIR\include\monkey\mk_core -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\mk_core\deps\libevent\include\event.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\mk_core\deps\libevent\include\evutil.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\mk_core\deps\libevent\include\event2 -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_BUILD_DIR\lib\monkey\mk_core\deps\libevent\include\event2\event-config.h $FLUENTBIT_INSTALL_DIR\include\event2 Copy-Item $FLUENTBIT_SOURCE_DIR\lib\msgpack-*\include\msgpack.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_SOURCE_DIR\lib\msgpack-*\include\msgpack -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\mbedtls-*\include\mbedtls -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\c-ares-*\include\*.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_BUILD_DIR\lib\c-ares-*\ares_build.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_BUILD_DIR\lib\c-ares-*\ares_config.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_BUILD_DIR\lib\c-ares-*\ares_config.h $FLUENTBIT_INSTALL_DIR\include New-Item $FLUENTBIT_INSTALL_DIR\lib\fluent-bit -ItemType Directory Copy-Item $FLUENTBIT_BUILD_DIR\library\Release\fluent-bit.lib $FLUENTBIT_INSTALL_DIR\lib\fluent-bit Copy-Item $FLUENTBIT_SOURCE_DIR\lib\cmetrics\include\cmetrics -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\cmetrics\include\prometheus_remote_write -destination $FLUENTBIT_INSTALL_DIR\include -recurs
CMake実行時にFLUENTBIT_ENABLE、FLUENTBIT_ROOTのオプションを設定します。
cmake -DORB_ROOT=$ORB_ROOT -DFLUENTBIT_ENABLE=ON -DFLUENTBIT_ROOT=$FLUENTBIT_INSTALL_DIR -DCMAKE_INSTALL_PREFIX=$OPENRTM_INSTALL_DIR
他の手順は通常のビルド手順と同じです。
以下のコマンドでインストールしてください。
cmake --build . --target install --config Release
td-agent、もしくはtd-agent-bitをインストール、起動する必要があります。
rtc.confで以下のように設定する。tagの名前は適宜変更する。
logger.plugins: C:\\Program Files\\OpenRTM-aist\\logger\\2.0.0\\FluentBit.dll logger.logstream.fluentd.output0.plugin: forward logger.logstream.fluentd.output0.conf.match:* logger.logstream.fluentd.input0.plugin: lib logger.logstream.fluentd.input0.conf.tag: test.simpleio
RTCを実行するとログを送信する。
またはOpenRTM-aistに含まれるrtc.fluentbit_stream.confを使用して起動することもできます。
${OPENRTM_INSTALL_DIR}\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f ${OPENRTM_INSTALL_DIR}\2.0.0\ext\logger\rtc.fluentbit_stream.conf
sudo apt install flex bison wget https://github.com/fluent/fluent-bit/archive/v1.8.9.tar.gz tar xf v1.8.9.tar.gz cd fluent-bit-1.8.9/ sed -i -e 's/jemalloc-5.2.1\/configure/jemalloc-5.2.1\/configure --disable-initial-exec-tls/g' CMakeLists.txt cd build cmake .. -DFLB_RELEASE=On -DFLB_TRACE=Off -DFLB_JEMALLOC=On -DFLB_TLS=On -DFLB_SHARED_LIB=On -DFLB_EXAMPLES=Off -DFLB_HTTP_SERVER=On -DFLB_IN_SYSTEMD=On -DFLB_OUT_KAFKA=Off cmake --build . --config Release -- -j$(nproc) sudo cmake --build . --target install
以下のコマンドで必要なヘッダーファイルをコピーします。
export FLUENTBIT_SOURCE_DIR=${WORKSPACE}/fluent-bit-1.8.9 export FLUENTBIT_BUILD_DIR = ${FLUENTBIT_SOURCE_DIR}/build export FLUENTBIT_INSTALL_DIR=/usr/local
mkdir -p ${FLUENTBIT_INSTALL_DIR}/include/lib/flb_libco cp -r ${FLUENTBIT_SOURCE_DIR}/lib/flb_libco/libco.h ${FLUENTBIT_INSTALL_DIR}/include/lib/flb_libco cp -r ${FLUENTBIT_BUILD_DIR}/include/jemalloc ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/msgpack-*/include/* ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/monkey/include/monkey ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/mbedtls-*/include/mbedtls ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/c-ares-*/include/* ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_BUILD_DIR}/lib/c-ares-*/ares_build.h ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_BUILD_DIR}/lib/c-ares-*/ares_config.h ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/cmetrics/include/* ${FLUENTBIT_INSTALL_DIR}/include/ cp ${FLUENTBIT_SOURCE_DIR}/lib/flb_libco/libco.h ${FLUENTBIT_INSTALL_DIR}/include/
CMake実行時にFLUENTBIT_ENABLE、FLUENTBIT_ROOTのオプションを設定します。
cmake -DFLUENTBIT_ENABLE=ON -DFLUENTBIT_ROOT=${FLUENTBITINSTALLDIR} ..
他の手順は通常のビルド手順と同じです。
以下のコマンドでインストールしてください。
cmake --build . --target install
td-agent、もしくはtd-agent-bitをインストール、起動する必要があります。
rtc.confで以下のように設定する。tagの名前は適宜変更する。
logger.plugins: /usr/local/lib/openrtm-2.0/logger/FluentBit.so logger.logstream.fluentd.output0.plugin: forward logger.logstream.fluentd.output0.conf.match:* logger.logstream.fluentd.input0.plugin: lib logger.logstream.fluentd.input0.tag: test.simpleio
RTCを実行するとログを送信する。
動作しない場合は/etc/ssl/certsから壊れたリンクを削除する。
またはOpenRTM-aistに含まれるrtc.fluentbit_stream.confを使用して起動することもできます。
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/logger/rtc.fluentbit_stream.conf
Python版のFluent LoggerプラグインはForward Outputのみに対応しています。 別にForward通信を受信するFluentd、Fluent Bitを起動して、処理して他のOutputプラグインで送信するという使い方ができます。
fluent-logger-pythonのインストールが必要です。
pip install fluent-logger
Ubuntuの場合はsudoで実行してください。
td-agent、もしくはtd-agent-bitをインストールする必要があります。
rtc.confに以下のように記述してRTCを起動するとfluentdにログが送信されます。
manager.modules.load_path: C:\\Python37\\Lib\\site-packages\\OpenRTM_aist\\ext\\logger\\fluentlogger logger.plugins: FluentLogger.py logger.logstream.fluentd.output0.tag: test.simpleio
manager.modules.load_pathはOpenRTM-aistをインストールしたPythonのパスによって適宜変更してください。 Ubuntuの場合は/usr/local/lib/python2.7/dist-packages/OpenRTM_aist/ext/logger/fluentlogger等になります。
fluentdでログは以下のように表示される。
2018-12-26 09:06:18.000000000 +0900 test.simpleio: {"message":"exit","time":"2018-12-26 09:06:18,841","name":"fluent.ec_worker","level":"TRACE"}
メッセージの内容、名前、ログを送信した時間、ログレベルが送信される。
OpenRTM-aistをビルド、インストールすると、Fluent Loggerプラグインの簡単な動作確認用の設定ファイルがインストールされます。
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\logger\rtc.fluentbit_stream.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/logger/rtc.fluentbit_stream.conf
KibanaはElastic社の開発したデータ可視化ツールです。 分析エンジンElasticSearchと連携してWebブラウザ上でグラフなどのデータ可視化ができるようになります。
OpenRTM-aistのFluent BitプラグインからElasticSearchにログを送信して、Kibanaでデータを可視化する手順を説明します。
Ubuntu 18.04環境で以下のコマンドによりElasticsearchをインストールします。 Ubuntu 18.04ではElasticsearchのバージョン次第で動作しない場合があるので、こちらで動作を確認した7.8.0をインストールします。
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - add-apt-repository "deb https://artifacts.elastic.co/packages/7.x/apt stable main" sudo apt update sudo apt install elasticsearch=7.8.0 sudo systemctl daemon-reload sudo systemctl enable elasticsearch.service
/etc/elasticsearch/elasticsearch.ymlを編集します。
network.bind_host: 0 discovery.seed_hosts: ["127.0.0.1", "[::1]"]
編集後にサービスを再起動します。
sudo systemctl restart elasticsearch.service
メモリの不足で起動できない場合は/etc/elasticesearch/jvm.optionsを編集して調節してください。
-Xms1g -Xmx1g
以下のコマンドでKibanaをインストールします。Elasticsearchと同じバージョンを指定します。
sudo apt install kibana=7.8.0 sudo systemctl daemon-reload sudo systemctl enable kibana.service
また、/etc/kibana/kibana.ymlに以下の行を追加します。
server.port: 5601 server.host: "0.0.0.0"
server.hostにNICに設定されたIPアドレスを指定してください。
server.host: "192.168.11.2"
サービスを再起動します。
sudo systemctl restart kibana.service
以下のrtc.confを作成してください。
logger.enable: YES logger.log_level: INFO logger.plugins: ${OPNRTM_INSTALL_DIR}/lib/openrtm-2.0/logger/FluentBit.so logger.logstream.fluentd.input.plugin: lib logger.logstream.fluentd.input.conf.tag: myRTCs_log logger.logstream.fluentd.output0.plugin: es logger.logstream.fluentd.output0.conf.match: * logger.logstream.fluentd.output0.conf.host: 127.0.0.1 logger.logstream.fluentd.output0.conf.port: 9200 logger.logstream.fluentd.output0.conf.Index: fluentbit
${OPNRTM_INSTALL_DIR}はOpenRTM-aistをインストールしたパスに置き換えてください。 host、portにElasticsearchのアドレスとポート番号を指定してください。 Indexやtagは任意の文字列を設定します。
このrtc.confを指定してRTCを起動します。
./share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
次にWebブラウザからKibanaにアクセスしてログを確認します。 http://127.0.0.1:5601にアクセスしてください。別の端末からアクセスする場合はIPアドレスを変更してください。
可視化するデータのインデックスパターンを設定します。今回の例ではrtc.confでIndexをfluentbitに指定しました。 ページが開いたら左上をクリックして表示されたメニューからManagmentのStack Managementをクリックしてください。
Stack Managementのページの左側のIndex Patternsをクリックします。
Index patternsのページのCreate Index patternボタンを押します。
Create index patternのページでIndex patternをfluentbit*に指定してNext stepボタンを押します。
Step 2でTime Filter field nameは@timestampのままCreate index patternボタンを押します。
ここからはデータを確認します。 ページ左上をクリックして、メニューからKibanaのDiscoverをクリックしてください。
Discoverの画面で左側にインデックスパターンが表示されているため、インデックスパターンをクリックして先ほど設定したfluentbit*に切り替えます。
これでログの一覧が確認できます。グラフなどで利用する手順についてはKibanaのマニュアルなどを参考にしてください。
OpenRTM-aist Python版で動作確認する場合はElasticsearch Loggerプラグインを使用します。 まずはelasticsearchのPythonライブラリ、ECSentbit:https://fluentbit.io/]]
Fluentd、Fluent Bitはデータを収集するInputプラグイン、データを送信するOutputプラグインを設定できます。 Fluentd、Fluent Bitの概要図は以下のようになっています。
Inputは外部プロセスから受信、プロセス内部からのログ書き込み、CPU使用率やディスク使用率等を取得するなどで収集したデータをOutputに渡します。 Outputは受け取ったデータを外部プロセスへ送信、ファイルへ書き込み、標準出力等します。 Input、Outputはプラグインとして実装されており、プラグインを変更することでデータの収集方法や送信方法を変更できるため、以下のような様々なデータの収集方法、送信方法を選択できます。
またInputからOutputにデータを渡す前にFilterでデータの変換、追加、除外等を実行できます。
Inputにはタグが設定でき、Output、Filterにはマッチングルールを設定できます。 Output、Filerはマッチングルールに一致したタグのデータを受け取ることができます。
このページではOpenRTM-aistのFluent Loggerプラグインの使用方法を説明します。
Fluent BitのビルドにBison/Flexが必要なため適当な場所に展開して環境変数PATHに設定します。
set PATH=%WORKDIR%\win_flex_bison-2.5.24;%PATH%
OpenSSLを適当な場所に展開してください。
Windows用に修正したFluent Bitのソースコードを適当な場所に展開してPowerShellでそのフォルダに移動してください。
PowerShellで以下のコマンドを実行するとFluent Bitをビルドします。
cmake -DFLB_RELEASE=On -DFLB_TRACE=Off -DFLB_SHARED_LIB=On -DFLB_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release -DOPENSSL_ROOT_DIR=${OpenSSL_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${FLUENTBIT_INSTALL_DIR} cmake --build . --config Release cmake --build . --target install --config Release
以下のコマンドで必要なヘッダーファイルをコピーします。
$FLUENTBIT_BUILD_DIR = "${FLUENTBIT_SOURCE_DIR}\build"
Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\include\monkey\mk_core\external -destination $FLUENTBIT_INSTALL_DIR\include\monkey\mk_core -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\mk_core\deps\libevent\include\event.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\mk_core\deps\libevent\include\evutil.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_SOURCE_DIR\lib\monkey\mk_core\deps\libevent\include\event2 -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_BUILD_DIR\lib\monkey\mk_core\deps\libevent\include\event2\event-config.h $FLUENTBIT_INSTALL_DIR\include\event2 Copy-Item $FLUENTBIT_SOURCE_DIR\lib\msgpack-*\include\msgpack.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_SOURCE_DIR\lib\msgpack-*\include\msgpack -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\mbedtls-*\include\mbedtls -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\c-ares-*\include\*.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_BUILD_DIR\lib\c-ares-*\ares_build.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_BUILD_DIR\lib\c-ares-*\ares_config.h $FLUENTBIT_INSTALL_DIR\include Copy-Item $FLUENTBIT_BUILD_DIR\lib\c-ares-*\ares_config.h $FLUENTBIT_INSTALL_DIR\include New-Item $FLUENTBIT_INSTALL_DIR\lib\fluent-bit -ItemType Directory Copy-Item $FLUENTBIT_BUILD_DIR\library\Release\fluent-bit.lib $FLUENTBIT_INSTALL_DIR\lib\fluent-bit Copy-Item $FLUENTBIT_SOURCE_DIR\lib\cmetrics\include\cmetrics -destination $FLUENTBIT_INSTALL_DIR\include -recurs Copy-Item $FLUENTBIT_SOURCE_DIR\lib\cmetrics\include\prometheus_remote_write -destination $FLUENTBIT_INSTALL_DIR\include -recurs
CMake実行時にFLUENTBIT_ENABLE、FLUENTBIT_ROOTのオプションを設定します。
cmake -DORB_ROOT=$ORB_ROOT -DFLUENTBIT_ENABLE=ON -DFLUENTBIT_ROOT=$FLUENTBIT_INSTALL_DIR -DCMAKE_INSTALL_PREFIX=$OPENRTM_INSTALL_DIR
他の手順は通常のビルド手順と同じです。
以下のコマンドでインストールしてください。
cmake --build . --target install --config Release
td-agent、もしくはtd-agent-bitをインストール、起動する必要があります。
rtc.confで以下のように設定する。tagの名前は適宜変更する。
logger.plugins: C:\\Program Files\\OpenRTM-aist\\logger\\2.0.0\\FluentBit.dll logger.logstream.fluentd.output0.plugin: forward logger.logstream.fluentd.output0.conf.match:* logger.logstream.fluentd.input0.plugin: lib logger.logstream.fluentd.input0.conf.tag: test.simpleio
RTCを実行するとログを送信する。
またはOpenRTM-aistに含まれるrtc.fluentbit_stream.confを使用して起動することもできます。
${OPENRTM_INSTALL_DIR}\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f ${OPENRTM_INSTALL_DIR}\2.0.0\ext\logger\rtc.fluentbit_stream.conf
sudo apt install flex bison wget https://github.com/fluent/fluent-bit/archive/v1.8.9.tar.gz tar xf v1.8.9.tar.gz cd fluent-bit-1.8.9/ sed -i -e 's/jemalloc-5.2.1\/configure/jemalloc-5.2.1\/configure --disable-initial-exec-tls/g' CMakeLists.txt cd build cmake .. -DFLB_RELEASE=On -DFLB_TRACE=Off -DFLB_JEMALLOC=On -DFLB_TLS=On -DFLB_SHARED_LIB=On -DFLB_EXAMPLES=Off -DFLB_HTTP_SERVER=On -DFLB_IN_SYSTEMD=On -DFLB_OUT_KAFKA=Off cmake --build . --config Release -- -j$(nproc) sudo cmake --build . --target install
以下のコマンドで必要なヘッダーファイルをコピーします。
export FLUENTBIT_SOURCE_DIR=${WORKSPACE}/fluent-bit-1.8.9 export FLUENTBIT_BUILD_DIR = ${FLUENTBIT_SOURCE_DIR}/build export FLUENTBIT_INSTALL_DIR=/usr/local
mkdir -p ${FLUENTBIT_INSTALL_DIR}/include/lib/flb_libco cp -r ${FLUENTBIT_SOURCE_DIR}/lib/flb_libco/libco.h ${FLUENTBIT_INSTALL_DIR}/include/lib/flb_libco cp -r ${FLUENTBIT_BUILD_DIR}/include/jemalloc ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/msgpack-*/include/* ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/monkey/include/monkey ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/mbedtls-*/include/mbedtls ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/c-ares-*/include/* ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_BUILD_DIR}/lib/c-ares-*/ares_build.h ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_BUILD_DIR}/lib/c-ares-*/ares_config.h ${FLUENTBIT_INSTALL_DIR}/include/ cp -r ${FLUENTBIT_SOURCE_DIR}/lib/cmetrics/include/* ${FLUENTBIT_INSTALL_DIR}/include/ cp ${FLUENTBIT_SOURCE_DIR}/lib/flb_libco/libco.h ${FLUENTBIT_INSTALL_DIR}/include/
CMake実行時にFLUENTBIT_ENABLE、FLUENTBIT_ROOTのオプションを設定します。
cmake -DFLUENTBIT_ENABLE=ON -DFLUENTBIT_ROOT=${FLUENTBITINSTALLDIR} ..
他の手順は通常のビルド手順と同じです。
以下のコマンドでインストールしてください。
cmake --build . --target install
td-agent、もしくはtd-agent-bitをインストール、起動する必要があります。
rtc.confで以下のように設定する。tagの名前は適宜変更する。
logger.plugins: /usr/local/lib/openrtm-2.0/logger/FluentBit.so logger.logstream.fluentd.output0.plugin: forward logger.logstream.fluentd.output0.conf.match:* logger.logstream.fluentd.input0.plugin: lib logger.logstream.fluentd.input0.tag: test.simpleio
RTCを実行するとログを送信する。
動作しない場合は/etc/ssl/certsから壊れたリンクを削除する。
またはOpenRTM-aistに含まれるrtc.fluentbit_stream.confを使用して起動することもできます。
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/logger/rtc.fluentbit_stream.conf
Python版のFluent LoggerプラグインはForward Outputのみに対応しています。 別にForward通信を受信するFluentd、Fluent Bitを起動して、処理して他のOutputプラグインで送信するという使い方ができます。
fluent-logger-pythonのインストールが必要です。
pip install fluent-logger
Ubuntuの場合はsudoで実行してください。
td-agent、もしくはtd-agent-bitをインストールする必要があります。
rtc.confに以下のように記述してRTCを起動するとfluentdにログが送信されます。
manager.modules.load_path: C:\\Python37\\Lib\\site-packages\\OpenRTM_aist\\ext\\logger\\fluentlogger logger.plugins: FluentLogger.py logger.logstream.fluentd.output0.tag: test.simpleio
manager.modules.load_pathはOpenRTM-aistをインストールしたPythonのパスによって適宜変更してください。 Ubuntuの場合は/usr/local/lib/python2.7/dist-packages/OpenRTM_aist/ext/logger/fluentlogger等になります。
fluentdでログは以下のように表示される。
2018-12-26 09:06:18.000000000 +0900 test.simpleio: {"message":"exit","time":"2018-12-26 09:06:18,841","name":"fluent.ec_worker","level":"TRACE"}
メッセージの内容、名前、ログを送信した時間、ログレベルが送信される。
OpenRTM-aistをビルド、インストールすると、Fluent Loggerプラグインの簡単な動作確認用の設定ファイルがインストールされます。
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\logger\rtc.fluentbit_stream.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/logger/rtc.fluentbit_stream.conf
KibanaはElastic社の開発したデータ可視化ツールです。 分析エンジンElasticSearchと連携してWebブラウザ上でグラフなどのデータ可視化ができるようになります。
OpenRTM-aistのFluent BitプラグインからElasticSearchにログを送信して、Kibanaでデータを可視化する手順を説明します。
Ubuntu 18.04環境で以下のコマンドによりElasticsearchをインストールします。 Ubuntu 18.04ではElasticsearchのバージョン次第で動作しない場合があるので、こちらで動作を確認した7.8.0をインストールします。
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - add-apt-repository "deb https://artifacts.elastic.co/packages/7.x/apt stable main" sudo apt update sudo apt install elasticsearch=7.8.0 sudo systemctl daemon-reload sudo systemctl enable elasticsearch.service
/etc/elasticsearch/elasticsearch.ymlを編集します。
network.bind_host: 0 discovery.seed_hosts: ["127.0.0.1", "[::1]"]
編集後にサービスを再起動します。
sudo systemctl restart elasticsearch.service
メモリの不足で起動できない場合は/etc/elasticesearch/jvm.optionsを編集して調節してください。
-Xms1g -Xmx1g
以下のコマンドでKibanaをインストールします。Elasticsearchと同じバージョンを指定します。
sudo apt install kibana=7.8.0 sudo systemctl daemon-reload sudo systemctl enable kibana.service
また、/etc/kibana/kibana.ymlに以下の行を追加します。
server.port: 5601 server.host: "0.0.0.0"
server.hostにNICに設定されたIPアドレスを指定してください。
server.host: "192.168.11.2"
サービスを再起動します。
sudo systemctl restart kibana.service
以下のrtc.confを作成してください。
logger.enable: YES logger.log_level: INFO logger.plugins: ${OPNRTM_INSTALL_DIR}/lib/openrtm-2.0/logger/FluentBit.so logger.logstream.fluentd.input.plugin: lib logger.logstream.fluentd.input.conf.tag: myRTCs_log logger.logstream.fluentd.output0.plugin: es logger.logstream.fluentd.output0.conf.match: * logger.logstream.fluentd.output0.conf.host: 127.0.0.1 logger.logstream.fluentd.output0.conf.port: 9200 logger.logstream.fluentd.output0.conf.Index: fluentbit
${OPNRTM_INSTALL_DIR}はOpenRTM-aistをインストールしたパスに置き換えてください。 host、portにElasticsearchのアドレスとポート番号を指定してください。 Indexやtagは任意の文字列を設定します。
このrtc.confを指定してRTCを起動します。
./share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
次にWebブラウザからKibanaにアクセスしてログを確認します。 http://127.0.0.1:5601にアクセスしてください。別の端末からアクセスする場合はIPアドレスを変更してください。
可視化するデータのインデックスパターンを設定します。今回の例ではrtc.confでIndexをfluentbitに指定しました。 ページが開いたら左上をクリックして表示されたメニューからManagmentのStack Managementをクリックしてください。
Stack Managementのページの左側のIndex Patternsをクリックします。
Index patternsのページのCreate Index patternボタンを押します。
Create index patternのページでIndex patternをfluentbit*に指定してNext stepボタンを押します。
Step 2でTime Filter field nameは@timestampのままCreate index patternボタンを押します。
ここからはデータを確認します。 ページ左上をクリックして、メニューからKibanaのDiscoverをクリックしてください。
Discoverの画面で左側にインデックスパターンが表示されているため、インデックスパターンをクリックして先ほど設定したfluentbit*に切り替えます。
これでログの一覧が確認できます。グラフなどで利用する手順についてはKibanaのマニュアルなどを参考にしてください。
OpenRTM-aist Python版で動作確認する場合はElasticsearch Loggerプラグインを使用します。 まずはelasticsearchのPythonライブラリ、ECSフォーマッタ をインストールします。elasticsearchのバージョンには注意してください。
pip install elasticsearch==7.8.0 pip install ecs-logging
以下のようなrtc.confを用意してESLogger.pyをロードしてください。
logger.enable: YES logger.log_level: PARANOID logger.plugins: C:\\Python37\\Lib\\site-packages\\OpenRTM_aist\\ext\\logger\\eslogger\\ESLogger.py logger.logstream.elasticsearch.output0.host: 127.0.0.1 logger.logstream.elasticsearch.output0.port: 9200 logger.logstream.elasticsearch.output0.index: fluentbit
接続先のElasticsearchサーバーのアドレス、ポート番号、データを登録するインデックスを指定してください。
このrtc.confを指定してRTCを起動します。
ConsoleOut.py -f rtc.conf
ほとんど以下のページと手順は同じです。
Fluentdをインストールしてください。
インストール後、Td-agent Command Promptを起動してください。
次にtd-agentをインストールしたフォルダ(C:\opt\td-agent)にconf\td-agent.confというファイルを作成します。
C:\opt\td-agent |- conf |-td-agent.conf
td-agent.confには以下の内容を記述します。
<source> @type forward </source> <match test.**> @type stdout </match>
Td-agent Command Promptで以下のコマンドを入力してfluentdを実行します。
> fluentd -c conf\td-agent.conf
以下のコマンドでFluentdをインストールします。
curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-bionic-td-agent4.sh | sh
次に設定ファイル(/etc/td-agent/td-agent.conf)を編集します。
<source> @type forward </source> <match test.**> @type stdout </match>
以下のコマンドでtd-agentを起動します。念のためtd-agentサービスは停止します。
sudo systemctl stop td-agent.service ※念のためサービス停止 /usr/sbin/td-agent
以下のコマンドでtd-agent-bitをインストールします。
wget -qO - https://packages.fluentbit.io/fluentbit.key | sudo apt-key add - sudo echo "deb https://packages.fluentbit.io/ubuntu/bionic bionic main" >> /etc/apt/sources.list sudo apt-get update sudo apt-get install td-agent-bit
以下のコマンドでfluent-bitを起動します。
fluent-bit -i forward -F stdout -m 'test.*' -o null
以下のページの指示に従いインストールします。
以下のコマンドでインストールします。
> choco install -y python
以下からWin64OpenSSL-1_0_2r.exeを入手して、それを実行してインストールします。
以下の環境変数を設定します。
OPENSSL_CONF | C:\OpenSSL-Win64\bin\openssl.cfg |
環境変数PATHにC:\OpenSSL-Win64\binを追加します。
以下のページからNuGetパッケージ(.nupkg)ファイルをダウンロードしてください。
以下のコマンドでインストールします。依存するNugetパッケージが増える場合もあるようなので、適宜変更してください。
> choco install -y -s <'''ダウンロードしたパス'''> asio eigen tinyxml-usestl tinyxml2 log4cxx
以下のコマンドでインストールします。
> python -m pip install -U catkin_pkg empy pyparsing pyyaml setuptools
以下のページからros2-****-********-windows-release-amd64.zipをダウンロードします。
C:\dev\ros2等に展開して完了です。
CMake実行前にROS2の環境を設定するスクリプトを実行します。
> call C:\dev\ros2\local_setup.bat
CMake実行時にFASTRTPS_ENABLE、ROS2_ENABLEのオプションをONにします。
> cmake -DORB_ROOT=C:/workspace/omniORB-4.2.3-win64-vc14 -G "Visual Studio 16 2019" -A x64 -DFASTRTPS_ENABLE=ON -DROS2_ENABLE=ON ..
その他の手順は通常と同じです。
適当な場所にインストールしてください。
インストールするディレクトリはCMAKE_INSTALL_PREFIXのオプションで設定します。
> cmake .. -DCMAKE_INSTALL_PREFIX=C:/workspace/OpenRTM-aist/build_omni/install > cmake --build . --config Release --target install
<'インストールしたパス'>\2.0.0\Components\C++\Examples\vc14のサンプルコンポーネントを実行します。
以下の内容のrtc.confを作成してください。
manager.modules.load_path: {インストールしたパス}\\2.0.0\\ext\\transport manager.modules.preload: FastRTPSTransport.dll, ROS2Transport.dll manager.components.preconnect: ConsoleOut0.in?interface_type=fast-rtps&marshaling_type=ros2:std_msgs/Float32&fast-rtps.topic=chatter, ConsoleIn0.out?interface_type=fast-rtps&marshaling_type=ros2:std_msgs/Float32&fast-rtps.topic=chatter manager.components.preactivation: ConsoleOut0, ConsoleIn0
ROS/ROS2用のシリアライザと対応するROS/ROS2メッセージ型の関係を以下のリンクで示します。
コネクタの生成はmanager.components.preconnectオプションにより設定します。 この例ではConsoleOut0コンポーネントのinのポート、ConsoleIn0コンポーネントのoutのポートにそれぞれコネクタを生成しています。
実行前に環境変数PATHに以下を追加する必要があります。
ConsoleInComp.exe、ConsoleOutComp.exeを実行すると通信ができるようになります。
以下のコマンドでインストールします。
$ curl http://repo.ros2.org/repos.key | sudo apt-key add - $ sudo sh -c 'echo "deb [arch=amd64,arm64] http://repo.ros2.org/ubuntu/main $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros2-latest.list' $ export ROS_DISTRO=crystal $ sudo apt update $ sudo apt install ros-${ROS_DISTRO}-ros-core
ROS2用にbashの設定を以下のように行います。(次回以降のbash起動時の設定と、現在実行中のbashの設定を行います。)
echo "source /opt/ros/crystal/setup.bash" >> ~/.bashrc source ~/.bashrc
CMake実行時にFASTRTPS_ENABLE、ROS2_ENABLEのオプションをONにします。
$ cmake -DCORBA=omniORB -DCMAKE_BUILD_TYPE=Release -DFASTRTPS_ENABLE=ON -DROS2_ENABLE=ON ..
その他の手順は通常と同じです。
ビルド後にインストールしてください。
$ cmake --build . --target install
以下のrtc.confを作成します。
manager.modules.load_path: /usr/local/lib/openrtm-2.0/transport/ manager.modules.preload: FastRTPSTransport.so, ROS2Transport.so manager.components.preconnect: ConsoleOut0.in?interface_type=fast-rtps&marshaling_type=ros2:std_msgs/Float32&fast-rtps.topic=chatter, ConsoleIn0.out?interface_type=fast-rtps&marshaling_type=ros2:std_msgs/Float32&fast-rtps.topic=chatter manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aistのシリアライザが対応しているメッセージ型を以下に示します。
RTCを起動して動作確認します。
それぞれ別のターミナルから起動してください。
/usr/local/share/openrtm-2.0/components/c++/examples/ConsoleInComp
/usr/local/share/openrtm-2.0/components/c++/examples/ConsoleOutComp
C++版と同じ手順でROS2をインストールしてください。
OpenRTM-aist 1.2等をインストーラーでインストールしておいてください。 OpenRTM-aist Python版のソースコードを入手してください。
以下のコマンドでOpenRTM-aist Python版をインストールしてください。
python setup.py build python setup.py install
動作前に以下のコマンドを実行してください。
call C:\dev\ros2\setup.bat
以下のようなrtc.confを作成し、ROS2Transport.pyをロード後、インターフェース型にopenspliceを指定して起動します。
manager.modules.load_path: C:\\Python37\\Lib\\site-packages\\OpenRTM_aist\\ext\\transport\\ROS2Transport manager.modules.preload: ROS2Transport.py manager.components.preconnect: ConsoleOut0.in?interface_type=ros2&marshaling_type=ros2:std_msgs/Float32&ros2.topic=chatter, ConsoleIn0.out?interface_type=ros2&marshaling_type=ros2:std_msgs/Float32&ros2.topic=chatter manager.components.preactivation: ConsoleOut0, ConsoleIn0
以下のコマンドでインストールします。
$ curl http://repo.ros2.org/repos.key | sudo apt-key add - $ sudo sh -c 'echo "deb [arch=amd64,arm64] http://repo.ros2.org/ubuntu/main $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros2-latest.list' $ export ROS_DISTRO=crystal $ sudo apt update $ sudo apt install ros-${ROS_DISTRO}-desktop
ROS2の環境設定のbashを実行するようにします。
$ echo "source /opt/ros/crystal/setup.bash" >> ~/.bashrc $ source ~/.bashrc
$ sudo apt-get install python-omniorb-omg omniidl-python doxygen
OpenRTM-aist Python版のソースコードを入手してください。
以下のコマンドでOpenRTM-aist Python版をビルド/インストールしてください。
$ python setup.py build $ python setup.py install
ros2のsetup.bashを実行するとPYTHONPATHが上書きされるようなので以下のコマンドを実行する。
$ export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.6/site-packages $ export PATH=$PATH:/usr/local/lib/python3.6/site-packages/
omniORBpyがインストールされているディレクトリにあわせて変更してください。
以下のようなrtc.confを作成し、ROS2Transport.pyをロードし、インターフェース型にros2、シリアライザにros2:std_msgs/Float32を指定して起動するように指定します。
manager.modules.load_path: /usr/local/lib/python3.6/site-packages/OpenRTM_aist/ext/transport/ROS2Transport/ manager.modules.preload: ROS2Transport.py manager.components.preconnect: ConsoleOut0.in?interface_type=ros2&marshaling_type=ros2:std_msgs/Float32&ros2.topic=chatter, ConsoleIn0.out?interface_type=ros2&marshaling_type=ros2:std_msgs/Float32&ros2.topic=chatter manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aistのシリアライザが対応しているメッセージ型を以下に示します。
以下のコマンドでRTCを起動して動作確認してください。
$ python /usr/local/share/openrtm-2.0/components/python/SimpleIO/ConsoleIn.py
$ python /usr/local/share/openrtm-2.0/components/python/SimpleIO/ConsoleOut.py
Fast DDS通信機能のオプションを設定してください。
以下のオプションが設定できます。
オプション名 | 設定例 | 内容 |
ros2.args | rclpy.initの引数args | |
ros2.node.name | node_name | ノード名 |
Fast DDS通信機能のオプションを設定してください。
接続時に設定可能な項目は以下の通りです。
オプション名 | デフォルト値 | オプション | 内容 | |
marshaling_type | シリアライザの種類。ros:std_msgs/Float32などが設定できる。 | |||
ros2.topic | chatter | DDSトピック名 | ||
ros2.reader_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, SYSTEM_DEFAULT_QOS | 送信側の堅牢性(VOLATILE_DURABILITY_QOS:変わりやすい、TRANSIENT_LOCAL_DURABILITY_QOS:一時的なローカル設定) | |
ros2.reader_qos.deadline.period.sec | 0 | 受信側の最小周期 | ||
ros2.reader_qos.deadline.period.nanosec | 0 | |||
ros2.reader_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS, SYSTEM_DEFAULT_LIVELINESS_QOS | ||
ros2.reader_qos.liveliness.lease_duration.sec | 0 | 受信側のハートビートの周期 | ||
ros2.reader_qos.liveliness.lease_duration.nanosec | 0 | |||
ros2.reader_qos.reliability.kind | RELIABLE_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS, SYSTEM_DEFAULT_RELIABILITY_QOS | 受信側の信頼性(RELIABLE_RELIABILITY_QOS:高信頼、BEST_EFFORT_RELIABILITY_QOS:最高速度) | |
ros2.reader_qos.history.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS, SYSTEM_DEFAULT_HISTORY_QOS | 受信データの保持方法(KEEP_ALL_HISTORY_QOS:すべてのデータを保持、KEEP_LAST_HISTORY_QOSで指定したデータ数だけ保持) | KEEP_LAST |
ros2.reader_qos.history.depth | 1 | 受信側の保持するデータ数 | ||
ros2.reader_qos.lifespan.duration.sec | 0 | |||
ros2.reader_qos.lifespan.duration.nanosec | 0 | |||
ros2.reader_qos.avoid_ros_namespace_conventions | YES | YES, NO | ||
ros2.writer_qos.durability.kind | TRANSIENT_DURABILITY_QOS | VOLATILE_DURABILITY_QOS, TRANSIENT_LOCAL_DURABILITY_QOS, SYSTEM_DEFAULT_QOS | 送信側の堅牢性(VOLATILE_DURABILITY_QOS:変わりやすい、TRANSIENT_LOCAL_DURABILITY_QOS:一時的なローカル設定) | |
ros2.writer_qos.deadline.period.sec | 0 | 送信側の最小周期 | ||
ros2.writer_qos.deadline.period.nanosec | 0 | |||
ros2.writer_qos.liveliness.kind | AUTOMATIC_LIVELINESS_QOS | AUTOMATIC_LIVELINESS_QOS, MANUAL_BY_TOPIC_LIVELINESS_QOS, SYSTEM_DEFAULT_LIVELINESS_QOS | ||
ros2.writer_qos.liveliness.lease_duration.sec | 0 | 送信側のハートビートの周期 | ||
ros2.writer_qos.liveliness.lease_duration.nanosec | 0 | |||
ros2.writer_qos.reliability.kind | RELIABLE_RELIABILITY_QOS | BEST_EFFORT_RELIABILITY_QOS, RELIABLE_RELIABILITY_QOS, SYSTEM_DEFAULT_RELIABILITY_QOS | 送信側の信頼性(RELIABLE_RELIABILITY_QOS:高信頼、BEST_EFFORT_RELIABILITY_QOS:最高速度) | |
ros2.writer_qos.history.kind | KEEP_LAST_HISTORY_QOS | KEEP_LAST_HISTORY_QOS, KEEP_ALL_HISTORY_QOS, SYSTEM_DEFAULT_HISTORY_QOS | 送信データの保持方法(KEEP_ALL_HISTORY_QOS:すべてのデータを保持、KEEP_LAST_HISTORY_QOSで指定したデータ数だけ保持) | |
ros2.writer_qos.history.depth | 1 | 送信側の保持するデータ数 | ||
ros2.writer_qos.lifespan.duration.sec | 0 | 送信側の未送信データの保持時間 | ||
ros2.writer_qos.lifespan.duration.nanosec | 0 | |||
ros2.writer_qos.avoid_ros_namespace_conventions | YES | YES, NO |
以下に設定例を記載します。
manager.components.preconnect: ConsoleOut0.in?interface_type=ros2&marshaling_type=ros2:std_msgs/Float32, ConsoleIn0.out?interface_type=ros2&marshaling_type=ros2:std_msgs/Float32
OpenRTM-aistをビルド、インストールすると、ROS2Transportの簡単な動作確認用の設定ファイルがインストールされます。
D:\ros2-windows\setup.bat %RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\transport\rtc.ros2.conf
source /opt/ros/dashing/setup.sh source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/transport/rtc.ros2.conf
以下のサイトの手順に従ってRos4WinをUSBメモリにインストールしてください。
※リポジトリのURLが変わった関係でrptが正常に動作しない場合があります。修正済みでない場合はまずsrc\rpt\ros4win.pyのファイルを修正してください。
#PKG_REPO_BASE="http://hara.jpn.com/cgi/" #修正前 PKG_REPO_BASE="http://hara-jp.com/cgi/" #修正後
以下のコマンドでRos4Winをインストールしてください。
git clone https://github.com/haraisao/rpt cd rqt python src\rpt\rpt.py update python src\rpt\rpt.py install ros_base python src\rpt\rpt.py install ros_setup
最初に以下のコマンドでCMAKE_PREFIX_PATH、ROS_HOME_DRIVEの環境変数を設定します。 ここではドライブ"D:"にインストールしたUSBドライブが刺さっている前提でコマンドを示していますが、違うドライブに刺さっている場合は"D:"の部分をそのドライブ名に変更してください。
set ROS_HOME_DRIVE=D: set CMAKE_PREFIX_PATH=%CMAKE_PREFIX_PATH%;%ROS_HOME_DRIVE%/opt/ros/melodic/share
以降の作業の前に以下のコマンドでROSの環境を設定します。
D:\opt\ros\melodic\ros_setup.bat
CMake実行時にROS_ENABLEのオプションをONにします。
cmake -DORB_ROOT=C:/workspace/omniORB-4.2.3-win64-vc14 -DCORBA=omniORB -G "Visual Studio 16 2019" -A x64 -DROS_ENABLE=ON ..
その他の手順は通常と同じです。
ビルド後にインストールしてください。
cmake --build . --config Release --target install
以下のrtc.confを作成します。
manager.modules.load_path: C:\\workspace\\openrtm\\build_omni\\devel\\bin\\Release manager.modules.preload: ROSTransport.dll manager.components.preconnect: ConsoleOut0.in?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleOut0, ConsoleIn0.out?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleIn0 manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aistのシリアライザーモジュール(ROSTransport.dll)が対応しているメッセージ型は以下のようになります。
RTCを起動して動作確認します。 以下のコマンドでClinkを起動してください。
D:\opt\start_ros.bat
以降の作業はClink上で実行します。
以下のファイルを実行します。この時上記の変更をしたrtc.confは、VC14等のOpenRTM-aistをインストール時に指定したVisual Studioのバージョンに関連したのフォルダー(デフォルトではExamplesの下のVC14)に実行するexeファイルがありますので、そこと同じディレクトリに置くようにしてください。
${OpenRTM_INSTALL_DIR}\2.0\Components\C++\Examples\ConsoleInComp.exe ${OpenRTM_INSTALL_DIR}\2.0\Components\C++\Examples\ConsoleOutComp.exe
以下のコマンドでインストールしてください。
$ export ROS_DISTRO=melodic $ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' $ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116 $ sudo apt-get -y update $ sudo apt-get -y install ros-${ROS_DISTRO}-ros-base $ sudo rosdep init $ rosdep update
ROS用にbashの設定を以下のように行います。(次回以降のbash起動時の設定と、現在実行中のbashの設定を行います。)
$ echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> ~/.bashrc $ source ~/.bashrc
CMake実行時にROS_ENABLEのオプションをONにします。
$ cmake -DCORBA=omniORB -DCMAKE_BUILD_TYPE=Release -DROS_ENABLE=ON ..
その他の手順は通常と同じです。
ビルド後にインストールしてください。
$ cmake --build . --target install
以下のrtc.confを作成します。このファイルは下記のRTCコンポーネントを起動する時に使うカレントワーキングディレクトリにおいてください。
manager.modules.load_path: /usr/local/lib/openrtm-2.0/transport/ manager.modules.preload: ROSTransport.so manager.components.preconnect: ConsoleOut0.in?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleOut0, ConsoleIn0.out?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleIn0 manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aistのシリアライザーモジュール(ROSTransport.so)が対応しているメッセージ型は以下のようになります。
ConsoleInComp、ConsoleOutCompを起動して動作確認します。
それぞれ別のターミナルから起動してください。
$ /usr/local/share/openrtm-2.0/components/c++/examples/ConsoleInComp
$ /usr/local/share/openrtm-2.0/components/c++/examples/ConsoleOutComp
以下のページに従ってROSをUSBメモリにインストールしてください。
OpenRTM-aist 1.2等をインストーラーでインストールしておいてください。 OpenRTM-aist Python版のソースコードを入手してください。
以下のコマンドでOpenRTM-aist Python版をインストールしてください。
python setup.py build python setup.py install
start_ros.batを2回実行して、ROSの環境設定をしたウインドウを2つ開いてください。
D:\opt\start_ros.bat
片方のウインドウでroscoreを起動します。
roscore
もう片方のウインドウでOpenRTM-aistをインストールしたディレクトリをPYTHONPATHに設定します。
set PYTHONPATH=%PYTHONPATH%;C:\Python37\Lib\site-packages;C:\Python37\Lib\site-packages\OpenRTM_aist;C:\Python37\Lib\site-packages\OpenRTM_aist\utils;C:\Python37\Lib\site-packages\OpenRTM_aist\RTM_IDL
以下のrtc.confを作成します。(rtc.confはRTCのexeファイルが実行される時のディレクトリに作成してください。サンプルバッチファイルを使う場合は、バッチファイルから起動されるexeファイルが置かれているディレクトリになります。)
manager.modules.load_path: C:\\Python37\\Lib\\site-packages\\OpenRTM_aist\\ext\\transport\\ROSTransport manager.modules.preload: ROSTransport.py manager.components.preconnect: ConsoleOut0.in?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleOut0, ConsoleIn0.out?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleIn0 manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aistのシリアライザーモジュール(ROSTransport.py)が対応しているメッセージ型は以下のようになります。
上記のrtc.confを用いてRTCを起動して動作確認してください。
C++版と同じ手順でROSをインストールしてください。
以下のパッケージをインストールしてください。
$ sudo apt-get install python-omniorb-omg omniidl-python doxygen
以下のコマンドでOpenRTM-aist Python版をインストールします。
$ git clone https://github.com/OpenRTM/OpenRTM-aist-Python $ cd OpenRTM-aist-Python $ python setup.py build $ sudo python setup.py install
以下のrtc.confを作成します。(rtc.confはRTCを実行する時のカレントワーキングディレクトリに作成してください。)
manager.modules.load_path: /usr/local/lib/python2.7/dist-packages/OpenRTM_aist/ext/transport/ROSTransport/ manager.modules.preload: ROSTransport.py manager.components.preconnect: ConsoleOut0.in?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleOut0, ConsoleIn0.out?interface_type=ros&marshaling_type=ros:std_msgs/Float32&ros.topic=chatter&ros.node.name=ConsoleIn0 manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aistのシリアライザーモジュール(ROSTransport.py)が対応しているメッセージ型は以下のようになります。
以下のコマンドでRTCを起動して動作確認してください。
$ python /usr/local/share/openrtm-2.0/components/python/SimpleIO/ConsoleIn.py
$ python /usr/local/share/openrtm-2.0/components/python/SimpleIO/ConsoleOut.py
データポート接続時のコネクタプロファイルに設定できるオプションは以下の通りです。
オプション名 | デフォルト値 | オプション | 内容 |
marshaling_type | シリアライザの種類。ros:std_msgs/Float32などが設定できる。 | ||
ros.topic | chatter | トピック名 | |
ros.roscore.host | localhost | ROS Masterのホスト名 | |
ros.roscore.port | 11311 | ROS Masterのポート番号 | |
ros.node.name | ROSノードの名前 | ||
ros.node.anonymous | NO | YES,NO | |
ros.so_keepalive | YES | YES,NO | |
ros.tcp_nodelay | YES | YES,NO | YES:ROSノード名をUUIDで設定、NO:ROSノードをrtcompに設定 |
ros.tcp_keepcnt | 9 | ||
ros.tcp_keepidle | 60 | ||
ros.tcp_keepintvl | 10 |
データポート接続時のコネクタプロファイルに設定できるオプションは以下の通りです。
オプション名 | デフォルト値 | オプション | 内容 |
marshaling_type | シリアライザの種類。ros:std_msgs/Float32などが設定できる。 | ||
ros.topic | chatter | トピック名 | |
ros.roscore.host | localhost | ROS Masterのホスト名 | |
ros.roscore.port | 11311 | ROS Masterのポート番号 | |
ros.node.name | ROSノードの名前 | ||
ros.node.anonymous | NO | YES,NO | |
ros.so_reuseaddr | YES | YES,NO | |
ros.so_keepalive | YES | YES,NO | |
ros.tcp_nodelay | YES | YES,NO | YES:ROSノード名をUUIDで設定、NO:ROSノードをrtcompに設定 |
ros.tcp_keepcnt | 9 | ||
ros.tcp_keepidle | 60 | ||
ros.tcp_keepintvl | 10 | ||
ros.sock.timeout | 60 |
OpenRTM-aistをビルド、インストールすると、ROSTransportの簡単な動作確認用の設定ファイルがインストールされます。
D:\opt\ros\melodic\ros_setup.bat roscore
D:\opt\ros\melodic\ros_setup.bat %RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\transport\rtc.ros.conf
source /opt/ros/melodic/setup.bash roscore
source /opt/ros/melodic/setup.bash source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/transport/rtc.ros.conf
ROS,ROS2通信機能を使用する場合、以下のROS/ROS2メッセージ型に対応のシリアライザをOpenRTM-aistは備えています。以下のメッセージ型以外が必要な場合は、そのメッセージ型に変換するシリアライザを独自に実装してください。
シリアライザ名 | RTMデータ型 | ROS,ROS2メッセージ型 |
ros:std_msgs/Float32, ros2:std_msgs/Float32 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/Float32 |
ros:std_msgs/Float64, ros2:std_msgs/Float64 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/Float64 |
ros:std_msgs/Int8, ros2:std_msgs/Int8 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/Int8 |
ros:std_msgs/Int16, ros2:std_msgs/Int16 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/Int16 |
ros:std_msgs/Int32, ros2:std_msgs/Int32 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/UInt8 |
ros:std_msgs/Int64, ros2:std_msgs/Int64 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/UInt16 |
ros:std_msgs/UInt32, ros2:std_msgs/UInt32 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/UInt32 |
ros:std_msgs/UInt64, ros2:std_msgs/UInt64 |
TimedState,TimedShort, TimedLong,TimedUShort, TimedULong,TimedFloat, TimedDouble |
std_msgs/UInt64 |
ros:std_msgs/Float32MultiArray, ros2:std_msgs/Float32MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/Float32MultiArray |
ros:std_msgs/Float32MultiArray, ros2:std_msgs/Float32MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/Float32MultiArray |
ros:std_msgs/Float64MultiArray, ros2:std_msgs/Float64MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq, TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/Float64MultiArray |
ros:std_msgs/Int8MultiArray, ros2:std_msgs/Int8MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/Int8MultiArray |
ros:std_msgs/Int16MultiArray, ros2:std_msgs/nt16MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/Int16MultiArray |
ros:std_msgs/Int32MultiArray, ros2:std_msgs/Int32MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/Int32MultiArray |
ros:std_msgs/Int64MultiArray, ros2:std_msgs/Int64MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/Int64MultiArray |
ros:std_msgs/UInt8MultiArray, ros2:std_msgs/UInt8MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/UInt8MultiArray |
ros:std_msgs/UInt16MultiArray, ros2:std_msgs/UInt16MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/UInt16MultiArray |
ros:std_msgs/UInt32MultiArray, ros2:std_msgs/UInt32MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/UInt32MultiArray |
ros:std_msgs/UInt64MultiArray, ros2:std_msgs/UInt64MultiArray |
TimedShortSeq,TimedLongSeq, TimedUShortSeq,TimedULongSeq, TimedFloatSeq,TimedDoubleSeq |
std_msgs/UInt64MultiArray |
ros:std_msgs/String, ros2:std_msgs/String |
TimedString | std_msgs/String |
ros:geometry_msgs/PointStamped, ros2:geometry_msgs/PointStamped |
TimedPoint3D | geometry_msgs/PointStamped |
ros:geometry_msgs/QuaternionStamped, ros2:geometry_msgs/QuaternionStamped |
TimedQuaternion | geometry_msgs/QuaternionStamped |
ros:geometry_msgs/Vector3Stamped, ros2:geometry_msgs/Vector3Stamped |
TimedVector3D | geometry_msgs/Vector3Stamped |
ros:sensor_msgs/Image, ros2:sensor_msgs/Image |
CameraImage | sensor_msgs/Image |
エラーを取得する方法として2つの方法があります。 rtctree (rtshell のもととなっているライブラリ)ですと簡単に実現できますが、 まずは原理的なところから説明させていただきます。
1) ECに対してポーリングをする あるRTCにアタッチされている実行コンテキスト(EC)に対して get_component_state() で 現在の状態を問い合わせる。 この方法はポーリングですので多用するとシステムの速度低下を招きます。
疑似コードで説明いたします。
rtc = <何らかの方法でRTCのオブジェクトリファレンスを取得> ec_list = rtc.get_owned_contexts(); switch (ec_list[0].get_component_state(rtc)) {
case CREATED_STATE: printf("Created state."); break; case INACTIVE_STATE: printf("Inactive state."); break; case ACTIVE_STATE: printf("Active state."); break; case ERROR_STATE: printf("Error state."); break; default: printf("Unknown state"); break;
まずRTCからECを取得して、そのECに対してRTCを引数にして状態を取得しています。 このような呼び出し方をしているのは、以下の様な考え方からです。
RTCのステータスとして Inactive-Active-Error とされているのは、実際にはRTC の状態 ではなく、ある実行コンテキスト(EC)があるRTCと結びついたときの状態です。 (すなわち、状態はEC側にある、という考え方です。) http://www.omg.org/spec/RTC/ のFigure5.6 がそれに当たります。
通常は自身のECしかないため、ECの状態とRTCの状態を同一視しても問題ないのですが、 実際には一つのRTCは複数のECにアタッチされる可能性があることをご理解ください。
2) ComponentObserver を利用する もう一つはComponentObserver (1.1.0以降で導入) を利用する方法です。 ComponentObserverは以下の様なインターフェースを持っており、問い合わせをしたい側で サーバントを実装し、このオブジェクトをRTCにアタッチすることで状態が変わったとき などにコールバックさせます。
@interface ComponentObserver の項をご覧ください。
obs_svt = new ComponentOberver_impl(); // サーバント OpenRTM::ComponentObserver obs_ref = obs_svt._this(); // オブジェクト参照 SDO::ServiceProfile profile; profile.id = UUID(); profile.interface_type = CORBA_Util::toRepositoryId<OpenRTM::ComponentObserver>(); // rtm/Typename.h CORBA_SeqUtil.push_back(profile.properties, NVUtil::newNV("observed_status", "RTC_STATUS")); CORBA_SeqUtil.push_back(profile.properties, NVUtil::newNV("heartbeat.enable", "YES")); CORBA_SeqUtil.push_back(profile.properties, NVUtil::newNV("heartbeat.interval", "1.0")); profile.service = obs_ref;
rtc = <何らかの方法でRTCのオブジェクトリファレンスを取得> SDO::Configuration conf = rtc.get_configuration(); // SDO::get_configuration() conf.add_service_profile(profile);
状態がACTIVEに変わったら、上記 ovs_svt の ComponentOberver_impl::update_status("RTC_STATUS", "ACTIVE:0"); 状態がINACTIVEに変わったら、 ComponentOberver_impl::update_status("RTC_STATUS", "INACTIVE:0"); 状態がERRORに変わったら、 ComponentOberver_impl::update_status("RTC_STATUS", "ERROR:0"); が呼び出される。
ちなみに、rtshellのもととなっているrtctreeでは、たとえば RTCTree のコンストラクタに dynamic = True をセットするとツリーオブジェクトがRTCの状態を取得する際に ComponentObserverを利用して状態を取得するようになります。
https://github.com/gbiggs/rtctree/blob/master/rtctree/tree.py
また TreeNode::add_callback() を利用すると、イベントをフックできるようです。
https://github.com/gbiggs/rtctree/blob/master/rtctree/node.py
このファイルの一番下にイベント名が定義されています。 https://github.com/gbiggs/rtctree/blob/master/rtctree/component.py
このページではOpenRTM-aistのRTC操作関数群CORBA_RTCUtil機能の利用方法に説明します。
今回使用したソースコードは以下から入手できます。
C++の場合はOpenRTM-aistとリンクしたプログラムをビルドする環境が必要です。
以下のCMakeLists.txtを作成してください。
cmake_minimum_required(VERSION 3.1) set(target CORBA_RTCUtil_test) project(${target} CXX) find_package(OpenRTM REQUIRED) add_definitions(${OPENRTM_CFLAGS}) link_directories(${OPENRTM_LIBRARY_DIRS}) add_executable(${target} ${target}.cpp) target_link_libraries(${target} ${OPENRTM_LIBRARIES}) target_include_directories(${target} SYSTEM PRIVATE ${OPENRTM_INCLUDE_DIRS})
また、CORBA_RTCUtil_test.cppのソースファイルを作成してCMakeを実行します。 ソースコードからビルドしたOpenRTM-aistを使う場合は、environment-setup.omniorb.vc**.batを実行します。
%OPENRTM_INSTALL_DIR%\2.0.0\ext\environment-setup.omniorb.vc16.bat mkdir build cd build cmake ..
CORBA_RTCUtil_test.cppには以下の内容を記述しておきます。
#include <rtm/Manager.h> #include <rtm/NamingManager.h> #include <rtm/CORBA_RTCUtil.h> #include <iostream> int main (int argc, char** argv) { RTC::Manager* manager; manager = RTC::Manager::init(argc, argv); manager->activateManager(); manager->runManager(true); RTC::RTObject_var consolein = RTC::RTObject::_nil(); RTC::RTObject_var consoleout = RTC::RTObject::_nil(); RTC::NamingManager* nm = RTC::Manager::instance().getNaming(); RTC::RTCList consoleinlist = nm->string_to_component("rtcname://localhost:2809/*/ConsoleIn0"); if (consoleinlist.length() > 0) { consolein = consoleinlist[0]; } else { std::cout << "Could not found ConsoleIn0" << std::endl; return 1; } RTC::RTCList consoleoutlist = nm->string_to_component("rtcname://localhost:2809/*/ConsoleOut0"); if (consoleoutlist.length() > 0) { consoleout = consoleoutlist[0]; } else { std::cout << "Could not found ConsoleOut0" << std::endl; return 1; } RTC::RTObject_var configsample = RTC::RTObject::_nil(); RTC::RTCList configsamplelist = nm->string_to_component("rtcname://localhost:2809/*/ConfigSample0"); if (configsamplelist.length() > 0) { configsample = configsamplelist[0]; } else { std::cout << "Could not found ConfigSample0" << std::endl; return 1; } RTC::RTObject_var myserviceprovider = RTC::RTObject::_nil(); RTC::RTCList myserviceproviderlist = nm->string_to_component("rtcname://localhost:2809/*/MyServiceProvider0"); if (myserviceproviderlist.length() > 0) { myserviceprovider = myserviceproviderlist[0]; } else { std::cout << "Could not found MyServiceProvider0" << std::endl; return 1; } RTC::RTObject_var myserviceconsumer = RTC::RTObject::_nil(); RTC::RTCList myserviceconsumerlist = nm->string_to_component("rtcname://localhost:2809/*/MyServiceConsumer0"); if (myserviceconsumerlist.length() > 0) { myserviceconsumer = myserviceconsumerlist[0]; } else { std::cout << "Could not found MyServiceConsumer0" << std::endl; return 1; } //以降の処理はここに記述する manager->terminate(); manager->join(); return 0; }
Pythonの場合は以下のCORBA_RTCUtil_test.pyを用意してください。
#!/usr/bin/env python # -*- coding: utf-8 -*- # -*- Python -*- import sys import OpenRTM_aist import OpenRTM_aist.CORBA_RTCUtil from omniORB import CORBA def main(): mgr = OpenRTM_aist.Manager.init(sys.argv) mgr.activateManager() mgr.runManager(True) nm = OpenRTM_aist.Manager.instance().getNaming() consoleinlist = nm.string_to_component( "rtcname://localhost:2809/*/ConsoleIn0") if consoleinlist: consolein = consoleinlist[0] else: print("Could not found ConsoleIn0") sys.exit(1) consoleoutlist = nm.string_to_component( "rtcname://localhost:2809/*/ConsoleOut0") if consoleoutlist: consoleout = consoleoutlist[0] else: print("Could not found ConsoleOut0") sys.exit(1) configsamplelist = nm.string_to_component( "rtcname://localhost:2809/*/ConfigSample0") if consoleoutlist: configsample = consoleoutlist[0] else: print("Could not found ConfigSample0") sys.exit(1) myserviceproviderlist = nm.string_to_component( "rtcname://localhost:2809/*/MyServiceProvider0") if myserviceproviderlist: myserviceprovider = myserviceproviderlist[0] else: print("Could not found MyServiceProvider0") sys.exit(1) myserviceconsumerlist = nm.string_to_component( "rtcname://localhost:2809/*/ConsoleOut0") if myserviceconsumerlist: myserviceconsumer = myserviceconsumerlist[0] else: print("Could not found ConsoleOut0") sys.exit(1) #以降の処理はここに記述する mgr.shutdown() if __name__ == "__main__": main()
以下の内容のrtc.confを作成してください。
manager.shutdown_auto: NO
ConsoleIn、ConsoleOut、ConfiguSample、MyServiceProvider、MyServiceConsumerのサンプルコンポーネントを起動しておきます。
データポートの接続のために、ポートのオブジェクトリファレンスを取得するget_port_by_name関数を使用します。
関数名 | get_port_by_name | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
name | std::string& | RTC名.ポート名 |
戻り値 | ||
型名 | 意味 | |
RTC::PortService_ptr | ポートのオブジェクトリファレンス |
RTC::PortService_var port_in_var = CORBA_RTCUtil::get_port_by_name(consoleout.in(), "ConsoleOut0.in"); if (CORBA::is_nil(port_in_var)) { std::cout << "Could not found ConsoleOut0.in" << std::endl; return 1; } RTC::PortService_var port_out_var = CORBA_RTCUtil::get_port_by_name(consolein.in(), "ConsoleIn0.out"); if (CORBA::is_nil(port_out_var)) { std::cout << "Could not found ConsoleIn0.out" << std::endl; return 1; }
port_in_var = OpenRTM_aist.CORBA_RTCUtil.get_port_by_name( consoleout, "ConsoleOut0.in") if CORBA.is_nil(port_in_var): print("Could not found ConsoleOut0.in") sys.exit(1) port_out_var = OpenRTM_aist.CORBA_RTCUtil.get_port_by_name( consolein, "ConsoleIn0.out") if CORBA.is_nil(port_out_var): print("Could not found ConsoleOut0.in") sys.exit(1)
またget_port_by_url関数を使用すると、rtcname形式、rtcloc形式の文字列からオブジェクトリファレンスを取得できます。
関数名 | get_port_by_url | |
引数 | ||
引数名 | 型名 | 意味 |
port_name | std::string& | ポートのURI |
戻り値 | ||
型名 | 意味 | |
RTC::PortService_ptr | ポートのオブジェクトリファレンス |
RTC::PortService_var port_in_var = CORBA_RTCUtil::get_port_by_url("rtcname://localhost:2809/*/ConsoleOut0.in"); if (CORBA::is_nil(port_in_var)) { std::cout << "Could not found ConsoleOut0.in" << std::endl; return 1; } RTC::PortService_var port_out_var = CORBA_RTCUtil::get_port_by_url("rtcname://localhost:2809/*/ConsoleIn0.out"); if (CORBA::is_nil(port_out_var)) { std::cout << "Could not found ConsoleIn0.out" << std::endl; return 1; }
port_in_var = OpenRTM_aist.CORBA_RTCUtil.get_port_by_url( "rtcname://localhost:2809/*/ConsoleOut0.in") if CORBA.is_nil(port_in_var): print("Could not found ConsoleOut0.in") sys.exit(1) port_out_var = OpenRTM_aist.CORBA_RTCUtil.get_port_by_url( "rtcname://localhost:2809/*/ConsoleIn0.out") if CORBA.is_nil(port_out_var): print("Could not found ConsoleOut0.in") sys.exit(1)
取得したデータポートをconnect関数で接続します。
関数名 | connect | |
引数 | ||
引数名 | 型名 | 意味 |
name | std::string& | コネクタの名前 |
prop | coil::Properties& | コネクタの設定情報 |
port0 | RTC::PortService_ptr | 接続するポート1 |
port1 | RTC::PortService_ptr | 接続するポート2 |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
coil::Properties prop; prop["dataport.dataflow_type"] = "push"; prop["dataport.interface_type"] = "corba_cdr"; prop["dataport.subscription_type"] = "new"; CORBA_RTCUtil::connect("test_connector", prop, port_in_var.in(), port_out_var.in());
prop = OpenRTM_aist.Properties() prop.setProperty("dataport.dataflow_type", "push") prop.setProperty("dataport.interface_type", "corba_cdr") prop.setProperty("dataport.subscription_type", "new") OpenRTM_aist.CORBA_RTCUtil.connect( "test_connector", prop, port_in_var, port_out_var)
関数名 | disconnect_connector_name | |
引数 | ||
引数名 | 型名 | 意味 |
port_ref | RTC::PortService_ptr | 接続中のポート |
conn_name | std::string& | コネクタの名前 |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
コネクタ名を指定してコネクタを削除するためにはdisconnect_connector_name関数を使用します。
CORBA_RTCUtil::disconnect_connector_name(port_in_var.in(), "test_connector");
OpenRTM_aist.CORBA_RTCUtil.disconnect_by_portref_connector_name( port_in_var, "test_connector")
コネクタのURIからオブジェクトリファレンスを取得してコネクタを削除する場合はdisconnect_connector_name関数を使用します。
関数名 | disconnect_connector_name | |
引数 | ||
引数名 | 型名 | 意味 |
port_name | std::string& | ポートのURI |
conn_name | std::string& | コネクタの名前 |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::disconnect_connector_name("rtcname://localhost:2809/*/ConsoleOut0.in", "test_connector");
OpenRTM_aist.CORBA_RTCUtil.disconnect_by_portname_connector_name( "rtcname://localhost:2809/*/ConsoleOut0.in", "test_connector")
複数のポートを一度に接続するためにはconnect_multi関数を使用します。
関数名 | connect_multi | |
引数 | ||
引数名 | 型名 | 意味 |
name | std::string& | コネクタの名前 |
prop | coil::Properties& | コネクタの設定情報 |
port0 | RTC::PortService_ptr | 接続するポート1 |
target_ports | RTC::PortServiceList& | ポート1と接続するポートのリスト |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
RTC::PortServiceList target_ports; target_ports.length(1); target_ports[0] = RTC::PortService::_duplicate(port_out_var.in()); CORBA_RTCUtil::connect_multi("test_connector", prop, port_in_var.in(), target_ports);
OpenRTM_aist.CORBA_RTCUtil.connect_multi( "test_connector", prop, port_in_var, [port_out_var])
対象ポートのすべてのコネクタを削除するためにはdisconnect_all関数を使います。
関数名 | disconnect_all | |
引数 | ||
引数名 | 型名 | 意味 |
port_ref | RTC::PortService_ptr | 接続中のポート |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::disconnect_all(port_in_var.in());
OpenRTM_aist.CORBA_RTCUtil.disconnect_all_by_ref(port_in_var)
関数名 | disconnect_all | |
引数 | ||
引数名 | 型名 | 意味 |
port_name | std::string& | ポートのURI |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::disconnect_all("rtcname://localhost:2809/*/ConsoleIn0.out");
OpenRTM_aist.CORBA_RTCUtil.disconnect_all_by_name( "rtcname://localhost:2809/*/ConsoleIn0.out")
RTCをアクティブ化するためにはactivate関数を使用します。
関数名 | activate | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
ec_id | RTC::UniqueId | 実行コンテキストのID |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
RTCは状態を実行コンテキストごとに持っているため、デフォルトの実行コンテキスト(ID:0)以外で状態を変更する場合はec_idを指定します。
CORBA_RTCUtil::activate(consolein.in(), 0); CORBA_RTCUtil::activate(consoleout.in(), 0);
OpenRTM_aist.CORBA_RTCUtil.activate(consoleout, 0) OpenRTM_aist.CORBA_RTCUtil.activate(consolein, 0)
RTCを非アクティブ化するためにはdeactivate関数を使用します。
関数名 | deactivate | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
ec_id | RTC::UniqueId | 実行コンテキストのID |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::deactivate(consolein.in(), 0); CORBA_RTCUtil::deactivate(consoleout.in(), 0);
OpenRTM_aist.CORBA_RTCUtil.deactivate(consoleout, 0) OpenRTM_aist.CORBA_RTCUtil.deactivate(consolein, 0)
RTCをリセットするためにはreset関数を使用します。
関数名 | reset | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
ec_id | RTC::UniqueId | 実行コンテキストのID |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::reset(consolein.in(), 0); CORBA_RTCUtil::reset(consoleout.in(), 0);
OpenRTM_aist.CORBA_RTCUtil.reset(consoleout, 0) OpenRTM_aist.CORBA_RTCUtil.reset(consolein, 0)
RTCの現在の状態を取得するためにはget_state関数を使用します。
関数名 | get_state | |
引数 | ||
引数名 | 型名 | 意味 |
state | RTC::LifeCycleState | 状態 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
ec_id | RTC::UniqueId | 実行コンテキストのID |
戻り値 | ||
型名 | 意味 | |
bool | true:状態取得成功、false:状態取得失敗 |
RTC::LifeCycleState state; CORBA_RTCUtil::get_state(state, consoleout.in(), 0); std::cout << state << std::endl;
ret, state = OpenRTM_aist.CORBA_RTCUtil.get_state(consoleout, 0) print(state)
また、is_in_inactive関数、is_in_active関数、is_in_error関数で現在の状態が非アクティブ状態、アクティブ状態、エラー状態かを判定できます。
if (CORBA_RTCUtil::is_in_inactive(consoleout.in()))
{ std::cout << "Inactive State" << std::endl; } else if (CORBA_RTCUtil::is_in_active(consoleout.in())) { std::cout << "Active State" << std::endl; } else if (CORBA_RTCUtil::is_in_error(consoleout.in())) { std::cout << "Error State" << std::endl; }
if OpenRTM_aist.CORBA_RTCUtil.is_in_inactive(consoleout): print("Inactive State") elif OpenRTM_aist.CORBA_RTCUtil.is_in_active(consoleout): print("Active State") elif OpenRTM_aist.CORBA_RTCUtil.is_in_error(consoleout): print("Error State")
実行コンテキストの実行周期を変更するには、set_default_rate関数を使用します。
関数名 | set_default_rate | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
rate | CORBA::Double | 実行周期 |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::set_default_rate(consoleout.in(), 20.0);
OpenRTM_aist.CORBA_RTCUtil.set_default_rate(consoleout, 20.0)
set_default_rate関数はデフォルトの実行コンテキストの実行周期を取得しますが、指定IDの実行コンテキストから実行周期を取得するためにはset_current_rate関数を使用します。
関数名 | set_current_rate | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
ec_id | RTC::UniqueId | 実行コンテキストのID |
rate | CORBA::Double | 実行周期 |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::set_current_rate(consoleout.in(), 0, 50.0);
OpenRTM_aist.CORBA_RTCUtil.set_current_rate(consoleout, 0, 50.0)
現在の実行周期を取得するためには、get_default_rate関数を使用します。
関数名 | get_default_rate | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
戻り値 | ||
型名 | 意味 | |
CORBA::Double | 実行周期 |
std::cout << CORBA_RTCUtil::get_default_rate(consoleout.in()) << std::endl;
print(OpenRTM_aist.CORBA_RTCUtil.get_default_rate(consoleout))
指定IDの実行コンテキストから実行周期を取得するためにはget_current_rate関数を使用します。
関数名 | get_current_rate | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
ec_id | RTC::UniqueId | 実行コンテキストのID |
戻り値 | ||
型名 | 意味 | |
CORBA::Double | 実行周期 |
std::cout << CORBA_RTCUtil::get_current_rate(consoleout.in(), 0) << std::endl;
print(OpenRTM_aist.CORBA_RTCUtil.get_current_rate(consoleout, 0))
通常はRTCが起動時に生成する実行コンテキストが関連付け(アタッチ)されていますが、、外部の実行コンテキストをRTCにアタッチすると、アタッチした実行コンテキストでRTCを駆動できるようになります。
実行コンテキストを指定のRTCにアタッチするためにはadd_rtc_to_default_ec関数を使用します。
関数名 | add_rtc_to_default_ec | |
引数 | ||
引数名 | 型名 | 意味 |
localcomp | RTC::RTObject_ptr | アタッチする実行コンテキストをデフォルト実行コンテキストとして持つRTC |
othercomp | RTC::RTObject_ptr | アタッチするRTC |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::add_rtc_to_default_ec(consoleout.in(), consolein.in());
OpenRTM_aist.CORBA_RTCUtil.add_rtc_to_default_ec(consoleout, consolein)
アタッチした実行コンテキストの関連付け解除(デタッチ)するためにはremove_rtc_to_default_ec関数を使用します。
関数名 | remove_rtc_to_default_ec | |
引数 | ||
引数名 | 型名 | 意味 |
localcomp | RTC::RTObject_ptr | デタッチする実行コンテキストをデフォルト実行コンテキストとして持つRTC |
othercomp | RTC::RTObject_ptr | デタッチするRTC |
戻り値 | ||
型名 | 意味 | |
RTC::ReturnCode_t |
CORBA_RTCUtil::remove_rtc_to_default_ec(consoleout.in(), consolein.in());
OpenRTM_aist.CORBA_RTCUtil.remove_rtc_to_default_ec(consoleout, consolein)
アタッチした外部RTCの一覧を取得するためにはget_participants_rtc関数を使用します。
関数名 | get_participants_rtc | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | 対象の実行コンテキストをデフォルト実行コンテキストとして持つRTC |
戻り値 | ||
型名 | 意味 | |
RTC::RTCList |
RTC::RTCList rtclist = CORBA_RTCUtil::get_participants_rtc(consoleout.in()); for(CORBA::ULong i=0;i < rtclist.length();i++) { std::cout << i << "\t" << CORBA_RTCUtil::get_component_profile(rtclist[i].in()) << std::endl; }
i = 0 for rtc in OpenRTM_aist.CORBA_RTCUtil.get_participants_rtc(consoleout): print(i, OpenRTM_aist.CORBA_RTCUtil.get_component_profile(rtc)) i += 1
コンフィギュレーションパラメータの設定をするためにはset_active_configuration関数を使用します。 この関数では現在アクティブなコンフィギュレーションセットのパラメータが設定されます。
関数名 | set_active_configuration | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
value_name | std::string& | パラメータ名 |
value | std::string& | 設定値 |
戻り値 | ||
型名 | 意味 | |
bool | true:設定成功、false:設定失敗 |
CORBA_RTCUtil::set_active_configuration(configsample.in(), "int_param1", "100");
OpenRTM_aist.CORBA_RTCUtil.set_active_configuration( configsample, "int_param1", "100")
コンフィギュレーションセットを指定してパラメータを設定する場合はset_configuration関数を使用します。 この関数を実行すると、アクティブなコンフィギュレーションセットが変更されます。
関数名 | set_configuration | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
confset_name | std::string& | コンフィギュレーションセット名 |
value_name | std::string& | パラメータ名 |
value | std::string& | 設定値 |
戻り値 | ||
型名 | 意味 | |
bool | true:設定成功、false:設定失敗 |
CORBA_RTCUtil::set_configuration(configsample.in(), "mode0", "str_param1", "test");
OpenRTM_aist.CORBA_RTCUtil.set_configuration( configsample, "mode0", "str_param1", "test")
現在アクティブなコンフィギュレーションセットの名前を取得するにはget_active_configuration_name関数を使用します。
関数名 | get_active_configuration_name | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
戻り値 | ||
型名 | 意味 | |
std::string | コンフィギュレーションセット名 |
std::cout << CORBA_RTCUtil::get_active_configuration_name(configsample.in()) << std::endl;
print(OpenRTM_aist.CORBA_RTCUtil.get_active_configuration_name(configsample))
アクティブなコンフィギュレーションセットのパラメータ一覧を取得するにはget_active_configuration関数を使用します。
関数名 | get_active_configuration | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
戻り値 | ||
型名 | 意味 | |
coil::Properties | パラメータ一覧 |
std::cout << CORBA_RTCUtil::get_active_configuration(configsample.in()) << std::endl;
print(OpenRTM_aist.CORBA_RTCUtil.get_active_configuration(configsample))
コンフィギュレーションセットを指定してパラメータ一覧を取得するにはget_configuration関数を使用します。
関数名 | get_configuration | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
conf_name | std::string& | コンフィギュレーションセット名 |
戻り値 | ||
型名 | 意味 | |
coil::Properties | パラメータ一覧 |
std::cout << CORBA_RTCUtil::get_configuration(configsample.in(), "mode1") << std::endl;
print(OpenRTM_aist.CORBA_RTCUtil.get_configuration(configsample, "mode1"))
指定のパラメータのみを取得する場合はget_parameter_by_key関数を使用します。
関数名 | get_parameter_by_key | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
conf_name | std::string& | コンフィギュレーションセット名 |
value_name | std::string& | パラメータ名 |
戻り値 | ||
型名 | 意味 | |
std::string | パラメータの値 |
std::cout << CORBA_RTCUtil::get_parameter_by_key(configsample.in(), "mode1", "int_param1") << std::endl;
print(OpenRTM_aist.CORBA_RTCUtil.get_parameter_by_key( configsample, "mode1", "int_param1"))
コンポーネントプロファイルを取得するにはget_component_profile関数を使用します。
関数名 | get_component_profile | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
戻り値 | ||
型名 | 意味 | |
coil::Properties | コンポーネントプロファイルの情報 |
std::cout << CORBA_RTCUtil::get_component_profile(consolein.in()) << std::endl;
print(OpenRTM_aist.CORBA_RTCUtil.get_component_profile(consolein))
指定のRTCが保持しているポートの名前一覧を取得するにはget_port_names関数を使用します。
関数名 | get_port_names | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
戻り値 | ||
型名 | 意味 | |
coil::vstring | ポート名一覧 |
coil::vstring portlist = CORBA_RTCUtil::get_port_names(consolein.in()); for (auto& port : portlist) { std::cout << port << std::endl; }
for port in OpenRTM_aist.CORBA_RTCUtil.get_port_names(consolein): print(port)
InPortの名前一覧を取得するにはget_inport_names関数、OutPortの名前一覧を取得するにはget_outport_names関数、サービスポートの名前一覧を取得するにはget_svcport_names関数を使用します。
coil::vstring inportlist = CORBA_RTCUtil::get_inport_names(consoleout.in()); for (auto& port : inportlist) { std::cout << port << std::endl; }
coil::vstring outportlist = CORBA_RTCUtil::get_outport_names(consolein.in()); for (auto& port : outportlist) { std::cout << port << std::endl; } coil::vstring svcportlist = CORBA_RTCUtil::get_svcport_names(myserviceprovider.in()); for (auto& port : svcportlist) { std::cout << port << std::endl; }
for port in OpenRTM_aist.CORBA_RTCUtil.get_inport_names(consoleout): print(port) for port in OpenRTM_aist.CORBA_RTCUtil.get_outport_names(consolein): print(port) for port in OpenRTM_aist.CORBA_RTCUtil.get_svcport_names(myserviceprovider): print(port)
指定ポートのコネクタの名前一覧を取得するにはget_connector_names関数を使用します。
関数名 | get_connector_names | |
引数 | ||
引数名 | 型名 | 意味 |
port | RTC::PortService_ptr | ポートのオブジェクトリファレンス |
戻り値 | ||
型名 | 意味 | |
coil::vstring | コネクタ名一覧 |
coil::vstring inconlist = CORBA_RTCUtil::get_connector_names(port_in_var.in()); for (auto& connector : inconlist) { std::cout << connector << std::endl; }
for connector in OpenRTM_aist.CORBA_RTCUtil.get_connector_names_by_portref(port_in_var): print(connector)
ポート名を指定してコネクタの名前一覧を取得することもできます。
関数名 | get_connector_names | |
引数 | ||
引数名 | 型名 | 意味 |
rtc | RTC::RTObject_ptr | RTCのオブジェクトリファレンス |
port_name | std::string& | ポート名 |
戻り値 | ||
型名 | 意味 | |
coil::vstring | コネクタ名一覧 |
coil::vstring outconlist = CORBA_RTCUtil::get_connector_names(consolein.in(), "ConsoleIn0.out"); for (auto& connector : outconlist) { std::cout << connector << std::endl; }
for connector in OpenRTM_aist.CORBA_RTCUtil.get_connector_names(consolein, "ConsoleIn0.out"): print(connector)
OpenRTM-aistのデータポートは基本的にCORBAのメソッド呼び出しでデータを転送しますが、通信インターフェースのプラグインを追加することで様々な通信プロトコルを選択可能になります。
このページでは独自通信インターフェースの追加方法を説明します。 以下の独自シリアライザ作成方法も参考にしてください。
OpenRTM-aistにはデータフロー型がPush型の通信とPull型の通信、まだ実装中ですが双方向通信のduplex型があります。 Push型通信はInPortConsumer、InPortProviderで構成されており、Pull型通信はOutPortConsumer、OutPortProviderで構成されています。
Push型通信ではOutPort側でPublisherがInPortConsumerのput関数を呼び出して、put関数内でInPortProviderへデータを転送します。 InPortProviderではInPortConnectorオブジェクトのwrite関数を呼んでデータを追加します。
Pull型通信ではInPort側でOutPortConsumerのget関数を呼び出して、get関数内でOutPortProviderからデータを取得します。 OutPort側でOutPortProviderがOutPortConnectorのread関数を呼んでデータを取得してOutPortConsumerに渡します。
このため、Push型通信のためのInPortConsumer、InPortProvider、もしくはPull型通信のためのOutPortConsumer、OutPortProviderを実装することで独自の通信インターフェースが実現できます。
以下に独自インターフェース型の実装手順を記載します。
このページではC++で独自インターフェースを作成する手順を説明します。
以下のソースコードのサンプルでは重要でない部分は省略しているため、詳細なソースコードは以下から取得してください。
ビルドのために以下のCMakeLists.txtを作成してください。 OpenRTM-aistのライブラリの検出の設定が必要です。 また、生成する動的ライブラリの名前を${target}.dll、${target}.soにする必要があります。 Linux環境では先頭にlibを付けるので(libTestIF.so)、以下の例では先頭のlibを削除しています。
cmake_minimum_required(VERSION 3.1) set(target TestIF) project(${target} CXX) find_package(OpenRTM REQUIRED) add_definitions(${OPENRTM_CFLAGS}) link_directories(${OPENRTM_LIBRARY_DIRS}) add_library(${target} SHARED ${target}.cpp TestInPortConsumer.cpp TestInPortConsumer.h TestInPortProvider.cpp TestInPortProvider.h TestOutPortConsumer.cpp TestOutPortConsumer.h TestOutPortProvider.cpp TestOutPortProvider.h) target_link_libraries(${target} ${OPENRTM_LIBRARIES}) target_include_directories(${target} SYSTEM PRIVATE ${OPENRTM_INCLUDE_DIRS}) set_target_properties(${target} PROPERTIES PREFIX "")
ただし、Push型通信を実装する場合はTestInPortConsumer、TestInPortProviderが必要で、Pull型通信を実装する場合はTestOutPortConsumer、TestOutPortConsumerが必要なため、どちらかしか実装しない場合は不要なファイルの作成は不要です。
Push型通信実装のためにTestInPortConsumer(InPortConsumer)、TestInPortProvider(InPortProvider)を実装します。
まず以下のようなヘッダーファイル(TestInPortConsumer.h)、ソースファイル(TestInPortConsumer.cpp)を用意します。
#ifndef TESTINPORTCONSUMER_H #define TESTINPORTCONSUMER_H #include <rtm/InPortConsumer.h> class TestInPortConsumer : public RTC::InPortConsumer { public: TestInPortConsumer(); ~TestInPortConsumer() override; void init(coil::Properties& prop) override; RTC::DataPortStatus put(RTC::ByteData& data) override; void publishInterfaceProfile(SDOPackage::NVList& properties) override; bool subscribeInterface(const SDOPackage::NVList& properties) override; void unsubscribeInterface(const SDOPackage::NVList& properties) override; }; #endif
#include "TestInPortConsumer.h" TestInPortConsumer::TestInPortConsumer() { } TestInPortConsumer::~TestInPortConsumer() { } void TestInPortConsumer::init(coil::Properties& prop) { } RTC::DataPortStatus TestInPortConsumer::put(RTC::ByteData& data) { return RTC::DataPortStatus::PORT_OK; } void TestInPortConsumer::publishInterfaceProfile(SDOPackage::NVList& properties) { } bool TestInPortConsumer::subscribeInterface(const SDOPackage::NVList& properties) { return true; } void TestInPortConsumer::unsubscribeInterface(const SDOPackage::NVList& properties) { }
今回はここにファイルの読み書きでデータを転送する独自インターフェースを実装します。
まずコネクタの初期化時にinit関数が呼ばれます。 変数propにはRTSystemEditor等で設定したコネクタの接続情報が格納されています。 以下の例ではpropからtestif.filenameのパラメータを取得してファイル名に設定しています。 init関数は複数回呼ばれる可能性があるので、その点は注意する必要があります。
void TestInPortConsumer::init(coil::Properties& prop) { if (prop.propertyNames().size() == 0) { return; } m_filename = prop.getProperty("testif.filename", "test.dat"); }
データの書き込み時にはput関数が呼ばれます。 変数dataにはバイト列にシリアライズしたデータが格納されています。
RTC::DataPortStatus TestInPortConsumer::put(RTC::ByteData& data) { std::ofstream fout; fout.open(m_filename, std::ios::out | std::ios::binary | std::ios::trunc); if (fout.fail()) { return RTC::DataPortStatus::PORT_ERROR; } else { m_dataid += 1; fout.write((const char*)&m_dataid, sizeof(unsigned long)); const unsigned long size = data.getDataLength(); fout.write((const char*)&size, sizeof(unsigned long)); if (size > 0) { fout.write((const char*)data.getBuffer(), size); } } return RTC::DataPortStatus::PORT_OK; }
この例ではファイルにデータのID、データサイズ、バイト列データを書き込んでいます。 変数dataのgetDataLength関数でデータサイズ、getBuffer関数でバイト列データを取得して、取得したデータを何らかの方法でInPortProviderへ送信します。 データの読み込みには他にreadData関数を使う事ができます。
その他の関数は基本的に実装の必要はありませんが、InPortProvider側で追加の情報を設定する場合はsubscribeInterface関数でその情報の取得をする必要があります。 unsubscribeInterfaceはコネクタ切断時に呼ばれるので、subscribeInterface関数での処理に関して何らかの終了処理が必要な場合は記述します。
まず以下のようなヘッダーファイル(TestInPortProvider.h)、ソースファイル(TestInPortProvider.cpp)を用意します。
#ifndef TESTINPORTPROVIDER_H #define TESTINPORTPROVIDER_H #include <rtm/InPortProvider.h> #include <thread> class TestInPortProvider : public RTC::InPortProvider { public: TestInPortProvider(); ~TestInPortProvider() override; void init(coil::Properties& prop) override; void setBuffer(RTC::BufferBase<RTC::ByteData>* buffer) override; void setListener(RTC::ConnectorInfo& info, RTC::ConnectorListenersBase* listeners) override; void setConnector(RTC::InPortConnector* connector) override; private: RTC::InPortConnector* m_connector; }; #endif
#include "TestInPortProvider.h" #include <fstream> TestInPortProvider::TestInPortProvider() : m_connector(nullptr) { setInterfaceType("testif"); } TestInPortProvider::~TestInPortProvider() { } void TestInPortProvider::init(coil::Properties& prop) { } void TestInPortProvider::setBuffer(RTC::BufferBase<RTC::ByteData>* buffer) { } void TestInPortProvider::setListener(RTC::ConnectorInfo& info, RTC::ConnectorListenersBase* listeners) { } void TestInPortProvider::setConnector(RTC::InPortConnector* connector) { m_connector = connector; }
ここに処理を追加していきます。 今回の例では、init関数で指定ファイルが変更されているかをポーリングするスレッドを作成しています。
void TestInPortProvider::init(coil::Properties& prop) { if (prop.propertyNames().size() == 0) { return; } const std::string filename = prop.getProperty("testif.filename", "test.dat"); if (!m_running) { m_thread = std::thread([this, filename] { this->m_running = true; unsigned long lastid = 0; while (this->m_running) { if (this->m_connector != nullptr) { std::ifstream fin(filename, std::ios::in | std::ios::binary); if (!fin.fail()) { unsigned long id = 0; fin.read((char*)&id, sizeof(unsigned long)); if (id != lastid) { lastid = id; unsigned long size = 0; fin.read((char*)&size, sizeof(unsigned long)); if (size > 0) { RTC::ByteData data; data.setDataLength(size); fin.read((char*)data.getBuffer(), size); this->m_connector->write(data); } } } } } }); } }
ファイルからデータを取得後に、m_connectorのwrite関数を呼び出してデータをInPortConnectorに渡しています。 InPortConsumerのデータをファイルに書き込んで、InPortProviderでファイルからデータを読み込むというデータ転送を実装できました。
Pull型通信実装のためにTestInPortConsumer(OutPortConsumer)、TestInPortProvider(OutPortProvider)を実装します。 ただし、Push型通信のみを実装する場合はここは飛ばしてください。
まず以下のようなヘッダーファイル(TestOutPortConsumer.h)、ソースファイル(TestOutPortConsumer.cpp)を用意します。
#ifndef TESTOUTPORTCONSUMER_H #define TESTOUTPORTCONSUMER_H #include <rtm/SystemLogger.h> #include <rtm/OutPortConsumer.h> class TestOutPortConsumer : public RTC::OutPortConsumer { public: TestOutPortConsumer(); ~TestOutPortConsumer() override; void init(coil::Properties& prop) override; void setBuffer(RTC::CdrBufferBase* buffer) override; void setListener(RTC::ConnectorInfo& info, RTC::ConnectorListenersBase* listeners) override; RTC::DataPortStatus get(RTC::ByteData& data) override; bool subscribeInterface(const SDOPackage::NVList& properties) override; void unsubscribeInterface(const SDOPackage::NVList& properties) override; }; #endif
#include "TestOutPortConsumer.h" TestOutPortConsumer::TestOutPortConsumer() { } TestOutPortConsumer::~TestOutPortConsumer() { } void TestOutPortConsumer::init(coil::Properties& prop) { } void TestOutPortConsumer::setBuffer(RTC::CdrBufferBase* buffer) { } void TestOutPortConsumer::setListener(RTC::ConnectorInfo& info, RTC::ConnectorListenersBase* listeners) { } RTC::DataPortStatus TestOutPortConsumer::get(RTC::ByteData& data) { return RTC::DataPortStatus::PORT_OK; } bool TestOutPortConsumer::subscribeInterface(const SDOPackage::NVList& properties) { return true; } void TestOutPortConsumer::unsubscribeInterface(const SDOPackage::NVList& properties) { }
今回の例ではinit関数で読み書きするファイル名を指定します。
void TestOutPortConsumer::init(coil::Properties& prop) { if (prop.propertyNames().size() == 0) { return; } m_filename_in = prop.getProperty("testif.filename_in", "test_in.dat"); m_filename_out = prop.getProperty("testif.filename_out", "test_out.dat"); }
ここに処理を追加していきます。 Pull型通信ではデータ読み込み時にget関数を呼びますが、以下の例ではファイルAに呼び出しのIDを書き込みます。 次にファイルBからデータサイズとバイト列データを読み込んで変数dataに格納しています。 データサイズを設定するにはsetDataLength関数を使用します。 データの格納にはgetBuffer関数で取得したポインタのアドレスに書き込むか、writeData関数を使用します。
RTC::DataPortStatus TestOutPortConsumer::get(RTC::ByteData& data) { std::ofstream fout; fout.open(m_filename_out, std::ios::out | std::ios::binary | std::ios::trunc); if (fout.fail()) { return RTC::DataPortStatus::PORT_ERROR; } else { m_dataid += 1; fout.write((const char*)&m_dataid, sizeof(unsigned long)); fout.close(); for (int i = 0; i < 100; i++) { std::ifstream fin(m_filename_in, std::ios::in | std::ios::binary); if (!fin.fail()) { unsigned long id = 0; fin.read((char*)&id, sizeof(unsigned long)); if (id == m_dataid) { unsigned long size = 0; fin.read((char*)&size, sizeof(unsigned long)); if (size > 0) { data.setDataLength(size); fin.read((char*)data.getBuffer(), size); return RTC::DataPortStatus::PORT_OK; } } } } } return RTC::DataPortStatus::PORT_ERROR; }
まず以下のようなヘッダーファイル(TestOutPortProvider.h)、ソースファイル(TestOutPortProvider.cpp)を用意します。
#ifndef TESTOUTPORTPROVIDER_H #define TESTOUTPORTPROVIDER_H #include <rtm/OutPortProvider.h> class TestOutPortProvider : public RTC::OutPortProvider { public: TestOutPortProvider(); ~TestOutPortProvider() override; void init(coil::Properties& prop) override; void setBuffer(RTC::CdrBufferBase* buffer) override; void setListener(RTC::ConnectorInfo& info, RTC::ConnectorListenersBase* listeners) override; void setConnector(RTC::OutPortConnector* connector) override; private: RTC::OutPortConnector* m_connector; }; #endif
#include "TestOutPortProvider.h" TestOutPortProvider::TestOutPortProvider() : m_connector(nullptr) { setInterfaceType("testif"); } TestOutPortProvider::~TestOutPortProvider() { } void TestOutPortProvider::init(coil::Properties& prop) { } void TestOutPortProvider::setBuffer(RTC::CdrBufferBase* buffer) { } void TestOutPortProvider::setListener(RTC::ConnectorInfo& info, RTC::ConnectorListenersBase* listeners) { } void TestOutPortProvider::setConnector(RTC::OutPortConnector* connector) { m_connector = connector; }
ここに処理を追加していきます。 以下の例ではinit関数でファイルが変更されたかをポーリングして、変更時に別のファイルにデータを書き込むスレッドを起動しています。
void TestOutPortProvider::init(coil::Properties& prop) { if (prop.propertyNames().size() == 0) { return; } const std::string filename_in = prop.getProperty("testif.filename_in", "test_in.dat"); const std::string filename_out = prop.getProperty("testif.filename_out", "test_out.dat"); if (!m_running) { m_thread = std::thread([this, filename_in, filename_out] { this->m_running = true; unsigned long lastid = 0; while (this->m_running) { if (this->m_connector != nullptr) { std::ifstream fin(filename_out, std::ios::in | std::ios::binary); if (!fin.fail()) { unsigned long id = 0; fin.read((char*)&id, sizeof(unsigned long)); fin.close(); if (lastid != id) { std::ofstream fout; fout.open(filename_in, std::ios::out | std::ios::binary | std::ios::trunc); if (!fout.fail()) { fout.write((const char*)&id, sizeof(unsigned long)); RTC::ByteData data; m_connector->read(data); const unsigned long size = data.getDataLength(); fout.write((const char*)&size, sizeof(unsigned long)); if (size > 0) { fout.write((const char*)data.getBuffer(), size); } } lastid = id; } } } } }); } }
まずm_connectorのread関数を呼んでOutPortConnectorから転送するデータを取得します。 getDataLength関数でデータサイズを取得、getBuffer関数でバイト列データを取得してファイルに書き込んでいます。
これにより、OutPortConsumerでファイルAにデータのIDを書き込み後にOutPortProviderでファイルAからIDを読み込んで前回読み込んだデータのIDと一致しているかを判定します。 新しいデータだと判定したらファイルBにデータを書き込んで、OutPortConsumerでファイルBが新しいデータかを判定してOutPortConnectorにデータを渡します。
ここまでに実装した独自インターフェースを使用可能にするためファクトリに登録します。 以下の内容のTestIF.cppを作成してください。
#include "TestInPortConsumer.h" #include "TestInPortProvider.h" #include "TestOutPortConsumer.h" #include "TestOutPortProvider.h" #include <rtm/Manager.h> extern "C" { DLL_EXPORT void TestIFInit(RTC::Manager* manager) { { RTC::InPortProviderFactory& factory(RTC::InPortProviderFactory::instance()); factory.addFactory("testif", ::coil::Creator< ::RTC::InPortProvider, TestInPortProvider>, ::coil::Destructor< ::RTC::InPortProvider, TestInPortProvider>); } { RTC::InPortConsumerFactory& factory(RTC::InPortConsumerFactory::instance()); factory.addFactory("testif", ::coil::Creator< ::RTC::InPortConsumer, TestInPortConsumer>, ::coil::Destructor< ::RTC::InPortConsumer, TestInPortConsumer>); } { RTC::OutPortProviderFactory& factory(RTC::OutPortProviderFactory::instance()); factory.addFactory("testif", ::coil::Creator< ::RTC::OutPortProvider, TestOutPortProvider>, ::coil::Destructor< ::RTC::OutPortProvider, TestOutPortProvider>); } { RTC::OutPortConsumerFactory& factory(RTC::OutPortConsumerFactory::instance()); factory.addFactory("testif", ::coil::Creator< ::RTC::OutPortConsumer, TestOutPortConsumer>, ::coil::Destructor< ::RTC::OutPortConsumer, TestOutPortConsumer>); } } }
ビルドしてTestIF.dll、TestIF.so生成後に、以下のrtc.confを作成してください。 ${TestIF_DIR}にはTestIF.dll、TestIF.soのフォルダのパスを指定してください。
manager.modules.load_path: ${TestIF_DIR} manager.preload.modules: TestIF.dll
作成したrtc.confを指定してConsoleIn、ConsoleOutのサンプルコンポーネントを起動します。これでOpenRTM-aistがTestIF.dllをロードします。
ConsoleIn -f rtc.conf
ConsoleOut -f rtc.conf
RTSystemEditorでデータポートを接続しようとすると、以下のようにInterface Typeでtestifが選択可能になっています。
Interface Typeにtestifを選択して接続すると、実装したファイル読み書きによるデータ転送ができることが確認できます。
Pull型通信を動作確認する場合について、Pull型通信ではInPortのisNew関数が使えず新規のデータが存在するかは確認できません。 このため、ConsoleOutコンポーネントのisNew関数を実行している部分をコメントアウトして再ビルドする必要があります。
//if (m_inIn.isNew())
今回の例ではtestif.filename、testif.filename_in、testif.filename_outというオプションで読み書きするファイル名を指定できるようにしましたが、これらをデータポートのプロファイルからオプションの情報を取得するように設定を追加できます。ただし、リリース版のOpenRTM-aist 2.0では使えない場合があるので、OpenRTM-aistをソースコードからビルドしてください。
static const char* const testifpush_option[] = { "filename.__value__", "test.dat", "filename.__widget__", "text", "filename.__constraint__", "none", "" }; extern "C" { DLL_EXPORT void TestIFInit(RTC::Manager* manager) { { coil::Properties prop(testifpush_option); RTC::InPortProviderFactory& factory(RTC::InPortProviderFactory::instance()); factory.addFactory("testif", ::coil::Creator< ::RTC::InPortProvider, TestInPortProvider>, ::coil::Destructor< ::RTC::InPortProvider, TestInPortProvider>, prop); }
このページではPythonで独自インターフェースを作成する手順を説明します。
以下のソースコードのサンプルでは重要でない部分は省略しているため、詳細なソースコードは以下から取得してください。
Push型通信実装のためにTestInPortConsumer(InPortConsumer)、TestInPortProvider(InPortProvider)を実装します。
まず以下のようなPythonファイル(TestInPortConsumer.py)を用意します。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import OpenRTM_aist class TestInPortConsumer( OpenRTM_aist.InPortConsumer): def __init__(self): pass def __del__(self): pass def init(self, prop): if not prop.propertyNames(): return def put(self, data): return self.PORT_OK def publishInterfaceProfile(self, properties): pass def subscribeInterface(self, properties): return True def unsubscribeInterface(self, properties): pass def TestInPortConsumerInit(): factory = OpenRTM_aist.InPortConsumerFactory.instance() factory.addFactory("testif", TestInPortConsumer)
今回はここにファイルの読み書きでデータを転送する独自インターフェースを実装します。
まずコネクタの初期化時にinit関数が呼ばれます。 変数propにはRTSystemEditor等で設定したコネクタの接続情報が格納されています。 以下の例ではpropからtestif.filenameのパラメータを取得してファイル名に設定しています。 init関数は複数回呼ばれる可能性があるので、その点は注意する必要があります。
def init(self, prop): if not prop.propertyNames(): return self._filename = prop.getProperty("testif.filename", "test.dat")
データの書き込み時にはput関数が呼ばれます。 変数dataはbytes型のシリアライズしたデータが格納されています。
def put(self, data): with open(self._filename, 'wb') as fout: self._dataid += 1 try: fout.write(struct.pack('L', self._dataid)) fout.write(struct.pack('L', len(data))) fout.write(data) except BaseException: return self.PORT_ERROR return self.PORT_OK
この例ではファイルにデータのID、データサイズ、バイト列データを書き込んでいます。 変数dataのgetDataLength関数でデータサイズ、getBuffer関数でバイト列データを取得して、取得したデータを何らかの方法でInPortProviderへ送信します。
その他の関数は基本的に実装の必要はありませんが、InPortProvider側で追加の情報を設定する場合はsubscribeInterface関数でその情報の取得をする必要があります。 unsubscribeInterfaceはコネクタ切断時に呼ばれるので、subscribeInterface関数での処理に関して何らかの終了処理が必要な場合は記述します。
まず以下のようなPythonファイル(TestInPortProvider.py)を用意します。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import OpenRTM_aist class TestInPortProvider(OpenRTM_aist.InPortProvider): def __init__(self): OpenRTM_aist.InPortProvider.__init__(self) self.setInterfaceType("testif") def __del__(self): pass def exit(self): pass def init(self, prop): if not prop.propertyNames(): return def setBuffer(self, buffer): pass def setListener(self, info, listeners): pass def setConnector(self, connector): self._connector = connector def TestInPortProviderInit(): factory = OpenRTM_aist.InPortProviderFactory.instance() factory.addFactory("testif", TestInPortProvider)
ここに処理を追加していきます。 今回の例では、init関数で指定ファイルが変更されているかをポーリングするスレッドを作成しています。
def init(self, prop): if not prop.propertyNames(): return filename = prop.getProperty("testif.filename", "test.dat") def polling(): self._running = True lastid = 0 while self._running: if self._connector: if os.path.exists(filename): with open(filename, 'rb') as fin: try: id = struct.unpack("L", fin.read(struct.calcsize("L")))[0] if id != lastid: lastid = id size = struct.unpack("L", fin.read(struct.calcsize("L")))[0] if size > 0: data = fin.read(size) self._connector.write(data) except BaseException: pass self._thread = threading.Thread(target=polling) self._thread.start()
ファイルからデータを取得後に、m_connectorのwrite関数を呼び出してデータをInPortConnectorに渡しています。 InPortConsumerのデータをファイルに書き込んで、InPortProviderでファイルからデータを読み込むというデータ転送を実装できました。
Pull型通信実装のためにTestInPortConsumer(OutPortConsumer)、TestInPortProvider(OutPortProvider)を実装します。 ただし、Push型通信のみを実装する場合はここは飛ばしてください。
まず以下のようなPythonファイル(TestOutPortConsumer.py)を用意します。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import OpenRTM_aist class TestOutPortConsumer( OpenRTM_aist.OutPortConsumer): def __init__(self): pass def __del__(self): pass def init(self, prop): if not prop.propertyNames(): return def setBuffer(self, buffer): pass def setListener(self, info, listeners): pass def get(self): return self.PORT_ERROR, "" def subscribeInterface(self, properties): return True def unsubscribeInterface(self, properties): pass def TestOutPortConsumerInit(): factory = OpenRTM_aist.OutPortConsumerFactory.instance() factory.addFactory("testif", TestOutPortConsumer) return
今回の例ではinit関数で読み書きするファイル名を指定します。
def init(self, prop): if not prop.propertyNames(): return self._filename_in = prop.getProperty( "testif.filename_in", "test_in.dat") self._filename_out = prop.getProperty( "testif.filename_out", "test_out.dat")
ここに処理を追加していきます。 Pull型通信ではデータ読み込み時にget関数を呼びますが、以下の例ではファイルAに呼び出しのIDを書き込みます。 次にファイルBからデータサイズとバイト列データを読み込んで値を返しています。
def get(self): with open(self._filename_in, 'wb') as fout: self._dataid += 1 try: print(self._dataid) fout.write(struct.pack('L', self._dataid)) except BaseException: return self.PORT_ERROR for i in range(100): if os.path.exists(self._filename_out): with open(self._filename_out, 'rb') as fin: try: id = struct.unpack("L", fin.read(struct.calcsize("L")))[0] if id == self._dataid: self._dataid = id size = struct.unpack("L", fin.read(struct.calcsize("L")))[0] if size > 0: data = fin.read(size) return self.PORT_OK, data except BaseException: pass return self.PORT_ERROR, ""
まず以下のようなPythonファイル(TestOutPortProvider.py)を用意します。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import OpenRTM_aist class TestOutPortProvider(OpenRTM_aist.OutPortProvider): def __init__(self): OpenRTM_aist.OutPortProvider.__init__(self) self.setInterfaceType("testif") self._thread = None self._running = False self._connector = None def __del__(self): pass def exit(self): if self._running: self._running = False self._thread.join() def init(self, prop): if not prop.propertyNames(): return def setBuffer(self, buffer): pass def setListener(self, info, listeners): pass def setConnector(self, connector): self._connector = connector def TestOutPortProviderInit(): factory = OpenRTM_aist.OutPortProviderFactory.instance() factory.addFactory("testif", TestOutPortProvider)
ここに処理を追加していきます。 以下の例ではinit関数でファイルが変更されたかをポーリングして、変更時に別のファイルにデータを書き込むスレッドを起動しています。
def init(self, prop): if not prop.propertyNames(): return filename_in = prop.getProperty("testif.filename_in", "test_in.dat") filename_out = prop.getProperty("testif.filename_out", "test_out.dat") def polling(): self._running = True lastid = 0 while self._running: if self._connector: if os.path.exists(filename_in): with open(filename_in, 'rb') as fin: try: id = struct.unpack("L", fin.read(struct.calcsize("L")))[0] if id == lastid: continue except BaseException: continue with open(filename_out, 'wb') as fout: try: fout.write(struct.pack('L', id)) ret, data = self._connector.read() fout.write(struct.pack('L', len(data))) if ret == OpenRTM_aist.BufferStatus.BUFFER_OK: fout.write(data) lastid = id except BaseException: pass
まずm_connectorのread関数を呼んでOutPortConnectorから転送するデータを取得します。 getDataLength関数でデータサイズを取得、getBuffer関数でバイト列データを取得してファイルに書き込んでいます。
これにより、OutPortConsumerでファイルAにデータのIDを書き込み後にOutPortProviderでファイルAからIDを読み込んで前回読み込んだデータのIDと一致しているかを判定します。 新しいデータだと判定したらファイルBにデータを書き込んで、OutPortConsumerでファイルBが新しいデータかを判定してOutPortConnectorにデータを渡します。
ここまでに実装した独自インターフェースを使用可能にするためファクトリに登録します。 以下の内容のTestIF.pyを作成してください。
#!/usr/bin/env python # -*- coding: utf-8 -*- # -*- Python -*- import TestInPortConsumer import TestInPortProvider import TestOutPortConsumer import TestOutPortProvider def TestIFInit(mgr): TestInPortConsumer.TestInPortConsumerInit() TestInPortProvider.TestInPortProviderInit() TestOutPortConsumer.TestOutPortConsumerInit() TestOutPortProvider.TestOutPortProviderInit()
TestInPortProviderInit、TestInPortConsumerInit、TestOutPortProviderInit、TestOutPortConsumerInit関数ではInPortProviderFactory、InPortConsumerFactory、OutPortProviderFactory、OutPortConsumerFactoryのaddFactory関数で実装した独自インターフェースを登録しています。 testifという名前をポート接続時に指定することで使用できます。 TestIFInit関数はPythonモジュールをロードする時に呼び出す関数です。〇〇.pyであれば〇〇Initというように、初期化関数はPythonファイルの名前+Initにしてください。 Push型のみ、もしくはPull型通信のみの実装の場合は、必要なモジュールだけを登録してください。
以下のrtc.confを作成してください。 ${TestIF_DIR}にはTestIF.pyのフォルダのパスを指定してください。
manager.modules.load_path: . manager.modules.preload: TestIF.py
作成したrtc.confを指定してConsoleIn、ConsoleOutのサンプルコンポーネントを起動します。これでOpenRTM-aistがTestIF.pyをロードします。
python ConsoleIn.py -f rtc.conf
python ConsoleOut.py -f rtc.conf
RTSystemEditorでデータポートを接続しようとすると、以下のようにInterface Typeでtestifが選択可能になっています。
Interface Typeにtestifを選択して接続すると、実装したファイル読み書きによるデータ転送ができることが確認できます。
Pull型通信を動作確認する場合について、Pull型通信ではInPortのisNew関数が使えず新規のデータが存在するかは確認できません。 このため、ConsoleOutコンポーネントのisNew関数を実行している部分をコメントアウトする必要があります。
# if self._inport.isNew():
今回の例ではtestif.filename、testif.filename_in、testif.filename_outというオプションで読み書きするファイル名を指定できるようにしましたが、これらをデータポートのプロファイルからオプションの情報を取得するように設定を追加できます。ただし、リリース版のOpenRTM-aist 2.0では使えない場合があるので、OpenRTM-aistをソースコードからビルドしてください。
testifpush_option = [ "filename_in.__value__", "test_in.dat", "filename_in.__widget__", "text", "filename_in.__constraint__", "none", "filename_out.__value__", "test_out.dat", "filename_out.__widget__", "text", "filename_out.__constraint__", "none", "" ] def TestInPortProviderInit(): prop = OpenRTM_aist.Properties(defaults_str=testifpush_option) factory = OpenRTM_aist.InPortProviderFactory.instance() factory.addFactory("testif", TestInPortProvider, prop)
OpenRTM-aistにはrtcname形式、rtcloc形式という文字列からRTCへアクセスする機能が利用できます。
rtcname形式は指定のネームサーバーに登録されたRTCにアクセスする方式であり、接続するネームサーバーのアドレス、ネーミングコンテキスト、RTCのバインディング名を指定することでRTCのオブジェクトリファレンスを取得できます。
rtcname://{ネームサーバーのIPアドレス}:{ネームサーバーのポート番号}/{ネーミングコンテキスト名(省略可)}/{RTCのバインディング名}
rtcloc形式は指定のマスターマネージャに登録されたスレーブマネージャからRTCにアクセスする方式であり、接続するマスターマネージャのアドレス、RTCのカテゴリ名、RTCのインスタンス名を指定することでRTCのオブジェクトリファレンスを取得できます。
rtcloc://{マスターマネージャのIPアドレス}:{マスターマネージャのポート番号}/{RTCのカテゴリ名(省略可)}/{RTCのインスタンス名}
以下のようにrtc.confのmanager.components.preconnect、manager.components.preactivationでrtcname形式によりRTCを指定することで、外部のプロセスで起動したポートの接続やRTCのアクティブ化ができます。
manager.components.preconnect: ConsoleIn0.out?port=rtcname://localhost:2809/test.host_cxt/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcname://localhost:2809/test.host_cxt/ConsoleOut0
ただし、ネーミングコンテキスト(この例ではtest.host_cxt)は以下のように省略できます。
manager.components.preconnect: ConsoleIn0.out?port=rtcname://localhost:2809/*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcname://localhost:2809/*/ConsoleOut0
※以下の機能はリリース版のOpenRTM-aist 2.0.0で未サポートの場合があります。機能を使う場合はソースコードからビルドする必要があります。
OpenRTM-aistはデフォルトでIIOP通信を行いますが、設定を変更することでomniORBのSSLIOP、HTTP、HTTPS、WebSocket、WebSocket over SSL/TLS通信、TAOのSSLIOP、HTIOP、SHMIOP通信で外部のRTCにアクセスすることができます。 以下のようにrtcnameの後にプロトコル名を指定することで設定できます。
rtcname.{プロトコル名}://{ネームサーバーのIPアドレス}:{ネームサーバーのポート番号}/{ネーミングコンテキスト名(省略可)}/{RTCのバインディング名}
ただし、設定する通信プロトコルをOpenRTM-aistで使用できるように設定する必要があります。 使用例についても以下のページを参考にしてください。
以下のようにrtc.confのmanager.components.preconnect、manager.components.preactivationでrtcloc形式によりRTCを指定することで、外部のプロセスで起動したポートの接続やRTCのアクティブ化ができます。 rtcloc形式を使用するためにはマネージャからRTCを取得する機能を有効にするためnaming.typeオプションにmanagerを追加します。
naming.type: corba, manager manager.components.preconnect: ConsoleIn0.out?port=rtcloc://localhost:2810/example/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcloc://localhost:2810/example/ConsoleOut0
ただし、ネーミングコンテキスト(この例ではtest.host_cxt)は以下のように省略できます。
manager.components.preconnect: ConsoleIn0.out?port=rtcloc://localhost:2810/*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcloc://localhost:2810/*/ConsoleOut0
rtcname形式と同じく、rtcloc形式でも通信プロトコルを指定することができます。
rtcloc.{プロトコル名}://{マスターマネージャのIPアドレス}:{マスターマネージャのポート番号}/{RTCのカテゴリ名(省略可)}/{RTCのインスタンス名}
omniORB 4.3ではHTTP通信機能をサポートしており、GIOPメッセージをHTTPパケットで送信する仕組みを利用することができます。 HTTP通信機能の利点として、ファイアーウォールやHTTPプロキシサーバを経由した通信が容易になる事や、リバースプロキシやロードバランサー等の既存の仕組みを流用しやすくなるという事があります。 このページではomniORBのHTTP、HTTPS、WebSocket、WSS(WebSocket over SSL/TLS)通信機能OpenRTM-aistから利用する方法を説明します。 ただし、HTTP通信機能はomniORBの独自仕様のため、TAO独自仕様のHTIOP等とは互換性はありません。
以下にomniORBのHTTPパケットの一例を掲載しておきます。TAOのHTIOPでは最初にGETメソッドを呼び出しており、動作が違う事が分かります。
POST /call HTTP/1.1 Host: localhost:2809 User-Agent: omniORB Connection: keep-alive Content-Type: application/octet-stream Content-Length: 103 GIOP\x01\x02\x01\x00[\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00NameService\x00\x06\x00\x00\x00_is_a\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00IDL:omg.org/CosNaming/NamingContextExt:1.0\x00
まず、OpenSSLのヘッダーファイル、ライブラリを適当な場所に展開してください。
OpenRTM-aist+omniORBを以下の手順でビルド、インストールします。
ただし、CMake実行時にHTTP_ENABLE、OPENSSL_ROOT_DIRのオプションを設定する必要があります。
設定項目 | 内容 | 設定例 |
HTTP_ENABLE | HTTPTransportプラグインの生成の有無 | ON |
OPENSSL_ROOT_DIR | OpenSSLの各種ファイルを配置したパス | C:/work/OpenSSL/x64 |
また、CMake実行時にOpenRTM-aistのインストールフォルダは指定してそこにインストールするようにしてください。
set OPENRTM_INSTALL_DIR=C:/work/openrtm_install set OMNIORB_SOURCE_DIR=C:/workspace/omniORB-4.3.0-x64-vc16-py310 set OPENSSL_ROOT_DIR=C:/work/OpenSSL/x64 cmake .. -DORB_ROOT=%OMNIORB_SOURCE_DIR% -DHTTP_ENABLE=ON -DOPENSSL_ROOT_DIR=%OPENSSL_ROOT_DIR% -DCMAKE_INSTALL_PREFIX=%OPENRTM_INSTALL_DIR% cmake --build . --config Release cmake --build . --config Release --target install
OpenSSLのヘッダとライブラリをインストールします。
sudo apt install libssl-dev
OpenRTM-aist+omniORBを以下の手順でビルド、インストールします。
ただし、HTTP_ENABLEのオプションを設定する必要があります。
設定項目 | 内容 | 設定例 |
HTTP_ENABLE | HTTPTransportプラグインの生成の有無 | ON |
set OPENRTM_INSTALL_DIR=~/work/openrtm_install cmake .. -DHTTP_ENABLE=ON -DCMAKE_INSTALL_PREFIX=$OPENRTM_INSTALL_DIR cmake --build . --config Release -- -j$(nproc) cmake --build . --config Release --target install
以下の手順でOpenRTM-aist Python版をインストールしてださい。
ただし、動作確認でOpenRTM-aist C++版付属のネームサーバーを使用するため、C++版のビルドも実行してください。
HTTPTransportの動作確認のためにはネームサーバーがHTTP通信に対応している必要があります。 OpenRTM-aist付属のopenrtmNamesを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\bin\vc16\openrtmNames.exe -f %OPENRTM_INSTALL_DIR%/2.0.0/ext/rtc.names.http.conf
$OPENRTM_INSTALL_DIR/bin/openrtmNames -f $OPENRTM_INSTALL_DIR/etc/rtc.names.http.conf
以下のようなrtc.confを作成します。OpenRTM-aistをインストールしたパスは適宜変更してください。
C++では以下のファイルを作成します。
manager.modules.load_path: C:/work/openrtm_install/2.0.0/ext/vc16/http manager.preload.modules: HTTPTransport.dll corba.args:-ORBserverTransportRule "* http" -ORBclientTransportRule "* http" -ORBendPoint giop:http:http:///call corba.nameservers: http://localhost:2809/call corba.master_manager: http:http://localhost:2810/call
Pythonでは以下のファイルを作成します。
manager.modules.load_path: C:/Python37/Lib/site-packages/OpenRTM_aist/ext/http manager.preload.modules: HTTPTransport.py corba.args:-ORBserverTransportRule "* http" -ORBclientTransportRule "* http" -ORBendPoint giop:http:http:///call corba.nameservers: http://localhost:2809/call corba.master_manager: http:http://localhost:2810/call
各設定項目の内容は以下のようになっています。
項目名 | 説明 |
corba.args | CORBAライブラリの初期化関数に渡す引数。ここでHTTP通信のエンドポイントを設定する必要がある。 |
corba.nameservers | ネームサーバーのアドレス。ここでHTTP通信でネームサーバーに接続するように設定する。 |
corba.master_manager | マスターマネージャのエンドポイント。マスターマネージャの場合は自身のエンドポイントを設定し、スレーブマネージャの場合は接続先のマスターマネージャのアドレスを設定する。 |
このrtc.confを指定してConsoleIn、ConsoleOutのRTCを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleInComp.exe -f rtc.conf
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleInComp -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleIn.py -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleIn.py -f rtc.conf
これでネームサーバーに登録されますが、RTシステムエディタにHTTP通信機能はないため、OpenRTM-aistの機能かrtshellによりポートの接続やRTCのアクティブ化を実行する必要があります。
HTTPTransportの動作確認のためにはネームサーバーがHTTP通信に対応している必要があります。 OpenRTM-aist付属のopenrtmNamesを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\bin\vc16\openrtmNames.exe -f %OPENRTM_INSTALL_DIR%/2.0.0/ext/rtc.names.https.conf $OPENRTM_INSTALL_DIR/bin/openrtmNames -f $OPENRTM_INSTALL_DIR/etc/rtc.names.https.conf
rtc.names.https.confでは生成済みのルート証明書root.crtと秘密鍵とサーバー証明書を連結したファイルserver.pemを使用するため、動作確認に使用するRTCもこれらの証明書ファイルを使います。 実際にシステムを開発する際は証明書と秘密鍵を変更してください。
以下のようなrtc.confを作成します。OpenRTM-aistをインストールしたパスは適宜変更してください。
C++では以下のファイルを作成します。
manager.modules.load_path: C:/work/openrtm_install/2.0.0/ext/vc16/http manager.preload.modules: HTTPTransport.dll corba.http.certificate_authority_file:C:/work/openrtm_install/2.0.0/ext/ssl/root.crt corba.http.key_file:C:/work/openrtm_install/2.0.0/ext/ssl/server.pem corba.http.key_file_password:password corba.args:-ORBserverTransportRule "* http" -ORBclientTransportRule "* http" -ORBendPoint giop:http:https:///call corba.nameservers: https://localhost:2809/call corba.master_manager: http:https://localhost:2810/call
Pythonでは以下のファイルを作成します。
manager.modules.load_path: C:/Python37/Lib/site-packages/OpenRTM_aist/ext/http manager.preload.modules: HTTPTransport.py corba.http.certificate_authority_file:C:/Python37/Lib/site-packages/OpenRTM_aist/ext/ssl/root.crt corba.http.key_file:C:/Python37/Lib/site-packages/OpenRTM_aist/ext/ssl/server.pem corba.http.key_file_password:password corba.args:-ORBserverTransportRule "* http" -ORBclientTransportRule "* http" -ORBendPoint giop:http:https:///call corba.nameservers: https://localhost:2809/call corba.master_manager: http:https://localhost:2810/call
各設定項目の内容は以下のようになっています。
項目名 | 説明 |
corba.http.certificate_authority_file | ルート証明書 |
corba.http.key_file | 秘密鍵+サーバー証明書兼クライアント証明書の連結ファイル |
corba.http.key_file_password | 秘密鍵のパスフレーズ |
corba.args | CORBAライブラリの初期化関数に渡す引数。ここでHTTPS通信のエンドポイントを設定する必要がある。 |
corba.nameservers | ネームサーバーのアドレス。ここでHTTPS通信でネームサーバーに接続するように設定する。 |
corba.master_manager | マスターマネージャのエンドポイント。マスターマネージャの場合は自身のエンドポイントを設定し、スレーブマネージャの場合は接続先のマスターマネージャのアドレスを設定する。 |
このrtc.confを指定してConsoleIn、ConsoleOutのRTCを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleInComp.exe -f rtc.conf
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleInComp -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleIn.py -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleIn.py -f rtc.conf
これでネームサーバーに登録されますが、RTシステムエディタにHTTP通信機能はないため、OpenRTM-aistの機能かrtshellによりポートの接続やRTCのアクティブ化を実行する必要があります。
HTTPTransportの動作確認のためにはネームサーバーがHTTP通信に対応している必要があります。 OpenRTM-aist付属のopenrtmNamesを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\bin\vc16\openrtmNames.exe -f %OPENRTM_INSTALL_DIR%/2.0.0/ext/rtc.names.ws.conf
$OPENRTM_INSTALL_DIR/bin/openrtmNames -f $OPENRTM_INSTALL_DIR/etc/rtc.names.ws.conf
以下のようなrtc.confを作成します。OpenRTM-aistをインストールしたパスは適宜変更してください。
C++では以下のファイルを作成します。
manager.modules.load_path: C:/work/openrtm_install/2.0.0/ext/vc16/http manager.preload.modules: HTTPTransport.dll corba.args:-ORBserverTransportRule "* http,tcp" -ORBclientTransportRule "* http,tcp" -ORBendPoint giop:http:ws:///ws -ORBendPoint giop:tcp:: corba.nameservers: ws://localhost:2809/ws corba.master_manager: giop:http:ws://localhost:2810/ws
Pythonでは以下のファイルを作成します。
manager.modules.load_path: C:/Python37/Lib/site-packages/OpenRTM_aist/ext/http manager.preload.modules: HTTPTransport.py corba.args:-ORBserverTransportRule "* http,tcp" -ORBclientTransportRule "* http,tcp" -ORBendPoint giop:http:ws:///ws -ORBendPoint giop:tcp:: corba.nameservers: ws://localhost:2809/ws corba.master_manager: giop:http:ws://localhost:2810/ws
IIOP(TCP)のエンドポイントを設定していますが、これはWebSocketのアドレスだけをエンドポイントに設定した場合にCORBAオブジェクトの比較(_is_equivalent)が上手く動作しないためなので、今後omniORB側で修正されたら設定は不要です。
各設定項目の内容は以下のようになっています。
項目名 | 説明 |
corba.args | CORBAライブラリの初期化関数に渡す引数。ここでHTTP通信のエンドポイントを設定する必要がある。 |
corba.nameservers | ネームサーバーのアドレス。ここでWebSocket通信でネームサーバーに接続するように設定する。 |
corba.master_manager | マスターマネージャのエンドポイント。マスターマネージャの場合は自身のエンドポイントを設定し、スレーブマネージャの場合は接続先のマスターマネージャのアドレスを設定する。 |
このrtc.confを指定してConsoleIn、ConsoleOutのRTCを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleInComp.exe -f rtc.conf
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleInComp -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleIn.py -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleIn.py -f rtc.conf
これでネームサーバーに登録されますが、RTシステムエディタにHTTP通信機能はないため、OpenRTM-aistの機能かrtshellによりポートの接続やRTCのアクティブ化を実行する必要があります。
HTTPTransportの動作確認のためにはネームサーバーがHTTP通信に対応している必要があります。 OpenRTM-aist付属のopenrtmNamesを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\bin\vc16\openrtmNames.exe -f %OPENRTM_INSTALL_DIR%/2.0.0/ext/rtc.names.wss.conf
$OPENRTM_INSTALL_DIR/bin/openrtmNames -f $OPENRTM_INSTALL_DIR/etc/rtc.names.https.conf
rtc.names.https.confでは生成済みのルート証明書root.crtと秘密鍵とサーバー証明書を連結したファイルserver.pemを使用するため、動作確認に使用するRTCもこれらの証明書ファイルを使います。 実際にシステムを開発する際は証明書と秘密鍵を変更してください。
以下のようなrtc.confを作成します。OpenRTM-aistをインストールしたパスは適宜変更してください。
C++では以下のファイルを作成します。
manager.modules.load_path: C:/work/openrtm_install/2.0.0/ext/vc16/http manager.preload.modules: HTTPTransport.dll corba.http.certificate_authority_file:C:/work/openrtm_install/2.0.0/ext/ssl/root.crt corba.http.key_file:C:/work/openrtm_install/2.0.0/ext/ssl/server.pem corba.http.key_file_password:password corba.args:-ORBserverTransportRule "* http,tcp" -ORBclientTransportRule "* http,tcp" -ORBendPoint giop:http:wss:///ws -ORBendPoint giop:tcp:: corba.nameservers: wss://localhost:2809/ws corba.master_manager: giop:http:wss://localhost:2810/ws
Pythonでは以下のファイルを作成します。
manager.modules.load_path: C:/Python37/Lib/site-packages/OpenRTM_aist/ext/http manager.preload.modules: HTTPTransport.py corba.http.certificate_authority_file:C:/Python37/Lib/site-packages/OpenRTM_aist/ext/ssl/root.crt corba.http.key_file:C:/Python37/Lib/site-packages/OpenRTM_aist/ext/ssl/server.pem corba.http.key_file_password:password corba.args:-ORBserverTransportRule "* http,tcp" -ORBclientTransportRule "* http,tcp" -ORBendPoint giop:http:wss:///ws -ORBendPoint giop:tcp:: corba.nameservers: wss://localhost:2809/ws corba.master_manager: giop:http:wss://localhost:2810/ws
各設定項目の内容は以下のようになっています。
項目名 | 説明 |
corba.http.certificate_authority_file | ルート証明書 |
corba.http.key_file | 秘密鍵+サーバー証明書兼クライアント証明書の連結ファイル |
corba.http.key_file_password | 秘密鍵のパスフレーズ |
corba.args | CORBAライブラリの初期化関数に渡す引数。ここでWSS通信のエンドポイントを設定する必要がある。 |
corba.nameservers | ネームサーバーのアドレス。ここでWSS通信でネームサーバーに接続するように設定する。 |
corba.master_manager | マスターマネージャのエンドポイント。マスターマネージャの場合は自身のエンドポイントを設定し、スレーブマネージャの場合は接続先のマスターマネージャのアドレスを設定する。 |
このrtc.confを指定してConsoleIn、ConsoleOutのRTCを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleInComp.exe -f rtc.conf
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleInComp -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleIn.py -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleIn.py -f rtc.conf
これでネームサーバーに登録されますが、RTシステムエディタにHTTP通信機能はないため、OpenRTM-aistの機能かrtshellによりポートの接続やRTCのアクティブ化を実行する必要があります。
rtc.confのmanager.components.preconnect、manager.components.preactivationでrtcname形式、rtcloc形式を指定することでポートの接続、RTCのアクティブ化ができます。 HTTP通信の場合は以下のようにプロトコルにhttp、https、ws、wssを指定することで使用可能になります。
manager.components.preconnect: ConsoleIn0.out?port=rtcname.http://localhost:2809/call#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcname.http://localhost:2809/call#*/ConsoleOut0
naming.type: corba, manager manager.components.preconnect: ConsoleIn0.out?port=rtcloc.http://localhost:2810/call#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcloc.http://localhost:2810/call#*/ConsoleOut0
manager.components.preconnect: ConsoleIn0.out?port=rtcname.https://localhost:2809/call#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcname.https://localhost:2809#call/*/ConsoleOut0
naming.type: corba, manager manager.components.preconnect: ConsoleIn0.out?port=rtcloc.https://localhost:2810/call#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcloc.https://localhost:2810/call#*/ConsoleOut0
manager.components.preconnect: ConsoleIn0.out?port=rtcname.ws://localhost:2809/ws#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcname.ws://localhost:2809/ws#*/ConsoleOut0
naming.type: corba, manager manager.components.preconnect: ConsoleIn0.out?port=rtcloc.ws://localhost:2810/call#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcloc.ws://localhost:2810/call#*/ConsoleOut0
manager.components.preconnect: ConsoleIn0.out?port=rtcname.wss://localhost:2809/ws#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcname.wss://localhost:2809/ws#*/ConsoleOut0
naming.type: corba, manager manager.components.preconnect: ConsoleIn0.out?port=rtcloc.wss://localhost:2810/ws#*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcloc.wss://localhost:2810/ws#*/ConsoleOut0
まず、現在インストールされるrtshellでは対応していないため、最新版のrtctree、rtshell、rtsprofileが必要です。
rtshellでHTTP通信機能を使用するためには以下の環境変数を設定する必要があります。
環境変数名 | 設定例 | 意味 |
RTCTREE_HTTP_ENABLE | YES | YES:rtctreeでHTTP通信機能を有効にする。 |
RTCTREE_NAMESERVERS | http://localhost:2809/call | 接続するネームサーバー |
ORBhttpsCAFile | root.crt | ルート証明書 |
ORBhttpsKeyFile | server.pem | 秘密鍵+サーバー証明書兼クライアント証明書の連結ファイル |
ORBhttpsKeyPassword | password | 秘密鍵のパスフレーズ |
ORBserverTransportRule | "* http" | サーバー側の通信プロトコル選択のルール |
ORBclientTransportRule | "* http" | クライアント側の通信プロトコル選択のルール |
ORBendPoint | giop:http:http:///call | omniORBのエンドポイント |
set RTCTREE_HTTP_ENABLE=YES set ORBhttpsCAFile=%RTM_ROOT%/ext/ssl/root.crt set ORBhttpsKeyFile=%RTM_ROOT%/ext/ssl/server.pem set ORBhttpsKeyPassword=password set RTCTREE_NAMESERVERS=https://localhost:2809/call set ORBserverTransportRule=* http set ORBclientTransportRule=* http set ORBendPoint=giop:http:https:///call
以下のように接続するネームサーバーのアドレスの前にhttps:を付けることでHTTPS通信でネームサーバーに接続できるようになります。
rtcon /https:localhost:2809/call#test.host_cxt/ConsoleIn0.rtc:out /https:localhost:2809/call#est.host_cxt/ConsoleOut0.rtc:in rtact /https:localhost:2809/call#test.host_cxt/ConsoleIn0.rtc /https:localhost:2809/call#test.host_cxt/ConsoleOut0.rtc rtdeact /https:localhost:2809/call#test.host_cxt/ConsoleIn0.rtc /https:localhost:2809/call#test.host_cxt/ConsoleOut0.rtc rtexit /https:localhost:2809/call#test.host_cxt/ConsoleOut0.rtc rtcryo /https:localhost:2809/call -o sys.rtsys
プロキシサーバーを設定するには、ORBhttpProxy、ORBhttpProxyUsername、ORBhttpProxyPasswordオプションを設定します。
corba.args:-ORBserverTransportRule "* http" -ORBclientTransportRule "* http" -ORBendPoint giop:http:https:///call -ORBhttpProxy http://localhost:3128 -ORBhttpProxyUsername username -ORBhttpProxyPassword pass
corba.jsはTypeScript用のCORBA実装(ORB、IDLコンパイラ)です。
現状、corba.jsはomniORBのWebsocket通信には対応していないため、当面の間はこちらで修正を加えたもので動作を確認します。
まず、node.js、npmをインストールしてください。
Ubuntu環境では以下のコマンドでインストールしてください。
sudo apt-get install nodejs nodejs-dev node-gyp libssl1.0-dev npm sudo npm install -g n sudo n latest
現状、Linux環境でないとIDLコンパイルが実行できないようなので、corba.jsはUbuntu環境でビルドしてください。
git clone https://github.com/Nobu19800/corba.js cd corba.js npm install npm run build
これ以降の作業はWindowsでも実行できます。 まず、OpenRTM-aistのテスト用のプログラム(openrtm_corbajs_test)を作成したので、これをビルドします。
cd .. git clone https://github.com/Nobu19800/openrtm_corbajs_test cd openrtm_corbajs_test npm install
この時点でnode_modulesフォルダにcorba.jsも含む依存ライブラリが一式インストールされていますが、corba.jsは先ほどビルドしたものを使用するため、インストールしたcorba.jsは削除して差し替えた後にビルドします。
rm -rf node_modules/corba.js cp -r ../corba.js/ node_modules/ npm run build
Webブラウザ上で実行する場合とnode.jsで実行する場合についてソースコードの修正が必要です。 なにも修正しない場合ブラウザで操作する形式でビルドしています。
事前準備として、Websocket通信のエンドポイントでネームサーバーとConsoleOutコンポーネントを起動してください。
%OPENRTM_INSTALL_DIR%\2.0.0\bin\vc16\openrtmNames.exe -f %OPENRTM_INSTALL_DIR%/2.0.0/ext/rtc.names.ws.conf
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f rtc.conf
$OPENRTM_INSTALL_DIR/bin/openrtmNames -f $OPENRTM_INSTALL_DIR/etc/rtc.names.ws.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
動作確認のためにはopenrtm_corbajs_test付属のindex.htmlをWebブラウザで開きます。
ここでネームサーバーのアドレスとバインディング名を指定してexitボタンを押すとConsoleOutコンポーネントが終了します。
Webブラウザ環境に対応したスクリプト生成のためにrollup.jsというツールを使用しています。Rollup、rollup.jsは複数のJavascriptファイルを一つのモジュールにするJavaScript 用のバンドラーです。
この設定のためにrollup.config.jsを作成しています。
node.jsで実行する場合、ネームサーバーのエンドポイントにlocalhostと設定すると正常に動作せず、ネームサーバーのエンドポイントに127.0.0.1のように直接IPアドレスを指定してcorba.js側でも127.0.0.1へアクセスする必要があります。
corba.args:-ORBserverTransportRule "* http" -ORBclientTransportRule "* http" -ORBendPoint giop:http:ws://127.0.0.1:2809/ws
この変更後にネームサーバーを起動してください。
src/openrtmTest.tsを編集します。 以下の2行の1行目のコメントアウトを解除して、2行目をコメントアウトしてください。
import { WsProtocol } from "corba.js/net/ws" //import { WsProtocol } from "corba.js/net/browser"
そして、以下の2行についても同様の変更をしてください。
let print = console.log //let print = alert
この後、再度ビルドしてサンプルプログラムを実行します。
npm run build node lib/openrtmTestMain.js
サンプルプログラムのopenrtmTest.tsの概要について説明します。
まず最初にcorba.jsやRTCのスタブ、スケルトンファイルを読み込んでいます。
import { ORB, GIOPDecoder } from 'corba.js' import { NamingContextExtStub } from 'corba.js' //import { WsProtocol } from "corba.js/net/ws" import { WsProtocol } from "corba.js/net/browser" import * as skel from "./example_echo_skel.js" import * as stub from "./example_echo_stub.js" import * as RTC_skel from "./RTC_skel.js" import * as RTC_stub from "./RTC_stub.js" import * as RTC_interface from "./RTC.js" import * as RTC_value from "./RTC_value.js" import * as RTC_valuetype from "./RTC_valuetype.js"
Webブラウザから実行しているのはexit_component関数です。
最初にスタブクラスを登録しています。実際に使用しているのは以下のRTObjectクラスだけです。
orb.registerStubClass(RTC_stub.RTC.RTObject)
使用する通信プロトコルとしてWebSocketを追加しています。node.jsからの実行であればWebSocket over SSL/TLS通信も追加可能です。
orb.addProtocol(new WsProtocol())
アドレスを指定してネームサーバーのオブジェクトリファレンスを取得します。
await orb.stringToObject(address+"#NameService").then( (nameobject: any) => { let rootContext = NamingContextExtStub.narrow(nameobject)
RTCのバインディング名を指定してRTCのオブジェクトリファレンスを取得しています。 この辺の記述方法はcorba.jsの対応状況で変わる可能性があります。
rootContext.resolve_str(rtcpath).then( (reference: any) => { orb.getConnection(reference.host, reference.port, reference.pathname).then( (objectConnection: any) => { let rtc = new RTC_stub.RTC.RTObject(objectConnection.orb, reference.objectKey, objectConnection);
RTCのオブジェクトリファレンスからexitメソッドを呼び出して終了処理を実行します。 戻り値で終了処理の成功失敗を判定しています。
rtc.exit().then( (ret: RTC_interface.RTC.ReturnCode_t) => { if(ret === RTC_interface.RTC.ReturnCode_t.RTC_OK) { print("RTC termination process has completed successfully.") } else { print("error code:"+ret) }
今のところ、corba.jsの一部機能の不足や言語使用の制限などで実行できないことがいくつかあります。
これらの問題からOMG RTC仕様のIDLファイルはIDLコンパイルできなかったため、サンプルプログラム付属のTypeScriptソースファイルは多重継承やany型を削除したIDLファイルをIDLコンパイル後に修正しています。 一応、多重継承の問題とインクルードの問題は修正を加えることで対応可能ですが、any型についてはシリアライズ、デシリアライズ処理の変更が必要ですが、openrtm_corbajs_test付属のファイルでは対応できていません。
RTC_value.tsの以下の部分でNameValueのシリアライズ、デシリアライズについて記述があるので、ここに修正することで対応してください。
export interface NameValue { name: string value: any } export function initNameValue(object: NameValue, init?: Partial<NameValue> | GIOPDecoder) { if (init instanceof GIOPDecoder) { const decoder = init object.name = decoder.string() object.name = decoder.any() } else { object.name = (init === undefined || init.name === undefined) ? "" : init.name } } export function encodeNameValue(encoder: GIOPEncoder, obj: NameValue) { encoder.string(obj.name) encoder.any(obj.name) }
any型などのCORBAの仕様については以下のページが参考になります。
OpenRTM-aistをビルド、インストールすると、HTTPTransportの簡単な動作確認用の設定ファイルがインストールされます。
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\bin\vc16\openrtmNames.exe -f %RTM_ROOT%\ext\rtc.names.http.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\http\rtc.http.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/bin/openrtmNames -f ${OPENRTM_INSTALL_DIR}/etc/rtc.names.http.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/http/rtc.http.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\bin\vc16\openrtmNames.exe -f %RTM_ROOT%\ext\rtc.names.https.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\http\rtc.https.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/bin/openrtmNames -f ${OPENRTM_INSTALL_DIR}/etc/rtc.names.https.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/http/rtc.https.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\bin\vc16\openrtmNames.exe -f %RTM_ROOT%\ext\rtc.names.ws.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\http\rtc.ws.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/bin/openrtmNames -f ${OPENRTM_INSTALL_DIR}/etc/rtc.names.ws.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/http/rtc.ws.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\bin\vc16\openrtmNames.exe -f %RTM_ROOT%\ext\rtc.names.wss.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\http\rtc.wss.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/bin/openrtmNames -f ${OPENRTM_INSTALL_DIR}/etc/rtc.names.wss.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/wss/rtc.http.conf
オブジェクトのCORBA Security Service仕様のセキュリティ機能を一部使用可能になっています。 CORBA Security Serviceではセキュリティポリシーのモデル、認証、アクセス制御、メッセージ保護、委譲、監査、否認不可の機能を定義していますが、omniORBではGIOPメッセージをSSL/TLSによるサーバー・クライアント認証と暗号化で保護するSSLIOP通信をサポートしています。 このページではOpenRTM-aistでomniORBのSSLIOP通信を使用する手順を説明します。
まず、OpenSSLのヘッダーファイル、ライブラリを適当な場所に展開してください。
OpenRTM-aist+omniORBを以下の手順でビルド、インストールします。
ただし、CMake実行時にSSL_ENABLE、OPENSSL_ROOT_DIRのオプションを設定する必要があります。
設定項目 | 内容 | 設定例 |
SSL_ENABLE | SSLTransportプラグインの生成の有無 | ON |
OPENSSL_ROOT_DIR | OpenSSLの各種ファイルを配置したパス | C:/work/OpenSSL/x64 |
また、CMake実行時にOpenRTM-aistのインストールフォルダは指定してそこにインストールするようにしてください。
set OPENRTM_INSTALL_DIR=C:/work/openrtm_install set OMNIORB_SOURCE_DIR=C:/workspace/omniORB-4.2.5-x64-vc14-py310 set OPENSSL_ROOT_DIR=C:/work/OpenSSL/x64 cmake .. -DORB_ROOT=%OMNIORB_SOURCE_DIR% -DSSL_ENABLE=ON -DOPENSSL_ROOT_DIR=%OPENSSL_ROOT_DIR% -DCMAKE_INSTALL_PREFIX=%OPENRTM_INSTALL_DIR% cmake --build . --config Release cmake --build . --config Release --target install
OpenSSLのヘッダとライブラリをインストールします。
sudo apt install libssl-dev
OpenRTM-aist+omniORBを以下の手順でビルド、インストールします。
ただし、SSL_ENABLEのオプションを設定する必要があります。
設定項目 | 内容 | 設定例 |
SSL_ENABLE | SSLTransportプラグインの生成の有無 | ON |
set OPENRTM_INSTALL_DIR=~/work/openrtm_install cmake .. -DSSL_ENABLE=ON -DCMAKE_INSTALL_PREFIX=$OPENRTM_INSTALL_DIR cmake --build . --config Release -- -j$(nproc) cmake --build . --config Release --target install
以下の手順でOpenRTM-aist Python版をインストールしてださい。
ただし、動作確認でOpenRTM-aist C++版付属のネームサーバーを使用するため、C++版のビルドも実行してください。
SSLTransportの動作確認のためにはネームサーバーがSSLIOP通信に対応している必要があります。 OpenRTM-aist付属のopenrtmNamesを起動します。
以下のコマンドを実行してください。パスは確認して変更してください。
%OPENRTM_INSTALL_DIR%\2.0.0\bin\vc16\openrtmNames.exe -f %OPENRTM_INSTALL_DIR%\2.0.0\ext\rtc.names.ssl.conf
$OPENRTM_INSTALL_DIR/bin/openrtmNames -f $OPENRTM_INSTALL_DIR/etc/rtc.names.ssl.conf
rtc.names.ssl.confでは生成済みのルート証明書root.crtと秘密鍵とサーバー証明書を連結したファイルserver.pemを使用するため、動作確認に使用するRTCもこれらの証明書ファイルを使います。 実際にシステムを開発する際は証明書と秘密鍵を変更してください。
以下のようなrtc.confを作成します。OpenRTM-aistをインストールしたパスは適宜変更してください。
C++では以下のファイルを作成します。
manager.modules.load_path: C:/work/openrtm_install/2.0.0/ext/ssl manager.preload.modules: SSLTransport.dll corba.ssl.certificate_authority_file:C:/work/openrtm_install/2.0.0/ext/ssl/root.crt corba.ssl.key_file:C:/work/openrtm_install/2.0.0/ext/ssl/server.pem corba.ssl.key_file_password:password corba.args:-ORBserverTransportRule "* ssl" -ORBclientTransportRule "* ssl" -ORBendPoint giop:ssl:: corba.nameservers: corbaloc:ssliop:localhost:2809 corba.master_manager: giop:ssl:localhost:2810
Pythonでは以下のファイルを作成します。
manager.modules.load_path: C:/Python37/Lib/site-packages/OpenRTM_aist/ext/vc16/ssl manager.preload.modules: SSLTransport.py corba.ssl.certificate_authority_file:C:/Python37/Lib/site-packages/OpenRTM_aist/ext/ssl/root.crt corba.ssl.key_file:C:/Python37/Lib/site-packages/OpenRTM_aist/ext/ssl/server.pem corba.ssl.key_file_password:password corba.args:-ORBserverTransportRule "* ssl" -ORBclientTransportRule "* ssl" -ORBendPoint giop:ssl:: corba.nameservers: corbaloc:ssliop:localhost:2809 corba.master_manager: giop:ssl:localhost:2810
各設定項目の内容は以下のようになっています。
項目名 | 説明 |
corba.ssl.certificate_authority_file | ルート証明書 |
corba.ssl.key_file | 秘密鍵+サーバー証明書兼クライアント証明書の連結ファイル |
corba.ssl.key_file_password | 秘密鍵のパスフレーズ |
corba.args | CORBAライブラリの初期化関数に渡す引数。ここでSSLIOP通信のエンドポイントを設定する必要がある。 |
corba.nameservers | ネームサーバーのアドレス。ここでSSLIOP通信でネームサーバーに接続するように設定する。 |
corba.master_manager | マスターマネージャのエンドポイント。マスターマネージャの場合は自身のエンドポイントを設定し、スレーブマネージャの場合は接続先のマスターマネージャのアドレスを設定する。 |
このrtc.confを指定してConsoleIn、ConsoleOutのRTCを起動します。
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleInComp.exe -f rtc.conf
%OPENRTM_INSTALL_DIR%\2.0.0\Components\C++\Examples\vc16\ConsoleOutComp.exe -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f rtc.conf
${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleInComp -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleIn.py -f rtc.conf
python %OpenRTMPython_INSTALL_DIR%\Lib\site-packages\ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleOut.py -f rtc.conf
python3 ${OpenRTMPython_INSTALL_DIR}/share/openrtm-2.0/components/python3/SimpleIO/ConsoleIn.py -f rtc.conf
これでネームサーバーに登録されますが、RTシステムエディタにSSLIOP通信機能はないため、OpenRTM-aistの機能かrtshellによりポートの接続やRTCのアクティブ化を実行する必要があります。
rtc.confのmanager.components.preconnect、manager.components.preactivationでrtcname形式、rtcloc形式を指定することでポートの接続、RTCのアクティブ化ができます。 SSLIOP通信の場合は以下のようにプロトコルにssliopを指定することで使用可能になります。
manager.components.preconnect: ConsoleIn0.out?port=rtcname.ssliop://localhost:2809/*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcname.ssliop://localhost:2809/*/ConsoleOut0
naming.type: corba, manager manager.components.preconnect: ConsoleIn0.out?port=rtcloc.ssliop://localhost:2810/*/ConsoleOut0.in manager.components.preactivation: ConsoleIn0, rtcloc.ssliop://localhost:2810/*/ConsoleOut0
まず、現在インストールされるrtshellでは対応していないため、最新版のrtctree、rtshell、rtsprofileが必要です。
rtshellでSSLIOP通信機能を使用するためには以下の環境変数を設定する必要があります。
環境変数名 | 設定例 | 意味 |
RTCTREE_SSL_ENABLE | YES | YES:rtctreeでSSLIOP通信機能を有効にする。 |
RTCTREE_NAMESERVERS | ssliop:localhost:2809 | 接続するネームサーバー |
ORBsslCAFile | root.crt | ルート証明書 |
ORBsslKeyFile | server.pem | 秘密鍵+サーバー証明書兼クライアント証明書の連結ファイル |
ORBsslKeyPassword | password | 秘密鍵のパスフレーズ |
ORBserverTransportRule | "* ssl" | サーバー側の通信プロトコル選択のルール |
ORBclientTransportRule | "* ssl" | クライアント側の通信プロトコル選択のルール |
ORBendPoint | giop:ssl:: | omniORBのエンドポイント |
set RTCTREE_SSL_ENABLE=YES set ORBsslCAFile=%RTM_ROOT%/ext/ssl/root.crt set ORBsslKeyFile=%RTM_ROOT%/ext/ssl/server.pem set ORBsslKeyPassword=password set RTCTREE_NAMESERVERS=ssliop:localhost:2809 set ORBserverTransportRule=* ssl set ORBclientTransportRule=* ssl set ORBendPoint=giop:ssl::
以下のように接続するネームサーバーのアドレスの前にssliop:を付けることでSSLIOP通信でネームサーバーに接続できるようになります。
rtcon /ssliop:localhost:2809/test.host_cxt/ConsoleIn0.rtc:out /ssliop:localhost:2809/test.host_cxt/ConsoleOut0.rtc:in rtact /ssliop:localhost:2809/test.host_cxt/ConsoleIn0.rtc /ssliop:localhost:2809/test.host_cxt/ConsoleOut0.rtc rtdeact /ssliop:localhost:2809/test.host_cxt/ConsoleIn0.rtc /ssliop:localhost:2809/test.host_cxt/ConsoleOut0.rtc rtexit /ssliop:localhost:2809/test.host_cxt/ConsoleOut0.rtc rtcryo ssliop:localhost:2809 -o sys.rtsys
まずは秘密鍵、証明書の生成が必要です。
証明書にはルート証明書、中間証明書、サーバー証明書、クライアント証明書があります。 以下はサーバー証明書によるサーバー認証を行う場合の概要図です。
通信するサーバー、クライアントPC以外に公開鍵証明書認証局(CA、Certificate Authority)が必要です。 認証局はルート証明書と対応する秘密鍵(秘密鍵1)を持っています。 サーバーは秘密鍵を生成後、生成した秘密鍵(秘密鍵a)でCSR(Certificate Signing Request:公開鍵情報、ウェブサイトの所有者情報)を認証局に送信します。 認証局はCSRに秘密鍵1で署名したサーバー証明書を発行します。 サーバーとクライアントのSSL/TLS通信のハンドシェイク処理でサーバー証明書を送信します。この時に他にも鍵交換アルゴリズムの処理などもありますが説明は省略します。 クライアントは予め入手しておいたルート証明書の公開鍵でサーバー証明書の署名の検証を行い、証明書の検証が完了したら暗号化通信(秘密鍵aで符号化、サーバー証明書の公開鍵で復号)を開始します。
この他に中間認証局がルート認証局から中間証明書を取得し、中間認証局がサーバー証明書を発行する場合があります。 説明は以下のサイトの図が分かりやすいので参考になると思います。
ここまでの説明ではクライアント側がサーバーの認証をしていましたが、サーバーがクライアントの認証をする場合があります。 omniORBでは引数`-ORBsslVerifyMode`や環境変数`ORBsslVerifyMode`で以下のパラメータを設定することで認証方法を変更可能です。
パラメータ | 意味 |
none | サーバー証明書の検証に失敗してもハンドシェイクを継続する。クライアント証明書の要求は実行しない。 |
peer(デフォルト値) | サーバーがクライアント証明書を要求する。サーバー認証、クライアント認証(クライアント証明書が送信されてきた場合)で失敗したらハンドシェイクを終了する。 |
peer, fail | クライアント証明書が送信されなかったらハンドシェイクを終了する。 |
peer, once | クライアント認証を最初のハンドシェイクでのみ実行する。 |
peer, fail, once | 上記の組み合わせ。 |
omniORBはサーバー証明書、クライアント証明書のルート証明書ファイルを個別に指定できないため、どちらも`corba.ssl.certificate_authority_file`オプションで指定してください。
まとめると、OpenRTM-aistのSSL/TLS通信にはルート証明書、サーバー証明書、クライアント証明書、中間証明書、秘密鍵を以下のように配置する必要があります。
以降ではOpenSSLのコマンドを使って自己認証局と自己署名証明書(いわゆるオレオレ証明書)を作成してみます。 cnfファイルは上記のリンク先のサイトのものを使用します。
まず適当な作業フォルダにroot、inter、serverフォルダを作成します。
ルート認証局の秘密鍵、ルート証明書を作成します。
mkdir root cd root mkdir newcerts type nul > index.txt echo 01 > serial echo 00 > crlnumberl openssl genrsa -out RootCA_key.pem -passout pass:rootpass 2048 openssl req -new -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Root CA" -out RootCA_csr.pem -key RootCA_key.pem -passin pass:rootpass -config ../conf/openssl_sign.cnf openssl ca -batch -extensions v3_ca -out RootCA_crt.pem -in RootCA_csr.pem -selfsign -keyfile RootCA_key.pem -passin pass:rootpass -config ../conf/openssl_sign.cnf openssl x509 -in RootCA_crt.pem -out RootCA_crt.pem cd ..
次に中間認証局の秘密鍵、中間証明書のCSRを作成します。
mkdir inter cd inter mkdir newcerts type nul > index.txt echo 01 > serial echo 00 > crlnumberl openssl genrsa -out InterCA_key.pem -passout pass:interpass 2048 openssl req -new -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Intermediate CA" -out InterCA_csr.pem -key InterCA_key.pem -passin pass:interpass -config ../conf/openssl_sign.cnf cd ..
ルート認証局で中間証明書を発行します。
cd root openssl ca -batch -extensions v3_ca -out ..\inter\InterCA_crt.pem -in ..\inter\InterCA_csr.pem -cert RootCA_crt.pem -keyfile RootCA_key.pem -passin pass:interpass -config ../conf/openssl_sign.cnf cd ..
サーバーで秘密鍵とサーバー証明書のCSRを作成します。
mkdir server cd server mkdir newcerts type nul > index.txt echo 01 > serial echo 00 > crlnumberl openssl genrsa -out Server_key.pem -passout pass:serverpass 2048 openssl req -new -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=EXAMPLE Server" -out Server_csr.pem -key Server_key.pem -passin pass:serverpass -config ../conf/openssl_sign.cnf cd ..
中間認証局でサーバー証明書を発行します。
cd inter openssl x509 -req -in ..\server\Server_csr.pem -sha256 -CA InterCA_crt.pem -CAkey InterCA_key.pem -set_serial 01 -days 730 -out ..\server\Server_crt.pem -passin pass:serverpass cd ..
秘密鍵、サーバー証明書、中間証明書を連結します。
cd server openssl x509 -in Server_crt.pem -out Server_crt.pem openssl x509 -in ..\inter\InterCA_crt.pem -out InterCA_crt.pem copy /b Server_key.pem + Server_crt.pem + InterCA_crt.pem server.pem
今回使用するのは連結したファイル(server.pem)とルート証明書(RootCA_crt.pem)です。
OpenRTM-aistをビルド、インストールすると、SSLTransportの簡単な動作確認用の設定ファイルがインストールされます。
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\bin\vc16\openrtmNames.exe -f %RTM_ROOT%\ext\rtc.names.ssl.conf
%RTM_ROOT%\ext\environment-setup.omniorb.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\ssl\rtc.ssl.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/bin/openrtmNames -f ${OPENRTM_INSTALL_DIR}/etc/rtc.names.ssl.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/ssl/rtc.ssl.conf
まずは通常のRTC作成手順と同じくプロジェクトの作成、モジュール名の設定、言語の設定(C++)を行います。
次にFSMタブからFSMのチェックボックスをオンにします。 さらに新規作成ボタンを押してGUIエディタを起動します。
起動したエディタで右クリックしてAdd nodeを選択する。
作成したノードを右クリックしてEdit nodeを選択します。
State Nameを適当な名前に変更します。
同様の手順でノードを複数作成します。 以下の図ではToggle Initial、Toggle finalを設定しているノードがありますが、この設定により生成するコードは変化しないようです。
一部のノードはOn Entry、On Exitをオンにしてください。
またノードからノードへドラッグアンドドロップすることで状態遷移を定義します。
エディタを閉じます。
その後、コード生成を行います。
ビルドにはOpenRTM-aist 2.0が必要です。 以下の手順でOpenRTM-aistでビルドしてください。
その後、INSTALLのプロジェクトをビルドして適当な場所にインストールしてください。 インストールする場所を変更するためにはCMAKE_INSTALL_PREFIXのオプションを変更します。
RTCのコードを生成したフォルダで以下のコマンドを実行します。
mkdir build cd build set OPENRTM_DIR={OpenRTM-aistをインストールしたディレクトリ}\2.0.0\cmake cmake -G "Visual Studio 15 2017" -A x64 .. cmake --build . --config Release
執筆中
OpenRTM-aistはFluent Bitプラグインのように、OpenRTM-aistデフォルトのロガー以外のロギング機能を拡張することができます。
このページでは独自ロガーの作成方法、使用手順を説明します。
今回作成したソースコードは以下から入手できます。
C++の場合はビルドのためのCMakeLists.txtを用意してください。今回はTestLoggerという名前で作成します。
cmake_minimum_required(VERSION 3.1) set(target TestLogger) project(${target} CXX) find_package(OpenRTM REQUIRED) add_definitions(${OPENRTM_CFLAGS}) link_directories(${OPENRTM_LIBRARY_DIRS}) add_library(${target} SHARED ${target}.cpp ${target}.h) target_link_libraries(${target} ${OPENRTM_LIBRARIES}) target_include_directories(${target} SYSTEM PRIVATE ${OPENRTM_INCLUDE_DIRS}) set_target_properties(${target} PROPERTIES PREFIX "")
ヘッダーファイル(TestLogger.h)、ソースファイル(TestLogger.cpp)を用意します。 coil::LogStreamBufferクラスを継承したTestLoggerStreamクラス、RTC::LogstreamBaseクラスを継承したTestLoggerクラスを実装します。 TestLoggerStreamはロギングの処理を実装するクラスで、TestLoggerはTestLoggerStreamを生成して外部から取得可能にするクラスです。
#ifndef TESTLOGGER_H #define TESTLOGGER_H #include <rtm/LogstreamBase.h> class TestLoggerStream : public coil::LogStreamBuffer { public: TestLoggerStream(); ~TestLoggerStream() override; bool init(const coil::Properties& prop); void write(int level, const std::string& name, const std::string& date, const std::string& mes) override; private: std::string header; }; class TestLogger : public RTC::LogstreamBase { public: TestLogger(); ~TestLogger() override; bool init(const coil::Properties& prop) override; coil::LogStreamBuffer* getStreamBuffer() override; private: TestLoggerStream m_logstream; }; extern "C" { void DLL_EXPORT TestLoggerInit(); } #endif
#include "TestLogger.h" #include <iostream> TestLoggerStream::TestLoggerStream() { } TestLoggerStream::~TestLoggerStream() { } bool TestLoggerStream::init(const coil::Properties& prop) { header = prop["header"]; return true; } void TestLoggerStream::write(int level, const std::string& name, const std::string& date, const std::string& mes) { std::cout << header << ":" << mes << std::endl; } TestLogger::TestLogger() { } TestLogger::~TestLogger() { } bool TestLogger::init(const coil::Properties& prop) { m_logstream.init(prop); return true; } coil::LogStreamBuffer* TestLogger::getStreamBuffer() { return &m_logstream; } extern "C" { void TestLoggerInit() { ::RTC::LogstreamFactory:: instance().addFactory("testlogger", ::coil::Creator< ::RTC::LogstreamBase, TestLogger>, ::coil::Destructor< ::RTC::LogstreamBase, TestLogger>); } }
TestLoggerクラスのinit関数で初期化、getStreamBuffer関数でLogStreamBufferオブジェクトを取得することができます。 TestLoggerクラスは特に理由が無ければ変更の必要はないです。
TestLoggerStreamクラスのwrite関数でログの出力を行います。 この例では、プロパティのheaderオプションに設定した文字列をログメッセージの先頭に追加して標準出力しています。
TestLoggerInit関数は動的ライブラリをロードする時に呼び出す関数です。〇〇.dllであれば〇〇Initというように、初期化関数は動的ライブラリの名前+Initにしてください。 TestLoggerInit関数内でLogstreamFactoryのaddFactory関数を呼ぶことでロガーを追加できます。
ビルドしてTestLogger.dll、TestLogger.soを生成後に動作確認を行います。
以下のrtc.confを作成してください。
logger.enable: YES logger.log_level: VERBOSE logger.plugins: TestLogger.dll logger.logstream.testlogger.enable: ON logger.logstream.testlogger.header: example
まずlogger.pluginsオプションを設定してTestLoggerをロードするようにします。 ただロードするだけでは有効にはならないため、logger.logstream.testlogger.enableオプションを設定します。
※OpenRTM-aistの動作としてはlogger.logstream.${モジュール名}以下のオプションが設定されている場合にロガーが有効になるため、必ずしもenableオプションである必要はありません。
logger.logstream.testlogger.headerオプションでログメッセージの先頭に追加する文字列を指定しています。
このrtc.confを指定してRTCを起動するとログが標準出力されることが確認できます。
Pythonファイル(TestLogger.py)を用意します。 OpenRTM_aist.LogstreamBaseを継承したTestLoggerクラスを実装します。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import OpenRTM_aist class TestLogger(OpenRTM_aist.LogstreamBase): def __init__(self): OpenRTM_aist.LogstreamBase.__init__(self) self._header = "" def __del__(self): pass def init(self, prop): self._header = prop.getProperty("header") return True def log(self, msg, level, name): print(self._header+":"+msg) return True def setLogLevel(self, level): pass def shutdown(self): return True def TestLoggerInit(mgr): OpenRTM_aist.LogstreamFactory.instance().addFactory("testlogger", TestLogger)
TestLoggerクラスのinit関数で初期化、log関数でログの出力、setLogLevel関数でログレベルの設定、shutdown関数で終了処理を行います。 この例では、プロパティのheaderオプションに設定した文字列をログメッセージの先頭に追加して標準出力しています。
TestLoggerInit関数はPythonモジュールをロードする時に呼び出す関数です。〇〇.pyであれば〇〇Initというように、初期化関数はPythonファイルの名前+Initにしてください。 TestLoggerInit関数内でLogstreamFactoryのaddFactory関数を呼ぶことでロガーを追加できます。
以下のrtc.confを作成してください。
logger.enable: YES logger.log_level: VERBOSE logger.plugins: TestLogger.py logger.logstream.testlogger.enable: ON logger.logstream.testlogger.header: example
まずlogger.pluginsオプションを設定してTestLoggerをロードするようにします。 ただロードするだけでは有効にはならないため、logger.logstream.testlogger.enableオプションを設定します。
logger.logstream.testlogger.headerオプションでログメッセージの先頭に追加する文字列を指定しています。
このrtc.confを指定してRTCを起動するとログが標準出力されることが確認できます。
OpenRTM-aistのデータポートでは以下のようにデータをバイト列に変換するシリアライザ、データを送信する通信インターフェースの種類については複数の実装から選択可能です。
インターフェース型が選択可能のためRTC同士だけではなく、ROSのノード、あるいはROS2のようにDDSにより通信を行うプロセスとデータのやり取りが可能になります。 またシリアライザが選択可能のため、図のようにTimedLong型をTimedLong型のような別のデータ型に変換して様々なデータ型のポートと柔軟に接続することができます。
現在はC++版、Python版で使用可能です。
以下に独自シリアライザの作成手順を記載します。
OpenRTM-aist 2.0以上が必要なため、以下の手順でソースコードからビルドを行う必要がある。
ビルド終了後、特定の場所にインストールする。
cmake-guiでCMAKE_INSTALL_PREFIXを設定するか、cmake実行時のコマンドで設定する。
cmake -DORB_ROOT=C:/workspace/omniORB-4.2.3-win64-vc141 -G "Visual Studio 16 2019" -A x64 .. -DCMAKE_INSTALL_PREFIX=C:/workspace/openrtm_install
ビルド後に、以下のコマンドでインストールする。
cmake --build .. --target INSTALL --config Release
Visual Studio上でINSTALLのプロジェクトをビルドしてもインストールできる。
独自シリアライザの実装には以下のファイルを作成する必要がある。
CMakeLists.txtにはOpenRTM-aistのパッケージの検出、動的ライブラリを生成するようにコマンドを記述します。
cmake_minimum_required (VERSION 3.0.2) project (TestSerializer VERSION 1.0 LANGUAGES CXX)
#OpenRTM-aistの検出 find_package(OpenRTM REQUIRED) #インクルードディレクトリ、リンクディレクトリ、コンパイル時のフラグの設定 include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR}/idl) include_directories(${OPENRTM_INCLUDE_DIRS}) add_definitions(${OPENRTM_CFLAGS}) link_directories(${OPENRTM_LIBRARY_DIRS}) #動的リンクライブラリの生成 add_library(${PROJECT_NAME} SHARED TestSerializer.cpp) #生成するライブラリ名をTestSerializer.dll(もしくは.so)に設定 set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") #OpenRTM-aistのライブラリとリンク target_link_libraries(${PROJECT_NAME} ${OPENRTM_LIBRARIES})
TestSerializer.cppを以下のように作成します。
#include <rtm/ByteDataStreamBase.h> #include <rtm/idl/BasicDataTypeSkel.h> #include <coil/Factory.h> #include <rtm/Manager.h> //以下はシリアライザの実装 template <class DataType> class TestSerializer : public RTC::ByteDataStream<DataType> { public: TestSerializer():m_buffer(NULL), m_length(0){}; void writeData(const unsigned char* buffer, unsigned long length) override { delete m_buffer; m_buffer = new unsigned char[length]; memcpy(m_buffer, buffer, length); m_length = length; } void readData(unsigned char* buffer, unsigned long length) const override { if (m_buffer) { memcpy(buffer, m_buffer, length); } } unsigned long getDataLength() const override { return m_length; } bool serialize(const DataType& data) override { delete m_buffer; m_buffer = new unsigned char[1]; m_buffer[0] = static_cast<unsigned char>(data.data); m_length = 1; return true; } bool deserialize(DataType& data) override { if (m_buffer) { data.data = static_cast<long>(m_buffer[0])+1; return true; } return false; } private: unsigned char* m_buffer; unsigned long m_length; }; extern "C" { //以下はモジュールロード時に呼び出される関数 DLL_EXPORT void TestSerializerInit(RTC::Manager* manager) { //以下のファクトリはデータ型ごとに登録する必要がある RTC::addSerializer<RTC::TimedLong, TestSerializer<RTC::TimedLong>>("test"); }; }
シリアライザにはwriteData関数、readData関数、getDataLength関数、serialize関数、deserialize関数を実装する必要がある。 serialize関数はRTMのデータをunsigned char型に変換して内部のバッファに保存する。 保存したデータはreadData関数で取り出すことができる。 このため、データ送信時の処理は以下のようになっている。
writeData関数は内部のバッファにバイト列のデータを書き込む関数である。 deserialize関数は内部のバッファのデータをRTMのデータ型に変換して外部の変数に渡す。 このため、データ受信時の処理は以下のようになっている。
getDataLengthは内部で保持しているデータの長さを取得する関数である。
OpenRTM-aistをソースコードからビルド、インストールした場合は環境変数が設定されていないためcmake実行時にOpenRTMConfig.cmakeの場所を指定する必要がある。
cmake -G "Visual Studio 15 2017" -A x64 .. -DOpenRTM_DIR=C:/workspace/openrtm1/build/install/2.0.0/cmake
この後Visual Studio等でビルドを行う。
上記の作業でTestSerializer.dllが生成されているはずのため、TestSerializer.dllをRTC実行時にロードして利用できるようにする。
rtc.confに以下のように記述することでロードできる。モジュール探索パスは適宜変更する。
manager.modules.load_path: . manager.modules.preload: TestSerializer.dll
データポート接続時にmarshaling_typeのオプションでシリアライザを設定できる。
manager.components.preconnect: ConsoleOut0.in?port=ConsoleIn0.out&marshaling_type=test
RT System Editorで設定する場合はdataport.marshaling_typeといパラメータで設定する。
これで独自シリアライザ(TestSerializer)が使用可能になったため、ConsoleInとConsoleOutで通信すると標準入力した数値に1を足した数値が表示される。
以下はConsoleInとConsoleOutのデータポートを接続してアクティベートするrtc.confの例。
manager.modules.load_path: . manager.modules.preload: TestSerializer.dll, ConsoleOut.dll manager.components.precreate: ConsoleOut manager.components.preconnect: ConsoleOut0.in?port=ConsoleIn0.out&marshaling_type=test manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aist 2.0以上が必要なため、以下の手順でソースコードからビルドを行う必要がある。
独自シリアライザの実装には以下のファイルを作成する必要がある。
TestSerializer.pyを以下のように作成します。
#!/usr/bin/env python # -*- coding: euc-jp -*- import OpenRTM_aist import RTC #以下はシリアライザの実装 class TestSerializer(OpenRTM_aist.ByteDataStreamBase): def __init__(self): pass def __del__(self): pass def serialize(self, data): if data._NP_RepositoryId == RTC.TimedLong._NP_RepositoryId: bdata = str(data.data) return OpenRTM_aist.ByteDataStreamBase.SERIALIZE_OK, bdata else: return OpenRTM_aist.ByteDataStreamBase.SERIALIZE_ERROR, "" def deserialize(self, cdr, data_type): if data_type._NP_RepositoryId == RTC.TimedLong._NP_RepositoryId: data_type.data = int(cdr)+1 return OpenRTM_aist.ByteDataStreamBase.SERIALIZE_OK, data_type else: return OpenRTM_aist.ByteDataStreamBase.SERIALIZE_ERROR, data_type #以下はモジュールロード時に呼び出される関数 def TestSerializerInit(mgr): OpenRTM_aist.SerializerFactories.instance().addSerializer("test:RTC.TimedLong", # addFactory関数の第1引数で登録名を設定。以下で独自シリアライザを利用するときはこの名前を使用する。 TestSerializer, RTC.TimedLong) #OpenRTM_aist.SerializerFactory.instance().addSerializerGlobal("test", #addSerializerGlobalを使うと特定のデータ型だけではなく、全てのデータ型でTestSerializerを使用可能にする TestSerializer)
シリアライザにはserialize関数、deserialize関数を実装する必要がある。 serialize関数はRTMのデータをバイト列のデータ等に変換してリターンコードと変換後のデータを返す。
deserialize関数はバイト列のデータなどをRTMのデータに変換してリターンコードと変換後のデータを返す。
TestSerializer.pyをRTC実行時にロードして利用できるようにする。
rtc.confに以下のように記述することでロードできる。モジュール探索パスは適宜変更する。
manager.modules.load_path: . manager.modules.preload: TestSerializer.py
データポート接続時にmarshaling_typeのオプションでシリアライザを設定できる。
manager.components.preconnect: ConsoleOut0.in?port=ConsoleIn0.out&marshaling_type=test
RT System Editorで設定する場合はdataport.marshaling_typeといパラメータで設定する。
これで独自シリアライザ(TestSerializer)が使用可能になったため、ConsoleInとConsoleOutで通信すると標準入力した数値に1を足した数値が表示される。
以下はConsoleInとConsoleOutのデータポートを接続してアクティベートするrtc.confの例。
manager.modules.load_path: . manager.modules.preload: TestSerializer.py, ConsoleOut.py manager.components.precreate: ConsoleOut manager.components.preconnect: ConsoleOut0.in?port=ConsoleIn0.out&marshaling_type=test manager.components.preactivation: ConsoleOut0, ConsoleIn0
OpenRTM-aistのデータ型とROSのメッセージ型を変換するシリアライザの作成のためには、ROSTransport、ROSのヘッダーファイルのインクルード、ライブラリのリンクが必要になります。 以下のようにCMakeLists.txtでOpenRTM-aist、ROS、Boostを検出します。
#OpenRTM-aistの検出 find_package(OpenRTM 2.0 REQUIRED) find_package(ROSTransport REQUIRED)
#ROSの検出 find_package(PkgConfig REQUIRED) pkg_check_modules(roscpp roscpp) if(NOT roscpp_FOUND) message(FATAL_ERROR "can not find roscpp.") endif() #Boostの検出 find_package(Boost COMPONENTS chrono filesystem system) if(NOT Boost_FOUND) find_package(Boost REQUIRED COMPONENTS chrono filesystem signals system) endif()
以下のように動的リンクライブラリの生成、検出したライブラリのリンク、インクルードディレクトリの設定を行います。
#インクルードディレクトリ、リンクディレクトリ、コンパイル時のフラグの設定 include_directories(${OPENRTM_INCLUDE_DIRS}) add_definitions(${OPENRTM_CFLAGS}) link_directories(${OPENRTM_LIBRARY_DIRS}) link_directories(${roscpp_LIBRARY_DIRS}) #動的リンクライブラリの生成 add_library(${PROJECT_NAME} SHARED TestRosSerializer.cpp) #生成するライブラリ名をTestRosSerializer.dll(もしくは.so)に設定 set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") #OpenRTM-aist、ROS、Boostのライブラリとリンク target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${roscpp_INCLUDE_DIRS} PRIVATE ${Boost_INCLUDE_DIRS} PRIVATE ${ROSTRANSPORT_INCLUDE_DIRS}) target_link_libraries(${PROJECT_NAME} ${OPENRTM_LIBRARIES} ${roscpp_LIBRARIES} ${Boost_LIBRARIES} ${ROSTRANSPORT_LIBRARIES})
ROS用シリアライザを作成する場合、CPPファイルでROSSerializer.hをインクルードします。 また、今回はROSのgeometry_msgs/TwistStamped型を使用するため、geometry_msgs/TwistStamped.hをインクルードします。このインクルードファイルは使用するメッセージ型により変更します。
#include <rtm/ByteDataStreamBase.h> #include <rtm/idl/BasicDataTypeSkel.h> #include <rtm/idl/ExtendedDataTypesSkel.h> #include <coil/Factory.h> #include <rtm/Manager.h> #include <rtm/ext/ROSTransport/ROSSerializer.h> #include <geometry_msgs/TwistStamped.h>
ROSSerializerBaseクラスを継承したクラスを定義します。 ROSSerializerBaseクラスのテンプレート引数には使用するOpenRTM-aistのデータ型を指定します。今回はRTC::TimedVelocity3D型を使用するため、RTC::TimedVelocity3Dを指定します。
class TestRosSerializer : public RTC::ROSSerializerBase<RTC::TimedVelocity3D> { public: TestRosSerializer(){};
以下のようにTestRosSerializerクラスのメンバ関数としてserialize関数を定義する。 serialize関数では、RTC::TimedVelocity3D型のデータをgeometry_msgs/TwistStamped型のデータに変換し、その後バイト列データに変換しています。
bool serialize(const RTC::TimedVelocity3D& data) override { geometry_msgs::TwistStamped msg; msg.header.stamp.sec = data.tm.sec; msg.header.stamp.nsec = data.tm.nsec; msg.twist.linear.x = data.data.vx; msg.twist.linear.y = data.data.vy; msg.twist.linear.z = data.data.vz; msg.twist.angular.x = data.data.vr; msg.twist.angular.y = data.data.vp; msg.twist.angular.z = data.data.va; RTC::ROSSerializerBase<RTC::TimedVelocity3D>::m_message = ros::serialization::serializeMessage<geometry_msgs::TwistStamped>(msg); return true; }
次にdeserialize関数を定義します。 deserialize関数では、バイト列データをgeometry_msgs/TwistStamped型のデータに変換し、その後RTC::TimedVelocity3D型のデータに変換しています。
bool deserialize(RTC::TimedVelocity3D& data) override { geometry_msgs::TwistStamped msg; ros::serialization::deserializeMessage(ROSSerializerBase<RTC::TimedVelocity3D>::m_message, msg); data.tm.sec = msg.header.stamp.sec; data.tm.nsec = msg.header.stamp.nsec; data.data.vx = msg.twist.linear.x; data.data.vy = msg.twist.linear.y; data.data.vz = msg.twist.linear.z; data.data.vr = msg.twist.angular.x; data.data.vp = msg.twist.angular.y; data.data.va = msg.twist.angular.z; return true; }
以下ように{ライブラリ名}Init関数を定義すると、動的リンクライブラリのロード時にこの関数が呼ばれます。 TestRosSerializerInit関数内でファクトリにシリアライザを追加することにより、RTC起動時に実装したシリアライザが使えるようにします。
extern "C" { //以下はモジュールロード時に呼び出される関数 DLL_EXPORT void TestRosSerializerInit(RTC::Manager* /*manager*/) { //シリアライザの登録 RTC::addRosSerializer<RTC::TimedVelocity3D, geometry_msgs::TwistStamped, TestRosSerializer>("ros:geometry_msgs/TwistStamped"); } }
以下から作成済みのシリアライザ、動作確認用のRTCをダウンロードできます。
作成したTestRosSerializerをビルドしてください。 ビルド、実行時にはROSの環境変数が設定されている必要があるため、以下のコマンドを実行してください。
source /opt/ros/noetic/setup.bash
rtc.confを作成します。 ROSTransport.soと、作成したシリアライザTestRosSerializer.soをロードするように設定します。 TestRosSerializer.soのパスは、ビルドしたディレクトリのパスに変更してください。
manager.modules.load_path: /usr/lib/openrtm-2.0/transport/, ~/TestRosSerializer/build manager.modules.preload: ROSTransport.so, TestRosSerializer.so
以下のようにサンプルコンポーネントのtestVelocity3DInのInPort、testVelocity3DOutのOutPortでコネクションを生成します。
manager.components.preconnect: testVelocity3DIn0.in?interface_type=ros&marshaling_type=ros:geometry_msgs/TwistStamped&ros.topic=chatter&ros.so_keepalive=NO&ros.node.name=testVelocity3DIn0, testVelocity3DOut0.out?interface_type=ros&marshaling_type=ros:geometry_msgs/TwistStamped&ros.topic=chatter&ros.node.name=testVelocity3DOut0
動作確認する場合は、testOpenRTMSerializerに含まれているtestVelocity3DIn、testVelocity3DOutのサンプルコンポーネントをビルドしてください。
以下のコマンド実行後、RTCをアクティブ化するとtestVelocity3DOutのPublisherからtestVelocity3DInのSubscriberにデータが送信されて、testVelocity3DInを起動した画面に数値が表示されます。
testVelocity3DOutComp -f rtc.conf
testVelocity3DInComp -f rtc.conf
今回の動作確認ではRTC同士でROSのトピック通信を実行しましたが、ROSノードと通信を確認する場合は、geometry_msgs/TwistStamped型のPublisher、Subscriberを持つROSノードを作成して試してください。
OpenRTM-aistのデータ型とROSのメッセージ型を変換するシリアライザの作成のためには、ROSTransport、ROS2のヘッダーファイルのインクルード、ライブラリのリンクが必要になります。 以下のようにCMakeLists.txtでOpenRTM-aist、ROS2、FastDDSを検出します。
cmake_minimum_required(VERSION 3.5) #OpenRTM-aistの検出 find_package(OpenRTM 2.0 REQUIRED) find_package(ROS2Transport REQUIRED) #ROS2の検出 find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) find_package(geometry_msgs REQUIRED) find_package(sensor_msgs REQUIRED) #FastDDSの検出 find_package(fastcdr REQUIRED) find_package(fastrtps REQUIRED)
以下のように動的リンクライブラリの生成、検出したライブラリのリンク、インクルードディレクトリの設定を行います。
#インクルードディレクトリ、リンクディレクトリ、コンパイル時のフラグの設定 include_directories(${OPENRTM_INCLUDE_DIRS}) add_definitions(${OPENRTM_CFLAGS}) link_directories(${OPENRTM_LIBRARY_DIRS}) #動的リンクライブラリの生成 add_library(${PROJECT_NAME} SHARED TestRos2Serializer.cpp) #生成するライブラリ名をTestRos2Serializer.dll(もしくは.so)に設定 set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${rclcpp_INCLUDE_DIRS} PUBLIC ${std_msgs_INCLUDE_DIRS} PUBLIC ${geometry_msgs_INCLUDE_DIRS} PUBLIC ${sensor_msgs_INCLUDE_DIRS} PUBLIC ${ROS2TRANSPORT_INCLUDE_DIRS}) #OpenRTM-aistのライブラリとリンク target_link_libraries(${PROJECT_NAME} ${OPENRTM_LIBRARIES} ${ROS2TRANSPORT_LIBRARIES} ${rclcpp_LIBRARIES} ${std_msgs_LIBRARIES} ${geometry_msgs_LIBRARIES} ${sensor_msgs_LIBRARIES} ${std_msgs_LIBRARIES__rosidl_typesupport_fastrtps_cpp} ${geometry_msgs_LIBRARIES__rosidl_typesupport_fastrtps_cpp} ${sensor_msgs_LIBRARIES__rosidl_typesupport_fastrtps_cpp} fastcdr fastrtps) target_compile_definitions(${PROJECT_NAME} PRIVATE STD_MSGS_VERSION_MAJOR=${std_msgs_VERSION_MAJOR} GEOMETORY_MSGS_VERSION_MAJOR=${geometry_msgs_VERSION_MAJOR} SENSOR_MSGS_VERSION_MAJOR=${sensor_msgs_VERSION_MAJOR} STD_MSGS_VERSION_MINOR=${std_msgs_VERSION_MINOR} GEOMETORY_MSGS_VERSION_MINOR=${geometry_msgs_VERSION_MINOR} SENSOR_MSGS_VERSION_MINOR==${sensor_msgs_VERSION_MINOR})
ROS用シリアライザを作成する場合、CPPファイルでROS2Serializer.hをインクルードします。 また、今回はROS2のgeometry_msgs/TwistStamped型を使用するため、geometry_msgs/msg/twist_stamped.hpp、geometry_msgs/msg/detail/twist_stamped__rosidl_typesupport_fastrtps_cpp.hppをインクルードします。このインクルードファイルは使用するメッセージ型により変更します。
#include <rtm/ByteDataStreamBase.h> #include <rtm/idl/BasicDataTypeSkel.h> #include <rtm/idl/ExtendedDataTypesSkel.h> #include <coil/Factory.h> #include <rtm/Manager.h> #include <geometry_msgs/msg/twist_stamped.hpp> #if (STD_MSGS_VERSION_MAJOR >= 2) #include <geometry_msgs/msg/detail/twist_stamped__rosidl_typesupport_fastrtps_cpp.hpp> #else #include <geometry_msgs/msg/twist_stamped__rosidl_typesupport_fastrtps_cpp.hpp> #endif #include <rtm/ext/ROS2Transport/ROS2Serializer.h>
ROS2SerializerBaseクラスを継承したクラスを定義します。 ROS2SerializerBaseクラスのテンプレート引数には使用するOpenRTM-aistのデータ型を指定します。今回はRTC::TimedVelocity3D型を使用するため、RTC::TimedVelocity3Dを指定します。
class TestRos2Serializer : public RTC::ROS2SerializerBase<RTC::TimedVelocity3D> { public: TestRos2Serializer(){};
以下のようにTestRos2Serializerクラスのメンバ関数としてserialize関数を定義する。 serialize関数では、RTC::TimedVelocity3D型のデータをgeometry_msgs/TwistStamped型のデータに変換し、その後バイト列データに変換しています。 geometry_msgs/TwistStamped型のデータからバイト列データへの変換は、geometrymsg_serialize関数を使用しています。 std_msgパッケージのメッセージ型の場合はstdmsg_serialize関数、geometry_msgsパッケージのメッセージ型の場合はgeometrymsg_serialize関数、sensor_msgパッケージのメッセージ型の場合はsensormsg_serialize関数を使用します。
bool serialize(const RTC::TimedVelocity3D& data) override { geometry_msgs::msg::TwistStamped msg; msg.header.stamp.sec = data.tm.sec; msg.header.stamp.nanosec = data.tm.nsec; msg.twist.linear.x = data.data.vx; msg.twist.linear.y = data.data.vy; msg.twist.linear.z = data.data.vz; msg.twist.angular.x = data.data.vr; msg.twist.angular.y = data.data.vp; msg.twist.angular.z = data.data.va; return RTC::ROS2SerializerBase<RTC::TimedVelocity3D>::geometrymsg_serialize(msg); }
std_msg、geometry_msgs、sensor_msg以外のパッケージのメッセージ型の場合は、stdmsg_serialize関数の実装を参考にして記述してください。
次にdeserialize関数を定義します。 deserialize関数では、バイト列データをgeometry_msgs/TwistStamped型のデータに変換し、その後RTC::TimedVelocity3D型のデータに変換しています。 バイト列データからgeometry_msgs/TwistStamped型のデータへの変換は、geometrymsg_deserialize関数を使用しています。 std_msgパッケージのメッセージ型の場合はstdmsg_deserialize関数、geometry_msgsパッケージのメッセージ型の場合はgeometrymsg_deserialize関数、sensor_msgパッケージのメッセージ型の場合はsensormsg_deserialize関数を使用します。
bool deserialize(RTC::TimedVelocity3D& data) override { geometry_msgs::msg::TwistStamped msg; bool ret = ROS2SerializerBase<RTC::TimedVelocity3D>::geometrymsg_deserialize(msg); data.tm.sec = msg.header.stamp.sec; data.tm.nsec = msg.header.stamp.nanosec; data.data.vx = msg.twist.linear.x; data.data.vy = msg.twist.linear.y; data.data.vz = msg.twist.linear.z; data.data.vr = msg.twist.angular.x; data.data.vp = msg.twist.angular.y; data.data.va = msg.twist.angular.z; return ret; }
std_msg、geometry_msgs、sensor_msg以外のパッケージのメッセージ型の場合は、stdmsg_deserialize関数の実装を参考にして記述してください。
以下ように{ライブラリ名}Init関数を定義すると、動的リンクライブラリのロード時にこの関数が呼ばれます。 TestRos2SerializerInit関数内でファクトリにシリアライザを追加することにより、RTC起動時に実装したシリアライザが使えるようにします。
extern "C" { //以下はモジュールロード時に呼び出される関数 DLL_EXPORT void TestRos2SerializerInit(RTC::Manager* /*manager*/) { //シリアライザの登録 RTC::addRos2Serializer<RTC::TimedVelocity3D, geometry_msgs::msg::TwistStamped, TestRos2Serializer>("ros2:geometry_msgs/TwistStamped"); } }
以下から作成済みのシリアライザ、動作確認用のRTCをダウンロードできます。
作成したTestRos2Serializerをビルドしてください。 ビルド、実行時にはROS2の環境変数が設定されている必要があるため、以下のコマンドを実行してください。
source /opt/ros/foxy/setup.bash
rtc.confを作成します。 FastRTPSTransport.so、ROS2Transport.soと、作成したシリアライザTestRos2Serializer.soをロードするように設定します。 TestRos2Serializer.soのパスは、ビルドしたディレクトリのパスに変更してください。
manager.modules.load_path: /usr/lib/openrtm-2.0/transport/, ~/TestRos2Serializer/build manager.modules.preload: FastRTPSTransport.so, ROS2Transport.so, TestRos2Serializer.so
以下のようにサンプルコンポーネントのtestVelocity3DInのInPort、testVelocity3DOutのOutPortでコネクションを生成します。
manager.components.preconnect: testVelocity3DIn0.in?interface_type=fast-rtps&marshaling_type=ros2:geometry_msgs/TwistStamped&fast-rtps.topic=chatter, testVelocity3DOut0.out?interface_type=fast-rtps&marshaling_type=ros2:geometry_msgs/TwistStamped&fast-rtps.topic=chatter
動作確認する場合は、testOpenRTMSerializerに含まれているtestVelocity3DIn、testVelocity3DOutのサンプルコンポーネントをビルドしてください。
以下のコマンド実行後、RTCをアクティブ化するとtestVelocity3DOutのPublisherからtestVelocity3DInのSubscriberにデータが送信されて、testVelocity3DInを起動した画面に数値が表示されます。
testVelocity3DOutComp -f rtc.conf
testVelocity3DInComp -f rtc.conf
今回の動作確認ではRTC同士でROS2のトピック通信を実行しましたが、ROS2ノードと通信を確認する場合は、geometry_msgs/TwistStamped型のPublisher、Subscriberを持つROS2ノードを作成して試してください。
Choreonoidはオープンソースのロボット用シミュレーションソフトウェアです。 拡張性が高く、物理エンジン、通信機能、スクリプティング機能、制御アルゴリズム等をC++プラグインとして追加できます。
Choreonoid用OpenRTMプラグインはChoreonoid上でRTCを起動し、シミュレータ上のオブジェクトのトルクや速度、ビジョンセンサやレーザーレンジセンサ等の入出力をポートの入出力と関連付けたRTCを作成できます。 これにより外部のRTCとChoreonoidの入出力が連携し、RTCの再利用によるシミュレータ実行の効率化、シミュレータ環境から実機環境へシームレスに移行できます。
このページではOpenRTMプラグインのインストール手順について説明します。
OpenRTMプラグインは現在OpenRTM-aist 1.2.2以前のバージョンのサポートを終了しています。 OpenRTM-aist 2.0.0以上のバージョンのインストールが必要です。
OpenRTM-aist+omniORBを以下の手順でビルド、インストールしてください。 ※インストーラーでOpenRTM-aistをインストールしている場合は不要。
ただし、CMake実行時にOpenRTM-aistのインストールフォルダは指定してそこにインストールするようにしてください。
set OPENRTM_INSTALL_DIR=C:/work/openrtm_install set OMNIORB_SOURCE_DIR=C:/workspace/omniORB-4.2.5-x64-vc14-py310 cmake .. -DORB_ROOT=%OMNIORB_SOURCE_DIR% -DCMAKE_INSTALL_PREFIX=%OPENRTM_INSTALL_DIR% cmake --build . --config Release cmake --build . --config Release --target install
またOpenSSLのヘッダーファイル、ライブラリを適当な場所に展開してください。
Choreonoidを以下の手順でビルド、インストールしてください。
CMake、Boost、Qtのバージョンには注意してください。
OpenRTMプラグインの使用のためにはCORBAプラグインのビルドに、ヘッダーファイルなどの各種ファイルをインストールが必要です。 また、OpenRTM Pythonプラグインの使用のためにはPythonプラグインのビルドが必要です。
設定項目 | 内容 | 設定例 |
ENABLE_CORBA | CORBA通信機能の有効化、無効化 | ON |
BUILD_CORBA_PLUGIN | CORBAプラグインのビルドの有無 | ON |
CHOREONOID_OMNIORB_DIR | omniORBのインストールフォルダのパス | C:/work/openrtm_install/2.0.0/omniORB/4.2.5_vc16 |
INSTALL_SDK | ヘッダーファイルなどの各種ファイルをインストールするか | ON |
ENABLE_PYTHON | Pythonスクリプティング機能、およびPythonプラグインのビルドの有無 | ON |
CMAKE_INSTALL_PREFIX | Choreonoidのインストールフォルダ | C:/work/choreonoid_install |
CHOREONOID_OMNIORB_DIRについては環境変数OMNI_ROOTを設定していると自動でomniORBを検出しますが、Choreonoidが生成するCMakeコンフィグファイルの問題でOpenRTMプラグインのビルドでエラーが発生することがあるので必ず手動でパスを設定してください。 またPythonプラグインのビルドのため、Pythonをインストールしてください。
コマンドでは以下のように入力できます。
set CHOREONOID_INSTALL_DIR=C:/work/choreonoid_install Invoke-WebRequest -Uri https://github.com/choreonoid/choreonoid/archive/refs/tags/v1.7.0.zip -OutFile choreonoid-1.7.0.zip Expand-Archive -Path choreonoid-1.7.0.zip -DestinationPath . Rename-Item choreonoid-1.7.0 choreonoid cd choreonoid mkdir build cd build cmake .. -DENABLE_CORBA=ON -DBUILD_CORBA_PLUGIN=ON -DINSTALL_SDK=ON -DCHOREONOID_OMNIORB_DIR=%OPENRTM_INSTALL_DIR%/2.0.0/omniORB/4.2.5_vc16 -DENABLE_PYTHON=ON -DCMAKE_INSTALL_PREFIX=%CHOREONOID_INSTALL_DIR% cmake --build . --config Release cmake --build . --config Release --target install
※choreonoidのリポジトリのmasterブランチのソースコードに不具合があり、WindowsでのCorbaPluginのビルドでエラーが発生します。masterブランチのソースコードを使う場合、src/CorbaPlugin/CorbaPlugin.cppの以下の部分を修正してください。
nameServerProcess.start(QString("\"") + command.c_str() + "\""); //修正前 nameServerProcess.start(QString("\"") + command.c_str() + "\"", QStringList()); //修正後
※OpenRTM-aistをインストーラーでインストールした場合はCHOREONOID_OMNIORB_DIRオプションの設定は不要です。
OpenRTMプラグインのソースコードは以下から入手できます。
Choreonoidと同様、CMake実行後にVisual Studioでビルドします。
CMakeでは以下の項目を設定します。
設定項目 | 内容 | 設定例 |
Choreonoid_DIR | ChoreonoidのCMakeコンフィグファイルがインストールされたフォルダ | C:/work/choreonoid_install/share/choreonoid/cmake |
OpenRTM_DIR | OpenRTM-aistのCMakeコンフィグファイルがインストールされたフォルダ | C:/work/openrtm_install/2.0.0/cmake |
以下のコマンドを実行することでビルド、インストールができます。 生成したOpenRTMプラグインはChoreonoidのインストールフォルダにコピーされます。
git clone https://github.com/OpenRTM/choreonoid-openrtm cd choreonoid-openrtm mkdir build cd build cmake .. -DChoreonoid_DIR=%CHOREONOID_INSTALL_DIR%/share/choreonoid/cmake -DOpenRTM_DIR=%OPENRTM_INSTALL_DIR%/2.0.0/cmake cmake --build . --config Release cmake --build . --config Release --target install
※OpenRTM-aistをインストーラーでインストールした場合はOpenRTM_DIRオプションの設定は不要です。
OpenRTMプラグインのソースコードは以下から入手できます。
CMakeの設定項目はOpenRTMプラグインと同じです。
以下のコマンドを実行することでビルド、インストールができます。
git clone https://github.com/Nobu19800/OpenRTMPythonPlugin cd OpenRTMPythonPlugin mkdir build cd build cmake .. -DChoreonoid_DIR=%CHOREONOID_INSTALL_DIR%/share/choreonoid/cmake -DOpenRTM_DIR=%OPENRTM_INSTALL_DIR%/2.0.0/cmake cmake --build . --config Release cmake --build . --config Release --target install
※OpenRTM-aistをインストーラーでインストールした場合はOpenRTM_DIRオプションの設定は不要です。
Choreonoidをビルド、インストールすると、基本的には必要なファイルはインストール先にコピーされます。 ただし、Pythonプラグインをビルドする場合は、対応するバージョンのPythonがインストールされている必要があります。
このため、対応するバージョンのPythonがインストールされていない場合は、以下のページのように組み込み用Pythonを同梱する必要があります。
まずは、対応するバージョンのpython-3.x.y-embed-amd64をダウンロードしてください。
次に必要なライブラリをインストールします。 Choreonoidはnumpyが必要なためインストールします。
python -m pip install numpy
また、Choreonoid Pythonプラグインのサンプルプログラムを実行するためにPySDL2が必要なためインストールします。
python -m pip install pysdl2 pysdl2-dll
omniORB、OpenRTM-aistをインストールする必要があるため、以下のファイル、フォルダをpython-3.x.y-embed-amd64/Lib/site-packages以下のコピーしてください。
OpenRTM-aist+omniORBを以下の手順でビルド、インストールしてください。
export OPENRTM_INSTALL_PATH=~/work/openrtm_install git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist/ mkdir build cd build/ git clone cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$OPENRTM_INSTALL_PATH cmake --build . --config Release sudo cmake --build . --config Release --target install
Choreonoidを以下の手順でビルド、インストールしてください。
CMake、Boost、Qtのバージョンには注意してください。
OpenRTMプラグインの使用のためにはCORBAプラグインのビルドに、ヘッダーファイルなどの各種ファイルをインストールが必要です。 また、OpenRTM Pythonプラグインの使用のためにはPythonプラグインのビルドが必要です。
設定項目 | 内容 | 設定例 |
ENABLE_CORBA | CORBA通信機能の有効化、無効化 | ON |
BUILD_CORBA_PLUGIN | CORBAプラグインのビルドの有無 | ON |
INSTALL_SDK | ヘッダーファイルなどの各種ファイルをインストールするか | ON |
ENABLE_PYTHON | Pythonスクリプティング機能、およびPythonプラグインのビルドの有無 | ON |
CMAKE_INSTALL_PREFIX | Choreonoidのインストールフォルダ | ~/work/choreonoid_install |
export CHOREONOID_INSTALL_DIR=~/work/choreonoid_install git clone https://github.com/choreonoid/choreonoid cd choreonoid mkdir build cd build cmake .. -DENABLE_CORBA=ON -DBUILD_CORBA_PLUGIN=ON -DINSTALL_SDK=ON -DENABLE_PYTHON=ON -DCMAKE_INSTALL_PREFIX=$CHOREONOID_INSTALL_DIR cmake --build . --config Release cmake --build . --config Release --target install
OpenRTMプラグインのソースコードは以下から入手できます。
CMakeでは以下の項目を設定します。
設定項目 | 内容 | 設定例 |
Choreonoid_DIR | ChoreonoidのCMakeコンフィグファイルがインストールされたフォルダ | ~/work/choreonoid_install/share/choreonoid/cmake |
OpenRTM_DIR | OpenRTM-aistのCMakeコンフィグファイルがインストールされたフォルダ | ~/work/openrtm_install/lib/openrtm-2.0/cmake |
以下のコマンドを実行することでビルド、インストールができます。 生成したOpenRTMプラグインはChoreonoidのインストールフォルダにコピーされます。
git clone https://github.com/OpenRTM/choreonoid-openrtm cd choreonoid-openrtm mkdir build cd build cmake .. -DChoreonoid_DIR=$CHOREONOID_INSTALL_DIR/share/choreonoid/cmake -DOpenRTM_DIR=$OPENRTM_INSTALL_PATH/lib/openrtm-2.0/cmake cmake --build . --config Release cmake --build . --config Release --target install
OpenRTMプラグインのソースコードは以下から入手できます。
CMakeの設定項目はOpenRTMプラグインと同じです。
以下のコマンドを実行することでビルド、インストールができます。
git clone https://github.com/Nobu19800/OpenRTMPythonPlugin cd OpenRTMPythonPlugin mkdir build cd build cmake .. -DChoreonoid_DIR=$CHOREONOID_INSTALL_DIR/share/choreonoid/cmake -DOpenRTM_DIR=$OPENRTM_INSTALL_PATH/lib/openrtm-2.0/cmake cmake --build . --config Release cmake --build . --config Release --target install
使用方法については以下のページを参考にしてください。
Choreonoidはオープンソースのロボット用シミュレーションソフトウェアです。 拡張性が高く、物理エンジン、通信機能、スクリプティング機能、制御アルゴリズム等をC++プラグインとして追加できます。
このページでは、Choreonoidシミュレータ上の移動ロボットの入出力を行うRTCの作成手順を説明します。
講習会の実習の場合はUSBメモリ等で資料を配布しているため、USBメモリ内のchoreonoidフォルダ内のchoreonoid.batをダブルクリックして起動してください。
Choreonoid上で以下のアイテムを追加してシミュレーション環境を構築します。
World(ワールドアイテム) |-AISTSimulator(AISTシミュレータ) |-Floor(model/misc/floor.body) |-RaspberryPiMouse(model/RaspberryPiMouse/RaspberryPiMouse.body) |-RaspberryPiMouseIo(PyRTC) |-RobotController(RTC) |-RTSystem
Choreonoidで仮想世界を表現するワールドアイテムを追加します。 ボディモデル等の各アイテムはワールドアイテムと関連付けする必要があります。
「ファイル」->「新規」->「ワールド」をクリックしてWorldを追加してください。
名前は変更せずに生成します。
ワールドアイテムが追加されると、アイテムビューにWorldが表示されます。
Choreonoidは複数のプラグインから使用する物理エンジンを選択することができます。 Choreonoid本体でサポートしているプラグインとしては、AISTシミュレータ、ODE, Bullet, PhysXが使用できます。
今回はAISTシミュレータを追加するため、「ファイル」->「新規」->「AISTシミュレータ」をクリックしてください。
名前は変更せずに生成します。
AISTシミュレータアイテムが追加されると、アイテムビューにAISTSimulatorが表示されます。
地面を表現するボディアイテムを追加します。 「ファイル」->「読み込み」->「ボディ」をクリックしてください。
「ボディ読み込み」の画面でfloor.bodyを選択します。 左側のshareをクリックして、share/model/misc/floor.bodyのファイルを選択してください。
アイテムが追加されると、アイテムビューにFloorが表示されます。
Raspberry Piマウスを表現するボディアイテムを追加します。 先ほどと同じ手順で「ファイル」->「読み込み」->「ボディ」をクリックしてください。
「ボディ読み込み」の画面でRaspberryPiMouse.bodyを選択します。 左側のshareをクリックして、share/model/RaspberryPiMouse/RaspberryPiMouse.bodyのファイルを選択してください。
アイテムが追加されると、アイテムビューにRaspberryPiMouseが表示されます。
また、シーンビューにRaspberryPiマウスの3Dモデルが表示されます。
Choreonoid上でRTSystemEditorの一部機能を使用するためのRTSystemアイテムを追加します。 「ファイル」->「新規」->「RTSystem」をクリックしてください。名前の変更は不要です。
アイテムが追加されると、アイテムビューにRTSystemが表示されます。
この時点でChoreonoid上にネームサーバー、システムエディタは表示されていません。
まずネームサーバーを表示するには、「表示」->「ビューの表示」->「RTC List」をクリックします。
これでプロパティ、リンクプロパティの右にRTC Listタブが表示されます。
システムエディタを表示するには、「表示」->「ビューの表示」->「RTC Diagram」をクリックします。
これでシーンの右にRTC Diagramタブが表示されます。
以下のページで作成したRobotControllerコンポーネントをシミュレータで利用可能にします。
RTCを表現するRTCアイテムを追加してください。
「ファイル」->「新規」->「RTC」をクリックします。
名前をRobotControllerに変更します。
アイテムが追加されると、アイテムビューにRobotControllerが表示されます。
次にRobotControllerComp.exeとRobotControllerアイテムを関連付けます。 アイテムビューからRobotControllerを選択して、プロパティからRTC moduleを設定します。
「ファイルを選択」の画面でRobotControllerComp.exeを選択します。 初期の状態だと拡張子dllのファイルしか表示しないため、ファイルの種類を全てのファイル (*) に設定してからファイルを選択してください。
PythonのRTCをChoreonoid上で起動するため、PyRTCアイテムを追加します。
「ファイル」->「新規」->「PyRTC」をクリックします。
名前をRaspberryPiMouseIoに変更します。
アイテムが追加されると、アイテムビューにRaspberryPiMouseIoが表示されます。
ここからはRTC Builderで作業します。
以下の仕様のRTCを作成してください。
基本 | |
コンポーネント名 | RaspberryPiMouseIo |
アクティビティ | |
なし | |
データポート(OutPort) | |
なし | |
データポート(InPort) | |
ポート名 | velocity |
データ型 | RTC::TimedVelocity2D |
コンフィギュレーション | |
なし | |
言語・環境 | |
言語 | Python |
コード生成すると、RaspberryPiMouseIo.pyが作成されるのでこのファイルをVisual Studio CodeやIDLEなどで編集します。
RaspberryPiMouseIoクラスにsetBody、outputToSimulator、inputFromSimulatorのメンバ関数を追加します。
setBody関数はRTC側でChoreonoidのボディオブジェクトを取得する関数です。 取得したBodyオブジェクトからLinkオブジェクトを取得することで、対象のJointの入出力ができます。
outputToSimulator関数は、シミュレータ上のオブジェクトから取得したデータをOutPortから出力する処理を行う関数です。
inputFromSimulator関数は、InPortの入力データをシミュレータ上のオブジェクトに入力する処理を行う関数です。
各関数は、シミュレーション実行時に以下の図のような順序で呼ばれます。
RaspberryPiMouseIo.pyに以下のコードを追加してください。 Pythonなので、インデントには注意してください。「def ~」を「# def onRateChanged~」のインデントに合わせる必要があります。
# def onRateChanged(self, ec_id): # # return RTC.RTC_OK def setBody(self, body): self.ioBody = body self.wheelR = self.ioBody.link("RIGHT_WHEEL") self.wheelL = self.ioBody.link("LEFT_WHEEL") def outputToSimulator(self): pass def inputFromSimulator(self): if self._velocityIn.isNew(): data = self._velocityIn.read() vx = data.data.vx va = data.data.va wheel_distance = 0.0425 wheel_radius = 0.04 rms = (vx + va*wheel_distance)/wheel_radius lms = (vx - va*wheel_distance)/wheel_radius self.wheelR.dq = rms self.wheelL.dq = lms
Choreonoidでの作業に戻ります。 アイテムビューからRaspberryPiMouseIoを選択して、プロパティからRTC Moduleを設定します。
「ファイルを選択」の画面で先ほど編集したRaspberryPiMouseIo.pyを選択します。
※RaspberryPiMouseIo.pyを更新した場合は、再度この作業を行う事で再読み込みしてください。
アイテムビューで、全てのアイテムはワールドアイテムの子アイテムとして配置する必要があります。 また、RaspberryPiMouseIoはRaspberryPiMouseの子アイテムとして配置します。
World |- AISTSimulator |- Floor |- RaspberryPiMouse | |- RaspberryPiMouseIo |- RobotController |- RTSystem
位置関係が違う場合はドラッグアンドドロップして移動してください。
起動したRTCのポートを接続します。
この時点でRobotController0とRaspberryPiMouseIo0が起動していますが、RTC Listに表示が無い場合は「Update」ボタンを押してください。
RTC ListからRTCをRTC Diagramにドラッグアンドドロップして、以下のポートを接続してください。
InPort | OutPort | ||
RobotController0 | out | RaspberryPiMouseIo0 | velocity |
RTCアイテムにexeファイルを設定した場合はRTCを自動でアクティブ化しないため、RTC Diagram上でRobotController0を右クリックして「Activate」を選択してください。 ※RaspberryPiMouseIo0はシミュレーションを開始すると自動的にアクティブ状態になるため操作の必要はありません。
「初期位置からのシミュレーション開始」ボタンを押すとシミュレーションを開始します。
シーンタブに切り替えるとシミュレーションを3DCGで表示します。
Choreonoid OpenRTMプラグインにはコンフィギュレーションパラメータ編集機能がないため、RTSystemEditorで作業します。
ネームサービスビューでRobotControllerを選択して、コンフィギュレーションビューから「編集」ボタンを押して、コンフィギュレーションパラメータを変更してみてください。
Choreonoidで表示したRaspberry Piマウスが移動しているか確認すれば完了です。
ネームサービスビューにlocalhostと表示されていない場合については、以下のようにネームサービス接続ボタンを押して、localhostのネームサーバーに接続してください。
以下から OpenRTM-aist のソースコードを入手してください。
以下からビルド済みの omniORB を入手してください。
チェックアウトしたフォルダー(OpenRTM-aist)に移動して以下のコマンドを実行してください。
mkdir build cd build cmake -DORB_ROOT=C:/workspace/omniORB-4.2.3-win64-vc141 -G "Visual Studio 16 2019" -DCMAKE_INSTALL_PREFIX=C:/workspace/openrtminstall .. cmake --build . --config Release cmake --build . --config Release --target install
変数名 | 意味 | 設定できる値 |
CORBA | CORBA のライブラリー | omniORB |
以下から OpenRTM-aist のソースコードを入手してください。
以下の手順でTAOをビルドします。
チェックアウトしたフォルダー(OpenRTM-aist)に移動して以下のコマンドを実行してください。
mkdir build cd build cmake -DORB_ROOT=C:/workspace/ACE_wrappers -DCORBA=TAO -G "Visual Studio 16 2019" -DCMAKE_INSTALL_PREFIX=C:/workspace/openrtminstall .. set PATH=%PATH%;C:\workspace\ACE_wrappers\lib; cmake --build . --config Release cmake --build . --config Release --target install
omniORBのWindows 10 IoT用のビルド済みバイナリファイルは現在のところ配布していないため、自力でビルドする必要があります。 Cygwinのインストールが必要です。
omniORBのソースコードを入手してください。
omniORB-4.2.2.tar.bz2を適当な場所に展開してください。
最初にARM+Windows用の修正パッチを適用します。 以下から修正パッチを入手してください。
Cygwin上で以下のコマンドを実行してください。
patch -p1 -d omniORB-4.2.2 < omniORB-4.2.2-windows-iot.patch
omniORB-4.2.2.tar.bz2を展開したフォルダのmk/platforms/arm_win32_vs_14.mkを編集します。 使用するVisual Studioのバージョンが違う場合は合ったものを選択してください。 以下のようにPythonのディレクトリを指定します。
PYTHON = /cygdrive/c/Python27/python
次にconfig/config.mkを編集します。 以下のように対応したmkファイルを指定します。 Visual Studioのバージョンが違う場合は適宜対応してください。
platform = arm_win32_vs_14
クロスコンパイルを行うため、idlコンパイラなどの実行ファイルは開発環境で動作可能なものを用意します。
以下からx86用にビルドした omniORB のバイナリを入手してください。
zipファイルを展開したフォルダのbin/x86_win32の中身を、omniORB-4.2.2.tar.bz2を展開したフォルダのbin/x86_win32にコピーしてください。
omniORB-4.2.2.tar.bz2を展開したディレクトリに移動して、以下のコマンドを実行してください。
set PATH=C:\cygwin64\bin;%PATH%; call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_arm cd src make export
これでbin/ARM_win32に実行ファイルが、lib/ARM_win32にライブラリが生成されます。 vcvarsall.batについてはVisual Studioのバージョンにあったものを使用してください。 Visual Studio 2017の場合はC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.batとなります。
OpenRTM-aistのビルドは通常とほとんど同じです。 cmakeのオプションとしてVisual Studio 14 2015 ARMというようにARM用のコンパイラを指定してください。
mkdir build cd build cmake -DORB_ROOT=C:/workspace/omniORB-4.2.2 -G "Visual Studio 14 2015" -A ARM -DCMAKE_INSTALL_PREFIX=C:/workspace/openrtminstall .. cmake --build . --config Release cmake --build . --config Release --target install
Visual StudioにARM用コンパイラがインストールされていないとビルドできません。 ARM用コンパイラをインストールしていない場合は、Visual Studio Installerを起動してARM用Visual Studio C++コンパイラとライブラリ'をインストールしてください。
sudo apt install libomniorb4-dev omniidl omniorb-nameserver git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist/ mkdir build cd build/ cmake -DCMAKE_BUILD_TYPE=Release .. cmake --build . --config Release -- -j$(nproc) sudo cmake --build . --config Release --target install
変数名 | 意味 | 設定できる値 |
CORBA | CORBA のライブラリー | omniORB |
以下の手順でTAOをビルドします。
以下のコマンドでOpenRTM-aistをビルドしてください。
git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist/ mkdir build cd build cmake -DCORBA=TAO -DCMAKE_BUILD_TYPE=Release .. cmake --build . --config Release -- -j$(nproc) sudo cmake --build . --config Release --target install
事前にWind River Workbenchのホームディレクトリを指定する必要があります。 Wind River WorkbenchをインストールしたディレクトリをWIND_HOMEという変数に設定してください。
export WIND_HOME=/home/openrtm/WindRiver
OpenRTM-aistのビルドの前に、omniORBのビルドを行う必要があります。
omniORBのソースコードを入手してください。
omniORBのVxWorks対応パッチを入手してください。
以下のコマンドでビルドを実行します。
wget https://jaist.dl.sourceforge.net/project/omniorb/omniORB/omniORB-4.2.2/omniORB-4.2.2.tar.bz2 tar xf omniORB-4.2.2.tar.bz2 wget http://svn.openrtm.org/omniORB/trunk/vxworks/omniORB-4.2.2-vxworks.patch patch -p1 -d omniORB-4.2.2 < omniORB-4.2.2-vxworks.patch cd omniORB-4.2.2 mkdir build cd build ../configure make cd .. sed -i '1s/^/platform = ${VXWORKS_PLATFORM}\n/' config/config.mk cd src make export
ただし、VXWORKS_PLATFORMには動作環境に合ったものを入力するようにしてください。
VXWORKS_PLATFORM | CPU | VxWorksのバージョン | 実装方法 |
powerpc_vxWorks_kernel_6.6 | PowerPC | 6.6 | カーネルモジュール |
powerpc_vxWorks_RTP_6.6 | PowerPC | 6.6 | RTP |
powerpc_vxWorks_kernel_6.9 | PowerPC | 6.9 | カーネルモジュール |
powerpc_vxWorks_RTP_6.9 | PowerPC | 6.9 | RTP |
simlinux_vxWorks_kernel_6.6 | Linux上のシミュレータ | 6.6 | カーネルモジュール |
simpentium_vxWorks_RTP_6.6 | Linux上のシミュレータ | 6.6 | RTP |
simlinux_vxWorks_kernel_6.9 | Linux上のシミュレータ | 6.9 | カーネルモジュール |
simpentium_vxWorks_RTP_6.9 | Linux上のシミュレータ | 6.9 | RTP |
以下のコマンドを入力してください。
git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist/ mkdir build cd build/ cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DVX_VERSION=${VX_VERSION} -DORB_ROOT=${ORB_ROOT} -DOMNI_VERSION=42 -DCORBA=omniORB -DVX_CPU_FAMILY=${ARCH} .. make
ただし、TOOLCHAIN_FILE、VX_VERSION 、ORB_ROOT、ARCHには以下の設定をしてください。
TOOLCHAIN_FILE | VxWorks 6.6(カーネルモジュール、PowerPC)の場合は../Toolchain-vxworks6.6-Linux.cmake、それ以外の場合は../Toolchain-vxworks6.cmake |
VX_VERSION | vxworks-6.6かvxworks-6.9 |
ORB_ROOT | omniORBのディレクトリ(例:/home/openrtm/omniORB-4.2.2) |
VX_CPU_FAMILY | ppc(PowerPC)、simlinux(カーネルモジュール、シミュレータ)、simpentium(RTP、シミュレータ) |
RTPの場合はcmakeコマンドに-DRTP=ONを追加する必要があります。
cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DVX_VERSION=${VX_VERSION} -DORB_ROOT=${ORB_ROOT} -DOMNI_VERSION=42 -DCORBA=omniORB -DVX_CPU_FAMILY=${ARCH} -DRTP=ON .. cmake --build . --config Release
※現在のところ対応環境はVxWorks 6.6、PowerPCのみです。
以下のコマンドを入力してください。
git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist/ mkdir build cd build/ cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DORB_ROOT=${ORB_ROOT} -DCORBA=ORBexpress .. make
TOOLCHAIN_FILE、ORB_ROOTには以下の設定をしてください。
TOOLCHAIN_FILE | カーネルモジュールの場合は../Toolchain-vxworks6.6-Linux.cmake、RTPの場合は../Toolchain-vxworks6.cmake |
ORB_ROOT | ORBexpressのディレクトリ(例:/home/openrtm/OIS/ORBexpress/RT_2.8.4_PATCH_KC1) |
VMWare上のQNX 6.5でビルドします。 以下のページからISOイメージを入手してください。
まずはパッケージ管理システムpkgsrcをインストールします。 以下のコマンドでソースコードを入手してください。
svn checkout --username ユーザ名 --password パスワード http://community.qnx.com/svn/repos/pkgsrc/HEAD_650/pkgsrc
ユーザー名、パスワードはQNXのアカウントのメールアドレス、パスワードを設定してください。
次に以下のコマンドでインストールします。 コマンドはsuで実行してください。
(cd pkgsrc/bootstrap && ./bootstrap) (cd pkgsrc/misc/figlet && ../../bootstrap/work/bin/bmake install)
環境変数PKG_PATHを設定しておいてください。
export PKG_PATH=ftp://ftp.netbsd.org/pub/pkgsrc/packages/QNX/i386/6.5.0_head_20110826/All/
まずはlibuuidのビルドをします。 libuuid-1.0.3.tar.gzをダウンロードしてQNXに転送してください。
ファイルを展開してください。
tar xf libuuid-1.0.3.tar.gz
libuuidのビルドにはsys/syscall.h、bits/syscall.h、asm/unistd.h、asm/unistd_32.h(もしくはasm/unistd_64.h)が必要になります。 ファイルを入手してlibuuid-1.0.3の下にコピーしてください。
libuuid-1.0.3 |-sys | |-syscall.h |-bits | |-syscall.h |-asm | |-unistd.h | |-unistd_32.h(もしくはunistd_64.h) |-(省略)
以下のコマンドでビルド、インストールしてください。
cd libuuid-1.0.3 ./configure make make install cd ..
まずはomniORB-4.2.3.tar.bz2を入手してQNXに転送してください。
ファイルを展開してください。
tar xf omniORB-4.2.3.tar.bz2
以下のファイルについて変更が必要です。
まずconfigureについては2箇所の変更が必要です。 以下の*-*-nto-qnx)の行を追加してください。
case "$host" in *-*-linux-*) plat_name="Linux"; plat_def="__linux__"; os_v="2";; *-*-nto-qnx) plat_name="Linux"; plat_def="__linux__"; os_v="2";;
以下のx86-pc-*)の部分を追加してください。
case "$host" in i?86-*) proc_name="x86Processor"; proc_def="__x86__";; x86-pc-*) proc_name="x86Processor"; proc_def="__x86__";;
mk/beforeauto.mk.inは以下の部分を変更してください。
#OMNITHREAD_LIB += -lpthread #削除 OMNITHREAD_LIB += -lsocket #追加
以下のコマンドでビルドします。
./configure make make install cd ..
OpenRTM-aistのビルドにはcmake、pkg-config、Python 2.7が必要です。
/usr/pkg/sbin/pkg_add -v pkg-config-0.25nb1 /usr/pkg/sbin/pkg_add -v cmake-2.8.5 /usr/pkg/sbin/pkg_add -v python27-2.7.2
環境変数PKG_CONFIG_PATHを設定してください。
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
OpenRTM-aistのソースコードを入手してQNXに転送してください。
OpenRTM-aistのディレクトリに移動して以下のコマンドを実行します。
mkdir build cd build/ ln -s /usr/pkg/bin/python2.7 ./python export PATH=$PWD:$PATH cmake -DCORBA=omniORB .. cmake --build . --config Release -- -j$(nproc) cmake --build . --target install
Ubuntu上にQNX Software Development Platform 7.0をインストールしてビルドします。 まずはQNX Software Centerをインストールしてください。
sudo apt-get install libgtk2.0-0:i386 chmod a+x qnx-setup-201808201144-lin.run ./qnx-setup-201808201144-lin.run
QNX Software Centerを起動してAdd InstallationからQNX Software Development Platformをインストールしてください。
/home/openrtm/qnx/qnxsoftwarecenter/qnxsoftwarecenter
まずはlibuuidのビルドをします。
wget https://jaist.dl.sourceforge.net/project/libuuid/libuuid-1.0.3.tar.gz tar xf libuuid-1.0.3.tar.gz
libuuidのビルドにはsys/syscall.h、bits/syscall.h、asm/unistd.h、asm/unistd_32.h(もしくはasm/unistd_64.h)が必要になります。 ファイルを入手してlibuuid-1.0.3の下にコピーしてください。
cd libuuid-1.0.3 mkdir sys cp /usr/include/x86_64-linux-gnu/sys/syscall.h sys mkdir asm cp /usr/include/x86_64-linux-gnu/asm/unistd.h asm cp /usr/include/x86_64-linux-gnu/asm/unistd_64.h asm mkdir bits cp /usr/include/x86_64-linux-gnu/bits/syscall.h bits
QNXクロスコンパイル環境設定のためにスクリプトを実行します。
source ~/qnx700/qnxsdp-env.sh
以下のコマンドでビルドします。 qnx700のパスは適宜変更してください。
./configure --prefix=/home/openrtm/qnx700/target/qnx7/usr/ CC="qcc -V5.4.0,gcc_ntox86_64_gpp" CXX="q++ -V5.4.0,gcc_ntox86_64_gpp" AR=ntox86_64-ar RANLIB=ntox86_64-ranlib --host=x86_64-unknown-linux-gnu make make install cd ..
まずはomniORBのソースコードを入手してください。
wget https://jaist.dl.sourceforge.net/project/omniorb/omniORB/omniORB-4.2.3/omniORB-4.2.3.tar.bz2 tar xf omniORB-4.2.3.tar.bz2 cd omniORB-4.2.3
Ubuntu上でomniidlをビルドする必要があります。 qnxsdp-env.shを実行していない環境でomniORBのビルドを行いインストールしてください。
./configure make make install
QNXでビルドするために
#OMNITHREAD_LIB += -lpthread OMNITHREAD_LIB += -lsocket
以下のコマンドでビルドしてください。
make clean ./configure --prefix=/home/openrtm/qnx700/target/qnx7/usr/ CC="qcc -V5.4.0,gcc_ntox86_64_gpp" CXX="q++ -V5.4.0,gcc_ntox86_64_gpp" AR=ntox86_64-ar RANLIB=ntox86_64-ranlib --host=x86_64-unknown-linux-gnu make make install
omniORB、uuidをpkg-configで検出するために環境変数PKG_CONFIG_PATHを設定してください。
export PKG_CONFIG_PATH=/home/openrtm/qnx700/target/qnx7/usr/lib/pkgconfig
以下のコマンドでビルドします。
git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist/ mkdir build cd build cmake -DCORBA=omniORB -DCMAKE_TOOLCHAIN_FILE=../Toolchain-QNX7.cmake -DCMAKE_INSTALL_PREFIX=/home/openrtm/qnx700/target/qnx7/usr/ .. cmake --build . --config Release -- -j$(nproc)
VMWare用のイメージを入手するためには、QNX Software Centerでファイルをダウンロードします。
QNX Software Development Platform->Reference Images->QNX SDP 7.0 x86-64 virtual machine for VMWareをインストールしてください。
インストールしたQNX_SDP.vmxをVMwareで開くと仮想マシンが起動します。
名前 | 説明 | デフォルト |
CORBA | 利用するCORBAのライブラリの種類(omniORB、TAO、ORBexpress) | omniORB |
ORB_ROOT | CORBAのライブラリをインストールした場所 | 設定しない場合、Ubuntu、omniORBの場合はFindPkgConfigで検索。それ以外はエラー |
SSL_ENABLE | SSLによるセキュアな通信を有効にするためのプラグインを生成するか ON:生成する OFF:生成しない |
OFF |
HTTP_ENABLE | HTTP通信を有効にするためのプラグインを生成するか ON:生成する OFF:生成しない |
OFF |
OPENSSL_ROOT | OpenSSLの各種ファイルを配置したディレクトリ。Windowsの場合は必須 | |
OBSERVER_ENABLE | コンポーネントオブザーバーを有効にするかどうか ON:有効 OFF:無効 |
OFF |
DOCUMENTS_ENABLE | Doxygenでドキュメントを生成するかどうか ON:生成する OFF:生成しない |
OFF |
ROS_ENABLE | ROS通信用シリアライザ、インターフェースを生成するか ON:生成する OFF:生成しない |
OFF |
FASTRTPS_ENABLE | DDS(Fast-RTPS)通信用インターフェースを生成するか ON:生成する OFF:生成しない |
OFF |
ROS2_ENABLE | ROS2通信用シリアライザを生成するか ON:生成する OFF:生成しない |
OFF |
EXAMPLES_ENABLE | サンプルコンポーネントを生成するかどうか ON:生成する OFF:生成しない |
ON |
UTILS_ENABLE | サンプルコンポーネントを生成するかどうか ON:生成する OFF:生成しない |
ON |
EXTLIB_ENABLE | サンプルコンポーネントを生成するかどうか ON:生成する OFF:生成しない |
ON |
FLUENTBIT_ENABLE | Fluent Bitロガープラグインを生成するかどうか ON:生成する OFF:生成しない |
OFF |
FLUENTBIT_ROOT | Fluent Bitのソースコードのディレクトリ | |
OPENSPLICE_ENABLE | DDS(OpenSplice)通信用インターフェースを生成するか ON:生成する OFF:生成しない |
OFF |
OPENSPLICE_DIR | OpenSpliceをインストールしたディレクトリ | |
RAPIDXML_DIR | rapidxmlを展開したディレクトリ |
名前 | 説明 | デフォルト |
OMNI_VERSION | omniORBのメジャーバージョン。omniORBを手動でビルド、任意の場所にインストールした場合は必須 | 設定しなかった場合、LinuxでomniORBがpkg-configでインストールした場合は自動的に設定する。それ以外はエラー |
OMNI_MINOR | omniORBのマイナーバージョン。omniORBを手動でビルド、任意の場所にインストールした場合は必須 | 同上 |
OMNITHREAD_VERSION | omniThreadのバージョン。omniORBを手動でビルド、任意の場所にインストールした場合は必須 | 同上 |
依存はlibcoil、libRTCのみ。
EXTLIB_ENABLEがONになっている必要がある。
FASTRTPS_ENABLEがONになっている必要があるため、FastRTPSTransportのビルドは必須。
ビルドにはPython、Cygwinのインストールが必要です。
sslTp、httpTp機能を使う場合はOpenSSLのビルドが必要です。
Strawberry Perlをインストールして以下のコマンドを実行する。
set OPENSSL_INSTALL_DIR=C:/work/openssl_install call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 perl Configure VC-WIN64A --prefix=%OPENSSL_INSTALL_DIR% no-asm shared nmake install
omniORBのソースコードを入手します。
mk/platforms/x86_win32_vs_16.mkでPython、OpenSSLのパスを設定します。OPEN_SSL_ROOTを設定しなかった場合でもビルドは可能ですが、sslTp、httpTp機能は使えません。
PYTHON = /cygdrive/c/Python310/python
OPEN_SSL_ROOT = /cygdrive/c/work/openssl_install
config/config.mkでビルドする環境を指定してください。
platform = x86_win32_vs_16
omniORBを展開したフォルダに移動して以下のコマンドを実行してください。
set PATH=C:\cygwin64\bin;%PATH%; call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 cd src make export
次にomniORBpyのビルドを実行します。 まずomniORBpyのソースコードを入手してください。
omniORBpyをomniORBのsrc/lib以下にコピーします。
omniORB-4.x.y |--src | |--lib | |--omniORBpy |--mk | |--platforms | |--x86_win32_vs_16 |--config |--config.mk
omniORBpyフォルダに移動してmakeコマンドを実行します。
cd lib\omniORBpy make export
omniORB、omniORBpyの動作確認をするためには環境変数PATH、PYTHONPATHの設定が必要です。
set omniORB_DIR=C:/workspace/omniORB-4.3.0 set PATH=%omniORB_DIR%\bin\x86_win32;%PATH% set PYTHONPATH=%omniORB_DIR%\lib\x86_win32;%omniORB_DIR%\lib\python;%PYTHONPATH%
sslTp、httpTp機能を使う場合はOpenSSLのインストールが必要です。
sudo apt install libssl-dev
次にomniORBのソースコードを入手してビルドします。
export PYTHON=/usr/bin/python3 export OMNIORB_INSTALL_DIR=~/work/omniorb_install wget https://jaist.dl.sourceforge.net/project/omniorb/omniORB/omniORB-4.3.0/omniORB-4.3.0.tar.bz2 tar xf omniORB-4.3.0.tar.bz2 cd omniORB-4.3.0 ./configure --prefix=${OMNIORB_INSTALL_DIR} --with-openssl make make install
omniORBpyのビルドを実行します。
export PYTHON=/usr/bin/python3 wget https://jaist.dl.sourceforge.net/project/omniorb/omniORBpy/omniORBpy-4.3.0/omniORBpy-4.3.0.tar.bz2 tar xf omniORBpy-4.3.0.tar.bz2 cd omniORBpy-4.3.0 ./configure --with-omniorb=${OMNIORB_INSTALL_DIR} --prefix=${OMNIORB_INSTALL_DIR} --with-openssl make make install
omniORB、omniORBpyの動作確認をするためには環境変数PATH、LD_LIBRARY_PATH、PYTHONPATHの設定が必要です。
export PATH=${OMNIORB_INSTALL_DIR}/bin:$PATH export LD_LIBRARY_PATH=${OMNIORB_INSTALL_DIR}/lib:${LD_LIBRARY_PATH} export PYTHONPATH=${OMNIORB_INSTALL_DIR}/lib/python3.6/site-packages:$PYTHONPATH
また、pkg-configでomniORBを検出するには以下のように環境変数PKG_CONFIGを設定する。
export PKG_CONFIG_PATH=${OMNIORB_INSTALL_DIR}/lib/pkgconfig:$PKG_CONFIG_PATH
以下から ACE+TAO.zip をダウンロードしてください。
Visual Studio で ACE と TAO のビルドをします。
ACE+TAO.zip を展開したフォルダーの ace/config-win32.h を ace/config.h に変更してください。
ACE_vs2019.sln (もしくは ACE_vs2017.sln)を Visual Studio で開いてビルドしてください。 64bitの場合はソリューションプラットフォームがWin32となっている部分をx64に変更してください。
次に以下の環境変数を設定した状態でTAO_vs2019.sln (もしくは TAO_vs2017.sln)を Visual Studio で開いてビルドしてください。
環境変数 | 内容 | 設定例 |
ACE_ROOT | ACE_wrappersを展開したフォルダのパス | C:/work/ACE_wrappers |
cd TAO set ACE_ROOT=C:/work/ACE_wrappers TAO_vs2019.sln
ACE+TAO.tar.gzを入手して以下のコマンドでビルドします。
export ACE_INSTALL_DIR=~/work/ace_install sudo apt-get install gperf export ACE_ROOT=${PWD}/ACE_wrappers/build/linux export TAO_ROOT=${ACE_ROOT}/TAO export LD_LIBRARY_PATH=$ACE_ROOT/ace:$ACE_ROOT/lib export INSTALL_PREFIX=$ACE_INSTALL_DIR wget https://github.com/DOCGroup/ACE_TAO/releases/download/ACE%2BTAO-7_0_6/ACE+TAO-7.0.6.tar.gz tar xf ACE+TAO-7.0.6.tar.gz cd ACE_wrappers mkdir -p build/linux ./bin/create_ace_build build/linux echo '#include "ace/config-linux.h"' > build/linux/ace/config.h echo 'include $(ACE_ROOT)/include/makeinclude/platform_linux.GNU' > build/linux/include/makeinclude/platform_macros.GNU cd build/linux make make install cd TAO make make install
SSLIOPを有効にする場合は、以下のようにsslオプションを有効にしてSSLIOPをビルドする必要があります。
cd build/linux make ssl=1 make install ssl=1 cd TAO make SSLIOP ssl=1 make install ssl=1
また、pkg-configでACE+TAOを検出するには以下のように環境変数PKG_CONFIGを設定する。
export PKG_CONFIG_PATH=${ACE_INSTALL_DIR}/lib/pkgconfig:$PKG_CONFIG_PATH
ネームサーバーをSSLIOP通信可能な状態で起動するためには以下のコマンドを実行する。
${ACE_INSTALL_DIR}bin/tao_cosnaming -ORBSvcConf server.conf -ORBEndpoint iiop://localhost:/ssl_port=2809
エンドポイントをssliop://localhost:2809のように設定するとcorbaloc形式でのアクセスが上手くいかないため、上記のようにiiop://localhost:/ssl_port=2809と指定する。
server.confは例えば以下のようなファイルを用意する。
dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem -SSLCAfile PEM:cacert.pem" static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory"
まず、以下の手順でomniORBをビルドしてください。
次にOpenRTM-aistをビルドします。
set OpenRTM_INSTALL_DIR=C:/work/openrtm_install git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=%OpenRTM_INSTALL_DIR% -DORB_ROOT=%omniORB_DIR% cmake --build . --config Release cmake --build . --config Release --target install
まずは環境変数PATHとPYTHONPATHを設定します。
set OpenRTMPython_INSTALL_DIR=C:/work/python_install git clone https://github.com/OpenRTM/OpenRTM-aist-Python cd OpenRTM-aist-Python python setup.py build python setup.py install --prefix %OpenRTMPython_INSTALL_DIR%
環境変数PATHとPYTHONPATHを設定します。
git clone https://github.com/OpenRTM/rtctree cd rtctree python setup.py build python setup.py install_lib --install-dir %OpenRTMPython_INSTALL_DIR%\Lib\site-packages
git clone https://github.com/OpenRTM/rtsprofile cd rtsprofile python setup.py build python setup.py install_lib --install-dir %OpenRTMPython_INSTALL_DIR%\Lib\site-packages
git clone https://github.com/OpenRTM/rtshell cd rtshell python setup.py build python setup.py install --prefix %OpenRTMPython_INSTALL_DIR%
インストールが完了したら環境変数の設定を行ってください。
まず、以下の手順でTAOをビルドしてください。
次にOpenRTM-aistをビルドします。
set OpenRTM_INSTALL_DIR=C:/work/openrtm_install set PATH=%PATH%;%ACE_ROOT%\lib; git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=%OpenRTM_INSTALL_DIR% -DORB_ROOT=%ACE_ROOT% -DCORBA=TAO cmake --build . --config Release cmake --build . --config Release --target install
インストールが完了したら環境変数の設定を行ってください。
OpenRTM-aist-Python、rtshell、rtctree、rtsprofileはTAOには対応していません。
OpenRTM-aist C++のRTC等を実行するためには環境変数%PATH%を設定する必要があります。
set PATH=%OpenRTM_INSTALL_DIR%\2.0.0\bin\vc16;%OpenRTM_INSTALL_DIR%\2.0.0\omniORB\4.3.0_vc16\bin\x86_win32;%PATH%
OpenRTM-aist Python、rtctree、rtsprofileを使うためには環境変数PYTHONPATHを設定する必要があります。
set PYTHONPATH=%OpenRTMPython_INSTALL_DIR%\Lib\site-packages;%OpenRTMPython_INSTALL_DIR%\Lib\site-packages\OpenRTM_aist;%OpenRTMPython_INSTALL_DIR%\Lib\site-packages\OpenRTM_aist\RTM_IDL;%PYTHONPATH%
rtshellを使うためには環境変数PATHの設定が必要です。
set PATH=%OpenRTMPython_INSTALL_DIR%\Scripts;%PATH%
外部のRTCをビルドするためには、CMake実行時にOpenRTMConfig.cmakeをインストールしたパスを指定する必要があります。
cmake .. -DOpenRTM_DIR=%OpenRTM_INSTALL_DIR%/2.0.0/cmake
OpenRTM-aist C++をインストールすると、環境変数を設定するバッチファイルがインストールされます。
%OpenRTM_INSTALL_DIR%\2.0.0\ext\environment-setup.omniorb.vc16.bat
このバッチファイルを実行することで以下の環境変数が設定されます。
変数名 | 設定値 | 内容 |
OMNI_ROOT | %RTM_ROOT%/omniORB/4.3.0_%RTM_VC_VERSION%/ | omniORBをインストールしたフォルダ |
OpenRTM_DIR | %RTM_ROOT%/cmake | OpenRTM-aistのCMake設定ファイルをインストールしたフォルダ |
RTM_BASE | %OpenRTM_INSTALL_DIR% | OpenRTM-aistをインストールしたフォルダ |
RTM_IDL_DIR | %RTM_ROOT%/rtm/idl | OpenRTM-aistのIDLファイルをインストールしたフォルダ |
RTM_ROOT | %OpenRTM_INSTALL_DIR%/2.0.0 | OpenRTM-aistの2.0.0をインストールしたフォルダ |
RTM_VC_VERSION | vc** | ビルドしたVisual Studioのバージョン |
PATH | %RTM_ROOT%/bin/%RTM_VC_VERSION%;%OMNI_ROOT%/bin/x86_win32;%PATH% | PATHにOpenRTM-aist、omniORBの実行ファイルのパスを追加 |
OpenRTM-aist Python、rtshellの環境変数は設定されません。 Pythonのホームフォルダ(C:\Python37等)にインストールした場合は環境変数の設定は不要ですが、それ以外は手動で設定する必要があります。
まず、以下の手順でomniORBをビルドしてください。
以下の手順で環境変数PKG_CONFIGを設定します。
次にOpenRTM-aistをビルドします。
export OPENRTM_INSTALL_DIR=$OMNIORB_INSTALL_DIR export PATH=$OMNIORB_INSTALL_DIR/bin:$PATH git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=$OPENRTM_INSTALL_DIR cmake --build . --config Release -- -j$(nproc) cmake --build . --config Release --target install
まずは環境変数PATHとLD_LIBRARY_PATH、PYTHONPATHを設定します。
export OPENRTMPYTHON_INSTALL_DIR=$OMNIORB_INSTALL_DIR git clone https://github.com/OpenRTM/OpenRTM-aist-Python cd OpenRTM-aist-Python python3 setup.py build python3 setup.py install --prefix $OPENRTMPYTHON_INSTALL_DIR
環境変数PATHとLD_LIBRARY_PATH、PYTHONPATHを設定します。
git clone https://github.com/OpenRTM/rtctree cd rtctree python3 setup.py build python3 setup.py install_lib --install-dir $OPENRTMPYTHON_INSTALL_DIR/lib/python3.6/site-packages
git clone https://github.com/OpenRTM/rtsprofile cd rtsprofile python3 setup.py build python3 setup.py install_lib --install-dir $OPENRTMPYTHON_INSTALL_DIR/lib/python3.6/site-packages
git clone https://github.com/OpenRTM/rtshell cd rtshell python3 setup.py build python3 setup.py install --prefix $OPENRTMPYTHON_INSTALL_DIR
インストールが完了したら環境変数の設定を行ってください。
まず、以下の手順でTAOをビルドしてください。
以下の手順で環境変数PKG_CONFIGを設定します。
次にOpenRTM-aistをビルドします。
export OPENRTM_INSTALL_DIR=$ACE_INSTALL_DIR export LD_LIBRARY_PATH=ACE_INSTALL_DIR/lib:$LD_LIBRARY_PATH git clone https://github.com/OpenRTM/OpenRTM-aist cd OpenRTM-aist mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=$OPENRTM_INSTALL_DIR -DCORBA=TAO cmake --build . --config Release -- -j$(nproc) cmake --build . --config Release --target install
インストールが完了したら環境変数の設定を行ってください。
OpenRTM-aist-Python、rtshell、rtctree、rtsprofileはTAOには対応していません。
OpenRTM-aist C++のRTC等を実行するためには環境変数PATH、LD_LIBRARY_PATHを設定する必要があります。
export PATH=$OPENRTM_INSTALL_DIR/bin:$PATH export LD_LIBRARY_PATH=$OPENRTM_INSTALL_DIR/lib:$LD_LIBRARY_PATH
OpenRTM-aist Python、rtctree、rtsprofileを使うためには環境変数PYTHONPATHを設定する必要があります。
export PYTHONPATH=$OPENRTM_INSTALL_DIR/lib/python3.6/site-packages:$OPENRTM_INSTALL_DIR/lib/python3.6/site-packages/OpenRTM_aist:$OPENRTM_INSTALL_DIR/lib/python3.6/site-packages/OpenRTM_aist/RTM_IDL:$PYTHONPATH
rtshellを使うためには環境変数PATHの設定が必要です。
export PATH=$OPENRTMPYTHON_INSTALL_DIR/bin:$PATH
omniORBやOpenRTM-aist等をインストールしたパスが同じ場合は以下のコマンドだけ実行します。
export PATH=$OPENRTM_INSTALL_DIR/bin:$PATH export LD_LIBRARY_PATH=$OPENRTM_INSTALL_DIR/lib:$LD_LIBRARY_PATH export PYTHONPATH=$OPENRTM_INSTALL_DIR/lib/python3.6/site-packages:$OPENRTM_INSTALL_DIR/lib/python3.6/site-packages/OpenRTM_aist:$OPENRTM_INSTALL_DIR/lib/python3.6/site-packages/OpenRTM_aist/RTM_IDL:$PYTHONPATH
OpenRTM-aist C++をインストールすると、環境変数を設定するバッチファイルがインストールされます。
source ${OpenRTM_INSTALL_DIR}/etc/environment-setup.sh
このバッチファイルを実行することで以下の環境変数が設定されます。
変数名 | 設定値 | 内容 | |
OpenRTM_DIR | ${OpenRTM_INSTALL_DIR}/lib/openrtm-2.0/cmake | OpenRTM-aistのCMake設定ファイルをインストールしたフォルダ | |
RTM_IDL_DIR | ${OpenRTM_INSTALL_DIR}/include/openrtm-2.0/rtm/idl | OpenRTM-aistのIDLファイルをインストールしたフォルダ | |
PATH | ${OpenRTM_INSTALL_DIR}/bin:$PATH | PATHにOpenRTM-aist、omniORBの実行ファイルのパスを追加 | ] |
LD_LIBRARY_PATH | ${OpenRTM_INSTALL_DIR}/lib:$LD_LIBRARY_PATH | PATHにOpenRTM-aist、omniORBの実行ファイルのパスを追加 |
OpenRTM-aist Python、rtshellの環境変数は設定されません。 Pythonのホームフォルダ(C:\Python37等)にインストールした場合は環境変数の設定は不要ですが、それ以外は手動で設定する必要があります。
外部のRTCをビルドするためには、CMake実行時にOpenRTMConfig.cmakeをインストールしたパスを指定する必要があります。
cmake .. -DOpenRTM_DIR=${OPENRTM_INSTALL_DIR}/lib/openrtm-2.0/cmake
このページではOpenRTM-aistで通信ミドルウェアにTAOを使用した場合に各種通信プロトコルを使用するための設定ファイルの作成方法を説明します。 TAOではIIOP、DIOP、UIOP、HTIOP、SHMIOP、SSLIOP、SCIOP、MIOP、COIOP、ZIOP通信が使用可能です。 ただし、IIOP、SSLIOP、ZIOP通信以外は独自規格のプロトコルのため、他のCORBA実装との互換性はありません。
DIOP(Datagram Inter-ORB Protocol)はGIOPをUDP/IP上の実装であり、IIOP(TCP/IP)と比較すると軽量ですが到達保障がない通信プロトコルです。 IIOP通信との大きな違いとしてCORBAサービスの呼び出しが一方通行であり、戻り値を取ることができません。 例えば、外部のツールからRTCのコンポーネントプロファイルを取得する場合には、DIOP通信では戻り値(コンポーネントプロファイル)を取得できないため使用できません。
OpenRTM-aistでDIOP通信を使用するために、データポートのデータ転送用に以下のoneway属性のメソッドを定義しています。
module OpenRTM { interface InPortCdrUDP { oneway void put(in CdrData data); }; };
実際に使用する場合は、以下の図のようにデータポートのデータ送信にDIOP通信を用いて、それ以外はIIOP等の別の通信で接続する必要があります。
以下にrtc.confの設定例を記載します。 IIOPとDIOPのエンドポイントを設定します。
corba.args: -ORBEndpoint iiop://: -ORBEndpoint diop://: -ORBSvcConf svc.conf
svc.confはTAOの設定ファイルです。 svc.confという名前のファイルが実行パスに存在すれば自動的に読み込みますが、ORBSvcConfオプションで明示的に指定もできます。
以下にsvc.confでは以下のようにORBProtocolFactoryの設定を行います。
static Advanced_Resource_Factory "-ORBProtocolFactory DIOP_Factory -ORBProtocolFactory IIOP_Factory -ORBReactorType select_st"
OpenRTM-aistでインストールされるrtc.diop.conf、svc.confを使用することもできます。
%RTM_ROOT%Components\C++\Examples\%RTM_VC_VERSION%\ConsoleInComp.exe -f ext\tao_diop\rtc.diop.conf %RTM_ROOT%Components\C++\Examples\%RTM_VC_VERSION%\ConsoleOutComp.exe -f ext\tao_diop\rtc.diop.conf
ポート接続時にInterface Typeにcorba_cdr_udpを指定して接続することでDIOP通信によりデータの転送を行います。
RT System EditorではConnector Profileで設定します。
rtc.confではinterface_typeをcorba_cdr_udpに設定して事前接続設定をします。
manager.components.preconnect: ConsoleIn0.out?port=rtcname://localhost:2809/*/ConsoleOut0.in&interface_type=corba_cdr_udp
HTIOP(HTTP Tunneling Inter-ORB Protocol)はGIOPメッセージをHTTPパケットで送信する通信プロトコルです。 HTIOP通信の利点としては、ファイアーウォールやHTTPプロキシサーバを経由した通信が容易になる事や、リバースプロキシやロードバランサー等の既存の仕組みを流用しやすいという事が挙げられます。
まずはネームサーバーを起動しますが、ネームサーバーにもHTIOPのエンドポイントを設定する必要があります。 以下の内容の設定ファイルsvc.names.htiop.confを作成してください。
dynamic HTIOP_Factory Service_Object * TAO_HTIOP:_make_TAO_HTIOP_Protocol_Factory () "-config ./HT_Config.conf" static Resource_Factory "-ORBProtocolFactory HTIOP_Factory"
TAO付属のネームサーバーtao_cosnamingを起動します。 WindowsでOpenRTM-aistをビルドした場合、${RTM_ROOT}/ACE/${RTM_VC_VERSION}/bin/tao_cosnaming.exeにコピーしています。Ubuntuの場合はTAOをインストールした時に${OPENRTM_INSTALL_DIR}/binに入っているものを使用してください。
以下のように作成したsvc.names.htiop.confを指定してtao_cosnamingを起動します。
ACE\vc16\bin\tao_cosnaming.exe -ORBEndpoint htiop://127.0.0.1:2809 -ORBSvcConf ext/svc.names.htiop.conf
CosoleIn、ConsoleOutコンポーネントを以下の内容のrtc.confで起動します。
corba.args: -ORBEndpoint htiop:// -ORBSvcConf ext/tao_htiop/svc.htiop.conf corba.nameservers: corbaloc:htiop:localhost:2809 corba.master_manager: htiop://127.0.0.1:2810 manager.components.preactivation: ConsoleIn0, rtcname.htiop://localhost:2809/*/ConsoleOut0 manager.components.preconnect: ConsoleIn0.out?port=rtcname.htiop://localhost:2809/*/ConsoleOut0.in
corba.argsオプションはTAOのORB_init関数への引数を指定します。 HTIOPのエンドポイントとTAOの設定ファイル(ext/svc.htiop.conf)を設定しています。
設定ファイルsvc.htiop.confは以下の内容で作成します。
dynamic HTIOP_Factory Service_Object * TAO_HTIOP:_make_TAO_HTIOP_Protocol_Factory () "-config ext/tao_htiop/HT_Config.conf" static Advanced_Resource_Factory "-ORBProtocolFactory HTIOP_Factory"
また、接続するネームサーバーの設定を行います。 ネームサーバーはHTIOPのエンドポイント(htiop:localhost:2809)を指定します。
HTIOP通信を使用する場合、RT System EditorやrtshellではRTCを操作できません。 現在のところ、独自にプログラムを作成するか、マネージャ起動時の事前接続(preconnect)、事前アクティブ化(preactivation)の設定を行う必要があります。
HT_Config.confでプロキシサーバーの設定を行うことができます。
[htbp] proxy_port=3128 proxy_host=localhost
以下にHTIOP通信時のHTTPパケットの内容の一例を掲載します。 GETメソッド実行後にPOSTメソッドを実行します。POSTメソッドのボディにGIOPメッセージを格納して送信します。
GET http://127.0.0.1:2809//1/request1647425846.html HTTP/1.1
POST http://127.0.0.1:2809//1/request1647418153.html HTTP/1.1 Content-Type: application/octet-stream Content-Length: 123 GIOP\x01\x00\x01\x00o\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0c\x00\x00\x00\x01\xc0N\r\x01\x00\x01\x00\t\x01\x01\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00NameService\x00\x06\x00\x00\x00_is_a\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00IDL:omg.org/CosNaming/NamingContextExt:1.0\x00
SSLIOP(Secure Sockets Layer (SSL) Inter-ORB Protocol)は、GIOPにSSL/TLSによるサーバー・クライアント認証、通信内容の暗号化を適用した通信プロトコルでセキュアな通信が可能になります。
まず、OpenRTM-aistをビルドする時にCMake実行でSSL_ENABLEオプションをオンにしてください。
cmake .. -DSSL_ENABLE=ON
OpenRTM-aistをビルド、インストール後に、まずはネームサーバーを起動します。 ネームサーバーにはSSLIOPのエンドポイントを指定するため、以下の内容の設定ファイルsvc.names.ssliop.confを作成してください。
dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:./etc/ssl/server.pem -SSLCertificate PEM:./etc/ssl/root.crt -SSLPassword passward -SSLCAfile PEM:./etc/ssl/root.crt" static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory"
SSLPrivateKeyオプションでは秘密鍵、SSLCertificateオプションではサーバー証明書、SSLCAfileではルート証明書を指定します。
TAO付属のネームサーバーtao_cosnamingを起動します。
以下のように作成したsvc.names.ssliop.confを指定してtao_cosnamingを起動します。
tao_cosnaming -ORBEndpoint iiop://localhost:/ssl_port=2809 -ORBSvcConf etc/svc.names.ssliop.conf
CosoleIn、ConsoleOutコンポーネントを以下の内容のrtc.confで起動します。
corba.args: -ORBEndpoint htiop:// -ORBSvcConf ./etc/tao_htiop/svc.ssliop.conf corba.nameservers: corbaloc:ssliop:127.0.0.1:2809 corba.master_manager: ssliop://127.0.0.1:2810 manager.components.preactivation: ConsoleIn0, rtcname.ssliop://localhost:2809/*/ConsoleOut0 manager.components.preconnect: ConsoleIn0.out?port=rtcname.ssliop://localhost:2809/*/ConsoleOut0.in
corba.argsオプションはTAOのORB_init関数への引数を指定します。 SSLIOPのエンドポイントとTAOの設定ファイル(ext/svc.ssliop.conf)を設定しています。
''svc.ssliop.conf'は以下の内容で作成します。
dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:./etc/ssl/server.pem -SSLCertificate PEM:./etc/ssl/root.crt -SSLPassword passward -SSLCAfile PEM:./etc/ssl/root.crt" static Advanced_Resource_Factory "-ORBProtocolFactory SSLIOP_Factory"
また、接続するネームサーバーの設定を行います。 ネームサーバーはSSLIOPのエンドポイント(ssliop:127.0.0.1:2809)を指定します。
SSLIOP通信はOMG CORBA Security Service仕様の規格のため、omniORBやOiL等の他の実装との通信も可能です。 このため、rtshellでポートの接続、RTCのアクティブ化の操作ができます。rtshellによるSSLIOP通信の利用方法はについては以下のページを参考にしてください。
rtc.confに記述したように、マネージャ起動時の事前接続(preconnect)、事前アクティブ化(preactivation)の設定を行う事もできます。
SHMIOP(Shared Memory Inter-ORB Protocol)は共有メモリでGIOPメッセージをやり取りするための通信プロトコルです。 共有メモリの読み書きでデータを転送するためTCP/IP通信での転送と比較するとパフォーマンスの向上が期待できます。 ただし、データの転送は共有メモリですが、データ書き込みの通知にTCP/IP通信を使用しています。
corba.args: -ORBListenEndpoints shmiop:// -ORBSvcConf /home/nobu/testlib/etc/tao_shmiop/svc.shmiop.conf -ORBDebugLevel 5 corba.nameservers: corbaloc:shmiop:1.0@2809 corba.master_manager: shmiop://1.0@hostname:2810
static Advanced_Resource_Factory "-ORBProtocolFactory SHMIOP_Factory -ORBProtocolFactory IIOP_Factory -ORBReactorType select_st"
OpenRTM-aistをビルド、インストールすると、上記の通信プロトコルの簡単な動作確認用の設定ファイルがインストールされます。
%RTM_ROOT%\ext\environment-setup.tao.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\tao_diop\rtc.diop.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/tao_diop/rtc.diop.conf
%RTM_ROOT%\ext\environment-setup.tao.vc16.bat %RTM_ROOT%\ACE\vc16\bin\tao_cosnaming.exe -ORBEndpoint htiop://127.0.0.1:2809 -ORBSvcConf %RTM_ROOT%\ext\svc.names.htiop.conf
%RTM_ROOT%\ext\environment-setup.tao.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\tao_htiop\rtc.htiop.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/bin/openrtmNames -ORBEndpoint htiop://127.0.0.1:2809 -ORBSvcConf ${OPENRTM_INSTALL_DIR}/etc/svc.names.htiop.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/tao_htiop/rtc.htiop.conf
%RTM_ROOT%\ext\environment-setup.tao.vc16.bat %RTM_ROOT%\ACE\vc16\bin\tao_cosnaming.exe -ORBEndpoint iiop://localhost:/ssl_port=2809 -ORBSvcConf %RTM_ROOT%\ext\svc.names.ssliop.conf
%RTM_ROOT%\ext\environment-setup.tao.vc16.bat %RTM_ROOT%\Components\C++\Examples\vc16\ConsoleOutComp.exe -f %RTM_ROOT%\ext\tao_ssliop\rtc.ssliop.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/bin/openrtmNames -ORBEndpoint iiop://localhost:/ssl_port=2809 -ORBSvcConf ${OPENRTM_INSTALL_DIR}/etc/svc.names.ssliop.conf
source ${OPENRTM_INSTALL_DIR}/etc/environment-setup.sh ${OPENRTM_INSTALL_DIR}/share/openrtm-2.0/components/c++/examples/ConsoleOutComp -f ${OPENRTM_INSTALL_DIR}/etc/tao_ssliop/rtc.ssliop.conf
マネージャはRTCを管理する仕組みです。 1つのプロセスに1つのマネージャが起動します。
マネージャにはマスターマネージャとスレーブマネージャの2種類あります。 マスターマネージャはスレーブマネージャを管理する上位のマネージャであり、スレーブマネージャはRTCの生成、実行するためのマネージャです。
RTSystemEditor等の外部のツールからマスターマネージャのAPIを呼び出すことでRTCの生成、削除などが実行できます。 RTCはマスターマネージャ上では直接起動せずに、マスターマネージャがスレーブマネージャのAPIを呼び出してRTCを起動するように指令します。
以下はPythonでマスターマネージャにRTCの生成を指令するプログラムの例です。
import sys from omniORB import CORBA import RTM orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID) obj = orb.string_to_object("corbaloc:iiop:localhost:2810/manager") mgr = obj._narrow(RTM.Manager) rtc = mgr.create_component("ConsoleIn&manager_name=samplemaneger")
マスターマネージャを起動する場合はrtcdを-dオプションを付けて実行します。
rtcd -d -f rtc.conf
rtc.confでモジュール探索パスを設定しておく必要があります。
manager.modules.load_path: C:/Program Files/OpenRTM-aist/1.2.2/Components/C++/OpenCV/vc14
スレーブマネージャを起動する場合は特にオプションは必要ありませんが、rtc.confでマネージャ名、モジュール探索パスを設定してください。 またデフォルトの設定ではRTCが1つも実行してない場合にマネージャを自動終了する機能があるためそれをオフにしてください。
manager.instance_name: samplemaneger manager.modules.load_path: C:/Program Files/OpenRTM-aist/1.2.2/Components/C++/OpenCV/vc14 manager.shutdown_auto:NO
create_componentはRTCを生成するためのAPIです。 以下のように引数に起動するRTCのベンダ名、カテゴリ名、コンポーネント名、言語名、バージョン番号を入力することでRTCを生成します。
mgr.create_component("RTC:AIST:Example:ConsoleIn:C++:1.0.0")
引数の文字列は以下のような内容で入力します。
RTC:[vendor]:[category]:[implementation_id]:[version]
ただし、implementation_id以外は省略できるため、以下のようにRTC名だけを入力しても生成できます。
mgr.create_component("ConsoleIn")
RTCはスレーブマネージャ上で起動しますが、RTCを起動するスレーブマネージャを指定する場合は以下のようにmanager_nameのオプションで指定します。
mgr.create_component("ConsoleIn&manager_name=samplemaneger")
起動するスレーブマネージャをアドレスとポート番号を指定してRTCを起動する場合はmanager_addressのオプションで指定します。
mgr.create_component("Flip&manager_address=localhost:2811")
manager_nameオプションでスレーブマネージャ名を指定した場合に指定のスレーブマネージャが起動していない場合、マスターマネージャは指定の名前のスレーブマネージャを起動します。 例えば、以下のsamplemanegerという名前のスレーブマネージャが起動していない場合、新たにsamplemanegerという名前のスレーブマネージャを起動します。
mgr.create_component("ConsoleIn&manager_name=samplemaneger")
以下のようにmanager_nameオプションを指定しない場合、manager_[プロセスID]の名前のスレーブマネージャを新たに起動します。
mgr.create_component("ConsoleIn")
例えばOpenRTM-aistのサンプルコンポーネントにはC++、Python、Javaで実装したConsoleInコンポーネントの3種類が使用できます。 同一コンポーネント名のRTCを区別して起動する場合、以下のように言語名で区別することができます。
mgr.create_component("RTC:AIST:Example:ConsoleIn:Python:1.0.0")
言語名でも区別できない場合は、予めRTCを起動するスレーブマネージャを起動しておいて、create_componentでマネージャ名を指定することで対応できます。
スレーブマネージャのAPIを直接呼び出す場合はget_slave_managersでマスターマネージャからスレーブマネージャを取得して実行します。 以下は指定の名前のスレーブマネージャでモジュールをロードしてRTCを起動する例です。
import sys from omniORB import CORBA import RTM import OpenRTM_aist orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID) obj = orb.string_to_object("corbaloc:iiop:localhost:2810/manager") mgr = obj._narrow(RTM.Manager) print(mgr.create_component("Flip&manager_name=samplemaneger")) def getSlaveManager(master, slavename): slavemgrs = master.get_slave_managers() for slavemgr in slavemgrs: prof = slavemgr.get_configuration() prop = OpenRTM_aist.Properties() OpenRTM_aist.NVUtil.copyToProperties(prop, prof) name = prop.getProperty("manager.instance_name") if name == slavename: return slavemgr return None samplemaneger = getSlaveManager(mgr, "samplemaneger") samplemaneger.load_module( "C:\\Program Files\\OpenRTM-aist\\1.2.2\\Components\\C++\\Examples\\vc14\\ConsoleIn.dll", "ConsoleInInit") samplemaneger.create_component("ConsoleIn")