Esempio n. 1
0
void SSimRobotEntity::setInitPosition(Vector3d pos)
{
	int jsize = m_allJoints.size();

	for (int i = 0; i < jsize; i++) {

		SSimJoint *sjoint = m_allJoints[i];
		SSimRobotParts rparts = sjoint->robotParts;
		//dBodyID  body  = m_allJoints[i]->robotParts.objParts.body;
		dBodyID  body  = rparts.objParts.body;
		dJointID joint = sjoint->joint;
		//dGeomID geom = rparts.objParts.geoms[0];    

		if (i == 0) {
			dBodySetPosition(body, pos.x(), pos.y(), pos.z());
			//dGeomSetPosition(geom,pos.x(),pos.y(),pos.z());

			//const dReal *gpos = dGeomGetPosition(geom);
			//LOG_MSG(("root body pos = (%f, %f, %f)", pos.x(), pos.y(), pos.z()));
			//LOG_MSG(("root geom pos = (%f, %f, %f)", gpos[0], gpos[1], gpos[2]));
		}
		else {
			// TODO: deal with a case in non-hinge joint

			// gap between joint from root joint
			dReal trans_x = sjoint->posFromRoot.x();
			dReal trans_y = sjoint->posFromRoot.y();
			dReal trans_z = sjoint->posFromRoot.z();

			//LOG_MSG(("zure (%f, %f, %f)", trans_x, trans_y, trans_z));
			//LOG_MSG(("zure of body(%f, %f, %f)", rparts.com.x(), rparts.com.y(), rparts.com.z()));

			dBodySetPosition(body,
							 pos.x()+trans_x+rparts.com.x(),
							 pos.y()+trans_y+rparts.com.y(),
							 pos.z()+trans_z+rparts.com.z());

			//const dReal *gpos = dGeomGetPosition(geom);
			LOG_MSG(("body(id:%d) pos = (%f, %f, %f)",body, pos.x()+trans_x+rparts.com.x(), pos.y()+trans_y+rparts.com.y(), pos.z()+trans_z+rparts.com.z()));
			//LOG_MSG(("geom pos = (%f, %f, %f)", gpos[0], gpos[1], gpos[2]));

			// setting of joint position
			int type = dJointGetType(joint);
			if (type == dJointTypeHinge) {
				dJointSetHingeAnchor(joint,
									 pos.x()+trans_x,
									 pos.y()+trans_y,
									 pos.z()+trans_z);
			}
			LOG_MSG(("joint(%d) pos = (%f, %f, %f)",joint, pos.x()+trans_x, pos.y()+trans_y, pos.z()+trans_z));

			/*
			  dGeomSetPosition(geom,
			  pos.x()+trans_x+rparts.com.x(),
			  pos.y()+trans_y+rparts.com.y(),
			  pos.z()+trans_z+rparts.com.z());
			*/
		}
	}
}
Esempio n. 2
0
static void _soy_joints_hinge_anchor_set (soyjointsHinge* self, soyatomsPosition* anchor) {
	struct dxJoint* _tmp0_;
	soyatomsPosition* _tmp1_;
	gfloat _tmp2_;
	gfloat _tmp3_;
	soyatomsPosition* _tmp4_;
	gfloat _tmp5_;
	gfloat _tmp6_;
	soyatomsPosition* _tmp7_;
	gfloat _tmp8_;
	gfloat _tmp9_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (anchor != NULL);
	g_rw_lock_writer_lock (&soy_scenes__stepLock);
	_tmp0_ = ((soyjointsJoint*) self)->joint;
	_tmp1_ = anchor;
	_tmp2_ = soy_atoms_position_get_x (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = anchor;
	_tmp5_ = soy_atoms_position_get_y (_tmp4_);
	_tmp6_ = _tmp5_;
	_tmp7_ = anchor;
	_tmp8_ = soy_atoms_position_get_z (_tmp7_);
	_tmp9_ = _tmp8_;
	dJointSetHingeAnchor ((struct dxJoint*) _tmp0_, (dReal) _tmp3_, (dReal) _tmp6_, (dReal) _tmp9_);
	g_rw_lock_writer_unlock (&soy_scenes__stepLock);
}
Esempio n. 3
0
// Create a ball and a pole
void createBallandPole() {
	dMass m1;
	dReal x0 = 0.0, y0 = 0.0, z0 = 2.5;

	// ball
	ball.radius = 0.2;
	ball.mass = 1.0;
	ball.body = dBodyCreate(world);
	dMassSetZero(&m1);
	dMassSetSphereTotal(&m1, ball.mass, ball.radius);
	dBodySetMass(ball.body, &m1);
	dBodySetPosition(ball.body, x0, y0, z0);

	ball.geom = dCreateSphere(space, ball.radius);
	dGeomSetBody(ball.geom, ball.body);

	// pole
	pole.radius = 0.025;
	pole.length = 1.0;
	pole.mass = 1.0;
	pole.body = dBodyCreate(world);
	dMassSetZero(&m1);
	dMassSetCapsule(&m1, pole.mass, 3, pole.radius, pole.length);
	dBodySetMass(pole.body, &m1);
	dBodySetPosition(pole.body, x0, y0, z0 - 0.5 * pole.length);

	pole.geom = dCreateCCylinder(space, pole.radius, pole.length);
	dGeomSetBody(pole.geom, pole.body);

	// hinge joint
	joint = dJointCreateHinge(world, 0);
	dJointAttach(joint, ball.body, pole.body);
	dJointSetHingeAnchor(joint, x0, y0, z0 - ball.radius);
	dJointSetHingeAxis(joint, 1, 0, 0);
}
Esempio n. 4
0
// ang2 = position angle
// ang  = rotation angle
Robot::Wheel::Wheel(Robot* robot,int _id,float ang,float ang2,int wheeltexid)
{
    id = _id;
    rob = robot;
    float rad = rob->cfg->robotSettings.RobotRadius - rob->cfg->robotSettings.WheelThickness / 2.0;
    ang *= M_PI/180.0f;
    ang2 *= M_PI/180.0f;
    float x = rob->m_x;
    float y = rob->m_y;
    float z = rob->m_z;
    float centerx = x+rad*cos(ang2);
    float centery = y+rad*sin(ang2);
    float centerz = z-rob->cfg->robotSettings.RobotHeight*0.5+rob->cfg->robotSettings.WheelRadius-rob->cfg->robotSettings.BottomHeight;
    cyl = new PCylinder(centerx,centery,centerz,rob->cfg->robotSettings.WheelRadius,rob->cfg->robotSettings.WheelThickness,rob->cfg->robotSettings.WheelMass,0.9,0.9,0.9,wheeltexid);
    cyl->setRotation(-sin(ang),cos(ang),0,M_PI*0.5);
    cyl->setBodyRotation(-sin(ang),cos(ang),0,M_PI*0.5,true);       //set local rotation matrix
    cyl->setBodyPosition(centerx-x,centery-y,centerz-z,true);       //set local position vector
    cyl->space = rob->space;

    rob->w->addObject(cyl);

    joint = dJointCreateHinge (rob->w->world,0);

    dJointAttach (joint,rob->chassis->body,cyl->body);
    const dReal *a = dBodyGetPosition (cyl->body);
    dJointSetHingeAxis (joint,cos(ang),sin(ang),0);
    dJointSetHingeAnchor (joint,a[0],a[1],a[2]);

    motor = dJointCreateAMotor(rob->w->world,0);
    dJointAttach(motor,rob->chassis->body,cyl->body);
    dJointSetAMotorNumAxes(motor,1);
    dJointSetAMotorAxis(motor,0,1,cos(ang),sin(ang),0);
    dJointSetAMotorParam(motor,dParamFMax,rob->cfg->robotSettings.Wheel_Motor_FMax);
    speed = 0;
}
Esempio n. 5
0
Robot::Kicker::Kicker(Robot* robot)
{
    rob = robot;

    float x = rob->m_x;
    float y = rob->m_y;
    float z = rob->m_z;
    float centerx = x+(rob->cfg->robotSettings.RobotCenterFromKicker+rob->cfg->robotSettings.KickerThickness);
    float centery = y;
    float centerz = z-(rob->cfg->robotSettings.RobotHeight)*0.5f+rob->cfg->robotSettings.WheelRadius-rob->cfg->robotSettings.BottomHeight+rob->cfg->robotSettings.KickerZ;
    box = new PBox(centerx,centery,centerz,rob->cfg->robotSettings.KickerThickness,rob->cfg->robotSettings.KickerWidth,rob->cfg->robotSettings.KickerHeight,rob->cfg->robotSettings.KickerMass,0.9,0.9,0.9);
    box->setBodyPosition(centerx-x,centery-y,centerz-z,true);
    box->space = rob->space;

    rob->w->addObject(box);

    joint = dJointCreateHinge (rob->w->world,0);
    dJointAttach (joint,rob->chassis->body,box->body);
    const dReal *aa = dBodyGetPosition (box->body);
    dJointSetHingeAnchor (joint,aa[0],aa[1],aa[2]);
    dJointSetHingeAxis (joint,0,-1,0);

    dJointSetHingeParam (joint,dParamVel,0);
    dJointSetHingeParam (joint,dParamLoStop,0);
    dJointSetHingeParam (joint,dParamHiStop,0);

    rolling = 0;
    kicking = false;
}
Esempio n. 6
0
void Hinge::createPhysics()
{
  ASSERT(axis);
  ASSERT(axis->motor);

  //
  axis->create();

  //
  PrimaryObject::createPhysics();

  // find bodies to connect
  Body* parentBody = dynamic_cast<Body*>(parent);
  ASSERT(!parentBody || parentBody->body);
  ASSERT(!children.empty());
  Body* childBody = dynamic_cast<Body*>(*children.begin());
  ASSERT(childBody);
  ASSERT(childBody->body);

  // create joint
  joint = dJointCreateHinge(Simulation::simulation->physicalWorld, 0);
  dJointAttach(joint, childBody->body, parentBody ? parentBody->body : 0);
  //set hinge joint parameter
  dJointSetHingeAnchor(joint, pose.translation.x, pose.translation.y, pose.translation.z);
  Vector3<> globalAxis = pose.rotation * Vector3<>(axis->x, axis->y, axis->z);
  dJointSetHingeAxis(joint, globalAxis.x, globalAxis.y, globalAxis.z);
  if(axis->cfm != -1.f)
    dJointSetHingeParam(joint, dParamCFM, dReal(axis->cfm));

  if(axis->deflection)
  {
    const Axis::Deflection& deflection = *axis->deflection;
    float minHingeLimit = deflection.min;
    float maxHingeLimit = deflection.max;
    if(minHingeLimit > maxHingeLimit)
      minHingeLimit = maxHingeLimit;
    //Set physical limits to higher values (+10%) to avoid strange hinge effects.
    //Otherwise, sometimes the motor exceeds the limits.
    float internalTolerance = (maxHingeLimit - minHingeLimit) * 0.1f;
    if(dynamic_cast<ServoMotor*>(axis->motor))
    {
      minHingeLimit -= internalTolerance;
      maxHingeLimit += internalTolerance;
    }
    dJointSetHingeParam(joint, dParamLoStop, dReal(minHingeLimit));
    dJointSetHingeParam(joint, dParamHiStop, dReal(maxHingeLimit));
    // this has to be done due to the way ODE sets joint stops
    dJointSetHingeParam(joint, dParamLoStop, dReal(minHingeLimit));
    if(deflection.stopCFM != -1.f)
      dJointSetHingeParam(joint, dParamStopCFM, dReal(deflection.stopCFM));
    if(deflection.stopERP != -1.f)
      dJointSetHingeParam(joint, dParamStopERP, dReal(deflection.stopERP));
  }

  // create motor
  axis->motor->create(this);

  OpenGLTools::convertTransformation(rotation, translation, transformation);
}
Esempio n. 7
0
/*** 車輪の生成 ***/
void makeWheel()
{
    dMass mass;
    dReal r = 0.1;
    dReal w = 0.024;
    dReal m = 0.15;
    dReal d = 0.01;
    dReal tmp_z = Z;

    dReal wx[WHEEL_NUM] = {SIDE[0]/2+w/2+d, - (SIDE[0]/2+w/2+d), 0, 0};
    dReal wy[WHEEL_NUM] = {0, 0, SIDE[1]/2+w/2+d, - (SIDE[1]/2+w/2+d)};
    dReal wz[WHEEL_NUM] = {tmp_z, tmp_z, tmp_z, tmp_z};
    dReal jx[WHEEL_NUM] = {SIDE[0]/2, - SIDE[0]/2, 0, 0};
    dReal jy[WHEEL_NUM] = {0, 0, SIDE[1]/2, - SIDE[1]/2};
    dReal jz[WHEEL_NUM] = {tmp_z, tmp_z, tmp_z, tmp_z};

    for (int i = 0; i < WHEEL_NUM; i++)
    {
        wheel[i].v    = 0.0;

// make body, geom and set geom to body.
// The position and orientation of geom is abondoned.
        wheel[i].body = dBodyCreate(world);
        wheel[i].geom = dCreateCylinder(space,r, w);
        dGeomSetBody(wheel[i].geom,wheel[i].body);

// set configure of body
        dMassSetZero(&mass);
        if (i < 2) {
            dMassSetCylinderTotal(&mass,m, 1, r, w);
        } else {
            dMassSetCylinderTotal(&mass,m, 2, r, w);
        }
        dBodySetMass(wheel[i].body,&mass);

// set position and orientation of body.
        dBodySetPosition(wheel[i].body, wx[i], wy[i], wz[i]);
        dMatrix3 R;
        if (i >= 2) {
            dRFromAxisAndAngle(R,1,0,0,M_PI/2.0);
            dBodySetRotation(wheel[i].body,R);
        } else {
            dRFromAxisAndAngle(R,0,1,0,M_PI/2.0);
            dBodySetRotation(wheel[i].body,R);
        }

// make joint.
        wheel[i].joint = dJointCreateHinge(world,0);
        dJointAttach(wheel[i].joint,base.body,wheel[i].body);
        if (i < 2) {
            dJointSetHingeAxis(wheel[i].joint, 1, 0, 0);
        } else {
            dJointSetHingeAxis(wheel[i].joint, 0, -1, 0);
        }
        dJointSetHingeAnchor(wheel[i].joint, jx[i], jy[i], jz[i]);
    }
}
Esempio n. 8
0
/**
 * This method is called if the joint should be attached.
 * It creates the ODE-joint, calculates the current anchor-position
 * and axis-orientation and attaches the Joint.
 * @param obj1 first ODE-object to attach with
 * @param obj2 second ODE-object to attach with
 **/
void HingeJoint::attachJoint(dBodyID obj1, dBodyID obj2)
{
	gmtl::Vec3f newAnchor, newAxis, scaleVec;
	gmtl::Quatf entityRot;
	gmtl::AxisAnglef axAng;
	TransformationData entityTrans;

	joint = dJointCreateHinge(world, 0);
	dJointAttach(joint, obj1, obj2);

	newAnchor = anchor;
	newAxis = axis;
	if (mainEntity != NULL)
	{
		entityTrans = mainEntity->getEnvironmentTransformation();
// get the scale values of the mainEntity
		scaleVec = entityTrans.scale;

// scale Anchor-offset by mainEntity-scale value
		newAnchor[0] *= scaleVec[0];
		newAnchor[1] *= scaleVec[1];
		newAnchor[2] *= scaleVec[2];

// scale Axis by mainEntity-scale value because of possible distortion
		newAxis[0] *= scaleVec[0];
		newAxis[1] *= scaleVec[1];
		newAxis[2] *= scaleVec[2];
		gmtl::normalize(newAxis);

// get the Rotation of the mainEntity
		entityRot = entityTrans.orientation;

// rotate Axis by mainEntity-rotation
		newAxis *= entityRot;

// rotate Anchor-offset by mainEntity-rotation
		newAnchor *= entityRot;

// transform new Anchor to world coordinates
		newAnchor += entityTrans.position;

	} // if
	dJointSetHingeAnchor(joint, newAnchor[0], newAnchor[1], newAnchor[2]);
	dJointSetHingeAxis(joint, newAxis[0], newAxis[1], newAxis[2]);

// ODE parameters for minimizing failure in Hinge Joint
// It should not be correct this way but it works better than without it ;-)
	dJointSetHingeParam(joint, dParamCFM, 0);
	dJointSetHingeParam(joint, dParamStopERP, 0);
	dJointSetHingeParam(joint, dParamStopCFM, 0);

	oldAngle = 0;

// set the maximum and minimum Joint-angles (if set).
	if (anglesSet)
		setODEAngles();
} // attachJoint
Esempio n. 9
0
void HingeJoint::applyAnchor(dReal x, dReal y, dReal z)
{
	dJointSetHingeAnchor(m_joint, x, y, z);

	// Set of max and min of joint angle
	dJointSetHingeAxis (m_joint, m_axis.x(), m_axis.y(), m_axis.z());
	dJointSetHingeParam(m_joint, dParamLoStop, -2.0*M_PI);
	dJointSetHingeParam(m_joint, dParamHiStop,  2.0*M_PI);
}
Esempio n. 10
0
bool ActiveHingeModel::initModel() {

	// Create the 4 components of the hinge
	hingeRoot_ = this->createBody(B_SLOT_A_ID);
	dBodyID frame = this->createBody(B_FRAME_ID);
	dBodyID servo = this->createBody(B_SERVO_ID);
	hingeTail_ = this->createBody(B_SLOT_B_ID);

	// Set the masses for the various boxes

	float separation = 0;//inMm(0.1);

	this->createBoxGeom(hingeRoot_, MASS_SLOT, osg::Vec3(0, 0, 0),
			SLOT_THICKNESS, SLOT_WIDTH, SLOT_WIDTH);

	dReal xFrame = separation + FRAME_LENGTH / 2 + SLOT_THICKNESS / 2;
	this->createBoxGeom(frame, MASS_FRAME, osg::Vec3(xFrame,
			SERVO_POSITION_OFFSET, 0),
			FRAME_LENGTH, FRAME_WIDTH, FRAME_HEIGHT);

	dReal xServo = xFrame + (FRAME_ROTATION_OFFSET - (FRAME_LENGTH / 2))
			+ SERVO_ROTATION_OFFSET - SERVO_LENGTH/2;
	this->createBoxGeom(servo, MASS_SERVO, osg::Vec3(xServo,
			SERVO_POSITION_OFFSET, 0),
			SERVO_LENGTH, SERVO_WIDTH, SERVO_HEIGHT);

	dReal xTail = xServo + SERVO_LENGTH / 2 + separation + SLOT_THICKNESS / 2;
	this->createBoxGeom(hingeTail_, MASS_SLOT, osg::Vec3(xTail, 0, 0),
			SLOT_THICKNESS, SLOT_WIDTH, SLOT_WIDTH);

	// Create joints to hold pieces in position

	// root <-> connectionPartA
	this->fixBodies(hingeRoot_, frame, osg::Vec3(1, 0, 0));

	// connectionPartA <(hinge)> connectionPArtB
	dJointID joint = dJointCreateHinge(this->getPhysicsWorld(), 0);
	dJointAttach(joint, frame, servo);
	dJointSetHingeAxis(joint, 0, 1, 0);
	dJointSetHingeAnchor(joint,
			SLOT_THICKNESS / 2 + separation + FRAME_ROTATION_OFFSET, 0, 0);

	// connectionPartB <-> tail
	this->fixBodies(servo, hingeTail_, osg::Vec3(1, 0, 0));

	// Create servo
	this->motor_.reset(
			new ServoMotor(joint, ServoMotor::DEFAULT_MAX_FORCE_SERVO,
					ServoMotor::DEFAULT_GAIN,
					ioPair(this->getId(),0)));

	return true;

}
Esempio n. 11
0
/**
*@brief 位置設定の関数
* @param x 位置(X)
* @param y 位置(Y)
* @param z 位置(Z)
*/
void ODEJointObj::SetJointPosition(double px, double py, double pz)
{
	ms->mu->lock();
	if(JointType == 2)
	{
		dJointSetHingeAnchor(joint, px, py, pz);
		SetPosition(bscale_x*px + offx, bscale_y*py + offy, bscale_z*pz + offz);
		jx = px;
		jy = py;
		jz = pz;
	}
	ms->mu->unlock();
}
Esempio n. 12
0
void CODEHingeJoint::setParams()
{
	double anchorPos[3];
	mpBodyAnchors[0]->getPosition(anchorPos);
	dJointSetHingeAnchor(mID, anchorPos[0], anchorPos[1], anchorPos[2]);
	dJointSetHingeAxis(mID, mAxisX, mAxisY, mAxisZ);
	dJointSetHingeParam(mID, dParamLoStop, mLowerLimit);
	dJointSetHingeParam(mID, dParamHiStop, mUpperLimit);
	if (mStopERP >= 0)
		dJointSetHingeParam(mID, dParamStopERP, mStopERP);
	if (mStopCFM >= 0)
		dJointSetHingeParam(mID, dParamStopCFM, mStopCFM);
}
Esempio n. 13
0
void JOINT::Create_In_Simulator(dWorldID world, OBJECT *firstObject, OBJECT *secondObject) {

	joint = dJointCreateHinge(world,0);

	dJointAttach( joint , firstObject->Get_Body() , secondObject->Get_Body() );

	dJointSetHingeAnchor(joint,x,y,z);

	dJointSetHingeAxis(joint,normalX,normalY,normalZ);

	dJointSetHingeParam(joint,dParamLoStop,lowStop);

        dJointSetHingeParam(joint,dParamHiStop,highStop);
}
Esempio n. 14
0
AppHalf::AppHalf(dWorldID world, dSpaceID space, AppDesignID app_design,
		 dBodyID main_body, dBodyID blade)
:  ebMain(main_body), ebBlade(blade)
{
	// NOTE: app_design must have a side called before this, so that A..E and K..Q are one of left or right

	// create bodies with geometries

	// create links and connect them
	jA = dJointCreateHinge(world, 0);
	dJointSetHingeAxis(jA, 0, 1, 0);	// is -1 or 1 a matter? only for angle and anglerate sign, i think.
	dReal *A = app_design->getA();
	dJointSetHingeAnchor(jA, A[0], A[1], A[2]);
	dJointConnect(jA, ebMain, bBeam);
}
Esempio n. 15
0
static void set_phys_joint_anchor(dJointID j, const float v[3])
{
    switch (dJointGetType(j))
    {
    case dJointTypeBall:
        dJointSetBallAnchor     (j, v[0], v[1], v[2]); break;
    case dJointTypeHinge:
        dJointSetHingeAnchor    (j, v[0], v[1], v[2]); break;
    case dJointTypeHinge2:
        dJointSetHinge2Anchor   (j, v[0], v[1], v[2]); break;
    case dJointTypeUniversal:
        dJointSetUniversalAnchor(j, v[0], v[1], v[2]); break;
    default: break;
    }
}
Esempio n. 16
0
static void soy_joints_hinge_real_setup (soyjointsJoint* base, soyatomsPosition* anchor, soyatomsAxis* axis1, soyatomsAxis* axis2) {
	soyjointsHinge * self;
	struct dxJoint* _tmp0_;
	soyatomsPosition* _tmp1_;
	gfloat _tmp2_;
	gfloat _tmp3_;
	soyatomsPosition* _tmp4_;
	gfloat _tmp5_;
	gfloat _tmp6_;
	soyatomsPosition* _tmp7_;
	gfloat _tmp8_;
	gfloat _tmp9_;
	struct dxJoint* _tmp10_;
	soyatomsAxis* _tmp11_;
	gfloat _tmp12_;
	gfloat _tmp13_;
	soyatomsAxis* _tmp14_;
	gfloat _tmp15_;
	gfloat _tmp16_;
	soyatomsAxis* _tmp17_;
	gfloat _tmp18_;
	gfloat _tmp19_;
	self = (soyjointsHinge*) base;
	_tmp0_ = ((soyjointsJoint*) self)->joint;
	_tmp1_ = anchor;
	_tmp2_ = soy_atoms_position_get_x (_tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = anchor;
	_tmp5_ = soy_atoms_position_get_y (_tmp4_);
	_tmp6_ = _tmp5_;
	_tmp7_ = anchor;
	_tmp8_ = soy_atoms_position_get_z (_tmp7_);
	_tmp9_ = _tmp8_;
	dJointSetHingeAnchor ((struct dxJoint*) _tmp0_, (dReal) _tmp3_, (dReal) _tmp6_, (dReal) _tmp9_);
	_tmp10_ = ((soyjointsJoint*) self)->joint;
	_tmp11_ = axis1;
	_tmp12_ = soy_atoms_axis_get_x (_tmp11_);
	_tmp13_ = _tmp12_;
	_tmp14_ = axis1;
	_tmp15_ = soy_atoms_axis_get_y (_tmp14_);
	_tmp16_ = _tmp15_;
	_tmp17_ = axis1;
	_tmp18_ = soy_atoms_axis_get_z (_tmp17_);
	_tmp19_ = _tmp18_;
	dJointSetHingeAxis ((struct dxJoint*) _tmp10_, (dReal) _tmp13_, (dReal) _tmp16_, (dReal) _tmp19_);
}
Esempio n. 17
0
File: 6axis4.cpp Progetto: Ry0/ODE
/*** ロボットアームの生成 ***/
void  makeArm()
{
  dMass mass;                                    // 質量パラメータ
  dReal x[NUM]      = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00};  // 重心 x
  dReal y[NUM]      = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00};  // 重心 y
  dReal z[NUM]      = {0.05, 0.55, 1.55, 2.30, 2.80, 3.35, 3.85, 4.0};  // 重心 z
  dReal length[NUM-1] = {0.10, 1.00, 1.00, 0.50, 0.50, 0.50, 0.50};  // 長さ
  dReal weight[NUM] = {9.00, 2.00, 2.00, 1.00, 1.00, 0.50, 0.50, 0.50};  // 質量
  dReal r[NUM-1]      = {0.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};  // 半径
  dReal c_x[NUM]    = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00};  // 関節中心点 x
  dReal c_y[NUM]    = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00};  // 関節中心点 y
  dReal c_z[NUM]    = {0.00, 0.10, 1.10, 2.10, 2.60, 3.10, 3.60, 3.9};  // 関節中心点 z
  dReal axis_x[NUM] = {0, 0, 0, 0, 0, 0, 0, 0};              // 関節回転軸 x
  dReal axis_y[NUM] = {0, 0, 1, 1, 0, 1, 0, 0};              // 関節回転軸 y
  dReal axis_z[NUM] = {1, 1, 0, 0, 1, 0, 1, 1};              // 関節回転軸 z

  // リンクの生成
  for (int i = 0; i < NUM-1; i++) {
    rlink[i].body = dBodyCreate(world);
    dBodySetPosition(rlink[i].body, x[i], y[i], z[i]);
    dMassSetZero(&mass);
    dMassSetCapsuleTotal(&mass,weight[i],3,r[i],length[i]);
    dBodySetMass(rlink[i].body, &mass);
    rlink[i].geom = dCreateCapsule(space,r[i],length[i]);
    dGeomSetBody(rlink[i].geom,rlink[i].body);
  }
  rlink[NUM-1].body = dBodyCreate(world);
  dBodySetPosition(rlink[NUM-1].body, x[NUM-1], y[NUM-1], z[NUM-1]);
  dMassSetZero(&mass);
  dMassSetBoxTotal(&mass,weight[NUM-1],0.4,0.4,0.4);
  dBodySetMass(rlink[NUM-1].body, &mass);
  rlink[NUM-1].geom = dCreateBox(space,0.4,0.4,0.4);
  dGeomSetBody(rlink[NUM-1].geom,rlink[NUM-1].body);

  // ジョイントの生成とリンクへの取り付け
  joint[0] = dJointCreateFixed(world, 0);  // 固定ジョイント
  dJointAttach(joint[0], rlink[0].body, 0);
  dJointSetFixed(joint[0]);
  for (int j = 1; j < NUM; j++) {
    joint[j] = dJointCreateHinge(world, 0); // ヒンジジョイント
    dJointAttach(joint[j], rlink[j].body, rlink[j-1].body);
    dJointSetHingeAnchor(joint[j], c_x[j], c_y[j], c_z[j]);
    dJointSetHingeAxis(joint[j], axis_x[j], axis_y[j],axis_z[j]);
  }
}
Esempio n. 18
0
/**
 * Creates a new ODE_HingeJoint.
 *
 * @param body1 the first body to connect the joint to.
 * @param body2 the second body to connect the joint to.
 * @return the new ODE_HingeJoint.
 */
