fkanehiro / hrpsys-base

Basic RT components and utilities to control robots using OpenRTM
Other
41 stars 88 forks source link

rtm.connectPortsのデフォルトパラメータについて #552

Open garaemon opened 9 years ago

garaemon commented 9 years ago

rtm.connectPortsのデフォルトパラメータですが、これらはどのような意図で選ばれているのでしょうか?

rtshellのものと少し違うように見えます.

cc: @snozawa

fkanehiro commented 9 years ago

リアルタイムプロセス内での通信を想定したデフォルト値になっています。

2015年4月3日 2:04 Ryohei Ueda notifications@github.com:

rtm.connectPorts https://github.com/fkanehiro/hrpsys-base/blob/master/python/rtm.py#L502 のデフォルトパラメータですが、これらはどのような意図で選ばれているのでしょうか?

rtshellのもの https://github.com/gbiggs/rtshell/blob/master/rtshell/rtcon.py#L37 と少し違うように見えます.

cc: @snozawa https://github.com/snozawa

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552.

garaemon commented 9 years ago

リアルタイムプロセス内というのは、二つのポートどちらも同じ実時間プロセスの中で通信することを期待しているということでしょうか?

2015年4月3日金曜日、Fumio KANEHIROnotifications@github.comさんは書きました:

リアルタイムプロセス内での通信を想定したデフォルト値になっています。

2015年4月3日 2:04 Ryohei Ueda <notifications@github.com javascript:_e(%7B%7D,'cvml','notifications@github.com');>:

rtm.connectPorts https://github.com/fkanehiro/hrpsys-base/blob/master/python/rtm.py#L502

のデフォルトパラメータですが、これらはどのような意図で選ばれているのでしょうか?

rtshellのもの https://github.com/gbiggs/rtshell/blob/master/rtshell/rtcon.py#L37 と少し違うように見えます.

cc: @snozawa https://github.com/snozawa

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552.

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89062358 .

✉︎ from iPhone

fkanehiro commented 9 years ago

はい、そうです。

2015年4月3日 10:35 Ryohei Ueda notifications@github.com:

リアルタイムプロセス内というのは、二つのポートどちらも同じ実時間プロセスの中で通信することを期待しているということでしょうか?

2015年4月3日金曜日、Fumio KANEHIROnotifications@github.comさんは書きました:

リアルタイムプロセス内での通信を想定したデフォルト値になっています。

2015年4月3日 2:04 Ryohei Ueda <notifications@github.com javascript:_e(%7B%7D,'cvml','notifications@github.com');>:

rtm.connectPorts < https://github.com/fkanehiro/hrpsys-base/blob/master/python/rtm.py#L502>

のデフォルトパラメータですが、これらはどのような意図で選ばれているのでしょうか?

rtshellのもの https://github.com/gbiggs/rtshell/blob/master/rtshell/rtcon.py#L37 と少し違うように見えます.

cc: @snozawa https://github.com/snozawa

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552.

— Reply to this email directly or view it on GitHub < https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89062358>

.

✉︎ from iPhone

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89108086 .

garaemon commented 9 years ago

rtm.connectPortsで実時間スレッドのポートと、外部の計算機のポートをつないだところ、ときどき通信が行われないという事がありました

https://github.com/start-jsk/rtmros_common/issues/690

今ポートのパラメータをデフォルトのものに変えて(rtshellを利用して)テストしています.

k-okada commented 9 years ago

@fkanehiro さん.hrpsys 内のRTC(体内の時間プロセス)と外部の計算機上のRTCとの間の通信はどのようなパラメータがいい,というのはあるでしょうか?また,外部のRTCの実行時のパラメータはなにがいい,というのもあるでしょうか? いまは -o "exec_cxt.periodic.type:PeriodicExecutionContext" -o "exec_cxt.periodic.rate:2000" (体内は500hz)としていますが,どうも無駄にCPUを食っているようで困っています.

◉ Kei Okada

2015-04-03 11:36 GMT+09:00 Ryohei Ueda notifications@github.com:

rtm.connectPortsで実時間スレッドのポートと、外部の計算機のポートをつないだところ、ときどき通信が行われないという事がありました

start-jsk/rtmros_common#690 https://github.com/start-jsk/rtmros_common/issues/690

今ポートのパラメータをデフォルトのものに変えて(rtshellを利用して)テストしています.

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89129210 .

fkanehiro commented 9 years ago

実時間から非実時間への通信は、subscriptionのタイプをflush以外にする、というのが一番重要で 後は通信の周期をアプリケーションに応じて設定するのだと思います。 実行周期もアプリ次第ではあるのですが、2000Hzとなるとほぼ休みなしで回っているイメージで 重くなるのも当然という気がします(もちろん処理内容にもよりますが)。 そんなに高周期が必要なんでしょうか?

