示例#1
0
文件: Physics.cpp 项目: 2asoft/xray
void BodyCutForce(dBodyID body,float l_limit,float w_limit)
{
	const dReal wa_limit=w_limit/fixed_step;
	const dReal* force=	dBodyGetForce(body);
	dReal force_mag=dSqrt(dDOT(force,force));

	//body mass
	dMass m;
	dBodyGetMass(body,&m);

	dReal force_limit =l_limit/fixed_step*m.mass;

	if(force_mag>force_limit)
	{
		dBodySetForce(body,
			force[0]/force_mag*force_limit,
			force[1]/force_mag*force_limit,
			force[2]/force_mag*force_limit
			);
	}


	const dReal* torque=dBodyGetTorque(body);
	dReal torque_mag=dSqrt(dDOT(torque,torque));

	if(torque_mag<0.001f) return;

	dMatrix3 tmp,invI,I;

	// compute inertia tensor in global frame
	dMULTIPLY2_333 (tmp,m.I,body->R);
	dMULTIPLY0_333 (I,body->R,tmp);

	// compute inverse inertia tensor in global frame
	dMULTIPLY2_333 (tmp,body->invI,body->R);
	dMULTIPLY0_333 (invI,body->R,tmp);

	//angular accel
	dVector3 wa;
	dMULTIPLY0_331(wa,invI,torque);
	dReal wa_mag=dSqrt(dDOT(wa,wa));

	if(wa_mag>wa_limit)
	{
		//scale w 
		for(int i=0;i<3;++i)wa[i]*=wa_limit/wa_mag;
		dVector3 new_torqu;

		dMULTIPLY0_331(new_torqu,I,wa);

		dBodySetTorque 
			(
			body,
			new_torqu[0],
			new_torqu[1],
			new_torqu[2]
			);
	}
}
示例#2
0
ngl::Vec3 RigidBody::getForce() const
{
  // When getting, the returned values are pointers to internal data structures,
  //  so the vectors are valid until any changes are made to the rigid body
  //  system structure.
  const dReal *pos=dBodyGetForce(m_id);
  return ngl::Vec3(*pos,*(pos+1),*(pos+2));
}
示例#3
0
bool ODERigidObject::WriteState(File& f) const
{
  //TODO: use body quaternion
  Vector3 w,v;
  const dReal* pos=dBodyGetPosition(bodyID);
  const dReal* q=dBodyGetQuaternion(bodyID);
  GetVelocity(w,v);
  //do we need this?
  const dReal* frc=dBodyGetForce(bodyID);
  const dReal* trq=dBodyGetTorque(bodyID);
    
  if(!WriteArrayFile(f,pos,3)) return false;
  if(!WriteArrayFile(f,q,4)) return false;
  if(!WriteFile(f,w)) return false;
  if(!WriteFile(f,v)) return false;
  if(!WriteArrayFile(f,frc,3)) return false;
  if(!WriteArrayFile(f,trq,3)) return false;
  return true;
}
示例#4
0
/*** P control tries to add a force that reduces the distance between
 the current joint angles and the desired value in the lookup table THETA. 
 ***/
