[openrtm-users 03350] Re: OpenRTM-aist-1.1.2 RTC Builder で自動生成されるデータポートのコードの仕様変更? (Python) について

Tomohiro UMETANI umetani @ konan-u.ac.jp
2016年 12月 27日 (火) 10:55:01 JST


安藤様,OpenRTM-MLのみなさま

甲南大学の梅谷です.
お世話になっております.

安藤様:
自動生成されるコードと必要な方法について
複数の例を挙げて,また,なぜエラーになるのかを,
懇切丁寧にご説明くださりまして,
まことにありがとうございます.

自動生成の時点では,多様なデータ型への対応のために,
ver. 1.1.2でのデータポートの初期化が
以下のように行われることを理解いたしました.

> outdata_arg = [None] * ((len(RTC._d_TimedLong) - 4) / 2)
> self._d_outdata = RTC.TimedLong(*outdata_arg)

また,ver. 1.1.2 では,コードを加筆・修正して,
データポートの構造体を型に応じて明示的に初期化する必要が
あることを理解いたしました.
ご教示いただきまして,まことにありがとうございました.

このたびは,出力されたコードへの
当方の理解が十分でなかったことが原因の1つであり,
申し訳ありません.
また,当方の習熟不足のために,
PythonでのRTコンポーネントのコードを
C++ でのRTコンポーネント作成時と同じ感覚で
書いてしまっていたことも原因だったと思います.
お手数をおかけいたしました.

また,次期バージョンで,初期化コード部分でのコメント追加に
ご対応いただけるとのこと,まことにありがとうございます.

なにとぞよろしくお願い申し上げます.
まずは御礼まで.

On Mon, 26 Dec 2016 17:47:40 +0900
Ando Noriaki <n-ando @ aist.go.jp> wrote:

> 梅谷先生
> 
> 安藤です
> 
> 1.1.2のBuilderで自動生成されるPythonの以下のコードですが、
> 基本的には、Builderで生成直後のRTCを実行時にエラーを出さないためだけ
> のコードとお考え下さい。
> 
> outdata_arg = [None] * ((len(RTC._d_TimedLong) - 4) / 2)
> self._d_outdata = RTC.TimedLong(*outdata_arg)
> 
> ですので、
> 
> # outdata_arg = [None] * ((len(RTC._d_TimedLong) - 4) / 2)
> self._d_outdata = RTC.TimedLong(RTC.TIme(0,0), 0)
> 
> のように修正してお使いください。
> 
> なぜこのようになっているかといいますと、TimedLong くらいの簡単な構造体
> であれば、RTC.TimedLong(RTC.TIme(0,0), 0) のような単純な初期化でいいのですが、
> CameraIMage等では
> 
> self._d_camera = RTC.CameraImage(RTC.Time(0,0), 640, 480, 24, "bitmap",
> 1.0, [])
> 
> TimedPose2Dなどでは、
> 
> self._d_currentPose =
> RTC.TimedPose2D(RTC.Time(0,0),RTC.Pose2D(RTC.Point2D(0,0), 0))
> 
> のように、型ごとに特有の初期化をする必要があります。
> 
> これをBuilderで画一的に回避するために、データポートのデータ型の第1階層をすべてNone
> で初期化しているのが、1.1.2のBuilderが生成するコードです。
> 
> setTimestamp() 関数では、データポートのデータ型の tm フィールドが RTC.Time型で
> あることを前提として、 tm.sec, tm.nsec に時間を代入しようとしますが、
> 上記の自動的な初期化では None が代入されており、RTC.Timeオブジェクトとして
> 情報が入っておりませんので、sec, nsec のフィールドが無く、代入時にエラーとなります。
> 
> 次のバージョンでは初期化コード部分に分かりやすいようにコメントを入れたいと思います。
> 分かりにくい変更、また説明不足で申し訳ございません。
> 
> 以上、よろしくお願いいたします。
> 
> 
> 
> 
> 2016年12月23日 16:20 Tomohiro UMETANI <umetani @ konan-u.ac.jp>:
> 
> > openrtm-users メーリングリストのみなさま
> >
> > 甲南大学の梅谷です.
> > 先日のRTミドルウェアコンテスト2016では
> > 大変お世話になりました.
> >
> > 現在,OpenRTM-aist-1.1.2-RELEASE (Python)の,
> > Ver. 1.1.2 Windows用インストーラ (32bit版)をインストールし,
> > 使用しております.
> > インストール元は以下のところのものです.
> > http://www.openrtm.org/openrtm/ja/node/6034
> >
> > OpenRTM-aist-1.1.2 付属のOpenRTP でのRTC Builder で
> > データポートがあるPythonのコンポーネントのコードを出力したのですが,
> > 自動出力されるデータポートのコードがver. 1.1.2 では,
> > 以下のように変更されていました.
> >
> > ここから
> > =====
> >         outdata_arg = [None] * ((len(RTC._d_TimedLong) - 4) / 2)
> >         self._d_outdata = RTC.TimedLong(*outdata_arg)
> >         """
> >         """
> >         self._data_outOut = OpenRTM_aist.OutPort("data_out",
> > self._d_outdata)
> > =====
> > ここまで
> >
> > 自動出力される変数の名前が変わっているのは良いのですが,
> > 特に上2行に関しては,ver. 1.1.0 では,TimedLong型の場合
> > =====
> >         self._d_outdata = RTC.TimedLong(RTC.Time(0,0),0)
> > =====
> >
> > のように出力されていたと認識しています.TimedLongSeq型の場合は
> >         RTC.TimedLongSeq(RTC.Time(0,0),[])
> > でした.
> >
> > このためかどうかわかりませんが,
> > 1.1.0時代のコードを手掛かりに,データポートから値を出力させるプログラムを
> > 1.1.2で出力されたコードに1.1.0と同じ方法で,
> > タイムスタンプを付けるコードをそのまま書くと,
> > Execute時にエラーが出てしまいます.
> >
> > 実行時のrtc ログの抜粋(一部)を以下に示します
> > ====
> > 2016-12-23 15:16:26,710 SdoServiceAdmin WARNING No available SDO service
> > in the factory: IDL:OpenRTM/ComponentObserver:1.0
> > 2016-12-23 15:16:26,710 SdoServiceAdmin ERROR type 90c1ad6d-06bc-4969-b10e-306291cf0653
> > already exists.
> > 2016-12-23 15:16:28,378 rtobject ERROR Traceback (most recent call last):
> >   File "C:\Python27\lib\site-packages\OpenRTM_aist\RTObject.py", line
> > 1560, in on_execute
> >     ret = self.onExecute(ec_id)
> >   File "C:\Users\umetani\workspace\DataPortSample\DataPortSample.py",
> > line 187, in onExecute
> >     OpenRTM_aist.setTimestamp(self._d_outdata)
> >   File "C:\Python27\lib\site-packages\OpenRTM_aist\OutPort.py", line 51,
> > in setTimestamp
> >     data.tm.sec  = tm.sec
> > AttributeError: 'NoneType' object has no attribute 'sec'
> >
> > 2016-12-23 15:16:32,388 ec_worker ERROR State of the RTC is not
> > ACTIVE_STATE.
> > 2016-12-23 15:16:32,411 ec_worker WARNING ExecutionContext is already
> > stopped.
> > 2016-12-23 15:16:32,411 ec_base ERROR Invoking on_shutdown() for each RTC
> > failed.
> > ====
> >
> > 添付ファイルには,数が多く紛らわしくて申し訳ありませんが,
> > 以下のものを添付いたします.
> > =====
> > 1. 確認したRTコンポーネントのXMLファイル RTC.xml
> > 2. 実行時のログ  rtc1164.log
> > 3. RTC Builder で自動出力したコード DataPortSample_output.py
> > 4. エラーが出ることを確認したコード DataPortSample_1.1.2.py
> > 5. データポートの宣言を1.1.0の方法に修正したもの DataPortSample_1.1.0.py
> >   (これは正しく動作します)
> > =====
> >
> > RTミドルウェアコンテストでのコンポーネント改良時,
> > 1.1.2で自動生成したテンプレートをもとに
> > コンポーネントを作成しているときに,このエラーに遭遇しました.
> >
> > 不勉強で申し訳ありませんが,
> > データポートの宣言部分(自動生成される部分です)を修正せずに,
> > 現行の1.1.2 のバージョンで,正しくタイムスタンプを付けることができる
> > コードの書き方をご教示いただけないでしょうか.
> > よろしくお願い申し上げます.
> >
> > この場合「サンプルのコードを読むように」と良くいわれるのですが,
> > インストール時に入っている examples のコードは
> >
> >         RTC.TimedLong(RTC.Time(0,0),0)
> >
> > で宣言されており,現行のバージョンで自動出力されたコードの
> > 書き方とは異なっております.そのため,困ってしまいました.
> > 最終的には,RTミドルウェアコンテストの他の参加者の方が
> > アップロードされていたコードを参考に,
> > 1.1.0でのデータポート宣言方法にコードを修正して,
> > 実行できるようになった次第です.
> >
> > #バグを生む原因になりますので,
> > #自動生成されるコードを修正することは避けたいです.
> >
> > なにとぞよろしくお願い申し上げます.
> >
> > --
> > Tomohiro UMETANI
> > E-mail: umetani @ konan-u.ac.jp
> >
> > _______________________________________________
> > openrtm-users mailing list
> > openrtm-users @ openrtm.org
> > http://www.openrtm.org/mailman/listinfo/openrtm-users
> >
> >


More information about the openrtm-users mailing list