忍者ブログ
ロボット、千葉ロッテマリーンズについていいかげんなことを書きます。
[1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]  [9
なんだか最近、いろんなサイト上にペーパークラフトの兜を作ってサッカー日本代表を応援しようとか言う広告が出てくるのですが、流行らないものを無理やり流行らせようとしているごり押し感しかしないため非常に不快です。



それはさておき、RTM講習会等でファイアウォールを切れとか強要されますが、多分嫌な人もいるかもしれないので、ファイアウォールを切らなかった場合の動作について説明します。

まず、以下のように2台のマシンを用意してマシン1ではファイアウォールが有効、マシン2ではファイアウォールが無効の場合を考えます。

なお、RTシステムエディタがマシン2で動作している場合は、マシン2側からポート1への接続がブロックされるためコネクタの接続は不可能です。






コネクタを接続するときのシーケンス図が以下のようになっています。
RTシステムエディタからポート1のconnect関数を呼び出して、さらにポート1は内部のnotify_connect関数を呼び出します。さらにポート1からポート2のnotify_connect関数を呼び出すという流れになっています。
この場合はポート1からポート2に接続しにいっているので、問題なく接続できます。






しかし、以下のようにコネクタプロファイルに登録したポートのリストの順番が変わりポート2がポート1のnotify_connect関数を呼び出す場合は、ファイアウォールにブロックされるため接続できません。




RTシステムエディタがポート2のconnect関数を呼び出した場合も、ポート2からポート1のnotify_connect関数がリモート呼び出しできないため接続不可です。






このためファイアウォールを有効にした場合のポートの接続には注意が必要ですが、現状RTシステムエディタの機能としてどちらのポートのconnect関数を呼ぶのか、ポートの登録順をどうするかなどの設定はできないため、自分で接続するためのコードを書くしかありません。






そしてデータ転送時の動作ですが、以下のようにPush型接続で通信する場合、マシン1からマシン2に接続しにいくので、問題なく接続できます。







これがPull型接続の場合にはマシン2からマシン1に接続しにいくのでブロックされます。





マシン2でファイアウォールが有効になっている場合、Push型接続はマシン1からマシン2に接続しにいくのでブロックされます。






Pull型接続の場合はマシン2からマシン1に接続しにいくので、問題なく通信できます。








このため、以下のようにインポート、アウトポートでPush型、Pull型を使い分けることで、ファイアウォールが有効な場合でも理論上は通信ができます。








なぜ理論上はと言ったかというと、現状のOpenRTM-aistの実装の問題によりマシン2からマシン1に接続しにいく場合があるからです。

OpenRTM-aistはポートのプロファイル取得時等にポートのオブジェクトの存在確認を行い、オブジェクトが存在しない場合は切断するという処理を実行しています。
マシン2のRTCでその処理が実行された場合、オブジェクトの存在確認時にマシン1へ接続しにいってしまうためブロックされてしまいます。







ちなみにファイアウォールを有効にした場合でも何故か外部のRTCと接続できたり、ネットワークを切り替えたら通信できなくなる場合がありますが、単純にファイアウォールの設定が原因であることが多いです。このページの手順で確認すると、例えばPythonはプライベートがチェックされていて、パブリックにはチェックが無い場合があります。このためパブリックネットワークに接続した場合はファイアウォールにブロックされてしまいます。




ちなみにサービスポートを使用する場合、マシン2のRTCからマシン1のRTCのサービスは呼び出すことはできないため注意が必要になります。


マシン1、マシン2でファイアウォールが有効の場合は、通常の方法では相互通信はできません。
会津大が開発しているようなメッセージブローカをサーバーに配置する仕組みが必要になります。
ただし、この場合でもRTシステムエディタからの操作、サービスポートの利用はできないため、何かしら新しい仕組みが必要になります。


と言うか、ここまで長々と説明しておいてなんですが、ポート番号指定でRTCを起動してもらってファイアウォールの設定してもらう方が簡単です。


そうした場合に外部からRTCを操作されてしまう可能性があるわけですが、ファイアウォールで特定IPアドレス以外制限するようにして、さらにSSL暗号化を有効にしてもらうぐらいしか対策は無いです。




違う話になりますが、以下のようにマシン1とマシン2が内部ネットワークにある場合は、現状のOpenRTM-aistの仕組みでは通信できないため諦めましょう。




ポートフォワーディングを設定したらできるかもしれませんが、両方のルーターで設定する必要があるためあまり現実的ではないように思います。
どうしてもこの構成で通信したかったら、メッセージブローカを配置したサーバーを作るか、UDPホールパンチングをするデータポートでも作ってもらうしかなさそうです。あるいはVPN接続するというのはOpenRTMでは昔から行われているようですが、それも色々と面倒くさいのであまりやりたくありません。メッセージブローカのサーバーを使う場合は誰かが用意したものを使うという選択肢もありますが、VPNを使う場合は自前で色々と準備しなければならないのであまりお勧めはできません。



ちなみに、片方のマシンが外部からアクセスできる場合は、Pull型通信を駆使することで通信できます。理論上はですが。












にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
PR
昨日、OiLのマーシャリング、アンマーシャリングの話をしましたが、あの問題は解決しました。

やはりアラインメントの問題だったのですが、OiLの以下の部分の-1を-2に変更したら解決しました。そりゃ1つ位置がずれていたら、アラインメントのために移動するポインタの位置が変わってしまうので上手くいくはずがありません。



local function alignment(self, size)
local extra = (self.cursor-1)%size
if extra > 0 then return size-extra end
return 0
end









ただOiLのソースコードのこの部分を変更すると他にも影響が出る可能性があるため、OpenRTM内でalign関数を差し替えています。

理屈ではポインタの初期位置を一つ前にするだけで良さそうなのですが、何故かアンマーシャリングが上手くいきません。



これでCameraImage型の通信もできるようになったので、以下のようにOpenResty上で起動したRTCが画像データを受け取ってWEBブラウザで表示することもできます。






昨日ver.0.2.1をリリースしたのですが、舌の根も乾かないうちに0.2.2をリリースするのは面倒なので、こっそりファイルだけ差し替えます。どうせ誰もダウンロードしていないだろうと思います。というかいたら気持ち悪い











にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
以前の記事でUSBラズパイとかいう製品の存在価値が分からないと言いましたが、案の定叩かれているようです。そりゃそうだよなあ。買うことを検討している人は考え直したほうがいいと思う。


それはさておき。OiLのマーシャリング、アンマーシャリングの動作がどうにも不可解なので調べてみます。
CDRの先頭に1,255,255,255という謎の値がくっついているのは以前言った通りなのですが、TimedVelocity2D型、CameraImage型等で調べたところ、他の部分にも謎の値が挿入されてしまいます。

まずTimedVelocity2D型をマーシャリングすると以下のようになります。
格納されている値は全て0に設定してあるため、全て0になるはずですが、13~16にかけて255という値が挿入されています。


位置  値
1       1
2       255
3       255
4       255
5       0
6       0
7       0
8       0
9       0
10      0
11      0
12      0
13      255
14      255
15      255
16      255
17      0
18      0
19      0
20      0
21      0
22      0
23      0
24      0
25      0
26      0
27      0
28      0
29      0
30      0
31      0
32      0
33      0
34      0
35      0
36      0
37      0
38      0
39      0
40      0



CameraImage型は以下のようになります。
これも全て0になるはずですが、255が挿入されています。

位置  値
1       1
2       255
3       255
4       255
5       0
6       0
7       0
8       0
9       0
10      0
11      0
12      0
13      0
14      0
15      0
16      0
17      0
18      0
19      255
20      255
21      1
22      0
23      0
24      0
25      0
26      255
27      255
28      255
29      255
30      255
31      255
32      255
33      0
34      0
35      0
36      0
37      0
38      0
39      0
40      0
41      0
42      0
43      0
44      0

TimedVelocity2D型について推測すると、structの変数の前に255が挿入されると推測されます。

位置  値
------------------------
1       1
2       255
3       255
4       255
------------------------
Time(sec):unsigned long
5       0
6       0
7       0
8       0
------------------------
Time(nsec):unsigned long
9       0
10      0
11      0
12      0
------------------------
13      255
14      255
15      255
16      255
------------------------
Velocity2D(vx):double
17      0
18      0
19      0
20      0
21      0
22      0
23      0
24      0
------------------------
Velocity2D(vy):double
25      0
26      0
27      0
28      0
29      0
30      0
31      0
32      0
------------------------
Velocity2D(va):double
33      0
34      0
35      0
36      0
37      0
38      0
39      0
40      0
------------------------


CameraImage型は以下のようになります。
位置  値
------------------------
1       1
2       255
3       255
4       255
------------------------
Time(sec):unsigned long
5       0
6       0
7       0
8       0
------------------------
Time(nsec):unsigned long
9       0
10      0
11      0
12      0
------------------------
width:unsigned short
13      0
14      0
------------------------
height:unsigned short
15      0
16      0
------------------------
bpp:unsigned short
17      0
18      0
------------------------
19      255
20      255
------------------------
format:string
21      1
22      0
23      0
24      0
25      0
------------------------
26      255
27      255
28      255
29      255
30      255
31      255
32      255
------------------------
fDiv::double
33      0
34      0
35      0
36      0
37      0
38      0
39      0
40      0
------------------------
pixels:sequence<octet>
41      0
42      0
43      0
44      0



なるほど。全く分かりません。アラインメントの問題なのでしょうか?

というわけで、OiLのalign関数をただ0を返す関数に置き換えました。



encoder.align = function(...)return 0 end







これで上記の255が消えて全て上手くいく・・・と思ったのですが、CameraImage型はomniORB等でマーシャリングするとアラインメントのためかbppとformatの間に0が2個入るため上手くいきません。この問題を解決するのは容易ではありません。


まあでも、これでとりあえずほとんどのデータ型で通信できるようになったはずなので、修正版0.2.1をリリースしました









にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
USBラズパイなるものが発売されるらしいけど、一体ラズパイエミュレータと比べて何の利点があるのだろう・・・
一本9800円も払うんだったら普通にラズパイ買うだろうし、謎です。この製品を貶したいのではなく、ただ純粋に疑問です。



それはさておき、Dynamixel XM430-W350-RをOpenCM9.04-C+OpenCM 485拡張ボードに接続して動作確認しようとしたのですが、かなり詰まる部分があったのでメモしておきます。


まず、OpenCM9.04を使うにあたりOpenCM IDEを使って動作確認しようとしたのですが、これが何故か上手くいきませんでした。サンプルコードのDXL_BUS_SERIAL1を拡張ボード用にDXL_BUS_SERIAL3に変更してもピクリとも動きません。ボーレートを変更しても関係ないようです。Dynamixel 2.0のプロトコルに対応していないのか、XMシリーズが駄目なのかは謎です。


一旦RoboPlusでOpenCM9.04のファームウェアを修復後、RoboPlus 2.0 Managerで確認してみました。

まず、Dynamixel XM430-W350-R、OpenCM9.04-C、OpenCM 485拡張ボードを以下のように接続します。USBケーブルはPCと接続してください。





拡張ボードの電源は以下のスイッチでオンオフができます。
オンにするとXM430-W350-RのLEDが一回点滅します。
点滅しなかった場合はバッテリーが壊れている可能性があります。ちなみに画像に映っているバッテリーですが、一度も使っていないのに既に壊れています。








R+ Manager 2.0を起動後、アップデートするかどうか聞かれた場合はアップデートしてください。

アップデート後は、R+ Manager 2.0起動後に以下の画面が表示されます。






ProductからDYNAMIXEL Xを選んで○を押してください。




次に以下の画面でUpdate & Testを選んでください。







Nextを選んでいくとポート番号の選択画面に移行するため、適切なポートを選択してください。
OpenCM9.04-Cを直接接続した場合はROBOTIS Virtual COM Portと表示されるのでわかるとは思いますが、USBダウンローダーLN-101で接続するとUSB Serial Port(1.0)としか表示されないので分かり辛いかもしれません。






その後Nextを押していくとOpenCM9.04-Cと接続します。
本来であればXM-430-W350も表示されるはずですが、設定を変更しないと表示されません。

Control Tableで、Dynamixel ChannelをEXP Board(XH/XM)に変更してください。




それからBand Rate (Bus)を57600bpsに変更してください。




この後に、一旦Update & Testを×ボタンで終了後、OpenCM9.04-Cをリセット、OpenCM 485拡張ボードの電源を落として再起動、再度Update & TestによりOpenCM9.04-Cと接続すると、Device一覧にXM430-W350が表示されます。




表示されない場合はOpenCM9.04-cのリセットボタンを押して再起動、拡張ボードの電源を入れ直すなどで接続できるかもしれません。



Control Table画面でXM430-W350-Rの状態を確認できます。
Torque EnableをONにした後、Goal Positionの値を操作することでモーターが動作します。










独自のプログラムでXM430-W350-Rを操作する場合は、Dynamixel Protocol 2 Libraryというライブラリがあるようなのでこれを使います。Dynamixel SDKというライブラリもあるようなのですが、XMシリーズが動くかどうかは不明です。libdynamixelは大丈夫みたいです。と言うかなんでこんなに乱立しているんだ。



とりあえず、CMake設定ファイルを以下のように作成します。ファイル名は適当に変更してください。


cmake_minimum_required(VERSION 2.8)


set(DX2LIB_ROOT ${DX2LIB_ROOT} CACHE PATH "set DX2LIB_ROOT ")

if(NOT DX2LIB_ROOT)
message(FATAL_ERROR "Please set DX2LIB_ROOT.")
endif()





project (DXLTest)

include_directories(${DX2LIB_ROOT})
link_directories(${DX2LIB_ROOT})

add_executable(DXLTest DXLTest.cpp)
target_link_libraries(DXLTest dx2lib_x32.lib)cmake_minimum_required(VERSION 2.8)


set(DX2LIB_ROOT ${DX2LIB_ROOT} CACHE PATH "set DX2LIB_ROOT ")

if(NOT DX2LIB_ROOT)
message(FATAL_ERROR "Please set DX2LIB_ROOT.")
endif()





project (DXLTest)

include_directories(${DX2LIB_ROOT})
link_directories(${DX2LIB_ROOT})

add_executable(DXLTest DXLTest.cpp)
target_link_libraries(DXLTest dx2lib_x32.lib)


















DXLTest.cppには、とりあえずライブラリを展開したフォルダのSampleCode\VC\smpl1(template).cの中身をコピーします。

ただ何故かエラーが出るので、DXDEVICEIDをTDeviceIDに変更します。



DXDEVICEID dev;

TDeviceID dev;
















後は適当にモーターを操作するコードを追加します。



TErrorCode err;

//トルクをオンにする
DX2_WriteByteData(dev, 1, 64, 1, &err);
Sleep(1000);
//90度の位置に回転
DX2_WriteLongData(dev, 1, 116, 3072, &err);
Sleep(1000);
//-90度の位置に回転
DX2_WriteLongData(dev, 1, 116, 1024, &err);
Sleep(1000);
//トルクをオフにする
DX2_WriteByteData(dev, 1, 64, 0, &err);














詳細については仕様を見ながら試すしかなさそうです。
そう考えるとlibdynamixel使った方が良かったかもしれません。
libdynamixelだと以下のようになります。



DynamixelV2 m("\\\\.\\COM3", 1000000));
m.TorqueEnable(1);
Sleep(1000);
m.MovePosition(1, 1024);
Sleep(1000);
m.MovePosition(1, 3072);
Sleep(1000);
m.TorqueDisable(1);