dJointID ODE_HingeJoint::createJoint(dBodyID body1, dBodyID body2) {
	if(mJointAxisPoint1->get().equals(mJointAxisPoint2->get())) {
		Core::log("Invalid axes for ODE_HingeJoint.");
		return 0;
	}
	//if one of the bodyIDs is null, the joint is connected to a static object.
	dJointID newJoint = dJointCreateHinge(mWorldID, mGeneralJointGroup);
	dJointAttach(newJoint, body1, body2);
	
	Vector3D anchor = mJointAxisPoint1->get() ;
	Vector3D axis = mJointAxisPoint2->get() ;
	
	axis.set(mJointAxisPoint2->getX() - mJointAxisPoint1->getX(), mJointAxisPoint2->getY() - mJointAxisPoint1->getY(), mJointAxisPoint2->getZ() - mJointAxisPoint1->getZ());
	
	dJointSetHingeAnchor(newJoint, anchor.getX(), anchor.getY(), anchor.getZ());
	dJointSetHingeAxis(newJoint, axis.getX(), axis.getY(), axis.getZ());
	return newJoint; 
}
Esempio n. 19
0
int main (int argc, char **argv)
{
  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;

  // create world
  dInitODE2(0);
  world = dWorldCreate();

  dMass m;
  dMassSetBox (&m,1,SIDE,SIDE,SIDE);
  dMassAdjust (&m,MASS);

  dQuaternion q;
  dQFromAxisAndAngle (q,1,1,0,0.25*M_PI);

  body[0] = dBodyCreate (world);
  dBodySetMass (body[0],&m);
  dBodySetPosition (body[0],0.5*SIDE,0.5*SIDE,1);
  dBodySetQuaternion (body[0],q);

  body[1] = dBodyCreate (world);
  dBodySetMass (body[1],&m);
  dBodySetPosition (body[1],-0.5*SIDE,-0.5*SIDE,1);
  dBodySetQuaternion (body[1],q);

  hinge = dJointCreateHinge (world,0);
  dJointAttach (hinge,body[0],body[1]);
  dJointSetHingeAnchor (hinge,0,0,1);
  dJointSetHingeAxis (hinge,1,-1,1.41421356);

  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  dWorldDestroy (world);
  dCloseODE();
  return 0;
}
Esempio n. 20
0
sODEJoint* sODEJoint::AddHingeJoint( int id, dBodyID body1, dBodyID body2, float ax, float ay, float az, float x, float y, float z )
{
	sODEJoint *pJoint = new sODEJoint( );

	//modify prev and next pointers of any involved joints, make new joint the new head
	pJoint->pNextJoint = pODEJointList;
	if ( pODEJointList ) pODEJointList->pPrevJoint = pJoint;
	pODEJointList = pJoint;

	//create the ODE hinge joint
	pJoint->oJoint = dJointCreateHinge( g_ODEWorld, 0 );
	dJointAttach( pJoint->oJoint, body1, body2 );
	dJointSetHingeAnchor( pJoint->oJoint, x,y,z );
	dJointSetHingeAxis( pJoint->oJoint, ax,ay,az );

	pJoint->iID = id;

	return pJoint;
}
Esempio n. 21
0
static void _soy_joints_hinge_anchor_set (soyjointsHinge* self, soyatomsPosition* anchor) {
	struct dxJoint* _tmp0_ = NULL;
	soyatomsPosition* _tmp1_ = NULL;
	gfloat _tmp2_ = 0.0F;
	gfloat _tmp3_ = 0.0F;
	soyatomsPosition* _tmp4_ = NULL;
	gfloat _tmp5_ = 0.0F;
	gfloat _tmp6_ = 0.0F;
	soyatomsPosition* _tmp7_ = NULL;
	gfloat _tmp8_ = 0.0F;
	gfloat _tmp9_ = 0.0F;
#line 51 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	g_return_if_fail (self != NULL);
#line 51 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	g_return_if_fail (anchor != NULL);
#line 52 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	g_rw_lock_writer_lock (&soy_scenes__stepLock);
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp0_ = ((soyjointsJoint*) self)->joint;
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp1_ = anchor;
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp2_ = soy_atoms_position_get_x (_tmp1_);
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp3_ = _tmp2_;
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp4_ = anchor;
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp5_ = soy_atoms_position_get_y (_tmp4_);
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp6_ = _tmp5_;
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp7_ = anchor;
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp8_ = soy_atoms_position_get_z (_tmp7_);
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	_tmp9_ = _tmp8_;
#line 53 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	dJointSetHingeAnchor ((struct dxJoint*) _tmp0_, (dReal) _tmp3_, (dReal) _tmp6_, (dReal) _tmp9_);
#line 56 "/home/jeff/Documents/libraries/libsoy/src/joints/Hinge.gs"
	g_rw_lock_writer_unlock (&soy_scenes__stepLock);
#line 379 "Hinge.c"
}
Esempio n. 22
0
void createHingeLeg(ODEObject &leg,
	ODEObject &bodyAttachedTo,
	dJointID &joint,
	dReal xPos, dReal yPos, dReal zPos,
	dReal xRot, dReal yRot, dReal zRot,
	dReal radius, dReal length,
	dReal maxAngle, dReal minAngle,
	dReal anchorXPos, dReal anchorYPos, dReal anchorZPos)
{
	dMatrix3 legOrient;
	dRFromEulerAngles(legOrient, xRot, yRot, zRot);

	//position and orientation
	leg.Body = dBodyCreate(World);
	dBodySetPosition(leg.Body, xPos, yPos, zPos);
	dBodySetRotation(leg.Body, legOrient);
	dBodySetLinearVel(leg.Body, 0, 0, 0);
	dBodySetData(leg.Body, (void *)0);

	//mass
	dMass legMass;
	dMassSetCapsule(&legMass, 1, 3, radius, length);
	//dBodySetMass(leg.Body, &legMass);

	//geometry
	leg.Geom = dCreateCapsule(Space, radius, length);
	dGeomSetBody(leg.Geom, leg.Body);

	//hinge joint
	joint = dJointCreateHinge(World, jointgroup);

	//attach and anchor
	dJointAttach(joint, bodyAttachedTo.Body, leg.Body);
	dJointSetHingeAnchor(joint, anchorXPos, anchorYPos, anchorZPos);

	//axes
	dJointSetHingeAxis(joint, 0, 1, 0);

	//Max and min angles
	dJointSetHingeParam(joint, dParamHiStop, maxAngle);
	dJointSetHingeParam(joint, dParamLoStop, minAngle);

}
Esempio n. 23
0
void SkidSteeringVehicle::create() {
    this->vehicleBody = dBodyCreate(this->environment->world);
    this->vehicleGeom = dCreateBox(this->environment->space, this->vehicleBodyLength, this->vehicleBodyWidth, this->vehicleBodyHeight);
    this->environment->setGeomName(this->vehicleGeom, name + ".vehicleGeom");
    dMassSetBox(&this->vehicleMass, this->density, this->vehicleBodyLength, this->vehicleBodyWidth, this->vehicleBodyHeight);
    dGeomSetCategoryBits(this->vehicleGeom, Category::OBSTACLE);
    dGeomSetCollideBits(this->vehicleGeom, Category::OBSTACLE | Category::TERRAIN);
    dBodySetMass(this->vehicleBody, &this->vehicleMass);
    dBodySetPosition(this->vehicleBody, this->xOffset, this->yOffset, this->zOffset);
    dGeomSetBody(this->vehicleGeom, this->vehicleBody);
    dGeomSetOffsetPosition(this->vehicleGeom, 0, 0, this->wheelRadius);

    dReal w = this->vehicleBodyWidth + this->wheelWidth + 2 * this->trackVehicleSpace;
    for(int fr = 0; fr < 2; fr++) {
        for(int lr = 0; lr < 2; lr++) {
            this->wheelGeom[fr][lr] = dCreateCylinder(this->environment->space, this->wheelRadius, this->wheelWidth);
            this->environment->setGeomName(this->wheelGeom[fr][lr], this->name + "." + (!fr ? "front" : "rear") + (!lr ? "Left" : "Right") + "Wheel");
            dGeomSetCategoryBits(this->wheelGeom[fr][lr], Category::TRACK_GROUSER);
            dGeomSetCollideBits(this->wheelGeom[fr][lr], Category::TERRAIN);
            dMassSetCylinder(&this->wheelMass[fr][lr], this->density, 3, this->wheelRadius, this->wheelWidth);
            this->wheelBody[fr][lr] = dBodyCreate(this->environment->world);
            dBodySetMass(this->wheelBody[fr][lr], &this->wheelMass[fr][lr]);
            dGeomSetBody(this->wheelGeom[fr][lr], this->wheelBody[fr][lr]);
            dBodySetPosition(this->wheelBody[fr][lr], this->xOffset + (fr - 0.5) * this->wheelBase, this->yOffset + w * (lr - 0.5), this->zOffset);
            dMatrix3 wheelR;
            dRFromZAxis(wheelR, 0, 2 * lr - 1, 0);
            dBodySetRotation(this->wheelBody[fr][lr], wheelR);
            this->wheelJoint[fr][lr] = dJointCreateHinge(this->environment->world, 0);
            dJointAttach(this->wheelJoint[fr][lr], this->vehicleBody, this->wheelBody[fr][lr]);
            dJointSetHingeAnchor(this->wheelJoint[fr][lr], this->xOffset + (fr - 0.5) * this->wheelBase, this->yOffset + this->vehicleBodyWidth * (lr - 0.5), this->zOffset);
            dJointSetHingeAxis(this->wheelJoint[fr][lr], 0, 1, 0);
            dJointSetHingeParam(this->wheelJoint[fr][lr], dParamFMax, 5.0);
        }
    }
    
    this->bodyArray = dRigidBodyArrayCreate(this->vehicleBody);
    for(int fr = 0; fr < 2; fr++) {
        for(int lr = 0; lr < 2; lr++) {
            dRigidBodyArrayAdd(this->bodyArray, this->wheelBody[fr][lr]);
        }
    }
}
Esempio n. 24
0
int main(int argc, char *argv[]) {
  dsFunctions fn;
  double x[NUM] = {0.00}, y[NUM] = {0.00};  // Center of gravity
  double z[NUM]         = { 0.05, 0.50, 1.50, 2.55};
  double m[NUM] = {10.00, 2.00, 2.00, 2.00};       // mass
  double anchor_x[NUM]  = {0.00}, anchor_y[NUM] = {0.00};// anchors of joints  &nbsp;
  double anchor_z[NUM] = { 0.00, 0.10, 1.00, 2.00};
  double axis_x[NUM]  = { 0.00, 0.00, 0.00, 0.00};  // axises of joints
  double axis_y[NUM]  = { 0.00, 0.00, 1.00, 1.00};
  double axis_z[NUM]  = { 1.00, 1.00, 0.00, 0.00};
  fn.version = DS_VERSION;  fn.start   = &start;   fn.step   = &simLoop;
  fn.command = &command;
  fn.path_to_textures = "../../drawstuff/textures";

  dInitODE();  // Initialize ODE
  world = dWorldCreate();  // Create a world
  dWorldSetGravity(world, 0, 0, -9.8);

  for (int i = 0; i < NUM; i++) {
    dMass mass;
    link[i] = dBodyCreate(world);
    dBodySetPosition(link[i], x[i], y[i], z[i]); // Set a position
    dMassSetZero(&mass);      // Set mass parameter to zero
    dMassSetCapsuleTotal(&mass,m[i],3,r[i],l[i]);  // Calculate mass parameter
    dBodySetMass(link[i], &mass);  // Set mass
  }

  joint[0] = dJointCreateFixed(world, 0); // A fixed joint
  dJointAttach(joint[0], link[0], 0);     // Attach the joint between the ground and the base
  dJointSetFixed(joint[0]);               // Set the fixed joint

  for (int j = 1; j < NUM; j++) {
    joint[j] = dJointCreateHinge(world, 0); // Create a hinge joint
    dJointAttach(joint[j], link[j-1], link[j]); // Attach the joint
    dJointSetHingeAnchor(joint[j], anchor_x[j], anchor_y[j],anchor_z[j]);
    dJointSetHingeAxis(joint[j], axis_x[j], axis_y[j], axis_z[j]);
  }
  dsSimulationLoop(argc, argv, 640, 570, &fn); // Simulation loop
  dCloseODE();
  return 0;
}
Esempio n. 25
0
    void createLeg( const dWorldID & _world ){
        // read leg parameters there 
        lower_part.mass = 0.5;
        lower_part.radius = 0.1;
        lower_part.length = 0.5;

        dReal lower_part_pos[3] =  {0.0, 0.0, lower_part.length};

        upper_part.mass = 0.5;
        upper_part.radius = 0.1;
        upper_part.length = 0.5;

        dReal upper_part_pos[3] =  {0.0, 0.0, upper_part.length + lower_part.length};

        createPart(_world,lower_part, lower_part_pos);
        createPart(_world,upper_part, upper_part_pos);

        jointHinge = dJointCreateHinge(_world, 0); // Create a hinge joint
        dJointAttach(jointHinge, lower_part.body, upper_part.body ); // Attach the joint
        dJointSetHingeAnchor(jointHinge, 1.0,0.0,0.0);//anchor_x[j], anchor_y[j],anchor_z[j]);
    }
