Добавлены навигационные решения

This commit is contained in:
Степанов Станислав 2025-03-26 16:13:29 +03:00
parent f3ff85be3d
commit 312153ecee
8 changed files with 452 additions and 0 deletions

72
Solutions/Inc/Nmea_Gga.h Normal file
View File

@ -0,0 +1,72 @@
//
// Created by villuton on 25.03.25.
//
#ifndef NMEA_GGA_H
#define NMEA_GGA_H
#include "Nmea0183Parser_Time.h"
#include "Nmea0183_Sentence.h"
#define GGA_MSG_ID "GGA"
#define GGA_MSG_ID_LEN (3)
#define DGPS_SID_MIN (0000)
#define DGPS_SID_MAX (1023)
/**
* GPS Quality indicator:
*/
typedef enum {
SIG_Invalid = 0, /**< Fix not valid*/
SIG_Fix = 1, /**< GPS fix */
SIG_Differential = 2, /**< Differential GPS fix (DGNSS), SBAS, OmniSTAR VBS, Beacon, RTX in GVBS mode */
SIG_Sensitive = 3, /**< Not applicable */
SIG_RtkFixed = 4, /**< RTK Fixed, xFill */
SIG_RtkFloat = 5, /**< RTK Float, OmniSTAR XP/HP, Location RTK, RTX */
SIG_InsDead = 6 /**< INS Dead reckoning */
}eGGA_sig;
/**
* Reference station ID's descriptors
* When using one of the MSS (Mobile Satellite Services),
* the Reference Station ID field indicates the following services:
*/
typedef enum {
SID_CenterPoint = 0002, /**< CenterPoint or ViewPoint RTX */
SID_RangePoint = 0005, /**< RangePoint RTX */
SID_FieldPoint = 0006, /**< FieldPoint RTX */
SID_VBS = 0100, /**< VBS */
SID_HP = 1000, /**< HP */
SID_HP_XP_Orbits = 1001, /**< HP/XP (Orbits) */
SID_HP_G2_Orbits = 1002, /**< HP/G2 (Orbits) */
SID_XP_GPS = 1008, /**< XP (GPS) */
SID_G2_GPS = 1012, /**< G2 (GPS) */
SID_G2_GPS_GLONASS = 1013, /**< G2 (GPS/GLONASS) */
SID_G2_GLONASS = 1014, /**< G2 (GLONASS) */
SID_HP_XP_GPS = 1016, /**< HP/XP (GPS) */
SID_HP_G2_GPS = 1020, /**< HP/G2 (GPS) */
SID_HP_G2_GPS_GLONASS = 1021, /**< HP/G2 (GPS/GLONASS) */
}eGGA_dgps_sid;
/**
* GGA packet information structure (Global Positioning System Fix Data)
*/
typedef struct
{
tNmeaUtc utc; /**< UTC of position (just time) */
tNmeaLocation location; /**< Sentence location data in fractional NDEG and Cardinal directions */
eGGA_sig sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */
int satinuse; /**< Number of satellites in use (not those in view) */
double HDOP; /**< Horizontal dilution of precision */
double elv; /**< Antenna altitude above/below mean sea level (geoid) */
char elv_units; /**< [M]eters (Antenna height unit) */
double diff; /**< Geoidal separation (Diff. between WGS-84 earth ellipsoid and mean sea level. '-' = geoid is below WGS-84 ellipsoid) */
char diff_units; /**< [M]eters (Units of geoidal separation) */
double dgps_age; /**< Time in seconds since last DGPS update */
int dgps_sid; /**< DGPS station ID number */
} tNmeaGGA;
#endif //NMEA_GGA_H

41
Solutions/Inc/Nmea_Gsa.h Normal file
View File

