- ベストアンサー
C++言語で、レナードジョーンズ関数型のポテンシャル法をプログラム
わたしはODE(Open Dynamics Engine)について勉強しているのですが、障害物回避の方法で、レナードジョーンズ関数を利用したポテンシャル法をC++でプログラムしたいのですがどのようなプログラムを作ればいいのかわかりません。引力と斥力の合成ベクトルを求めるプログラムを教えていただきたいので、よろしくお願いします
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
なるほど、面白そうな応用ですね。3対の操作を自動化するための手法の一つにレナード-ジョーンズ・ポテンシャルの考えを入れる。確かに、一定間隔の距離関係は保てそうと思います。ただ、ボールに対しても同じ考えでうまくいくでしょうか?ボールの移動速度と操作マシンの加速性(反応速度)も重要となりそうですね。 まず、どの程度の精度・速度でお互い+ボールの位置関係を把握出来るかが重要なポイントと思います。把握出来るものとして、自機を原点とした場合の相互の位置関係(距離・方向)を検出し、引力・斥力をスカラー量で計算します。ディフェンス機(以降:子機)の正面をy軸座標と固定した場合の、座標(x,y)に変換し、このデータを成分ごとに合成し、最後に(移動方向・マシンの加速度)のデータに換算し移動する。この機能を各子機に実装すればよいかと思います。簡単にはこんな感じでしょうか? ボールに対して遠い位置にいるマシンが他機の斥力に邪魔され反応が鈍る事もありそうに思いませんか?恐らく、A・B・n・mのパラメータのチューニングが鍵になりそうですね。また、マシンの反応速度と1サイクルの計算速度のバランスも重要になりそうだと思います。 以上、おおまかなアドバイスですが参考になりましたでしょうか?仕様の取り違い等があれば、また追記お願いします。
その他の回答 (3)
遠くからの力は弱い方が都合が良いものなのでしょうか?レナードの式を計算する上で引力(加速度)は距離の逆数となっていますがその事ですか?求まる引力の値をマシンの加速度に直す換算にもよるかと思いますが、単純に、マシン間での衝突回避の為の手法であれば、これで大丈夫だと思います。ただ、ボールに対して遠い位置にいるマシンは反応が鈍くなる様に思いますが、それで良いのでしょうか・・・。 とりあえず、目算が立てられたのであれば、試作し検証を行いつつ改善を行っていくと良いと思いますよ。パラメータの設定によっては、マシンの動作も大幅に変化すると思いますし。イメージ通りの動きでなければ、加速度の算出式に一工夫加える事(算出式の変更・追加)も出来て、拡張性もある良い方法かと思います。拡張例としては、マシンごとにフィールドでのデフォルトの重力場を個別に設定したとして、それも加速度計算に利用できればフォーメーションを組んだりも出来そうに思います。がんばってみてください。 また、なにかあれば追記お願いします。
お礼
回答ありがとうございます。 IMTさんのアドバイスのおかげもあり、 ついにそれらしきものができあがりました。 やはり、目標物が遠くへ行けば行くほど子機のスピードを速めたほうがよいと思ったので、目標物と子機間の距離rを速度の変数として使うことで実現しました。 斥力と引力のベクトルの微調整は本当に小さな違いでも実行に大きな差いがでるのですね。 プログラムを見られたら不備な点はまだまだ多いでしょうが、 思い描いていたものが実行されて満足しています。 どうもありがとうございました。
- thamansa
- ベストアンサー率40% (95/232)
レナードジョーンズ関数については何も知らないのですが、 > どのようなプログラムを作ればいいのかわかりません とのことですのでアドバイスをひとつ。 > 1.引力と斥力の合成ベクトルを求める のところまではわかっているようですので、次のステップで進めてください。 ・まずは合成ベクトルを求めるアルゴリズムを整理して、手計算できるレベルまで明確にする。 ・アルゴリズムがわかれば後は実装するだけ。 基本的に、自分が手で計算できないアルゴリズムは、プログラムで実装することができません。
お礼
夜晩くにどうもありがとうございます。 なるほど。手計算できるところまでかみくだければ プログラムできますよね。 積分で言うなら「台形の面積をだしてそれをt=0からt=t'まで 足していく」のような感じですよね?? しかしこの場合、合成ベクトルは、どのように表せばいいのか考えましたが、アイデアが浮かびませんでした。 もしよいアイデアがあればお願いします。 わたしたちが与えられている関数は U(r)=-A/r^n+B/r^mで これ(ポテンシャルエネルギー)を微分すると ロボが受ける力F(r)=-nA/r^(n+1)+mB/r^(m+1)と なりますがnA,mB,n+1,m+1をそれぞれA',B',n',m'とおくと U(r)と同じ式になるからプログラムではU(r)を使ってください。 ということでした。 また、ロボにはセンサが実装されていて彼らは、目標物に向かって進んでいくことができます。このとき、センサが目標物を感知(ロボの視野に入ったら)したらその方向へ引力、他のロボを感知したらその方向から斥力を受けるようにしたいのです。
レナード-ジョーンズ・ポテンシャルとは、ウィキペディアにのっている内容のものでよいですか?具体的に、どの様な入力を与え、どの様な結果を得たいのかの仕様がはっきりしないと、アドバイスし辛いので追記よろしくお願いします。
お礼
情報が少なくて申し訳ありませんでした。 レナード-ジョーンズ・ポテンシャルで与えられている式は 位置rにいる物体のポテンシャルエネルギーU(r)=-A/r^n+B/r^m で右辺の一項目が引力、二項目が斥力を表しています。 私が作りたいプログラムは、 差動駆動型ロボットを4体用いて、1体はフォワードで、フォワードは、コマンドで手動で動かし、3体はディフェンスをして、その3体はポテンシャル法(斥力)で一定の距離を保ちつつ、フォワードのボールを取りに行く(引力)ようなプログラムを作りたいのですが、 ロボット、ボール、グランドなどはもうプログラムできていて、 あとはそのポテンシャル法の関数が書ければということで質問させていただきました。 また、手持ちの資料で与えられているアルゴリズムは while(1){ 1.引力と斥力の合成ベクトルを求める 2.その方向へ進む } です。 どうでしょうか?
お礼
回答ほんとうにありがとうございます!! 私は今友達と一緒に考えていて、スカラで全て計算した後にベクトル計算すればいいのではないかというアイデアを、さっきまさにIMTさんから回答をいただく直前に思いつき、そしてIMTさんの回答のおかげで確信にかわりました。また、スカラを逆数で計算することで遠くのものからの力は弱く近いものからの力は強いようにできると考えたのですがどうでしょうか??