Ejemplo n.º 1
0
//Значение сигнала
//t - с
//sin(fi0 - 2pi(fo*t + kt^2/2))
short signal(double t)
{
	int rnd=0;
	double pi=0;
	short signal=0;
	short signalInst=0;
	double f0=DEV_WorkFreq;
	double dfdt = 0;
	//currentF = f0  + dfdt * t;
	//rnd = rand() % 650;// * (((int)(t * DEV_SampleFreq) )% 2);
	pi = MATH_Pi;
	//short signal = 6550*sin( 2*pi*(f0 * t + dfdt * t*t / 2)) + 3000 * sin( 2*pi*(3*f0 * t + dfdt * t*t / 2)-0.6*pi) +	2000 * sin( 2*pi*(4*f0 * t + dfdt * t*t / 2)-0.2*pi) + 2000 * sin( 2*pi*(2*f0 * t + dfdt * t*t / 2)-0.2*pi)+ rnd;
	//short signal = 6550*sin( 2*pi*(f0 * t + dfdt * t*t / 2)) + 500 * sin( 2*pi*(3*f0 * t + dfdt * t*t / 2)-0.6*pi) +	500 * sin( 2*pi*(4*f0 * t + dfdt * t*t / 2)-0.2*pi) + 500 * sin( 2*pi*(2*f0 * t + dfdt * t*t / 2)-0.2*pi);//+ rnd;
#ifdef MSVC
	signal = 6550*sin(2*pi*(f0 * t + dfdt * t*t / 2))+3500*sin(2*pi*2*(f0 * t + dfdt * t*t / 2))+1000*sin(2*pi*3*(f0 * t + dfdt * t*t / 2));
		//+4000*sin(2*5*pi*(f0 * t + dfdt * t*t / 2))+4500*sin(2*7*pi*(f0 * t + dfdt * t*t / 2))+5000*sin(2*9*pi*(f0 * t + dfdt * t*t / 2));//+rnd;
	signalInst = 6550*sin(2*pi*(f0 * t + dfdt * t*t / 2));
#else
	signal = 6550*arm_sin_f32( -2*pi*(f0 * t + dfdt * t*t / 2));//+rnd;
	signalInst = 6550*arm_sin_f32( -2*pi*(f0 * t + dfdt * t*t / 2));
#endif

	//fprintf(sinFile, "%i;", signalInst);
	return signal;
}
Ejemplo n.º 2
0
void IMU::computeYaw(void) {
	float32_t sqrt_result, arg1, arg2;
	float32_t mag[3];
	mag[0] = magnetometer.axis_f[0];
	mag[1] = magnetometer.axis_f[1];
	mag[2] = magnetometer.axis_f[2];

	//Normalise measurement:
	arg1 = (float32_t) (mag[0]) * (mag[0]) + (mag[1]) * (mag[1]) + (mag[2]) * (mag[2]);
	arm_sqrt_f32(arg1, &sqrt_result);
	mag[0] /= sqrt_result;
	mag[1] /= sqrt_result;
	mag[2] /= sqrt_result;

	arg1 = arm_sin_f32(XRollAngleInRad) * mag[2] - arm_cos_f32(XRollAngleInRad) * mag[1];
	arg2 = arm_cos_f32(YPitchAngleInRad) * mag[0]
			+ arm_sin_f32(XRollAngleInRad) * arm_sin_f32(YPitchAngleInRad) * mag[1]
			+ arm_cos_f32(XRollAngleInRad) * arm_sin_f32(YPitchAngleInRad) * mag[2];
	ZYawAngleInRad = atan2f(arg1, arg2);

	//Correct declination, and change to compass angles
//	ZYawAngleInRad += (5.0 + (16.0 / 60.0))*PI/180.0; //Positive declination.
//	if (ZYawAngleInRad < 0) {
//		ZYawAngleInRad += 2 * PI;
//	} else if (ZYawAngleInRad > 2 * PI) {
//		ZYawAngleInRad -= 2 * PI;
//	}
}
Ejemplo n.º 3
0
/**
* \brief ADC interrupt handler.
*/
void ADC_Handler(void)
{
	uint32_t tmp;
	uint32_t status ;

	status = adc_get_status(ADC);
	
	/* Checa se a interrupção é devido ao canal 5 */
	static float rad_antes = 0;
	if ((status & ADC_ISR_EOC5)) {
		tmp = adc_get_channel_value(ADC, ADC_POT_CHANNEL);

			ili93xx_set_foreground_color(COLOR_WHITE);
			ili93xx_draw_filled_rectangle(9, 39, ILI93XX_LCD_WIDTH,55);
			v=3.3*((float)tmp)/4095.0;
			rad=2*pi*((float)tmp)/4095.0;
			ili93xx_draw_line(120,160,120+54*arm_cos_f32(rad_antes),160+54*arm_sin_f32(rad_antes));
			ili93xx_set_foreground_color(COLOR_BLACK);
			sprintf(vet, "Tensao: %f", v);
			ili93xx_draw_string(10, 40, vet);
			ili93xx_draw_line(120,160,120+54*arm_cos_f32(rad),160+54*arm_sin_f32(rad));
			rad_antes = rad;

	}
	

	
}
Ejemplo n.º 4
0
void Sine_f32::generate(float32_t *sgn) {
    for (uint32_t i=0; i<_block_size; i++) {
        *sgn = (_amplitude * arm_sin_f32(_x));
        sgn++;
        _x += _dx;
    }
}
Ejemplo n.º 5
0
void IMU::removeCentrifugalForceEffect(void) {
	float32_t arg1 = .0, sumOfSquares = .0;
	float32_t result = .0;
	volatile float32_t centrifugalAcceleration[3] = { .0 };
	float32_t rotationThresholdInRadPerSec = 5.0;
	//Physical dimensions on board in mm
	const float32_t dx = 0.015,	//15 mm
			dy = 0.01,		//20 mm
			dz = 0.003;	//3 mm
	float32_t *const pGyroAxis = gyro.axisInRadPerS, *const pAccAxis = accelerometer.axisInMPerSsquared;

	if (pGyroAxis[0] > rotationThresholdInRadPerSec) {
		centrifugalAcceleration[1] = pGyroAxis[0] * pGyroAxis[0] * dx;
	}
	if (pGyroAxis[1] > rotationThresholdInRadPerSec) {
		centrifugalAcceleration[0] = pGyroAxis[1] * pGyroAxis[1] * dy;
	}
	if (pGyroAxis[2] > rotationThresholdInRadPerSec) {
		arm_sqrt_f32(sumOfSquares, &result);
		centrifugalAcceleration[0] = pGyroAxis[2] * pGyroAxis[2] * result;
		centrifugalAcceleration[1] = pGyroAxis[2] * pGyroAxis[2] * result;

		sumOfSquares = dx * dx + dy * dy;
		arg1 = dy / sumOfSquares;
		centrifugalAcceleration[0] *= arm_sin_f32(arg1);
		arg1 = dx / sumOfSquares;
		centrifugalAcceleration[1] *= arm_cos_f32(arg1);
	}
	pAccAxis[0] -= centrifugalAcceleration[0];
	pAccAxis[1] -= centrifugalAcceleration[1];
	pAccAxis[2] -= centrifugalAcceleration[2];
}
Ejemplo n.º 6
0
int32_t main(void) 
{ 
	float32_t diff; 
	uint32_t i; 
 
	for(i=0; i< blockSize; i++) 
    { 
        cosOutput = arm_cos_f32(testInput_f32[i]); 
		sinOutput = arm_sin_f32(testInput_f32[i]); 
 
		arm_mult_f32(&cosOutput, &cosOutput, &cosSquareOutput, 1); 
		arm_mult_f32(&sinOutput, &sinOutput, &sinSquareOutput, 1); 
 
		arm_add_f32(&cosSquareOutput, &sinSquareOutput, &testOutput, 1);
 
		/* absolute value of difference between ref and test */ 
	    diff = fabsf(testRefOutput_f32 - testOutput); 
	 
	    /* Comparison of sin_cos value with reference */ 
	    if(diff > DELTA) 
	    { 
		   status = ARM_MATH_TEST_FAILURE; 
	    } 
		 
	    if( status == ARM_MATH_TEST_FAILURE) 
	    { 
	       while(1); 
	    } 
 
    } 

    while(1);                             /* main function does not return */
} 
Ejemplo n.º 7
0
/**
 * \brief Generate sinusoidale signals for voice changing.
 */