void Pcontrol()
{
  dReal kp = 2.0;    //effects how quickly it tries to acheive the desired angle (original=2)
	//  dReal kp = 10.0;    //effects how quickly it tries to acheive the desired angle
  dReal fMax = 100.0; //fMax is the max for it can apply trying to acheive the desired angle
  
//#define ANG_VELOCITY
#ifndef ANG_VELOCITY
  for(int segment = 0; segment < BODY_SEGMENTS; ++segment) {
      for (int i = 0; i < num_legs; i++) {
	  for (int j = 0; j < num_links; j++) {
	      dReal tmp = dJointGetHingeAngle(leg[segment][i][j].joint);
	      dReal diff = THETA[segment][i][j] - tmp;
	      dReal u;
	      u = kp * diff;
	      
	      //cout << "\n\n***" << u << "***\n\n\n\n" << endl;

	      dJointSetHingeParam(leg[segment][i][j].joint,  dParamVel,
				  u);
	      dJointSetHingeParam(leg[segment][i][j].joint, dParamFMax,
				  fMax);
	  }
      }
#else //when using angular velocity
      for(int segment = 0; segment < BODY_SEGMENTS; ++segment) {
	  for (int i = 0; i < num_legs; i++) {
	      for (int j = 0; j < num_links; j++) {
		  //dReal tmp = dJointGetHingeAngle(leg[segment][i][j].joint);
		  //dReal diff = THETA[segment][i][j] - tmp;
		  //dReal u;
		  //u = kp * diff;
		  
		  dReal desiredValue = THETA[segment][i][j];
		  desiredValue *= 2.25;

		  //cout << "\n\n***" << desiredValue << "***\n\n\n\n" << endl;

		  dJointSetHingeParam(leg[segment][i][j].joint,  dParamVel,
				      desiredValue);
		  dJointSetHingeParam(leg[segment][i][j].joint, dParamFMax,
				      fMax);
	      }
	  }
	  
#endif
#ifdef USE_NLEG_ROBOT
		if(segment < BODY_SEGMENTS-1) {
			// applying torso joint force
			dReal tmp = dJointGetHingeAngle(torso[segment].joint); //joints might start in segment 2
			dReal diff = torsoJointDesiredAngle[segment] - tmp;
			
			dReal u;
			u = kp * diff;  
			dJointSetHingeParam(torso[segment].joint,  dParamVel, u);
			dJointSetHingeParam(torso[segment].joint, dParamFMax, fMax); 
		}
#endif        
	}
}

/*** Control of walking ***/
void walk()
{
  
	//  int numSheets;
	//  
	//  #ifdef HIDDEN_LAYER
	//  numSheets = 3;
	//  #else
	//  numSheets = 2;
	//  #endif
  
  timeSteps++;
	
  //jmc added to print out joint angles
	
  if(printJointAngles){
		static bool doOnce = true;
		if(doOnce){
			doOnce=false;
			//remove the file if it is there already
			ofstream jangle_file;        
			jangle_file.open ("jointAngles.txt", ios::trunc );
			jangle_file.close();      
		}
  }
	
	
	
  //clear out the network
  //LHZ  - When Recurrence is turned on, we multiply the input values by the recurrent values that were in 
  //the input nodes to begin with, if they are all 0, the network will never take a value. So we start it with
  //all 1's, since this will act as if ther was no recurrence for the first update. 
  
  substrate_pointer->reinitialize();
	
	if(experimentType != 33)  //If it is a NEAT experiment, the substrate can have an arbitrary number of layers, so we need to update 1+ExtraActivationUpdates num times
	{
	   substrate_pointer->dummyActivation();   //dummyActivation sets a flag so that the first update does not add on ExtraActivationUdates num updates
	}
	
  dReal roll, pitch, yaw;
	
	for(int segment = 0; segment < BODY_SEGMENTS; ++segment) {
		roll = pitch = yaw = 0.0;
		
		const dReal * torsoRotation = dBodyGetRotation(torso[segment].body);
		get_euler(torsoRotation, roll, pitch, yaw);
#if LEGSWING_ODE_DEBUG
		printf("roll: %f, pitch: %f, yaw: %f\n", roll, pitch, yaw); 
#endif
		
		for (int leg_no = 0; leg_no < num_legs; leg_no++) {
			for (int joint_no = 0; joint_no < num_joints; joint_no++) {
				
				
				dReal jangle = dJointGetHingeAngle(leg[segment][leg_no][joint_no].joint) - jointError[segment][leg_no][joint_no];  // hidding joint error for sensor
				
				int currDirectionPositive;
				
				if(jangle-lastJangle[segment][leg_no][joint_no] > 0.00001) currDirectionPositive =1; //we use a small positive number to ignore tinsy values
				else currDirectionPositive =0;
				
				//printf("jangle: %e, lastJangle_pneat[leg_no][joint_no]: %e, currDir: %i\n", jangle, lastJangle_pneat[leg_no][joint_no], currDirectionPositive);
				
				if(printJointAngles){
					ofstream jangle_file;        
					jangle_file.open ("jointAngles.txt", ios::app );
					jangle_file << jangle << " ";
					if(leg_no==num_legs-1 and joint_no==num_joints-1) jangle_file << endl;
					jangle_file.close();      
				}
				
				
				if(currDirectionPositive and !lastJangleDirectionPositve[segment][leg_no][joint_no]) numDirectionChanges++;
				if(!currDirectionPositive and lastJangleDirectionPositve[segment][leg_no][joint_no]) numDirectionChanges++;
				//if(visualize_pneat)  printf("numDirectionChanges_pneat %i \n", numDirectionChanges_pneat);
				
				lastJangleDirectionPositve[segment][leg_no][joint_no] =currDirectionPositive;
				lastJangle[segment][leg_no][joint_no] = jangle; 
				
				int xInt =joint_no; //which node we will be setting or getting. x & y are within the sheet, z specifies which sheet (0=input, 1=hidden, 2=output)
				int yInt =leg_no+(segment*2);     
				int zInt =0;        
				
#if LEGSWING_ODE_DEBUG				
				printf("About to set input (x: %i,y: %i,z: %i) to joint angle: %f \n", xInt, yInt, zInt, jangle);
#endif
				
				substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)],jangle);
								
				//<start> if inputting lastDesiredAngle    
				//xInt = xInt+1; //bump it one, cause the last desired angle goes into the input to the right of the current angle for that joint
				//#if LEGSWING_ODE_DEBUG
				//printf("about to set input (x: %i,y: %i,z: %i) to last desired joint angle: %f \n", xInt, yInt, zInt, newDesiredAngle[leg_no][joint_no]);
				//#endif
				
				//substrate_pointer->setValue(
				//                            nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)],
				//                            newDesiredAngle[segment][leg_no][joint_no]
				//                            );
			}
			
			//set whether the leg is touching the ground
			int xInt = 3;  //putting touch just to the right of the 4th legs lastAngle
			int yInt = leg_no+(segment*2); 
			int zInt = 0;
			
			substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)], thisLegIsTouching[segment][leg_no]);
		}
		
