このページは首都大学東京大学院のユビキタスロボティクス特論(2019年5月15日)で行うOpenRTM-aist 1.2.0のインストール、Flipコンポーネント作成の手順を記したページです。 本来はopenrtm.orgのページに記載してあるのですが、授業当日にopenrtm.orgを閉じるらしいので臨時ページを作成しました。

既にRTミドルウェアの概要については説明済みだと聞いていますが、分からない点は以下の用語集を参考にしてください。

OpenRTM-aist 1.2.1(もしくは1.2.0)のインストール

インストーラー一式を保存したUSBメモリを配布します。 おそらく人数分は無いと思いますのでVisual Studioがインストールされていない人を優先してください。 以下のリンクからでも入手できますが、一斉にダウンロードを始めると混雑するためできるだけUSBメモリのインストーラーを使用してください。

Windowsの場合

以下のソフトウェアをインストールしてください。

Visual Studioがインストール済みかの確認

Visual Studio 2008、2012、2013、2015、2017、2019がインストール済みの場合はここでのVisual Studioのインストールは必要ありません。 既にインストール済みかどうか確認するためには、Windows 10の場合だと左下の「ここに入力して検索」にVisual Studioと入力して検索してください。

image

Windows 8の場合はスタート画面->アプリビューから探してください。

OpenRTM-aist 1.1.2以前をインストールしている場合

研究室のノートPCの場合だと去年の授業などでインストールされている可能性があります。 OpenRTM-aist 1.1.2以前をインストールしている場合はアンインストールしてください。 Windowsだとコントロールパネルからプログラム->プログラムのアンインストールで設定してください。

Visual Studioをインストールすることが困難な場合について

Visual Studioは大量のファイルをダウンロードする必要があるため環境によってはダウンロードに数時間かかる可能性があります。 オフラインインストーラーを用意していますので、USBメモリ内のvs_installer_2019/vs_community__2112361810.1542592799_2019.exeをダブルクリックして実行してください。

以下の画面では続行をクリックしてください。

1

C++によるデスクトップ開発のチェックがONになっていることを確認してインストールボタンを押してください。

2

再起動が必要な場合は再起動してください。

Visual Studioを最初に起動したときにサインインを求められます。サインインしない場合は30日間のみ使用できます。 今回は30日以上使用するという事のようですので、Microsoftアカウントを持っていない場合は以下の手順で作成してサインインしてください。

Ubuntuの場合

$ sudo apt-get install gcc g++
$ sudo apt-get install libomniorb4-dev omniidl omniorb-nameserver
$ sudo apt-get install python-omniorb-omg omniidl-python
$ sudo apt-get install cmake
$ sudo apt-get install doxygen
# Ubuntu 18.04、18.10の場合
$ sudo apt-get install openjdk-8-jdk
# Ubuntu 16.04の場合
$ sudo apt-get install default-jdk

Ubuntu 18.04、18.10の場合は以下のコマンドでjava8に切り替えます。

$ sudo update-alternatives --config java
ubuntu 18.04 (64bit) の場合

C++版のインストール
wget https://github.com/OpenRTM/OpenRTM-aist/releases/download/v1.2.0/OpenRTM-aist_1.2.0_ubuntu18.04_amd64_package.tar.gz
tar xf OpenRTM-aist_1.2.0_ubuntu18.04_amd64_package.tar.gz
cd OpenRTM-aist_1.2.0_ubuntu18.04_amd64_package
sudo sh install-openrtm-deb-packages.sh
cd ..

Python版のインストール
wget https://github.com/OpenRTM/OpenRTM-aist-Python/releases/download/v1.2.0/OpenRTM-aist-Python_1.2.0_ubuntu18.04_amd64_package.tar.gz
tar xf OpenRTM-aist-Python_1.2.0_ubuntu18.04_amd64_package.tar.gz
cd OpenRTM-aist-Python_1.2.0_ubuntu18.04_amd64_package
sudo sh install-openrtm-deb-packages.sh
cd ..