まあ別に何のライブラリを使っても性能的には大差はないだろうし、ライセンス次第な気もします。








にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
実は今までOpenRTM-erlangを使ったことがなかったため、使い方をメモしておきます。備忘録です。このブログは首相案件ではありません。


Windowsでも試してみたのですがコンポーネントプロファイルを取得しようとした途端に落ちるため、Ubuntuで動作確認します。
まあ落ちても即座に再起動するのですが、再試行しても無駄なようなので、Windowsでの動作はとりあえず諦めます。
Windowsだからなのか、Erlang/OTPのバージョンの問題なのかは不明です。


Ubuntu 16.04でErlang/OTPはaptでインストールできます。


$ sudo apt-get install erlang




そしてOpenRTM-erlangのビルドをしますが、Erlang/OTP 18からいろいろと変わったらしく、そのままではビルドできません。
修正したものを用意したので、フォークしたリポジトリからソースコードをダウンロードしてください、

後はコマンドでmakeすればebinフォルダにbeamファイルが生成されます。


サンプルを実行するには、exampleフォルダに移動後、以下のコマンドを実行してください。


$ erl -pa ../ebin
1> openrtm_erl:start(0,[]).
2> run_sample:run().


と言ってはみたものの、これが正しい使い方かは不明です。


これでTicker0.rtcとPrinter0.rtcが通信を開始しますが、ログメッセージが大量に表示されるためよく分かりません。
ログレベルを起動時に変更する方法は分からないので、defaults.erlのrtl_paranoidの部分をrtl_silentに変更するなどして対処してください。