2015年4月17日 2:22 Kei Okada notifications@github.com:

@fkanehiro さん.hrpsys 内のRTC(体内の時間プロセス)と外部の計算機上のRTCとの間の通信はどのようなパラメータがいい,というのはあるでしょうか?また,外部のRTCの実行時のパラメータはなにがいい,というのもあるでしょうか?

いまは -o "exec_cxt.periodic.type:PeriodicExecutionContext" -o "exec_cxt.periodic.rate:2000" (体内は500hz)としていますが,どうも無駄にCPUを食っているようで困っています.

◉ Kei Okada

2015-04-03 11:36 GMT+09:00 Ryohei Ueda notifications@github.com:

rtm.connectPortsで実時間スレッドのポートと、外部の計算機のポートをつないだところ、ときどき通信が行われないという事がありました

start-jsk/rtmros_common#690 https://github.com/start-jsk/rtmros_common/issues/690

今ポートのパラメータをデフォルトのものに変えて(rtshellを利用して)テストしています.

— Reply to this email directly or view it on GitHub < https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89129210>

.

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93789670 .

k-okada commented 9 years ago

ロボットのセンサ情報をROSに出していきたいので,それなりに回ってくれると嬉しいです. データが来たらonExecuteが一回回る,みたいなコードはかけないんでしたっけ? そちらでも例えば画像処理なんかはhrpsysのシリアライズに入っていない外部のRTC があるんじゃなにかと思っているんですが,どうされていますでしょうか.

あと,逆に実時間のRTCにサービスコールを呼ぶだけの,外部のRTCというのもあるんですが, これはら実行周期が例えば1Hzでも,大丈夫でしょうか?イメージとしては外部のRTCはonExecuteが 1hzでまわっていて,これとは非同期に適当なタイミングの外部のRTCから内部の実時間RTCにサービスコールをよぶのですが, このとき外部のRTCではサービスコールを呼ぶコードが実行されたらすぐに内部に信号がいくでしょうか? あるいは,なにかonExecuteの実行周期と同期したりするんでしょうか?

◉ Kei Okada

2015-04-17 6:50 GMT+09:00 Fumio KANEHIRO notifications@github.com:

実時間から非実時間への通信は、subscriptionのタイプをflush以外にする、というのが一番重要で 後は通信の周期をアプリケーションに応じて設定するのだと思います。 実行周期もアプリ次第ではあるのですが、2000Hzとなるとほぼ休みなしで回っているイメージで 重くなるのも当然という気がします(もちろん処理内容にもよりますが)。 そんなに高周期が必要なんでしょうか?

2015年4月17日 2:22 Kei Okada notifications@github.com:

@fkanehiro さん.hrpsys

内のRTC(体内の時間プロセス)と外部の計算機上のRTCとの間の通信はどのようなパラメータがいい,というのはあるでしょうか?また,外部のRTCの実行時のパラメータはなにがいい,というのもあるでしょうか?

いまは -o "exec_cxt.periodic.type:PeriodicExecutionContext" -o "exec_cxt.periodic.rate:2000" (体内は500hz)としていますが,どうも無駄にCPUを食っているようで困っています.

◉ Kei Okada

2015-04-03 11:36 GMT+09:00 Ryohei Ueda notifications@github.com:

rtm.connectPortsで実時間スレッドのポートと、外部の計算機のポートをつないだところ、ときどき通信が行われないという事がありました

start-jsk/rtmros_common#690 https://github.com/start-jsk/rtmros_common/issues/690

今ポートのパラメータをデフォルトのものに変えて(rtshellを利用して)テストしています.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89129210>

.

— Reply to this email directly or view it on GitHub < https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93789670>

.

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93847615 .

fkanehiro commented 9 years ago

ロボットのセンサ情報をROSに出していきたいので,それなりに回ってくれると嬉しいです.

それなり、がどの程度かわかりませんが、実時間RTCと外との接続の送信周期を設定すれば、 それなりに出ると思います。

データが来たらonExecuteが一回回る,みたいなコードはかけないんでしたっけ?

規格としてはイベントドリブンなRTCというのも存在しますが、実装されてませんね。 現存の機能で実現するには外部トリガ付きの実行コンテキストを割り当てて駆動したい ときにトリガをかけるということでしょうか。

そちらでも例えば画像処理なんかはhrpsysのシリアライズに入っていない外部のRTC があるんじゃなにかと思っているんですが,どうされていますでしょうか.

必要に応じて30Hzとか10Hzとかに設定しています。

あと,逆に実時間のRTCにサービスコールを呼ぶだけの,外部のRTCというのもあるんですが, これはら実行周期が例えば1Hzでも,大丈夫でしょうか?イメージとしては外部のRTCはonExecuteが 1hzでまわっていて,これとは非同期に適当なタイミングの外部のRTCから内部の実時間RTCにサービスコールをよぶのですが, このとき外部のRTCではサービスコールを呼ぶコードが実行されたらすぐに内部に信号がいくでしょうか? あるいは,なにかonExecuteの実行周期と同期したりするんでしょうか?