#ifndef LEGSWING_ODE_DEBUG  
		assert(num_legs==4); //warning: only works with four legs
		printf("Legs touching:  FrontLeft (%i), BackLeft (%i), BackRight (%i), FrontRight (%i)\n", thisLegIsTouching[segment][0],thisLegIsTouching[segment][1], thisLegIsTouching[segment][2], thisLegIsTouching[segment][3]); 
#endif
		
		
		
		//printf("timeStepDivisor_pneat: %f\n", timeStepDivisor_pneat);
		
		//  use if evolving sine period
		//  if(fabs(timeStepDivisor_pneat<1)) sineOfTimeStep =0; //prevent divide by zero errors, and allow them to silence the sine wave
		//  else sineOfTimeStep = sin(dReal(timeSteps_pneat)/timeStepDivisor_pneat)*M_PI;
		dReal sineOfTimeStep = sin(dReal(timeSteps)/50.0)*M_PI;

#ifdef USE_EXTRA_NODE
		dReal negSineOfTimeStep = (-1.0 * sineOfTimeStep);
#endif		

		if(visualize and sineOfTimeStep>.9999*M_PI) printf("****************************************************\n");
		if(visualize and sineOfTimeStep<-.9999*M_PI) printf("---------------------------------------------------\n");
		//printf("sineOfTimeStep: %f\n", sineOfTimeStep);
		
		
#ifndef USE_NLEG_ROBOT
		//<start> use to spread the PRYS horizontally
		//insert the roll, pitch and yaw to the 7th-9th columns of the 1st row
		//int yInt = 0; 
		//int zInt = 0;
		//dReal insertValue; 
		//
		//for(int q=0;q<3;q++){
		//    int xInt = 7+q;  
		//    if      (q==0) insertValue = roll;
		//    else if (q==1) insertValue = pitch;
		//    else           insertValue = yaw;
		//    substrate_pointer->setValue(
		//                                nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)],
		//                                insertValue
		//                                );
		//}
		//<ent> use to spread the PRYS horizontally
		
		//<start> to spread PRYS vertically
		//insert the roll, pitch and yaw to the 1st/0th-4th/3rd row of the 5th/4th columns 
		int xInt = 4;  
		int zInt = 0;
		dReal insertValue; 
		for(int q=0;q<3;q++){
			int yInt = q; 
			if      (q==0) insertValue = roll;
			else if (q==1) insertValue = pitch;
			else           insertValue = yaw;
			substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)], insertValue);
		}
		//<end>
		
		//insert a sine wave based on timeSteps
		xInt = 4;  
		int yInt = 3; 
		zInt = 0;

		substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)], sineOfTimeStep);
		
		
#else  // USE_NLEG_ROBOT
		//<start> to spread PRYS vertically
		//insert the roll, pitch and yaw to the 1st/0th-4th/3rd row of the 5th/4th columns 
		int xInt = 4;  
		int zInt = 0;
		dReal insertValue; 
		
		//roll	
		int yInt = segment*2; 
		substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)], roll);
		
		//pitch	
		yInt = (segment*2)+1; 
		substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)],	pitch);
		
		//yaw	
		xInt = 5;  
		yInt = segment*2; 
		substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)], yaw);
		//<end>
		if(segment < 1) 
		{
			//insert a sine wave based on timeSteps
			yInt = segment*2+1;
			
			substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)],	sineOfTimeStep);		
		} else
		{			
			dReal torsoAngle = dJointGetHingeAngle(torso[segment-1].joint);  //TODO: does torso zero have a valid joint?
			yInt = segment*2+1;
			substrate_pointer->setValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)],	torsoAngle);	
		}
