1 /***************************************************************************
2  *
3  * Project:  OpenCPN
4  * Purpose:  NMEA0183 Support Classes
5  * Author:   Samuel R. Blackburn, David S. Register
6  *
7  ***************************************************************************
8  *   Copyright (C) 2010 by Samuel R. Blackburn, David S Register           *
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program; if not, write to the                         *
22  *   Free Software Foundation, Inc.,                                       *
23  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.             *
24  ***************************************************************************
25  *
26  *   S Blackburn's original source license:                                *
27  *         "You can use it any way you like."                              *
28  *   More recent (2010) license statement:                                 *
29  *         "It is BSD license, do with it what you will"                   *
30  */
31 
32 
33 #include "nmea0183.h"
34 //#pragma hdrstop
35 
36 /*
37 ** Author: Samuel R. Blackburn
38 ** CI$: 76300,326
39 ** Internet: sammy@sed.csc.com
40 **
41 ** You can use it any way you like.
42 */
43 
44 //IMPLEMENT_DYNAMIC( VTG, RESPONSE )
45 
VTG()46 VTG::VTG()
47 {
48    Mnemonic = _T("VTG");
49    Empty();
50 }
51 
~VTG()52 VTG::~VTG()
53 {
54    Mnemonic.Empty();
55    Empty();
56 }
57 
Empty(void)58 void VTG::Empty( void )
59 {
60 //   ASSERT_VALID( this );
61 
62    TrackDegreesTrue       = 0.0;
63    TrackDegreesMagnetic   = 0.0;
64    SpeedKnots             = 0.0;
65    SpeedKilometersPerHour = 0.0;
66 }
67 
Parse(const SENTENCE & sentence)68 bool VTG::Parse( const SENTENCE& sentence )
69 {
70 //   ASSERT_VALID( this );
71 
72    /*
73    ** VTG - Track made good and Ground speed
74    **
75    **        1   2 3   4 5	 6 7   8 9
76    **        |   | |   | |	 | |   | |
77    ** $--VTG,x.x,T,x.x,M,x.x,N,x.x,K*hh<CR><LF>
78    **
79    ** Field Number:
80    **  1) Track Degrees
81    **  2) T = True
82    **  3) Track Degrees
83    **  4) M = Magnetic
84    **  5) Speed Knots
85    **  6) N = Knots
86    **  7) Speed Kilometers Per Hour
87    **  8) K = Kilometers Per Hour
88    **  9) Checksum
89    */
90 
91    /*
92    ** First we check the checksum...
93    */
94 
95       int target_field_count = 8;
96 
97       NMEA0183_BOOLEAN check = sentence.IsChecksumBad( 9 );
98 
99       if ( check == NTrue )
100       {
101 
102   /*
103       ** This may be an NMEA Version 2.3 sentence, with "Mode" field
104   */
105             wxString checksum_in_sentence = sentence.Field( 9 );
106             if(checksum_in_sentence.StartsWith(_T("*")))       // Field is a valid erroneous checksum
107             {
108                   SetErrorMessage( _T("Invalid Checksum") );
109                   return( FALSE );
110             }
111 
112            else
113            {
114                   target_field_count = 9;
115                   check = sentence.IsChecksumBad( 10 );
116                   if( check == NTrue)
117                   {
118                         SetErrorMessage( _T("Invalid Checksum") );
119                         return( FALSE );
120                   }
121             }
122       }
123 
124 
125 
126    if ( sentence.GetNumberOfDataFields() != target_field_count )
127    {
128          SetErrorMessage( _T("Invalid FieldCount") );
129          return( FALSE );
130    }
131 
132 
133    TrackDegreesTrue       = sentence.Double( 1 );
134    TrackDegreesMagnetic   = sentence.Double( 3 );
135    SpeedKnots             = sentence.Double( 5 );
136    SpeedKilometersPerHour = sentence.Double( 7 );
137 
138    return( TRUE );
139 }
140 
Write(SENTENCE & sentence)141 bool VTG::Write( SENTENCE& sentence )
142 {
143 //   ASSERT_VALID( this );
144 
145    /*
146    ** Let the parent do its thing
147    */
148 
149    RESPONSE::Write( sentence );
150 
151    sentence += TrackDegreesTrue;
152    sentence += _T("T");
153    sentence += TrackDegreesMagnetic;
154    sentence += _T("M");
155    sentence += SpeedKnots;
156    sentence += _T("N");
157    sentence += SpeedKilometersPerHour;
158    sentence += _T("K");
159 
160    sentence.Finish();
161 
162    return( TRUE );
163 }
164 
operator =(const VTG & source)165 const VTG& VTG::operator = ( const VTG& source )
166 {
167 //   ASSERT_VALID( this );
168 
169    TrackDegreesTrue       = source.TrackDegreesTrue;
170    TrackDegreesMagnetic   = source.TrackDegreesMagnetic;
171    SpeedKnots             = source.SpeedKnots;
172    SpeedKilometersPerHour = source.SpeedKilometersPerHour;
173 
174    return( *this );
175 }
176