@ -0,0 +1,41 @@
//
// Created by villuton on 25.03.25.
//
#ifndef NMEA_GSA_H
#define NMEA_GSA_H
#include "Nmea_Config.h"
#define GSA_MSG_ID "GSA"
#define GSA_MSG_ID_LEN (3)
#define GSA_FIX_MODE_EMPTY (0)
#define GSA_FIX_MODE_Manual 'M'
#define GSA_FIX_MODE_Automatic 'A'
typedef enum {
GSA_NaN = 0, /**< (Empty field) */
GSA_FixNotAvailable = 1, /**< Fix not available */
GSA_2D = 2, /**< 2D */
GSA_3D = 3 /**< 3D */
}eGSA_fix_type;
/**
* GSA packet information structure (Satellite status)
*/
typedef struct
{
char fix_mode; /**< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D) */
int fix_type; /**< Type, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */
int sat_prn[NMEA_MAXSAT]; /**< PRNs of satellites used in position fix (null for unused fields) */
double PDOP; /**< Dilution of precision */
double HDOP; /**< Horizontal dilution of precision */
double VDOP; /**< Vertical dilution of precision */
} tNmeaGSA;
bool NmeaGsa_Parse(char *str, size_t len, tNmeaGSA *result);
#endif //NMEA_GSA_H

43
Solutions/Inc/Nmea_Gsv.h Normal file
View File

@ -0,0 +1,43 @@
//
// Created by villuton on 25.03.25.
//
#ifndef NMEA_GSV_H
#define NMEA_GSV_H
#include "Nmea_Config.h"
#define GSV_MSG_ID "GSV"
#define GSV_MSG_ID_LEN (3)
/**
* Information about satellite
* @see nmeaSATINFO
* @see nmeaGPGSV
*/
typedef struct
{
int id; /**< Satellite PRN number */
int in_use; /**< Used in position fix */
int elv; /**< Elevation in degrees, 90 maximum */
int azimuth; /**< Azimuth, degrees from true north, 000 to 359 */
int sig; /**< Signal, 00-99 dB */
} tNmeaSATELLITE;
/**
* GSV packet information structure (Satellites in view)
*/
typedef struct
{
int pack_count; /**< Total number of messages of this type in this cycle */
int pack_index; /**< Message number */
int sat_count; /**< Total number of satellites in view */
tNmeaSATELLITE sat_data[NMEA_SATINPACK];
} tNmeaGSV;
bool NmeaGsv_Parse(char *str, size_t len, tNmeaGSV *result);
#endif //NMEA_GSV_H

41
Solutions/Inc/Nmea_Rmc.h Normal file
View File

@ -0,0 +1,41 @@
//
// Created by villuton on 25.03.25.
//
#ifndef NMEA_RMC_H
#define NMEA_RMC_H
#include "Nmea0183Parser_Time.h"
#include "Nmea0183_Sentence.h"
#define RMC_MSG_ID "RMC"
#define RMC_MSG_ID_LEN (3)
#define RMC_STATUS_NotValid 'V'
#define RMC_STATUS_Valid 'A'
#define RMC_MODE_Autonomous 'A'
#define RMC_MODE_Differential 'D'
#define RMC_MODE_Estimated 'E'
#define RMC_MODE_NotValid 'N'
#define RMC_MODE_Simulator 'S'
/**
* RMC packet information structure (Recommended Minimum sentence C)
*/
typedef struct {
tNmeaTime time; /**< time of position */
char status; /**< Status (A = active or V = void) */
tNmeaLocation location; /**< Sentence location data in fractional NDEG and Cardinal directions */
double speed; /**< Speed over the ground in knots */
double direction; /**< Track angle in degrees True */
double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */
char declin_ew; /**< [E]ast or [W]est */
char mode; /**< Mode indicator of fix type (A = autonomous, D = differential, E = estimated, N = not valid, S = simulator) */
}tNmeaRMC;
bool NmeaRmc_Parse(char *str, size_t len, tNmeaRMC *result);
#endif //NMEA_RMC_H

77
Solutions/Src/Nmea_Gga.c Normal file
View File

@ -0,0 +1,77 @@
//
// Created by villuton on 25.03.25.
//
#include <stddef.h>
#include "Nmea_Gga.h"
#include "Nmea0183Parser_Private.h"
#include "Nmea_Config.h"
bool NmeaGga_Parse(char *str, size_t len, tNmeaGGA *result)
{
char *end = str + len;
char *front = str;
char *nextDivider = front-1;
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
if (!Nmea0183ParseUtc(front, nextDivider, &result->utc)) {
return false;
}
} else {
result->utc = (tNmeaUtc){0};
}
result->location.lat =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : NMEA_DEF_LAT;
result->location.ns =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0)?
*front : 0;
result->location.lon =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0)?
Nmea0183ParseDouble(front, nextDivider - front) : NMEA_DEF_LON;
result->location.ew =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : 0;
result->sig =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : SIG_Invalid;
result->satinuse =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->HDOP =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front,nextDivider - front) : 0;
result->elv =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front,nextDivider - front) : 0;
result->elv_units =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : 0;
result->diff =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front,nextDivider - front) : 0;
result->diff_units =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : 0;
if(result->sig == SIG_Differential){
result->dgps_age =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->dgps_sid =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->dgps_sid =
((DGPS_SID_MIN <= result->dgps_sid) && (result->dgps_sid<= DGPS_SID_MAX)) ?
result->dgps_sid : 0;
} else{
result->dgps_age = 0;
result->dgps_sid = 0;
}
return true;
}