サービスはonExecute()を実行するのとは別のスレッドで呼ばれるので呼べばすぐに実行されます。

2015年4月17日 9:27 Kei Okada notifications@github.com:

ロボットのセンサ情報をROSに出していきたいので,それなりに回ってくれると嬉しいです. データが来たらonExecuteが一回回る,みたいなコードはかけないんでしたっけ? そちらでも例えば画像処理なんかはhrpsysのシリアライズに入っていない外部のRTC があるんじゃなにかと思っているんですが,どうされていますでしょうか.

あと,逆に実時間のRTCにサービスコールを呼ぶだけの,外部のRTCというのもあるんですが, これはら実行周期が例えば1Hzでも,大丈夫でしょうか?イメージとしては外部のRTCはonExecuteが 1hzでまわっていて,これとは非同期に適当なタイミングの外部のRTCから内部の実時間RTCにサービスコールをよぶのですが, このとき外部のRTCではサービスコールを呼ぶコードが実行されたらすぐに内部に信号がいくでしょうか? あるいは,なにかonExecuteの実行周期と同期したりするんでしょうか?

◉ Kei Okada

2015-04-17 6:50 GMT+09:00 Fumio KANEHIRO notifications@github.com:

実時間から非実時間への通信は、subscriptionのタイプをflush以外にする、というのが一番重要で 後は通信の周期をアプリケーションに応じて設定するのだと思います。 実行周期もアプリ次第ではあるのですが、2000Hzとなるとほぼ休みなしで回っているイメージで 重くなるのも当然という気がします(もちろん処理内容にもよりますが)。 そんなに高周期が必要なんでしょうか?

2015年4月17日 2:22 Kei Okada notifications@github.com:

@fkanehiro さん.hrpsys

内のRTC(体内の時間プロセス)と外部の計算機上のRTCとの間の通信はどのようなパラメータがいい,というのはあるでしょうか?また,外部のRTCの実行時のパラメータはなにがいい,というのもあるでしょうか?

いまは -o "exec_cxt.periodic.type:PeriodicExecutionContext" -o "exec_cxt.periodic.rate:2000" (体内は500hz)としていますが,どうも無駄にCPUを食っているようで困っています.

◉ Kei Okada

2015-04-03 11:36 GMT+09:00 Ryohei Ueda notifications@github.com:

rtm.connectPortsで実時間スレッドのポートと、外部の計算機のポートをつないだところ、ときどき通信が行われないという事がありました

start-jsk/rtmros_common#690 https://github.com/start-jsk/rtmros_common/issues/690

今ポートのパラメータをデフォルトのものに変えて(rtshellを利用して)テストしています.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89129210>

.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93789670>

.

— Reply to this email directly or view it on GitHub < https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93847615>

.

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93867614 .

k-okada commented 9 years ago

周期は体内が200-500hzとして同じぐらいをかんがえいます。 いまは https://github.com/start-jsk/rtmros_common/blob/master/hrpsys_ros_bridge/src/HrpsysSeqStateROSBridge.cpp#L260 みたいなコードでisNewだったら処理して、、、みたいにしていて、取りこぼしがないようにするとなると受け取り側を1000hzぐらいで回さないと、と思ってプログラムを書いています。

いま一つrtcの周期と通信の周期の違いがわかっていないですが体内が200hzで回ることが分かっていれば通信も200でよくて、rtcは余裕をみてまわすのが正しいでしょうか?それともrtcも200かちょっと上にしてでデータはqueueにたまるかもしれないけどいずれisNew->readされる感じでしょうか?

◉ Kei Okada

2015/04/17 9:38、Fumio KANEHIRO notifications@github.com のメッセージ:

ロボットのセンサ情報をROSに出していきたいので,それなりに回ってくれると嬉しいです.

それなり、がどの程度かわかりませんが、実時間RTCと外との接続の送信周期を設定すれば、 それなりに出ると思います。

データが来たらonExecuteが一回回る,みたいなコードはかけないんでしたっけ?

規格としてはイベントドリブンなRTCというのも存在しますが、実装されてませんね。 現存の機能で実現するには外部トリガ付きの実行コンテキストを割り当てて駆動したい ときにトリガをかけるということでしょうか。

そちらでも例えば画像処理なんかはhrpsysのシリアライズに入っていない外部のRTC があるんじゃなにかと思っているんですが,どうされていますでしょうか.

必要に応じて30Hzとか10Hzとかに設定しています。