RT System Editorからアクティブ化をしようとしたのですが、何故か失敗しています。





確かにErlangは使ってみると面白いプログラミング言語ではあるのですが、言語仕様が気に食わないというか、コードの記述方法が気持ち悪いです。
関数の途中に「,」が入ったり、関数の最後が「.」だったりと、なかなか馴染めそうにありません。
というか、関数でアロー演算子->を使う言語は嫌いです。MoonScriptも嫌いです。
アロー演算子ではなくて、全角の→を使えと思います。それはさすがに嘘ですけど。

標準でCORBAやFSMのライブラリが入っている言語って、Erlangだけなんだろうなあ。



(追記)
UbuntuでErlang/OTP 20を使って動作確認したのですが特に問題はなかったため、Windows上で動作させることが問題のようです。Erlang/OTPのバージョンは関係ありませんでした。





にほんブログ村 科学ブログ ロボットへ
にほんブログ村のロボットのカテゴリから
全然人が来ない・・・

人気ブログランキングへ
&lt;&lt; 前のページ 次のページ &gt;&gt;
カレンダー
11 2019/12 01
S M T W T F S
1 2 3 4 5 6
9 10 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
フリーエリア
最新CM
[12/11 Nobu]
[12/11 Kanamura]
[08/24 Nobu]
[08/24 puku]
[08/22 Nobu]
プロフィール
HN:
Nobu
年齢:
31
性別:
男性
誕生日:
1988/09/22
職業:
あれ
趣味:
妄想、自堕落
バーコード
ブログ内検索
P R
カウンター
忍者ブログ [PR]