Esempio n. 26
0
bool ActiveWheelModel::initModel() {

   // Create the 4 components of the hinge
   wheelRoot_ = this->createBody(B_SLOT_ID);
   dBodyID servo = this->createBody(B_SERVO_ID);
   dBodyID wheel = this->createBody(B_WHEEL_ID);

   // Set the masses for the various boxes
   dMass mass;


   this->createBoxGeom(wheelRoot_, MASS_SLOT, osg::Vec3(0, 0, 0),
         SLOT_THICKNESS, SLOT_WIDTH, SLOT_WIDTH);

   dReal zServo = 0;//-SLOT_WIDTH / 2 + SERVO_Z_OFFSET + SERVO_HEIGHT / 2;
   this->createBoxGeom(servo, MASS_SERVO, osg::Vec3(X_SERVO, 0, zServo),
         SERVO_LENGTH, SERVO_WIDTH, SERVO_HEIGHT);

   this->createCylinderGeom(wheel, MASS_WHEEL, osg::Vec3(X_WHEEL, 0, 0), 1,
         getRadius(), WHEEL_THICKNESS);

   // Create joints to hold pieces in position

   // slot <slider> hinge
   this->fixBodies(wheelRoot_, servo, osg::Vec3(1, 0, 0));

   // servo <(hinge)> wheel
   dJointID joint = dJointCreateHinge(this->getPhysicsWorld(), 0);
   dJointAttach(joint, servo, wheel);
   dJointSetHingeAxis(joint, 1, 0, 0);
   dJointSetHingeAnchor(joint, X_WHEEL, 0, 0);

   // Create servo
   this->motor_.reset(
         new ServoMotor(joint, ServoMotor::DEFAULT_MAX_FORCE,
        		 ioPair(this->getId(),0)));

   return true;

}
Else::AcrobotArticulatedBody
::AcrobotArticulatedBody( dWorldID argWorldID,
                          dSpaceID argSpaceID,
                          double argScale )