あと,逆に実時間のRTCにサービスコールを呼ぶだけの,外部のRTCというのもあるんですが, これはら実行周期が例えば1Hzでも,大丈夫でしょうか?イメージとしては外部のRTCはonExecuteが 1hzでまわっていて,これとは非同期に適当なタイミングの外部のRTCから内部の実時間RTCにサービスコールをよぶのですが, このとき外部のRTCではサービスコールを呼ぶコードが実行されたらすぐに内部に信号がいくでしょうか? あるいは,なにかonExecuteの実行周期と同期したりするんでしょうか?

サービスはonExecute()を実行するのとは別のスレッドで呼ばれるので呼べばすぐに実行されます。

2015年4月17日 9:27 Kei Okada notifications@github.com:

ロボットのセンサ情報をROSに出していきたいので,それなりに回ってくれると嬉しいです. データが来たらonExecuteが一回回る,みたいなコードはかけないんでしたっけ? そちらでも例えば画像処理なんかはhrpsysのシリアライズに入っていない外部のRTC があるんじゃなにかと思っているんですが,どうされていますでしょうか.

あと,逆に実時間のRTCにサービスコールを呼ぶだけの,外部のRTCというのもあるんですが, これはら実行周期が例えば1Hzでも,大丈夫でしょうか?イメージとしては外部のRTCはonExecuteが 1hzでまわっていて,これとは非同期に適当なタイミングの外部のRTCから内部の実時間RTCにサービスコールをよぶのですが, このとき外部のRTCではサービスコールを呼ぶコードが実行されたらすぐに内部に信号がいくでしょうか? あるいは,なにかonExecuteの実行周期と同期したりするんでしょうか?

◉ Kei Okada

2015-04-17 6:50 GMT+09:00 Fumio KANEHIRO notifications@github.com:

実時間から非実時間への通信は、subscriptionのタイプをflush以外にする、というのが一番重要で 後は通信の周期をアプリケーションに応じて設定するのだと思います。 実行周期もアプリ次第ではあるのですが、2000Hzとなるとほぼ休みなしで回っているイメージで 重くなるのも当然という気がします(もちろん処理内容にもよりますが)。 そんなに高周期が必要なんでしょうか?

2015年4月17日 2:22 Kei Okada notifications@github.com:

@fkanehiro さん.hrpsys

内のRTC(体内の時間プロセス)と外部の計算機上のRTCとの間の通信はどのようなパラメータがいい,というのはあるでしょうか?また,外部のRTCの実行時のパラメータはなにがいい,というのもあるでしょうか?

いまは -o "exec_cxt.periodic.type:PeriodicExecutionContext" -o "exec_cxt.periodic.rate:2000" (体内は500hz)としていますが,どうも無駄にCPUを食っているようで困っています.

◉ Kei Okada

2015-04-03 11:36 GMT+09:00 Ryohei Ueda notifications@github.com:

rtm.connectPortsで実時間スレッドのポートと、外部の計算機のポートをつないだところ、ときどき通信が行われないという事がありました

start-jsk/rtmros_common#690 https://github.com/start-jsk/rtmros_common/issues/690

今ポートのパラメータをデフォルトのものに変えて(rtshellを利用して)テストしています.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89129210>

.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93789670>

.

— Reply to this email directly or view it on GitHub < https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93847615>

.

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93867614 .

— Reply to this email directly or view it on GitHub.

fkanehiro commented 9 years ago

使う側でどのくらい最新のデータをすぐに欲しいかにもよりますが、データの生成元が200Hzであれば、 送信周期やそれを読む方の周期は200Hzかそれ以下でよいのではと思います。 取りこぼしが心配であれば接続時にバッファ長を適度な値に設定しておけばよいかと思います。

2015年4月17日 10:10 Kei Okada notifications@github.com:

周期は体内が200-500hzとして同じぐらいをかんがえいます。 いまは https://github.com/start-jsk/rtmros_common/blob/master/hrpsys_ros_bridge/src/HrpsysSeqStateROSBridge.cpp#L260 みたいなコードでisNewだったら処理して、、、みたいにしていて、取りこぼしがないようにするとなると受け取り側を1000hzぐらいで回さないと、と思ってプログラムを書いています。

いま一つrtcの周期と通信の周期の違いがわかっていないですが体内が200hzで回ることが分かっていれば通信も200でよくて、rtcは余裕をみてまわすのが正しいでしょうか?それともrtcも200かちょっと上にしてでデータはqueueにたまるかもしれないけどいずれisNew->readされる感じでしょうか?

◉ Kei Okada

2015/04/17 9:38、Fumio KANEHIRO notifications@github.com のメッセージ:

ロボットのセンサ情報をROSに出していきたいので,それなりに回ってくれると嬉しいです.

それなり、がどの程度かわかりませんが、実時間RTCと外との接続の送信周期を設定すれば、 それなりに出ると思います。

データが来たらonExecuteが一回回る,みたいなコードはかけないんでしたっけ?