static void dsp_sin_init(void)
{
	uint32_t i;
	uint32_t j;
	float32_t ratio;
	float32_t freq;

	freq = SAMPLING_FREQUENCY;

	for (j = 0; j < SLIDER_SELECTOR_NB; ++j) {

		/* Generate a sinus based on sampling freq with a delta. */
		ratio = freq / SAMPLING_FREQUENCY;

		for (i = 0 ; i < SAMPLE_BLOCK_SIZE; i++) {
			/* Amplification is set to 1. */
			if (ratio <= 1.0) {
				/* It won't change anything. */
				sin_buffer[j][i] = 1;
			} else {
				sin_buffer[j][i] = arm_sin_f32(2 * PI * i * ratio);
			}
		}

		/* Increase delta. */
		freq += VOICE_CHANGER_DELTA;
	}
}
Ejemplo n.º 8
0
//
// Main Routine
//
int main(void) {
#ifdef DEBUG
	CSerial ser;		// declare a UART object
	ser.enable();
	CDebug dbg(ser);	// Debug stream use the UART object
	dbg.start();
#endif

	//
	// Your setup code here
	//
	swPWM pwm(TIMER_1);
	pwm.period(0.01);		// set the period time of PWM to 10ms.
	pwm.enable();			// start the pwm

	int pins[] = {LED_PIN_0, LED_PIN_1, LED_PIN_2, LED_PIN_3};

	float y;
	int x[4] = { 0, 10, 20, 30 };        // initialize all channels x degree

	//
    // Enter main loop.
	//
    while(1) {
    	//
    	// FireFly loop
    	//
		for (int ch = 0; ch < 4; ch++) {
			x[ch] = (x[ch] + 10) % 360;							// degree 0~360, step by 2
			y = arm_sin_f32((x[ch] * M_PI) / 180.0f);           // y = sine @x
			pwm.output(pins[ch], map(y, -1.0f, 1.0f, 0.0f, 1.0f)); 	// update the duty-cycle of channel
		}
		sleep(10);    // speed
    }
}
Ejemplo n.º 9
0
void Sine_f32::process(float32_t *sgn_in, float32_t *sgn_out) {
    for (uint32_t i=0; i<_block_size; i++) {
        *sgn_out = *sgn_in + (_amplitude * arm_sin_f32(_x));
        sgn_in++; sgn_out++;
        _x += _dx;
    }
}
Ejemplo n.º 10
0
static mp_obj_t py_image_draw_keypoints(mp_obj_t image_obj, mp_obj_t kpts_obj)
{
    image_t *image = NULL;
    py_kp_obj_t *kpts=NULL;

    /* get pointer */
    image = py_image_cobj(image_obj);
    kpts = (py_kp_obj_t*)kpts_obj;

    /* sanity checks */
    PY_ASSERT_TRUE_MSG(image->bpp == 1,
            "This function is only supported on GRAYSCALE images");
    PY_ASSERT_TYPE(kpts_obj, &py_kp_type);

    color_t cl = {.r=0xFF, .g=0xFF, .b=0xFF};
    for (int i=0; i<kpts->size; i++) {
        kp_t *kp = &kpts->kpts[i];
        float co = arm_cos_f32(kp->angle);
        float si = arm_sin_f32(kp->angle);
        imlib_draw_line(image, kp->x, kp->y, kp->x+(co*10), kp->y+(si*10));
        imlib_draw_circle(image, kp->x, kp->y, 4, &cl);
    }

    return mp_const_none;
}

static mp_obj_t py_image_find_blobs(mp_obj_t image_obj)
{
    /* C stuff */
    array_t *blobs;
    struct image *image;
    mp_obj_t blob_obj[6];

    /* MP List */
    mp_obj_t objects_list = mp_const_none;

     /* get image pointer */
    image = py_image_cobj(image_obj);

    /* run color dector */
    blobs = imlib_count_blobs(image);

    /* Create empty Python list */
    objects_list = mp_obj_new_list(0, NULL);

    if (array_length(blobs)) {
        for (int j=0; j<array_length(blobs); j++) {
             blob_t *r = array_at(blobs, j);
             blob_obj[0] = mp_obj_new_int(r->x);
             blob_obj[1] = mp_obj_new_int(r->y);
             blob_obj[2] = mp_obj_new_int(r->w);
             blob_obj[3] = mp_obj_new_int(r->h);
             blob_obj[4] = mp_obj_new_int(r->c);
             blob_obj[5] = mp_obj_new_int(r->id);
             mp_obj_list_append(objects_list, mp_obj_new_tuple(6, blob_obj));
        }
    }
    array_free(blobs);
    return objects_list;
}
/* ----------------------------------------------------------------------------
* Calculation of Sine values from Cubic Interpolation and Linear interpolation
* ---------------------------------------------------------------------------- */
int32_t main(void)
{
	uint32_t i;
	arm_status status;

	arm_linear_interp_instance_f32 S = {188495, -3.141592653589793238, XSPACING, &arm_linear_interep_table[0]};

	/*------------------------------------------------------------------------------
	*  Method 1: Test out Calculated from Cubic Interpolation
	*------------------------------------------------------------------------------*/
	for(i=0; i< TEST_LENGTH_SAMPLES; i++)
	{
		testOutput[i] = arm_sin_f32(testInputSin_f32[i]);
	}

	/*------------------------------------------------------------------------------
	*  Method 2: Test out Calculated from Cubic Interpolation and Linear interpolation
	*------------------------------------------------------------------------------*/

	for(i=0; i< TEST_LENGTH_SAMPLES; i++)
	{
	  	testLinIntOutput[i] = arm_linear_interp_f32(&S, testInputSin_f32[i]);
	}

	/*------------------------------------------------------------------------------
	*  					SNR calculation for method 1
	*------------------------------------------------------------------------------*/
	snr1 = arm_snr_f32(testRefSinOutput32_f32, testOutput, 2);

	/*------------------------------------------------------------------------------
	*  					SNR calculation for method 2
	*------------------------------------------------------------------------------*/
	snr2 = arm_snr_f32(testRefSinOutput32_f32, testLinIntOutput, 2);

	/*------------------------------------------------------------------------------
	*  					Initialise status depending on SNR calculations
	*------------------------------------------------------------------------------*/
	if( snr2 > snr1)
	{
		status = ARM_MATH_SUCCESS;
	}
	else
	{
		status = ARM_MATH_TEST_FAILURE;
	}

	/* ----------------------------------------------------------------------
	** Loop here if the signals fail the PASS check.
	** This denotes a test failure
	** ------------------------------------------------------------------- */
	if( status != ARM_MATH_SUCCESS)
	{
		while(1);
	}

    while(1);                             /* main function does not return */
}
/*=====================================================================================================*/
void Quaternion_ToNumQ( Quaternion *pNumQ, EulerAngle *pAngE )
{
  float halfP = pAngE->Pitch/2.0f;
  float halfR = pAngE->Roll/2.0f;
  float halfY = pAngE->Yaw/2.0f;

  float sinP = arm_sin_f32(halfP);
  float cosP = arm_cos_f32(halfP);
  float sinR = arm_sin_f32(halfR);
  float cosR = arm_cos_f32(halfR);
  float sinY = arm_sin_f32(halfY);
  float cosY = arm_cos_f32(halfY);

  pNumQ->q0 = cosY*cosR*cosP + sinY*sinR*sinP;
  pNumQ->q1 = cosY*cosR*sinP - sinY*sinR*cosP;
  pNumQ->q2 = cosY*sinR*cosP + sinY*cosR*sinP;
  pNumQ->q3 = sinY*cosR*cosP - cosY*sinR*sinP;
}
Ejemplo n.º 13
0
// simply take average on a square patch, not even gaussian approx
static uint8_t mean_intensity(image_t *image, i_image_t *i_image, int kp_x, int kp_y, uint32_t rot, uint32_t point)
{
    int pidx = (point/6)%8;
    float alpha, beta, theta = 0;

    if (rot) {
        theta = rot*PI_2/(float)kNB_ORIENTATION; // orientation of the pattern
    }
    beta = PI/n[pidx]*(pidx%2); // orientation offset so that groups of points on each circles are staggered
    alpha = (float)(point%n[pidx])*PI_2/(float)n[pidx]+beta+theta;

    float px = radius[pidx] * PATTERN_SCALE * arm_cos_f32(alpha);
    float py = radius[pidx] * PATTERN_SCALE * arm_sin_f32(alpha);
    float psigma = sigma[pidx] * PATTERN_SCALE;

    // get point position in image
    float xf = px+kp_x;
    float yf = py+kp_y;
    int x = (int) xf;
    int y = (int) yf;
    int imagecols = image->w;

    // calculate output:
    int ret_val;
    if (psigma < 0.5f) {
        // interpolation multipliers:
        int r_x = (xf-x)*1024;
        int r_y = (yf-y)*1024;
        int r_x_1 = (1024-r_x);
        int r_y_1 = (1024-r_y);
        uint8_t* ptr = image->data+(y*imagecols+x);
        // linear interpolation:
        ret_val = (r_x_1*r_y_1*(int)(*ptr++));
        ret_val += (r_x*r_y_1*(int)(*ptr));
        ptr += imagecols;
        ret_val += (r_x*r_y*(int)(*ptr--));
        ret_val += (r_x_1*r_y*(int)(*ptr));
        return (ret_val+512)/1024;
    } else {
        int x_left    = (int) (xf-psigma+0.5f);
        int y_top     = (int) (yf-psigma+0.5f);
        int x_right   = (int) (xf+psigma+1.5f);//integral image is 1px wider
        int y_bottom  = (int) (yf+psigma+1.5f);//integral image is 1px higher

        ret_val  = i_image->data[i_image->w*y_bottom+x_right];//bottom right corner
        ret_val -= i_image->data[i_image->w*y_bottom+x_left];
        ret_val += i_image->data[i_image->w*y_top+x_left];
        ret_val -= i_image->data[i_image->w*y_top+x_right];
        ret_val  = ret_val/( (x_right-x_left)* (y_bottom-y_top) );
        return ret_val;
    }
}
void Rotate3dVector(float vector[3], float roll, float pitch, float yaw, float Retorno[3])
{
	roll = roll/57.3;
	pitch = pitch/57.3;
	yaw = yaw/57.3;

	float A = roll;
	float B = pitch;
	float C = yaw;

	float cosA, sinA;
	float cosB, sinB;
	float cosC, sinC;

	cosA = arm_cos_f32(A);
	sinA = arm_sin_f32(A);

	cosB = arm_cos_f32(B);
	sinB = arm_sin_f32(B);

	cosC = arm_cos_f32(C);
	sinC = arm_sin_f32(C);

	float RotationMatrix_f32[9] = 	{cosB*cosC, cosC*sinA*sinB-cosA*sinC, cosA*cosC*sinB+sinA*sinC,
									cosB*sinC, cosA*cosC+sinA*sinB*sinC, -cosC*sinA+cosA*sinB*sinC,
									-sinB, cosB*cosA, cosA*cosB};
	
	arm_matrix_instance_f32 RotationMatrix;
	arm_mat_init_f32(&RotationMatrix, 3, 3, RotationMatrix_f32);

	arm_matrix_instance_f32 InVector;
	arm_mat_init_f32(&InVector, 3, 1, vector);

	arm_matrix_instance_f32 OutVector;
	arm_mat_init_f32(&OutVector, 3, 1, Retorno);

	arm_mat_mult_f32(&RotationMatrix, &InVector, &OutVector);

}
Ejemplo n.º 15
0
/**
 * \brief Generate a sinus input signal.
 *
 * \param freq Sinus frequency.
 */