RTSystemEditor/RTCBuilderのインストール
wget https://github.com/OpenRTM/OpenRTP-aist/releases/download/v1.2.0/OpenRTP-aist_1.2.0_ubuntu18.04_amd64_package.tar.gz
tar xf OpenRTP-aist_1.2.0_ubuntu18.04_amd64_package.tar.gz
cd OpenRTP-aist_1.2.0_ubuntu18.04_amd64_package
sudo sh install-openrtm-deb-packages.sh
cd ..

Flipコンポーネント作成手順

以下のようにInPortで受信した画像を左右上下に反転させてOutPortから出力するRTコンポーネント(RTC)を作成します。

image

作成手順は以下のようになっています。

  1. RTCの仕様を決める
  2. RTC BuilderでRTCのひな形コードを生成する
  3. 内部の処理を実装する
  4. RT System EditorでRTシステムを作成、動作確認をする

RTCの仕様を決める

RTCのモジュール名等の基本的な情報、RTCにどのようなデータポート、サービスポート、コンフィギュレーションパラメータなどが使えるのか等の仕様をまず決める必要があります。 今回は以下のような仕様に設定します。

   
モジュール名 Flip
アクティビティ onActivated、onDeactivated、onExecute
InPort 1個(originalImage)
OutPort 1個(flippedImage)
コンフィギュレーションパラメータ 1個(flipMode)

FlipコンポーネントはInPortで他のRTCから受信した画像データをOutPortから出力するRTCのため、まずInPortとOutPortが必要です。 また画像を反転させる方向の設定をコンフィギュレーションパラメータで設定できるようにします。

以下はoriginalImageというInPortの仕様です。 originalImageは他のRTCから画像データを受信するポートに該当します。

   
ポート名 originalImage
RTC::CameraImage

以下はflippedImageというOutPortの仕様です。 originalImageで受信した画像データを反転した画像を送信します。

   
ポート名 flippedImage
RTC::CameraImage

RTC::CameraImageは画像データを送受信するためのデータ型です。 以下に現在使用可能なデータ型の一覧を記載してありますので参考にしてください。

以下はflipModeというコンフィギュレーションパラメータの仕様です。 コンフィギュレーションパラメータはRT System Editor等のツールから実行中のRTCのパラメータを操作するための機能です。

   
パラメーター名 flipMode
int
デフォルト値 0
制約 (0, -1, 1)
Widget radio

このコンフィギュレーションパラメータで画像反転パターンを設定します。

RTCは状態遷移を行い、状態によりonActivated、onDeactivated、onExecute等のコールバック関数を呼び出します。 これらのコールバック関数で画像反転処理、リソースの解放処理などを実行します。RTCの主たる機能を実行する部分をアクティビティと言います。

今回は以下のコールバック関数を有効にします。

関数名 意味
onActivated RTCがアクティブ状態に遷移したときに呼び出されるコールバック関数。初期化などを実行する。
onDeactivated RTCが非アクティブ状態に遷移したときに呼び出されるコールバック関数。終了処理などを実行する。
onExecute RTCがアクティブ状態の時に周期的に呼び出されるコールバック関数。メインの処理を実行する。

RTC BuilderでRTCのひな形コードを生成する

RTC BuilderはRTCのひな形コードを生成するためのGUIツールです。 先ほど決めた仕様をRTC Builderに入力すると、C++、Python、Java、Luaのコードを生成できます。

OpenRTPの起動

OpenRTPはRTC Builder、RT System Editorのツールを含む開発環境です。

Windowsの場合は、デスクトップのショートカットをダブルクリックしてください。

image

もしくはWindows 10の場合は左下の「ここに入力して検索」にOpenRTPと入力して起動してください。

image

Ubuntuの場合は以下のコマンドを入力します。

openrtp

最初にワークスペースの指定が必要なため、適当な場所を指定して起動ボタンを押してください。

image

OpenRTPが起動しない場合

