ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
今回は独自の通信方法の実装方法をメモしておきます。
Push型の通信、OpenRTM-aistのPython版を前提にしていますが、C++版でも手順はほぼ同じです。
まずはOpenRTM-aistのPython版に含まれるInPortCorbaCdrConsumer.py、InPortCorbaCdrProvider.pyのクラスを継承したクラスを作成します。
とりあえず、InPortTestConsumer.py、InPortTestProvider.pyというファイルを作成してください。
後は適当にこんな感じでコードを書いておきます。
InPortTestConsumer.py
InPortTestProvider.py
次にInPortTestConsumer、InPortTestProviderのファクトリを登録しておく必要があるため、rtc.confのmanager.modules.preloadにInPortTestConsumer.py, InPortTestProvider.pyを記述しておくことで上記の初期化関数を呼び出します。
ただInPortCorbaCdrConsumer.py、InPortCorbaCdrProvider.pyの初期化関数には引数がないためrtc.confのmanager.modules.preloadに記述するとエラーが出て読み込めないみたいです。上のコードで使いもしないのにmanagerの引数を用意しているのはそのためです。
これで準備完了です。
適当なRTCを起動してデータポートを接続してください。
上手くできていればRTシステムエディタのコネクタプロファイル設定のInterface Typeにtestが追加されているはずなので、これを選択してコネクタを接続してください。
後はいつもどおり通信できていれば成功です。
ただ今回はInPortCorbaCdrProvider、InPortCorbaCdrConsumerを継承して作成しただけなので、通常の通信方法と何も変わりません。
独自の通信方法を実装するために詳細を見ていきます。
とりあえずRTC_A、RTC_Bの2つのコンポーネントがあって、RTC_AからRTC_Bにデータを送信するという事にします。
まず最初OutPortConnector.pyのwrite関数を見てください。
cdrMarshal関数でデータを符号化した後にself._publisher.write関数に渡しています。
この時点でデータはCDRというバイト列に変換されています。
当然ですがこの時点ではまだデータはRTC_A側にあります。
その後、データはInPortCorbaCdrConsumerのput関数に渡されます。
put関数を見てみると、引数のdataをinportcdr.put関数に渡しています。
inportcdrはDataPort.idlで定義されたInPortCdrのオブジェクトリファレンスなので、これを使ってInPortCorbaCdrProviderのput関数を呼び出しているという事になります。
つまりこの時点でRTC_AからRTC_Bにデータが送られたという事にはなります。pull型だと少し話は変わりますけど。
InPortCorbaCdrProviderのput関数でデータを受け取ると、self._connector.write関数に渡しています。そしてデータを受け取ったコネクタ(InPortPushConnector)のwrite関数内でcdrUnmarshalによりCDRからデータを復号化してバッファに書き込んでいます。
つまり新たにInPort~Consumer、InPort~Providerクラスを作成したとして、既にCDRに符号化したデータの通信する方法を変更する事ぐらいしか出来ないので、データを直接変数に書き込もうとした場合などはOpenRTM-aistのソースコード自体を変更するしかありません。
このコードではInPortTestConsumerクラスでput関数を定義してファイルにデータを書き込み→InPortTestProviderクラスのput関数内でファイルを読み込むという事をやっています。
ファイル名を別に送信していますが、実際にはコネクタプロファイルで設定できた方が効率的だとは思います。
今回は実験のためにInPortCorbaCdrProviderクラスとInPortCorbaCdrConsumerクラスを継承して作成しましたが、実際にはInPortProviderクラスとInPortConsumerクラスを継承して作成する事にはなると思います。
独自の通信方法を実装する場合は①あまり複雑にしない事、②仕様書を用意する事が必要かもしれないです。でないと他の言語で実装ができません。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
Push型の通信、OpenRTM-aistのPython版を前提にしていますが、C++版でも手順はほぼ同じです。
まずはOpenRTM-aistのPython版に含まれるInPortCorbaCdrConsumer.py、InPortCorbaCdrProvider.pyのクラスを継承したクラスを作成します。
とりあえず、InPortTestConsumer.py、InPortTestProvider.pyというファイルを作成してください。
後は適当にこんな感じでコードを書いておきます。
InPortTestConsumer.py
import OpenRTM_aist
class InPortTestConsumer(OpenRTM_aist.InPortCorbaCdrConsumer):
def __init__(self):
OpenRTM_aist.InPortCorbaCdrConsumer.__init__(self)
def InPortTestConsumerInit(manager):
factory = OpenRTM_aist.InPortConsumerFactory.instance()
factory.addFactory("test",
InPortTestConsumer,
OpenRTM_aist.Delete)
InPortTestProvider.py
import OpenRTM_aist
class InPortTestProvider(OpenRTM_aist.InPortCorbaCdrProvider):
def __init__(self):
OpenRTM_aist.InPortCorbaCdrProvider.__init__(self)
self.setInterfaceType("test")
def InPortTestProviderInit(manager):
factory = OpenRTM_aist.InPortProviderFactory.instance()
factory.addFactory("test",
InPortTestProvider,
OpenRTM_aist.Delete)
次にInPortTestConsumer、InPortTestProviderのファクトリを登録しておく必要があるため、rtc.confのmanager.modules.preloadにInPortTestConsumer.py, InPortTestProvider.pyを記述しておくことで上記の初期化関数を呼び出します。
ただInPortCorbaCdrConsumer.py、InPortCorbaCdrProvider.pyの初期化関数には引数がないためrtc.confのmanager.modules.preloadに記述するとエラーが出て読み込めないみたいです。上のコードで使いもしないのにmanagerの引数を用意しているのはそのためです。
これで準備完了です。
適当なRTCを起動してデータポートを接続してください。
上手くできていればRTシステムエディタのコネクタプロファイル設定のInterface Typeにtestが追加されているはずなので、これを選択してコネクタを接続してください。
後はいつもどおり通信できていれば成功です。
ただ今回はInPortCorbaCdrProvider、InPortCorbaCdrConsumerを継承して作成しただけなので、通常の通信方法と何も変わりません。
独自の通信方法を実装するために詳細を見ていきます。
とりあえずRTC_A、RTC_Bの2つのコンポーネントがあって、RTC_AからRTC_Bにデータを送信するという事にします。
まず最初OutPortConnector.pyのwrite関数を見てください。
cdrMarshal関数でデータを符号化した後にself._publisher.write関数に渡しています。
この時点でデータはCDRというバイト列に変換されています。
当然ですがこの時点ではまだデータはRTC_A側にあります。
その後、データはInPortCorbaCdrConsumerのput関数に渡されます。
put関数を見てみると、引数のdataをinportcdr.put関数に渡しています。
inportcdrはDataPort.idlで定義されたInPortCdrのオブジェクトリファレンスなので、これを使ってInPortCorbaCdrProviderのput関数を呼び出しているという事になります。
つまりこの時点でRTC_AからRTC_Bにデータが送られたという事にはなります。pull型だと少し話は変わりますけど。
InPortCorbaCdrProviderのput関数でデータを受け取ると、self._connector.write関数に渡しています。そしてデータを受け取ったコネクタ(InPortPushConnector)のwrite関数内でcdrUnmarshalによりCDRからデータを復号化してバッファに書き込んでいます。
つまり新たにInPort~Consumer、InPort~Providerクラスを作成したとして、既にCDRに符号化したデータの通信する方法を変更する事ぐらいしか出来ないので、データを直接変数に書き込もうとした場合などはOpenRTM-aistのソースコード自体を変更するしかありません。
このコードではInPortTestConsumerクラスでput関数を定義してファイルにデータを書き込み→InPortTestProviderクラスのput関数内でファイルを読み込むという事をやっています。
ファイル名を別に送信していますが、実際にはコネクタプロファイルで設定できた方が効率的だとは思います。
今回は実験のためにInPortCorbaCdrProviderクラスとInPortCorbaCdrConsumerクラスを継承して作成しましたが、実際にはInPortProviderクラスとInPortConsumerクラスを継承して作成する事にはなると思います。
独自の通信方法を実装する場合は①あまり複雑にしない事、②仕様書を用意する事が必要かもしれないです。でないと他の言語で実装ができません。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
PR
前回のomniORBでSSLを使う方法について色々と補足をしておきます。
まず色々試した結果、以下のようなエラーが出るかもしれない事が分かりました。
まず①ですが-ORBsslVerifyMode noneというオプションをORB初期化時に追加すれば一応は消えます。あまり良くはないだろうけど、試すだけならこれでも大丈夫です。
②ですが、これはOpenSSLのバージョンが新しいと発生するみたいです。なんでもOpenSSLの新しいバージョンではDHパラメータが2048bit必要だから発生するらしいけど、どこで設定するのかは不明です。詳しい人は教えてください。1.0.2は駄目で、0.9.8は大丈夫みたいなのでこれをインストールしてください。
③ですが、これは秘密鍵の長さが短い場合に発生するみたいです。512bitだと発生するので1024bit以上にしておけば大丈夫だとは思います。
とりあえず手順を纏めておきます。
Python、omniORBpyはインストール済みと言う事で話を進めます。
まずはここからOpenSSLの0.9.8をインストールしてください。
一応、インストールしたディレクトリ(C:\OpenSSL\bin\)にパスを通しておくと便利かもしれないです。
簡単な動作確認のプログラムを作成したので、ここからダウンロードしてください。
予めネーミングサービスを起動しておいてください。
test_srv.py(サーバー)を起動した後に、test_clt.py(クライアント)を起動して通信ができていれば成功しているはずです。
SSLのよる通信を自作のプログラムで使用するまでの手順を説明します。
まずは証明書、秘密鍵を作成する必要があるので以下のコマンドで作成してください。
次にソースコードを見ていきます。
まずは何にせよsslTPをインポートします。
from omniORB import sslTP
次に証明書、秘密鍵、パスワードを設定してください。
これで準備完了です。
他に変更する点はありません。
ただ、これでは本当にSSLで暗号化して通信しているのかは謎です。
一応、ORBtraceLevelオプションを25にして詳細まで表示するようにすれば、
クライアントサーバー
と言う風な感じでSSLで通信しているらしいという事は分かるのですが、実態がどうなっているかは謎です。確認する方法があれば教えてください。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
まず色々試した結果、以下のようなエラーが出るかもしれない事が分かりました。
① omniORB: openSSL error detected in sslAddress::connect. Reason: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
② omniORB: openSSL error detected in sslAddress::connect. Reason: error:14082174:SSL routines:ssl3_check_cert_and_algorithm:dh key too small
③omniORB: openSSL error detected in SSL accept from giop:ssl:[::ffff:192.168.0.2]:58767 : error:04075070:rsa routines:RSA_sign:digest too big for rsa key
まず①ですが-ORBsslVerifyMode noneというオプションをORB初期化時に追加すれば一応は消えます。あまり良くはないだろうけど、試すだけならこれでも大丈夫です。
②ですが、これはOpenSSLのバージョンが新しいと発生するみたいです。なんでもOpenSSLの新しいバージョンではDHパラメータが2048bit必要だから発生するらしいけど、どこで設定するのかは不明です。詳しい人は教えてください。1.0.2は駄目で、0.9.8は大丈夫みたいなのでこれをインストールしてください。
③ですが、これは秘密鍵の長さが短い場合に発生するみたいです。512bitだと発生するので1024bit以上にしておけば大丈夫だとは思います。
とりあえず手順を纏めておきます。
Python、omniORBpyはインストール済みと言う事で話を進めます。
まずはここからOpenSSLの0.9.8をインストールしてください。
一応、インストールしたディレクトリ(C:\OpenSSL\bin\)にパスを通しておくと便利かもしれないです。
簡単な動作確認のプログラムを作成したので、ここからダウンロードしてください。
予めネーミングサービスを起動しておいてください。
test_srv.py(サーバー)を起動した後に、test_clt.py(クライアント)を起動して通信ができていれば成功しているはずです。
SSLのよる通信を自作のプログラムで使用するまでの手順を説明します。
まずは証明書、秘密鍵を作成する必要があるので以下のコマンドで作成してください。
openssl genrsa 1024 > private-key.key
openssl req -new -key private-key.key > private-key.csr
openssl x509 -days 3650 -req -signkey private-key.key < private-key.csr > certs.crt
名前は適当に変更してください。次にソースコードを見ていきます。
まずは何にせよsslTPをインポートします。
from omniORB import sslTP
次に証明書、秘密鍵、パスワードを設定してください。
sslTP.certificate_authority_file("certs.crt")
sslTP.key_file("private-key.key")
sslTP.key_file_password("test")
そしてSSLを有効にするためにオプションを追加します。
os.environ['ORBendPoint'] = 'giop:ssl::'
os.environ['ORBsslVerifyMode'] = 'none'
そしてSSLを有効にするためにオプションを追加します。
sys.argv.extend(["-ORBendPoint","giop:ssl::"])
さらに証明書がいい加減でも通信できるように以下のような記述を追加します。
さらに証明書がいい加減でも通信できるように以下のような記述を追加します。
sys.argv.extend(["-ORBsslVerifyMode","none"])
※小技ですが、以下のように環境変数でも設定できます。os.environ['ORBendPoint'] = 'giop:ssl::'
os.environ['ORBsslVerifyMode'] = 'none'
これで準備完了です。
他に変更する点はありません。
ただ、これでは本当にSSLで暗号化して通信しているのかは謎です。
一応、ORBtraceLevelオプションを25にして詳細まで表示するようにすれば、
クライアント
omniORB: Scavenger task execute.
omniORB: LocateRequest to remote: root<0>
omniORB: Client attempt to connect to giop:ssl:192.168.0.2:63241
omniORB: Client opened connection to giop:ssl:192.168.0.2:63241
omniORB: sendChunk: to giop:ssl:192.168.0.2:63241 38 bytes
omniORB: inputMessage: from giop:ssl:192.168.0.2:63241 20 bytes
omniORB: Send codeset service context: (ISO-8859-1,UTF-16)
omniORB: sendChunk: to giop:ssl:192.168.0.2:63241 110 bytes
omniORB: inputMessage: from giop:ssl:192.168.0.2:63241 46 bytes
omniORB: Accepted connection from giop:ssl:[::ffff:192.168.0.2]:63278 because of
this rule: "* unix,ssl,tcp"
omniORB: inputMessage: from giop:ssl:[::ffff:192.168.0.2]:63278 38 bytes
omniORB: Handling a GIOP LOCATE_REQUEST.
omniORB: sendChunk: to giop:ssl:[::ffff:192.168.0.2]:63278 20 bytes
omniORB: inputMessage: from giop:ssl:[::ffff:192.168.0.2]:63278 110 bytes
omniORB: Receive codeset service context and set TCS to (ISO-8859-1,UTF-16)
echoString() called with message: Hello from Python
omniORB: sendChunk: to giop:ssl:[::ffff:192.168.0.2]:63278 46 bytes
omniORB: Scanning Python thread states.
と言う風な感じでSSLで通信しているらしいという事は分かるのですが、実態がどうなっているかは謎です。確認する方法があれば教えてください。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
最近知った事をメモしていきます。
まずomniORBpyでSSLでの保護を有効にする手順をメモします。
最初にをsslTPインポートしてください。
from omniORB import sslTP
この際にdll load failedが出る場合はOpenSSLをインストールしてください。
次にこんな感じで鍵ファイル、パスワードを指定してください。
ORB_initの前に記述するようにしてください。
そしてORB_initのオプションに-ORBendPoint giop:ssl::を追加すれば有効になっているらしい。
有効になっているかどうかをどう確認するのかは分かりませんけど。
次にオブジェクトリファレンスからサーバントを取得する方法です。
このコードのonExecuteみたいにするだけです。
Pythonだから簡単に見えますけど、C++だとダイナミックキャストをする必要があるので簡単ではありません。特にサービスポートの場合は難しいように思います。required側では実態が分からないのでどうすればキャストできるのでしょうね?
CORBAの初歩らしいので今更感がするのですが、実際に使ったことがなかったのであまり理解していませんでした。まあ知ったかぶりしてもいい事なんてないし。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
まずomniORBpyでSSLでの保護を有効にする手順をメモします。
最初にをsslTPインポートしてください。
from omniORB import sslTP
この際にdll load failedが出る場合はOpenSSLをインストールしてください。
次にこんな感じで鍵ファイル、パスワードを指定してください。
ORB_initの前に記述するようにしてください。
sslTP.certificate_authority_file("root.pem")
sslTP.key_file("client.pem")
sslTP.key_file_password("password")
鍵ファイルはOpenSSLで適当に作成してください。そしてORB_initのオプションに-ORBendPoint giop:ssl::を追加すれば有効になっているらしい。
有効になっているかどうかをどう確認するのかは分かりませんけど。
次にオブジェクトリファレンスからサーバントを取得する方法です。
このコードのonExecuteみたいにするだけです。
Pythonだから簡単に見えますけど、C++だとダイナミックキャストをする必要があるので簡単ではありません。特にサービスポートの場合は難しいように思います。required側では実態が分からないのでどうすればキャストできるのでしょうね?
CORBAの初歩らしいので今更感がするのですが、実際に使ったことがなかったのであまり理解していませんでした。まあ知ったかぶりしてもいい事なんてないし。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
とりあえず色々と言い忘れたことがあったみたいです。
まず便利ツール賞、SUGAR SWEET ROBOTICS賞、組込みシステム技術協会賞賞を頂きました。
賞を提供してくださった方々には感謝します。
それから名刺をたくさんもらいました。僕は名刺を持っていなかったので無礼を働いてしまったことをお詫びします。
ここで伝えるのもおかしいですが、メールは以下のアドレスにお願いします。
見て分かる通り上のふざけたメールアドレスは趣味用です。真面目な話は下のメールアドレスにお願いします。
あと個人的にメールアドレスを伝えなければならない人がいるので、後でメールを送ります。
まああんまり夜中に送ると迷惑かもしれないので明日にしますけど。
RTMコンテスト2010でコンテスト運営の人に深夜4時にメールを送ったらすぐにメールが返ってきて内心ビクビクしたという事があったので、それ以来夜中にメールは送らないようにしています。
懇談会では大変有意義なおしゃべりができました。
明日もRTシステムとオープン化には寝坊しなければ行くのでよろしくお願いします。
それから発表会では大学院の時の後輩に偶然再会しました。
まさかこんなところで会うとは思っていませんでした。
ここからは他の作品の感想、というか悪口です。
正直、発表前日まではこういう審査結果になるとは思っていませんでした。
この作品がそんなに高評価になるとは全く思っていなかったのですが、実験をするのに命がかかっていたのなら仕方がないかもしれません。
正直僕はソースコードを読んだ感じで絶対に乗りたくないと思っていたのですが、それだけの危険を冒して実験を繰り返したのは評価できるかもしれないです。出川哲朗でもなかなかここまでは体を張ることはないと思います。
(追記)念のために言っておきますが、貶そうとする意図はありません。一回実験するのに数十メートルの範囲から人を遠ざける必要があるわけで、かなり大変だったと思います。一度バグを出せば命を落とす可能性がありますからね。まさに死と隣り合わせです。僕が研究を指導する立場の人間だったら実験を許可しません。
あとはこの作品が高評価だったのも意外でした。
ソースコードを読んだ感じで正しく動作できていないのではないかと思っていたので、発表前の僕個人の評価はあまり高くありませんでした。そうやら僕は発表前まで勘違いをしていたらしく、作品自体ではなくてコミュニティ的活動がメインだったみたいですね。それなら分かるような気がします。
コミュニティ的活動もそうですけど、授業で使ってもらったとか、どこかで展示したとかはかなり評価が難しいように思います。
人に使ってもらうためにコンテストに参加してプロジェクトページを作っているのに、他で使ってもらったから評価が高くなるというのは何かが破綻しています。
上の作品みたいにコミュニティ的な活動がメインでその結果こういう作品ができたという順序なら理解できますけど、作品を作ってそれをどこかで使ってもらったから評価してほしいというのはよく分かりません。プロジェクトページに公開した時点で不特定多数の人が使えるようになっていると思うのですが。
まあ完全な負け惜しみなので、聞き流してもらっていいですけど。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
まず便利ツール賞、SUGAR SWEET ROBOTICS賞、組込みシステム技術協会賞賞を頂きました。
賞を提供してくださった方々には感謝します。
それから名刺をたくさんもらいました。僕は名刺を持っていなかったので無礼を働いてしまったことをお詫びします。
ここで伝えるのもおかしいですが、メールは以下のアドレスにお願いします。
見て分かる通り上のふざけたメールアドレスは趣味用です。真面目な話は下のメールアドレスにお願いします。
あと個人的にメールアドレスを伝えなければならない人がいるので、後でメールを送ります。
まああんまり夜中に送ると迷惑かもしれないので明日にしますけど。
RTMコンテスト2010でコンテスト運営の人に深夜4時にメールを送ったらすぐにメールが返ってきて内心ビクビクしたという事があったので、それ以来夜中にメールは送らないようにしています。
懇談会では大変有意義なおしゃべりができました。
明日もRTシステムとオープン化には寝坊しなければ行くのでよろしくお願いします。
それから発表会では大学院の時の後輩に偶然再会しました。
まさかこんなところで会うとは思っていませんでした。
ここからは他の作品の感想、というか悪口です。
正直、発表前日まではこういう審査結果になるとは思っていませんでした。
この作品がそんなに高評価になるとは全く思っていなかったのですが、実験をするのに命がかかっていたのなら仕方がないかもしれません。
正直僕はソースコードを読んだ感じで絶対に乗りたくないと思っていたのですが、それだけの危険を冒して実験を繰り返したのは評価できるかもしれないです。出川哲朗でもなかなかここまでは体を張ることはないと思います。
(追記)念のために言っておきますが、貶そうとする意図はありません。一回実験するのに数十メートルの範囲から人を遠ざける必要があるわけで、かなり大変だったと思います。一度バグを出せば命を落とす可能性がありますからね。まさに死と隣り合わせです。僕が研究を指導する立場の人間だったら実験を許可しません。
あとはこの作品が高評価だったのも意外でした。
ソースコードを読んだ感じで正しく動作できていないのではないかと思っていたので、発表前の僕個人の評価はあまり高くありませんでした。そうやら僕は発表前まで勘違いをしていたらしく、作品自体ではなくてコミュニティ的活動がメインだったみたいですね。それなら分かるような気がします。
コミュニティ的活動もそうですけど、授業で使ってもらったとか、どこかで展示したとかはかなり評価が難しいように思います。
人に使ってもらうためにコンテストに参加してプロジェクトページを作っているのに、他で使ってもらったから評価が高くなるというのは何かが破綻しています。
上の作品みたいにコミュニティ的な活動がメインでその結果こういう作品ができたという順序なら理解できますけど、作品を作ってそれをどこかで使ってもらったから評価してほしいというのはよく分かりません。プロジェクトページに公開した時点で不特定多数の人が使えるようになっていると思うのですが。
まあ完全な負け惜しみなので、聞き流してもらっていいですけど。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
何事もなく負けました。
まあこうなるとは思っていましたけど。
今のところ来年は参加しない予定です。
四国のどこかでRTM講習会をやるなら考えますけど。
そういえば結局、去年の例の作品は受賞取り消しになったみたいですね。
あまりにも悪質だったので仕方ないとは思います。
ひょっとしたら恨まれているかもしれないので、ちょっと過激な発言は控えようかと思います。
と言うわけで、明日からは何も書きません。
無を書くという新ジャンルに挑戦します。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・
まあこうなるとは思っていましたけど。
今のところ来年は参加しない予定です。
四国のどこかでRTM講習会をやるなら考えますけど。
そういえば結局、去年の例の作品は受賞取り消しになったみたいですね。
あまりにも悪質だったので仕方ないとは思います。
ひょっとしたら恨まれているかもしれないので、ちょっと過激な発言は控えようかと思います。
と言うわけで、明日からは何も書きません。
無を書くという新ジャンルに挑戦します。
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・