static void dsp_sin_input(float32_t freq)
{
	uint32_t i;
	uint32_t y;
	float32_t ratio;

	if (freq < 1) {
		freq = 1;
	}

	ratio = freq / SAMPLING_FREQUENCY;

	for (i = 0, y = 0; i < SAMPLE_BLOCK_SIZE; i++) {
		/* Amplification is set to 1. */
		wav_in_buffer[y++] = arm_sin_f32(2 * PI * i * ratio);
		wav_in_buffer[y++] = 0;
	}
}
Ejemplo n.º 16
0
float getValueForCoord(float x, float y, float time) {
	//	float value = arm_sin_f32(x * 10 + time);

	float value =0.0;
	value += arm_sin_f32(x * 10 + time);
	value += arm_sin_f32(10*(x*arm_sin_f32(time/2) + y*arm_cos_f32(time/3))+time);

	float cx = x+0.5*arm_sin_f32(time/5);
	float cy = y+0.5*arm_sin_f32(time/3);

	value += arm_sin_f32( sqrtf(100 * ((cx*cx)+(cy*cy))+1)+time);

	return value;
}
Ejemplo n.º 17
0
void body_aimming_angle()
{
	global_aimming_angle(&(global_yaw),&(global_pitch));
	
	
	/*transform global vetor form global to body*/
	
	vector_x_fc = vector_y;
	vector_y_fc = -vector_x;
	vector_z_fc = vector_z;

	//printf("%f,%f,%f\r\n",vector_x_fc,vector_y_fc,vector_z_fc);

	/*turn body by yaw,pitch,roll*/
	vector_body_x = Mq11*vector_x_fc + Mq12*vector_y_fc + Mq13*vector_z_fc;
	vector_body_y = Mq21*vector_x_fc + Mq22*vector_y_fc + Mq23*vector_z_fc;
	vector_body_z = Mq31*vector_x_fc + Mq32*vector_y_fc + Mq33*vector_z_fc;

	//printf("%f,%f,%f\r\n",vector_body_x,vector_body_y,vector_body_z);

	//printf("global_yaw,%f,global_pitch,%f\r\n",global_yaw,global_pitch);

	body_yaw   = (atan2f(vector_body_y,vector_body_x));
	body_pitch = toDeg(atan2f(-vector_body_z,(arm_cos_f32(body_yaw) * vector_body_x + arm_sin_f32(body_yaw) * vector_body_y)));
	body_yaw   = toDeg(body_yaw);

	if(body_pitch > 90.0)
	{
		body_yaw  = body_yaw + 180.0;
		body_pitch= 180.0 - body_pitch;
	}
/*	else if(body_pitch < 0.0)
	{
		body_yaw  = body_yaw + 180.0;
		body_pitch= -body_pitch;
	}
*/
	//printf("body_yaw,%f,body_pitch,%f\r\n",body_yaw,body_pitch);

}
Ejemplo n.º 18
0
void DAC_Ch2_SineWaveConfig(void) {
	float32_t xfactor = 2.0 * PI / SIN_TABLE_SIZE;
	for (int i = 0; i < SIN_TABLE_SIZE; i++) {
		uint16_t ival = arm_sin_f32(i * xfactor) * 2046.0 + 2046.0;
		sin_table[i] = ival;
		//display_bar(0, 4096, (int) sin_table[i]);
	}

	DMA_InitTypeDef DMA_InitStructure;
	DAC_InitTypeDef DAC_InitStructure;

	/* DAC channel1 Configuration */
	DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
	DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
	DAC_Init(DAC_Channel_1, &DAC_InitStructure);

	/* DMA1_Stream5 channel1 configuration **************************************/
	DMA_DeInit(DMA1_Stream5 );
	DMA_InitStructure.DMA_Channel = DMA_Channel_7;
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) DAC_DHR12R1_ADDRESS;
	DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &sin_table;
	DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
	DMA_InitStructure.DMA_BufferSize = SIN_TABLE_SIZE;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
	DMA_Init(DMA1_Stream5, &DMA_InitStructure);
	DMA_Cmd(DMA1_Stream5, ENABLE);
	DAC_Cmd(DAC_Channel_1, ENABLE);
	DAC_DMACmd(DAC_Channel_1, ENABLE);
}
Ejemplo n.º 19
0
/* The main process of FFT.
 * Using the butterfly algorithm.
 */
