mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 13:11:20 -05:00 
			
		
		
		
	Fix surface position calculation.
Check latitude and local decode is in valid range.
This commit is contained in:
		
							parent
							
								
									f823741b34
								
							
						
					
					
						commit
						21956dc9d0
					
				@ -474,6 +474,26 @@ void ADSBDemodGUI::updatePosition(Aircraft *aircraft)
 | 
				
			|||||||
        m_adsbDemod->setTarget(aircraft->m_azimuth, aircraft->m_elevation);
 | 
					        m_adsbDemod->setTarget(aircraft->m_azimuth, aircraft->m_elevation);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Called when we have lat & long from local decode and we need to check if it is in a valid range (<180nm/333km)
 | 
				
			||||||
 | 
					// or 1/4 of that for surface positions
 | 
				
			||||||
 | 
					bool ADSBDemodGUI::updateLocalPosition(Aircraft *aircraft, double latitude, double longitude, bool surfacePosition)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Calculate range to aircraft from station
 | 
				
			||||||
 | 
					    m_azEl.setTarget(latitude, longitude, feetToMetres(aircraft->m_altitude));
 | 
				
			||||||
 | 
					    m_azEl.calculate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Don't use the full 333km, as there may be some error in station position
 | 
				
			||||||
 | 
					    if (m_azEl.getDistance() < (surfacePosition ? 80000 : 320000))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        aircraft->m_latitude = latitude;
 | 
				
			||||||
 | 
					        aircraft->m_longitude = longitude;
 | 
				
			||||||
 | 
					        updatePosition(aircraft);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Try to find an airline logo based on ICAO
 | 
					// Try to find an airline logo based on ICAO
 | 
				
			||||||
