首先把上次的模拟结果全部画到了一张图里, 可以看一下模拟效果.
还是很有趣.
这次是可控制的关节运动, 不像上次一样全部是纯自然的动作了.
不过这次没法保证代码和结果是完全对的, 参数太多,没太多时间挨个改...
先来看效果
这些展示了关节重心的移动过程, 基本上是在很疯狂的旋转.
第一个关节设定了和大地的fixJoint却还能小幅旋转, 真是神奇....
总之先放在这吧
【关节运动模拟 in ODE】
Mac-mini:ode$ cat example6.d
import std.stdio;
import ode;
static dWorldID world;
static dSpaceID space;
static dJointGroupID contactgroup;
struct cot{
dBodyID link;
dJointID joint;
dReal l,r,theta;
dReal x,y,z;
dReal mass;
dReal anchorx,anchory,anchorz;
dReal axisx, axisy, axisz;
}cot*[] links;
const
double k1 = 10., fMax = 100.;
void control(){
foreach(l;
links[1..$]){
double tmp = l.theta - dJointGetHingeAngle(l.joint);
dJointSetHingeParam(l.joint, dParamVel, k1*tmp);
dJointSetHingeParam(l.joint, dParamFMax, fMax);
}
}extern(System) void nearCallBack(void* date, dGeomID o1, dGeomID o2){
const maxContacts = 10;
dContact[maxContacts] contact;
int numc = dCollide(o1, o2, maxContacts, &contact[0].geom, dContact.sizeof);
if (numc>0) {
for (uint i = 0;
i< numc;
i++) {
with (contact[i].surface){
mode = dContactSoftCFM | dContactSoftERP | dContactApprox1;
mu = dInfinity;
soft_cfm = 1e-8;
soft_erp = 1.;
}
dJointID c = dJointCreateContact(world, contactgroup, &contact[i]);
dJointAttach(c, dGeomGetBody(contact[i].geom.g1), dGeomGetBody(contact[i].geom.g2));
}
}
}void simLoop(){
control();
dSpaceCollide(space, null ,&nearCallBack);
dWorldStep(world, 0.01);
dJointGroupEmpty(contactgroup);
dReal* pos;
foreach(k,b;
links){
pos = dBodyGetPosition(b.link);
foreach(i;
0..3) writef("%.6f\t",*(pos+i));
}
writeln();
}void create(cot* b){
b.link = dBodyCreate(world);
dMass m1;
dMassSetZero(&m1);
dMassSetCylinderTotal(&m1,b.mass,2,b.r, b.l);
dBodySetMass(b.link,&m1);
dBodySetPosition(b.link, b.x,b.y,b.z);
}void createFixedJoint(cot* b1, cot* b2){
b1.joint = dJointCreateFixed(world,null);
if (!b2){ dJointAttach(b1.joint, b1.link, null);
}
else{ dJointAttach(b1.joint,b1.link,b2.link);
}
dJointSetFixed(b1.joint);
}void createHinge(cot* a1, cot* b1){
b1.joint = dJointCreateHinge(world, null);
dJointAttach(b1.joint,a1.link, b1.link);
dJointSetHingeAnchor(b1.joint, b1.anchorx, b1.anchory, b1.anchorz);
dJointSetHingeAxis(b1.joint, b1.axisx, b1.axisy, b1.axisz);
}/*
struct cot{
dBodyID link;
dJointID joint;
dReal l,r,theta;
dReal x,y,z;
dReal mass;
dReal anchorx,anchory,anchorz;
dReal axisx, axisy, axisz;
}*/void main(){
links ~= new cot(null,null,0.1,0.2,0,0,0,0.05,10,0,0,0,0,0,1);
links ~= new cot(null,null,0.9,0.04,90,0.0,0,0.5,2,0,0,0.1,0,0,1);
links ~= new cot(null,null,1,0.04,120,0,0.0,1.5,2,0,0,1,0,1,0);
links ~= new cot(null,null,1,0.04,70,0,0,2.55,2,0,0,2,0,1,0);
dInitODE();
world = dWorldCreate();
space = dHashSpaceCreate(null);
contactgroup = dJointGroupCreate(0);
dWorldSetERP(world, 0.5);
dWorldSetCFM(world, 1e-3);
dWorldSetGravity(world, 0, 0, -9.8);
foreach(b;
links) create(b);
createFixedJoint(links[0], null);
for(uint i=1;
i
推荐阅读
- 对于微信小程序开发的想法
- 杂谈|Google的佩奇等级
- 网络电话|【D-U-N-S 号申请最新流程】(心得)
- 脑洞大开|重庆人最爱汗蒸,东莞人最爱唱K(美团大数据分析)
- windows升级powershell
- 如何给别人介绍一个你做过的项目
- 算法|将军令算法杂谈
- 男人,应该这样活着
- 毕业快一年,我想说我过得如何()