OpenRTM / OpenRTM-aist

OpenRTM-aist: RT-Middleware and OMG RTC implementation in C++ implemented by AIST
https://openrtm.org/
Other
19 stars 12 forks source link

TimedWStringのデータポートを持つJavaのRTCが異常終了 #396

Closed y-masutani closed 4 years ago

y-masutani commented 5 years ago

1.2.0のRTC Builderを使って,TimedWStringの入力データポートと出力データポートを持つJavaのコンポーネントを新規に作成したところ,実行時に異常終了します.RTC Builderでコード生成し,Javaのパースペクティブに切り替え,コードは何も触らず,Antビルドすると成功しました.その後,生成されたバッチファイルを実行すると,

Component create failed.

とだけ表示されて,Javaのプログラムが終了します.

なお,ポートの型をTimedStringに変更すると問題は発生しません.

確認をいただけると幸いです.

n-ando commented 5 years ago

RTCBのバグだと思うのですが、OutPort変数に対して生成したコード上で initializeParam が呼び出されていないようです。 すべてのOutPortの変数に対しても initializeParam(m_hogehoge_val); を呼び出してみていただけないでしょうか?

以下が試しに、WStringとStringのInPortとOutPortをそれぞれ作成したRTCのコンストラクタの初期化コード部分です。OutPortについてはinitializeParamが呼び出されていません。

        super(manager);
        // <rtc-template block="initializer">
        m_wstringin_val = new TimedWString();
        initializeParam(m_wstringin_val);
        m_wstringin = new DataRef<TimedWString>(m_wstringin_val);
        m_wstringinIn = new InPort<TimedWString>("wstringin", m_wstringin);
        m_dp_name_val = new TimedString();
        initializeParam(m_dp_name_val);
        m_dp_name = new DataRef<TimedString>(m_dp_name_val);
        m_dp_nameIn = new InPort<TimedString>("dp_name", m_dp_name);
        m_wstringout_val = new TimedWString();
        m_wstringout = new DataRef<TimedWString>(m_wstringout_val);
        m_wstringoutOut = new OutPort<TimedWString>("wstringout", m_wstringout);
        m_dp_name2_val = new TimedString();
        m_dp_name2 = new DataRef<TimedString>(m_dp_name2_val);
        m_dp_name2Out = new OutPort<TimedString>("dp_name2", m_dp_name2);
        // </rtc-template>
Nobu19800 commented 5 years ago

上記の修正で試しているのですが、以下のようなExceptionが発生します。データの転送自体は問題なく実行できています。

java.lang.ClassCastException: Unknown data type.
        at jp.go.aist.rtm.RTC.util.NVUtil.copyToProperties(Unknown Source)
        at jp.go.aist.rtm.RTC.Manager.publishPorts(Unknown Source)
        at jp.go.aist.rtm.RTC.Manager.registerComponent(Unknown Source)
        at jp.go.aist.rtm.RTC.Manager.createComponent(Unknown Source)
        at JavaTestComp.myModuleInit(JavaTestComp.java:28)
        at jp.go.aist.rtm.RTC.Manager.activateManager(Unknown Source)
        at JavaTestComp.main(JavaTestComp.java:91)
java.lang.ClassCastException: Unknown data type.
        at jp.go.aist.rtm.RTC.util.NVUtil.copyToProperties(Unknown Source)
        at jp.go.aist.rtm.RTC.Manager.subscribePorts(Unknown Source)
        at jp.go.aist.rtm.RTC.Manager.registerComponent(Unknown Source)
        at jp.go.aist.rtm.RTC.Manager.createComponent(Unknown Source)
        at JavaTestComp.myModuleInit(JavaTestComp.java:28)
        at jp.go.aist.rtm.RTC.Manager.activateManager(Unknown Source)
        at JavaTestComp.main(JavaTestComp.java:91)
