示例#1
0
文件: devLXV7.cpp 项目: Mazuk/LK8000
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Parses LXWP0 sentence.
///
/// @param d         device descriptor
/// @param sentence  received NMEA sentence
/// @param info      GPS info to be updated
///
/// @retval true if the sentence has been parsed
///
//static
bool DevLXV7::LXWP0(PDeviceDescriptor_t d, const TCHAR* sentence, NMEA_INFO* info)
{
  // $LXWP0,logger_stored, airspeed, airaltitude,
  //   v1[0],v1[1],v1[2],v1[3],v1[4],v1[5], hdg, windspeed*CS<CR><LF>
  //
  // 0 loger_stored : [Y|N] (not used in LX1600)
  // 1 IAS [km/h] ----> Condor uses TAS!
  // 2 baroaltitude [m]
  // 3-8 vario values [m/s] (last 6 measurements in last second)
  // 9 heading of plane (not used in LX1600)
  // 10 windcourse [deg] (not used in LX1600)
  // 11 windspeed [km/h] (not used in LX1600)
  //
  // e.g.:
  // $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1



 /*
  if (ParToDouble(sentence, 10, &info->ExternalWindDirection) &&
      ParToDouble(sentence, 11, &info->ExternalWindSpeed))
    info->ExternalWindAvailalbe = TRUE;
*/
  TriggerVarioUpdate();

  return(true);
} // LXWP0()
示例#2
0
void
MergeThread::Tick()
{
  ScopeLock protect(device_blackboard.mutex);

  Process();

  const MoreData &basic = device_blackboard.Basic();
  if (last_any.location_available != basic.location_available)
    // trigger update if gps has become available or dropped out
    TriggerGPSUpdate();

  if ((bool)last_any.alive != (bool)basic.alive ||
      (bool)last_any.location_available != (bool)basic.location_available)
    /* trigger a redraw when the connection was just lost, to show the
       new state; when no GPS is connected, no other entity triggers
       the redraw, so we have to do it */
    TriggerCalculatedUpdate();

  TriggerVarioUpdate();

  /* update last_any in every iteration */
  last_any = basic;

  /* update last_fix only when a new GPS fix was received */
  if ((basic.time_available &&
       (!last_fix.time_available || basic.time != last_fix.time)) ||
      basic.location_available != last_fix.location_available)
    last_fix = basic;
}
示例#3
0
void
MergeThread::Tick()
{
  bool gps_updated, calculated_updated;

#ifdef HAVE_PCM_PLAYER
  bool vario_available;
  double vario;
#endif

  {
    ScopeLock protect(device_blackboard.mutex);

    Process();

    const MoreData &basic = device_blackboard.Basic();

    /* call Driver::OnSensorUpdate() on all devices */
    if (devices != nullptr)
      devices->NotifySensorUpdate(basic);

    /* trigger update if gps has become available or dropped out */
    gps_updated = last_any.location_available != basic.location_available;

    /* trigger a redraw when the connection was just lost, to show the
       new state; when no GPS is connected, no other entity triggers
       the redraw, so we have to do it */
    calculated_updated = (bool)last_any.alive != (bool)basic.alive ||
      (bool)last_any.location_available != (bool)basic.location_available;

#ifdef HAVE_PCM_PLAYER
    vario_available = basic.brutto_vario_available;
    vario = vario_available ? basic.brutto_vario : 0;
#endif

    /* update last_any in every iteration */
    last_any = basic;

    /* update last_fix only when a new GPS fix was received */
    if ((basic.time_available &&
         (!last_fix.time_available || basic.time != last_fix.time)) ||
        basic.location_available != last_fix.location_available)
      last_fix = basic;
  }

#ifdef HAVE_PCM_PLAYER
  if (vario_available)
    AudioVarioGlue::SetValue(vario);
  else
    AudioVarioGlue::NoValue();
#endif

  if (gps_updated)
    TriggerGPSUpdate();

  if (calculated_updated)
    TriggerCalculatedUpdate();

  TriggerVarioUpdate();
}
示例#4
0
static BOOL PZAN2(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *apGPS)
{
  TCHAR ctemp[80];
  double vtas, wnet, vias;

  NMEAParser::ExtractParameter(String,ctemp,0);
  vtas = StrToDouble(ctemp,NULL)/3.6;
  
  NMEAParser::ExtractParameter(String,ctemp,1);
  wnet = (StrToDouble(ctemp,NULL)-10000)/100; // cm/s
  apGPS->Vario = wnet;


  if (apGPS->BaroAltitudeAvailable)
  {
    vias = vtas/AirDensityRatio(AltitudeToQNEAltitude(apGPS->BaroAltitude));

  } else {
    vias = 0.0;
  }

  apGPS->AirspeedAvailable = TRUE;
  apGPS->TrueAirspeed = vtas;
  apGPS->IndicatedAirspeed = vias;
  apGPS->VarioAvailable = TRUE;

  TriggerVarioUpdate();

  return TRUE;
}
示例#5
0
static BOOL _PRS(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *_INFO){
	(void)d;
	if(UpdateBaroSource(_INFO, 0, d, StaticPressureToAltitude((HexStrToInt(String)*1.0)))){
		TriggerVarioUpdate();
	}
	return TRUE;
}
示例#6
0
static BOOL VARIO(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS)
{
  // $VARIO,fPressure,fVario,Bat1Volts,Bat2Volts,BatBank,TempSensor1,TempSensor2*CS

  TCHAR ctemp[80];
  NMEAParser::ExtractParameter(String,ctemp,0);
  double ps = StrToDouble(ctemp,NULL);
  UpdateBaroSource( pGPS, 0,d,  	 (1 - pow(fabs(ps / QNH), 0.190284)) * 44307.69);

  NMEAParser::ExtractParameter(String,ctemp,1);
  pGPS->Vario = StrToDouble(ctemp,NULL)/10.0;
  // JMW vario is in dm/s

  NMEAParser::ExtractParameter(String,ctemp,2);
  pGPS->ExtBatt1_Voltage = StrToDouble(ctemp,NULL);
  NMEAParser::ExtractParameter(String,ctemp,3);
  pGPS->ExtBatt2_Voltage = StrToDouble(ctemp,NULL);
  NMEAParser::ExtractParameter(String,ctemp,4);
  pGPS->ExtBatt_Bank = (int)StrToDouble(ctemp,NULL);

/*
  StartupStore(_T("++++++ BATTBANK: "));
  StartupStore(ctemp);
  StartupStore(_T("\n"));
*/

  pGPS->VarioAvailable = TRUE;

  TriggerVarioUpdate();

  return TRUE;
}
示例#7
0
static BOOL LK8EX1(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *GPS_INFO)
{

  TCHAR ctemp[80];
  bool havebaro=false;

  // HPA from the pressure sensor
  NMEAParser::ExtractParameter(String,ctemp,0);
  double ps = StrToDouble(ctemp,NULL);
  if (ps!=999999) {
	ps/=100;
	if (d == pDevPrimaryBaroSource) {
	    UpdateBaroSource( GPS_INFO, LK_EXT1, (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69);
	}
  }

  // QNE
  if (!havebaro) {
	NMEAParser::ExtractParameter(String,ctemp,1);
	double ba = StrToDouble(ctemp,NULL);
	if (ba!=99999) {
		if (d == pDevPrimaryBaroSource) {
		    UpdateBaroSource( GPS_INFO, LK_EXT1,  AltitudeToQNHAltitude(ba));
		}
	}
  }


  // VARIO
  NMEAParser::ExtractParameter(String,ctemp,2);
  double va = StrToDouble(ctemp,NULL);
  if (va != 9999) {
	GPS_INFO->Vario = va/100;
	GPS_INFO->VarioAvailable = TRUE;
  } else
	GPS_INFO->VarioAvailable = FALSE;

  // OAT
  NMEAParser::ExtractParameter(String,ctemp,3);
  double ta = StrToDouble(ctemp,NULL);
  if (ta != 99) {
	GPS_INFO->OutsideAirTemperature = ta;
	GPS_INFO->TemperatureAvailable=TRUE;
  }

  // BATTERY PERCENTAGES
  NMEAParser::ExtractParameter(String,ctemp,4);
  double voa = StrToDouble(ctemp,NULL);
  if (voa!=999) {
	GPS_INFO->ExtBatt1_Voltage = voa;
  }



  // currently unused in LK, but ready for next future
  TriggerVarioUpdate();

  return TRUE;
}
示例#8
0
BOOL PBB50(TCHAR *String, NMEA_INFO *pGPS) {
  // $PBB50,100,0,10,1,10000,0,1,0,20*4A..
  // $PBB50,0,.0,.0,0,0,1.07,0,-228*58
  // $PBB50,14,-.2,.0,196,0,.92,0,-228*71

  double vtas, vias, wnet;
  TCHAR ctemp[80];

  NMEAParser::ExtractParameter(String,ctemp,0);
  vtas = StrToDouble(ctemp,NULL)/TOKNOTS;

  NMEAParser::ExtractParameter(String,ctemp,1);
  wnet = StrToDouble(ctemp,NULL)/TOKNOTS;

  NMEAParser::ExtractParameter(String,ctemp,2);
  pGPS->MacReady = StrToDouble(ctemp,NULL)/TOKNOTS;
  CheckSetMACCREADY(pGPS->MacReady);

  NMEAParser::ExtractParameter(String,ctemp,3);
  vias = sqrt(StrToDouble(ctemp,NULL))/TOKNOTS;

  // inclimb/incruise 1=cruise,0=climb, OAT
  NMEAParser::ExtractParameter(String,ctemp,6);


  #if USESWITCHES
  int climb = iround(StrToDouble(ctemp,NULL));
  pGPS->SwitchState.VarioCircling = (climb==1);
  #endif

  #if 0 // UNUSED EnableExternalTriggerCruise
  if (EnableExternalTriggerCruise) {
    if (climb) {
      ExternalTriggerCruise = false;
      ExternalTriggerCircling = true;
    } else {
      ExternalTriggerCruise = true;
      ExternalTriggerCircling = false;
    }
  } else {
    ExternalTriggerCruise = false;
  }
  #endif

  NMEAParser::ExtractParameter(String,ctemp,7);
  pGPS->OutsideAirTemperature = StrToDouble(ctemp,NULL);
  pGPS->TemperatureAvailable = true;

  pGPS->AirspeedAvailable = TRUE;
  pGPS->IndicatedAirspeed = vias;
  pGPS->TrueAirspeed = vtas;
  pGPS->VarioAvailable = TRUE;
  pGPS->Vario = wnet;

  TriggerVarioUpdate();

  return FALSE;
}
示例#9
0
static BOOL VMVABD(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *GPS_INFO)
{
/*
	$VMVABD,  
	0000.0 gps altitude,		0
	M,				1
	0000.0 bari altitude,		2
	M,				3
	-0.0 vario ms,,,		4
	MS,				7
	0.0 ias or tas,			8
	KH,				9
	22.4 temp,			10
	C*nn

	091129
	The Brauniger Compeo can send TAS if a pitot is connected (delta hang gliders) or IAS is rotary device for para.
	Since rotary is seldom used, we assume TAS is received. No indication from NMEA about IAS or TAS selected.
	100114 IAS or TAS???
*/

  TCHAR ctemp[80];
  double vtas, vias;

  NMEAParser::ExtractParameter(String,ctemp,0);
  GPS_INFO->Altitude = StrToDouble(ctemp,NULL);

  NMEAParser::ExtractParameter(String,ctemp,2);
  if (d == pDevPrimaryBaroSource) {
	  GPS_INFO->BaroAltitude = AltitudeToQNHAltitude(StrToDouble(ctemp,NULL));
	  GPS_INFO->BaroAltitudeAvailable = TRUE;
  }

  NMEAParser::ExtractParameter(String,ctemp,4);
  GPS_INFO->Vario = StrToDouble(ctemp,NULL);
  GPS_INFO->VarioAvailable = TRUE;

  NMEAParser::ExtractParameter(String,ctemp,8);
  if (ctemp[0] != '\0') { // 100209
	// we store m/s  , so we convert it from kmh
	vias = StrToDouble(ctemp,NULL)/3.6;
	GPS_INFO->IndicatedAirspeed = vias;
	// Check if zero?
	vtas = vias*AirDensityRatio(GPS_INFO->BaroAltitude);
	GPS_INFO->TrueAirspeed = vtas;

	if (GPS_INFO->IndicatedAirspeed >0) 
		GPS_INFO->AirspeedAvailable = TRUE;
	else 
		GPS_INFO->AirspeedAvailable = FALSE;
  } else
		GPS_INFO->AirspeedAvailable = FALSE;


  TriggerVarioUpdate();

  return TRUE;
}
示例#10
0
文件: devIlec.cpp 项目: Mazuk/LK8000
static BOOL PILC(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *GPS_INFO)
{

  TCHAR ctemp[80];

  NMEAParser::ExtractParameter(String,ctemp,0);

  if (_tcscmp(ctemp,_T("PDA1"))==0) {

	NMEAParser::ExtractParameter(String,ctemp,1);
	if (d == pDevPrimaryBaroSource)
	    {
	    UpdateBaroSource( GPS_INFO, ILEC, AltitudeToQNHAltitude(StrToDouble(ctemp, NULL)));
	}

	NMEAParser::ExtractParameter(String,ctemp,2);
	GPS_INFO->Vario = StrToDouble(ctemp,NULL);

	NMEAParser::ExtractParameter(String,ctemp,3); // wind direction, integer
	double wfrom;
	wfrom = StrToDouble(ctemp,NULL); //@ could also be the NMEA checksum!
	NMEAParser::ExtractParameter(String,ctemp,4); // wind speed kph integer

	if (_tcslen(ctemp)!=0) {
		double wspeed, wconfidence;
		wspeed = StrToDouble(ctemp,NULL);
		NMEAParser::ExtractParameter(String,ctemp,5); // confidence  0-100 percentage
		wconfidence = StrToDouble(ctemp,NULL);
		// StartupStore(_T(".... WIND from %.0f speed=%.0f kph  confidence=%.0f\n"),wfrom,wspeed,wconfidence);

		SetWindEstimate(wspeed/TOKPH, wfrom,(int)(wconfidence/100)*10);
                CALCULATED_INFO.WindSpeed=wspeed/TOKPH;
                CALCULATED_INFO.WindBearing=wfrom;


	} 
		// else StartupStore(_T(".. NO WIND\n"));
	
	
	GPS_INFO->VarioAvailable = TRUE;
	TriggerVarioUpdate();
	return TRUE;
  }

  if (_tcscmp(ctemp,_T("SET"))==0) {
	NMEAParser::ExtractParameter(String,ctemp,1);
	QNH = StrToDouble(ctemp,NULL);
	// StartupStore(_T("... SET QNH= %.1f\n"),QNH);
	CAirspaceManager::Instance().QnhChangeNotify(QNH);

	return TRUE;
  }

  // Using the polar requires recalculating polar coefficients internally each time.. no thanks.
  // if (_tcscmp(ctemp,_T("POLAR"))==0) { } 

  return TRUE;
}
示例#11
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Parses LXWP0 sentence.
///
/// @param d         device descriptor
/// @param sentence  received NMEA sentence
/// @param info      GPS info to be updated
///
/// @retval true if the sentence has been parsed
///
//static
bool DevLXMiniMap::LXWP0(PDeviceDescriptor_t d, const TCHAR* sentence, NMEA_INFO* info)
{
  // $LXWP0,logger_stored, airspeed, airaltitude,
  //   v1[0],v1[1],v1[2],v1[3],v1[4],v1[5], hdg, windspeed*CS<CR><LF>
  //
  // 0 loger_stored : [Y|N] (not used in LX1600)
  // 1 IAS [km/h] ----> Condor uses TAS!
  // 2 baroaltitude [m]
  // 3-8 vario values [m/s] (last 6 measurements in last second)
  // 9 heading of plane (not used in LX1600)
  // 10 windcourse [deg] (not used in LX1600)
  // 11 windspeed [km/h] (not used in LX1600)
  //
  // e.g.:
  // $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1

  TICKER = GetTickCount();

  double alt, airspeed;

  if (ParToDouble(sentence, 1, &airspeed))
  {
    airspeed /= TOKPH;
    info->TrueAirspeed = airspeed;
    info->AirspeedAvailable = TRUE;


  }

  if (ParToDouble(sentence, 2, &alt))
  {
    info->IndicatedAirspeed = airspeed / AirDensityRatio(alt);

    if (d == pDevPrimaryBaroSource)
    {
      UpdateQNH(CalculateQNH(alt, alt + AltOffset));
      UpdateBaroSource(info, 0, d, alt + AltOffset);


     /* if(FirstCheckBaroAlt)
      {
      FirstCheckBaroAlt = false;
      InputEvents::eventSetup(_T("Basic"));
      }*/
    }
  }

  if (ParToDouble(sentence, 3, &info->Vario))
    info->VarioAvailable = TRUE;

  if (ParToDouble(sentence, 10, &info->ExternalWindDirection) &&
      ParToDouble(sentence, 11, &info->ExternalWindSpeed))
    info->ExternalWindAvailable = TRUE;

  TriggerVarioUpdate();

  return(true);
} // LXWP0()
示例#12
0
bool DevLXV7_EXP::PLXVF(PDeviceDescriptor_t d, const TCHAR* sentence, NMEA_INFO* info)
{

  double alt, airspeed;


  if (ParToDouble(sentence, 1, &info->AccelX))
    if (ParToDouble(sentence, 2, &info->AccelY))
      if (ParToDouble(sentence, 3, &info->AccelZ))
        info->AccelerationAvailable = true;

  if (ParToDouble(sentence, 5, &airspeed))
  {
//	airspeed = 135.0/TOKPH;
	info->IndicatedAirspeed = airspeed;
	info->AirspeedAvailable = TRUE;

  }

  if (ParToDouble(sentence, 6, &alt))
  {
	UpdateBaroSource( info, 0, d, AltitudeToQNHAltitude(alt));
    info->TrueAirspeed =  airspeed * AirDensityRatio(alt);
  }

  if (ParToDouble(sentence, 4, &info->Vario))
  {
	info->VarioAvailable = TRUE;
	TriggerVarioUpdate();
  }


  // Get STF switch
double fTmp;
if (ParToDouble(sentence, 7, &fTmp))
{
int  iTmp = (int)(fTmp+0.1);
EnableExternalTriggerCruise = true;

static int  iOldVarioSwitch=0;
if(iTmp != iOldVarioSwitch)
{
  iOldVarioSwitch = iTmp;
  if(iTmp==1)
  {
    ExternalTriggerCruise = true;
    ExternalTriggerCircling = false;
  }
  else
  {
    ExternalTriggerCruise = false;
    ExternalTriggerCircling = true;
  }
}
}

  return(true);
} // PLXVF()
示例#13
0
文件: Parser.cpp 项目: rkalman/LK8000
void NMEAParser::Reset(void) {

  // clear status
  nmeaParser1._Reset();
  nmeaParser2._Reset();

  // trigger updates
  TriggerGPSUpdate();
  TriggerVarioUpdate();
}
示例#14
0
static BOOL LK8EX1(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS)
{

    TCHAR ctemp[80];
    bool havebaro=false;

    // HPA from the pressure sensor
    NMEAParser::ExtractParameter(String,ctemp,0);
    double ps = StrToDouble(ctemp,NULL);
    if (ps!=999999) {
        UpdateBaroSource( pGPS, 0,d, StaticPressureToAltitude(ps));
        havebaro = true;
    }

    // QNE
    if (!havebaro) {
        NMEAParser::ExtractParameter(String,ctemp,1);
        double ba = StrToDouble(ctemp,NULL);
        if (ba!=99999) {
            UpdateBaroSource( pGPS, 0,d,  AltitudeToQNHAltitude(ba));
        }
    }


    // VARIO
    NMEAParser::ExtractParameter(String,ctemp,2);
    double va = StrToDouble(ctemp,NULL);
    if (va != 9999) {
        pGPS->Vario = va/100;
        pGPS->VarioAvailable = TRUE;
    } else
        pGPS->VarioAvailable = FALSE;

    // OAT
    NMEAParser::ExtractParameter(String,ctemp,3);
    double ta = StrToDouble(ctemp,NULL);
    if (ta != 99) {
        pGPS->OutsideAirTemperature = ta;
        pGPS->TemperatureAvailable=TRUE;
    }

    // BATTERY PERCENTAGES
    NMEAParser::ExtractParameter(String,ctemp,4);
    double voa = StrToDouble(ctemp,NULL);
    if (voa!=999) {
        pGPS->ExtBatt1_Voltage = voa;
    }



    // currently unused in LK, but ready for next future
    TriggerVarioUpdate();

    return TRUE;
}
示例#15
0
/**
 * Main loop of the CalculationThread
 */
void
CalculationThread::tick()
{
  const bool gps_updated = gps_trigger.test();

  // update and transfer master info to glide computer
  {
    ScopeLock protect(mutexBlackboard);
    const GlidePolar &glide_polar = glide_computer.get_glide_polar();

    // if (new GPS data available)
    if (gps_updated)
      device_blackboard.tick(glide_polar);
    else
      device_blackboard.tick_fast(glide_polar);

    // Copy data from DeviceBlackboard to GlideComputerBlackboard
    glide_computer.ReadBlackboard(device_blackboard.Basic());
    // Copy settings form SettingsComputerBlackboard to GlideComputerBlackboard
    glide_computer.ReadSettingsComputer(device_blackboard.SettingsComputer());
    // Copy mapprojection from MapProjectionBlackboard to GlideComputerBlackboard
    glide_computer.ReadMapProjection(device_blackboard.MapProjection());
  }

  // if (time advanced and slow calculations need to be updated)
  if (gps_updated && glide_computer.ProcessGPS())
    // do slow calculations
    glide_computer.ProcessIdle();

  // values changed, so copy them back now: ONLY CALCULATED INFO
  // should be changed in DoCalculations, so we only need to write
  // that one back (otherwise we may write over new data)
  {
    ScopeLock protect(mutexBlackboard);
    device_blackboard.ReadBlackboard(glide_computer.Calculated());
    if (device_blackboard.Basic().MacCready != glide_computer.Basic().MacCready)
      device_blackboard.SetMC(glide_computer.Basic().MacCready);
  }

  // if (new GPS data)
  if (gps_updated) {
    // inform map new data is ready
#ifdef ENABLE_OPENGL
    CommonInterface::main_window.map.invalidate();
#else
    draw_thread->trigger_redraw();
#endif

    if (!glide_computer.Basic().TotalEnergyVarioAvailable)
      // emulate vario update
      TriggerVarioUpdate();
  }
}
示例#16
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Parses LXWP0 sentence.
///
/// @param d         device descriptor
/// @param sentence  received NMEA sentence
/// @param info      GPS info to be updated
///
/// @retval true if the sentence has been parsed
///
//static
bool DevLX::LXWP0(PDeviceDescriptor_t d, const TCHAR* sentence, NMEA_INFO* info)
{
  // $LXWP0,logger_stored, airspeed, airaltitude,
  //   v1[0],v1[1],v1[2],v1[3],v1[4],v1[5], hdg, windspeed*CS<CR><LF>
  //
  // 0 loger_stored : [Y|N] (not used in LX1600)
  // 1 IAS [km/h] ----> Condor uses TAS!
  // 2 baroaltitude [m]
  // 3-8 vario values [m/s] (last 6 measurements in last second)
  // 9 heading of plane (not used in LX1600)
  // 10 windcourse [deg] (not used in LX1600)
  // 11 windspeed [km/h] (not used in LX1600)
  //
  // e.g.:
  // $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1

  double alt=0, airspeed=0;

  if (ParToDouble(sentence, 1, &airspeed))
  {
    airspeed /= TOKPH;
    info->TrueAirspeed = airspeed;
    info->AirspeedAvailable = TRUE;
  }

  if (ParToDouble(sentence, 2, &alt))
  {
    if (airspeed>0) {
      LKASSERT(AirDensityRatio(alt)!=0);
      info->IndicatedAirspeed = airspeed / AirDensityRatio(alt);
    }

    UpdateBaroSource( info, 0,d,  AltitudeToQNHAltitude(alt));
  }

  if (ParToDouble(sentence, 8, &info->Vario)) /* take the last value to be more recent */
    info->VarioAvailable = TRUE;

  if (ParToDouble(sentence, 9, &info->MagneticHeading)) 
      info->MagneticHeadingAvailable=TRUE;

  if (ParToDouble(sentence, 10, &info->ExternalWindDirection) &&
      ParToDouble(sentence, 11, &info->ExternalWindSpeed))
  {
	info->ExternalWindSpeed /= TOKPH;  /* convert to m/s */
    info->ExternalWindAvailable = TRUE;
  }
  TriggerVarioUpdate();

  return(true);
} // LXWP0()
示例#17
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// Parses LXWP0 sentence.
///
/// @param d         device descriptor
/// @param sentence  received NMEA sentence
/// @param info      GPS info to be updated
///
/// @retval true if the sentence has been parsed
///
//static
bool DevLX16xx::LXWP0(PDeviceDescriptor_t d, const TCHAR* sentence, NMEA_INFO* info)
{
  // $LXWP0,logger_stored, airspeed, airaltitude,
  //   v1[0],v1[1],v1[2],v1[3],v1[4],v1[5], hdg, windspeed*CS<CR><LF>
  //
  // 0 loger_stored : [Y|N] (not used in LX1600)
  // 1 IAS [km/h] ----> Condor uses TAS!
  // 2 baroaltitude [m]
  // 3-8 vario values [m/s] (last 6 measurements in last second)
  // 9 heading of plane (not used in LX1600)
  // 10 windcourse [deg] (not used in LX1600)
  // 11 windspeed [km/h] (not used in LX1600)
  //
  // e.g.:
  // $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1

  double alt, airspeed;

  if (ParToDouble(sentence, 1, &airspeed))
  {
    airspeed /= TOKPH;
    info->TrueAirspeed = airspeed;
    info->AirspeedAvailable = TRUE;
  }
  if(LX166AltitudeUpdateTimeout >0)
	  LX166AltitudeUpdateTimeout--;
  else
    if (ParToDouble(sentence, 2, &alt))
    {
    	LX16xxAlt = (int) alt;
      info->IndicatedAirspeed = airspeed / AirDensityRatio(alt);
      UpdateBaroSource( info, 0,d, AltitudeToQNHAltitude(alt));
    }

  if (ParToDouble(sentence, 3, &info->Vario))
    info->VarioAvailable = TRUE;


 /*
  if (ParToDouble(sentence, 10, &info->ExternalWindDirection) &&
      ParToDouble(sentence, 11, &info->ExternalWindSpeed))
    info->ExternalWindAvailable = TRUE;
*/
  TriggerVarioUpdate();

  return(true);
} // LXWP0()
示例#18
0
文件: LX.cpp 项目: hnpilot/XCSoar
static bool
LXWP0(NMEAInputLine &line, NMEA_INFO *GPS_INFO, bool enable_baro)
{
  /*
  $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1

   0 loger_stored (Y/N)
   1 IAS (kph) ----> Condor uses TAS!
   2 baroaltitude (m)
   3-8 vario (m/s) (last 6 measurements in last second)
   9 heading of plane
  10 windcourse (deg)
  11 windspeed (kph)
  */

  line.skip();

  fixed airspeed;
  GPS_INFO->AirspeedAvailable = line.read_checked(airspeed);

  fixed alt = line.read(fixed_zero);

  if (GPS_INFO->AirspeedAvailable) {
    GPS_INFO->TrueAirspeed = Units::ToSysUnit(airspeed, unKiloMeterPerHour);
    GPS_INFO->IndicatedAirspeed =
      GPS_INFO->TrueAirspeed / AtmosphericPressure::AirDensityRatio(alt);
  }

  if (enable_baro) {
    GPS_INFO->BaroAltitudeAvailable = true;
    GPS_INFO->BaroAltitude = alt; // ToDo check if QNH correction is needed!
  }

  GPS_INFO->TotalEnergyVarioAvailable =
    line.read_checked(GPS_INFO->TotalEnergyVario);

  line.skip(6);

  GPS_INFO->ExternalWindAvailable = ReadSpeedVector(line, GPS_INFO->wind);

  TriggerVarioUpdate();

  return true;
}
示例#19
0
static BOOL cLXWP0(PDeviceDescriptor_t d, const TCHAR *String,
                   NMEA_INFO *GPS_INFO) {
  TCHAR ctemp[80];

  /*
  $LXWP0,Y,222.3,1665.5,1.71,,,,,,239,174,10.1

   0 loger_stored (Y/N)
   1 IAS (kph) ----> Condor uses TAS!
   2 baroaltitude (m)
   3 vario (m/s)
   4-8 unknown
   9 heading of plane
  10 windcourse (deg)
  11 windspeed (kph)

  */
  double alt, airspeed;

  NMEAParser::ExtractParameter(String,ctemp,1);
  airspeed = StrToDouble(ctemp,NULL)/TOKPH;

  NMEAParser::ExtractParameter(String,ctemp,2);
  alt = StrToDouble(ctemp,NULL);

  GPS_INFO->IndicatedAirspeed = airspeed/AirDensityRatio(alt);
  GPS_INFO->TrueAirspeed = airspeed;

  if (d == pDevPrimaryBaroSource){
    GPS_INFO->BaroAltitudeAvailable = TRUE;
    GPS_INFO->BaroAltitude = alt;    // ToDo check if QNH correction is needed!
  }

  NMEAParser::ExtractParameter(String,ctemp,3);
  GPS_INFO->Vario = StrToDouble(ctemp,NULL);

  GPS_INFO->AirspeedAvailable = TRUE;
  GPS_INFO->VarioAvailable = TRUE;

  TriggerVarioUpdate();

  return TRUE;
}
示例#20
0
文件: Parser.cpp 项目: rkalman/LK8000
// TASMAN instruments support for Tasman Flight Pack model Fp10
BOOL NMEAParser::PTAS1(TCHAR *String, TCHAR **params, size_t nparams, NMEA_INFO *pGPS)
{
  double wnet,baralt,vtas;

  wnet = (StrToDouble(params[0],NULL)-200)/(10*TOKNOTS);
  baralt = max(0.0, (StrToDouble(params[2],NULL)-2000)/TOFEET);
  vtas = StrToDouble(params[3],NULL)/TOKNOTS;
  
  pGPS->AirspeedAvailable = TRUE;
  pGPS->TrueAirspeed = vtas;
  pGPS->VarioAvailable = TRUE;
  pGPS->Vario = wnet;
  UpdateBaroSource(pGPS, BARO__TASMAN, NULL,  AltitudeToQNHAltitude(baralt));
  pGPS->IndicatedAirspeed = vtas/AirDensityRatio(baralt);
 
  TASAvailable = true; // 100411 
  TriggerVarioUpdate();

  return FALSE;
}
示例#21
0
bool PLXVF(PDeviceDescriptor_t d, const TCHAR* sentence, NMEA_INFO* info)
{

    double alt, airspeed;

    if (ParToDouble(sentence, 5, &airspeed)) {
        info->IndicatedAirspeed = airspeed;
        info->AirspeedAvailable = TRUE;
    }

    if (ParToDouble(sentence, 6, &alt)) {
	UpdateBaroSource( info, 0, d, AltitudeToQNHAltitude(alt));
        info->TrueAirspeed =  airspeed * AirDensityRatio(alt);
    }

    if (ParToDouble(sentence, 4, &info->Vario)) {
	info->VarioAvailable = TRUE;
	TriggerVarioUpdate();
    }

    return(true);
} 
示例#22
0
static bool
VARIO(NMEAInputLine &line, NMEA_INFO *GPS_INFO)
{
  // $VARIO,fPressure,fVario,Bat1Volts,Bat2Volts,BatBank,TempSensor1,TempSensor2*CS

  fixed value;
  if (line.read_checked(value)) {
    GPS_INFO->BaroAltitude =
      GPS_INFO->pressure.StaticPressureToQNHAltitude(value * 100);
    GPS_INFO->BaroAltitudeAvailable = true;
  }

  if (line.read_checked(value)) {
    // vario is in dm/s
    GPS_INFO->TotalEnergyVario = value / 10;
    GPS_INFO->TotalEnergyVarioAvailable = true;
  }

  TriggerVarioUpdate();

  return true;
}
示例#23
0
void
DeviceBlackboard::Merge()
{
  real_data.reset();
  for (unsigned i = 0; i < NUMDEV; ++i) {
    per_device_data[i].expire();
    real_data.complement(per_device_data[i]);
  }

  if (replay_data.Connected) {
    replay_data.expire();
    SetBasic() = replay_data;
  } else if (simulator_data.Connected) {
    simulator_data.expire();
    SetBasic() = simulator_data;
  } else {
    SetBasic() = real_data;
  }

  computer.Fill(SetBasic(), SettingsComputer());

  ProcessFLARM();

  if (last_location_available != Basic().LocationAvailable) {
    last_location_available = Basic().LocationAvailable;
    TriggerGPSUpdate();
  } else if (last_vario_counter != Basic().VarioCounter) {
    last_vario_counter = Basic().VarioCounter;
    TriggerGPSUpdate();
  }

  if (last_te_vario_available != Basic().TotalEnergyVarioAvailable ||
      last_netto_vario_available != Basic().NettoVarioAvailable) {
    last_te_vario_available = Basic().TotalEnergyVarioAvailable;
    last_netto_vario_available = Basic().NettoVarioAvailable;
    TriggerVarioUpdate();
  }
}
示例#24
0
文件: Zander.cpp 项目: galippi/xcsoar
static bool
PZAN2(NMEAInputLine &line, NMEA_INFO *GPS_INFO)
{
  fixed vtas, wnet;

  if (line.read_checked(vtas)) {
    vtas /= fixed(3.6); // km/h -> m/s

    GPS_INFO->TrueAirspeed = vtas;
    GPS_INFO->IndicatedAirspeed = GPS_INFO->BaroAltitudeAvailable
      ? vtas / AtmosphericPressure::AirDensityRatio(GPS_INFO->BaroAltitude)
      : fixed_zero;
    GPS_INFO->AirspeedAvailable = true;
  }

  if (line.read_checked(wnet)) {
    GPS_INFO->TotalEnergyVario = (wnet - fixed(10000)) / 100;
    GPS_INFO->TotalEnergyVarioAvailable = true;
  }

  TriggerVarioUpdate();

  return true;
}
示例#25
0
////////////////////////////////////////////////////////////////////////////////////////////////////////
// $PCPROBE,T,Q0,Q1,Q2,Q3,ax,ay,az,temp,rh,batt,delta_press,abs_press,C,
// - "T" after "$PCPROBE" indicates that the string contains data. Data are represented as signed,
//  16-bit hexadecimal integers. The only exception is abs_press which is in signed 24-bits hex
//  format.
// - Q0, Q1, Q2, Q3: 3D orientation of the C-Probe in quaternion format. Heading, pitch, and roll can
//    be calculated as follows:
//      q0 = Q0 * 0.001;
//      q1 = Q1 * 0.001;
//      q2 = Q2 * 0.001;
//      q3 = Q3 * 0.001;
//      sin_pitch = -2 * (q0 * q2 - q3 * q1); // if sin_pitch > 1 or sin_pitch < -1, discard the data
//      pitch = asin(sin_pitch);
//      heading = M_PI + atan2(2*(q1 * q2 + q3 * q0), q3 * q3 - q0 * q0 - q1 * q1 + q2 * q2);
//      roll = atan2( 2 * (q0 * q1 + q3 * q2), q3 * q3 + q0 * q0 - q1 * q1 - q2 * q2);
// - ax, ay, az: x, y, z components of the acceleration in units of 0.001 g.
// - temp: temperature in units of 0.1°C.
// - rh: relative humidity in units of 0.1%.
// - batt: battery level from 0 to 100%.
// - delta_press: differential pressure (dynamic - static) in units of 0.1 Pa.
// - abs_press: absolute pressure in units of 1/400 Pa
// - C: is transmitted only if the C-Probe is being charged. In this case, heat produced by the charging
//    process is likely to affect the readings of the temperature and humidity sensors.
////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CDevCProbe::ParseData( wnmeastring& wiss, NMEA_INFO *pINFO ) {

	double q0 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	double q1 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	double q2 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	double q3 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;

	double sin_pitch = -2 * (q0 * q2 - q3 * q1); // if sin_pitch > 1 or sin_pitch < -1, discard the data

	if(sin_pitch < 1.0 && sin_pitch > -1.0){
		pINFO->MagneticCompassAvailable=TRUE;
		pINFO->Heading = (PI + atan2(2*(q1 * q2 + q3 * q0), q3 * q3 - q0 * q0 - q1 * q1 + q2 * q2))*RAD_TO_DEG;

		pINFO->GyroscopeAvailable=TRUE;
		pINFO->Pitch = asin(sin_pitch)*RAD_TO_DEG;
		pINFO->Roll = atan2( 2 * (q0 * q1 + q3 * q2), q3 * q3 + q0 * q0 - q1 * q1 - q2 * q2)*RAD_TO_DEG;
	}else{
		pINFO->MagneticCompassAvailable=FALSE;
		pINFO->GyroscopeAvailable=FALSE;
	}

	pINFO->AccelerationAvailable=TRUE;
	pINFO->AccelX = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	pINFO->AccelY = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	pINFO->AccelZ = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;

	pINFO->Gload = sqrt(pow(pINFO->AccelX,2.0)+pow(pINFO->AccelY,2.0)+pow(pINFO->AccelZ,2.0));

	pINFO->TemperatureAvailable=TRUE;
	pINFO->OutsideAirTemperature = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.1;

	pINFO->HumidityAvailable=TRUE;
	pINFO->RelativeHumidity = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.1;

	pINFO->ExtBatt1_Voltage = int16toDouble(HexStrToInt(wiss.GetNextString()))+1000;
	
	double delta_press = int16toDouble(HexStrToInt(wiss.GetNextString())) / 10.0 ;
	double abs_press = int24toDouble(HexStrToInt(wiss.GetNextString())) / 400.0;

	if(abs_press > 0.0) {
		UpdateBaroSource(pINFO, BARO__CPROBE, NULL, StaticPressureToAltitude(abs_press*100));
	}
	else {
		if(pINFO->BaroAltitudeAvailable) {
			abs_press = QNHAltitudeToStaticPressure(pINFO->BaroAltitude);
		}
		else {
			abs_press = QNHAltitudeToStaticPressure(pINFO->Altitude);
		}
	}

	if(delta_press>=0){
		pINFO->AirspeedAvailable = TRUE;
		pINFO->IndicatedAirspeed = sqrt(2*delta_press);
		pINFO->TrueAirspeed = TrueAirSpeed(delta_press,	pINFO->RelativeHumidity, pINFO->OutsideAirTemperature, abs_press>0.0?abs_press*100:101325.0);
	}

	if(*(wiss.GetNextString()) == L'C'){
		pINFO->ExtBatt1_Voltage *= -1;
	}

	LockDeviceData();
	m_delta_press = delta_press;
	m_abs_press = abs_press;
	UnlockDeviceData();

	TriggerVarioUpdate();
	return TRUE;
}
示例#26
0
////////////////////////////////////////////////////////////////////////////////////////////////////////
// $PCPROBE,T,Q0,Q1,Q2,Q3,ax,ay,az,temp,rh,batt,delta_press,abs_press,C,
// - "T" after "$PCPROBE" indicates that the string contains data. Data are represented as signed,
//  16-bit hexadecimal integers. The only exception is abs_press which is in signed 24-bits hex
//  format.
// - Q0, Q1, Q2, Q3: 3D orientation of the C-Probe in quaternion format. Heading, pitch, and roll can
//    be calculated as follows:
//      q0 = Q0 * 0.001;
//      q1 = Q1 * 0.001;
//      q2 = Q2 * 0.001;
//      q3 = Q3 * 0.001;
//      sin_pitch = -2 * (q0 * q2 - q3 * q1); // if sin_pitch > 1 or sin_pitch < -1, discard the data
//      pitch = asin(sin_pitch);
//      heading = M_PI + atan2(2*(q1 * q2 + q3 * q0), q3 * q3 - q0 * q0 - q1 * q1 + q2 * q2);
//      roll = atan2( 2 * (q0 * q1 + q3 * q2), q3 * q3 + q0 * q0 - q1 * q1 - q2 * q2);
// - ax, ay, az: x, y, z components of the acceleration in units of 0.001 g.
// - temp: temperature in units of 0.1°C.
// - rh: relative humidity in units of 0.1%.
// - batt: battery level from 0 to 100%.
// - delta_press: differential pressure (dynamic - static) in units of 0.1 Pa.
// - abs_press: absolute pressure in units of 1/400 Pa
// - C: is transmitted only if the C-Probe is being charged. In this case, heat produced by the charging
//    process is likely to affect the readings of the temperature and humidity sensors.
////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CDevCProbe::ParseData( tnmeastring& wiss, NMEA_INFO *pINFO ) {

	double q0 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	double q1 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	double q2 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	double q3 = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;

	double sin_pitch = -2 * (q0 * q2 - q3 * q1); // if sin_pitch > 1 or sin_pitch < -1, discard the data

	if(sin_pitch < 1.0 && sin_pitch > -1.0){
		pINFO->MagneticHeadingAvailable=TRUE;
		pINFO->MagneticHeading = (PI + atan2(2*(q1 * q2 + q3 * q0), q3 * q3 - q0 * q0 - q1 * q1 + q2 * q2))*RAD_TO_DEG;

		pINFO->GyroscopeAvailable=TRUE;
		pINFO->Pitch = asin(sin_pitch)*RAD_TO_DEG;
		pINFO->Roll = atan2( 2 * (q0 * q1 + q3 * q2), q3 * q3 + q0 * q0 - q1 * q1 - q2 * q2)*RAD_TO_DEG;
	}else{
		pINFO->MagneticHeadingAvailable=FALSE;
		pINFO->GyroscopeAvailable=FALSE;
	}

	pINFO->AccelerationAvailable=TRUE;
	pINFO->AccelX = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	pINFO->AccelY = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;
	pINFO->AccelZ = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.001;

	pINFO->TemperatureAvailable=TRUE;
	pINFO->OutsideAirTemperature = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.1;

	pINFO->HumidityAvailable=TRUE;
	pINFO->RelativeHumidity = int16toDouble(HexStrToInt(wiss.GetNextString())) * 0.1;

	pINFO->ExtBatt1_Voltage = int16toDouble(HexStrToInt(wiss.GetNextString()))+1000;

	double delta_press = int16toDouble(HexStrToInt(wiss.GetNextString())) * 1.0/10.0 ;
	double abs_press = int24toDouble(HexStrToInt(wiss.GetNextString())) * (1.0/4.0);

    LockDeviceData();
	m_delta_press = delta_press;
	m_abs_press = abs_press;
	UnlockDeviceData();
    
    // the highest sea level air pressure ever recorded was 1084 mb (32.01 in.) 
    //  at Siberia associated with an extremely cold air mass.
	if(abs_press > 0.0 && abs_press < 115000.0) {
		UpdateBaroSource(pINFO, BARO__CPROBE, NULL, StaticPressureToAltitude(abs_press));
	}
	else {
		if(pINFO->BaroAltitudeAvailable) {
			abs_press = QNHAltitudeToStaticPressure(pINFO->BaroAltitude);
		}
		else {
			abs_press = QNHAltitudeToStaticPressure(pINFO->Altitude);
		}
	}

	if(delta_press>0.0){
		pINFO->AirspeedAvailable = TRUE;
		pINFO->IndicatedAirspeed = sqrt(2 * delta_press / 1.225);
		pINFO->TrueAirspeed = TrueAirSpeed(delta_press,	pINFO->RelativeHumidity, pINFO->OutsideAirTemperature, abs_press>0.0?abs_press:101325.0);
	}

	if(*(wiss.GetNextString()) == L'C'){
		pINFO->ExtBatt1_Voltage *= -1;
	}

	TriggerVarioUpdate();
	return TRUE;
}
示例#27
0
static BOOL FLYSEN(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS)
{

  TCHAR ctemp[80];
  double vtas;
  static int offset=-1;

  d->nmeaParser.connected = true;

  // firmware 3.31h no offset
  // firmware 3.32  1 offset
  // Determine firmware version, assuming it will not change in the session!
  if (offset<0) {
	NMEAParser::ExtractParameter(String,ctemp,8);
	if ( (_tcscmp(ctemp,_T("A"))==0) || (_tcscmp(ctemp,_T("V"))==0))
		offset=0;
	else {
		NMEAParser::ExtractParameter(String,ctemp,9);
		if ( (_tcscmp(ctemp,_T("A"))==0) || (_tcscmp(ctemp,_T("V"))==0))
			offset=1;
		else
			return TRUE;
	}
  }

  // VOID GPS SIGNAL
  NMEAParser::ExtractParameter(String,ctemp,8+offset);
  if (_tcscmp(ctemp,_T("V"))==0) {
	pGPS->NAVWarning=true;
	// GPSCONNECT=false; // 121127 NO!!
	goto label_nogps;
  }
  // ------------------------

  double tmplat;
  double tmplon;

  NMEAParser::ExtractParameter(String,ctemp,1+offset);
  tmplat = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
  NMEAParser::ExtractParameter(String,ctemp,2+offset);
  tmplat = NorthOrSouth(tmplat, ctemp[0]);

  NMEAParser::ExtractParameter(String,ctemp,3+offset);
  tmplon = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
  NMEAParser::ExtractParameter(String,ctemp,4+offset);
  tmplon = EastOrWest(tmplon,ctemp[0]);

  if (!((tmplat == 0.0) && (tmplon == 0.0))) {
        pGPS->Latitude = tmplat;
        pGPS->Longitude = tmplon;
	pGPS->NAVWarning=false;
  }

  // GPS SPEED
  NMEAParser::ExtractParameter(String,ctemp,6+offset);
  pGPS->Speed = StrToDouble(ctemp,NULL)/10;

  // TRACK BEARING
  if (pGPS->Speed>1.0) {
	NMEAParser::ExtractParameter(String,ctemp,5+offset);
	pGPS->TrackBearing = AngleLimit360(StrToDouble(ctemp, NULL));
  }

  // HGPS
  NMEAParser::ExtractParameter(String,ctemp,7+offset);
  pGPS->Altitude = StrToDouble(ctemp,NULL);

  // ------------------------
  label_nogps:

  // SATS
  NMEAParser::ExtractParameter(String,ctemp,9+offset);
  pGPS->SatellitesUsed = (int) StrToDouble(ctemp,NULL);

  // DATE
  // Firmware 3.32 has got the date
  if (offset>0) {
	NMEAParser::ExtractParameter(String,ctemp,0);
	long gy, gm, gd;
	TCHAR *Stop;
        gy = _tcstol(&ctemp[4], &Stop, 10) + 2000;
        ctemp[4] = '\0';
        gm = _tcstol(&ctemp[2], &Stop, 10);
        ctemp[2] = '\0';
        gd = _tcstol(&ctemp[0], &Stop, 10);

	if ( ((gy > 1980) && (gy <2100) ) && (gm != 0) && (gd != 0) ) {
		pGPS->Year = gy;
		pGPS->Month = gm;
		pGPS->Day = gd;
	}
  }

  // TIME
  // ignoring 00:00.00
  // We need to manage UTC time
#ifndef OLD_TIME_MODIFY
  static int StartDay=-1;
  if (pGPS->SatellitesUsed>0) {
      NMEAParser::ExtractParameter(String,ctemp,0+offset);
      pGPS->Time = TimeModify(ctemp, pGPS, StartDay);
  }
  // TODO : check if TimeHasAdvanced check is needed (cf. Parser.cpp)
#else
  NMEAParser::ExtractParameter(String,ctemp,0+offset);
  double fixTime = StrToDouble(ctemp,NULL);

  static  int day_difference=0, previous_months_day_difference=0;
  static int startday=-1;

  if (fixTime>0 && pGPS->SatellitesUsed>0) {
	double hours, mins,secs;
	hours = fixTime / 10000;
	pGPS->Hour = (int)hours;
	mins = fixTime / 100;
	mins = mins - (pGPS->Hour*100);
	pGPS->Minute = (int)mins;
	secs = fixTime - (pGPS->Hour*10000) - (pGPS->Minute*100);
	pGPS->Second = (int)secs;

        fixTime = secs + (pGPS->Minute*60) + (pGPS->Hour*3600);

        if ((startday== -1) && (pGPS->Day != 0)) {
	   if (offset)
              StartupStore(_T(". FLYSEN First GPS DATE: %d-%d-%d%s"), pGPS->Year, pGPS->Month, pGPS->Day,NEWLINE);
	   else
              StartupStore(_T(". FLYSEN No Date, using PNA GPS DATE: %d-%d-%d%s"), pGPS->Year, pGPS->Month, pGPS->Day,NEWLINE);
           startday = pGPS->Day;
           day_difference=0;
           previous_months_day_difference=0;
        }
        if (startday != -1) {
           if (pGPS->Day < startday) {
              // detect change of month (e.g. day=1, startday=26)
              previous_months_day_difference=day_difference+1;
              day_difference=0;
              startday = pGPS->Day;
              StartupStore(_T(". FLYSEN Change GPS DATE to NEW MONTH: %d-%d-%d  (%d days running)%s"),
              pGPS->Year, pGPS->Month, pGPS->Day,previous_months_day_difference,NEWLINE);
           }
           if ( (pGPS->Day-startday)!=day_difference) {
              StartupStore(_T(". FLYSEN Change GPS DATE: %d-%d-%d%s"), pGPS->Year, pGPS->Month, pGPS->Day,NEWLINE);
           }

           day_difference = pGPS->Day-startday;
           if ((day_difference+previous_months_day_difference)>0) {
              fixTime += (day_difference+previous_months_day_difference) * 86400;
           }
        }
	pGPS->Time = fixTime;
  }
#endif

  // HPA from the pressure sensor
  //   NMEAParser::ExtractParameter(String,ctemp,10+offset);
  //   double ps = StrToDouble(ctemp,NULL)/100;
  //   pGPS->BaroAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;

  // HBAR 1013.25
  NMEAParser::ExtractParameter(String,ctemp,11+offset);
  double palt=StrToDouble(ctemp,NULL);
  UpdateBaroSource( pGPS, 0,d, QNEAltitudeToQNHAltitude(palt));

  // VARIO
  NMEAParser::ExtractParameter(String,ctemp,12+offset);
  pGPS->Vario = StrToDouble(ctemp,NULL)/100;

  // TAS
  NMEAParser::ExtractParameter(String,ctemp,13+offset);
  vtas=StrToDouble(ctemp,NULL)/10;
  pGPS->IndicatedAirspeed = vtas/AirDensityRatio(palt);
  pGPS->TrueAirspeed = vtas;
  if (pGPS->IndicatedAirspeed >0)
	pGPS->AirspeedAvailable = TRUE;
  else
	pGPS->AirspeedAvailable = FALSE;

  // ignore n.14 airspeed source

  // OAT
  NMEAParser::ExtractParameter(String,ctemp,15+offset);
  pGPS->OutsideAirTemperature = StrToDouble(ctemp,NULL);
  pGPS->TemperatureAvailable=TRUE;

  // ignore n.16 baloon temperature

  // BATTERY PERCENTAGES
  NMEAParser::ExtractParameter(String,ctemp,17+offset);
  pGPS->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)+1000;
  NMEAParser::ExtractParameter(String,ctemp,18+offset);
  pGPS->ExtBatt2_Voltage = StrToDouble(ctemp,NULL)+1000;



  pGPS->VarioAvailable = TRUE;

  // currently unused in LK, but ready for next future
  TriggerVarioUpdate();
  TriggerGPSUpdate();

  return TRUE;
}
示例#28
0
DWORD CalculationThread (LPVOID lpvoid) {
	(void)lpvoid;
  bool needcalculationsslow;

  NMEA_INFO     tmpGPS;
  DERIVED_INFO  tmpCALCULATED;
  FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime ;
  needcalculationsslow = false;

  // let's not create a deadlock here, setting the go after another race condition
  goCalculationThread=true; // 091119 CHECK
  // wait for proper startup signal
  while (!MapWindow::IsDisplayRunning()) {
    Sleep(100);
  }

  // while (!goCalculating) Sleep(100);
  Sleep(1000); // 091213  BUGFIX need to syncronize !!! TOFIX02 TODO

  while (!MapWindow::CLOSETHREAD) {

    WaitForSingleObject(dataTriggerEvent, 5000);
    ResetEvent(dataTriggerEvent);
    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    GetThreadTimes( hCalculationThread, &CreationTime, &ExitTime,&StartKernelTime,&StartUserTime);

    // make local copy before editing...
    LockFlightData();
      FLARM_RefreshSlots(&GPS_INFO);
      memcpy(&tmpGPS,&GPS_INFO,sizeof(NMEA_INFO));
      memcpy(&tmpCALCULATED,&CALCULATED_INFO,sizeof(DERIVED_INFO));
    UnlockFlightData();

    DoCalculationsVario(&tmpGPS,&tmpCALCULATED);
    if (!tmpGPS.VarioAvailable) {
    	TriggerVarioUpdate(); // emulate vario update
    } 
    
    if(DoCalculations(&tmpGPS,&tmpCALCULATED)){
	#if (WINDOWSPC>0) && !TESTBENCH
	#else
        if (!INPAN)
	#endif
	{
           MapWindow::MapDirty = true;
	}
        needcalculationsslow = true;

        if (tmpCALCULATED.Circling)
          MapWindow::mode.Fly(MapWindow::Mode::MODE_FLY_CIRCLING);
        else if (tmpCALCULATED.FinalGlide)
          MapWindow::mode.Fly(MapWindow::Mode::MODE_FLY_FINAL_GLIDE);
        else
          MapWindow::mode.Fly(MapWindow::Mode::MODE_FLY_CRUISE);
    }
        
    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    // This is activating another run for Thread Draw
    TriggerRedraws(&tmpGPS, &tmpCALCULATED);

    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    if (SIMMODE) {
	if (needcalculationsslow || ( ReplayLogger::IsEnabled() ) ) { 
		DoCalculationsSlow(&tmpGPS,&tmpCALCULATED);
		needcalculationsslow = false;
	}
    } else {
	if (needcalculationsslow) {
		DoCalculationsSlow(&tmpGPS,&tmpCALCULATED);
		needcalculationsslow = false;
	}
    }

    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    // values changed, so copy them back now: ONLY CALCULATED INFO
    // should be changed in DoCalculations, so we only need to write
    // that one back (otherwise we may write over new data)
    LockFlightData();
    memcpy(&CALCULATED_INFO,&tmpCALCULATED,sizeof(DERIVED_INFO));
    UnlockFlightData();

    // update live tracker with new values
    // this is a nonblocking call, live tracker runs on different thread
     LiveTrackerUpdate(&tmpGPS, &tmpCALCULATED);

    if (FlightDataRecorderActive) UpdateFlightDataRecorder(&tmpGPS,&tmpCALCULATED);
   
    
    if ( (GetThreadTimes( hCalculationThread, &CreationTime, &ExitTime,&EndKernelTime,&EndUserTime)) == 0) {
               Cpu_Calc=9999;
    } else {
               Cpustats(&Cpu_Calc,&StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime);
    }
  }
  return 0;
}
示例#29
0
//
// Support for new 2011 Digifly TOURTELL protocol 
// (Subset of TL1, pending upgrade in june 2011 for all devices)
//
static BOOL PDGFTTL(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS)
{
/*
	$PDGFTTL		     field     example
	QNE 1013.25 altitude		0	2025  meters
	QNH altitude			1	2000  meters
	vario cm/s	 		2	 250  2.5m/s
	IAS				4	45    kmh
	netto vario			3	-14   dm/s
	
*/

  TCHAR ctemp[80];
  double vtas, vias;
  double altqne, altqnh;
  static bool initqnh=true;

  NMEAParser::ExtractParameter(String,ctemp,0);
  altqne = StrToDouble(ctemp,NULL);
  NMEAParser::ExtractParameter(String,ctemp,1);
  altqnh = StrToDouble(ctemp,NULL);

  // AutoQNH will take care of setting an average QNH if nobody does it for a while
  if (initqnh) {
	// if digifly has qnh set by user qne and qnh are of course different
	if (altqne != altqnh) {
		QNH=FindQNH(altqne,altqnh);
        CAirspaceManager::Instance().QnhChangeNotify(QNH);
		StartupStore(_T(". Using Digifly QNH %f%s"),QNH,NEWLINE);
		initqnh=false;
	} else {
		// if locally QNH was set, either by user of by AutoQNH, stop processing QNH from digifly
		if ( (QNH <= 1012) || (QNH>=1014)) initqnh=false;
		// else continue entering initqnh until somebody changes qnh in either digifly or lk8000
	}
  }
  UpdateBaroSource( pGPS, 0,d,  AltitudeToQNHAltitude(altqne));

  NMEAParser::ExtractParameter(String,ctemp,2);
#if 1
  pGPS->Vario = StrToDouble(ctemp,NULL)/100;
#else
  double newVario = StrToDouble(ctemp,NULL)/100;
  pGPS->Vario = LowPassFilter(pGPS->Vario,newVario,0.1);
#endif
  pGPS->VarioAvailable = TRUE;


  NMEAParser::ExtractParameter(String,ctemp,4);
  if (ctemp[0] != '\0') {
	pGPS->NettoVario = StrToDouble(ctemp,NULL)/10; // dm/s
	pGPS->NettoVarioAvailable = TRUE;
  } else
	pGPS->NettoVarioAvailable = FALSE;


  NMEAParser::ExtractParameter(String,ctemp,4);
  if (ctemp[0] != '\0') {
	// we store m/s  , so we convert it from kmh
	vias = StrToDouble(ctemp,NULL)/3.6;

	if (vias >1) {
		vtas = vias*AirDensityRatio(pGPS->BaroAltitude);
		pGPS->TrueAirspeed = vtas;
		pGPS->IndicatedAirspeed = vias;
		pGPS->AirspeedAvailable = TRUE;
  	}
  } else {
	pGPS->AirspeedAvailable = FALSE;
  }


  TriggerVarioUpdate();

  return TRUE;
}
示例#30
0
static BOOL PDGFTL1(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS)
{
    /*
    	$PDGFTL1		     field     example
    	QNE 1013.25 altitude		0	2025  meters
    	QNH altitude			1	2000  meters
    	vario cm/s	 		2	 250  2.5m/s
    	netto vario			3	-14   dm/s
    	IAS				4	45    kmh
    	ground efficiency 		5	134   13:4 GR
    	Wind speed			6	28    kmh
    	Wind direction			7	65    degrees
    	Main lithium battery 3,82 v	8	382   0.01v
    	Backup AA battery 1,53 v 	9	153   0.01v

    	100209 Paolo Ventafridda
    	netto and ias optionals

    */

    TCHAR ctemp[80];
    double vtas, vias;
    double altqne, altqnh;
    static bool initqnh=true;



    NMEAParser::ExtractParameter(String,ctemp,0);
    altqne = StrToDouble(ctemp,NULL);
    NMEAParser::ExtractParameter(String,ctemp,1);
    altqnh = StrToDouble(ctemp,NULL);

    // AutoQNH will take care of setting an average QNH if nobody does it for a while
    if (initqnh) {
        // if digifly has qnh set by user qne and qnh are of course different
        if (altqne != altqnh) {
            UpdateQNH(FindQNH(altqne,altqnh));
            StartupStore(_T(". Using Digifly QNH %f%s"),QNH,NEWLINE);
            initqnh=false;
        } else {
            // if locally QNH was set, either by user of by AutoQNH, stop processing QNH from digifly
            if ( (QNH <= 1012) || (QNH>=1014)) initqnh=false;
            // else continue entering initqnh until somebody changes qnh in either digifly or lk8000
        }
    }
    UpdateBaroSource( pGPS,0, d,  AltitudeToQNHAltitude(altqne));


    NMEAParser::ExtractParameter(String,ctemp,2);
#if 1
    pGPS->Vario = StrToDouble(ctemp,NULL)/100;
#else
    double newVario = StrToDouble(ctemp,NULL)/100;
    pGPS->Vario = LowPassFilter(pGPS->Vario,newVario,0.1);
#endif
    pGPS->VarioAvailable = TRUE;


    NMEAParser::ExtractParameter(String,ctemp,3);
    if (ctemp[0] != '\0') {
        pGPS->NettoVario = StrToDouble(ctemp,NULL)/10; // dm/s
        pGPS->NettoVarioAvailable = TRUE;
    } else
        pGPS->NettoVarioAvailable = FALSE;


    NMEAParser::ExtractParameter(String,ctemp,4);
    if (ctemp[0] != '\0') {
        // we store m/s  , so we convert it from kmh
        vias = StrToDouble(ctemp,NULL)/3.6;

        if (vias >1) {
            vtas = vias*AirDensityRatio(altqne);
            pGPS->TrueAirspeed = vtas;
            pGPS->IndicatedAirspeed = vias;
            pGPS->AirspeedAvailable = TRUE;
        }
    } else {
        pGPS->AirspeedAvailable = FALSE;
    }


    NMEAParser::ExtractParameter(String,ctemp,8);
    pGPS->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)/100;
    NMEAParser::ExtractParameter(String,ctemp,9);
    pGPS->ExtBatt2_Voltage = StrToDouble(ctemp,NULL)/100;

    TriggerVarioUpdate();

    return TRUE;
}