OpenRTPが起動、終了を繰り返したり、何らかのエラーメッセージを出す場合があります。 起動終了を繰り返す場合はOSを再起動しないと解決しない場合もあります。

問題が発生した場合は以下のフォルダを削除してからOpenRTPを起動してください。(ユーザー名は適宜変更してください)

C:\Users\{ユーザー名}\.eclipse

RTC Builderの起動

OpenRTPを最初に起動したときにWelcomeページが開きますが、不要のため×ボタンで閉じてください。

image

右上のパースペクティブを開くボタンを押してください。

image

RTC Builderを選択して起動してください。

image

プロジェクト作成

RTC Buiderのプロジェクトを生成します。 以下のRTと書かれたアイコンをクリックしてください。

image

今回はプロジェクト名にFlipと入力してプロジェクトを作成します。

image

仕様の入力

Flipコンポーネントの仕様を入力していきます。

基本情報の設定

基本タブを選択してモジュール名Flipと入力してください。

image

アクティビティの設定

仕様通りにonActivated、onDeactivated、onExecuteを有効にします。 有効にするためには、アクティビティタブからonActivate等の名前をクリックしてON・OFFを切り替えます。

image

同じ手順でonDeactivated、onExecuteをONに切り替えます。

image

データポートの設定

データポートのタブを選択して、InPort、OutPortを追加します。 InPort、OutPortの追加はAddボタンを押します。

image

ポートの名前はポート名をクリックすることで変更できます。

image

InPortを仕様通りにポート名、データ型を設定します。

image

このとき必ずRTC::CameraImageを設定してください。Img::CameraImage、Img::TimedCameraImageと間違えないようにしてください。

OutPortを仕様通りにポート名、データ型を設定します。

image

コンフィギュレーションパラメータ

コンフィギュレーションタブを選択して、コンフィギュレーションパラメータを追加します。

image

仕様通りに入力します。

image

言語

言語・環境タブから言語をC++に設定します。

image

コード生成

基本タブに戻ってコード生成ボタンを押します。

image

これでCPPファイル、ヘッダーファイルなどのソースコード、CMake設定ファイルなどが生成できます。

パッケージエクスプローラのFlipを右クリックして、表示方法->システムエクスプローラーで確認できます。

image

内部の処理を実装する

RTCの内部で画像を反転させる処理を実装してRTCの実行ファイルを作成します。

CMake設定ファイルの編集

画像処理にはOpenCVというライブラリを使用します。 RTCのビルドにはCMakeというビルドシステムを使用しており、使用するライブラリの設定などはCMakeLists.txtという設定ファイルに記述する必要があります。 OpenCVのライブラリとリンクするためには、コードを生成したフォルダ(Flip)のsrc/CMakeLists.txtを以下のように編集します。

set(comp_srcs Flip.cpp )
set(standalone_srcs FlipComp.cpp)

find_package(OpenCV REQUIRED) #追加

if(${OPENRTM_VERSION_MAJOR} LESS 2)
add_dependencies(${PROJECT_NAME} ALL_IDL_TGT)
target_link_libraries(${PROJECT_NAME} ${OPENRTM_LIBRARIES} ${OpenCV_LIBS}) #${OpenCV_LIBS}を追加

add_executable(${PROJECT_NAME}Comp ${standalone_srcs}
  ${comp_srcs} ${comp_headers} ${ALL_IDL_SRCS})
add_dependencies(${PROJECT_NAME}Comp ALL_IDL_TGT)
target_link_libraries(${PROJECT_NAME}Comp ${OPENRTM_LIBRARIES} ${OpenCV_LIBS}) #${OpenCV_LIBS}を追加

※Flipフォルダ直下のCMakeLists.txtではありません。srcフォルダの下のCMakeLists.txtを編集してください。

Visual Studioのプロジェクト生成(Ubuntuの場合はMakefile)