void butterfly()
{
	int le, lei, ip, m, f = DATA_LENGTH;
	int level, i, j;
	struct cmplx u, w, t;

	// Calculate the level of butterfly algorithm
	for ( level = 1; (f>>=1) != 1; ++level )
		;

	for ( m = 1; m <= level; ++m )
	{
		le = 2 << ( m - 1 );
		lei = le >> 1;

		u.real = 1.0;
		u.imag = 0.0;

		w.real = arm_cos_f32( PI / lei );
		w.imag = -arm_sin_f32( PI / lei );

		for ( j = 0; j <= lei - 1; ++j )
		{
			for ( i = j; i < DATA_LENGTH; i = i + le )
			{
				ip = i + lei;
				t = EE( fft_input[ip], u );
				fft_input[ip].real = fft_input[i].real - t.real;
				fft_input[ip].imag = fft_input[i].imag - t.imag;
				fft_input[i].real = fft_input[i].real + t.real;
				fft_input[i].imag = fft_input[i].imag + t.imag;
			}
			u = EE( u, w );
		}
	}

}	// end of bufferfly()
int32_t main(void) 
{ 
   float32_t diff; 
   uint32_t i; 

   printf("Starting Test...\n");
   for (i=0; i < blockSize; i++) 
   { 
      cosOutput = arm_cos_f32(testInput_f32[i]); 
      printf("Cos %f = %f\n", testInput_f32[i], cosOutput);
 
      sinOutput = arm_sin_f32(testInput_f32[i]); 
      printf("Sin %f = %f\n", testInput_f32[i], sinOutput);

      arm_mult_f32(&cosOutput, &cosOutput, &cosSquareOutput, 1); 
      printf("Cos squared %f = %f\n", cosOutput, cosSquareOutput);

      arm_mult_f32(&sinOutput, &sinOutput, &sinSquareOutput, 1); 
      printf("Sin squared %f = %f\n", sinOutput, sinSquareOutput);

      arm_add_f32(&cosSquareOutput, &sinSquareOutput, &testOutput, 1);
      printf("Add %f and %f = %f\n", cosSquareOutput, sinSquareOutput, testOutput);
 
      /* absolute value of difference between ref and test */ 
      diff = fabsf(testRefOutput_f32 - testOutput); 
      /* Comparison of sin_cos value with reference */ 
      if (diff > DELTA) 
      { 
         printf("Diff failure %f\n", diff);
         exit(EXIT_FAILURE); /* just for QEMU testing */
         while(1); 
      } 
   } 
   printf("Ending Test...\n");
   exit(EXIT_SUCCESS); /* just for QEMU testing */
   while(1); /* main function does not return */
} 
Ejemplo n.º 21
0
Archivo: main.c Proyecto: johnlaur/PSDR
void polarToRect(float m, float a, float32_t* x, float32_t* y)
{
	*y = m * arm_sin_f32(a);
	*x = m * arm_cos_f32(a);
}
void correct_sensor()
{
	float Ellipse[5] = {0};
#define MovegAveFIFO_Size 250

	switch (SensorMode) {

	/************************** Mode_CorrectGyr **************************************/
	case Mode_GyrCorrect:
		/* Simple Moving Average */
		Gyr.X = (s16)MoveAve_SMA(Gyr.X, GYR_FIFO[0], MovegAveFIFO_Size);
		Gyr.Y = (s16)MoveAve_SMA(Gyr.Y, GYR_FIFO[1], MovegAveFIFO_Size);
		Gyr.Z = (s16)MoveAve_SMA(Gyr.Z, GYR_FIFO[2], MovegAveFIFO_Size);

		Correction_Time++;  // 等待 FIFO 填滿空值 or 填滿靜態資料

		if (Correction_Time == SampleRateFreg) {
			Gyr.OffsetX += (Gyr.X - GYR_X_OFFSET);  // 角速度為 0dps
			Gyr.OffsetY += (Gyr.Y - GYR_Y_OFFSET);  // 角速度為 0dps
			Gyr.OffsetZ += (Gyr.Z - GYR_Z_OFFSET);  // 角速度為 0dps

			Correction_Time = 0;
			SensorMode = Mode_AccCorrect;
		}

		break;

	/************************** Mode_CorrectAcc **************************************/
	case Mode_AccCorrect:
		/* Simple Moving Average */
		Acc.X = (s16)MoveAve_SMA(Acc.X, ACC_FIFO[0], MovegAveFIFO_Size);
		Acc.Y = (s16)MoveAve_SMA(Acc.Y, ACC_FIFO[1], MovegAveFIFO_Size);
		Acc.Z = (s16)MoveAve_SMA(Acc.Z, ACC_FIFO[2], MovegAveFIFO_Size);

		Correction_Time++;  // 等待 FIFO 填滿空值 or 填滿靜態資料

		if (Correction_Time == SampleRateFreg) {
			Acc.OffsetX += (Acc.X - ACC_X_OFFSET);  // 重力加速度為 0g
			Acc.OffsetY += (Acc.Y - ACC_Y_OFFSET);  // 重力加速度為 0g
			Acc.OffsetZ += (Acc.Z - ACC_Z_OFFSET);  // 重力加速度為 1g

			Correction_Time = 0;
			SensorMode = Mode_Quaternion; // Mode_MagCorrect;
		}

		break;

		/************************** Mode_CorrectMag **************************************/
#define MagCorrect_Ave    100
#define MagCorrect_Delay  600   // DelayTime : SampleRate * 600

	case Mode_MagCorrect:
		Correction_Time++;

		switch ((u16)(Correction_Time / MagCorrect_Delay)) {
		case 0:

			MagDataX[0] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[0] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		case 1:

			MagDataX[1] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[1] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		case 2:

			MagDataX[2] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[2] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		case 3:

			MagDataX[3] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[3] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		case 4:

			MagDataX[4] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[4] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		case 5:

			MagDataX[5] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[5] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		case 6:

			MagDataX[6] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[6] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		case 7:

			MagDataX[7] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
			MagDataY[7] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
			break;

		default:

			EllipseFitting(Ellipse, MagDataX, MagDataY, 8);
			Mag.EllipseSita = Ellipse[0];
			Mag.EllipseX0   = Ellipse[1];
			Mag.EllipseY0   = Ellipse[2];
			Mag.EllipseA    = Ellipse[3];
			Mag.EllipseB    = Ellipse[4];

			Correction_Time = 0;
			SensorMode = Mode_Quaternion;
			break;
		}

		break;

	/************************** Algorithm Mode **************************************/
	case Mode_Quaternion:
		/* To Physical */
		Acc.TrueX = Acc.X * MPU9150A_4g;      // g/LSB
		Acc.TrueY = Acc.Y * MPU9150A_4g;      // g/LSB
		Acc.TrueZ = Acc.Z * MPU9150A_4g;      // g/LSB
		Gyr.TrueX = Gyr.X * MPU9150G_2000dps; // dps/LSB
		Gyr.TrueY = Gyr.Y * MPU9150G_2000dps; // dps/LSB
		Gyr.TrueZ = Gyr.Z * MPU9150G_2000dps; // dps/LSB
		Mag.TrueX = Mag.X * MPU9150M_1200uT;  // uT/LSB
		Mag.TrueY = Mag.Y * MPU9150M_1200uT;  // uT/LSB
		Mag.TrueZ = Mag.Z * MPU9150M_1200uT;  // uT/LSB
		Temp.TrueT = Temp.T * MPU9150T_85degC; // degC/LSB

		Ellipse[3] = (Mag.X * arm_cos_f32(Mag.EllipseSita) + Mag.Y * arm_sin_f32(Mag.EllipseSita)) / Mag.EllipseB;
		Ellipse[4] = (-Mag.X * arm_sin_f32(Mag.EllipseSita) + Mag.Y * arm_cos_f32(Mag.EllipseSita)) / Mag.EllipseA;

		AngE.Pitch = toDeg(atan2f(Acc.TrueY, Acc.TrueZ));
		AngE.Roll  = toDeg(-asinf(Acc.TrueX));
		AngE.Yaw   = toDeg(atan2f(Ellipse[3], Ellipse[4])) + 180.0f;

		Quaternion_ToNumQ(&NumQ, &AngE);

		SensorMode = Mode_Algorithm;
		break;
	}

}
Ejemplo n.º 23
0
void svpwm(void)	{


	uint8_t	sector = Theta/_PIdiv3;
	float32_t	U_ref = hypotf(U_alpha,U_beta);
	if (U_ref > U_max) {
		U_ref = U_max;
	}
	float32_t	angle = Theta - (sector*_PIdiv3);
	float32_t	U_ref_percent = (_SQRT3)*(U_ref/_U_DC); // previous: (2/_SQRT3)
	float32_t	t_1 = U_ref_percent*arm_sin_f32(_PIdiv3-angle)*T_halfsample;
	float32_t	t_2 = U_ref_percent*arm_sin_f32(angle)*T_halfsample;
	float32_t	t_0 = T_halfsample - t_1 - t_2;
	float32_t	t_0_half = t_0/2;


	/* Switching counter values for Timer Interrupts */

	/* Upper switches */
	uint16_t	ontime_t_0_half = (t_0_half) * counterfrequency;
	uint16_t	ontime_value_1 = (t_0_half + t_1) * counterfrequency;
	uint16_t	ontime_value_2 = (t_0_half + t_2) * counterfrequency;
	uint16_t	ontime_value_3 = (t_0_half + t_1 + t_2) * counterfrequency;

	switch (sector)	{

		/*					Upper switches			*/

		/* Sector 1 */
		case 0:		switchtime[0] = &ontime_t_0_half;
					switchtime[1] = &ontime_value_1;
					switchtime[2] = &ontime_value_3;
				break;

		/* Sector 2 */
		case 1:		switchtime[0] = &ontime_value_2;
					switchtime[1] = &ontime_t_0_half;
					switchtime[2] = &ontime_value_3;
				break;

		/* Sector 3 */
		case 2:		switchtime[0] = &ontime_value_3;
					switchtime[1] = &ontime_t_0_half;
					switchtime[2] = &ontime_value_1;
				break;

		/* Sector 4 */
		case 3:		switchtime[0] = &ontime_value_3;
					switchtime[1] = &ontime_value_2;
					switchtime[2] = &ontime_t_0_half;
				break;

		/* Sector 5 */
		case 4:		switchtime[0] = &ontime_value_1;
					switchtime[1] = &ontime_value_3;
					switchtime[2] = &ontime_t_0_half;
				break;

		/* Sector 6 */
		case 5:		switchtime[0] = &ontime_t_0_half;
					switchtime[1] = &ontime_value_3;
					switchtime[2] = &ontime_value_2;
				break;
	}
}
Ejemplo n.º 24
0
/*=====================================================================================================*/
void AHRS_Update(void)
{
	float tempX = 0, tempY = 0;
	float Normalize;
	float gx, gy, gz;
// float hx, hy, hz;
// float wx, wy, wz;
// float bx, bz;
	float ErrX, ErrY, ErrZ;
	float AccX, AccY, AccZ;
	float GyrX, GyrY, GyrZ;
// float MegX, MegY, MegZ;
	float /*Mq11, Mq12, */Mq13,/* Mq21, Mq22, */Mq23,/* Mq31, Mq32, */Mq33;

	static float AngZ_Temp = 0.0f;
	static float exInt = 0.0f, eyInt = 0.0f, ezInt = 0.0f;

//   Mq11 = NumQ.q0*NumQ.q0 + NumQ.q1*NumQ.q1 - NumQ.q2*NumQ.q2 - NumQ.q3*NumQ.q3;
//   Mq12 = 2.0f*(NumQ.q1*NumQ.q2 + NumQ.q0*NumQ.q3);
	Mq13 = 2.0f * (NumQ.q1 * NumQ.q3 - NumQ.q0 * NumQ.q2);
//   Mq21 = 2.0f*(NumQ.q1*NumQ.q2 - NumQ.q0*NumQ.q3);
//   Mq22 = NumQ.q0*NumQ.q0 - NumQ.q1*NumQ.q1 + NumQ.q2*NumQ.q2 - NumQ.q3*NumQ.q3;
	Mq23 = 2.0f * (NumQ.q0 * NumQ.q1 + NumQ.q2 * NumQ.q3);
//   Mq31 = 2.0f*(NumQ.q0*NumQ.q2 + NumQ.q1*NumQ.q3);
//   Mq32 = 2.0f*(NumQ.q2*NumQ.q3 - NumQ.q0*NumQ.q1);
	Mq33 = NumQ.q0 * NumQ.q0 - NumQ.q1 * NumQ.q1 - NumQ.q2 * NumQ.q2 + NumQ.q3 * NumQ.q3;

	Normalize = invSqrtf(squa(Acc.TrueX) + squa(Acc.TrueY) + squa(Acc.TrueZ));
	AccX = Acc.TrueX * Normalize;
	AccY = Acc.TrueY * Normalize;
	AccZ = Acc.TrueZ * Normalize;

// Normalize = invSqrtf(squa(Meg.TrueX) + squa(Meg.TrueY) + squa(Meg.TrueZ));
// MegX = Meg.TrueX*Normalize;
// MegY = Meg.TrueY*Normalize;
// MegZ = Meg.TrueZ*Normalize;

	gx = Mq13;
	gy = Mq23;
	gz = Mq33;

// hx = MegX*Mq11 + MegY*Mq21 + MegZ*Mq31;
// hy = MegX*Mq12 + MegY*Mq22 + MegZ*Mq32;
// hz = MegX*Mq13 + MegY*Mq23 + MegZ*Mq33;

// bx = sqrtf(squa(hx) + squa(hy));
// bz = hz;

// wx = bx*Mq11 + bz*Mq13;
// wy = bx*Mq21 + bz*Mq23;
// wz = bx*Mq31 + bz*Mq33;

	ErrX = (AccY * gz - AccZ * gy)/* + (MegY*wz - MegZ*wy)*/;
	ErrY = (AccZ * gx - AccX * gz)/* + (MegZ*wx - MegX*wz)*/;
	ErrZ = (AccX * gy - AccY * gx)/* + (MegX*wy - MegY*wx)*/;

	exInt = exInt + ErrX * Ki;
	eyInt = eyInt + ErrY * Ki;
	ezInt = ezInt + ErrZ * Ki;

	GyrX = toRad(Gyr.TrueX);
	GyrY = toRad(Gyr.TrueY);
	GyrZ = toRad(Gyr.TrueZ);

	GyrX = GyrX + Kp * ErrX + exInt;
	GyrY = GyrY + Kp * ErrY + eyInt;
	GyrZ = GyrZ + Kp * ErrZ + ezInt;

	Quaternion_RungeKutta(&NumQ, GyrX, GyrY, GyrZ, SampleRateHelf);
	Quaternion_Normalize(&NumQ);
	Quaternion_ToAngE(&NumQ, &AngE);

	tempX    = (Mag.X * arm_cos_f32(Mag.EllipseSita) + Mag.Y * arm_sin_f32(Mag.EllipseSita)) / Mag.EllipseB;
	tempY    = (-Mag.X * arm_sin_f32(Mag.EllipseSita) + Mag.Y * arm_cos_f32(Mag.EllipseSita)) / Mag.EllipseA;
	AngE.Yaw = atan2f(tempX, tempY);

	AngE.Pitch = toDeg(AngE.Pitch);
	AngE.Roll  = toDeg(AngE.Roll);
	AngE.Yaw   = toDeg(AngE.Yaw) + 180.0f;

	/* 互補濾波 Complementary Filter */
#define CF_A 0.9f
#define CF_B 0.1f
	AngZ_Temp = AngZ_Temp + GyrZ * SampleRate;
	AngZ_Temp = CF_A * AngZ_Temp + CF_B * AngE.Yaw;

	if (AngZ_Temp > 360.0f)
		AngE.Yaw = AngZ_Temp - 360.0f;
	else if (AngZ_Temp < 0.0f)
		AngE.Yaw = AngZ_Temp + 360.0f;
	else
		AngE.Yaw = AngZ_Temp;
}
Ejemplo n.º 25
0
void vMovingControlTask(void *pvParameters)
{
	Position TargetPos;
	Position ExpectPos;
	MoveCmd SendCmd, ReResult;
	float DeltAngle, DeltDistance;
	float XYi[3];
	while (1)
	{
		if (pdTRUE == xQueueReceive(TargetPosQueue, &TargetPos, portMAX_DELAY))
		{
//			printf("get TargetPosQueue\r\n");
			while ((fabs(TargetPos.Angle - CurPos.Angle) > 180 ? 360 - fabs(TargetPos.Angle - CurPos.Angle) : fabs(TargetPos.Angle - CurPos.Angle)) * STEP_ANGLE >= ADJUST_STEP_ANGLE\
				|| sqrt(pow(TargetPos.y - CurPos.y, 2) + pow(TargetPos.x - CurPos.x, 2)) * STEP_METER >= ADJUST_STEP_DIRECT)
			{
//				Debug_printf("CurPos: %f %f %f\r\n", CurPos.Angle, CurPos.x, CurPos.y);
//				Debug_printf("CurPos: %f %f %f\r\n", CurPos.Angle, CurPos.x, CurPos.y);
//				Debug_printf("Compass: %f\r\n", CurAngle);
//				Debug_printf("DAngle: %f\r\n", fabs(TargetPos.Angle - CurPos.Angle) * STEP_ANGLE);
//				Debug_printf("Distance: %f\r\n", sqrt(pow(TargetPos.y - CurPos.y, 2) + pow(TargetPos.x - CurPos.x, 2)) * STEP_METER);
				if (sqrt(pow(TargetPos.y - CurPos.y, 2) + pow(TargetPos.x - CurPos.x, 2)) * STEP_METER >= ADJUST_STEP_DIRECT)
				{
					ExpectPos.Angle = (atan2(TargetPos.y - CurPos.y, TargetPos.x - CurPos.x)/PI)*180;
					
//					printf("ExpectPos.Angle1 : %f\r\n",ExpectPos.Angle);
					ExpectPos.x = CurPos.x;
					ExpectPos.y = CurPos.y;
					DeltAngle = ExpectPos.Angle - CurPos.Angle;
					
//					Debug_printf("DAngle: %f\r\n", DeltAngle);
					if (DeltAngle > 180)
					{
						DeltAngle = DeltAngle - 360;
					}                     
					if(DeltAngle < -180)
					{
						DeltAngle = 360 + DeltAngle;
					}
					if (DeltAngle < 0)
					{
						SendCmd.direct = turnright;
					}
					else
					{
						SendCmd.direct = turnleft;
					}
					SendCmd.step = fabs(DeltAngle) * STEP_ANGLE;
//					vTaskDelay(1000);
					xQueueSend(MoveCmdQueue, &SendCmd, portMAX_DELAY);
					if (pdTRUE == xQueueReceive(MoveRsultQueue, &ReResult, portMAX_DELAY))
					{
//						Debug_printf("get MoveRsultQueue\r\n");
						//CurPos = ExpectPos;
						if (SendCmd.direct == turnright)
						{
							CurPos.Angle = CurPos.Angle - ((float)ReResult.step) / STEP_ANGLE;
						}
						if (SendCmd.direct == turnleft)
						{
							CurPos.Angle = CurPos.Angle + ((float)ReResult.step) / STEP_ANGLE;
						}
						
						if (CurPos.Angle > 180)
						{
							CurPos.Angle = CurPos.Angle - 360;
						}
						if (CurPos.Angle < -180)
						{
							CurPos.Angle = CurPos.Angle + 360;
						}
						//??
						//????????;
						//printf("CurPos.Angle: %f\r\n", CurPos.Angle);
						if (ANGLE_CORRECTION_THRESHOLD < fabs(CurPos.Angle - CurAngle))
						{
							CurPos.Angle = CurAngle;
						}
						//printf("FIXED CurPos.Angle: %f\r\n", CurPos.Angle);
						if(pdTRUE == xQueueReceive(PositionUpdatekQueue, XYi, 2))
						{
							//????????;
							switch (GlobleCmdDir)
							{
								case forward:
									XYi[0] = XYi[0] + ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_cos_f32((CurPos.Angle / 180) * PI);
							    XYi[1] = XYi[1] + ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_sin_f32((CurPos.Angle / 180) * PI);
									break;
								case backward:
									XYi[0] = XYi[0] - ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_cos_f32((CurPos.Angle / 180) * PI);
							    XYi[1] = XYi[1] - ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_sin_f32((CurPos.Angle / 180) * PI);
									break;
								case turnright:			
									break;
								case turnleft:
									break;
								default:
									break;		
							}
							CurPos.x = XYi[0];
							CurPos.y = XYi[1];
						}
						if(pdTRUE == xSemaphoreTake(FoundTargetSyn, 1))
						{
//							Debug_printf("I am IN 1\r\n");
							TargetPos = CurPos;
						}
					}
				}
				else
				{
					ExpectPos.Angle = TargetPos.Angle;
					
//					printf("ExpectPos.Angle2 : %f\r\n",ExpectPos.Angle);
					ExpectPos.x = CurPos.x;
					ExpectPos.y = CurPos.y;
					DeltAngle = ExpectPos.Angle - CurPos.Angle;
					
					
					if (DeltAngle > 180)
					{
						DeltAngle = DeltAngle - 360;
					}                     
					if(DeltAngle < -180)
					{
						DeltAngle = 360 + DeltAngle;
					}
					if (DeltAngle < 0)
					{
						SendCmd.direct = turnright;
					}
					else
					{
						SendCmd.direct = turnleft;
					}
					SendCmd.step = fabs(DeltAngle) * STEP_ANGLE;
//					vTaskDelay(1000);
					xQueueSend(MoveCmdQueue, &SendCmd, portMAX_DELAY);
					if (pdTRUE == xQueueReceive(MoveRsultQueue, &ReResult, portMAX_DELAY))
					{
						//CurPos = ExpectPos;MoveRsultQueue
//						Debug_printf("get MoveRsultQueue\r\n");
						if (SendCmd.direct == turnright)
						{
							CurPos.Angle = CurPos.Angle - ((float)ReResult.step) / STEP_ANGLE;
						}
						if (SendCmd.direct == turnleft)
						{
							CurPos.Angle = CurPos.Angle + ((float)ReResult.step) / STEP_ANGLE;
						}
						
						if (CurPos.Angle > 180)
						{
							CurPos.Angle = CurPos.Angle - 360;
						}
						if (CurPos.Angle < -180)
						{
							CurPos.Angle = CurPos.Angle + 360;
						}
						//??
						//????????;
						//printf(" else CurPos.Angle: %f\r\n", CurPos.Angle);
						if (ANGLE_CORRECTION_THRESHOLD < fabs(CurPos.Angle - CurAngle))
						{
							CurPos.Angle = CurAngle;
						}
						//printf("else FIXED CurPos.Angle: %f\r\n", CurPos.Angle);
						if(pdTRUE == xQueueReceive(PositionUpdatekQueue, XYi, 2))
						{
							//????????;
							switch (GlobleCmdDir)
							{
								case forward:
									XYi[0] = XYi[0] + ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_cos_f32((CurPos.Angle / 180) * PI);
							    XYi[1] = XYi[1] + ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_sin_f32((CurPos.Angle / 180) * PI);
									break;
								case backward:
									XYi[0] = XYi[0] - ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_cos_f32((CurPos.Angle / 180) * PI);
							    XYi[1] = XYi[1] - ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_sin_f32((CurPos.Angle / 180) * PI);
									break;
								case turnright:			
									break;
								case turnleft:
									break;
								default:
									break;		
							}
							CurPos.x = XYi[0];
							CurPos.y = XYi[1];
						}
						if(pdTRUE == xSemaphoreTake(FoundTargetSyn, 100))
						{
//							Debug_printf("I am IN 2\r\n");
							TargetPos = CurPos;
						}
					}
				}
				
				if ((fabs(ExpectPos.Angle - CurPos.Angle) > 180 ? 360 - fabs(ExpectPos.Angle - CurPos.Angle) : fabs(ExpectPos.Angle - CurPos.Angle)) * STEP_ANGLE < ADJUST_STEP_ANGLE\
					&& sqrt(pow(TargetPos.y - CurPos.y, 2) + pow(TargetPos.x - CurPos.x, 2)) * STEP_METER >= ADJUST_STEP_DIRECT)
				{
					ExpectPos.x = TargetPos.x;
					ExpectPos.y = TargetPos.y;
					DeltDistance = sqrt(pow(ExpectPos.y - CurPos.y, 2) + pow(ExpectPos.x - CurPos.x, 2));
					SendCmd.direct = forward;
					SendCmd.step = DeltDistance * STEP_METER;
//					vTaskDelay(1000);
//          Debug_printf("return1\r\n");
					xQueueSend(MoveCmdQueue, &SendCmd, portMAX_DELAY);
					
					if (pdTRUE == xQueueReceive(MoveRsultQueue, &ReResult, portMAX_DELAY))
					{
//						Debug_printf("return2\r\n");
						//CurPos = ExpectPos;
//						Debug_printf("get MoveRsultQueue\r\n");
						CurPos.x = CurPos.x + (ReResult.step / STEP_METER) * arm_cos_f32((CurPos.Angle / 180) * PI);
						CurPos.y = CurPos.y + (ReResult.step / STEP_METER) * arm_sin_f32((CurPos.Angle / 180) * PI);
						
						//??
						//????????;
						if (ANGLE_CORRECTION_THRESHOLD < fabs(CurPos.Angle - CurAngle))
						{
							CurPos.Angle = CurAngle;
						}
						if(pdTRUE == xQueueReceive(PositionUpdatekQueue, XYi, 2))
						{
							//????????;
							switch (GlobleCmdDir)
							{
								case forward:
									XYi[0] = XYi[0] + ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_cos_f32((CurPos.Angle / 180) * PI);
							    XYi[1] = XYi[1] + ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_sin_f32((CurPos.Angle / 180) * PI);
									break;
								case backward:
									XYi[0] = XYi[0] - ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_cos_f32((CurPos.Angle / 180) * PI);
							    XYi[1] = XYi[1] - ((float)(ReResult.step - XYi[2]) / STEP_METER) * arm_sin_f32((CurPos.Angle / 180) * PI);
									break;
								case turnright:			
									break;
								case turnleft:
									break;
								default:
									break;		
							}
							CurPos.x = XYi[0];
							CurPos.y = XYi[1];
						}
						if(pdTRUE == xSemaphoreTake(FoundTargetSyn, 1))
						{
//							Debug_printf("I am IN 3\r\n");
							TargetPos = CurPos;
						}
//						Debug_printf("return3\r\n");
					}
				}
				
			}
//			Debug_printf("TargetPos: %f %f %f\r\n", CurPos.Angle, CurPos.x, CurPos.y);
//			Debug_printf("CurPos: %f %f %f\r\n", CurPos.Angle, CurPos.x, CurPos.y);
//			Debug_printf("Compass: %f\r\n", CurAngle);
			xSemaphoreGive(MoveComplete);
//			printf("Complete1\r\n");
		}
	}
}
/* Cálculos do seno utilizando as funções disponíveis nas funções de DSP do arm. */
float f_sin(float angle) {
	return arm_sin_f32(angle);
}
/* Cálculos do tan utilizando as funções disponíveis nas funções de DSP do arm. */
float f_tan(float angle) {
	return (arm_sin_f32(angle)/arm_cos_f32(angle));
}
Ejemplo n.º 28
0
static void GPS_ISR()
{
	TIM_ClearITPendingBit(GPS_TIMER, TIM_IT_Update);
	double l1 = (double)GetEncoder1Count() * Encoder1_Fact * Encoder1_DIR;
	ClearEncoder1Count();
	double l2 = (double)GetEncoder2Count() * Encoder2_Fact * Encoder2_DIR;
	ClearEncoder2Count();
#ifndef TWO_ENCODERS
	double l3 = (double)GetEncoder3Count() * Encoder3_Fact * Encoder3_DIR;
	ClearEncoder3Count();
#endif
	static double lastV = 0;

#ifdef TWO_ENCODERS
	if ( ABS(l1) < ROTATE_MESURE && ABS(l2) < ROTATE_MESURE)
	{
		g_isRotate = FALSE;
	}
	else
	{
		g_isRotate = TRUE;
	}
#else
	if ( ABS(l1 - l3) < ROTATE_MESURE )
	{
		g_isRotate = FALSE;
	}
	else
	{
		g_isRotate = TRUE;
	}
#endif

	static double LastDeg = 0;
	double currentDeg = CalculateGyroDeg();
	double deltaDeg = currentDeg - LastDeg ;
	double degData = (LastDeg + currentDeg);
	if (deltaDeg > 180 )
	{
		deltaDeg -= 360;
		degData += 360;
	}
	else if (deltaDeg < -180)
	{
		deltaDeg += 360;
		degData += 360;
	}
	g_AnglurSpeed = deltaDeg * 200;
	l1 -= deltaDeg * Encoder1_RotateFact;
	l2 -= deltaDeg * Encoder2_RotateFact;
	float _ts = l1 * l1 + l2 * l2;
	arm_sqrt_f32(_ts,&_ts);
	g_linerSpeed =  _ts * 200;
	lastV = g_linerSpeed;
#ifndef TWO_ENCODERS
	l3 -= deltaDeg * Encoder3_RotateFact;

	l1 = (l1 + l3) / 2.0;
#endif
	//计算等效的平移方向
	//
	degData = degData *0.5f + ANGLE_C;
	degData *= DEG2RAD;
	LastDeg = currentDeg;

	float degCosData, degSinData;
	degCosData = arm_cos_f32(degData);
	degSinData = arm_sin_f32(degData);
	double deltaX = l2 * degCosData -  l1 * degSinData ;
	double deltaY = l1 * degCosData +  l2 * degSinData ;

	g_NowlinerSpeedAngle = atan2(deltaY , deltaX) * RAD2DEG;
	g_X += deltaX;
	g_Y += deltaY;

}
Ejemplo n.º 29
0
/*=====================================================================================================*/
void SysTick_Handler( void )
{
  u8 IMU_Buf[20] = {0};

  u16 Final_M1 = 0;
  u16 Final_M2 = 0;
  u16 Final_M3 = 0;
  u16 Final_M4 = 0;

  s16 Thr = 0, Pitch = 0, Roll = 0, Yaw = 0;

  float Ellipse[5] = {0};

  static u8  BaroCnt = 0;

  static s16 ACC_FIFO[3][256] = {0};
  static s16 GYR_FIFO[3][256] = {0};
  static s16 MAG_FIFO[3][256] = {0};

  static s16 MagDataX[8] = {0};
  static s16 MagDataY[8] = {0};

  static u16 Correction_Time = 0;

  /* Time Count */
  SysTick_Cnt++;
  if(SysTick_Cnt == SampleRateFreg) {
    SysTick_Cnt = 0;
    Time_Sec++;
    if(Time_Sec == 60) {	// 0~59
      Time_Sec = 0;
      Time_Min++;
      if(Time_Sec == 60)
      Time_Min = 0;
    }
  }

  /* 400Hz, Read Sensor ( Accelerometer, Gyroscope, Magnetometer ) */
  MPU9150_Read(IMU_Buf);

  /* 100Hz, Read Barometer */
  BaroCnt++;
  if(BaroCnt == 4) {
    MS5611_Read(&Baro, MS5611_D1_OSR_4096);
    BaroCnt = 0;
  }

  Acc.X  = (s16)((IMU_Buf[0]  << 8) | IMU_Buf[1]);
  Acc.Y  = (s16)((IMU_Buf[2]  << 8) | IMU_Buf[3]);
  Acc.Z  = (s16)((IMU_Buf[4]  << 8) | IMU_Buf[5]);
  Temp.T = (s16)((IMU_Buf[6]  << 8) | IMU_Buf[7]);
  Gyr.X  = (s16)((IMU_Buf[8]  << 8) | IMU_Buf[9]);
  Gyr.Y  = (s16)((IMU_Buf[10] << 8) | IMU_Buf[11]);
  Gyr.Z  = (s16)((IMU_Buf[12] << 8) | IMU_Buf[13]);
  Mag.X  = (s16)((IMU_Buf[15] << 8) | IMU_Buf[14]);
  Mag.Y  = (s16)((IMU_Buf[17] << 8) | IMU_Buf[16]);
  Mag.Z  = (s16)((IMU_Buf[19] << 8) | IMU_Buf[18]);

  /* Offset */
  Acc.X -= Acc.OffsetX;
  Acc.Y -= Acc.OffsetY;
  Acc.Z -= Acc.OffsetZ;
  Gyr.X -= Gyr.OffsetX;
  Gyr.Y -= Gyr.OffsetY;
  Gyr.Z -= Gyr.OffsetZ;
  Mag.X *= Mag.AdjustX;
  Mag.Y *= Mag.AdjustY;
  Mag.Z *= Mag.AdjustZ;

  #define MovegAveFIFO_Size 250
  switch(SensorMode) {

  /************************** Mode_CorrectGyr **************************************/
    case Mode_GyrCorrect:
      LED_R = !LED_R;
      /* Simple Moving Average */
      Gyr.X = (s16)MoveAve_SMA(Gyr.X, GYR_FIFO[0], MovegAveFIFO_Size);
      Gyr.Y = (s16)MoveAve_SMA(Gyr.Y, GYR_FIFO[1], MovegAveFIFO_Size);
      Gyr.Z = (s16)MoveAve_SMA(Gyr.Z, GYR_FIFO[2], MovegAveFIFO_Size);

      Correction_Time++;  // 等待 FIFO 填滿空值 or 填滿靜態資料
      if(Correction_Time == 400) {
        Gyr.OffsetX += (Gyr.X - GYR_X_OFFSET);  // 角速度為 0dps
        Gyr.OffsetY += (Gyr.Y - GYR_Y_OFFSET);  // 角速度為 0dps
        Gyr.OffsetZ += (Gyr.Z - GYR_Z_OFFSET);  // 角速度為 0dps

        Correction_Time = 0;
        SensorMode = Mode_MagCorrect; // Mode_AccCorrect;
      }
      break;
 
  /************************** Mode_CorrectAcc **************************************/
    case Mode_AccCorrect:
      LED_R = ~LED_R;
      /* Simple Moving Average */
      Acc.X = (s16)MoveAve_SMA(Acc.X, ACC_FIFO[0], MovegAveFIFO_Size);
      Acc.Y = (s16)MoveAve_SMA(Acc.Y, ACC_FIFO[1], MovegAveFIFO_Size);
      Acc.Z = (s16)MoveAve_SMA(Acc.Z, ACC_FIFO[2], MovegAveFIFO_Size);

      Correction_Time++;  // 等待 FIFO 填滿空值 or 填滿靜態資料
      if(Correction_Time == 400) {
        Acc.OffsetX += (Acc.X - ACC_X_OFFSET);  // 重力加速度為 0g
        Acc.OffsetY += (Acc.Y - ACC_Y_OFFSET);  // 重力加速度為 0g
        Acc.OffsetZ += (Acc.Z - ACC_Z_OFFSET);  // 重力加速度為 1g

        Correction_Time = 0;
        SensorMode = Mode_Quaternion; // Mode_MagCorrect;
      }
      break;

  /************************** Mode_CorrectMag **************************************/
    #define MagCorrect_Ave    100
    #define MagCorrect_Delay  600   // 2.5ms * 600 = 1.5s
    case Mode_MagCorrect:
      LED_R = !LED_R;
      Correction_Time++;
      switch((u16)(Correction_Time/MagCorrect_Delay)) {
        case 0:
          LED_B = 0;
          MagDataX[0] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[0] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        case 1:
          LED_B = 1;
          MagDataX[1] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[1] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        case 2:
          LED_B = 0;
          MagDataX[2] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[2] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        case 3:
          LED_B = 1;
          MagDataX[3] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[3] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        case 4:
          LED_B = 0;
          MagDataX[4] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[4] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        case 5:
          LED_B = 1;
          MagDataX[5] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[5] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        case 6:
          LED_B = 0;
          MagDataX[6] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[6] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        case 7:
          LED_B = 1;
          MagDataX[7] = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], MagCorrect_Ave);
          MagDataY[7] = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], MagCorrect_Ave);
          break;
        default:
          LED_B = 1;
          EllipseFitting(Ellipse, MagDataX, MagDataY, 8);
          Mag.EllipseSita = Ellipse[0];
          Mag.EllipseX0   = Ellipse[1];
          Mag.EllipseY0   = Ellipse[2];
          Mag.EllipseA    = Ellipse[3];
          Mag.EllipseB    = Ellipse[4];

          Correction_Time = 0;
          SensorMode = Mode_Quaternion;
          break;
      }
      break;

  /************************** Algorithm Mode **************************************/
    case Mode_Quaternion:
      LED_R = !LED_R;

      /* To Physical */
      Acc.TrueX = Acc.X*MPU9150A_4g;        // g/LSB
      Acc.TrueY = Acc.Y*MPU9150A_4g;        // g/LSB
      Acc.TrueZ = Acc.Z*MPU9150A_4g;        // g/LSB
      Gyr.TrueX = Gyr.X*MPU9150G_2000dps;   // dps/LSB
      Gyr.TrueY = Gyr.Y*MPU9150G_2000dps;   // dps/LSB
      Gyr.TrueZ = Gyr.Z*MPU9150G_2000dps;   // dps/LSB
      Mag.TrueX = Mag.X*MPU9150M_1200uT;    // uT/LSB
      Mag.TrueY = Mag.Y*MPU9150M_1200uT;    // uT/LSB
      Mag.TrueZ = Mag.Z*MPU9150M_1200uT;    // uT/LSB
      Temp.TrueT = Temp.T*MPU9150T_85degC;  // degC/LSB

      Ellipse[3] = ( Mag.X*arm_cos_f32(Mag.EllipseSita)+Mag.Y*arm_sin_f32(Mag.EllipseSita))/Mag.EllipseB;
      Ellipse[4] = (-Mag.X*arm_sin_f32(Mag.EllipseSita)+Mag.Y*arm_cos_f32(Mag.EllipseSita))/Mag.EllipseA;

      AngE.Pitch = toDeg(atan2f(Acc.TrueY, Acc.TrueZ));
      AngE.Roll  = toDeg(-asinf(Acc.TrueX));
      AngE.Yaw   = toDeg(atan2f(Ellipse[3], Ellipse[4]))+180.0f;

      Quaternion_ToNumQ(&NumQ, &AngE);

      SensorMode = Mode_Algorithm;
      break;

  /************************** Algorithm Mode ****************************************/
    case Mode_Algorithm:

      /* 加權移動平均法 Weighted Moving Average */
      Acc.X = (s16)MoveAve_WMA(Acc.X, ACC_FIFO[0], 8);
      Acc.Y = (s16)MoveAve_WMA(Acc.Y, ACC_FIFO[1], 8);
      Acc.Z = (s16)MoveAve_WMA(Acc.Z, ACC_FIFO[2], 8);
      Gyr.X = (s16)MoveAve_WMA(Gyr.X, GYR_FIFO[0], 8);
      Gyr.Y = (s16)MoveAve_WMA(Gyr.Y, GYR_FIFO[1], 8);
      Gyr.Z = (s16)MoveAve_WMA(Gyr.Z, GYR_FIFO[2], 8);
      Mag.X = (s16)MoveAve_WMA(Mag.X, MAG_FIFO[0], 64);
      Mag.Y = (s16)MoveAve_WMA(Mag.Y, MAG_FIFO[1], 64);
      Mag.Z = (s16)MoveAve_WMA(Mag.Z, MAG_FIFO[2], 64);

      /* To Physical */
      Acc.TrueX = Acc.X*MPU9150A_4g;        // g/LSB
      Acc.TrueY = Acc.Y*MPU9150A_4g;        // g/LSB
      Acc.TrueZ = Acc.Z*MPU9150A_4g;        // g/LSB
      Gyr.TrueX = Gyr.X*MPU9150G_2000dps;   // dps/LSB
      Gyr.TrueY = Gyr.Y*MPU9150G_2000dps;   // dps/LSB
      Gyr.TrueZ = Gyr.Z*MPU9150G_2000dps;   // dps/LSB
      Mag.TrueX = Mag.X*MPU9150M_1200uT;    // uT/LSB
      Mag.TrueY = Mag.Y*MPU9150M_1200uT;    // uT/LSB
      Mag.TrueZ = Mag.Z*MPU9150M_1200uT;    // uT/LSB
      Temp.TrueT = Temp.T*MPU9150T_85degC;  // degC/LSB

      /* Get Attitude Angle */
      AHRS_Update();