規格としてはイベントドリブンなRTCというのも存在しますが、実装されてませんね。 現存の機能で実現するには外部トリガ付きの実行コンテキストを割り当てて駆動したい ときにトリガをかけるということでしょうか。

そちらでも例えば画像処理なんかはhrpsysのシリアライズに入っていない外部のRTC があるんじゃなにかと思っているんですが,どうされていますでしょうか.

必要に応じて30Hzとか10Hzとかに設定しています。

あと,逆に実時間のRTCにサービスコールを呼ぶだけの,外部のRTCというのもあるんですが, これはら実行周期が例えば1Hzでも,大丈夫でしょうか?イメージとしては外部のRTCはonExecuteが 1hzでまわっていて,これとは非同期に適当なタイミングの外部のRTCから内部の実時間RTCにサービスコールをよぶのですが, このとき外部のRTCではサービスコールを呼ぶコードが実行されたらすぐに内部に信号がいくでしょうか? あるいは,なにかonExecuteの実行周期と同期したりするんでしょうか?

サービスはonExecute()を実行するのとは別のスレッドで呼ばれるので呼べばすぐに実行されます。

2015年4月17日 9:27 Kei Okada notifications@github.com:

ロボットのセンサ情報をROSに出していきたいので,それなりに回ってくれると嬉しいです. データが来たらonExecuteが一回回る,みたいなコードはかけないんでしたっけ? そちらでも例えば画像処理なんかはhrpsysのシリアライズに入っていない外部のRTC があるんじゃなにかと思っているんですが,どうされていますでしょうか.

あと,逆に実時間のRTCにサービスコールを呼ぶだけの,外部のRTCというのもあるんですが, これはら実行周期が例えば1Hzでも,大丈夫でしょうか?イメージとしては外部のRTCはonExecuteが 1hzでまわっていて,これとは非同期に適当なタイミングの外部のRTCから内部の実時間RTCにサービスコールをよぶのですが, このとき外部のRTCではサービスコールを呼ぶコードが実行されたらすぐに内部に信号がいくでしょうか? あるいは,なにかonExecuteの実行周期と同期したりするんでしょうか?

◉ Kei Okada

2015-04-17 6:50 GMT+09:00 Fumio KANEHIRO notifications@github.com:

実時間から非実時間への通信は、subscriptionのタイプをflush以外にする、というのが一番重要で 後は通信の周期をアプリケーションに応じて設定するのだと思います。 実行周期もアプリ次第ではあるのですが、2000Hzとなるとほぼ休みなしで回っているイメージで 重くなるのも当然という気がします(もちろん処理内容にもよりますが)。 そんなに高周期が必要なんでしょうか?

2015年4月17日 2:22 Kei Okada notifications@github.com:

@fkanehiro さん.hrpsys

内のRTC(体内の時間プロセス)と外部の計算機上のRTCとの間の通信はどのようなパラメータがいい,というのはあるでしょうか?また,外部のRTCの実行時のパラメータはなにがいい,というのもあるでしょうか?

いまは -o "exec_cxt.periodic.type:PeriodicExecutionContext" -o "exec_cxt.periodic.rate:2000" (体内は500hz)としていますが,どうも無駄にCPUを食っているようで困っています.

◉ Kei Okada

2015-04-03 11:36 GMT+09:00 Ryohei Ueda notifications@github.com:

rtm.connectPortsで実時間スレッドのポートと、外部の計算機のポートをつないだところ、ときどき通信が行われないという事がありました

start-jsk/rtmros_common#690 https://github.com/start-jsk/rtmros_common/issues/690

今ポートのパラメータをデフォルトのものに変えて(rtshellを利用して)テストしています.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-89129210>

.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93789670>

.

— Reply to this email directly or view it on GitHub <

https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93847615>

.

— Reply to this email directly or view it on GitHub < https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93867614>

.

— Reply to this email directly or view it on GitHub.

— Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-93872414 .

snozawa commented 8 years ago

こちらに関連した話になりますが(OpenRTM一般の話に近いかもしれません)、

実時間制御系PCのRTCと外部PCのRTCとでデータポートを接続し通信を行うとき new, periodicの2つを指定すると実時間制御RTC側では実時間スレッドと別スレッドが 最初につくられて、それが通信をすると思いますが、

と理解しているのですが、あってますでしょうか。

また、実時間制御PC上の別スレッドは、1ポートあたり1スレッドになるので、 同じデータ量でも

を比較すると、後者のほうがスレッドのmutexのかかるタイミングもへるので、 オーバーヘッドがなくなるでしょうか。

fkanehiro commented 8 years ago

はい、そうだと思いますが、僕もOpenRTM-aistの実装を見ているわけではないので想像です。 @n-ando さん、こういう理解でいいでしょうか。

n-ando commented 8 years ago