#endif
		
		
#if SUBSTRATE_DEBUG
		cout << "State of the nodes pre-update\n";
		for (int z=0;z<numSheets;z++)
		{
			cout << "Printing Layer " << z << "************************************************" << endl;
			for (int y1=0;y1<numNodesYglobal;y1++)
			{
				for (int x1=0;x1<numNodesXglobal;x1++)
				{
					//cout << "(x,y,z): (" << x1 << "," << y1 << "," << z << "): " ;
					cout << setw(12) << setiosflags(ios::right) << fixed << 
					double(substrate_pointer->getValue(
																						 nameLookupGlobal[HCUBE::Node(x1,y1,z)]
																						 ));
				}
				cout << endl;
			}
		}
		
		
		cout << "Updating Substrate\n";
		//CREATE_PAUSE(string("Line Number: ")+toString(__LINE__));
#endif
		
		//have to update the network once for each layer of *links* (or NumLayers -1)
#if SUBSTRATE_DEBUG
		for (int a=0;a< numSheets - 1 ;a++)
		{
			substrate_pointer->update(1);
			
			cout << "State of the nodes post-update: " << a << endl;
			for (int z=0;z<numSheets;z++)
			{
				cout << "Printing Layer " << z << endl;
				for (int y1=0;y1<numNodesYglobal;y1++)
				{
					for (int x1=0;x1<numNodesXglobal;x1++)
					{
						//cout << "(x,y,z): (" << x1 << "," << y1 << "," << z << "): " ;
						cout << double(substrate_pointer->getValue(nameLookupGlobal[HCUBE::Node(x1,y1,z)]));
						cout << " ";
					}
					cout << endl;
				}
			}
		}
#else
		substrate_pointer->update(numSheets-1);
#endif        
	}
	for(int segment = 0; segment < BODY_SEGMENTS; ++segment){
		for (int leg_no = 0; leg_no < num_legs; leg_no++) {
			for (int joint_no = 0; joint_no < num_joints; joint_no++) {
				
				int xInt =joint_no*2; //which node we will be setting or getting. x & y are within the sheet, z specifies which sheet (0=input, 1=hidden, 2=output)
				int yInt =leg_no;     
				int zInt = numSheets-1;         //2 (or numSheets - 1) to get the output
				
				newDesiredAngle[segment][leg_no][joint_no] = M_PI*double(substrate_pointer->getValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)]));
				
#if LEGSWING_ODE_DEBUG
				printf("newDesiredAngle is: %f\n", newDesiredAngle[segment][leg_no][joint_no]);
#endif
				THETA[segment][leg_no][joint_no] = newDesiredAngle[segment][leg_no][joint_no] + jointError[segment][leg_no][joint_no];    // adding joint error
			}
		}
#ifdef USE_NLEG_ROBOT
		if(segment < BODY_SEGMENTS-1) {
			//get torso joint angle
			int xInt = 5;  
			int yInt = segment*2+1;
			int zInt = numSheets - 1;
			torsoJointDesiredAngle[segment] = M_PI*double(substrate_pointer->getValue(nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)]));
		}