//      if(KEYL_U == 0)	{	PID_Roll.Kp += 0.001f;	PID_Pitch.Kp += 0.001f;  }
//      if(KEYL_L == 0)	{	PID_Roll.Kp -= 0.001f;	PID_Pitch.Kp -= 0.001f;  }
//      if(KEYL_R == 0)	{	PID_Roll.Ki += 0.0001f;	PID_Pitch.Ki += 0.0001f; }
//      if(KEYL_D == 0)	{	PID_Roll.Ki -= 0.0001f;	PID_Pitch.Ki -= 0.0001f; }
//      if(KEYR_R == 0)	{	PID_Roll.Kd += 0.0001f;	PID_Pitch.Kd += 0.0001f; }
//      if(KEYR_D == 0)	{	PID_Roll.Kd -= 0.0001f;	PID_Pitch.Kd -= 0.0001f; }
//      if(KEYR_L == 0)	{	PID_Roll.SumErr = 0.0f;	PID_Pitch.SumErr = 0.0f; }
//      if(KEYL_U == 0)	{	PID_Yaw.Kp += 0.001f;    }
//      if(KEYL_L == 0)	{	PID_Yaw.Kp -= 0.001f;    }
//      if(KEYL_R == 0)	{	PID_Yaw.Ki += 0.001f;	 }
//      if(KEYL_D == 0)	{	PID_Yaw.Ki -= 0.001f;	 }
//      if(KEYR_R == 0)	{	PID_Yaw.Kd += 0.0001f;	 }
//      if(KEYR_D == 0)	{	PID_Yaw.Kd -= 0.0001f;	 }
//      if(KEYR_L == 0)	{	PID_Roll.SumErr = 0.0f;	 }

      /* Get ZeroErr */
      PID_Pitch.ZeroErr = (float)((s16)Exp_Pitch/4.5f);
      PID_Roll.ZeroErr  = (float)((s16)Exp_Roll/4.5f);
      PID_Yaw.ZeroErr   = (float)((s16)Exp_Yaw)+180.0f;

      /* PID */
      Roll  = (s16)PID_AHRS_Cal(&PID_Roll,   AngE.Roll,  Gyr.TrueX);
      Pitch = (s16)PID_AHRS_Cal(&PID_Pitch,  AngE.Pitch, Gyr.TrueY);
