/*!	This computes the wrenches of the virtual contact as used for grasp 
	quality computations. The important aspect to take into account is 
	wether we are using an object or not.
	
	If we are using an object, we assume that contact centroid and maxradius 
	have already been set to match those of the	object (hopefully, the grasp 
	has done this). Also, the force applied be the contact is scaled by a 
	function of the distance between the contact and the actual object.
	
	If there is no object, we assume that contact centroid and maxradius 
	have been preset dependign only on the set of virtual contacts that 
	make up the grasp (again, we hope the grasp has done this). There is no 
	scaling involved, all forces are handled normally as if the contact was 
	actually on the object.
*/
void
VirtualContact::computeWrenches(bool useObjectData, bool simplify)
{
	int i;
	//double alpha;
	vec3 radius, forceVec,torqueVec,tangentX,tangentY;

	//we need everything to be wrt world coordinates
	position worldLoc;
	vec3 worldNormal;

	if (!useObjectData) {	
		worldLoc = getWorldLocation();
		worldNormal = getWorldNormal();
		transf worldFrame = frame * body1->getTran();
		tangentX = worldFrame.affine().row(0);
		tangentY = worldFrame.affine().row(1);
	} else {
//		LOOK AT VIRTUAL CONTACT ON THE HAND
		worldLoc = getWorldLocation();
		worldNormal = getWorldNormal();
		tangentX = vec3(0,1,0) * worldNormal;
		tangentX = normalise(tangentX);
		tangentY = worldNormal * tangentX;
	}

	//mCenter needs to be already set to object cog if needed as such
	radius = worldLoc - mCenter;
	if (wrench) delete [] wrench;

	if (simplify) {
		numFCWrenches = 1; //this is hack-ish, should be fixed
		wrench = new Wrench[1];
		wrench[0].force = worldNormal;
		wrench[0].torque = (radius*worldNormal) / mMaxRadius;
		return;
	}

	numFCWrenches = numFrictionEdges;
	wrench = new Wrench[numFrictionEdges];

	//SHOULD SET UP COEFFICIENT BASED ON MATERIALS!
	for (i=0;i<numFCWrenches;i++) {
		forceVec = worldNormal + (tangentX*cof*frictionEdges[6*i])+ (tangentY*cof*frictionEdges[6*i+1]);
		//max friction is normal_force_magnitude (which is 1) * coeff_of_friction 
		//possible friction for this wrench is (friction_edge * max_friction) in the X and Y direction of the contact

		wrench[i].force = forceVec;

		wrench[i].torque = ( (radius*forceVec) + worldNormal*cof*frictionEdges[6*i+5] )/mMaxRadius;
		//max torque is contact_radius * normal_force_magnitude (which is 1) * coeff_of_friction
		//possible torque for this wrench is (friction_edge * max_torque) in the direction of the contact normal
		//the contact_radius coefficient is already taken into account in the friction_edge
	}
}
Example #2
0
LocalFrame SceneObject::getAutoGenWorldLocalFrame(unsigned fi, const vec3f& position, bool flat) const
{
	LocalFrame lf;
	lf.buildFromNormal(getWorldNormal(fi, position, flat));
	/*
	lf.n = getWorldNormal(fi, position, flat);
	vec3f tmpT;
	tmpT = (std::abs(lf.n.z) > 0.99f) ? vec3f(1,0,0) : vec3f(0,0,1);
	lf.s = lf.n.cross(tmpT);
	lf.s.normalize();
	lf.t = lf.s.cross(lf.n);
	lf.t.normalize();
	*/
	/*
	vec3f axis = up.cross(lf.n);
	float angle = acos(clampf(up.dot(lf.n), -1, 1));
	
	if (!(axis.length() >= 1e-6f || (axis.length() < 1e-6f && n.dot(lf.n) == 1.f)))
	{
		printf("error , %.8f\n" , n.dot(lf.n));
	}
	axis.normalize();
	//if (axis.length() < 1e-6f)
	//{
	//	lf.s = vec3f(1,0,0);
	//	lf.t = vec3f(0,0,1);
	//}
	//else
	{
		lf.s = vec3f(rotMat(axis, angle)*vec4<float>(vec3f(1,0,0), 0));
		lf.t = vec3f(rotMat(axis, angle)*vec4<float>(vec3f(0,0,1), 0));
	}
	*/
	return lf;
}