どちらかというとperiodicよりもnewの方がrace conditionになる確率は低いはず、というつもりで実装しています。両者とも、送信バッファを共有しているので、ここがロックを取り合う場所なのですが、 ・new: publisherスレッドが待機、onExecute() で write() されると signal() により起こされてネットワークにデータを送る。なので、onExecute()がものすごく早く、送信がものすごく遅いとかでない限り、ロックを取り合わないはず。 ・periodic: publisherスレッドは onExecute() とは無関係に一定周期で送信(ただし、このスレッドはリアルタイムスレッドではない)。もし、バッファに対する producer(onExecute()側)とconsumer(publisherスレッド) の生成・消費速度が異なる場合、一定時間後常定常的にrace conditionになるため、実時間性が守れなくなる可能性あり。

したがって、periodicの時は生成と消費速度が同じになるように、onExecute()の周期と、publisherスレッドの周期を合わせるか、異なる周期の場合は、onExecute()がpublisherスレッドの整数倍で動作させ、skip_countでその差を調整するようにしてください。バッファ長はジッタによって適宜調整して下さい。

snozawa commented 8 years ago

ありがとうございます。

何点か質問がございまして、 (1) new, periodicともにonExecuteとは別スレッドがpublisherとなりますが、 newはリアルタイム、periodicは非リアルタイムとして生成されるということでしょうか。

・new: publisherスレッドが待機、onExecute() で write() されると signal() により起こされてネットワークにデータを送る。なので、onExecute()がものすごく早く、送信がものすごく遅いとかでない限り、ロックを取り合わないはず。

(2) ロボットの制御系でonExecuteが250-500[Hz]くらいで回っている状況で、送信はそんなに早くない状況かと思っています。 この場合、periodicを50[Hz]で設定したとすると(整数倍にしています)、

となるので、250~500 vs 50で後者の方がrace condition的には良いのかと思っていたのですが、 そういうものでもないのでしょうか。

fkanehiro commented 8 years ago

(1)は両方非リアルタイムではないでしょうか (2)はnewの場合、送信スレッドはデータを待っていて、リアルタイム側からデータが書き込まれると起き上がってデータを送信するので、リアルタイム側がものすごく速くて、送信側が処理している最中に次のデータを書き込もうとでもしないかぎりは基本的にはリソースの競合が起きない、ということではないでしょうか。

2016年4月8日 15:23 Shunichi Nozawa notifications@github.com:

ありがとうございます。

何点か質問がございまして、 (1) new, periodicともにonExecuteとは別スレッドがpublisherとなりますが、 newはリアルタイム、periodicは非リアルタイムとして生成されるということでしょうか。

・new: publisherスレッドが待機、onExecute() で write() されると signal() により起こされてネットワークにデータを送る。なので、onExecute()がものすごく早く、送信がものすごく遅いとかでない限り、ロックを取り合わないはず。

(2) ロボットの制御系でonExecuteが250-500[Hz]くらいで回っている状況で、送信はそんなに早くない状況かと思っています。 この場合、periodicを50[Hz]で設定したとすると、

  • newだとonExecuteの実行周期250-500[Hz]で毎回write, signalにより起こされてpublisherが別スレッドでロックをとって送信をしてしまう
  • periodicだと、onExecuteとは無関係ではりますが、概ね50[Hz]周期でpublisher別スレッドがロックをとって送信する

となるので、250~500 vs 50で後者の方がrace condition的には良いのかと思っていたのですが、 そういうものでもないのでしょうか。

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/fkanehiro/hrpsys-base/issues/552#issuecomment-207236985

n-ando commented 8 years ago

だいたい @fkanehiro さんのおっしゃる通りです。 まず、競合の可能性があるのは主にバッファで、バッファのロックは読み出し・書き込みポインタにしかかかっていません。 (1) 両方とも非リアルタイムスレッドです。それ故、periodicの周期の正確さは保証されません。 (2) newだと、onExecute() がバッファに書き込み後、signalでpublisherスレッドを起こすので、publish作業(正確には、publisherスレッドがバッファからデータを取り出す時間)が 4ms-2ms (250Hz-500Hz) 以内に終われば、次のonExecute()の書き込みを妨げない。ゆえに、ロックを取り合うことはほとんどない。 periodic の場合は、仮に onExecute()が500Hzで、publisherが50Hzとすると、publisherが1回送信して待っている間に、onExecute()は10回書き込み、デフォルトバッファ長8のままだとを超えるので、すぐにバッファフル状態になります。(バッファ長が有限長ならいずれフル状態になる。) その後の挙動は、buffer_full_policy や タイムアウト時間にもよりますが、 a) overwrite モード:古いデータを上書きしますが、publisherとロックを取り合う確率は若干高い b) do_nothingモード:何もしないでデータを捨てるのでロックを取り合うことはない c) blockモード:バッファに空きができるまでタイムアウト時間だけ待つ(条件変数待ち) となるので、リアルタイム制御時には a) しか選択肢はないと思いますが、いずれにしろnewよりrace conditionが発生する確率は高くなるのではないでしょうか? ただし、periodic のskip_countを10のように設定すると、publisher スレッドは1つ値を読んで、10個捨てるので、実質onExecute() 側のスレッドを消費速度が同じになり、「うまくいけば」競合状態はより少なくなるかもしれません。ただし、publisher側スレッドは非リアルタイムスレッドですので、周期の正しさは保証されません。その辺はバッファによって吸収することを意図しています。

