プロジェクト

全般

プロフィール

Android 版 OpenRTM とのソースコードの差分について

Android 版 OpenRTM( 未来技術研究所様作成 ) は、 JacORB を使用している。 aist 版では、 sun 依存にする部分がある。
今後のバージョンアップを考慮して、移植作業の工数を減らす( 理想としては、移植作業が不要にする )ため、ソースコード差分を減らす、または、aist 版で JacORB を使用することを検討する。

作成:片見

ソースコードの移植作業について

aist 版 ( r597 ) との差分を示す。
r597 は、未来技術研究所様の依頼で、差分を減らすように修正したもの。
以下は、 Android 版 OpenRTM のソースコードと差分とったものではなく、未来技術研究所 高木さまからのメールの資料から抽出。
移植のために修正が必要なファイルを以下に示す。
  • jp/go/aist/rtm/RTC/IopIorInterceptor.java
  • jp/go/aist/rtm/RTC/Manager.java
  • jp/go/aist/rtm/RTC/ManagerConfig.java
  • jp/go/aist/rtm/RTC/ManagerServant.java
  • jp/go/aist/rtm/RTC/port/CorbaPort.java
  • jp/go/aist/rtm/RTC/util/ORBUtil.java
  • jp/go/aist/rtm/RTC/port/EncapsOutputStreamExt.java

jp/go/aist/rtm/RTC/IopIorInterceptor.java

aist 版では endpoint の取得で、sun 依存のクラスを使用している。

ソースコードで JacORB のコメントされているところを活かして、 sun とコメントされているところをコメントアウトすることにより、sun と JacORB の切り替えを行う。

--- .jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/IopIorInterceptor.java        2011-12-08 16:05:48.000000000 +0900
+++ .jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/IopIorInterceptor.java    2011-12-12 10:47:41.000000000 +0900
@@ -14,6 +14,15 @@
 import org.omg.IOP.TaggedComponent;
 import org.omg.PortableInterceptor.IORInterceptor;

