Arquivos
ardrone_autonomy/ARDroneLib/Soft/Lib/Maths/maths.c
T
2012-06-26 12:19:39 -07:00

167 linhas
4.1 KiB
C

/**
* \file maths.c
* \brief Maths library used by ARDrone
* \author Sylvain Gaeremynck <sylvain.gaeremynck@parrot.com>
* \author Jean-Baptiste Lanfrey <jean-baptiste.lanfrey@parrot.com>
* \version 1.0
*/
#include <Maths/maths.h>
float32_t f_epsilon = FLT_EPSILON;
bool_t f_is_zero( float32_t f )
{
bool_t ret;
float32_t af;
ret = FALSE;
af = (float32_t)fabsf( f );
if( af < f_epsilon )
ret = TRUE;
return ret;
}
float32_t f_zero( float32_t f )
{
if( f_is_zero(f) )
return 0.0f;
return f;
}
float32_t asin_taylor( float32_t x )
{
// float32_t xsquare = x*x;
// thrid order
return (float32_t)(x*(1.0f+x*x*0.16666667f));
// fifth order
// return (x*(1.0+xsquare*(1.0/6.0 + 3.0*xsquare/40.0);
}
float32_t atan2_taylor( float32_t num, float32_t den )
{
float32_t res;
if ( f_is_zero(den) ) {
// pi/2
res = 1.5707963268f;
}
else {
float32_t x = num/den;
// float32_t xsquare = x*x;
// thrid order
res = (float32_t)x*(1.0f-x*x*.33333333f);
// fifth order
// res = x*(1.0-xsquare*(1.0/3.0 + xsquare/5.0));
}
return (res);
}
// Polar saturation
void f_polar_sat( float32_t max, float32_t* phi, float32_t* theta)
{
float32_t alpha;
float32_t c_alpha, s_alpha;
float32_t phi_in;
float32_t theta_in;
phi_in = *phi;
theta_in = *theta;
// angle beta du plan du drone avec l'horizontal vaut beta = acosf(cosf(theta_in)*cosf(phi_in))
// on peut approximer par beta^2 = theta_in^2 + phi_in^2
if ( theta_in*theta_in + phi_in*phi_in > max*max ) {
alpha = (float32_t)atan2f(theta_in, phi_in);
sincosf( alpha, &s_alpha, &c_alpha);
*phi = max * c_alpha;
*theta = max * s_alpha;
}
}
float32_t exp_taylor( float32_t x )
{
return (float32_t)(1.0f+x+x*x*0.5f);
}
float32_t secant_taylor( float32_t x ) // secant(x) = 1 / cos(x)
{
return (float32_t)(1.0f+x*x*0.5f);
}
float32_t cos_taylor( float32_t x )
{
return (float32_t)(1.0f-x*x*0.5f);
}
float32_t sin_taylor( float32_t x )
{
return (float32_t)(x*(1.0f-x*x*.16666667f));
}
float32_t pow_taylor( float32_t x , float32_t y )
{
//x^y pour x> et y entier
float32_t coeff_3=(y*(y-1)*(y-2))/6;
float32_t coeff_2=(y*(y-1))/2;
float32_t coeff_1=y;
// float32_t puissance;
//if y positif{
return (float32_t)(coeff_3*(x-1)*(x-1)*(x-1)+coeff_2*(x-1)*(x-1)+(coeff_1*(x-1))+1);
//else
//puissance=(coeff_3*(x-1)*(x-1)*(x-1)+coeff_2*(x-1)*(x-1)+(coeff_1*(x-1))+1);
//return (float32_t) 1/puissance;
//}
}
float32_t time_navdata_in_ms(uint32_t current_time, int32_t dec)
{
//convert time given by get_current_time() in millisecond
uint32_t time_sec, time_micro_sec;
float32_t time_milli_sec;
time_sec = current_time >> dec;
time_micro_sec = current_time - (time_sec << dec);
time_milli_sec = (float32_t)(1000.0*time_sec + time_micro_sec/1000.0);
return(time_milli_sec);
}
#ifndef __ARDRONE_BIT_COUNTING_FUNCTIONS__
#define __ARDRONE_BIT_COUNTING_FUNCTIONS__
static uint32_t MASK_01010101 = (((unsigned int)(-1))/3); // 01010101010101010101010101010101
static uint32_t MASK_00110011 = (((unsigned int)(-1))/5); // 00110011001100110011001100110011
static uint32_t MASK_00001111 = (((unsigned int)(-1))/17); // 00001111000011110000111100001111
static inline int bitcountNifty_8(unsigned int n, uint32_t MASK_01010101, uint32_t MASK_00110011, uint32_t MASK_00001111)
{
n = (n & MASK_01010101) + ((n >> 1) & MASK_01010101) ;
n = (n & MASK_00110011) + ((n >> 2) & MASK_00110011) ;
n = (n & MASK_00001111) + ((n >> 4) & MASK_00001111) ;
return n;
}
static inline int bitcountNifty(unsigned int n, uint32_t MASK_01010101, uint32_t MASK_00110011, uint32_t MASK_00001111)
{
n = (n & MASK_01010101) + ((n >> 1) & MASK_01010101) ;
n = (n & MASK_00110011) + ((n >> 2) & MASK_00110011) ;
n = (n & MASK_00001111) + ((n >> 4) & MASK_00001111) ;
return n % 255 ;
}
uint32_t nb_bits_differents(uint32_t p, uint32_t q)
{
return bitcountNifty(p^q, MASK_01010101, MASK_00110011, MASK_00001111);
}
uint32_t nb_bits_differents_8(uint32_t p, uint32_t q)
{
return bitcountNifty_8(p^q, MASK_01010101, MASK_00110011, MASK_00001111);
}
#endif