CMake設定ファイルからVisual Studioのプロジェクト、Makefile等を作成できます。 まずはcmake-guiを起動してください。Windows 10の場合は左下の「ここに入力して検索」にCMakeと入力してCMake(cmake-gui)を起動してください。

image

cmake-guiにFlip直下のCMakeLists.txtをドラッグアンドドロップしてください。 これでcmake-guiの「Where is the source code」にFlipのディレクトリが設定されます。

image

「Where to build the binaries」にはFlip以下のbuildフォルダを指定してください。

image

次にConfigureボタンを押します。 この時、Flipコンポーネントのビルドに必要なライブラリの検出等を行います。

image

コンパイラの種類を設定します。 おそらくOpenRTM-aistの64bit版をインストールしているはずのため、「Optional Platform for genarator」にはx64を設定してください。

image

※cmake-guiのバージョンが古い場合は操作画面の構成が違っています。古いバージョンの場合は「Visual Stuidio 15 2017 Win64」等を設定してください。

その後、Finishボタンを押すとConfigureを開始します。成功すると「Configuring done」と表示されます。

ここで失敗する場合はVisual StudioのC++コンパイラがインストールされていない可能性があります。

次にGenarateをクリックします。

image

これでVisual Studioのプロジェクトファイルを生成できました。

Open Projectボタンを押してVisual Studioのソリューションファイルを開いてください。

image

※Visual Studioが複数インストールされている場合、Visual Studio 2019を指定して生成したのにVisual Studio 2017でソリューションファイルを開くということが発生します。その場合は生成したソリューションファイル(Flip.sln)を右クリックしてプログラムから開く->Microsoft Visual Studio 2019で開いてください。

image

Ubuntuの場合は以下のコマンドでMakefileを生成できます。

mkdir build
cmake ..

ソースコードの編集

Visual StudioのソリューションエクスプローラからFlip.hFlip.cppを開いて編集します。

image

Flip.hの編集

Flip.hの編集を行います。

以下のようにOpenCVのヘッダーファイルをインクルードします。

#include <rtm/idl/ExtendedDataTypesSkel.h>
#include <rtm/idl/InterfaceDataTypesSkel.h>
//OpenCV用インクルードファイルのインクルード
#include <opencv2/opencv.hpp> //追加

// Service implementation headers

反転した画像の保存するメンバー変数を追加します。

 private:
     // <rtc-template block="private_attribute">
  
     // </rtc-template>
 
     // <rtc-template block="private_operation">
  
     // </rtc-template>
         cv::Mat m_imageBuff; //追加
         cv::Mat m_flipImageBuff; //追加
Flip.cppの編集

Flip.cppの編集を行います。 下記のように、onActivated()、onDeactivated()、onExecute() を実装します。

 RTC::ReturnCode_t Flip::onActivated(RTC::UniqueId ec_id)
 {
 
        // OutPortの画面サイズの初期化
        m_flippedImage.width = 0;
        m_flippedImage.height = 0;
 
        return RTC::RTC_OK;
 }
 RTC::ReturnCode_t Flip::onDeactivated(RTC::UniqueId ec_id)
 {
        if (!m_imageBuff.empty())
        {
            // 画像用メモリの解放
            m_imageBuff.release();
            m_flipImageBuff.release();
        }
 
        return RTC::RTC_OK;
 }
 RTC::ReturnCode_t Flip::onExecute(RTC::UniqueId ec_id)
 {
        // 新しいデータのチェック
        if (m_originalImageIn.isNew()) {
            // InPortデータの読み込み
            m_originalImageIn.read();
 
            // InPortとOutPortの画面サイズ処理およびイメージ用メモリの確保
            if (m_originalImage.width != m_flippedImage.width || m_originalImage.height != m_flippedImage.height)
            {
                m_flippedImage.width = m_originalImage.width;
                m_flippedImage.height = m_originalImage.height;
 
                m_imageBuff.create(cv::Size(m_originalImage.width, m_originalImage.height), CV_8UC3);
                m_flipImageBuff.create(cv::Size(m_originalImage.width, m_originalImage.height), CV_8UC3);
 
             
            }
 
            // InPortの画像データをm_imageBuffにコピー
            memcpy(m_imageBuff.data, (void *)&(m_originalImage.pixels[0]), m_originalImage.pixels.length());
 
            // InPortからの画像データを反転する。 m_flipMode 0: X軸周り、1: Y軸周り、-1: 両方の軸周り
            cv::flip(m_imageBuff, m_flipImageBuff, m_flipMode);
 
            // 画像データのサイズ取得
            int len = m_flipImageBuff.channels() * m_flipImageBuff.cols * m_flipImageBuff.rows;
            m_flippedImage.pixels.length(len);
 
            // 反転した画像データをOutPortにコピー
            memcpy((void *)&(m_flippedImage.pixels[0]), m_flipImageBuff.data, len);
 
            // 反転した画像データをOutPortから出力する。
            m_flippedImageOut.write();
        }
 
      return RTC::RTC_OK;
 }

