Esempio n. 1
0
struct site LoadQTH(char *filename)
{
	/* This function reads SPLAT! .qth (site location) files.
	   The latitude and longitude may be expressed either in
	   decimal degrees, or in degree, minute, second format.
	   Antenna height is assumed to be expressed in feet above
	   ground level (AGL), unless followed by the letter 'M',
	   or 'm', or by the word "meters" or "Meters", in which
	   case meters is assumed, and is handled accordingly. */

	int	x;
	char	string[50], qthfile[255];
	struct	site tempsite;
	FILE	*fd=NULL;

	for (x=0; filename[x]!='.' && filename[x]!=0 && x<250; x++)
		qthfile[x]=filename[x];

	qthfile[x]='.';
	qthfile[x+1]='q';
	qthfile[x+2]='t';
	qthfile[x+3]='h';
	qthfile[x+4]=0;

	tempsite.lat=91.0;
	tempsite.lon=361.0;
	tempsite.name[0]=0;
	tempsite.azimuth=0.0;

	fd=fopen(qthfile,"r");

	if (fd!=NULL)
	{
		/* Site Name */
		fgets(string,49,fd);

		/* Strip <CR> and/or <LF> from end of site name */

		for (x=0; string[x]!=13 && string[x]!=10 && string[x]!=0; tempsite.name[x]=string[x], x++);

		tempsite.name[x]=0;

		/* Site Latitude */
		fgets(string,49,fd);
		tempsite.lat=ReadBearing(string);

		/* Site Longitude */
		fgets(string,49,fd);
		tempsite.lon=ReadBearing(string);

		fclose(fd);
	}

	return tempsite;
}
Esempio n. 2
0
/**
 * Parse HDM NMEA sentence.
 */
bool
NMEAParser::HDM(NMEAInputLine &line, NMEAInfo &info)
{
    /*
     * $HCHDM,238.5,M*hh/CR/LF
     *
     * Field Number:
     *  1) Magnetic Heading to one decimal place
     *  2) M (Magnetic)
     *  3) Checksum
     */
    Angle heading;
    bool heading_available = ReadBearing(line, heading);

    if (!heading_available)
        info.heading_available.Clear();
    else if (heading_available) {
        info.heading = heading;
        info.heading_available.Update(info.clock);
    }

    return true;
}
Esempio n. 3
0
bool
NMEAParser::RMC(NMEAInputLine &line, NMEAInfo &info)
{
    /*
     * $--RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxx,x.x,a,m,*hh
     *
     * Field Number:
     *  1) UTC Time
     *  2) Status, V=Navigation receiver warning A=Valid
     *  3) Latitude
     *  4) N or S
     *  5) Longitude
     *  6) E or W
     *  7) Speed over ground, knots
     *  8) Track made good, degrees true
     *  9) Date, ddmmyy
     * 10) Magnetic Variation, degrees
     * 11) E or W
     * 12) FAA mode indicator (NMEA 2.3 and later)
     * 13) Checksum
     */

    fixed this_time;
    if (!ReadTime(line, info.date_time_utc, this_time))
        return true;

    bool gps_valid = !NAVWarn(line.ReadFirstChar());

    GeoPoint location;
    bool valid_location = ReadGeoPoint(line, location);

    fixed speed;
    bool ground_speed_available = line.ReadChecked(speed);

    Angle track;
    bool track_available = ReadBearing(line, track);

    // JMW get date info first so TimeModify is accurate
    ReadDate(line, info.date_time_utc);

    Angle variation;
    bool variation_available = ReadVariation(line, variation);

    if (!TimeHasAdvanced(this_time, info))
        return true;

    if (!gps_valid)
        info.location_available.Clear();
    else if (valid_location)
        info.location_available.Update(info.clock);

    if (valid_location)
        info.location = location;

    if (ground_speed_available) {
        info.ground_speed = Units::ToSysUnit(speed, Unit::KNOTS);
        info.ground_speed_available.Update(info.clock);
    }

    if (track_available && info.MovementDetected()) {
        // JMW don't update bearing unless we're moving
        info.track = track;
        info.track_available.Update(info.clock);
    }

    if (!variation_available)
        info.variation_available.Clear();
    else if (variation_available) {
        info.variation = variation;
        info.variation_available.Update(info.clock);
    }

    info.gps.real = real;
#if defined(ANDROID) || defined(__APPLE__)
    info.gps.nonexpiring_internal_gps = false;
#endif

    return true;
}
Esempio n. 4
0
void
ParsePFLAA(NMEAInputLine &line, TrafficList &flarm, double clock)
{
    flarm.modified.Update(clock);

    // PFLAA,<AlarmLevel>,<RelativeNorth>,<RelativeEast>,<RelativeVertical>,
    //   <IDType>,<ID>,<Track>,<TurnRate>,<GroundSpeed>,<ClimbRate>,<AcftType>
    FlarmTraffic traffic;
    traffic.alarm_level = (FlarmTraffic::AlarmType)
                          line.Read((int)FlarmTraffic::AlarmType::NONE);

    double value;
    bool stealth = false;

    if (!line.ReadChecked(value))
        // Relative North is required !
        return;
    traffic.relative_north = value;

    if (!line.ReadChecked(value))
        // Relative East is required !
        return;
    traffic.relative_east = value;

    if (!line.ReadChecked(value))
        // Relative Altitude is required !
        return;
    traffic.relative_altitude = value;

    line.Skip(); /* id type */

    // 5 id, 6 digit hex
    char id_string[16];
    line.Read(id_string, 16);
    traffic.id = FlarmId::Parse(id_string, nullptr);

    Angle track;
    traffic.track_received = ReadBearing(line, track);
    if (!traffic.track_received) {
        // Field is empty in stealth mode
        stealth = true;
        traffic.track = Angle::Zero();
    } else
        traffic.track = track;

    traffic.turn_rate_received = line.ReadChecked(value);
    if (!traffic.turn_rate_received) {
        // Field is empty in stealth mode
        traffic.turn_rate = 0;
    } else
        traffic.turn_rate = value;

    traffic.speed_received = line.ReadChecked(value);
    if (!traffic.speed_received) {
        // Field is empty in stealth mode
        stealth = true;
        traffic.speed = 0;
    } else
        traffic.speed = value;

    traffic.climb_rate_received = line.ReadChecked(value);
    if (!traffic.climb_rate_received) {
        // Field is empty in stealth mode
        stealth = true;
        traffic.climb_rate = 0;
    } else
        traffic.climb_rate = value;

    traffic.stealth = stealth;

    unsigned type = line.Read(0);
    if (type > 15 || type == 14)
        traffic.type = FlarmTraffic::AircraftType::UNKNOWN;
    else
        traffic.type = (FlarmTraffic::AircraftType)type;

    FlarmTraffic *flarm_slot = flarm.FindTraffic(traffic.id);
    if (flarm_slot == nullptr) {
        flarm_slot = flarm.AllocateTraffic();
        if (flarm_slot == nullptr)
            // no more slots available
            return;

        flarm_slot->Clear();
        flarm_slot->id = traffic.id;

        flarm.new_traffic.Update(clock);
    }

    // set time of fix to current time
    flarm_slot->valid.Update(clock);

    flarm_slot->Update(traffic);
}