source: pacpussensors/trunk/NMEA0183/src/SENTENCE.cpp@ 134

Last change on this file since 134 was 59, checked in by DHERBOMEZ Gérald, 10 years ago

Integration of new modules:

  • GPS NMEA0183 decoder
  • Span CPT Decoder

Update of:

File size: 13.1 KB
Line 
1#include "nmea0183.h"
2#pragma hdrstop
3
4/*
5** Author: Samuel R. Blackburn
6** Internet: sam_blackburn@pobox.com
7**
8** You can use it any way you like as long as you don't try to sell it.
9**
10** Copyright, 1996, Samuel R. Blackburn
11**
12** $Workfile: sentence.cpp $
13** $Revision: 5 $
14** $Modtime: 10/10/98 2:43p $
15*/
16/*
17#ifdef _DEBUG
18#undef THIS_FILE
19static char BASED_CODE THIS_FILE[] = __FILE__;
20#endif
21*/
22
23#ifdef _MSC_VER
24# pragma warning(disable:4996)
25#endif // _MSC_VER
26
27#ifndef WIN32
28typedef unsigned char BYTE;
29#endif
30
31SENTENCE::SENTENCE()
32{
33 //Sentence.Empty();
34}
35
36SENTENCE::~SENTENCE()
37{
38 //Sentence.Empty();
39}
40
41NMEA0183_BOOLEAN SENTENCE::Boolean( int field_number ) const
42{
43 QString field_data;
44
45 field_data = Field( field_number );
46
47 if ( field_data == "A" )
48 {
49 return( True );
50 }
51 else if ( field_data == "V" )
52 {
53 return( False );
54 }
55 else
56 {
57 return( NMEA_Unknown );
58 }
59}
60
61COMMUNICATIONS_MODE SENTENCE::CommunicationsMode( int field_number ) const
62{
63 QString field_data;
64
65 field_data = Field( field_number );
66
67 if ( field_data == "d" )
68 {
69 return( F3E_G3E_SimplexTelephone );
70 }
71 else if ( field_data == "e" )
72 {
73 return( F3E_G3E_DuplexTelephone );
74 }
75 else if ( field_data == "m" )
76 {
77 return( J3E_Telephone );
78 }
79 else if ( field_data == "o" )
80 {
81 return( H3E_Telephone );
82 }
83 else if ( field_data == "q" )
84 {
85 return( F1B_J2B_FEC_NBDP_TelexTeleprinter );
86 }
87 else if ( field_data == "s" )
88 {
89 return( F1B_J2B_ARQ_NBDP_TelexTeleprinter );
90 }
91 else if ( field_data == "w" )
92 {
93 return( F1B_J2B_ReceiveOnlyTeleprinterDSC );
94 }
95 else if ( field_data == "x" )
96 {
97 return( A1A_MorseTapeRecorder );
98 }
99 else if ( field_data == "{" )
100 {
101 return( A1A_MorseKeyHeadset );
102 }
103 else if ( field_data == "|" )
104 {
105 return( F1C_F2C_F3C_FaxMachine );
106 }
107 else
108 {
109 return( CommunicationsModeUnknown );
110 }
111}
112
113unsigned char SENTENCE::ComputeChecksum( void ) const
114{
115 unsigned char checksum_value = 0;
116
117 int string_length = Sentence.length();
118 int index = 1; // Skip over the $ at the begining of the sentence
119
120 while( index < string_length &&
121 Sentence[ index ] != '*' &&
122 Sentence[ index ] != (char)CARRIAGE_RETURN &&
123 Sentence[ index ] != (char)LINE_FEED )
124 {
125 checksum_value ^= Sentence[ index ].toLatin1();
126 index++;
127 }
128
129 return( checksum_value );
130}
131
132double SENTENCE::Double( int field_number ) const
133{
134 QString field_data = "";
135
136 field_data = Field( field_number );
137
138 return( field_data.toDouble() );
139}
140
141EASTWEST SENTENCE::EastOrWest( int field_number ) const
142{
143 QString field_data;
144
145 field_data = Field( field_number );
146
147 if ( field_data == "E" )
148 {
149 return( East );
150 }
151 else if ( field_data == "W" )
152 {
153 return( West );
154 }
155 else
156 {
157 return( EW_Unknown );
158 }
159}
160
161const QString SENTENCE::Field( int desired_field_number ) const
162{
163 // Thanks to Vilhelm Persson (vilhelm.persson@st.se) for finding a
164 // bug that lived here.
165
166 QString return_string = "";
167
168 //return_string.Empty();
169
170 int index = 1; // Skip over the $ at the begining of the sentence
171 int current_field_number = 0;
172 int string_length = 0;
173
174 string_length = Sentence.length();
175
176 while( current_field_number < desired_field_number && index < string_length )
177 {
178 if ( Sentence[ index ] == ',' || Sentence[ index ] == '*' )
179 {
180 current_field_number++;
181 }
182
183 index++;
184 }
185
186 if ( current_field_number == desired_field_number )
187 {
188 while( index < string_length &&
189 Sentence[ index ] != ',' &&
190 Sentence[ index ] != '*' &&
191 Sentence[ index ] != (char)0x00 )
192 {
193 return_string += Sentence[ index ];
194 index++;
195 }
196 }
197
198 return( return_string );
199}
200
201WORD SENTENCE::GetNumberOfDataFields( void ) const
202{
203 int index = 1; // Skip over the $ at the begining of the sentence
204 int current_field_number = 0;
205 int string_length = 0;
206
207 string_length = Sentence.length();
208
209 while( index < string_length )
210 {
211 if ( Sentence[ index ] == '*' )
212 {
213 return( (WORD) current_field_number );
214 }
215
216 if ( Sentence[ index ] == ',' )
217 {
218 current_field_number++;
219 }
220
221 index++;
222 }
223
224 return( (WORD) current_field_number );
225}
226
227void SENTENCE::Finish( void )
228{
229 BYTE checksum = ComputeChecksum();
230
231 char temp_string[ 10 ];
232
233 ::sprintf( temp_string, "*%02X%c%c", (int) checksum, CARRIAGE_RETURN, LINE_FEED );
234
235 Sentence += temp_string;
236}
237
238int SENTENCE::Integer( int field_number ) const
239{
240 QString integer_string = "";
241
242 integer_string = Field( field_number );
243
244 return( ::atoi( integer_string.toLatin1() ) );
245}
246
247NMEA0183_BOOLEAN SENTENCE::IsChecksumBad( int checksum_field_number ) const
248{
249/*
250** Checksums are optional, return TRUE if an existing checksum is known to be bad
251*/
252
253 QString checksum_in_sentence;
254
255 if (checksum_field_number == 0)
256 checksum_in_sentence = getAutomaticChecksum();
257 else
258 checksum_in_sentence = Field( checksum_field_number );
259
260 if ( checksum_in_sentence == "" )
261 {
262 return( NMEA_Unknown );
263 }
264
265 if ( ComputeChecksum() != HexValue( checksum_in_sentence.toLatin1() ) )
266 {
267 return( True );
268 }
269
270 return( False );
271}
272
273/*! Get automatically the checksum in the sentence :
274* the 2 last characters after '*'
275*/
276const QString SENTENCE::getAutomaticChecksum( void ) const
277{
278 int positionOfAsterisk = Sentence.indexOf('*',1);
279 if (positionOfAsterisk != -1)
280 return Sentence.mid(positionOfAsterisk+1, 2);
281 else
282 return "";
283}
284
285LEFTRIGHT SENTENCE::LeftOrRight( int field_number ) const
286{
287 QString field_data;
288
289 field_data = Field( field_number );
290
291 if ( field_data == "L" )
292 {
293 return( Left );
294 }
295 else if ( field_data == "R" )
296 {
297 return( Right );
298 }
299 else
300 {
301 return( LR_Unknown );
302 }
303}
304
305NORTHSOUTH SENTENCE::NorthOrSouth( int field_number ) const
306{
307 QString field_data;
308
309 field_data = Field( field_number );
310
311 if ( field_data == "N" )
312 {
313 return( North );
314 }
315 else if ( field_data == "S" )
316 {
317 return( South );
318 }
319 else
320 {
321 return( NS_Unknown );
322 }
323}
324
325REFERENCE SENTENCE::Reference( int field_number ) const
326{
327 QString field_data;
328
329 field_data = Field( field_number );
330
331 if ( field_data == "B" )
332 {
333 return( BottomTrackingLog );
334 }
335 else if ( field_data == "M" )
336 {
337 return( ManuallyEntered );
338 }
339 else if ( field_data == "W" )
340 {
341 return( WaterReferenced );
342 }
343 else if ( field_data == "R" )
344 {
345 return( RadarTrackingOfFixedTarget );
346 }
347 else if ( field_data == "P" )
348 {
349 return( PositioningSystemGroundReference );
350 }
351 else
352 {
353 return( ReferenceUnknown );
354 }
355}
356
357const QDateTime SENTENCE::Time( int field_number ) const
358{
359 QDateTime return_value;
360
361 return_value = return_value.currentDateTime();
362
363 QString temp_string = Field( field_number );
364
365 if ( temp_string.length() >= 6 )
366 {
367 char temp_number[ 3 ];
368
369 temp_number[ 2 ] = 0x00;
370
371 temp_number[ 0 ] = temp_string[ 0 ].toLatin1();
372 temp_number[ 1 ] = temp_string[ 1 ].toLatin1();
373
374 int hours = ::atoi( temp_number );
375
376 temp_number[ 0 ] = temp_string[ 2 ].toLatin1();
377 temp_number[ 1 ] = temp_string[ 3 ].toLatin1();
378
379 int minutes = ::atoi( temp_number );
380
381 temp_number[ 0 ] = temp_string[ 4 ].toLatin1();
382 temp_number[ 1 ] = temp_string[ 5 ].toLatin1();
383
384 int seconds = ::atoi( temp_number );
385
386 temp_number[ 0 ] = temp_string[ 7 ].toLatin1();
387 temp_number[ 1 ] = temp_string[ 8 ].toLatin1();
388
389 int milliseconds = ::atoi( temp_number )*10;
390
391 int year = return_value.date().year();
392 int month = return_value.date().month();
393 int day = return_value.date().day();
394
395 //return_value = CTime( year, month, day, hours, minutes, seconds );
396 return_value = QDateTime(QDate(year, month, day) , QTime(hours, minutes, seconds, milliseconds) );
397 }
398
399 return( return_value );
400}
401
402TRANSDUCER_TYPE SENTENCE::TransducerType( int field_number ) const
403{
404 QString field_data;
405
406 field_data = Field( field_number );
407
408 if ( field_data == "A" )
409 {
410 return( AngularDisplacementTransducer );
411 }
412 else if ( field_data == "D" )
413 {
414 return( LinearDisplacementTransducer );
415 }
416 else if ( field_data == "C" )
417 {
418 return( TemperatureTransducer );
419 }
420 else if ( field_data == "F" )
421 {
422 return( FrequencyTransducer );
423 }
424 else if ( field_data == "N" )
425 {
426 return( ForceTransducer );
427 }
428 else if ( field_data == "P" )
429 {
430 return( PressureTransducer );
431 }
432 else if ( field_data == "R" )
433 {
434 return( FlowRateTransducer );
435 }
436 else if ( field_data == "T" )
437 {
438 return( TachometerTransducer );
439 }
440 else if ( field_data == "H" )
441 {
442 return( HumidityTransducer );
443 }
444 else if ( field_data == "V" )
445 {
446 return( VolumeTransducer );
447 }
448 else
449 {
450 return( TransducerUnknown );
451 }
452}
453
454/*
455** Operators
456*/
457
458SENTENCE::operator QString() const
459{
460 return( Sentence );
461}
462
463const SENTENCE& SENTENCE::operator = ( const SENTENCE& source )
464{
465 Sentence = source.Sentence;
466
467 return( *this );
468}
469
470const SENTENCE& SENTENCE::operator = ( const QString& source )
471{
472 Sentence = source;
473
474 return( *this );
475}
476
477const SENTENCE& SENTENCE::operator += ( const QString& source )
478{
479 Sentence += ",";
480 Sentence += source;
481
482 return( *this );
483}
484
485const SENTENCE& SENTENCE::operator += ( double value )
486{
487 char temp_string[ 80 ];
488
489 ::sprintf( temp_string, "%.3f", value );
490
491 Sentence += ",";
492 Sentence += temp_string;
493
494 return( *this );
495}
496
497const SENTENCE& SENTENCE::operator += ( COMMUNICATIONS_MODE mode )
498{
499 Sentence += ",";
500
501 switch( mode )
502 {
503 case F3E_G3E_SimplexTelephone:
504
505 Sentence += "d";
506 break;
507
508 case F3E_G3E_DuplexTelephone:
509
510 Sentence += "e";
511 break;
512
513 case J3E_Telephone:
514
515 Sentence += "m";
516 break;
517
518 case H3E_Telephone:
519
520 Sentence += "o";
521 break;
522
523 case F1B_J2B_FEC_NBDP_TelexTeleprinter:
524
525 Sentence += "q";
526 break;
527
528 case F1B_J2B_ARQ_NBDP_TelexTeleprinter:
529
530 Sentence += "s";
531 break;
532
533 case F1B_J2B_ReceiveOnlyTeleprinterDSC:
534
535 Sentence += "w";
536 break;
537
538 case A1A_MorseTapeRecorder:
539
540 Sentence += "x";
541 break;
542
543 case A1A_MorseKeyHeadset:
544
545 Sentence += "{";
546 break;
547
548 case F1C_F2C_F3C_FaxMachine:
549
550 Sentence += "|";
551 break;
552 }
553
554 return( *this );
555}
556
557const SENTENCE& SENTENCE::operator += ( TRANSDUCER_TYPE transducer )
558{
559 Sentence += ",";
560
561 switch( transducer )
562 {
563 case TemperatureTransducer:
564
565 Sentence += "C";
566 break;
567
568 case AngularDisplacementTransducer:
569
570 Sentence += "A";
571 break;
572
573 case LinearDisplacementTransducer:
574
575 Sentence += "D";
576 break;
577
578 case FrequencyTransducer:
579
580 Sentence += "F";
581 break;
582
583 case ForceTransducer:
584
585 Sentence += "N";
586 break;
587
588 case PressureTransducer:
589
590 Sentence += "P";
591 break;
592
593 case FlowRateTransducer:
594
595 Sentence += "R";
596 break;
597
598 case TachometerTransducer:
599
600 Sentence += "T";
601 break;
602
603 case HumidityTransducer:
604
605 Sentence += "H";
606 break;
607
608 case VolumeTransducer:
609
610 Sentence += "V";
611 break;
612 }
613
614 return( *this );
615}
616
617const SENTENCE& SENTENCE::operator += ( NORTHSOUTH northing )
618{
619 Sentence += ",";
620
621 if ( northing == North )
622 {
623 Sentence += "N";
624 }
625 else if ( northing == South )
626 {
627 Sentence += "S";
628 }
629
630 return( *this );
631}
632
633const SENTENCE& SENTENCE::operator += ( int value )
634{
635 char temp_string[ 80 ];
636
637 ::sprintf( temp_string, "%d", value );
638
639 Sentence += ",";
640 Sentence += temp_string;
641
642 return( *this );
643}
644
645const SENTENCE& SENTENCE::operator += ( EASTWEST easting )
646{
647 Sentence += ",";
648
649 if ( easting == East )
650 {
651 Sentence += "E";
652 }
653 else if ( easting == West )
654 {
655 Sentence += "W";
656 }
657
658 return( *this );
659}
660
661const SENTENCE& SENTENCE::operator += ( NMEA0183_BOOLEAN boolean )
662{
663 Sentence += ",";
664
665 if ( boolean == True )
666 {
667 Sentence += "A";
668 }
669 else if ( boolean == False )
670 {
671 Sentence += "V";
672 }
673
674 return( *this );
675}
676
677const SENTENCE& SENTENCE::operator += ( LATLONG& source )
678{
679 source.Write( *this );
680
681 return( *this );
682}
683
684const SENTENCE& SENTENCE::operator += ( const QDateTime time )
685{
686 QString temp_string = time.time().toString();
687
688 Sentence += ",";
689 Sentence += temp_string;
690
691 return( *this );
692}
Note: See TracBrowser for help on using the repository browser.