public void StartRealTime(GpsRealTimeHandler realtimeCallback)
        {
            int  total     = 0;
            int  maxErrors = 5;
            int  errors    = maxErrors;
            bool finished  = false;

            m_stopRealTime = false;

            while (!finished && !m_stopRealTime)
            {
                GpsRealTimeData pvtData = new GpsRealTimeData();                                // will be returned empty if no data

                MPacketReceived received = null;
                try
                {
                    received = m_linkLayer.ReceivePacket();
                    if (!received.isGood)
                    {
                        m_linkLayer.logError("StartRealTime: bad packet received, count=" + total);
                        pvtData.comment = "bad data packet from GPS";
                        realtimeCallback(pvtData);
                        continue;
                    }
                }
                catch (Exception e)
                {
                    m_linkLayer.logError("StartRealTime: " + e.Message + "  count=" + total);
                    //if(received != null)
                    {
                        try
                        {
                            m_linkLayer.ReOpen();
                        }
                        catch (Exception ee)
                        {
                            m_linkLayer.logError("while ReOpen(): " + ee.Message);
                        }
                    }
                    pvtData.comment = e.Message.StartsWith("Timeout") ?
                                      "GPS not responding - check cable" : ("error: " + e.Message);
                    realtimeCallback(pvtData);
                    continue;
                }
                //m_linkLayer.log("" + total + " ===  " + received);
                m_linkLayer.log("StartRealTime: good packet received, count=" + total + "   " + received);
                if (received.header.EndsWith("GGA"))                    // NMEA GGA expected for location
                {
                    m_linkLayer.log("StartRealTime: " + received.header + " packet received, count=" + total + "   content=" + received);
                    try
                    {
                        MPacket pvt = received.fromString();

                        /*
                         *      $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
                         *
                         *      Where:
                         *              GGA          Global Positioning System Fix Data
                         *      0	123519       Fix taken at 12:35:19 UTC
                         *      1	4807.038,N   Latitude 48 deg 07.038' N
                         *      3	01131.000,E  Longitude 11 deg 31.000' E
                         *      5	1            Fix quality: 0 = invalid
                         *                                                              1 = GPS fix
                         *                                                              2 = DGPS fix
                         *                                                              6 = estimated (2.3 feature)
                         *      6	08           Number of satellites being tracked
                         *      7	0.9          Horizontal dilution of position
                         *      8	545.4,M      Altitude, Meters, above mean sea level
                         *      10	46.9,M       Height of geoid (mean sea level) above WGS84
                         *                                              ellipsoid
                         *      12	(empty field) time in seconds since last DGPS update
                         *      13	(empty field) DGPS station ID number
                         * 47          the checksum data, always begins with *
                         */

                        double Lat  = pvt.parseLat(1);
                        double Lng  = pvt.parseLng(1);
                        double Elev = pvt.parseElev(8);                                 // alt above mean sea level
                        pvtData.location = new GeoCoord(Lng, Lat, Elev);
                        //m_linkLayer.log("coord=" + pvtData.location);

                        // time component:
                        pvtData.time = pvt.parseNmeaTime(0, Project.localToZulu(DateTime.Now));                         // UTC

                        // errors and velocity:
                        pvtData.posError  = 0;
                        pvtData.posErrorH = 0;
                        pvtData.posErrorV = 0;
                        pvtData.fix       = 0;                                          // failed integrity check
                        switch ((string)pvt.fields[5])
                        {
                        case "0":                                                       // invalid
                            pvtData.fix = 1;                                            // invalid
                            break;

                        case "1":                                                       // GPS fix
                            pvtData.fix = 2;                                            // two dimensional
                            break;

                        case "2":                                                       // DGPS fix
                            pvtData.fix = 4;                                            // two dimensional differential
                            break;

                        case "6":                                                       // estimated
                            pvtData.fix = 6;                                            // estimated
                            break;
                        }
                        pvtData.velocityEast  = 0;
                        pvtData.velocityNorth = 0;
                        pvtData.velocityUp    = 0;

                        pvtData.comment = "received " + received.header;
                        //realtimeCallback(pvtData);

                        total++;
                        errors = maxErrors;
                    }
                    catch (Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if (received.header.EndsWith("RMC"))                       // NMEA RMC may come
                {
                    m_linkLayer.log("StartRealTime: " + received.header + " packet received, count=" + total + "   content=" + received);
                    try
                    {
                        MPacket pvt = received.fromString();

                        // $GPRMC,052458.73,V,3334.6441,N,11739.6622,W,00.0,000.0,290103,13,E*4F

                        /*
                         * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                         *
                         * RMC - NMEA has its own version of essential gps pvt (position, velocity, time) data.
                         * It is called RMC, The Recommended Minimum, which might look like:
                         *
                         * $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
                         * $GPRMC,050821.000,A,3334.5551,N,11739.7705,W,0.00,,251006,,,A*67
                         *
                         * Where:
                         *  RMC          Recommended Minimum sentence C
                         * 0	123519       Fix taken at 12:35:19 UTC
                         * 1	A            Status A=active or V=Void.
                         * 2	4807.038,N   Latitude 48 deg 07.038' N
                         * 4	01131.000,E  Longitude 11 deg 31.000' E
                         * 6	022.4        Speed over the ground in knots
                         * 7	084.4        Track angle in degrees True
                         * 8	230394       Date - 23rd of March 1994
                         * 9	003.1,W      Magnetic Variation
                         * 6A          The checksum data, always begins with *
                         *
                         * Note that, as of the 2.3 release of NMEA, there is a new field in the RMC sentence
                         * at the end just prior to the checksum. The value of the entry is
                         * A=autonomous, D=differential, E=estimated, N=Data not valid.
                         */
                        bool status = "A".Equals(pvt.fields[1]);
                        if (status)
                        {
                            double Lat  = pvt.parseLat(2);
                            double Lng  = pvt.parseLng(2);
                            double Elev = 0.0d;
                            pvtData.location = new GeoCoord(Lng, Lat, Elev);
                            //m_linkLayer.log("coord=" + pvtData.location);

                            // time component (only time part):
                            pvtData.time = pvt.parseNmeaDateTime(0, 8); // UTC

                            if (!"".Equals(pvt.fields[6]))
                            {
                                double knots = Convert.ToDouble(pvt.fields[6]);
                                pvtData.velocity = knots * Distance.METERS_PER_NAUTICAL_MILE / 3600.0d;
                                // calculate velocity vector based on track angle:
                                if (!"".Equals(pvt.fields[7]))
                                {
                                    double trackAngleRad = Convert.ToDouble(pvt.fields[7]) * Math.PI / 180.0d;
                                    pvtData.velocityNorth = pvtData.velocity * Math.Cos(trackAngleRad);
                                    pvtData.velocityEast  = pvtData.velocity * Math.Sin(trackAngleRad);
                                }
                            }

                            pvtData.fix     = 2;                                                // assume two-dimensional
                            pvtData.comment = "received " + received.header;
                            realtimeCallback(pvtData);
                        }
                        total++;
                        errors = maxErrors;
                    }
                    catch (Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if (received.header.EndsWith("GLL"))                       // NMEA GLL may come
                {
                    m_linkLayer.log("StartRealTime: GLL packet received, count=" + total + "   content=" + received);
                    try
                    {
                        MPacket pvt = received.fromString();
                        // $GPGLL,3334.6464,N,11739.6583,W,052707.129,A*29

                        /*
                         * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                         *
                         * GLL - Geographic Latitude and Longitude is a holdover from Loran data and some old units
                         *   may not send the time and data valid information if they are emulating Loran data.
                         *   If a gps is emulating Loran data they may use the LC Loran prefix instead of GP.
                         *
                         * $GPGLL,4916.45,N,12311.12,W,225444,A,*31
                         *
                         * Where:
                         *  GLL          Geographic position, Latitude and Longitude
                         * 0	4916.46,N    Latitude 49 deg. 16.45 min. North
                         * 2	12311.12,W   Longitude 123 deg. 11.12 min. West
                         * 4	225444       Fix taken at 22:54:44 UTC
                         * 5	A            Data valid or V (void)
                         * 31          checksum data
                         *
                         */
                        bool status = "A".Equals(pvt.fields[5]);
                        if (status)
                        {
                            double Lat  = pvt.parseLat(0);
                            double Lng  = pvt.parseLng(0);
                            double Elev = 0.0d;
                            pvtData.location = new GeoCoord(Lng, Lat, Elev);
                            //m_linkLayer.log("coord=" + pvtData.location);

                            // time component (only time part):
                            pvtData.time = pvt.parseNmeaTime(4, Project.localToZulu(DateTime.Now)); // UTC

                            pvtData.fix     = 2;                                                    // assume two-dimensional
                            pvtData.comment = "received " + received.header;
                            //realtimeCallback(pvtData);
                        }
                        total++;
                        errors = maxErrors;
                    }
                    catch (Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if (received.header.EndsWith("GSV"))                       // NMEA GSV may come for satellite reception status
                {
                    m_linkLayer.log("StartRealTime: GSV packet received, count=" + total + "   content=" + received);

                    /*
                     * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                     *
                     * $GPGSV,3,1,08,14,69,204,,15,57,105,36,18,45,047,36,03,42,263,36*71
                     * $GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75
                     *
                     * Where:
                     *  GSV          Satellites in view
                     * 0	2            Number of sentences for full data
                     * 1	1            sentence 1 of 2
                     * 2	08           Number of satellites in view
                     * for up to 4 satellites per sentence {
                     *      3	01           Satellite PRN number
                     *      4	40           Elevation, degrees
                     *      5	083          Azimuth, degrees
                     *      6	46           Signal strength - higher is better
                     * }
                     * 75          the checksum data, always begins with *
                     */

                    //MPacket pvt  = received.fromString();
                    //pvtData.comment = "received";
                    //realtimeCallback(pvtData);

                    total++;
                    errors = maxErrors;
                }
                else if (received.header.EndsWith("VTG"))                       // NMEA GSA may come
                {
                    m_linkLayer.log("StartRealTime: GPVTG packet received, count=" + total + "   content=" + received);
                    // $GPVTG,309.62,T,,M,0.13,N,0.2,K*6E

                    /*
                     *  VTG - Course Over Ground and Ground Speed
                     *
                     *      Name		Example		Units	Description
                     *      Message ID	$GPVTG				VTG protocol header
                     *      Course		309.62		degrees Measured heading
                     *      Reference	T					True
                     *      Course					degrees	Measured heading
                     *      Reference	M					Magnetic
                     *      Speed		0.13		knots	Measured horizontal speed
                     *      Units		N			Knots
                     *      Speed		0.2			Km/hr	Measured horizontal speed
                     *      Units		K					Kilometers per hour
                     */
                }
                else if (received.header.EndsWith("GSA"))                       // NMEA GSA may come
                {
                    m_linkLayer.log("StartRealTime: GPGSA packet received, count=" + total + "   content=" + received);
                    // $GPGSA,A,2,15,18,14,31,,,,,,,,,05.6,05.6,*17

                    /*
                     * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                     *
                     * GSA - GPS DOP and active satellites. This sentence provides details on the nature of the
                     * fix. It includes the numbers of the satellites being used in the current solution and
                     * the DOP. DOP (dilution of precision) is an indication of the effect of satellite geometry
                     * on the accuracy of the fix. It is a unitless number where smaller is better. For 3D fixes
                     * using 4 satellites a 1.0 would be considered to be a perfect number. For overdetermined
                     * solutions it is possible to see numbers below 1.0. There are differences in the way the
                     * PRN's are presented which can effect the ability of some programs to display this data.
                     * For example, in the example shown below there are 5 satellites in the solution and
                     * the null fields are scattered indicating that the almanac would show satellites in
                     * the null positions that are not being used as part of this solution. Other receivers
                     * might output all of the satellites used at the beginning of the sentence with the
                     * null field all stacked up at the end. This difference accounts for some satellite
                     * display programs not always being able to display the satellites being tracked.
                     *
                     * $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
                     *
                     * Where:
                     *  GSA      Satellite status
                     *  A        Auto selection of 2D or 3D fix (M = manual)
                     *  3        3D fix - other values include: 1 = no fix
                     *                                          2 = 2D fix
                     *  04,05... PRNs of satellites used for fix (space for 12)
                     *  2.5      PDOP (dilution of precision)
                     *  1.3      Horizontal dilution of precision (HDOP)
                     *  2.1      Vertical dilution of precision (VDOP)
                     * 39      the checksum data, always begins with *
                     *
                     */
                }
                else
                {
                    m_linkLayer.log("StartRealTime: good other (unrecognized) packet received, count=" + total + "   content=" + received);
                }
            }             // end while()

            m_linkLayer.log("StartRealTime: finished receiving fixes count=" + total);
        }
Example #2
0
 public override void StartRealTime(GpsRealTimeHandler realtimeCallback)
 {
     m_appLayer.StartRealTime(realtimeCallback);
 }
Example #3
0
 public override void StartRealTime(GpsRealTimeHandler realtimeCallback)
 {
     m_appLayer.StartRealTime(realtimeCallback);
 }
Example #4
0
 public abstract void StartRealTime(GpsRealTimeHandler realtimeCallback);
Example #5
0
        private void simulateStartRealTime(GpsRealTimeHandler realtimeCallback)
        {
            int      toWait   = 3;
            int      toCount  = 10;
            double   degIncr  = 360.0d / (toCount * 4);
            double   degree   = 0.0d;
            int      count    = toCount;
            GeoCoord location = new GeoCoord(CameraManager.This.Location.Lng, CameraManager.This.Location.Lat);

            while (count-- > 0)
            {
                GpsRealTimeData rtData = new GpsRealTimeData();
                rtData.location = location;
                rtData.fix      = 2;
                rtData.time     = DateTime.Now;

                rtData.velocity      = 10.0d;
                rtData.velocityEast  = 5.0d * Math.Sin(degree * Math.PI / 180.0d);
                rtData.velocityNorth = 5.0d * Math.Cos(degree * Math.PI / 180.0d);
                degree += degIncr;

                realtimeCallback(rtData);

                location.Lat += 0.0005d;
                location.Lng += 0.0005d;

                Thread.Sleep(toWait);
            }
            count = toCount;
            while (count-- > 0)
            {
                GpsRealTimeData rtData = new GpsRealTimeData();
                rtData.location = location;
                rtData.fix      = 2;
                rtData.time     = DateTime.Now;

                rtData.velocity      = 10.0d;
                rtData.velocityEast  = 5.0d * Math.Sin(degree * Math.PI / 180.0d);
                rtData.velocityNorth = 5.0d * Math.Cos(degree * Math.PI / 180.0d);
                degree += degIncr;

                realtimeCallback(rtData);

                location.Lat -= 0.0005d;
                location.Lng += 0.0005d;

                Thread.Sleep(toWait);
            }
            count = toCount;
            while (count-- > 0)
            {
                GpsRealTimeData rtData = new GpsRealTimeData();
                rtData.location = location;
                rtData.fix      = 2;
                rtData.time     = DateTime.Now;

                rtData.velocity      = 10.0d;
                rtData.velocityEast  = 5.0d * Math.Sin(degree * Math.PI / 180.0d);
                rtData.velocityNorth = 5.0d * Math.Cos(degree * Math.PI / 180.0d);
                degree += degIncr;

                realtimeCallback(rtData);

                location.Lat -= 0.0005d;
                location.Lng -= 0.0005d;

                Thread.Sleep(toWait);
            }
            count = toCount;
            while (count-- > 0)
            {
                GpsRealTimeData rtData = new GpsRealTimeData();
                rtData.location = location;
                rtData.fix      = 2;
                rtData.time     = DateTime.Now;

                rtData.velocity      = 10.0d;
                rtData.velocityEast  = 5.0d * Math.Sin(degree * Math.PI / 180.0d);
                rtData.velocityNorth = 5.0d * Math.Cos(degree * Math.PI / 180.0d);
                degree += degIncr;

                realtimeCallback(rtData);

                location.Lat += 0.0005d;
                location.Lng -= 0.0005d;

                Thread.Sleep(toWait);
            }
        }
 public void StartRealTime(GpsRealTimeHandler realtimeCallback)
 {
     m_linkLayer.getPvtTransferProtocol().StartRealTime(realtimeCallback);
 }
        public void StartRealTime(GpsRealTimeHandler realtimeCallback)
        {
            int total = 0;
            int maxErrors = 5;
            int errors = maxErrors;
            bool finished = false;
            m_stopRealTime = false;

            while(!finished && !m_stopRealTime)
            {
                GpsRealTimeData pvtData = new GpsRealTimeData();		// will be returned empty if no data

                MPacketReceived received = null;
                try
                {
                    received = m_linkLayer.ReceivePacket();
                    if(!received.isGood)
                    {
                        m_linkLayer.logError("StartRealTime: bad packet received, count=" + total);
                        pvtData.comment = "bad data packet from GPS";
                        realtimeCallback(pvtData);
                        continue;
                    }
                }
                catch(Exception e)
                {
                    m_linkLayer.logError("StartRealTime: " + e.Message + "  count=" + total);
                    //if(received != null)
                    {
                        try
                        {
                            m_linkLayer.ReOpen();
                        }
                        catch (Exception ee)
                        {
                            m_linkLayer.logError("while ReOpen(): " + ee.Message);
                        }
                    }
                    pvtData.comment = e.Message.StartsWith("Timeout") ?
                        "GPS not responding - check cable" : ("error: " + e.Message);
                    realtimeCallback(pvtData);
                    continue;
                }
                //m_linkLayer.log("" + total + " ===  " + received);
                m_linkLayer.log("StartRealTime: good packet received, count=" + total + "   " + received);
                if(received.header.EndsWith("GGA"))	// NMEA GGA expected for location
                {
                    m_linkLayer.log("StartRealTime: " + received.header + " packet received, count=" + total + "   content=" + received);
                    try
                    {
                        MPacket pvt  = received.fromString();

                        /*
                            $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

                            Where:
                                GGA          Global Positioning System Fix Data
                            0	123519       Fix taken at 12:35:19 UTC
                            1	4807.038,N   Latitude 48 deg 07.038' N
                            3	01131.000,E  Longitude 11 deg 31.000' E
                            5	1            Fix quality: 0 = invalid
                                                        1 = GPS fix
                                                        2 = DGPS fix
                                                        6 = estimated (2.3 feature)
                            6	08           Number of satellites being tracked
                            7	0.9          Horizontal dilution of position
                            8	545.4,M      Altitude, Meters, above mean sea level
                            10	46.9,M       Height of geoid (mean sea level) above WGS84
                                                ellipsoid
                            12	(empty field) time in seconds since last DGPS update
                            13	(empty field) DGPS station ID number
                                *47          the checksum data, always begins with *
                        */

                        double Lat = pvt.parseLat(1);
                        double Lng = pvt.parseLng(1);
                        double Elev = pvt.parseElev(8);		// alt above mean sea level
                        pvtData.location = new GeoCoord(Lng, Lat, Elev);
                        //m_linkLayer.log("coord=" + pvtData.location);

                        // time component:
                        pvtData.time = pvt.parseNmeaTime(0, Project.localToZulu(DateTime.Now));	// UTC

                        // errors and velocity:
                        pvtData.posError = 0;
                        pvtData.posErrorH = 0;
                        pvtData.posErrorV = 0;
                        pvtData.fix = 0;			// failed integrity check
                        switch((string)pvt.fields[5])
                        {
                            case "0":				// invalid
                                pvtData.fix = 1;	// invalid
                                break;
                            case "1":				// GPS fix
                                pvtData.fix = 2;	// two dimensional
                                break;
                            case "2":				// DGPS fix
                                pvtData.fix = 4;	// two dimensional differential
                                break;
                            case "6":				// estimated
                                pvtData.fix = 6;	// estimated
                                break;
                        }
                        pvtData.velocityEast = 0;
                        pvtData.velocityNorth = 0;
                        pvtData.velocityUp = 0;

                        pvtData.comment = "received " + received.header;
                        //realtimeCallback(pvtData);

                        total++;
                        errors = maxErrors;
                    }
                    catch(Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if(received.header.EndsWith("RMC"))	// NMEA RMC may come
                {
                    m_linkLayer.log("StartRealTime: " + received.header + " packet received, count=" + total + "   content=" + received);
                    try
                    {
                        MPacket pvt  = received.fromString();

                        // $GPRMC,052458.73,V,3334.6441,N,11739.6622,W,00.0,000.0,290103,13,E*4F
                        /*
                         * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                         *
                        RMC - NMEA has its own version of essential gps pvt (position, velocity, time) data.
                        It is called RMC, The Recommended Minimum, which might look like:

                        $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
                        $GPRMC,050821.000,A,3334.5551,N,11739.7705,W,0.00,,251006,,,A*67

                        Where:
                            RMC          Recommended Minimum sentence C
                        0	123519       Fix taken at 12:35:19 UTC
                        1	A            Status A=active or V=Void.
                        2	4807.038,N   Latitude 48 deg 07.038' N
                        4	01131.000,E  Longitude 11 deg 31.000' E
                        6	022.4        Speed over the ground in knots
                        7	084.4        Track angle in degrees True
                        8	230394       Date - 23rd of March 1994
                        9	003.1,W      Magnetic Variation
                            *6A          The checksum data, always begins with *

                        Note that, as of the 2.3 release of NMEA, there is a new field in the RMC sentence
                         at the end just prior to the checksum. The value of the entry is
                          A=autonomous, D=differential, E=estimated, N=Data not valid.
                        */
                        bool status = "A".Equals(pvt.fields[1]);
                        if(status)
                        {
                            double Lat = pvt.parseLat(2);
                            double Lng = pvt.parseLng(2);
                            double Elev = 0.0d;
                            pvtData.location = new GeoCoord(Lng, Lat, Elev);
                            //m_linkLayer.log("coord=" + pvtData.location);

                            // time component (only time part):
                            pvtData.time = pvt.parseNmeaDateTime(0, 8);	// UTC

                            if(!"".Equals(pvt.fields[6]))
                            {
                                double knots = Convert.ToDouble(pvt.fields[6]);
                                pvtData.velocity = knots * Distance.METERS_PER_NAUTICAL_MILE / 3600.0d;
                                // calculate velocity vector based on track angle:
                                if(!"".Equals(pvt.fields[7]))
                                {
                                    double trackAngleRad = Convert.ToDouble(pvt.fields[7]) * Math.PI / 180.0d;
                                    pvtData.velocityNorth = pvtData.velocity * Math.Cos(trackAngleRad);
                                    pvtData.velocityEast = pvtData.velocity * Math.Sin(trackAngleRad);
                                }
                            }

                            pvtData.fix = 2;			// assume two-dimensional
                            pvtData.comment = "received " + received.header;
                            realtimeCallback(pvtData);
                        }
                        total++;
                        errors = maxErrors;
                    }
                    catch(Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if(received.header.EndsWith("GLL"))	// NMEA GLL may come
                {
                    m_linkLayer.log("StartRealTime: GLL packet received, count=" + total + "   content=" + received);
                    try
                    {
                        MPacket pvt  = received.fromString();
                        // $GPGLL,3334.6464,N,11739.6583,W,052707.129,A*29
                        /*
                         * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                         *
                        GLL - Geographic Latitude and Longitude is a holdover from Loran data and some old units
                             may not send the time and data valid information if they are emulating Loran data.
                             If a gps is emulating Loran data they may use the LC Loran prefix instead of GP.

                        $GPGLL,4916.45,N,12311.12,W,225444,A,*31

                        Where:
                            GLL          Geographic position, Latitude and Longitude
                        0	4916.46,N    Latitude 49 deg. 16.45 min. North
                        2	12311.12,W   Longitude 123 deg. 11.12 min. West
                        4	225444       Fix taken at 22:54:44 UTC
                        5	A            Data valid or V (void)
                            *31          checksum data

                        */
                        bool status = "A".Equals(pvt.fields[5]);
                        if(status)
                        {
                            double Lat = pvt.parseLat(0);
                            double Lng = pvt.parseLng(0);
                            double Elev = 0.0d;
                            pvtData.location = new GeoCoord(Lng, Lat, Elev);
                            //m_linkLayer.log("coord=" + pvtData.location);

                            // time component (only time part):
                            pvtData.time = pvt.parseNmeaTime(4, Project.localToZulu(DateTime.Now));	// UTC

                            pvtData.fix = 2;			// assume two-dimensional
                            pvtData.comment = "received " + received.header;
                            //realtimeCallback(pvtData);
                        }
                        total++;
                        errors = maxErrors;
                    }
                    catch(Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if(received.header.EndsWith("GSV"))	// NMEA GSV may come for satellite reception status
                {
                    m_linkLayer.log("StartRealTime: GSV packet received, count=" + total + "   content=" + received);
                    /*
                     * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                     *
                    $GPGSV,3,1,08,14,69,204,,15,57,105,36,18,45,047,36,03,42,263,36*71
                    $GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75

                    Where:
                        GSV          Satellites in view
                    0	2            Number of sentences for full data
                    1	1            sentence 1 of 2
                    2	08           Number of satellites in view
                    for up to 4 satellites per sentence {
                            3	01           Satellite PRN number
                            4	40           Elevation, degrees
                            5	083          Azimuth, degrees
                            6	46           Signal strength - higher is better
                    }
                        *75          the checksum data, always begins with *
                     */

                    //MPacket pvt  = received.fromString();
                    //pvtData.comment = "received";
                    //realtimeCallback(pvtData);

                    total++;
                    errors = maxErrors;
                }
                else if(received.header.EndsWith("VTG"))	// NMEA GSA may come
                {
                    m_linkLayer.log("StartRealTime: GPVTG packet received, count=" + total + "   content=" + received);
                    // $GPVTG,309.62,T,,M,0.13,N,0.2,K*6E
                    /*
                        VTG - Course Over Ground and Ground Speed

                        Name		Example		Units	Description
                        Message ID	$GPVTG				VTG protocol header
                        Course		309.62		degrees Measured heading
                        Reference	T					True
                        Course					degrees	Measured heading
                        Reference	M					Magnetic
                        Speed		0.13		knots	Measured horizontal speed
                        Units		N			Knots
                        Speed		0.2			Km/hr	Measured horizontal speed
                        Units		K					Kilometers per hour
                     */
                }
                else if(received.header.EndsWith("GSA"))	// NMEA GSA may come
                {
                    m_linkLayer.log("StartRealTime: GPGSA packet received, count=" + total + "   content=" + received);
                    // $GPGSA,A,2,15,18,14,31,,,,,,,,,05.6,05.6,*17
                    /*
                     * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                     *
                    GSA - GPS DOP and active satellites. This sentence provides details on the nature of the
                    fix. It includes the numbers of the satellites being used in the current solution and
                    the DOP. DOP (dilution of precision) is an indication of the effect of satellite geometry
                    on the accuracy of the fix. It is a unitless number where smaller is better. For 3D fixes
                    using 4 satellites a 1.0 would be considered to be a perfect number. For overdetermined
                    solutions it is possible to see numbers below 1.0. There are differences in the way the
                    PRN's are presented which can effect the ability of some programs to display this data.
                    For example, in the example shown below there are 5 satellites in the solution and
                    the null fields are scattered indicating that the almanac would show satellites in
                    the null positions that are not being used as part of this solution. Other receivers
                    might output all of the satellites used at the beginning of the sentence with the
                    null field all stacked up at the end. This difference accounts for some satellite
                    display programs not always being able to display the satellites being tracked.

                    $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39

                    Where:
                        GSA      Satellite status
                        A        Auto selection of 2D or 3D fix (M = manual)
                        3        3D fix - other values include: 1 = no fix
                                                                2 = 2D fix
                        04,05... PRNs of satellites used for fix (space for 12)
                        2.5      PDOP (dilution of precision)
                        1.3      Horizontal dilution of precision (HDOP)
                        2.1      Vertical dilution of precision (VDOP)
                        *39      the checksum data, always begins with *

                     */
                }
                else
                {
                    m_linkLayer.log("StartRealTime: good other (unrecognized) packet received, count=" + total + "   content=" + received);
                }
            } // end while()

            m_linkLayer.log("StartRealTime: finished receiving fixes count=" + total);
        }
        public void StartRealTime(GpsRealTimeHandler realtimeCallback)
        {
            int total = 0;
            int maxErrors = 5;
            int errors = maxErrors;
            bool finished = false;
            m_stopRealTime = false;
            DateTime lastGPGGA = DateTime.MinValue;
            DateTime lastGPRMC = DateTime.MinValue;
            double lastGPRMCvelocity = 0.0d;
            double lastGPRMCvelocityNorth = 0.0d;
            double lastGPRMCvelocityEast = 0.0d;

            //m_linkLayer.SetHandshake(Project.gpsMagellanHandshake);
            m_linkLayer.SetHandshake(true);		// safer with handshake on
            m_linkLayer.SendPacket(new MPacketCmd("FIX"));
            m_linkLayer.SendPacket(new MPacketCmd("NMEAON"));

            while(!finished && !m_stopRealTime)
            {
                GpsRealTimeData pvtData = new GpsRealTimeData();		// will be returned empty if no data

                MPacketReceived received = null;
                try
                {
                    received = m_linkLayer.ReceivePacket();
                    if(!received.isGood)
                    {
                        m_linkLayer.logError("StartRealTime: bad packet received, count=" + total);
                        pvtData.comment = "bad data packet from GPS";
                        realtimeCallback(pvtData);
                        continue;
                    }
                }
                catch(Exception e)
                {
                    m_linkLayer.logError("StartRealTime exception: " + e.Message + "  count=" + total);
                    //if(received != null)
                    {
                        try
                        {
                            m_linkLayer.ReOpen();
                        }
                        catch (Exception ee)
                        {
                            m_linkLayer.logError("while ReOpen(): " + ee.Message);
                        }
                    }
                    pvtData.comment = e.Message.StartsWith("Timeout") ?
                                                "GPS not responding - check cable" : ("error: " + e.Message);
                    realtimeCallback(pvtData);
                    continue;
                }

                m_linkLayer.log("StartRealTime: good packet received, count=" + total + "   " + received);

                if(received.header.Equals("GPGGA"))	// NMEA GGA expected for location (best data packet to hope for from Magellan)
                {
                    try
                    {
                        MPacket pvt  = received.fromString();

                        /*
                            $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

                            Where:
                                GGA          Global Positioning System Fix Data
                            0	123519       Fix taken at 12:35:19 UTC
                            1	4807.038,N   Latitude 48 deg 07.038' N
                            3	01131.000,E  Longitude 11 deg 31.000' E
                            5	1            Fix quality: 0 = invalid
                                                        1 = GPS fix
                                                        2 = DGPS fix
                                                        6 = estimated (2.3 feature)
                            6	08           Number of satellites being tracked
                            7	0.9          Horizontal dilution of position
                            8	545.4,M      Altitude, Meters, above mean sea level
                            10	46.9,M       Height of geoid (mean sea level) above WGS84
                                                ellipsoid
                            12	(empty field) time in seconds since last DGPS update
                            13	(empty field) DGPS station ID number
                                *47          the checksum data, always begins with *
                        */

                        double Lat = pvt.parseLat(1);
                        double Lng = pvt.parseLng(1);
                        double Elev = pvt.parseElev(8);		// alt above mean sea level
                        pvtData.location = new GeoCoord(Lng, Lat, Elev);
                        //m_linkLayer.log("coord=" + pvtData.location);

                        // time component:
                        pvtData.time = pvt.parseNmeaTime(0, Project.localToZulu(DateTime.Now));	// UTC

                        // errors and velocity:
                        pvtData.posErrorH = Convert.ToDouble((string)pvt.fields[7]) * 2.0d;		// ad-hoc factor to match device EPE reading
                        pvtData.posError = pvtData.posErrorH;
                        pvtData.posErrorV = -1;
                        pvtData.fix = 0;			// failed integrity check
                        switch((string)pvt.fields[5])
                        {
                            case "0":				// invalid
                                pvtData.fix = 1;	// invalid
                                break;
                            case "1":				// GPS fix
                                pvtData.fix = 2;	// two dimensional
                                break;
                            case "2":				// DGPS fix
                                pvtData.fix = 5;	// two dimensional differential
                                break;
                            case "6":				// estimated
                                pvtData.fix = 6;	// estimated
                                break;
                        }

                        string msg = "received " + received.header;
                        // GPGGA is lacking velocity data, mix it in from a recent GPRMC
                        if(DateTime.Now.Ticks < lastGPRMC.AddSeconds(10.0d).Ticks)
                        {
                            msg += "/GPRMC";
                            pvtData.velocity = lastGPRMCvelocity;
                            pvtData.velocityNorth = lastGPRMCvelocityNorth;
                            pvtData.velocityEast = lastGPRMCvelocityEast;
                        }
                        else
                        {
                            pvtData.velocity = -1.0d;
                            pvtData.velocityNorth = 0.0d;
                            pvtData.velocityEast = 0.0d;
                        }
                        pvtData.velocityUp = 0.0d;

                        pvtData.comment = msg;
                        lastGPGGA = DateTime.Now;		// GPGGA is the best we can hope for, don't allow others to be processed if we have this one
                        realtimeCallback(pvtData);

                        total++;
                        errors = maxErrors;
                    }
                    catch(Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if(received.header.Equals("GPRMC"))	// NMEA GPRMC may come with positioning data
                {
                    m_linkLayer.log("StartRealTime: GPRMC packet received, count=" + total + "   content=" + received);
                    try
                    {
                        MPacket pvt  = received.fromString();

                        // $GPRMC,052458.73,V,3334.6441,N,11739.6622,W,00.0,000.0,290103,13,E*4F
                        /*
                         * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                         *
                        RMC - NMEA has its own version of essential gps pvt (position, velocity, time) data.
                        It is called RMC, The Recommended Minimum, which might look like:

                        $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

                        Where:
                            RMC          Recommended Minimum sentence C
                        0	123519       Fix taken at 12:35:19 UTC
                        1	A            Status A=active or V=Void.
                        2	4807.038,N   Latitude 48 deg 07.038' N
                        4	01131.000,E  Longitude 11 deg 31.000' E
                        6	022.4        Speed over the ground in knots
                        7	084.4        Track angle in degrees True
                        8	230394       Date - 23rd of March 1994
                        9	003.1,W      Magnetic Variation
                            *6A          The checksum data, always begins with *

                        Note that, as of the 2.3 release of NMEA, there is a new field in the RMC sentence
                            at the end just prior to the checksum. The value of the entry is
                            A=autonomous, D=differential, E=estimated, N=Data not valid.
                        */
                        bool status = "A".Equals((string)pvt.fields[1]);
                        if(status)
                        {
                            // velocity is used to mix in GPGGA, compute it first:
                            double knots = Double.Parse((string)pvt.fields[6]);
                            lastGPRMCvelocity = knots * Distance.METERS_PER_NAUTICAL_MILE / 3600.0d;
                            // calculate velocity vector based on track angle:
                            double trackAngleRad = Convert.ToDouble(pvt.fields[7]) * Math.PI / 180.0d;
                            lastGPRMCvelocityNorth = lastGPRMCvelocity * Math.Cos(trackAngleRad);
                            lastGPRMCvelocityEast  = lastGPRMCvelocity * Math.Sin(trackAngleRad);
                            lastGPRMC = DateTime.Now;

                            // GPGGA is the best data we can hope for, don't allow others to be processed if we had a recent GPGGA
                            if(DateTime.Now.Ticks > lastGPGGA.AddSeconds(10.0d).Ticks)
                            {
                                double Lat = pvt.parseLat(2);
                                double Lng = pvt.parseLng(2);
                                double Elev = 0.0d;
                                pvtData.location = new GeoCoord(Lng, Lat, Elev);
                                //m_linkLayer.log("coord=" + pvtData.location);

                                // time component (only time part):
                                pvtData.time = pvt.parseNmeaDateTime(0, 8);	// UTC

                                pvtData.velocity		= lastGPRMCvelocity;
                                pvtData.velocityNorth	= lastGPRMCvelocityNorth;
                                pvtData.velocityEast	= lastGPRMCvelocityEast;

                                pvtData.fix = 2;			// assume two-dimensional
                                pvtData.comment = "received " + received.header;

                                realtimeCallback(pvtData);
                            }
                        }
                        total++;
                        errors = maxErrors;
                    }
                    catch(Exception ee)
                    {
                        m_linkLayer.logError("StartRealTime: " + ee.Message);
                    }
                }
                else if(received.header.Equals("GPGLL") || received.header.Equals("LCGLL"))	// NMEA GPGLL may come with positioning data
                {
                    m_linkLayer.log("StartRealTime: GPGLL packet received, count=" + total + "   content=" + received);
                    // GPGGA is the best we can hope for, don't allow others to be processed if we had a recent GPGGA
                    if(DateTime.Now.Ticks > lastGPGGA.AddSeconds(10.0d).Ticks)
                    {
                        try
                        {
                            MPacket pvt  = received.fromString();
                            // $GPGLL,3334.6464,N,11739.6583,W,052707.129,A*29
                            /*
                             * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                             *
                            GLL - Geographic Latitude and Longitude is a holdover from Loran data and some old units
                                 may not send the time and data valid information if they are emulating Loran data.
                                 If a gps is emulating Loran data they may use the LC Loran prefix instead of GP.

                            $GPGLL,4916.45,N,12311.12,W,225444,A,*31

                            Where:
                                GLL          Geographic position, Latitude and Longitude
                            0	4916.46,N    Latitude 49 deg. 16.45 min. North
                            2	12311.12,W   Longitude 123 deg. 11.12 min. West
                            4	225444       Fix taken at 22:54:44 UTC
                            5	A            Data valid or V (void)
                                *31          checksum data

                            */
                            bool status = "A".Equals((string)pvt.fields[5]);
                            if(status)
                            {
                                double Lat = pvt.parseLat(0);
                                double Lng = pvt.parseLng(0);
                                double Elev = 0.0d;
                                pvtData.location = new GeoCoord(Lng, Lat, Elev);
                                //m_linkLayer.log("coord=" + pvtData.location);

                                // time component (only time part):
                                pvtData.time = pvt.parseNmeaTime(4, Project.localToZulu(DateTime.Now));	// UTC

                                pvtData.fix = 2;			// assume two-dimensional
                                pvtData.comment = "received " + received.header;
                                realtimeCallback(pvtData);
                            }
                            total++;
                            errors = maxErrors;
                        }
                        catch(Exception ee)
                        {
                            m_linkLayer.logError("StartRealTime: " + ee.Message);
                        }
                    }
                }
                else if(received.header.Equals("GPGSV"))	// NMEA GPGSV may come for satellite reception status
                {
                    m_linkLayer.log("StartRealTime: GPGSV packet received, count=" + total + "   content=" + received);
                    /*
                     * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                     *
                    $GPGSV,3,1,08,14,69,204,,15,57,105,36,18,45,047,36,03,42,263,36*71
                    $GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75

                    Where:
                        GSV          Satellites in view
                    0	2            Number of sentences for full data
                    1	1            sentence 1 of 2
                    2	08           Number of satellites in view
                    for up to 4 satellites per sentence {
                            3	01           Satellite PRN number
                            4	40           Elevation, degrees
                            5	083          Azimuth, degrees
                            6	46           Signal strength - higher is better
                    }
                        *75          the checksum data, always begins with *
                     */

                    //MPacket pvt  = received.fromString();
                    //pvtData.comment = "received";
                    //realtimeCallback(pvtData);

                    total++;
                    errors = maxErrors;
                }
                else if(received.header.Equals("GPGSA"))	// NMEA GPGSA may come for satellite status
                {
                    m_linkLayer.log("StartRealTime: GPGSA packet received, count=" + total + "   content=" + received);
                    // $GPGSA,A,2,15,18,14,31,,,,,,,,,05.6,05.6,*17
                    /*
                     * see http://www.gpsinformation.org/dale/nmea.htm for NMEA reference
                     *
                    GSA - GPS DOP and active satellites. This sentence provides details on the nature of the
                    fix. It includes the numbers of the satellites being used in the current solution and
                    the DOP. DOP (dilution of precision) is an indication of the effect of satellite geometry
                    on the accuracy of the fix. It is a unitless number where smaller is better. For 3D fixes
                    using 4 satellites a 1.0 would be considered to be a perfect number. For overdetermined
                    solutions it is possible to see numbers below 1.0. There are differences in the way the
                    PRN's are presented which can effect the ability of some programs to display this data.
                    For example, in the example shown below there are 5 satellites in the solution and
                    the null fields are scattered indicating that the almanac would show satellites in
                    the null positions that are not being used as part of this solution. Other receivers
                    might output all of the satellites used at the beginning of the sentence with the
                    null field all stacked up at the end. This difference accounts for some satellite
                    display programs not always being able to display the satellites being tracked.

                    $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39

                    Where:
                        GSA      Satellite status
                        A        Auto selection of 2D or 3D fix (M = manual)
                        3        3D fix - other values include: 1 = no fix
                                                                2 = 2D fix
                        04,05... PRNs of satellites used for fix (space for 12)
                        2.5      PDOP (dilution of precision)
                        1.3      Horizontal dilution of precision (HDOP)
                        2.1      Vertical dilution of precision (VDOP)
                        *39      the checksum data, always begins with *

                     */
                }
                else if(received.header.Equals("PMGNST"))	// Magellan PMGNST may come for device status
                {
                    m_linkLayer.log("StartRealTime: PMGNST packet received, count=" + total + "   content=" + received);
                    /*
                    $PMGNST,02.12,3,T,534,05.0,+03327,00*40

                    where:
                        ST      status information
                    0	02.12   Firmware version number
                    1	3       2D or 3D
                    2	T       True if we have a fix False otherwise
                    3	534     numbers change - unknown
                    4	05.0    time left on the gps battery in hours
                    5	+03327  numbers change (freq. compensation?)
                    6	00      PRN number receiving current focus
                        *40    checksum
                    */

                    MPacket pvt  = received.fromString();
                    bool haveFix = "T".Equals((string)pvt.fields[2]);
                    if(!haveFix)
                    {
                        pvtData.comment = "no satellite fix";
                        realtimeCallback(pvtData);
                    }
                    //total++;
                    errors = maxErrors;
                }
                else
                {
                    m_linkLayer.log("StartRealTime: good other packet received, count=" + total + "   content=" + received);
                }
            } // end while()

            m_linkLayer.SendPacket(new MPacketCmd("NMEAOFF"));
            m_linkLayer.SendPacket(new MPacketCmd("STOP"));
            //if(Project.gpsMagellanHandshake)
            {
                m_linkLayer.SetHandshake(false);
            }
            m_linkLayer.log("StartRealTime: finished receiving fixes count=" + total);
        }
Example #9
0
 public abstract void StartRealTime(GpsRealTimeHandler realtimeCallback);
 public void StartRealTime(GpsRealTimeHandler realtimeCallback)
 {
     m_linkLayer.getPvtTransferProtocol().StartRealTime(realtimeCallback);
 }