#endif
		
		//get the timeStepDivisor
		//  xInt =10; //which node we will be setting or getting. x & y are within the sheet, z specifies which sheet (0=input, 1=hidden, 2=output)
		//  yInt =1;           
		//  zInt = 2;         //2 to get the output 
		//  timeStepDivisor = 100.0*double(substrate_pointer->getValue(
		//  nameLookupGlobal[HCUBE::Node(xInt,yInt,zInt)]));
		
		
		//if(visualize)printf("timeStepDivisor!: %f\n", timeStepDivisor);
		
		const dReal * torsoPosition = dBodyGetPosition(torso[segment].body);
				
		if(fabs(torsoPosition[0]) > maxXdistanceFrom0[segment]){
			maxXdistanceFrom0[segment] = fabs(torsoPosition[0]);
#ifndef LEGSWING_ODE_DEBUG
			printf("new maxX::::::::::::::::::::::::::::::::::::::::::::::: %f\n", maxXdistanceFrom0);
#endif
		}
		if(fabs(torsoPosition[1]) > maxYdistanceFrom0[segment]){
			maxYdistanceFrom0[segment] = fabs(torsoPosition[1]);
#ifndef LEGSWING_ODE_DEBUG
			printf("new maxY:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! %f\n", maxYdistanceFrom0);
#endif
		}
		
		currentXdistanceFrom0[segment] = fabs(torsoPosition[0]);
		currentYdistanceFrom0[segment] = fabs(torsoPosition[1]);
	}
	
	Pcontrol(); 
	
	for(int segment = 0; segment < BODY_SEGMENTS; ++segment) {
		for(int z=0;z<num_legs;z++) thisLegIsTouching[segment][z]=0; //reset these flags before checking the new state of things
	}
	
	if(fitness_function == 2) {
		for(int segment = 0; segment < BODY_SEGMENTS; ++segment) {
			for (int i = 0; i < num_legs; i++) {
				for (int j = 0; j < num_links; j++) {
					totalForce[0] += dBodyGetForce(leg[segment][i][j].body)[0];
					totalForce[1] += dBodyGetForce(leg[segment][i][j].body)[1];
					totalForce[2] += dBodyGetForce(leg[segment][i][j].body)[2];
				}
			}
			totalForce[0] += dBodyGetForce(torso[segment].body)[0];
			totalForce[1] += dBodyGetForce(torso[segment].body)[1];
			totalForce[2] += dBodyGetForce(torso[segment].body)[2];
		}
	}	
}
示例#5
0
/* returns the force acting on the body */
void body_force (t_real *res, dBodyID b) {
  dCopyVector3 (res, dBodyGetForce (b));
}
示例#6
0
文件: IoODEBody.c 项目: cdcarter/io
IoObject *IoODEBody_force(IoODEBody *self, IoObject *locals, IoMessage *m)
{
	IoODEBody_assertValidBody(self, locals, m);
	return IoVector_newWithODEPoint(IOSTATE, dBodyGetForce(BODYID));
}
示例#7
0
void	CPHCharacter::getForce(Fvector& force)
{
	if(!b_exist)return;
	force.set(*(Fvector*)dBodyGetForce(m_body));
}
示例#8
0
const dReal * SParts::getForce()
{
	return dBodyGetForce(m_odeobj->body());
}
示例#9
0
const dReal* ODE_Link::getForce(){
    return dBodyGetForce(bodyId);
}
示例#10
0
文件: base.cpp 项目: cxindex/gtglos
void base::hack_2d(void)
{
	const dReal *rot = dBodyGetAngularVel (body);
	const dReal *quat_ptr;
	dReal quat[4], quat_len;

	quat_ptr = dBodyGetQuaternion (body);
	quat[0] = quat_ptr[0];
	quat[1] = 0;
	quat[2] = 0;
	quat[3] = quat_ptr[3];
	quat_len = sqrt (quat[0] * quat[0] + quat[3] * quat[3]);
	quat[0] /= quat_len;
	quat[3] /= quat_len;
	dBodySetQuaternion (body, quat);
	dBodySetAngularVel (body, 0, 0, rot[2]);

//Restricting Rotation To One Axis
//The plane2D stops objects rotating along non-2d axes,
//but it does not compensate for drift

    const dReal *rot1 = dBodyGetAngularVel( body );
    const dReal *quat_ptr1;
    dReal quat1[4], quat_len1;
    quat_ptr1 = dBodyGetQuaternion( body );
    quat1[0] = quat_ptr1[0];
    quat1[1] = 0;
    quat1[2] = 0; 
    quat1[3] = quat_ptr1[3]; 
    quat_len1 = sqrt( quat1[0] * quat1[0] + quat1[3] * quat1[3] );
    quat1[0] /= quat_len1;
    quat1[3] /= quat_len1;
    dBodySetQuaternion( body, quat1 );
    dBodySetAngularVel( body, 0, 0, rot1[2] );

    dMatrix3 R = { 0, 0, 0, 0, 0, 1};
    // 0 0 y
    if(!rotatebit) //if there is no set rotatebit then don't make rotate in ode
    {
		quat1[0] = 0;
		quat1[1] = 0;
		quat1[2] = 0; 
		quat1[3] = 1; 
	    dBodySetQuaternion( body, quat1 );
		dBodySetAngularVel( body, 0, 0, 0 );
	}

	static dVector3 pointrelvel;
	const dReal *odepos;
	const dReal *force;
	
	dBodyGetRelPointVel(body,0,0,0,pointrelvel);
	odepos=dBodyGetPosition(body); 
	force = dBodyGetForce (body);
		
	
	dBodySetForce(body,force[0],force[1],0.000);
	if (odepos[2]>=0.001 || odepos[2]<=-0.001 ){
		dBodySetPosition (body,odepos[0],odepos[1], 0.000);
		dBodyAddRelForce (body,0,0, -(pointrelvel[2]));
		dBodySetTorque (body, 0.00, 0.00, 0.000);
	}
}