: ArticulatedBody( argWorldID, argSpaceID ),
  myRadius( 0.1 * argScale ),
  myLength( argScale ),
  myJointGroupID( 0 )
{
    // create body
    gmtl::Vec3d dims( 2*myRadius, 2*myRadius, 2*myRadius + myLength );
    const double density = 1.0;
    const int zDirection = 3;
    const double extraSpace = 0.1*myLength;
    dMass mass;

    dBodyID body = dBodyCreate( myWorldID );
    dBodySetData( body, this );

    // create cylinder aligned to z-axis
    dGeomID geom = dCreateCapsule( mySpaceID, myRadius, myLength );
    dGeomSetBody( geom, body );
    dBodySetPosition( body, 0, 0, extraSpace + 0.5*myLength + myRadius );
    dMassSetCappedCylinder( &mass, density, zDirection, myRadius, myLength );
    dBodySetMass( body, &mass );

    dJointID joint = dJointCreateHinge( myWorldID, myJointGroupID );
    dJointAttach( joint, NULL, body );
    dJointSetHingeAnchor( joint, 0, 0, extraSpace + myLength + myRadius );
    dVector3 axis;
    axis[0] = 0; axis[1] = 1; axis[2] = 0;
    dJointSetHingeAxis( joint, axis[0], axis[1], axis[2] );

    myBodies[0] = body;
    myJoints[0] = joint;
    myBodyDims[0] = dims;
    myGeoms.push_back( geom );
}
Esempio n. 28
0
//! A hinge requires a fixed anchor point and an axis
OscHingeODE::OscHingeODE(dWorldID odeWorld, dSpaceID odeSpace,
                         const char *name, OscBase* parent,
                         OscObject *object1, OscObject *object2,
                         double x, double y, double z, double ax, double ay, double az)
    : OscHinge(name, parent, object1, object2, x, y, z, ax, ay, az)
{
    m_response = new OscResponse("response",this);

	// create the constraint for object1
    cVector3d anchor(x,y,z);
    cVector3d axis(ax,ay,az);

    dJointID odeJoint = dJointCreateHinge(odeWorld,0);

    m_pSpecial = new ODEConstraint(this, odeJoint, odeWorld, odeSpace,
                                   object1, object2);

    dJointSetHingeAnchor(odeJoint, anchor.x, anchor.y, anchor.z);
    dJointSetHingeAxis(odeJoint, axis.x, axis.y, axis.z);

    printf("Hinge joint created between %s and %s at anchor (%f,%f,%f), axis (%f,%f,%f)\n",
        object1->c_name(), object2?object2->c_name():"world", x,y,z,ax,ay,az);
}
Esempio n. 29
0
void vmWishboneCar::buildWheelJoint(vmWheel *wnow, vmWishbone *snow, dReal shiftSign)
{
    // chassis pin joints
    const dReal *pos;
    snow->jChassisUp= dJointCreateHinge(world,0);
    dJointAttach(snow->jChassisUp,chassis.body,snow->uplink.body);
    dJointSetHingeAxis(snow->jChassisUp,1.0, 0.0, 0.0);
    pos= dBodyGetPosition(snow->uplink.body);
    dJointSetHingeAnchor(snow->jChassisUp,pos[0]
            ,pos[1]+0.5*shiftSign*snow->uplink.width, pos[2]);

    const dReal *pos1;
    snow->jChassisLow= dJointCreateHinge(world,0);
    dJointAttach(snow->jChassisLow, chassis.body, snow->lowlink.body);
    dJointSetHingeAxis(snow->jChassisLow,1.0, 0.0, 0.0);
    pos1= dBodyGetPosition(snow->lowlink.body);
    dJointSetHingeAnchor(snow->jChassisLow, pos1[0]
            , pos1[1]+0.5*shiftSign*snow->lowlink.width, pos1[2]);

    // rotor ball joint
    /*const dReal *p2;
    jRotorUp= dJointCreateBall(world,0);
    dJointAttach(jRotorUp, uplink.body, hlink.body);
    p2= dBodyGetPosition(uplink.body);
    dJointSetBallAnchor(jRotorUp, p2[0], p2[1]-0.5*uplink.width, p2[2]);

    const dReal *p3;
    jRotorLow= dJointCreateBall(world,0);
    dJointAttach(jRotorLow, lowlink.body,hlink.body);
    p3= dBodyGetPosition(lowlink.body);
    dJointSetBallAnchor(jRotorLow, p3[0], p3[1]-0.5*lowlink.width,p3[2]);*/

    const dReal *p2;
    snow->jRotorUp= dJointCreateHinge(world,0);
    dJointAttach(snow->jRotorUp, snow->uplink.body, snow->hlink.body);
    p2= dBodyGetPosition(snow->uplink.body);
    dJointSetHingeAnchor(snow->jRotorUp, p2[0]
            ,p2[1]-0.5*shiftSign*snow->uplink.width, p2[2]);
    dJointSetHingeAxis(snow->jRotorUp, 1.0, 0.0, 0.0);

    const dReal *p3;
    snow->jRotorLow= dJointCreateHinge(world,0);
    dJointAttach(snow->jRotorLow, snow->lowlink.body,snow->hlink.body);
    p3= dBodyGetPosition(snow->lowlink.body);
    dJointSetHingeAnchor(snow->jRotorLow, p3[0]
            ,p3[1]-0.5*shiftSign*snow->lowlink.width,p3[2]);
    dJointSetHingeAxis(snow->jRotorLow, 1.0, 0.0, 0.0);

    // rotor hinge joint
    const dReal *pw= dBodyGetPosition(wnow->body);
    snow->jRotorMid= dJointCreateHinge(world,0);
    dJointAttach(snow->jRotorMid, snow->hlink.body, wnow->body);
    dJointSetHingeAxis(snow->jRotorMid, 0.0,1.0,0.0);
    dJointSetHingeAnchor(snow->jRotorMid, pw[0],pw[1],pw[2]);


    // strut joint
    const dReal *ps1, *ps2;
    dReal angle= -shiftSign*strutAngle;

    ps1= dBodyGetPosition(snow->upstrut.body);
    ps2= dBodyGetPosition(snow->lowstrut.body);
    snow->jStrutUp= dJointCreateBall(world,0);
    dJointAttach(snow->jStrutUp, chassis.body, snow->upstrut.body);
    //dJointSetFixed(snow->jStrutUp);
    dJointSetBallAnchor(snow->jStrutUp, ps1[0]
            ,ps1[1]+0.5*shiftSign*snow->upstrut.width*fabs(sin(angle))
            ,ps1[2]+0.5*snow->upstrut.width*fabs(cos(angle)));

    snow->jStrutLow= dJointCreateBall(world,0);
    dJointAttach(snow->jStrutLow, snow->lowlink.body, snow->lowstrut.body);
    dJointSetBallAnchor(snow->jStrutLow, ps2[0]
            ,ps2[1]-0.5*shiftSign*snow->lowstrut.width*fabs(sin(angle))
            ,ps2[2]-0.5*snow->lowstrut.width*fabs(cos(angle)));

    // struct sliding joint
    snow->jStrutMid= dJointCreateSlider(world,0);
    dJointAttach(snow->jStrutMid, snow->upstrut.body, snow->lowstrut.body);
    dJointSetSliderAxis(snow->jStrutMid, 0.0,shiftSign*fabs(sin(angle)),fabs(cos(angle)));

    // set joint feedback
    wnow->feedback= new dJointFeedback;
    dJointSetFeedback(snow->jStrutMid,wnow->feedback);

    // suspension slider
    /*snow->jLowSpring= dJointCreateLMotor(world,0);
    dJointAttach(snow->jLowSpring, chassis.body, snow->lowlink.body);
    dJointSetLMotorNumAxes(snow->jLowSpring, 1);
    dJointSetLMotorAxis(snow->jLowSpring,0,0, 0.0, 0.0, 1.0);*/


}
bool ActiveCardanModel::initModel() {

    // Create the 4 components of the hinge
    cardanRoot_ = this->createBody(B_SLOT_A_ID);
    dBodyID connectionPartA = this->createBody(B_CONNECTION_A_ID);
    dBodyID crossPartA = this->createBody(B_CROSS_PART_A_ID);
    dBodyID crossPartB = this->createBody(B_CROSS_PART_B_ID);
    dBodyID connectionPartB = this->createBody(B_CONNECTION_B_ID);
    cardanTail_ = this->createBody(B_SLOT_B_ID);

    float separation = inMm(0.1);

    this->createBoxGeom(cardanRoot_, MASS_SLOT, osg::Vec3(0, 0, 0),
                        SLOT_THICKNESS, SLOT_WIDTH, SLOT_WIDTH);

    dReal xPartA = SLOT_THICKNESS / 2 + separation
                   + CONNNECTION_PART_LENGTH / 2;
    this->createBoxGeom(connectionPartA, MASS_SERVO, osg::Vec3(xPartA, 0, 0),
                        CONNNECTION_PART_LENGTH, CONNNECTION_PART_WIDTH,
                        CONNECTION_PART_HEIGHT);

    dReal xCrossPartA = xPartA + CONNECTION_PART_OFFSET;
    this->createBoxGeom(crossPartA, MASS_CROSS / 3,
                        osg::Vec3(xCrossPartA, 0, 0), CROSS_THICKNESS, CROSS_WIDTH,
                        CROSS_HEIGHT);
    this->createBoxGeom(crossPartB, MASS_CROSS / 3,
                        osg::Vec3(xCrossPartA, 0, 0), CROSS_THICKNESS, CROSS_HEIGHT,
                        CROSS_WIDTH);

    dReal xPartB = xCrossPartA + CONNECTION_PART_OFFSET;
    this->createBoxGeom(connectionPartB, MASS_SERVO, osg::Vec3(xPartB, 0, 0),
                        CONNNECTION_PART_LENGTH, CONNECTION_PART_HEIGHT,
                        CONNNECTION_PART_WIDTH);

    dReal xTail = xPartB + CONNNECTION_PART_LENGTH / 2 + separation
                  + SLOT_THICKNESS / 2;
    this->createBoxGeom(cardanTail_, MASS_SLOT, osg::Vec3(xTail, 0, 0),
                        SLOT_THICKNESS, SLOT_WIDTH, SLOT_WIDTH);

    // Cross Geometries
    dBodyID crossPartAedge1 = this->createBody(B_CROSS_PART_A_EDGE_1_ID);
    dBodyID crossPartAedge2 = this->createBody(B_CROSS_PART_A_EDGE_2_ID);

    dBodyID crossPartBedge1 = this->createBody(B_CROSS_PART_B_EDGE_1_ID);
    dBodyID crossPartBedge2 = this->createBody(B_CROSS_PART_B_EDGE_2_ID);

    this->createBoxGeom(crossPartAedge1, MASS_CROSS / 12,
                        osg::Vec3(xCrossPartA - (CROSS_WIDTH / 2 + CROSS_THICKNESS / 2), 0,
                                  CROSS_HEIGHT / 2 + (CROSS_THICKNESS / 2)),
                        CROSS_CENTER_OFFSET, CROSS_WIDTH, CROSS_THICKNESS);

    this->createBoxGeom(crossPartAedge2, MASS_CROSS / 12,
                        osg::Vec3(xCrossPartA - (CROSS_WIDTH / 2 + CROSS_THICKNESS / 2), 0,
                                  -CROSS_HEIGHT / 2 - (CROSS_THICKNESS / 2)),
                        CROSS_CENTER_OFFSET, CROSS_WIDTH, CROSS_THICKNESS);

    this->createBoxGeom(crossPartBedge1, MASS_CROSS / 12,
                        osg::Vec3(xCrossPartA + (CROSS_WIDTH / 2 + CROSS_THICKNESS / 2),
                                  CROSS_HEIGHT / 2 - (CROSS_THICKNESS / 2), 0),
                        CROSS_CENTER_OFFSET, CROSS_THICKNESS, CROSS_WIDTH);

    this->createBoxGeom(crossPartBedge2, MASS_CROSS / 12,
                        osg::Vec3(xCrossPartA + (CROSS_WIDTH / 2 + CROSS_THICKNESS / 2),
                                  -CROSS_HEIGHT / 2 + (CROSS_THICKNESS / 2), 0),
                        CROSS_CENTER_OFFSET, CROSS_THICKNESS, CROSS_WIDTH);

    // Create joints to hold pieces in position

    // root <-> connectionPartA
    this->fixBodies(cardanRoot_, connectionPartA, osg::Vec3(1, 0, 0));

    // connectionPartA <(hinge)> crossPartA
    dJointID joint = dJointCreateHinge(this->getPhysicsWorld(), 0);
    dJointAttach(joint, connectionPartA, crossPartA);
    dJointSetHingeAxis(joint, 0, 0, 1);
    dJointSetHingeAnchor(joint,
                         xPartA
                         + ((CONNNECTION_PART_LENGTH / 2)
                            - (CONNNECTION_PART_LENGTH
                               - CONNNECTION_PART_ROTATION_OFFSET)), 0, 0);

    // crossPartA <-> crossPartB
    this->fixBodies(crossPartA, crossPartB, osg::Vec3(1, 0, 0));

    // crossPartB <(hinge)> connectionPartB
    dJointID joint2 = dJointCreateHinge(this->getPhysicsWorld(), 0);
    dJointAttach(joint2, crossPartB, connectionPartB);
    dJointSetHingeAxis(joint2, 0, 1, 0);
    dJointSetHingeAnchor(joint2,
                         xPartB
                         - ((CONNNECTION_PART_LENGTH / 2)
                            - (CONNNECTION_PART_LENGTH
                               - CONNNECTION_PART_ROTATION_OFFSET)), 0, 0);

    // connectionPartB <-> tail
    this->fixBodies(connectionPartB, cardanTail_, osg::Vec3(1, 0, 0));

    // Fix cross Parts
    this->fixBodies(crossPartA, crossPartAedge1, osg::Vec3(1, 0, 0));
    this->fixBodies(crossPartA, crossPartAedge2, osg::Vec3(1, 0, 0));
    this->fixBodies(crossPartB, crossPartBedge1, osg::Vec3(1, 0, 0));
    this->fixBodies(crossPartB, crossPartBedge2, osg::Vec3(1, 0, 0));

    // Create motors
    motor1_.reset(
        new ServoMotor(joint, ServoMotor::DEFAULT_MAX_FORCE_SERVO,
                       ServoMotor::DEFAULT_GAIN,
                       ioPair(this->getId(),0)));
    motor2_.reset(
        new ServoMotor(joint2, ServoMotor::DEFAULT_MAX_FORCE_SERVO,
                       ServoMotor::DEFAULT_GAIN,
                       ioPair(this->getId(),1)));

    return true;

}