//      Yaw   = (s16)PID_AHRS_CalYaw(&PID_Yaw, AngE.Yaw,   Gyr.TrueZ);
      Yaw   = (s16)(PID_Yaw.Kd*Gyr.TrueZ);
      Thr   = (s16)Exp_Thr;

      /* Motor Ctrl */
      Final_M1 = PWM_M1 + Thr + Pitch + Roll + Yaw;
      Final_M2 = PWM_M2 + Thr - Pitch + Roll - Yaw;
      Final_M3 = PWM_M3 + Thr - Pitch - Roll + Yaw;
      Final_M4 = PWM_M4 + Thr + Pitch - Roll - Yaw;

      /* Check Connection */
      #define NoSignal 1  // 1 sec
      if(KEYR_L == 0)
        Motor_Control(PWM_MOTOR_MIN, PWM_MOTOR_MIN, PWM_MOTOR_MIN, PWM_MOTOR_MIN);
      else if(((Time_Sec-RecvTime_Sec)>NoSignal) || ((Time_Sec-RecvTime_Sec)<-NoSignal))
        Motor_Control(PWM_MOTOR_MIN, PWM_MOTOR_MIN, PWM_MOTOR_MIN, PWM_MOTOR_MIN);
      else
        Motor_Control(Final_M1, Final_M2, Final_M3, Final_M4);

      /* DeBug */
      Tmp_PID_KP = PID_Yaw.Kp*1000;
      Tmp_PID_KI = PID_Yaw.Ki*1000;
      Tmp_PID_KD = PID_Yaw.Kd*1000;
      Tmp_PID_Pitch = Yaw;

      break;
  }
}
Ejemplo n.º 30
0
/*
 *perform kalman filter at time K, estimate best navigation parameter error at time K
 *estimate navigation parameters at current time when acc bias estimation is stable
 */
void vIEKFProcessTask(void* pvParameters)
{
	u8 i,j;
	u8 acc_bias_stable = 0;	//indicate whether acc bias is stably estimated
	char logData[100]={0};
	
	ekf_filter filter;	
	float dt;
	
	float measure[5]={0};
	float insBufferK[INS_FRAME_LEN];
	float insBufferCur[INS_FRAME_LEN];
	float *p_insBuffer;

	float direction;
	u8 temp;
	GPSDataType gdt={0.0,0.0,0.0,0.0,0.0};
	portBASE_TYPE xstatus;
	
	PosConDataType pcdt;	//position message send to flight control task

	/*initial filter*/
	filter=ekf_filter_new(9,5,(float *)iQ,(float *)iR,INS_GetA,INS_GetH,INS_aFunc,INS_hFunc);
	memcpy(filter->x,x,filter->state_dim*sizeof(float));
	memcpy(filter->P,iP,filter->state_dim*filter->state_dim*sizeof(float));

	/*capture an INS frame*/
	xQueueReceive(AHRSToINSQueue,&p_insBuffer,portMAX_DELAY);
	/*last number in buffer represent time interval, not time */
	p_insBuffer[INDEX_DT]=0.0;
	
	Blinks(LED1,4);
	
	for(;;)
	{
		/*capture an INS frame*/
		xQueueReceive(AHRSToINSQueue,&p_insBuffer,portMAX_DELAY);
		PutToBuffer(p_insBuffer);
		p_insBuffer[INDEX_DT]=0.0;
		
		ReadBufferBack(insBufferK);
		dt=insBufferK[INDEX_DT];
		
		/*do INS integration at time K*/
		INS_Update(navParamK, insBufferK);
		
		/*do INS integration at current time*/
		if(acc_bias_stable)
		{
			ReadBufferFront(insBufferCur);
			INS_Update(navParamCur,insBufferCur);
		}
		
		/*predict navigation error at time K*/
		EKF_predict(filter
					, (void *)(insBufferK+3)
					, NULL
					, (void *)(&dt)
					, (void *)(filter->A)
					, NULL);
			
		xstatus=xQueueReceive(xUartGPSQueue,&gdt,0);	//get measurement data
		if(xstatus == pdPASS)
		{
			float meas_Err[5]={0.0};
			
			direction = gdt.COG*0.0174533;

			temp=(u8)(gdt.Lati*0.01);
			measure[0]=(0.01745329*(temp+(gdt.Lati-temp*100.0)*0.0166667)-initPos[0])*6371004;
			
			temp=(u8)(gdt.Long*0.01);
			measure[1]=(0.01745329*(temp+(gdt.Long-temp*100.0)*0.0166667)-initPos[1])*4887077;
			
			measure[2]=gdt.Alti-initPos[2];
			measure[3]=gdt.SPD*0.51444*arm_cos_f32(direction);
			measure[4]=gdt.SPD*0.51444*arm_sin_f32(direction);
			
			for(i=0;i<5;i++)
			{
				meas_Err[i] = navParamK[i] - measure[i];
			}
			
			/*data record*/
			/*uncomment this to record data for matlab simulation*/
//			sprintf(logData,"%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\r\n",
//											insBufferK[0],insBufferK[1],insBufferK[2],
//											insBufferK[3],insBufferK[4],insBufferK[5],
//											insBufferK[6],insBufferK[7],
//											measure[0],measure[1],measure[2],measure[3],measure[4],
//											navParamK[3],navParamK[4]);
//			xQueueSend(xDiskLogQueue,logData,0);
			
			sprintf(logData, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\r\n",
							measure[0],measure[1],measure[3],measure[4],
							navParamK[0],navParamK[1],navParamK[3],navParamK[4],
							navParamCur[0],navParamCur[1],navParamCur[3],navParamCur[4]);
			xQueueSend(xDiskLogQueue,logData,0);
			/*update*/
			EKF_update(filter
						, (void *)meas_Err
						, NULL
						, NULL
						, (void *)(filter->x)
						, NULL);		
//			printf("%.2f %.2f %.4f %.4f %.4f\r\n",meas_Err[0],meas_Err[1],filter->x[6],filter->x[7],filter->x[8]);
			/*
			 *correct navParamCur
			 */
			if(acc_bias_stable)
			{
				for(i=0;i<6;i++)
					navParamCur[i] -= filter->x[i];
				navParamCur[6] = filter->x[6];
				navParamCur[7] = filter->x[7];
				navParamCur[8] = filter->x[8];
				
				pcdt.posX = navParamCur[0];
				pcdt.posY = navParamCur[1];
				pcdt.posZ = navParamCur[2];
				
				pcdt.veloX = navParamCur[3];
				pcdt.veloY = navParamCur[4];
				pcdt.veloZ = navParamCur[5];
				
				/*put to queue*/
				xQueueSend(INSToFlightConQueue,&pcdt,0);
			}
			
			/*correct navParameters at time K
			 *reset error state x*/			
			for(i=0;i<6;i++)
			{
				navParamK[i] -= filter->x[i];
				filter->x[i] = 0.0;
			}
			navParamK[6] = filter->x[6];
			navParamK[7] = filter->x[7];
			navParamK[8] = filter->x[8];			
			
			/*when acc bias stable, 
			 *calculate current navigation parameters*/
			if(!acc_bias_stable && filter->P[60]<0.007)
			{
				acc_bias_stable = 1;
				//set init value
				for(i=0;i<filter->state_dim;i++)
				{
					navParamCur[i] = navParamK[i];
				}
				//extrapolate current navigation parameters from time K
				for(i=0;i<GPS_DELAY_CNT;i++) 
				{
					if(i+buffer_header >= GPS_DELAY_CNT)
					{
						for(j=0;j<INS_FRAME_LEN;j++)
							insBufferCur[j] = IMU_delay_buffer[(i+buffer_header-GPS_DELAY_CNT)*INS_FRAME_LEN+j];
					}
					else
					{
						for(j=0;j<INS_FRAME_LEN;j++)
							insBufferCur[j] = IMU_delay_buffer[(i+buffer_header)*INS_FRAME_LEN+j];
					}
					insBufferCur[0] -= navParamK[6];
					insBufferCur[1] -= navParamK[7];
					insBufferCur[2] -= navParamK[8];
					
					INS_Update(navParamCur,insBufferCur);
				}
				Blinks(LED1,1);
			}
//			printf("%.1f %.1f %.1f %.1f %.1f\r\n",navParamK[0],navParamK[1],navParamK[2],navParamK[3],navParamK[4]);
		}
		else
		{
			/*data record*/
			sprintf(logData,"%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\r\n",
											insBufferK[0],insBufferK[1],insBufferK[2],
											insBufferK[3],insBufferK[4],insBufferK[5],
											insBufferK[6],insBufferK[7],
											0.0,0.0,0.0,0.0,0.0,
											navParamK[3],navParamK[4]);
			xQueueSend(xDiskLogQueue,logData,0);
		}
	}
}