51
Solutions/Src/Nmea_Gsa.c Normal file
View File

@ -0,0 +1,51 @@
//
// Created by villuton on 26.03.25.
//
#include <stddef.h>
#include <stdbool.h>
#include "Nmea_Gsa.h"
#include "Nmea0183Parser_Private.h"
#include "Nmea_Config.h"
/**
*
* @param str NMEA string with GSA solutions
* @param len len GSA string
* @param result < (0) tNmeaGSA struct
* @return TRUE if parsing complete
*/
bool NmeaGsa_Parse(char *str, size_t len, tNmeaGSA *result)
{
char *end = str + len;
char *front = str;
char *nextDivider = front - 1;
result->fix_mode =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : GSA_FIX_MODE_EMPTY;
result->fix_type =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : GSA_NaN;
for(int i = 0; i < NMEA_MAXSAT; i++)
{
result->sat_prn[i] =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : GSA_FIX_MODE_EMPTY;
}
result->PDOP =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : 0;
result->HDOP =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : 0;
result->VDOP =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : 0;
return true;
}

48
Solutions/Src/Nmea_Gsv.c Normal file
View File

@ -0,0 +1,48 @@
//
// Created by villuton on 26.03.25.
//
#include <stddef.h>
#include <stdbool.h>
#include "Nmea_Gsv.h"
#include "Nmea0183Parser_Private.h"
#include "Nmea_Config.h"
/**
*
* @param str NMEA string with GSV solutions
* @param len len GSV string
* @param result < (0) tNmeaGSV struct
* @return TRUE if parsing complete
*/
bool NmeaGsv_Parse(char *str, size_t len, tNmeaGSV *result)
{
char *end = str + len;
char *front = str;
char *nextDivider = front - 1;
result->pack_count =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->pack_index =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->sat_count =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
for(int i = 0; i < NMEA_SATINPACK; i++)
{
result->sat_data[i].id =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->sat_data[i].elv =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->sat_data[i].azimuth =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
result->sat_data[i].sig =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front) : 0;
}
return true;
}

79
Solutions/Src/Nmea_Rmc.c Normal file
View File

@ -0,0 +1,79 @@
//
// Created by villuton on 25.03.25.
//
#include <stddef.h>
#include "Nmea_Rmc.h"
#include "Nmea0183Parser_Private.h"
#include "Nmea_Config.h"
/**
*
* @param str NMEA string with RMC solutions
* @param len len NMEA string
* @param result < (0) tNmeaRMC struct
* @return TRUE if parsing complete
*/
bool NmeaRmc_Parse(char *str, size_t len, tNmeaRMC *result)
{
char *end = str + len;
char *front = str;
char *nextDivider = front - 1;
result->status = RMC_STATUS_NotValid;
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
if (!Nmea0183ParseUtc(front, nextDivider, &result->time.utc)) {
return false;
}
} else {
result->time.utc = (tNmeaUtc){0};
}
result->status =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : RMC_STATUS_NotValid;
result->location.lat =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : NMEA_DEF_LAT;
result->location.ns =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0)?
*front : 0;
result->location.lon =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0)?
Nmea0183ParseDouble(front, nextDivider - front) : NMEA_DEF_LON;
result->location.ew =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : 0;
result->speed =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : 0;
result->direction =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : 0;
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
if (!Nmea0183ParseDate(front, nextDivider, &result->time.date)) {
return false;
}
} else {
result->time.date = (tNmeaDate){0};
}
result->declination =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
Nmea0183ParseDouble(front, nextDivider - front) : 0;
result->declin_ew =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : 0;
result->mode =
(Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) ?
*front : RMC_MODE_NotValid;
return true;
}