예제 #1
0
///////////////////////////////
//State derivatives calculation
void Kinematics::calcDerivatives()
{
	// variable declaration
	geometry_msgs::Vector3 tempVect;
	double Reb[9];

	// create transformation matrix from state orientation quaternion
	quat2rotmtx (parentObj->states.pose.orientation, Reb);

	// create position derivatives from earth velocity
	posDot = Reb*parentObj->states.velocity.linear;
	if (isnan(posDot)) {ROS_FATAL("NaN member in position derivative vector"); ros::shutdown();}

	// create body velocity derivatives from acceleration, angular rotation and body velocity
	linearAcc = (1.0/mass)*forceInput;
	if (isnan(linearAcc)) {ROS_FATAL("NaN member in linear acceleration vector"); ros::shutdown();}
	geometry_msgs::Vector3 corriolisAcc;
	vector3_cross(-parentObj->states.velocity.angular, parentObj->states.velocity.linear, &corriolisAcc);
	if (isnan(corriolisAcc)) {ROS_FATAL("NaN member in corriolis acceleration vector"); ros::shutdown();}
	speedDot = linearAcc + corriolisAcc;
	if (isnan(speedDot)) {ROS_FATAL("NaN member in velocity derivative vector"); ros::shutdown();}

	// create angular derivatives quaternion from angular rates
	quatDot.w = 1.0;
	quatDot.x = parentObj->states.velocity.angular.x*0.5*parentObj->dt;
	quatDot.y = parentObj->states.velocity.angular.y*0.5*parentObj->dt;
	quatDot.z = parentObj->states.velocity.angular.z*0.5*parentObj->dt;
	if (isnan(quatDot)) {ROS_FATAL("NaN member in quaternion derivative vector"); ros::shutdown();}

	// create angular rate derivatives from torque
	vector3_cross(parentObj->states.velocity.angular, J*parentObj->states.velocity.angular, &tempVect);
	tempVect = -tempVect+torqueInput;
	rateDot = Jinv*tempVect;
	if (isnan(rateDot)) {ROS_FATAL("NaN member in angular velocity derivative vector"); ros::shutdown();}
}
예제 #2
0
vector2 v3tov2(vector3 vec)
{
  return (vector2) { .x = vec.x, .y = vec.y };
}

vector2 doProjectPoint(projector tr, vector3 p)
{
  transformer_matrix tm = { .matrix = {{ 0.0f }} };
  for (int i = 0; i<2; ++i) {
    float t = vector3_dot(vector3_norm(
                            vector3_sub(tr.dir,
                                        vector3_mul(tr.axis[1-i],
                                                    vector3_dot(tr.axis[1-i],
                                                                tr.dir)))),
                          vector3_cross(tr.axis[0], tr.axis[1]));
    float k = sqrtf(1.0f - sqr(t))/t;
    for(int j = 0; j<3; ++j) {
      tm.matrix[i][j] = vector3_dot(axis[j], tr.axis[i]);
      tm.matrix[i][j] += sqrtf(1.0f - sqr(tm.matrix[i][j])) * k *
        vector3_dot(axis[j], vector3_cross(tr.axis[0], tr.axis[1]));
    }
    tm.matrix[i][3] = 0;
  }
  return v3tov2(doTransformMatrix(tm, vector3_sub(p, tr.base)));
}
예제 #3
0
/// \brief Returns the infinite line that is the intersection of \p plane and \p other.
inline DoubleLine plane3_intersect_plane3(const Plane3& plane, const Plane3& other)
{
  DoubleLine line;
  line.direction = vector3_cross(plane.normal(), other.normal());
  switch(vector3_largest_absolute_component_index(line.direction))
  {
  case 0:
    line.origin.x() = 0;
    line.origin.y() = (-other.dist() * plane.normal().z() - -plane.dist() * other.normal().z()) / line.direction.x();
    line.origin.z() = (-plane.dist() * other.normal().y() - -other.dist() * plane.normal().y()) / line.direction.x();
    break;
  case 1:
    line.origin.x() = (-plane.dist() * other.normal().z() - -other.dist() * plane.normal().z()) / line.direction.y();
    line.origin.y() = 0;
    line.origin.z() = (-other.dist() * plane.normal().x() - -plane.dist() * other.normal().x()) / line.direction.y();
    break;
  case 2:
    line.origin.x() = (-other.dist() * plane.normal().y() - -plane.dist() * other.normal().y()) / line.direction.z();
    line.origin.y() = (-plane.dist() * other.normal().x() - -other.dist() * plane.normal().x()) / line.direction.z();
    line.origin.z() = 0;
    break;
  default:
    break;
  }

  return line;
}
예제 #4
0
파일: moto-ray.c 프로젝트: qewerty/moto.old
int moto_ray_intersect_cylinder_dist(MotoRay *self,
        float *dist, float a[3], float b[3], float radius)
{
    const float z[3] = {0, 0, 1};
    float c[3], tmp;
    vector3_dif(c, a, b);

    float height = vector3_length(c);
    c[0] /= height;
    c[1] /= height;
    c[2] /= height;

    float cross[3];
    vector3_cross(cross, c, z);

    float cos0 = vector3_dot(c, z);
    float sin0 = acos(cos0);

    float m[16], im[16], t[16], tmpm[16];

    matrix44_rotate_from_axis_sincos(m, sin0, cos0, cross[0], cross[1], cross[2]);
    matrix44_translate(t, a[0], b[0], c[0]);
    matrix44_mult(tmpm, t, m);

    matrix44_inverse(im, tmpm, m, tmp);

    MotoRay r;
    moto_ray_set_transformed(&r, self, im);

    

    *dist = 1;
    return 1;
}
예제 #5
0
/// \brief Keep the value of \p infinity as small as possible to improve precision in Winding_Clip.
void Winding_createInfinite(FixedWinding& winding, const Plane3& plane, double infinity)
{
  double max = -infinity;
  int x = -1;
  for (int i=0 ; i<3; i++)
  {
    double d = fabs(plane.normal()[i]);
    if (d > max)
    {
      x = i;
      max = d;
    }
  }
  if(x == -1)
  {
    globalErrorStream() << "invalid plane\n";
    return;
  }
    
  DoubleVector3 vup = g_vector3_identity;  
  switch (x)
  {
  case 0:
  case 1:
    vup[2] = 1;
    break;    
  case 2:
    vup[0] = 1;
    break;    
  }


  vector3_add(vup, vector3_scaled(plane.normal(), -vector3_dot(vup, plane.normal())));
  vector3_normalise(vup);
    
  DoubleVector3 org = vector3_scaled(plane.normal(), plane.dist());
  
  DoubleVector3 vright = vector3_cross(vup, plane.normal());
  
  vector3_scale(vup, infinity);
  vector3_scale(vright, infinity);

  // project a really big  axis aligned box onto the plane
  
  DoubleLine r1, r2, r3, r4;
  r1.origin = vector3_added(vector3_subtracted(org, vright), vup);
  r1.direction = vector3_normalised(vright);
  winding.push_back(FixedWindingVertex(r1.origin, r1, c_brush_maxFaces));
  r2.origin = vector3_added(vector3_added(org, vright), vup);
  r2.direction = vector3_normalised(vector3_negated(vup));
  winding.push_back(FixedWindingVertex(r2.origin, r2, c_brush_maxFaces));
  r3.origin = vector3_subtracted(vector3_added(org, vright), vup);
  r3.direction = vector3_normalised(vector3_negated(vright));
  winding.push_back(FixedWindingVertex(r3.origin, r3, c_brush_maxFaces));
  r4.origin = vector3_subtracted(vector3_subtracted(org, vright), vup);
  r4.direction = vector3_normalised(vup);
  winding.push_back(FixedWindingVertex(r4.origin, r4, c_brush_maxFaces));
}
예제 #6
0
파일: moto-ray.c 프로젝트: qewerty/moto.old
/* TODO: Needs to be optimized? */
int moto_ray_intersect_triangle(MotoRay *self,
        MotoIntersection *intersection,
        float A[3], float B[3], float C[3])
{
    float tmp;
    float normal[3], v1[3], v2[3];
    vector3_dif(v1, B, A);
    vector3_dif(v2, C, A);

    vector3_cross(normal, v1, v2);
    vector3_normalize(normal, tmp);

    if( ! moto_ray_intersect_plane(self, intersection, A, normal))
        return 0;

    float n1[3], n2[3], n3[3], oA[3], oB[3], oC[3];
    vector3_dif(oA, A, self->pos);
    vector3_dif(oB, B, self->pos);
    vector3_dif(oC, C, self->pos);

    if(vector3_dot(self->dir, normal) < 0) /* faceforward */
    {
        vector3_cross(n1, oC, oA);
        vector3_normalize(n1, tmp);
        if(vector3_dot(n1, self->dir) > 0)
            return 0;

        vector3_cross(n2, oB, oC);
        vector3_normalize(n2, tmp);
        if(vector3_dot(n2, self->dir) > 0)
            return 0;

        vector3_cross(n3, oA, oB);
        vector3_normalize(n3, tmp);
        if(vector3_dot(n3, self->dir) > 0)
            return 0;
    }
    else
    {
        vector3_cross(n1, oA, oC);
        vector3_normalize(n1, tmp);
        if(vector3_dot(n1, self->dir) > 0)
            return 0;

        vector3_cross(n2, oC, oB);
        vector3_normalize(n2, tmp);
        if(vector3_dot(n2, self->dir) > 0)
            return 0;

        vector3_cross(n3, oB, oA);
        vector3_normalize(n3, tmp);
        if(vector3_dot(n3, self->dir) > 0)
            return 0;
    }

    return 1;
}
예제 #7
0
파일: vector3.c 프로젝트: tatref/misc
void vector3_test()
{
	vector3 zero = {0,0,0};
	vector3 one = {1,1,1};
	vector3 y = {0,1,0};
	vector3 half = {0.5,0.5,0.5};
	vector3 a;
	
	vector3_invert(&a, &one);
	vector3_subtract(&a, &one, &a);
	vector3_add(&a, &a, &one);
	vector3_print(&a);
	
	vector3_multiply(&a, &one, 0.5);
	vector3_divide(&a, &a, 2);
	vector3_print(&a);
	
	vector3_reflect(&a, &one, &y);
	vector3_print(&a);
	
	vector3_scalar_sub(&a, &zero, -0.5);
	vector3_scalar_add(&a, &a, 0.5);
	vector3_print(&a);
	
	vector3_cross(&a, &one, &y);
	vector3_print(&a);
	
	srand(3);
	vector3_random(&a);
	vector3_print(&a);
	
	printf("%.2f %.2f\n", 
		   vector3_dot(&half, &y), vector3_angle(&half, &y));
	
	printf("%.2f %.2f\n", 
		   vector3_distance(&one, &y), vector3_distancesq(&one, &y));
	
	vector3_copy(&a, &one);
	printf("%.2f %.2f\n", 
		   vector3_length(&one), vector3_length(vector3_normalize(&a)) );
}
예제 #8
0
// Wrench calculation function
geometry_msgs::Vector3 PanosContactPoints::getForce()
{
	double Reb[9];
	double kFLong, kFLat, kFrictionE, kFrictionX, kFrictionY;
	int i, j;
	contact = false;
	safe = true; // NaN protection flag
	geometry_msgs::Vector3 Euler;

	geometry_msgs::Quaternion quat = parentObj->states.pose.orientation; // Read vehicle orientation quaternion
	quat2rotmtx(quat, Reb); // Construct the rotation matrix
	Euler = quat2euler(quat);

	geometry_msgs::Wrench tempE, totalE; /** @todo This is a TODO list example */
	geometry_msgs::Vector3 dx,we,vpoint,Ve;

	totalE.force.x = 0;
	totalE.force.y = 0;
	totalE.force.z = 0;
	totalE.torque.x = 0;
	totalE.torque.y = 0;
	totalE.torque.z = 0;

	// Get velocity in the inertial frame
	Ve = parentObj->kinematics.posDot;

	// Read vehicle coordinates
	uavpos[0]=parentObj->states.pose.position.x;
	uavpos[1]=parentObj->states.pose.position.y;
	uavpos[2]=parentObj->states.pose.position.z;

	// Rotate contact points coordinates from body frame to earth frame
	multi_mtx_mtx_3Xn(Reb,pointCoords,cpi_up,contactPtsNo);

	// Place the spring ends to the contact points positions
	for (i=0;i<3;i++)
	{
		for (j=0;j<contactPtsNo;j++) {
			cpi_up[contactPtsNo*i+j] += uavpos[i]; // Place upper spring end to contact point
			if (i==2)
				cpi_up[contactPtsNo*i+j] -= len; //Raise the upper spring end to obtain a visually pleasing result in RViz
			cpi_down[contactPtsNo*i+j]=cpi_up[contactPtsNo*i+j]; // Place lower spring end to contact point
		}
	}

	// Rotate body angular speeds to earth frame
	we = Reb*parentObj->states.velocity.angular;

	// Main calculations for each contact point
	for (i=0;i<contactPtsNo;i++)
	{
		cpi_down[i+2*contactPtsNo]+=len; // Place lower spring end "len" below upper spring end
		// Calculate force arm
		dx.x = (cpi_up[i]-uavpos[0]);
		dx.y = (cpi_up[i+contactPtsNo]-uavpos[1]);
		dx.z = (cpi_up[i+2*contactPtsNo]-uavpos[2]);

		if (cpi_down[i+2*contactPtsNo]>0) // if the lower spring end touches the ground
		{
			cpi_down[i+2*contactPtsNo]=0; // Force lower spring end to stay at ground level
			contact=true;
			spp[i]=len+cpi_up[i+2*contactPtsNo]; // Calculate current spring contraction
			spd[i]=(spp[i]-sppprev[i])/parentObj->dt; // Calculate current spring contraction spreed
			vector3_cross(we,dx, &vpoint); // Contact point Earth-frame speed due to vehicle rotation
			vpoint = Ve+vpoint; // Add vehicle velocity to find total contact point velocity

			// Calculate spring force. Acts only upon Earth z-axis
			// tempE.force.z = -(kspring*spp[i] + mspring*spd[i]);
			tempE.force.z = -(springIndex[i]*spp[i] + springIndex[i + contactPtsNo]*spd[i]);
			// Make spring force negative or zero, as the spring lower end isn't fixed on the ground
			if (tempE.force.z > 0)
				tempE.force.z = 0;
			/** @todo model full spring contraction (possibly with exponential force curve after full contraction?) */

			int tempIndex = materialIndex[i];
			// Get longitudinal and lateral friction coefficients for this surface
			kFLong = frictForw[tempIndex];
			kFLat = frictSide[tempIndex];

			if ((inputBrake>0.9) && (i<3)) { // Apply breaks
				kFLong = 1.0;
			}

			// Convert friction coefficients to the Earth frame
			double trackAngle = Euler.z - atan2(vpoint.y, vpoint.x);
			if (i==2) { // Apply steeering
				trackAngle = trackAngle + inputSteer;
			}

			// Calculate the magnitude of the friction force in the Earth frame
			double frictionLong = fabs(sqrt(kFLong*(kFLong*cos(trackAngle)*cos(trackAngle)+kFLat*sin(trackAngle)*sin(trackAngle)))*tempE.force.z);
			frictionLong = std::max(frictionLong - 0.05*frictionLong/sqrt(vpoint.x*vpoint.x + vpoint.y*vpoint.y + 0.001), 0.0); //Aply static friction
			frictionLong = frictionLong*cos(trackAngle);

			double frictionLat = fabs(sqrt(kFLat*(kFLat*sin(trackAngle)*sin(trackAngle)+kFLong*cos(trackAngle)*cos(trackAngle)))*tempE.force.z);
			frictionLat = std::max(frictionLat - 0.05*frictionLat/sqrt(vpoint.x*vpoint.x + vpoint.y*vpoint.y + 0.001), 0.0); //Aply static friction
			frictionLat = frictionLat*sin(trackAngle);

			tempE.force.x = -frictionLong*cos(Euler.z)-frictionLat*sin(Euler.z);
			tempE.force.y = -frictionLong*sin(Euler.z)+frictionLat*cos(Euler.z);

			// Add current contact point force contribution to the total
			totalE.force = totalE.force + tempE.force;
			// Calculate current contact point torque
			vector3_cross(dx,tempE.force, &tempE.torque);
			// Add current contact point torque contribution to the total
			totalE.torque = totalE.torque + tempE.torque;

			if (i==2) {
				// std::cout << kFrictionLong << ',';
				// std::cout << trackAngle << ',';
				// std::cout << kFrictionE << ',';
				// std::cout << tempE.force.x << ',';
				// std::cout << tempE.force.y << ',';
				// // std::cout << tempB.force.z << ',';
				// std::cout << std::endl;
			}
		}

		// If there is no ground contact
		else {
			// Set spring contraction to zero
			spp[i] = 0;
			spd[i] = 0;
		}
		sppprev[i] = spp[i];
	}

	// Chech for rogue NaN results
	if (isnan(totalE.force.x) or isnan(totalE.force.y) or isnan(totalE.force.z)) {
		safe = false; /** @todo remove the safe safety, it is not used*/
		ROS_FATAL("State NAN in PanosGroundReactions force calculation!");
		ros::shutdown();
	}

	if (isnan(totalE.torque.x) or isnan(totalE.torque.y) or isnan(totalE.torque.z)) {
		safe = false;
		ROS_FATAL("State NAN in PanosGroundReactions torque calculation!");
		ros::shutdown();
	}

	// If there is a ground contact write the resulting wrench
	if (contact and safe) {
		wrenchGround.force= Reb/totalE.force;
		wrenchGround.torque= Reb/totalE.torque;
	}
	// Otherwise there is no wrench created
	else {
		wrenchGround.force.x = 0;
		wrenchGround.force.y = 0;
		wrenchGround.force.z = 0;
		wrenchGround.torque.x = 0;
		wrenchGround.torque.y = 0;
		wrenchGround.torque.z = 0;
	}

	return wrenchGround.force;

}
예제 #9
0
파일: plfig.c 프로젝트: gekola/BSUIR-labs
#include "plfig.h"

line3 getIntersection(plfig f1, plfig f2)
{
  const line3 line3z = { .src  = (vector3) { .x = 0.0f, .y = 0.0f, .z=0.0f },
                         .dest = (vector3) { .x = 0.0f, .y = 0.0f, .z=0.0f } };
  vector3 n1 = vector3_norm(vector3_cross(line3ToVector3(f1->line),
                                          line3ToVector3(f1->next->line)));
  vector3 n2 = vector3_norm(vector3_cross(line3ToVector3(f2->line),
                                          line3ToVector3(f2->next->line)));
  vector3 s = vector3_cross(n1, n2);
  if (vector3_dot(s, s) < eps)
    return line3z;
  s = vector3_norm(s);

  float mi = __builtin_inff(), ma = -__builtin_inff();
  vector3 dir = vector3_cross(n1, s);
  vector3 p = vector3_add(f1->line.src,
                          vector3_mul(dir,
                                      vector3_dot(vector3_sub(f2->line.src,
                                                              f1->line.src),
                                                  n2) / vector3_dot(dir, n2)));
  float pp = vector3_dot(s, p);

  figure3 *f = f1;
  while (f) {
    ma = max(ma, vector3_dot(f->line.src, s) - pp);
    mi = min(mi, vector3_dot(f->line.src, s) - pp);
    f = f->next;
  }
  f = f2;
예제 #10
0
Vector3 testCross1(const Vector3& a, const Vector3& b)
{
  return vector3_cross(a, b);
}
예제 #11
0
inline Vector3 triangle_cross (const BasicVector3<Element>& x, const BasicVector3<Element> y, const BasicVector3<
		Element>& z)
{
	return vector3_cross(y - x, z - x);
}