Exemplo n.º 1
0
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// $PCPROBE, FW,f
//  Firmware version. f = 0xNNMM, where NN is the major version number and MM the minor number.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CDevCProbe::ParseFW( tnmeastring& wiss, NMEA_INFO *pINFO ) {
	unsigned int Version = HexStrToInt(wiss.GetNextString());

	LockDeviceData();
	_stprintf(m_szVersion, TEXT("%u.%.02u"), ((Version&0xFF00) >> 8), (Version&0x00FF));
	UnlockDeviceData();

	return TRUE;
}
Exemplo n.º 2
0
BOOL CDevCProbe::ParseNMEA( DeviceDescriptor_t *d, TCHAR *String, NMEA_INFO *pINFO ) {
	tnmeastring wiss(String);
	TCHAR* strToken = wiss.GetNextString();

 	if(_tcscmp(strToken,TEXT("$PCPROBE"))==0) {

  		strToken = wiss.GetNextString();

  		// this sentence must handled first, also we can't detect end of Compass Calibration.
		if (_tcscmp(strToken,TEXT("COMPASSCALIBRATION"))==0) {
			// $PCPROBE,COMPASSCALIBRATION
			//  The calibration of the accelerometers and of the magnetometers is being performed

			// no other thread modify m_bCompassCal Flag : no lock needed for read in this thread
			if(!m_bCompassCalOn){
				LockDeviceData();
				m_bCompassCalOn=TRUE;
				UnlockDeviceData();
			}

			return TRUE;
		}

		// if we receive sentence other than compass calibration -> compass calibration is finish.
		// no other thread modify m_bCompassCal Flag : no lock needed for read in this thread
		if(m_bCompassCalOn) {
			LockDeviceData();
			m_bCompassCalOn=FALSE;
			UnlockDeviceData();
		}

  		if (_tcscmp(strToken,TEXT("T"))==0) {
			BOOL bOk = ParseData(wiss, pINFO);
			if(!pINFO->BaroAltitudeAvailable) {
				SetBaroOn(d);
			}
			return bOk;
		}
		if (_tcscmp(strToken,TEXT("GYROCALIBRATION"))==0) {

			LockDeviceData();
	 		m_bCompassCalOn=FALSE;
			UnlockDeviceData();

			return ParseGyro(wiss, pINFO);
		}
		if (_tcscmp(strToken,TEXT("FW"))==0) {

			LockDeviceData();
	 		m_bCompassCalOn=FALSE;
			UnlockDeviceData();

			return ParseFW(wiss, pINFO);
		}
		if(_tcscmp(strToken,TEXT("NAME"))==0) {

			LockDeviceData();
	 		m_bCompassCalOn=FALSE;
			UnlockDeviceData();

			return ParseName(wiss, pINFO);
		}
 	}
	return FALSE;
}
Exemplo n.º 3
0
void CDevCProbe::Update() {
	TCHAR Temp[50] = {0};

	LockFlightData();
	NMEA_INFO _INFO = GPS_INFO;
	UnlockFlightData();

	LockDeviceData();
	_stprintf(Temp, TEXT("C-Probe - Version: %s"), m_szVersion);
	UnlockDeviceData();

	m_wf->SetCaption(Temp);

	WndProperty* wp;
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpPitch"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f%s"), _INFO.Pitch, gettext(_T("_@M2179_")));
		wp->SetText(Temp);
	}
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpHeading"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f%s"), _INFO.MagneticHeading, gettext(_T("_@M2179_")));
		wp->SetText(Temp);
	}
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpRoll"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f%s"), _INFO.Roll, gettext(_T("_@M2179_")));
		wp->SetText(Temp);
	}

	wp = (WndProperty*)m_wf->FindByName(TEXT("prpGx"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f"), _INFO.AccelX);
		wp->SetText(Temp);
	}
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpGy"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f"), _INFO.AccelY);
		wp->SetText(Temp);
	}
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpGz"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f"), _INFO.AccelZ);
		wp->SetText(Temp);
	}

	wp = (WndProperty*)m_wf->FindByName(TEXT("prpTemp"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f %sC"), _INFO.OutsideAirTemperature, gettext(_T("_@M2179_")));
		wp->SetText(Temp);
	}
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpRh"));
	if(wp){
		_stprintf(Temp, TEXT("%.2f %%"), _INFO.RelativeHumidity);
		wp->SetText(Temp);
	}
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpDeltaPress"));
	if(wp){
		LockDeviceData();
		_stprintf(Temp, TEXT("%.2f Pa"), m_delta_press);
		UnlockDeviceData();

		wp->SetText(Temp);
	}
	wp = (WndProperty*)m_wf->FindByName(TEXT("prpAbsPress"));
	if(wp){
		LockDeviceData();
		_stprintf(Temp, TEXT("%.2f hPa"), m_abs_press);
		UnlockDeviceData();

		wp->SetText(Temp);
	}
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}