snozawa commented 8 years ago

ありがとうございます。

(1) 両方とも非リアルタイムスレッドです。それ故、periodicの周期の正確さは保証されません。 (2) newだと、onExecute() がバッファに書き込み後、signalでpublisherスレッドを起こすので、publish作業(正確には、publisherスレッドがバッファからデータを取り出す時間)が 4ms-2ms (250Hz-500Hz) 以内に終われば、次のonExecute()の書き込みを妨げない。ゆえに、ロックを取り合うことはほとんどない。 periodic の場合は、仮に onExecute()が500Hzで、publisherが50Hzとすると、publisherが1回送信して待っている間に、onExecute()は10回書き込み、デフォルトバッファ長8のままだとを超えるので、すぐにバッファフル状態になります。(バッファ長が有限長ならいずれフル状態になる。)

ロックを取り合う確率がperiodicが高いのは、publisherの実行タイミングとonExecute(のwrite部分)の実行タイミングに関して、

ということでしょうか。

少し前にこちらで試してみた現象としては、実時間制御周期250[hz]で 実時間制御RTC<=>外部のRTC の通信を行ったときに、

のようでした。 もしかしたら送信時間が実時間制御側の周期をこえてしまっているのかもしれません。

@n-andoさんにお教えいただいている条件ですと、 publisherスレッドの送信にかかる時間を現状の構成になってからこちらで測定してないのでしようと思うのですが、 現状の条件は

となっており、データ数・ポート数が多いのかもしれません。

ちなみに、データポートの通信で、同じデータ量でも

を比較すると、後者の方がよかったりすることもありますでしょうか。 データ自体のオーバーヘッドもありそうですが、今回のケースのように データポート1個につき1つのpublisherスレッドなので、 後者のほうがスレッドのmutexのかかるタイミングもへったりしますでしょうか。

n-ando commented 8 years ago

@snozawa さん、ありがとうございます。

ロックを取り合う確率がperiodicが高いのは、publisherの実行タイミングとonExecute(のwrite部分)の実行タイミングに関して、

・newであれば、onExecuteのwriteのタイミングでpublisherが呼ばれるので、ほぼpublisherとonExecuteは同期がとれてることになる。そのため、概ね猶予は4msくらいはあるので、送信がこれまでに終わって入れば大丈夫 ・periodicであれば、publiserの呼ばれるタイミングはonExecuteとは同期がとれてないことになる(publisherが非実時間スレッドなため)。そのため、送信時間がたとえ短くても、onExecuteのタイミングと周期実行時のpublisherの実行タイミングが近いと、ロックを取り合う確率が高くなる。 ということでしょうか。

ご推察のとおりです。ただ、@snozawa さんの環境ではそのようになっていない、ということのようですので、私が見落としている実装上の問題があるのかもしれません。これについては、調査してみます。

ちなみに、データポートの通信で、同じデータ量でも

・小さいデータ型をたくさんのポートで通信 ・大きいデータ型を少ないポートで通信 を比較すると、後者の方がよかったりすることもありますでしょうか。

についても、おっしゃる通りで、スレッドの数やロックの数からいっても後者の方がパフォーマンスは良くなるはずです。それにしても、データポートの数が多いですね。これらすべてが別スレッドでデータ送信をするとすると、オーバーヘッドが多いような気がします。OpenRTMの本体の話ですが、データポートのpublisherスレッドをひとまとめにするような実装が必要かもしれませんね。(データポートの送信スレッドのグルーピングとか。。。)

snozawa commented 8 years ago

@n-andoさん、ありがとうございます。 上記2点、よくわかりました。

おっしゃる通りで、スレッドの数やロックの数からいっても後者の方がパフォーマンスは良くなるはずです。

データポート数を少なくしてみる、というのをこちらでも試して比較してみます。

それにしても、データポートの数が多いですね。これらすべてが別スレッドでデータ送信をするとすると、オーバーヘッドが多いような気がします。

やはり当方のような使い方は、OpenRTMのケースとしては多いほうなのですね。

OpenRTMの本体の話ですが、データポートのpublisherスレッドをひとまとめにするような実装が必要かもしれませんね。(データポートの送信スレッドのグルーピングとか。。。)

これはぜひ実装していただけると助かる機能です。

snozawa commented 8 years ago

@n-andoさん

度々すいません。 periodicの使い方で1点質問があるのですが、

としたときに、 (onExecuteの5回分のうち1回のみが実質publishされる)

とするのですと、どのように違ってくるのでしょうか。 一見違いがよくわかりませんでした。

n-ando commented 8 years ago

buffer_full_policyがoverwrite とすると、常に最新値が送信されInPort側から見た場合は同じに見えますね。その代り、onExecuteとpublisherがロックを取り合う確率がかなり高くなると思います。

snozawa commented 8 years ago

ありがとうごじます。

buffer_full_policyがoverwrite とすると、常に最新値が送信されInPort側から見た場合は同じに見えますね。

なるほど、inPort側からの挙動が同じ、ということなのですね。

その代り、onExecuteとpublisherがロックを取り合う確率がかなり高くなると思います。

こちらがすこしわからなかったのですが、skipであってもロックがかかるのではと思いました。

  /*!                                                                                                                                                                      
   * @if jp                                                                                                                                                                
   * @brief スレッド実行関数                                                                                                                                               
   * @else                                                                                                                                                                 
   * @brief Thread execution function                                                                                                                                      
   * @endif                                                                                                                                                                
   */
  int PublisherPeriodic::svc(void)
  {
    Guard guard(m_retmutex);
    switch (m_pushPolicy)
      {
      case ALL:
        m_retcode = pushAll();
        break;
      case FIFO:
        m_retcode = pushFifo();
        break;
      case SKIP:
        m_retcode = pushSkip();
        break;
      case NEW:
        m_retcode = pushNew();
        break;
      default:
        m_retcode = pushNew();
        break;
      }
    return 0;
  }

上記はsrc/lib/rtm/PublisherPeriodic.cppからの抜粋ですが、 pushSkip関数の中でskip(読み飛ばし)もおこなっており、 それ自体がmutexがかかっているように思います。

こちらで一個勘違いをしていたかもしれないのは、skip_countは 送信のonExecute側の設定でしょうか。 そうすると、publisherの周期は2条件で50[Hz]で同じですが、

バッファを5個分もつが4つスキップする:skip_count = 4, buffer_length = 5 バッファを1個分でスキップはしない:skip_count = 0, buffer_length 1

となるので、skip_countが設定してある前者のほうが、ロックの可能性が低くなる、ということでしょうか。

また、それを考えますと、関連する別パラメータとしてpush_policy=newな状況をかんがえますと、

(1版め、2ばんめは先ほどの2条件と同じで、3ばんめのみ新規です) 3も2ばんめ同様にonExecuteが250[Hz]でonExecuteがロックをとってしまうので、 やはりこの3つをくらべても1ばんめのskip_countを設定するほうが ロックの観点では良い、ということでしょうか。

n-ando commented 8 years ago

その代り、onExecuteとpublisherがロックを取り合う確率がかなり高くなると思います。 こちらがすこしわからなかったのですが、skipであってもロックがかかるのではと思いました。

えーと、これはmutexをかけるかどうか、ではなく、複数のスレッドがmutexを取り合い、race conditionに陥るかどうか、という意味で上のように書きました。 mutexは複数のスレッドでアクセスする可能性のある変数には至る所でかけています。

・バッファを5個分もつが4つスキップする:skip_count = 4, buffer_length = 5 =>onExecuteが250[Hz]でまわってるとき、5回に4回は読み飛ばしなため、mutexかけてもすぐ抜けてくる。5回に1回のみ実際にバッファに書き込むため、mutexが実際かかる頻度は50[Hz] ・バッファを1個分でスキップはしない:skip_count = 0, buffer_length 1=>onExecuteが250[Hz]でまわるとき、毎回250[H]zでバッファ書き込みを行い、mutexが実際にかかる頻度は250[Hz] となるので、skip_countが設定してある前者のほうが、ロックの可能性が低くなる、ということでしょうか。

バッファの読み書きポインタに関するロックは、両方のケースとも publisherスレッド1周期当たり、 ・ onExecute() 5回 ・publisher: 1回 なのですポインタのmutexを取りに行く回数は同じですが、このほかにバッファのempty/full 時のための条件変数が一つずつあり、後者では常にbuffer full 状態になるので、full policyがoverwriteであっても、read側でfull条件のmutexを取りに行くとおもいます。 なお、push_policy = new というのは、skip_count = 読み出し可能なデータ数 - 1 という意味ですので、skip_count = 4 のときよりもしかすると効率が良いかもしれません(読み残しがないため)。

snozawa commented 8 years ago

ありがとうございます。

なお、push_policy = new というのは、skip_count = 読み出し可能なデータ数 - 1 という意味ですので、skip_count = 4 のときよりもしかすると効率が良いかもしれません(読み残しがないため)。

push_policy = newもよさそうですね。こちらも試してみたいと思います。