Пример #1
0
byte Beak::chirp(const char *chirpStr) {
    int16_t nFrames = numberOfFrames();
    size_t frameStoreSize = sizeof(SynthFrame[nFrames]);
    
    if(enoughSpaceFor(frameStoreSize)) {
        SynthFrame *frames = (SynthFrame *) alloca(frameStoreSize);
        return chirp(chirpStr, nFrames, frames);
    }
    else {
        return TOO_LITTLE_RAM_WARNING;
    }
}
Пример #2
0
byte Beak::chirp(const char *chirpStr, char *enoughSpaceForFrames) {
   return chirp(chirpStr, numberOfFrames(), (SynthFrame *) enoughSpaceForFrames);
}
/*----------------------------------------------------------------------------*/ 
void rls(void)
{
	double 	yhat = 0.0, er = 0.0, K = 0.0; 
	double 	lambda = 0.99;		/* forgetting factor, in range of [0.0, 1.0] */
	double  den = lambda; 
	int 	i, j;
	int 	n = (int)NA  + (int)NB;
	double 	pf[n];	/* pf = p * phi */
	double 	f1, f2, T, amp;
	f1 = 0.1; 		/* Hz */
	f2 = 100.0; 	/* Hz */
	T = 2.0;		/* seconds */
	amp = 1.0;		/* volt, rpm, etc */
	
	printf("RLS: time =%5.3f,  est_theta=[", t);   
    for(i = 0; i < n; i++)   
        printf("%8.4f", est_theta[i]);   
    printf("]\n");
	
	/* Excited input signal */
	u[0] = chirp(f1, f2, t, T, amp);
	/* Process output */
	y[0] = -a[0] * y[1] - a[1] * y[2] + b[0] * u[1] + b[1] * u[2];

	for(i = 0; i < n; i++)
	{
        yhat += phi[i] * est_theta[i]; /* compute the estimated value */
		pf[i] = 0.0;  
        for(j = 0; j < n; j++) 
			pf[i] += p[i][j] * phi[j]; 
			
		den += phi[i] * pf[i]; /* den = lambda + phi'*p*phi */
	}
	if ((den * 1000.0) < 0.001)
	{
		printf("Error: divided by zero, exiting...\n");
		exit(1);
	}
    er = y[0] - yhat; /* error between the process output and the estimated value */

	for (i = 0; i < n; i++)
	{
		/* the represence of the Kalman gain K here is just for easily understanding */
		K = pf[i] / den; 
		/* update estimate */
		est_theta[i] += K * er;
			
		/* update covariance matrix */
		for(j = 0; j <= i; j++) /* reason: update one part first then transpose */   
        {   
			/**
			 * p is a symmetric matrix so p = p'
			 * k is a vector, k[n]
			 * p = p - k*phi'*p = p - k*phi'*p' = p - k*(p*phi)' = p - k* pf'
			 */
			/* update the lower (left) triangular */
            p[i][j] -= K * pf[j];	  
            p[i][j] /= lambda;
			/* update the upper (right) triangular */
			p[j][i]	= p[i][j];	
        }
	}
	/* update process */
	u[2] = u[1];
	u[1] = u[0];
	y[2] = y[1];
	y[1] = y[0];
	/* update regression vector */
	phi[1] = phi[0];
	phi[0] = -y[0];
	phi[3] = phi[2];
    phi[2] = u[1]; 
}
Пример #4
0
extern void
display_vario( u8 line, u8 update )
{
   static u8 _idone; // initialisation helper
   static u8 _vbeat; // heartbeat

   u32 pressure;

   switch( update )
     {
      case DISPLAY_LINE_CLEAR:

	stop_buzzer();
	display_symbol( LCD_ICON_BEEPER1, SEG_OFF );
	display_symbol( LCD_ICON_BEEPER2, SEG_OFF );
	display_symbol( LCD_ICON_RECORD,  SEG_OFF );
	_display_l2_clean();
	return;

      case DISPLAY_LINE_UPDATE_FULL:

	display_symbol( LCD_ICON_BEEPER1,
			( G_vario.beep_mode ) ? SEG_ON : SEG_OFF );

	display_symbol( LCD_ICON_BEEPER2,
			(  ( G_vario.beep_mode == VARIO_BEEPMODE_ASCENT_0 )
			|| ( G_vario.beep_mode == VARIO_BEEPMODE_BOTH ))
			  ? SEG_ON : SEG_OFF );
	//
	// fall through to partial update
	//
      case DISPLAY_LINE_UPDATE_PARTIAL:
	break;
     }

#if VARIO_F_TIME
   // Update flight time regardless of whether we do have an altitude.
   //
   // Be careful to only update the time when a time update is active,
   // ie, not because this refresh is due to a DOWN button press.
   //
   if ( display.flag.update_time )
     {
	G_vario.stats.f_time.ss++;
	if ( G_vario.stats.f_time.ss > 59 )
	  {
	     G_vario.stats.f_time.ss = 0;
	     G_vario.stats.f_time.mm++;
	     if ( G_vario.stats.f_time.mm > 59 )
	       {
		  G_vario.stats.f_time.mm = 0;
		  G_vario.stats.f_time.hh++;
	       }
	     // Reset flight time after 19 hours, more will not fit on lcd !
	     if ( G_vario.stats.f_time.hh > 19 )
	       G_vario.stats.f_time.hh = 0;
	  }
     }
#endif

   //
   // Partial or full update. Make sure pressure sensor is being sampled, ie,
   // that line 1 is in altimeter mode.
   //

   if ( is_altitude_measurement() )
     {
	s16 diff;

	if ( vario_p_read( &pressure ) )
	  {
	     // Happens during key presses, never mind.
	     return; // no data, wait for update
	  }

	//
	// If this is the very first time we are here, we have no previous
	// pressure, handle that situation.
	//
	if ( !_idone  )
	  {
	     diff = 0;
	     ++_idone;
	  }
	else
	  {
	     //
	     // Calculate difference in Pascal - we will need it anyway for the
	     // buzzer. Pressure decreases with altitude, ensure going lower is
	     // negative.
	     // 
	     diff = G_vario.prev_pa - pressure;

#if VARIO_VZ
	     // update stats as we may want to see these after the flight.

	     if ( diff > G_vario.stats.vzmax ) G_vario.stats.vzmax = diff;
	     if ( diff < G_vario.stats.vzmin ) G_vario.stats.vzmin = diff;
#endif

#if VARIO_ALTMAX
	     // Peek at current altitude in altimeter data.
	     if ( G_vario.stats.altmax < sAlt.altitude )
	       G_vario.stats.altmax = sAlt.altitude;
#endif
	  }

	_display_l2_clean();
	// Pulse the vario heartbeat indicator.
	++_vbeat;
	display_symbol( LCD_ICON_RECORD, ( _vbeat & 1 ) ? SEG_ON : SEG_OFF );
	
	// Now see what value to display.

	switch( G_vario.view_mode )
	  {
	   case VARIO_VIEWMODE_ALT_M:
	     //
	     // convert the difference in Pa to a vertical velocity.
	     //
	     _display_signed( _pascal_to_vz( diff ), 1 );
	     break;

#if VARIO_ALT_PA
	   case VARIO_VIEWMODE_ALT_PA:
	     //
	     // display raw difference in Pascal.
	     //
	     _display_signed( diff, 0 );
	     break;
#endif
#if VARIO_PA
	   case VARIO_VIEWMODE_PA:
	     //
	     // display pressure as hhhh.pp (hPa and Pa)
	     //
	     _display_signed( pressure, 1 );
	     break;
#endif
#if VARIO_VZ
	   case VARIO_VIEWMODE_VZMAX:
	     display_symbol( LCD_SYMB_MAX, SEG_ON);
	     _display_signed( _pascal_to_vz( G_vario.stats.vzmax ), 1  );
	     break;

	   case VARIO_VIEWMODE_VZMIN:
	     display_symbol( LCD_SYMB_MAX, SEG_ON);
	     _display_signed( _pascal_to_vz( G_vario.stats.vzmin ), 1 );
	     break;
#endif

#if VARIO_ALTMAX
	   case VARIO_VIEWMODE_ALT_MAX:
	     display_symbol( LCD_SYMB_MAX, SEG_ON);
	     _display_signed( G_vario.stats.altmax, 0 );
	     break;
#endif
#if VARIO_F_TIME
	   case VARIO_VIEWMODE_F_TIME:
	     display_chars(LCD_SEG_L2_5_0, int_to_array(G_vario.stats.f_time.hh,2,0), SEG_ON);
	     display_chars(LCD_SEG_L2_3_0, int_to_array(G_vario.stats.f_time.mm,2,0), SEG_ON);
	     display_chars(LCD_SEG_L2_1_0, int_to_array(G_vario.stats.f_time.ss,2,0), SEG_ON);
	     display_symbol(LCD_SEG_L2_COL1, SEG_ON);
	     display_symbol(LCD_SEG_L2_COL0, SEG_ON);
	     break;
#endif
	   case VARIO_VIEWMODE_MAX:
	     break;

	  } // switch view mode

	// If beeper is enabled, beep.
	switch ( G_vario.beep_mode )
	  {
	   case VARIO_BEEPMODE_ASCENT_0:
	     if ( diff >= 0 ) chirp( diff );
	     break;
	   case VARIO_BEEPMODE_ASCENT_1:
	     if ( diff > 0 ) chirp( diff );
	     break;
	   case VARIO_BEEPMODE_BOTH:
	     if ( diff ) chirp( diff );
	     break;
	   case VARIO_BEEPMODE_OFF:
	   case VARIO_BEEPMODE_MAX:
	     break;
	  }
	
	// update previous pressure measurement.

	G_vario.prev_pa = pressure;

     } // L1 is in altimeter mode
   else
     {
	_display_l2_clean();
	display_chars(LCD_SEG_L2_5_0, (u8*) " NOALT", SEG_ON);
	_idone = 0; // avoid false peaks when re-enabling the altimeter
     }
}
Пример #5
0
byte Beak::chirp(const char *chirpStr) {
    int16_t nFrames = numberOfFrames();
    SynthFrame *frames = (SynthFrame *) alloca(sizeof(SynthFrame[nFrames]));

    return chirp(chirpStr, nFrames, frames);
}