+/*
+//<+JacORB
+import org.jacorb.orb.etf.ProtocolAddressBase;
+import org.jacorb.orb.iiop.IIOPAddress;
+import org.jacorb.orb.iiop.IIOPProfile;
+import java.util.List;
+import java.util.Iterator;
+//+>
+*/

 /**
  * {@.ja ポータブルインターセプタを利用してIORを書き換える.}
@@ -93,6 +102,7 @@
             return;
         }

+        //<+ sun 
         com.sun.corba.se.spi.orb.ORB sunorb 
                     = (com.sun.corba.se.spi.orb.ORB)orb;

@@ -103,6 +113,29 @@
             = (com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate)iop.getTaggedProfileTemplate();
         String host = ptemp.getPrimaryAddress().getHost();
         short port = (short)ptemp.getPrimaryAddress().getPort();
+        //+>
+
+/*
+        //<+ JacORB
+        ProtocolAddressBase address = null;
+        org.jacorb.orb.ORB jacorb = (org.jacorb.orb.ORB)orb;
+        if (jacorb.getBasicAdapter() == null) {
+            return;
+        }
+        List eplist = jacorb.getBasicAdapter().getEndpointProfiles();
+        for (Iterator i = eplist.iterator(); i.hasNext(); ) {
+            org.omg.ETF.Profile p = (org.omg.ETF.Profile)i.next();
+            if (p instanceof IIOPProfile) {
+                address = ((IIOPProfile)p).getAddress();
+                break;
+            }
+        }
+        if (address == null) {
+            return;
+        }
+        short port = (short)((IIOPAddress)address).getPort();
+        //+>
+*/

         for(int ic=0;ic<m_endpoints.size();ic++){
             if(m_endpoints.get(ic).Port==0){

jp/go/aist/rtm/RTC/Manager.java

ORB の起動 ( init() ) の引数を生成する際に、 sun 依存のものを使用。

ソースコードの final の String 変数を以下のように設定することにより、sun と JacORB の切り替えが可能。

変数名 sun を使用する場合 JacORB を使用する場合
SERVER_HOST "com.sun.CORBA.ORBServerHost" "OAIAddr"
SERVER_PORT "com.sun.CORBA.ORBServerPort" "OAPort"
LISTENER_PORT "com.sun.CORBA.POA.ORBPersistentServerPort" "OAPort"
+    private static final String SERVER_HOST = "com.sun.CORBA.ORBServerHost";
+    private static final String SERVER_PORT = "com.sun.CORBA.ORBServerPort";
+    private static final String LISTENER_PORT = "com.sun.CORBA.POA.ORBPersistentServerPort";
+    //private static final String SERVER_HOST = "OAIAddr";
+    //private static final String SERVER_PORT = "OAPort";
+    //private static final String LISTENER_PORT = "OAPort";

jp/go/aist/rtm/RTC/ManagerConfig.java

rtc.conf をサーチする path に差異がある。
CONFIG_FILE_PATH のファイルパスの変更。

     public static final String[] CONFIG_FILE_PATH = {
         "./rtc.conf",
-        "/etc/rtc.conf",
-        "/etc/rtc/rtc.conf",
-        "/usr/local/etc/rtc.conf",
-        "/usr/local/etc/rtc/rtc.conf",
+        "/sdcard/rtc.conf",
+        "/mnt/sdcard/rtc.conf",
         null
     };

jp/go/aist/rtm/RTC/ManagerServant.java

マネージャを CORBA 化して、参照を登録する部分で sun 依存の ORB を使用している。

createManagerCORBAServant() 内の orb のキャストを変更することで sun と JacORB を切り替える。
sun の場合は、com.sun.corba.se.impl.orb.ORBImpl を活かして、 JacORB の場合は、org.jacorb.orb.ORB を活かす。

+    private void createManagerCORBAServant() throws Exception {
+        m_mgr.getPOA().activate_object( this );
+        com.sun.corba.se.impl.orb.ORBImpl orb
+                = (com.sun.corba.se.impl.orb.ORBImpl)m_mgr.getORB();
+//        org.jacorb.orb.ORB orb
+//                = (org.jacorb.orb.ORB)m_mgr.getORB();
+        orb.register_initial_reference( 
+                "manager", m_mgr.getPOA().servant_to_reference(this) );
+    }

jp/go/aist/rtm/RTC/port/CorbaPort.java

org.omg.CORBA.ObjectHelper を JacORB 未実装のため削除

--- jp/go/aist/rtm/RTC/port/CorbaPort.java    2010-05-07 13:50:17 +0900
+++ jp/go/aist/rtm/RTC/port/CorbaPort.java    2011-08-11 09:03:39 +0900
@@ -17,7 +17,7 @@
 import org.omg.CORBA.ORB;
 import org.omg.CORBA.BAD_OPERATION;
 import org.omg.CORBA.Object;
-import org.omg.CORBA.ObjectHelper;
 import org.omg.CORBA.Any;
 import org.omg.CORBA.TCKind;
 import org.omg.PortableServer.Servant;
@@ -792,37 +792,37 @@
     }

-    private class subscribe implements operatorFunc {
-        
-        public subscribe(Vector<Consumer> cons) {
-            
-            this.m_cons = new Vector<Consumer>(cons);
-            this.m_len = cons.size();
-        }
-        
-        public void operator(java.lang.Object elem) {
-            
-            operator((NameValue) elem);
-        }
-        
-        public void operator(NameValue nv) {
-
-            for (int i = 0; i < this.m_len; ++i) {
-                if (this.m_cons.get(i).name.equals(nv.name)) {
-                    try {
-                        org.omg.CORBA.Object obj = ObjectHelper.extract(nv.value);
-                        if( obj != null ) {
-                            this.m_cons.get(i).consumer.setObject(obj);
-                        }
-                    } catch (BAD_OPERATION ignored) {
-                    }
-                }
-            }
-        }
-        
-        private Vector<Consumer> m_cons; // コンストラクタで必ず初期化されるので、ここではインスタンス生成しない。
-        private int m_len;
-    }

     // functors
     /**

jp/go/aist/rtm/RTC/util/ORBUtil.java

JacORBは、ロガー(Logger)未対応のためコメント

@@ -41,9 +41,9 @@
         if (orb == null) {
             orb = ORB.init(args, prop);
             try {
-                if (orb instanceof com.sun.corba.se.spi.orb.ORB) {
-                    Logger logger = ((com.sun.corba.se.spi.orb.ORB) orb).getLogger("");
-                    logger.setLevel(Level.SEVERE); // log 
+                if (orb instanceof org.jacorb.orb.ORB) {
+//                    Logger logger = ((org.jacorb.orb.ORB) orb).getLogger("");
+//                    logger.setLevel(Level.SEVERE); // log 
                 }
             } catch (Exception e) {
                 e.printStackTrace(); // system error

jp/go/aist/rtm/RTC/port/EncapsOutputStreamExt.java

データポートでシリアル化するために sun 依存のクラスを使用。

移植のための修正 sun を使用する場合 JacORB を使用する場合
ORB クラスのインポート com.sun.corba.se.spi.orb.ORB org.omg.CORBA.ORB
Stream クラスのインポート com.sun.corba.se.impl.encoding.EncapsOutputStream org.jacorb.orb.CDROutputStream
EncapsOutputStreamExt 継承するクラス EncapsOutputStream CDROutputStream
コンストラクタのスーパークラスの呼び出し super((ORB)orb,isLittleEndian); super((ORB)orb);
getByteArray()メソッド return toByteArray(); return getBufferCopy();
package jp.go.aist.rtm.RTC.port;
/**
 * {@.ja EncapsOutputStreamの拡張クラス。}
 * {@.en Expansion class of EncapsOutputStream}
 */

import com.sun.corba.se.impl.encoding.EncapsOutputStream;
import com.sun.corba.se.spi.orb.ORB;
//import org.jacorb.orb.CDROutputStream;
//import org.omg.CORBA.ORB;

//public class EncapsOutputStreamExt extends CDROutputStream {
public class EncapsOutputStreamExt extends EncapsOutputStream {
    /**
     * {@.ja コンストラクタ}
     * {@.en Constructor}
     * <p>
     *
     */
    public EncapsOutputStreamExt(org.omg.CORBA.ORB orb, boolean isLittleEndian) {
        super((ORB)orb,isLittleEndian);
        //super((ORB)orb);
    }

    /**
     * {@.ja ストリームの内容を配列で取得する。}
     * {@.en Gets the content of the stream in the array.}
     * <p>
     */
    public final byte[] getByteArray(){
        return toByteArray();
        //return getBufferCopy();
    }
}                                                                           

aist 版での JacORB の使用

概要

aist 版で sun ではなく、 JacORB を使用することにより、移植作業が不要となる。
そのため、 aist 版で JacORB を使用することを検討する。(Linux で確認。 )

調査/検討

sun 依存のクラスは、シリアライズ (EncapsInputStream,EncapsOutputStream) で使用してる。
その代替えとして JacORB の CDRInputStream,CDROutputStream の使用を検討したが、CDROutputStream は endian の設定ができないことがわかった。(CDRInputStream では endian のための実装がされている。 )
CDROutputStream を継承して endian のための実装をすることも可能であるが、本筋から外れるので、これは考慮しないものとする。

JacORB は、 OpenRTM-aist の一部の仕様 ( データポート接続のエンディアン設定機能 ) を満すことができいため、JacORB は採用は見送ることとする。
ただし、今後、JacORB がバージョンアップにより CDROutputStream の endian の実装がされれば、再検討する。

データポート接続のエンディアン設定機能を使用せず、多言語間の接続を Bigエンディアンで接続するという機能限定で使用する場合は、JacORB を使用することができる。

詳細

以下に他項目の検討内容を示す。

JacORB のインストール

JacORB は、sun-java に同梱されていないため、コンパイルおよびインストールする必要がある。
http://www.jacorb.org/download.html

コンパイルおよびインストールには、JDK と ANT が必要となる。

※ Java JDK 1.5 or above is required for JacORB 2.3.1

ビルド

rtm をビルドする際に、JacORB(/usr/local/JacORB/classes) の classpath を追加する。
idl コンパイラは idlj を使用してもエラーは発生しない。
※ RTCB の出力を変更する必要あり。

動作確認

  • classpath に以下を追加する。
    • /usr/local/JacORB/classes
    • /usr/local/JacORB/lib/avalon-framework-4.1.5.jar
  • java起動オプションを追加
    • -Djava.endorsed.dirs=/usr/local/JacORB/lib
    • -Dorg.omg.CORBA.ORBClass=org.jacorb.orb.ORB
    • -Dorg.omg.CORBA.ORBSingletonClass=org.jacorb.orb.ORBSingleton
  • 起動シェルスクリプトを変更する。
    java -Djava.endorsed.dirs=/usr/local/JacORB/lib -Dorg.omg.CORBA.ORBClass=org.jacorb.orb.ORB -Dorg.omg.CORBA.ORBSingletonClass=org.jacorb.orb.ORBSingleton RTMExamples.SimpleIO.ConsoleInComp -f RTMExamples/SimpleIO/rtc.conf ${1+"$@"}
    

    ※ RTCB の出力を変更する必要あり。
  • SimpleIO,SimpleServicem,ConfigSample が正常に動作することを確認した。
  • omniとの接続
    • SimpleIO:エンディアンが合わない。対応可能か調査中。
    • JacORB の CDROutputStream ではエンディアンの設定ができない。CDRInputStream では可能。ソースコードを確認したのうえで変更が必要。
  • java corba との接続
    • SimpleIO:エンディアンが合わない。対応可能か調査中。

JacORB の再配布

JacORB は GNU LIBRARY GENERAL PUBLIC LICENSE。

RTM と一緒に配布した方がユーザにとっては、インストール作業が楽になる。
バージョンアップを考慮するとユーザに委ねた方がいいのか?
※ 同梱する場合、インストーラの構成を修正する必要あり。

ネームサービス

examples で確認したところ、 orbd でも問題なし。
JacORB の ネームサービスを使用する必要があるか?

互換性

今までの財産との互換は?
sun と JacORB は接続可能か?
RTCは再コンパイルで利用可能か?

sun-java と JacORB の組み合せ

sun-java と JacORB でバージョン依存があるか?