QIcon *ADSBDemodGUI::getAirlineIcon(const QString &operatorICAO)
 | 
					QIcon *ADSBDemodGUI::getAirlineIcon(const QString &operatorICAO)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -727,6 +747,7 @@ void ADSBDemodGUI::handleADSB(
 | 
				
			|||||||
    m_correlationOnesAvg(correlationOnes);
 | 
					    m_correlationOnesAvg(correlationOnes);
 | 
				
			||||||
    aircraft->m_rssiItem->setText(QString("%1")
 | 
					    aircraft->m_rssiItem->setText(QString("%1")
 | 
				
			||||||
        .arg(CalcDb::dbPower(m_correlationOnesAvg.instantAverage()), 3, 'f', 1));
 | 
					        .arg(CalcDb::dbPower(m_correlationOnesAvg.instantAverage()), 3, 'f', 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ADS-B, non-transponder ADS-B or TIS-B rebroadcast of ADS-B (ADS-R)
 | 
					    // ADS-B, non-transponder ADS-B or TIS-B rebroadcast of ADS-B (ADS-R)
 | 
				
			||||||
    if ((df == 17) || ((df == 18) && ((ca == 0) || (ca == 1) || (ca == 6))))
 | 
					    if ((df == 17) || ((df == 18) && ((ca == 0) || (ca == 1) || (ca == 6))))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -765,7 +786,8 @@ void ADSBDemodGUI::handleADSB(
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (((tc >= 5) && (tc <= 18)) || ((tc >= 20) && (tc <= 22)))
 | 
					        else if (((tc >= 5) && (tc <= 18)) || ((tc >= 20) && (tc <= 22)))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if ((tc >= 5) && (tc <= 8))
 | 
					            bool surfacePosition = (tc >= 5) && (tc <= 8);
 | 
				
			||||||
 | 
					            if (surfacePosition)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Surface position
 | 
					                // Surface position
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -879,7 +901,8 @@ void ADSBDemodGUI::handleADSB(
 | 
				
			|||||||
            // We also need to check that both frames aren't greater than 10s apart in time (C.2.6.7), otherwise position may be out by ~10deg
 | 
					            // We also need to check that both frames aren't greater than 10s apart in time (C.2.6.7), otherwise position may be out by ~10deg
 | 
				
			||||||
            // We could compare global + local methods to see if the positions are sensible
 | 
					            // We could compare global + local methods to see if the positions are sensible
 | 
				
			||||||
            if (aircraft->m_cprValid[0] && aircraft->m_cprValid[1]
 | 
					            if (aircraft->m_cprValid[0] && aircraft->m_cprValid[1]
 | 
				
			||||||
               && (std::abs(aircraft->m_cprTime[0].toSecsSinceEpoch() - aircraft->m_cprTime[1].toSecsSinceEpoch()) < 10))
 | 
					               && (std::abs(aircraft->m_cprTime[0].toSecsSinceEpoch() - aircraft->m_cprTime[1].toSecsSinceEpoch()) < 10)
 | 
				
			||||||
 | 
					               && !surfacePosition)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Global decode using odd and even frames (C.2.6)
 | 
					                // Global decode using odd and even frames (C.2.6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -891,21 +914,19 @@ void ADSBDemodGUI::handleADSB(
 | 
				
			|||||||
                int ni, m;
 | 
					                int ni, m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int j = std::floor(59.0f*aircraft->m_cprLat[0] - 60.0f*aircraft->m_cprLat[1] + 0.5);
 | 
					                int j = std::floor(59.0f*aircraft->m_cprLat[0] - 60.0f*aircraft->m_cprLat[1] + 0.5);
 | 
				
			||||||
                latEven = dLatEven * ((j % 60) + aircraft->m_cprLat[0]);
 | 
					                latEven = dLatEven * (modulus(j, 60) + aircraft->m_cprLat[0]);
 | 
				
			||||||
 | 
					                // Southern hemisphere is in range 270-360, so adjust to -90-0
 | 
				
			||||||
                if (latEven >= 270.0f)
 | 
					                if (latEven >= 270.0f)
 | 
				
			||||||
                    latEven -= 360.0f;
 | 
					                    latEven -= 360.0f;
 | 
				
			||||||
                else if (latEven <= -270.0f)
 | 
					                latOdd = dLatOdd * (modulus(j, 59) + aircraft->m_cprLat[1]);
 | 
				
			||||||
                    latEven += 360.0f;
 | 
					 | 
				
			||||||
                latOdd = dLatOdd * ((j % 59) + aircraft->m_cprLat[1]);
 | 
					 | 
				
			||||||
                if (latOdd >= 270.0f)
 | 
					                if (latOdd >= 270.0f)
 | 
				
			||||||
                    latOdd -= 360.0f;
 | 
					                    latOdd -= 360.0f;
 | 
				
			||||||
                else if (latOdd <= -270.0f)
 | 
					 | 
				
			||||||
                    latOdd += 360.0f;
 | 
					 | 
				
			||||||
                if (aircraft->m_cprTime[0] >= aircraft->m_cprTime[1])
 | 
					                if (aircraft->m_cprTime[0] >= aircraft->m_cprTime[1])
 | 
				
			||||||
                    latitude = latEven;
 | 
					                    latitude = latEven;
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    latitude = latOdd;
 | 
					                    latitude = latOdd;
 | 
				
			||||||
 | 
					                if ((latitude <= 90.0) && (latitude >= -90.0))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    // Check if both frames in same latitude zone
 | 
					                    // Check if both frames in same latitude zone
 | 
				
			||||||
                    int latEvenNL = cprNL(latEven);
 | 
					                    int latEvenNL = cprNL(latEven);
 | 
				
			||||||
                    int latOddNL = cprNL(latOdd);
 | 
					                    int latOddNL = cprNL(latOdd);
 | 
				
			||||||
@ -935,40 +956,57 @@ void ADSBDemodGUI::handleADSB(
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    qDebug() << "ADSBDemodGUI::handleADSB: Invalid latitude " << latitude << " for " << hex << aircraft->m_icao
 | 
				
			||||||
 | 
					                        << " m_cprLat[0] " << aircraft->m_cprLat[0]
 | 
				
			||||||
 | 
					                        << " m_cprLat[1] " << aircraft->m_cprLat[1];
 | 
				
			||||||
 | 
					                    aircraft->m_cprValid[0] = false;
 | 
				
			||||||
 | 
					                    aircraft->m_cprValid[1] = false;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Local decode using a single aircraft position + location of receiver
 | 
					                // Local decode using a single aircraft position + location of receiver
 | 
				
			||||||
                // Only valid if within 180nm (C.2.6.4)
 | 
					                // Only valid if airbourne within 180nm/333km (C.2.6.4) or 45nm for surface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Caclulate latitude
 | 
					                // Caclulate latitude
 | 
				
			||||||
                const double dLatEven = 360.0/60.0;
 | 
					                const double maxDeg = surfacePosition ? 90.0 : 360.0;
 | 
				
			||||||
                const double dLatOdd = 360.0/59.0;
 | 
					                const double dLatEven = maxDeg/60.0;
 | 
				
			||||||
 | 
					                const double dLatOdd = maxDeg/59.0;
 | 
				
			||||||
                double dLat = f ? dLatOdd : dLatEven;
 | 
					                double dLat = f ? dLatOdd : dLatEven;
 | 
				
			||||||
 | 
					                double latitude, longitude;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int j = std::floor(m_azEl.getLocationSpherical().m_latitude/dLat) + std::floor(modulus(m_azEl.getLocationSpherical().m_latitude, dLat)/dLat - aircraft->m_cprLat[f] + 0.5);
 | 
					                int j = std::floor(m_azEl.getLocationSpherical().m_latitude/dLat) + std::floor(modulus(m_azEl.getLocationSpherical().m_latitude, dLat)/dLat - aircraft->m_cprLat[f] + 0.5);
 | 
				
			||||||
                aircraft->m_latitude = dLat * (j + aircraft->m_cprLat[f]);
 | 
					                latitude = dLat * (j + aircraft->m_cprLat[f]);
 | 
				
			||||||
                aircraft->m_latitudeItem->setData(Qt::DisplayRole, aircraft->m_latitude);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Caclulate longitude
 | 
					                // Caclulate longitude
 | 
				
			||||||
                double dLong;
 | 
					                double dLong;
 | 
				
			||||||
                int latNL = cprNL(aircraft->m_latitude);
 | 
					                int latNL = cprNL(latitude);
 | 
				
			||||||
                if (f == 0)
 | 
					                if (f == 0)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (latNL > 0)
 | 
					                    if (latNL > 0)
 | 
				
			||||||
                        dLong = 360.0 / latNL;
 | 
					                        dLong = maxDeg / latNL;
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                        dLong = 360.0;
 | 
					                        dLong = maxDeg;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if ((latNL - 1) > 0)
 | 
					                    if ((latNL - 1) > 0)
 | 
				
			||||||
                        dLong = 360.0 / (latNL - 1);
 | 
					                        dLong = maxDeg / (latNL - 1);
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                        dLong = 360.0;
 | 
					                        dLong = maxDeg;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                int m = std::floor(m_azEl.getLocationSpherical().m_longitude/dLong) + std::floor(modulus(m_azEl.getLocationSpherical().m_longitude, dLong)/dLong - aircraft->m_cprLong[f] + 0.5);
 | 
					                int m = std::floor(m_azEl.getLocationSpherical().m_longitude/dLong) + std::floor(modulus(m_azEl.getLocationSpherical().m_longitude, dLong)/dLong - aircraft->m_cprLong[f] + 0.5);
 | 
				
			||||||
                aircraft->m_longitude = dLong * (m + aircraft->m_cprLong[f]);
 | 
					                longitude =  dLong * (m + aircraft->m_cprLong[f]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (updateLocalPosition(aircraft, latitude, longitude, surfacePosition))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    aircraft->m_latitude = latitude;
 | 
				
			||||||
 | 
					                    aircraft->m_latitudeItem->setData(Qt::DisplayRole, aircraft->m_latitude);
 | 
				
			||||||
 | 
					                    aircraft->m_longitude = longitude;
 | 
				
			||||||
                    aircraft->m_longitudeItem->setData(Qt::DisplayRole, aircraft->m_longitude);
 | 
					                    aircraft->m_longitudeItem->setData(Qt::DisplayRole, aircraft->m_longitude);
 | 
				
			||||||
                    aircraft->m_coordinates.push_back(QVariant::fromValue(*new QGeoCoordinate(aircraft->m_latitude, aircraft->m_longitude, aircraft->m_altitude)));
 | 
					                    aircraft->m_coordinates.push_back(QVariant::fromValue(*new QGeoCoordinate(aircraft->m_latitude, aircraft->m_longitude, aircraft->m_altitude)));
 | 
				
			||||||
                updatePosition(aircraft);
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (tc == 19)
 | 
					        else if (tc == 19)
 | 
				
			||||||
 | 
				
			|||||||
@ -497,6 +497,7 @@ private:
 | 
				
			|||||||
    void displayStreamIndex();
 | 
					    void displayStreamIndex();
 | 
				
			||||||
    bool handleMessage(const Message& message);
 | 
					    bool handleMessage(const Message& message);
 | 
				
			||||||
    void updatePosition(Aircraft *aircraft);
 | 
					    void updatePosition(Aircraft *aircraft);
 | 
				
			||||||
 | 
					    bool updateLocalPosition(Aircraft *aircraft, double latitude, double longitude, bool surfacePosition);
 | 
				
			||||||
    void handleADSB(
 | 
					    void handleADSB(
 | 
				
			||||||
        const QByteArray data,
 | 
					        const QByteArray data,
 | 
				
			||||||
        const QDateTime dateTime,
 | 
					        const QDateTime dateTime,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user