画像反転処理はonExecute関数に実装しており、以下のように動作します。

image

ビルド

Visual Studioの「ビルド->ソリューションのビルド」を選択するとビルドします。

image

ビルドに成功するとFlip/build/src/Release(もしくはDebug)FlipComp.exeが生成されます。

Ubuntuの場合はmakeコマンドでビルドしてください。

動作確認

RT System Editorの起動

Flipコンポーネントの動作確認には、Flipコンポーネントへ画像データの送信、変換後の画像データの受信するRTCが必要になります。 またデータポートが通信を行うためにはコネクタを生成する必要があります。 データポートの接続、RTCのアクティブ化等はRT System Editor等のツールで操作できます。

OpenRTPの右上のパースペクティブを開くボタンを押してください。

image

RT System Editorを選択して起動してください。

image

ネームサーバー起動

ネームサーバーは名前でオブジェクトを管理するための仕組みです。 RTCは自身の参照をネームサーバーに登録することで名前でRTCを管理できるようになります。

ネームサービスビューの以下のボタンで起動できます。

image

OpenCVCameraコンポーネント、CameraViewerコンポーネントの起動

OpenCVCameraコンポーネントはUSBカメラの画像をOutPortから送信するRTC、CameraViewerコンポーネントはInPortの入力画像をGUIに表示するRTCです。 Windows 10の場合は左下の「ここに入力して検索」にC++_OpenCV-Examplesを入力してサンプルコンポーネントをインストールしたフォルダを開きます。

image

OpenCVCamera.bat、CameraViewer.batをダブルクリックするとRTCが起動します。

image

Flipコンポーネントの起動

ビルドして作成したFlipComo.exeをダブルクリックして起動してください。

データポートの接続

RT System EditorのONと書かれたボタンを押してSystem Diagramを起動します。 System Diagramにネームサーバーに登録されたRTCをドラッグアンドドロップします。

image

ポートからポートにドラッグアンドドロップすることでコネクタを生成できます。これでOutPortとInPortが通信できるようになります。

image

以下のようにポートを接続してください。

image

動作確認

RTCのアクティブ化

以下のActivate Systemsボタンを押すとシステムダイアグラム上のRTCをアクティブ化します。 RTCがアクティブ状態に遷移するとシステムダイアグラム上で緑色に変化します。

image

アクティブ化後、カメラ画像を反転させた画像がGUI上に表示されます。

Activate Systemsボタンが表示されない場合 OpenRTPを一旦終了、再起動してシステムダイアグラムの起動、RTCの配置をやり直してください。

コンフィギュレーションパラメータの操作

コンフィギュレーションパラメータを操作することで画像反転モードを変更できます。 Flipコンポーネントをクリックして、Configuration Viewの編集ボタンを押してください。

image

以下のラジオボタンを操作することで画像の反転方向を変更できます。

image

処理を中断する場合はDeactivate Systemsボタンを押してください。

image

RTCを終了する場合はAll Exitボタンを押してください。

image