簡単!実践!ロボットシュミレーションを使用してODEを勉強していくなかで気づいたことなど をメモしていく 最終的には自分がイメージしたものをすぐ描けるようなプログラムにしていく
衝突検出システムの中で最も基本となるオブジェクトでボディ単体の形やボディの集合の形を表す
dGeomID dCreateSphere(dSpaceID space, dReal r);
void dGeomSphereSetRadius(dGeomID sphere, dReal r);
dReal dGeomSphereGetRadius(dGeomID sphere);
dReal dGeomSpherePointDepth(dGeomID sphere, dReal x, dReal y, dReal z);
dGeomID dCreateBox(dSpaceID space, dReal lx, dReal ly, dReal lz);
void dGeomBoxSetLengths(dGeomID box, dReal lx, dReal ly, dReal lz);
void dGeomBoxGetLengths(dGeomID box, dVector3 result);
dReal dGeomBoxPointDepth(dGeomID box, dReal x, dReal y, dReal z);
dGeomID dCreatePlane(dSpaceID space, dReal a, dReal b, dReal c, dReal d);
a,b,cは平面の方程式ax+by+cz=dのパラメータ
void dGeomPlaneSetParams(dGeomID plane, dReal a, dReal b, dReal c, dReal d);
void dGeomPlaneGetParams(dGeomID plane, dVector4 result);
dReal dGeomPlanePointDepth(dGeomID plane, dReal x, dReal y, dReal z);
dGeomID dCreateCapsule(dSpaceID space, dReal r, dReal l);
両端の半球は長さlに含まれていないため => 実際はl + 2r*
void dGeomCapsuleSetParams(dGeomID capsule, dReal r, dReal l);
void dGeomCapsuleGetParams(dGeomID capsule, dReal *r, dReal *l);
dReal dGeomCapsulePointDepth(dGeomID capsule, dReal x, dReal y, dReal z);
dGeomID dCreateCylinder(dSpace space, dReal r, dReal l);
dGeomID dCreateRay(dSpaceID space, dReal l);
void dGeomRaySetLength(dGeomID ray, dReal l);
dReal dGeomRayGetLength(dGeomID ray);
void dGeomRaySet(dGeomID ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz);
光線の相対座標系のz軸が方向ベクトルに沿うように回転行列が調整される、ただし、光線の長さは調整されない
void GeomRayGet(dGeomID ray, dVector3 start, dVector3 dir);
剛体のこと
剛体は力が加えられても変形しない大きさのある理想的な物体
3次元空間でボディを指定するためには位置と姿勢を決めなければならない
dBodyId dBodyCreate(dWorldID world);
worldにボディを作成する
戻り値(dBodyID型)がボディを識別するためのID番号となる
void dMassSetZero(dMass *mass);
質量パラメータmassを0に初期化する
ロボットシュミレーションのための質量、慣性テンソル、重心位置など
重要なパラメータをまとめdMass構造体で定義している
typedef struct dMass{
dReal mass; // ボディの全質量
dVector4 c; // ボディ座標系での重心位置
dMatrix3 I; // ボディ座標系での慣性テンソル(3*3行列)
} dMass;
void dMassSetSphere(dMass *mass, dReal d, dReal r);
void dMassSetSphereTotal(dMass *mass, dReal m, dReal r);
基本Totalの方を使うのが楽
使用例
dMass mass;
dReal m = 10; //構造体にまとめるといい(質量)
dReal r = 1; //構造体にまとめるといい(半径)
dBodyID ball = dBodyCreate(world); //ballのなかにIDが入る
dMassSetZero(&mass); //重心をリセット
dMassSetSphereTotal(&mass, m, r);//massのパラメータの自動計算
dBodySetMass(ball, &mass); //ballというボディに現在のmassデータをセットする
dBodySetPosition(ball, x,y,z); //ballというボディの位置を与える
これが基本的な流れ => ほかのものにも適応できる
void dMassSetCapsule(dMass *mass, dReal d, int dir, dReal r, dReal l);
void dMassSetCapsuleTotal(dMass *mass, dReal m, int dir, dReal r, dReal l);
dirについて
長軸方向を表す
void dMassSetCylinder(dMass *mass, dReal d, int dir, dReal r, dReal l);
void dMassSetCylinderTotal(dMass *mass, dReal m, int dir, dReal r, dReal l);
基本カプセルと同じ
void dMassSetBox(dMass *mass, dReal d, dReal lx, dReal ly, dReal lz);
void dMassSetBoxTotal(dMass *mass, dReal m, dReal lx, dReal ly, dReal lz);
void dBodySetMass(dBodyID body, const dMass *mass);
ボディbodyに質量パラメータmassを設定する
void dBodyGetMass(dBodyID body, dMass *mass);
ボディbodyの質量パラメータmassを取得する
void dMassAdjust(dMass *mass, dReal new_m);
質量パラメータmassの全質量が質量new_mに一致するように質量パラメータを調整
void dMassTranslate(dMass *mass, dReal x, dReal y, dReal z);
ボディの位置は通常、重心位置となる。そして、それが相対座標系の原点になる
その原点を(x,y,z)と変位させたいときの質量パラメータmassを計算する
void dMassRotate(dMass *mass, const dMatrix3 R);
相対座標系で回転行列Rだけ回転させたときの質量パラメータmassを計算する
void dMassAdd(dMass *a, const dMass *b);
質量パラメータbを質量パラメータaに加える
void dBodySetPosition(dBodyID body, dReal x, dReal y, dReal z);
ボディbodyの位置を絶対座標系(x,y,z)[m]に設定する
void dRSetIdentity(dMatrix3 R);
void dRFromAxisAndAngle(dMatrix3 R, dReal ax, dReal ay, dReal az, dReal angle);
void dBodySetRotation(dBodyID body, const dMatrix3 R);
void dRtoQ(const dMatrix3 R, dQuaternion q);
void dRFromEulerAngles(dMatrix3, dReal phi, dReal theta, dReal psi);
void dRFrom2Axes(dMatrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz);
void dQsetIdentity(dQuaternion q);
void dQFromAxisAndAngle(dQuaternion q, dReal ax, dReal ay, dReal az, dReal angle);
void dBodySetQuaternion(dBodyID body, const dQuaternion q);
void dQMultiply0(dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
void dQMultiply1(dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
void dQMultiply2(dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
void dQMultiply3(dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
dQMultiplyの後の数字はほかの掛算関数と同様に
void dWtoDQ(const dVector3 w. const dQuaternion q, dVector4 dq);
void dBodySetLinerVel(dBodyID, dReal x, dReal y, dReal z);
void dBodySetAngularVel(dBodyId, dReal x, dReal y, dReal z);
ボディの速度(x軸成分, y軸成分, z軸成分)[m/s], 角速度(x軸まわり, y軸まわり, z軸まわり)[rad/s]を設定する
void dBodySetForce(dBodyID body, dReal x, dReal y, dReal z);
void dBodeySetTorque(dBodyID body, dRal x, dReal y, dReal z);
void dBodyDestroy(dBodyID body);
ボディbodyを破壊するが、ボディに接続されたジョイントは機能しなくなるが破壊はされない
## シュミレーションの再実行するための操作
dJointDestroy()
dBodyDestroy()
dGeomDestroy()
dJointGroupDestroy()
dJointGroupCreate()
dBodyCreate()
dBodySetMass()
dBodySetPosition()
dBodySetRotation()
dCreateBox()
などdGeomSetBody()
dJointCreateHinge()
などdsSetSphereQuality(n);
デフォルトではn=1
dsSetCapsuleQuality(n);
デフォルトではn=3
物理演算シュミレーター
GUIにOpenGl等を使用することができる
自分のbitbucket codepracticeの中にあるode-0.13.tar.bz2を他の場所にコピーし、
解凍する
###事前に必要なパッケージ
sudo apt-get install automake libtool freeglut3-dev
./boostrap
を実行./configure --with-trimesh=opcode --enable-new-trimesh --enable-shared --enable-release --with-x --enable-double-precision --with-libccd
を実行するmake
長いので待つsudo make install
以上でodeを使用する環境が整った
##drawstufを使用する場合
sudo cp -r include/drawstuff /usr/local/include/
sudo cp drawstuff/src/.libs/libdrawstuff.* /usr/local/lib
sudo ldconfig
これでgitのODE環境の作成が完了した