Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

センサ(とくに力センサ)がセンサごとに別データポートになっている点に関して #1088

Open
snozawa opened this issue Dec 21, 2016 · 17 comments

Comments

@snozawa
Copy link
Contributor

snozawa commented Dec 21, 2016

@fkanehiro さん
RobotHardwareなどで、センサ(とくに力センサ)がセンサごとに別データポートになっていると思いますが、
これは何か理由がございますでしょうか。

現状はrfsensor, lhsensorのような名前で、6次元force/momentのTimedDoubleSeqがセンサの数の分定義されていると思います。
これを、forcesensorといった名前で、6 x センサ数(HRP2なら24次元)の一個のポートにするとした場合に、不都合があったりしますでしょうか。

後者のように考えている理由は、

  • 別途議論させていただいている、ポートの数を減らしてオーバーヘッドを減らせます(https://github.com/fkanehiro/hrpsys-base/pull/1057#issuecomment-267212003)
  • rfsensorといった名前はVRMLの定義依存であり、かつロボット依存になります。なので、ポートの接続などでロボット情報を知って、rfsensorという名前をしる必要があります。forcesensorにすると、ロボットによらず、同じ名前で接続設定がかけます。センサのないロボットだと長さが0としておいたり、長さ0の場合write()しないといったことで実質的な通信が行われないようにもできます

の2点くらいをかんがえてます。
前者のオーバーヘッドはおいておくにしても、後者のロボット依存の部分が個人的には以前から気になって降りました。

データポートに燗するプログラムとして

  • データポート接続など設定を行うプログラム
  • RTCであり、データポートをつないでもらう側のプログラム

の2つがあるとします。

後者のRTCでは、だいたいの場合ModelLoaderへのアクセスが容易なので、
forcesensorの6 x センサ数の配列が、どこがrfsensorに相当して、といったものを
復元するのは容易に思います。

一方、前者に関して、具体的には、(downstream側の問題になりますが)ROSBridgeプログラムと制御RTCとの
ポートを接続するものを、rosのlaunch形式で記述できるようにしていますが、
https://github.com/start-jsk/rtmros_common/blob/master/hrpsys_ros_bridge/launch/hrpsys_ros_bridge.launch
ここにロボットのセンサ名依存の部分がかけず、別途pythonスクリプトで接続しているといったことをしています。
https://github.com/start-jsk/rtmros_common/blob/master/hrpsys_ros_bridge/scripts/sensor_ros_bridge_connect.py
launch形式のほうも、pythonなのでセンサ名を取得するようにすればよさげですが、
launch形式の記述と、ModelLoaderにアクセスして、、、の処理と総合してはるかに煩雑になり、現状行ってません。

@fkanehiro
Copy link
Owner

データポートを流れるデータの粒度をある程度細かくすることで、あるRTCがどのようなデータを入力としてとっているかをわかりやすくする、ということが目的となります。
もちろん通信のオーバヘッドを考えればまとめる方がよいのですが。

@snozawa
Copy link
Contributor Author

snozawa commented Dec 25, 2016

データポートを流れるデータの粒度をある程度細かくすることで、あるRTCがどのようなデータを入力としてとっているかをわかりやすくする、ということが目的となります。

後学のためいただけると幸いなのですが、ちなみにこちらは
rfsensor, lhsensorといった粒度で知りたいというニーズがあったためでしょうか?

もちろん通信のオーバヘッドを考えればまとめる方がよいのですが。

はい、通信オーバーヘッドに加えて、センサ名にロボット固有情報が必要になる、というのが個人的に大きかったです。

@fkanehiro
Copy link
Owner

右足と左足で分けたい、というのはあまりないと思います。右手と左手はあるかも。手と足は少なくとも分けたい、でもRobotHardwareは一般的にしておきたい、と考えると選択肢は力センサ全部まとめるか、バラバラにするかしかなかったのだと思います。

@snozawa
Copy link
Contributor Author

snozawa commented Dec 26, 2016

右足と左足で分けたい、というのはあまりないと思います。右手と左手はあるかも。手と足は少なくとも分けたい、でもRobotHardwareは一般的にしておきたい、と考えると選択肢は力センサ全部まとめるか、バラバラにするかしかなかったのだと思います。

なるほど、わかりました。
互換性のため今の個別なポートは残しつつ、forcesensorといったような力センサをまとめたポートを別途追加するのはいかがでしょうか。

@fkanehiro
Copy link
Owner

究極的にはRobotStateをポートから出す、というのもあると思いますが、どうでしょうか。

@k-okada
Copy link
Contributor

k-okada commented Dec 26, 2016 via email

@snozawa
Copy link
Contributor Author

snozawa commented Dec 26, 2016

わかりにくくなってすいませんが、本issueは

  • 通信のオーバーヘッド
  • 命名則などの点でモデルに強く依存している部分

の2点について質問となっており(https://github.com/fkanehiro/hrpsys-base/issues/1088#issue-196831839、https://github.com/fkanehiro/hrpsys-base/issues/1088#issuecomment-269113278)、
前者だけではないです。
最近通信オーバーヘッドの話がでてきていましたが、むしろ本issueは後者のモデルに依存した部分に関して、以前から質問させていただこうと思っていたものを思い出したので質問させていただきました、という経緯のものでした。

現状上がっている案として、(以下力センサの例)

  • (A) 力センサの各ポートを個別な名前で出す(rfsensor, lhsensor...など):<=現行の方法
  • (B) 力センサを全体でまとめた一個のポートで出す(forcesensor
  • (C) 力センサだけでなくRobotStateとして全部まとめて一個のポートで出す

が挙がっています。

(通信に関しては別途issueがあるので一旦命名則とモデルへの依存などに関して議論させていただきますと)
(A)と(B)との比較は

  • (A)だとポート名自体がモデル依存なので、接続設定などあらゆるところでモデル情報の取得と利用が必要になっている。downstreamの細かい話ですが、rtmlaunchではここが解決できてないorやろうと思えばできそうだけど綺麗になりそうにない(と個人的に思っています)
  • (B)だとポート名がモデルに依存しない。力センサのないロボットの場合は、長さ=0のデータにする(<=これはちょっと汚い?)
  • (A)の方が、細かくポート接続の流れを追うことができる(https://github.com/fkanehiro/hrpsys-base/issues/1088#issue-196831839)

で、個人的にはBの方が良いのかなと考えています。
また、
#1088 (comment)
のご指摘の点も含めて(B)と(C)を比較しますと

  • (B)、(C)ともにポート名の命名則という点では、モデル非依存にできそう
  • (C)は、VRMLマターなものになる。例えば「トルクセンサをRobotStateに追加したい」といった更新をしようとしたら、VRMLの変更が必要になり、若干おおごと。(B)はVRMLに関する変更でなく、互換性のとり方が若干緩くできる

となる気がします。
#1088 (comment)
のご指摘をいただく前は(B), (C)どっちでもいいのかなと思ってましたが、
(C)の方がVRMLに関することになるので扱いは複雑になりそうだと思いました。

また、@k-okadaさんの
#1088 (comment)
のご指摘のうち、

RobotStateを出すと、ロボットごとに型変わるようにならないでしょうか?あるいは強くvrmlとリンクして可変配列の1ー6個の要素はこれで、という解釈をこなう必要があると思います。

に関してですが、(僕の解釈によりますと)ロボット毎にRobotState型は多分同じなのだと思っています。

また、センサの有る無し、もしくは個数の違いは、配列の長さで吸収することになると思います。
この点に関しては、上記の(B)という方法と(C)という方法はどちらもそうなのかなと思います。
@fkanehiroさん、間違っていたら訂正いただけますと幸いです)。

@snozawa
Copy link
Contributor Author

snozawa commented Dec 26, 2016

通信オーバーヘッドに関してです。

4 通信の周期を見直す。例えば力センサのフィードバックを外部でやりことはなく、あってもeusで監視するだけなので、10hzとかでいいはず

周期はどうやって決めたら良いのでしょうか。
正直10Hz~20Hzで良いというので賛成ですが、数字の根拠を出せと言われると自身ないです(=何Hzと設定したら以降全ユーザが問題なくなるかが決めるのが難しそう)。
joint_statesなども具体的な数字をユーザからよく言われることがあるのですが、これも何か根拠があるんでしょうか?
また、特定のポートのHzを特定の数字に減らす意外にも、通信方式をかえる、オーバーヘッドをないようにする、
使ってないポートを減らす(https://github.com/start-jsk/rtmros_common/pull/981)、などで
現状のHzと同じでも問題なさそうなので、選択肢はあると思います。

ちなみに、現状4の方法を実現しようとしたら、push_policyをperiodicにして、10Hzとかにするのを
個別にポート毎にやるとできそうな気配があります。

@fkanehiro
Copy link
Owner

ところで、focesensorの配列として出したとして、それを足の力センサの情報を使いたいRTCが受け取った場合、何番目が右脚で何番目が左脚、というのはどうやって知るのでしょうか?

@snozawa
Copy link
Contributor Author

snozawa commented Dec 28, 2016

ところで、focesensorの配列として出したとして、それを足の力センサの情報を使いたいRTCが受け取った場合、何番目が右脚で何番目が左脚、というのはどうやって知るのでしょうか?

loadFromModelLoaderから取得したロボットインスタンスの情報から、
(例えば)sensorIdの順番で持ってくることを想定しています。
ここではrfsensorなどの個別ポート名(センサの名前)も、sensorIdも、ModelLoaderから取得できるとしています。
つまり、前者が読めていたプログラムであれば後者も読める、逆も然りとしています。
なので、もともとrfsensorなどの個別ポートのセンサ名を知ってデータの読み込みができたプログラムであれば、
sensorIdの順序で読み込みを行うこともできると考えています。

さらに具体例で申し上げますと、こちらで使っているプログラムでいうと、例えば力センサの接続を行うのに

  • [送信側RTC] : 実時間制御器のrtc : ポート名rfsensorなど個別ポート群
  • [接続設定プログラム] : rtmlaunch
  • [受信側RTC] : ROSBridgeプログラム : ポート名rfsensorなど個別ポート群

の3つのプログラムがあります。
送信、受信RTCを接続設定プログラムが接続をして、データポートの送受信がされます。
ここで、送信、受信RTCは既にModelLoaderにアクセスできており、力センサポート名もsensorIdも取得できます。

次に、接続設定プログラムなのですが、これは現状ModelLoaderの情報を取得できてなかったり、記法にも制限があったりで、rtmlaunch自体はrfsensorといった名前で接続を行うことができていません。

一方、

  • [送信側RTC] : 実時間制御器のrtc : ポート名forcesensorの1ポート
  • [接続設定プログラム] : rtmlaunch
  • [受信側RTC] : ROSBridgeプログラム : ポート名forcesensorの1ポート

という構成に変更すると、送信、受信RTC既にModelLoaderにアクセスできているので、今までどおりにModelLoaderを使い、力センサポート名を使ってる箇所をsensorIdを使うように書き換えるくらいで、送信受信を行うことができます。

次に、接続設定プログラムは、forcesensorという名前でロボット依存でないものになるので、ModelLoaderが取得できない(しにくい)場合でも接続設定が常にできます。

概して、forcesensorにするとロボット依存情報の露出がへるので、ロボット依存情報をしっていなければ
いけないレイヤ(プログラムコンポーネント)が少なくなるのでは、と思っています。
また、現状センサポート名もsensorIdもModelLoaderからどちらも読めているので、
送信受信側をそれに対応するのも比較的容易に思っています。

@fkanehiro
Copy link
Owner

となると右足の力センサのsensorIdは0である、というルールを作ることになりませんでしょうか。そうだとしたら右足の力センサの名称はrfsensorである、というルールを作るのと同じにはならないでしょうか。

@snozawa
Copy link
Contributor Author

snozawa commented Dec 29, 2016

となると右足の力センサのsensorIdは0である、というルールを作ることになりませんでしょうか。そうだとしたら右足の力センサの名称はrfsensorである、というルールを作るのと同じにはならないでしょうか。

これは
#1088 (comment)
の場合必要ないです。
sensorId、名前がVRMLに適切に記述してあれば何でも良いです。

ModelLoaderが [送信側RTC] 、[受信側RTC] の両方で使えてるので、この2者にとっては
sensor名もsensorIdもどちらも使えると思います。

@fkanehiro
Copy link
Owner

sensor名にせよ、sensorIdにせよ、右足に対応するのがどれか、というのを知るには、右足のsensor名はこれ、またはsensorIdはこれ、というのを都度教えるか、ルールを決める必要があるんではないでしょうか。

@snozawa
Copy link
Contributor Author

snozawa commented Dec 29, 2016

sensor名にせよ、sensorIdにせよ、右足に対応するのがどれか、というのを知るには、右足のsensor名はこれ、またはsensorIdはこれ、というのを都度教えるか、ルールを決める必要があるんではないでしょうか。

はい、そうだと思います。
その点は、本issueでかいてあるような方法、例えば
#1088 (comment)
の3つの方法のうち、いずれの方法を採用しても同様にでてくる問題だと思っています。
(3つの方法のどの方法にしてもあまり違いはないと思います)

例えば、現状は
#1088 (comment)
のうち(A)でrfsensorなどが個別にでていて、例えばそれを利用して
rfsensor = 右足力センサ」という対応をかいているプログラムがあったとしたら、
forcesensorを読み込んで、そのうちrfsensorに対応したsensorIdの配列の要素にアクセスする」
とかけるので、(A)から(B)はほぼ同様にできると思います。
m_robot->Sensor(hrp::Sensor::FORCE, i)->nameiの対応をとるようなプログラム)

また、
#1088 (comment)
の(B)はいかがでしょうか、というissueになっておりますが、
現状のAを廃止することなく互換性を残しながら(B)のポートも追加しておく、というようなことを考えて折ります

@fkanehiro
Copy link
Owner

そうすると通信のオーバヘッドの件をひとまず置いておけば、(A)も(B)もさして違いがなく、(B)のメリットはオーバーヘッドの軽減ということでしょうか。
力センサを配列で出すなら、他のセンサも同様にすべきで、それならいっそのことRobotStateで出してしまっては、という気がします。

@snozawa
Copy link
Contributor Author

snozawa commented Jan 4, 2017

そうすると通信のオーバヘッドの件をひとまず置いておけば、(A)も(B)もさして違いがなく、(B)のメリットはオーバーヘッドの軽減ということでしょうか。

はい、送信側RTC、接続設定プログラム、受信側RTCの3レイヤのうち、送信・受信側RTCにとっての
ロボット依存性は(A)、(B)にとってかわらないと思います。
一方で、接続設定プログラムまでみて考えると、(B)の方がメリットがあると考えてます。

例えば、各レイヤのどこがどういう理由でModelLoaderにアクセスして、
ロボット固有情報を取得する必要があるかを以下にまとめてみます。

(A)のrfsensorなど個別のポートで出す場合

  • [送信側RTC] : 実時間制御器のrtc : writeするのに、rfsensorなどの名前をしる必要があり、ModelLoaderにアクセスできる必要がある。
  • [接続設定プログラム] : rtmlaunch : 接続するのに、rfsensorなどの名前をしる必要があり、ModelLoaderにアクセスできる必要がある(現状ここができていません)。
  • [受信側RTC] : ROSBridgeプログラム : readするのに、rfsensorなどの名前をしる必要があり、ModelLoaderにアクセスできる必要がある。

(B)のforcesensorなど一律で一個のポートで出す場合

  • [送信側RTC] : 実時間制御器のrtc : writeするのに、sensorIdなどをしる必要があり、ModelLoaderにアクセスできる必要がある。
  • [接続設定プログラム] : rtmlaunch : 接続するのに、forcesensorというロボット非依存なポート名で接続できるので、このレイヤがロボット非依存になる。
  • [受信側RTC] : ROSBridgeプログラム : readするのに、sensorIdなどをしる必要があり、ModelLoaderにアクセスできる必要がある。

したがって、(B)の場合は(A)と異なり、接続設定プログラム(ポート同士を接続するものなど)
がModelLoaderにアクセスしてロボット固有情報を得なくてすむので、
ロボット固有情報に依存するレイヤが減らせていることになります。

力センサを配列で出すなら、他のセンサも同様にすべきで、それならいっそのことRobotStateで出してしまっては、という気がします。

はい、これも考えられますが、
#1088 (comment)
のコメントも踏まえてVRML変更まで必要になると少しおおごとになるきがしました。

@fkanehiro
Copy link
Owner

すみません、話が噛み合っていないのか色々分からないのですが、

  • (A)でwriteするのにrfsensorなどの名前を知る必要がある、とはどういうことでしょうか
  • (A)で右脚のセンサからのデータを使いたいRTCはそれを受け取るためのポートを作っておけばよく、ModelLoaderにアクセスする必要はないのではないのでしょうか。
  • RobotStateで出す場合にVRMLの変更が必要になるのはなぜでしょうか

(A)でも(B)でもどこかにロボット依存の情報が残り、(A)の場合は接続設定のプログラムで(B)の場合はRTCだと思っています。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants