Esempio n. 1
0
void vector_difference_to_euler_angles(fixedpointnum *v1, fixedpointnum *v2, fixedpointnum *euler) {
    // take the difference between the two attitudes and return the euler angles between them
    // find the axis of rotation and angle between the two downVectors
   // the cross products of the two vectors will give us the axis of rotation from one to the other
   fixedpointnum axisofrotation[3];
   vector_cross_product(v1, v2, axisofrotation);

   fixedpointnum axislength=lib_fp_sqrt(normalize_vector(axisofrotation));
   
   // get the angle of rotation between the two vectors
   fixedpointnum angle=lib_fp_atan2(axislength, vector_dot_product(v1, v2));

   fixedpointnum unitvector[3];
   unitvector[0]=0;
   unitvector[1]=FIXEDPOINTONE;
   unitvector[2]=0;
   
   euler[0]=lib_fp_multiply(vector_dot_product(axisofrotation, unitvector), angle);

   unitvector[0]=FIXEDPOINTONE;
   unitvector[1]=0;
   unitvector[2]=0;
   
   euler[1]=lib_fp_multiply(vector_dot_product(axisofrotation, unitvector), angle);
}
fixedpointnum navigation_getdistanceandbearing(fixedpointnum lat1,fixedpointnum lon1,fixedpointnum lat2,fixedpointnum lon2,fixedpointnum *bearing)
   { // returns fixedpointnum distance in meters and bearing in fixedpointnum degrees from point 1 to point 2
   fixedpointnum latdiff=lat2-lat1;
   fixedpointnum londiff=lib_fp_multiply(lon2-lon1,lib_fp_cosine(lat1>>LATLONGEXTRASHIFT));
      
   *bearing = FIXEDPOINT90 + lib_fp_atan2(-latdiff, londiff);
   if (*bearing >FIXEDPOINT180) *bearing -= FIXEDPOINT360;
   
   // distance is 111319 meters per degree. This factor needs to be shifted 16 to make it a fixedpointnum.
   // Since lat and lon are already shifted by 6,
   // we will shift by 10 more total.  Shift lat and long by 8 and the constant by 2 to get the extra 10.
   // The squaring will overflow our fixedpointnum at distances greater than 1000 meters or so, so test for size and shift accordingly
   if (lib_fp_abs(latdiff)+lib_fp_abs(londiff)>40000L)
      { // for big distances, don't shift lat and long.  Instead shift the constant by 10.
      // this will get us to 32 kilometers at which point our fixedpoingnum can't hold a larger distance.
      return(lib_fp_multiply(lib_fp_sqrt(lib_fp_multiply(latdiff,latdiff)+lib_fp_multiply(londiff,londiff)),113990656L));
      }
   else
      {
      latdiff=latdiff<<8;
      londiff=londiff<<8;
      return(lib_fp_multiply(lib_fp_sqrt(lib_fp_multiply(latdiff,latdiff)+lib_fp_multiply(londiff,londiff)),445276L));
      }
   }