java.lang.ClassCastException: Unknown data type.
        at jp.go.aist.rtm.RTC.util.NVUtil.copyToProperties(Unknown Source)
        at jp.go.aist.rtm.RTC.port.PortBase.notify_connect(Unknown Source)
        at jp.go.aist.rtm.RTC.port.OutPortBase.notify_connect(Unknown Source)
        at RTC.PortServicePOA._invoke(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(Unknown Source)
        at com.sun.corba.se.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.invoke(Unknown Source)
        at org.omg.CORBA.portable.ObjectImpl._invoke(Unknown Source)
        at RTC._PortServiceStub.notify_connect(Unknown Source)
        at jp.go.aist.rtm.RTC.port.PortBase.connectNext(Unknown Source)
        at jp.go.aist.rtm.RTC.port.PortBase.notify_connect(Unknown Source)
        at jp.go.aist.rtm.RTC.port.InPortBase.notify_connect(Unknown Source)
        at RTC.PortServicePOA._invoke(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(Unknown Source)
        at com.sun.corba.se.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.invoke(Unknown Source)
        at org.omg.CORBA.portable.ObjectImpl._invoke(Unknown Source)
        at RTC._PortServiceStub.notify_connect(Unknown Source)
        at jp.go.aist.rtm.RTC.port.PortBase.connect(Unknown Source)
        at jp.go.aist.rtm.RTC.port.InPortBase.connect(Unknown Source)
        at RTC.PortServicePOA._invoke(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleInput(Unknown Source)
        at com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(Unknown Source)
        at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequest(Unknown Source)
        at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.dispatch(Unknown Source)
        at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.doWork(Unknown Source)
        at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(Unknown Source)
        at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(Unknown Source)

Java版のソースコードを見てみたのですが、以下のコードでTimedShortやTimedString等のデータ型は何かしら処理するような記述があるのですが、TimedWStringやExtendedDataTypes.idl、InterfaceDataTypes.idlのデータ型、独自データ型については記述がないため必ずExceptionが発生します。処理の意図が不明のため修正のしようがないです。

y-masutani commented 5 years ago

@n-ando 様のご教示通り,すべての出力データポートの変数に対して initializeParam()を追加したところ,Component create failed. で終了することはなくなりました.しかし, @Nobu19800 様のご指摘の問題は同じように発生しています.

バージョン1.1.2で使っていたJavaのRTCを1.2.0で動かそうとしていますが,やはり,Component create failed. で終了してしまいます. しかし,そのRTCのImplクラスには initializeParam()の定義が含まれていませんでした.1.2.0のRTCBが生成した別のRTCのImplクラスからコピーしてみたところ,Component create failed. で終了することはなくなりました.

別のスレッドでも書きましたが,1.1.2で使っていたJavaのRTCを1.2.0で動かすための方法や注意点を教えていただけると幸いです.よろしくお願いいたします.

n-ando commented 5 years ago

これは、1.1.2で導入されたPortPofileからデータの値を取る機能のせいです。データポートの通信には支障はありません。この機能は1.2で廃止されたはずなのですがJava版は残ってしまったようです。修正コードはコミット済みです。

n-ando commented 5 years ago

1.1.2で使っていたJavaのRTCのデータポート変数の初期化部分はどのようになっていましたでしょうか? initializeParam() はJavaのデータポート変数初期化をリフレクションを使って自動化するための関数で、これ以前は、各自初期化引数を与えて初期化してもらっていました。1.2でも同じコードで初期化はされるはずなので、initializeParam()は必須ではありません。もし落ちるとすると別の部分で落ちている可能性があります。コードを見せていただければわかるかもしれません。

y-masutani commented 5 years ago

コードはこれです. https://github.com/MasutaniLab/NavigationManager/blob/master/src/NavigationManagerImpl.java

n-ando commented 5 years ago

とりあえず、以下のようにデータポート変数を初期化してやると動きました。 1.2以前はデータポート変数の初期化はユーザがいちいち手で書いてあげないといけないので面倒だったということから、initializeParam()関数を導入したという経緯があります。

ちなみに、このコードはこのままで1.1.2では動いていたということでしょうか?

 import RTC.RETURN_VALUE;
 import RTC.RTObject;
 import RTC.RangeData;
+import RTC.RangerGeometry;
+import RTC.RangerConfig;
+import RTC.Geometry3D;
+import RTC.Pose3D;
+import RTC.Point3D;
+import RTC.Orientation3D;
+import RTC.Size3D;
 import RTC.ReturnCode_t;
 import RTC.Time;
 import RTC.TimedPose2D;
@@ -75,21 +82,33 @@ public class NavigationManagerImpl extends DataFlowComponentBase {
                System.out.println("CP1");
                m_currentPose = new DataRef<TimedPose2D>(m_currentPose_val);
                m_currentPoseIn = new InPort<TimedPose2D>("currentPose", m_currentPose);
-               m_range_val = new RangeData();
+               m_range_val = new RangeData(new Time(0, 0), new double[0],
+                                 new RangerGeometry(
+                                     new Geometry3D(
+                                         new Pose3D(
+                                             new Point3D(0, 0, 0),
+                                             new Orientation3D(0, 0, 0)),
+                                         new Size3D()), new Geometry3D[0]),
+                                           new RangerConfig());
                m_range = new DataRef<RangeData>(m_range_val);
                m_rangeIn = new InPort<RangeData>("range", m_range);
-               m_path_val = new Path2D();
+               m_path_val = new Path2D(new Time(0, 0), new Waypoint2D[0]);
                m_path = new DataRef<Path2D>(m_path_val);
                m_pathIn = new InPort<Path2D>("path", m_path);
-               m_camera_val = new CameraImage();
+               m_camera_val = new CameraImage(new Time(0, 0), (short)0, (short)0, (short)0, new String(""
), 0, new byte[0]);
                m_camera = new DataRef<CameraImage>(m_camera_val);
                m_cameraIn = new InPort<CameraImage>("camera", m_camera);
                m_targetVelocity_val = new TimedVelocity2D(new RTC.Time(0, 0),
-                               new RTC.Velocity2D(0, 0, 0));
+                                                          new RTC.Velocity2D(0, 0, 0));
                m_targetVelocity = new DataRef<TimedVelocity2D>(m_targetVelocity_val);
                m_targetVelocityOut = new OutPort<TimedVelocity2D>("targetVelocity",
                                m_targetVelocity);
-               m_goal_val = new Waypoint2D();
+               m_goal_val = new Waypoint2D(new Pose2D(new Point2D(), 0.0),
+                                           0.0,
+                                           0.0,
+                                           new Time(0, 0),
+                                           new Velocity2D());
+               //                                          new Pose2D(new Point2D(), 0.0));
                m_goal = new DataRef<Waypoint2D>(m_goal_val);
                m_goalOut = new OutPort<Waypoint2D>("goal", m_goal);
                m_mapperServicePort = new CorbaPort("mapperService");