Implement Original Serializer (C++)

Installing OpenRTM-aist

OpenRTM-aist 2.0以上が必要なため、以下の手順でソースコードからビルドを行う必要がある。

ビルド終了後、特定の場所にインストールする。

cmake-guiでCMake_INSTALL_PREFIXを設定するか、cmake実行時のコマンドで設定する。

 cmake -DOMNI_VERSION=42 -DOMNI_MINOR=3 -DOMNITHREAD_VERSION=41 -DORB_ROOT=C:/workspace/omniORB-4.2.3-win64-vc141 -DCORBA=omniORB -G "Visual Studio 15 2017" -A x64 .. -DCMake_INSTALL_PREFIX=C:/workspace/openrtm_install

ビルド後に、以下のコマンドでインストールする。

 cmake --build .. --target INSTALL --config Release

Visual Studio上でINSTALLのプロジェクトをビルドしてもインストールできる。

独自シリアライザの作成

独自シリアライザの実装には以下のファイルを作成する必要がある。

  • C++ソースファイル(今回はTestSerializer.cppとする)
  • CMakeLists.txt

CMakeLists.txtの作成

CMakeLists.txtにはOpenRTM-aistのパッケージの検出、動的ライブラリを生成するようにコマンドを記述します。

 cmake_minimum_required (VERSION 3.0.2)
 
 project (TestSerializer
     VERSION 1.0
     LANGUAGES CXX)
 
 message(STATUS ${MSVC_TOOLSET_VERSION})
 
 #OpenRTM-aistの検出
 find_package(OpenRTM)
 
 #インクルードディレクトリ、リンクディレクトリ、コンパイル時のフラグの設定
 include_directories(${PROJECT_SOURCE_DIR}/include)
 include_directories(${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME})
 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})

CPPファイルの作成

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;
    }
 };
 
 extern "C"
 {
     //以下はモジュールロード時に呼び出される関数
     DLL_EXPORT void TestSerializerInit(RTC::Manager* manager)
     {
         //以下のファクトリはデータ型ごとに登録する必要がある
         coil::GlobalFactory <::RTC::ByteDataStream<RTC::TimedLong>>::
             instance().addFactory("test",  //addFactory関数の第1引数で登録名を設定。以下で独自シリアライザを利用するときはこの名前を使用する。
                 ::coil::Creator< ::RTC::ByteDataStream<RTC::TimedLong>,
                 TestSerializer<RTC::TimedLong>>,
                 ::coil::Destructor< ::RTC::ByteDataStream<RTC::TimedLong>,
                 TestSerializer<RTC::TimedLong>>);
     };
 }

シリアライザにはwriteData関数、readData関数、getDataLength関数、serialize関数、deserialize関数を実装する必要がある。 serialize関数はRTMのデータをunsigned char型に変換して内部のバッファに保存する。 保存したデータはreadData関数で取り出すことができる。 このため、データ送信時の処理は以下のようになっている。

sirializer2.png

writeData関数は内部のバッファにバイト列のデータを書き込む関数である。 deserialize関数は内部のバッファのデータをRTMのデータ型に変換して外部の変数に渡す。 このため、データ受信時の処理は以下のようになっている。

sirializer3.png

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といパラメータで設定する。

sirializer4.png

これで独自シリアライザ(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

Download

latest Releases : 2.0.0-RELESE

2.0.0-RELESE Download page

Number of Projects

Choreonoid

Motion editor/Dynamics simulator

OpenHRP3

Dynamics simulator

OpenRTP

Integrated Development Platform

AIST RTC collection

RT-Components collection by AIST

TORK

Tokyo Opensource Robotics Association

DAQ-Middleware

Middleware for DAQ (Data Aquisition) by KEK