kopia lustrzana https://github.com/bristol-seds/pico-tracker
Removed unused NMEA libs
rodzic
aa90d58e95
commit
342801af9e
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_CONFIG_H__
|
||||
#define __NMEA_CONFIG_H__
|
||||
|
||||
#define NMEA_VERSION ("0.5.3")
|
||||
#define NMEA_VERSION_MAJOR (0)
|
||||
#define NMEA_VERSION_MINOR (5)
|
||||
#define NMEA_VERSION_PATCH (3)
|
||||
|
||||
#define NMEA_CONVSTR_BUF (256)
|
||||
#define NMEA_TIMEPARSE_BUF (256)
|
||||
|
||||
#define NMEA_POSIX(x) x
|
||||
#define NMEA_INLINE inline
|
||||
|
||||
#include <assert.h>
|
||||
#define NMEA_ASSERT(x) assert(x)
|
||||
|
||||
|
||||
#endif /* __NMEA_CONFIG_H__ */
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_CONTEXT_H__
|
||||
#define __NMEA_CONTEXT_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define NMEA_DEF_PARSEBUFF (1024)
|
||||
|
||||
typedef enum {
|
||||
NMEA_ERROR_PARSE_TIME = 1,
|
||||
NMEA_ERROR_PARSE_GPGGA,
|
||||
NMEA_ERROR_PARSE_GPGAA_TIME,
|
||||
NMEA_ERROR_PARSE_GPGSA,
|
||||
NMEA_ERROR_PARSE_GPGSV,
|
||||
NMEA_ERROR_PARSE_GPRMC,
|
||||
NMEA_ERROR_PARSE_GPRMC_TIME,
|
||||
NMEA_ERROR_PARSE_GPVTG,
|
||||
NMEA_ERROR_PARSE_GPVTG_FORMAT,
|
||||
|
||||
NMEA_ERROR_MEMORY
|
||||
} nmea_error_t;
|
||||
|
||||
typedef void (*nmeaErrorFunc)(nmea_error_t err);
|
||||
|
||||
typedef struct _nmeaPROPERTY
|
||||
{
|
||||
nmeaErrorFunc error_func;
|
||||
int parse_buff_size;
|
||||
|
||||
} nmeaPROPERTY;
|
||||
|
||||
nmeaPROPERTY * nmea_property();
|
||||
|
||||
void nmea_error(nmea_error_t err);
|
||||
|
||||
#endif /* __NMEA_CONTEXT_H__ */
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.htm
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_GENERATE_H__
|
||||
#define __NMEA_GENERATE_H__
|
||||
|
||||
#include "sentence.h"
|
||||
|
||||
int nmea_generate(
|
||||
char *buff, int buff_sz, /* buffer */
|
||||
const nmeaINFO *info, /* source info */
|
||||
int generate_mask /* mask of sentence`s (e.g. GPGGA | GPGSA) */
|
||||
);
|
||||
|
||||
int nmea_gen_GPGGA(char *buff, int buff_sz, nmeaGPGGA *pack);
|
||||
int nmea_gen_GPGSA(char *buff, int buff_sz, nmeaGPGSA *pack);
|
||||
int nmea_gen_GPGSV(char *buff, int buff_sz, nmeaGPGSV *pack);
|
||||
int nmea_gen_GPRMC(char *buff, int buff_sz, nmeaGPRMC *pack);
|
||||
int nmea_gen_GPVTG(char *buff, int buff_sz, nmeaGPVTG *pack);
|
||||
|
||||
void nmea_info2GPGGA(const nmeaINFO *info, nmeaGPGGA *pack);
|
||||
void nmea_info2GPGSA(const nmeaINFO *info, nmeaGPGSA *pack);
|
||||
void nmea_info2GPRMC(const nmeaINFO *info, nmeaGPRMC *pack);
|
||||
void nmea_info2GPVTG(const nmeaINFO *info, nmeaGPVTG *pack);
|
||||
|
||||
int nmea_gsv_npack(int sat_count);
|
||||
void nmea_info2GPGSV(const nmeaINFO *info, nmeaGPGSV *pack, int pack_idx);
|
||||
|
||||
#endif /* __NMEA_GENERATE_H__ */
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_GENERATOR_H__
|
||||
#define __NMEA_GENERATOR_H__
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/*
|
||||
* high level
|
||||
*/
|
||||
|
||||
struct _nmeaGENERATOR;
|
||||
|
||||
enum nmeaGENTYPE
|
||||
{
|
||||
NMEA_GEN_NOISE = 0,
|
||||
NMEA_GEN_STATIC,
|
||||
NMEA_GEN_ROTATE,
|
||||
|
||||
NMEA_GEN_SAT_STATIC,
|
||||
NMEA_GEN_SAT_ROTATE,
|
||||
NMEA_GEN_POS_RANDMOVE,
|
||||
|
||||
NMEA_GEN_LAST
|
||||
};
|
||||
|
||||
struct _nmeaGENERATOR * nmea_create_generator(int type, nmeaINFO *info);
|
||||
void nmea_destroy_generator(struct _nmeaGENERATOR *gen);
|
||||
|
||||
int nmea_generate_from(
|
||||
char *buff, int buff_sz, /* buffer */
|
||||
nmeaINFO *info, /* source info */
|
||||
struct _nmeaGENERATOR *gen, /* generator */
|
||||
int generate_mask /* mask of sentence`s (e.g. GPGGA | GPGSA) */
|
||||
);
|
||||
|
||||
/*
|
||||
* low level
|
||||
*/
|
||||
|
||||
typedef int (*nmeaNMEA_GEN_INIT)(struct _nmeaGENERATOR *gen, nmeaINFO *info);
|
||||
typedef int (*nmeaNMEA_GEN_LOOP)(struct _nmeaGENERATOR *gen, nmeaINFO *info);
|
||||
typedef int (*nmeaNMEA_GEN_RESET)(struct _nmeaGENERATOR *gen, nmeaINFO *info);
|
||||
typedef int (*nmeaNMEA_GEN_DESTROY)(struct _nmeaGENERATOR *gen);
|
||||
|
||||
typedef struct _nmeaGENERATOR
|
||||
{
|
||||
void *gen_data;
|
||||
nmeaNMEA_GEN_INIT init_call;
|
||||
nmeaNMEA_GEN_LOOP loop_call;
|
||||
nmeaNMEA_GEN_RESET reset_call;
|
||||
nmeaNMEA_GEN_DESTROY destroy_call;
|
||||
struct _nmeaGENERATOR *next;
|
||||
|
||||
} nmeaGENERATOR;
|
||||
|
||||
int nmea_gen_init(nmeaGENERATOR *gen, nmeaINFO *info);
|
||||
int nmea_gen_loop(nmeaGENERATOR *gen, nmeaINFO *info);
|
||||
int nmea_gen_reset(nmeaGENERATOR *gen, nmeaINFO *info);
|
||||
void nmea_gen_destroy(nmeaGENERATOR *gen);
|
||||
void nmea_gen_add(nmeaGENERATOR *to, nmeaGENERATOR *gen);
|
||||
|
||||
#endif /* __NMEA_GENERATOR_H__ */
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_GMATH_H__
|
||||
#define __NMEA_GMATH_H__
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/**< PI value */
|
||||
#define NMEA_PI (3.141592653589793)
|
||||
|
||||
/**< PI division by 180 */
|
||||
#define NMEA_PI180 (NMEA_PI / 180)
|
||||
|
||||
/**< Earth's mean radius in km */
|
||||
#define NMEA_EARTHRADIUS_KM (6378)
|
||||
|
||||
/**< Earth's mean radius in m */
|
||||
#define NMEA_EARTHRADIUS_M (NMEA_EARTHRADIUS_KM * 1000)
|
||||
|
||||
/**< Earth's semi-major axis in m according WGS84 */
|
||||
#define NMEA_EARTH_SEMIMAJORAXIS_M (6378137.0)
|
||||
|
||||
/**< Earth's semi-major axis in km according WGS84 */
|
||||
#define NMEA_EARTH_SEMIMAJORAXIS_KM (NMEA_EARTHMAJORAXIS_KM / 1000)
|
||||
|
||||
/**< Earth's flattening according WGS84 */
|
||||
#define NMEA_EARTH_FLATTENING (1 / 298.257223563)
|
||||
|
||||
/**< Factor for translating DOP to meters */
|
||||
#define NMEA_DOP_FACTOR (5)
|
||||
|
||||
/*
|
||||
* degree VS radian
|
||||
*/
|
||||
|
||||
double nmea_degree2radian(double val);
|
||||
double nmea_radian2degree(double val);
|
||||
|
||||
/*
|
||||
* NDEG (NMEA degree)
|
||||
*/
|
||||
|
||||
double nmea_ndeg2degree(double val);
|
||||
double nmea_degree2ndeg(double val);
|
||||
|
||||
double nmea_ndeg2radian(double val);
|
||||
double nmea_radian2ndeg(double val);
|
||||
|
||||
/*
|
||||
* DOP
|
||||
*/
|
||||
|
||||
double nmea_calc_pdop(double hdop, double vdop);
|
||||
double nmea_dop2meters(double dop);
|
||||
double nmea_meters2dop(double meters);
|
||||
|
||||
/*
|
||||
* positions work
|
||||
*/
|
||||
|
||||
void nmea_info2pos(const nmeaINFO *info, nmeaPOS *pos);
|
||||
void nmea_pos2info(const nmeaPOS *pos, nmeaINFO *info);
|
||||
|
||||
double nmea_distance(
|
||||
const nmeaPOS *from_pos,
|
||||
const nmeaPOS *to_pos
|
||||
);
|
||||
|
||||
double nmea_distance_ellipsoid(
|
||||
const nmeaPOS *from_pos,
|
||||
const nmeaPOS *to_pos,
|
||||
double *from_azimuth,
|
||||
double *to_azimuth
|
||||
);
|
||||
|
||||
int nmea_move_horz(
|
||||
const nmeaPOS *start_pos,
|
||||
nmeaPOS *end_pos,
|
||||
double azimuth,
|
||||
double distance
|
||||
);
|
||||
|
||||
int nmea_move_horz_ellipsoid(
|
||||
const nmeaPOS *start_pos,
|
||||
nmeaPOS *end_pos,
|
||||
double azimuth,
|
||||
double distance,
|
||||
double *end_azimuth
|
||||
);
|
||||
|
||||
#endif /* __NMEA_GMATH_H__ */
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_INFO_H__
|
||||
#define __NMEA_INFO_H__
|
||||
|
||||
#include "time.h"
|
||||
|
||||
#define NMEA_SIG_BAD (0)
|
||||
#define NMEA_SIG_LOW (1)
|
||||
#define NMEA_SIG_MID (2)
|
||||
#define NMEA_SIG_HIGH (3)
|
||||
|
||||
#define NMEA_FIX_BAD (1)
|
||||
#define NMEA_FIX_2D (2)
|
||||
#define NMEA_FIX_3D (3)
|
||||
|
||||
#define NMEA_MAXSAT (12)
|
||||
#define NMEA_SATINPACK (4)
|
||||
#define NMEA_NSATPACKS (NMEA_MAXSAT / NMEA_SATINPACK)
|
||||
|
||||
#define NMEA_DEF_LAT (5001.2621)
|
||||
#define NMEA_DEF_LON (3613.0595)
|
||||
|
||||
/**
|
||||
* Position data in fractional degrees or radians
|
||||
*/
|
||||
typedef struct _nmeaPOS
|
||||
{
|
||||
double lat; /**< Latitude */
|
||||
double lon; /**< Longitude */
|
||||
|
||||
} nmeaPOS;
|
||||
|
||||
/**
|
||||
* Information about satellite
|
||||
* @see nmeaSATINFO
|
||||
* @see nmeaGPGSV
|
||||
*/
|
||||
typedef struct _nmeaSATELLITE
|
||||
{
|
||||
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 */
|
||||
|
||||
} nmeaSATELLITE;
|
||||
|
||||
/**
|
||||
* Information about all satellites in view
|
||||
* @see nmeaINFO
|
||||
* @see nmeaGPGSV
|
||||
*/
|
||||
typedef struct _nmeaSATINFO
|
||||
{
|
||||
int inuse; /**< Number of satellites in use (not those in view) */
|
||||
int inview; /**< Total number of satellites in view */
|
||||
nmeaSATELLITE sat[NMEA_MAXSAT]; /**< Satellites information */
|
||||
|
||||
} nmeaSATINFO;
|
||||
|
||||
/**
|
||||
* Summary GPS information from all parsed packets,
|
||||
* used also for generating NMEA stream
|
||||
* @see nmea_parse
|
||||
* @see nmea_GPGGA2info, nmea_...2info
|
||||
*/
|
||||
typedef struct _nmeaINFO
|
||||
{
|
||||
int smask; /**< Mask specifying types of packages from which data have been obtained */
|
||||
|
||||
nmeaTIME utc; /**< UTC of position */
|
||||
|
||||
int sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */
|
||||
int fix; /**< Operating mode, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */
|
||||
|
||||
double PDOP; /**< Position Dilution Of Precision */
|
||||
double HDOP; /**< Horizontal Dilution Of Precision */
|
||||
double VDOP; /**< Vertical Dilution Of Precision */
|
||||
|
||||
double lat; /**< Latitude in NDEG - +/-[degree][min].[sec/60] */
|
||||
double lon; /**< Longitude in NDEG - +/-[degree][min].[sec/60] */
|
||||
double elv; /**< Antenna altitude above/below mean sea level (geoid) in meters */
|
||||
double speed; /**< Speed over the ground in kilometers/hour */
|
||||
double direction; /**< Track angle in degrees True */
|
||||
double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */
|
||||
|
||||
nmeaSATINFO satinfo; /**< Satellites information */
|
||||
|
||||
} nmeaINFO;
|
||||
|
||||
void nmea_zero_INFO(nmeaINFO *info);
|
||||
|
||||
#endif /* __NMEA_INFO_H__ */
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
* $Id: nmea.h 17 2008-03-11 11:56:11Z xtimor $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_H__
|
||||
#define __NMEA_H__
|
||||
|
||||
#include "./config.h"
|
||||
#include "./units.h"
|
||||
#include "./gmath.h"
|
||||
#include "./info.h"
|
||||
#include "./sentence.h"
|
||||
#include "./generate.h"
|
||||
#include "./generator.h"
|
||||
#include "./parse.h"
|
||||
#include "./parser.h"
|
||||
#include "./context.h"
|
||||
|
||||
#endif /* __NMEA_H__ */
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_PARSE_H__
|
||||
#define __NMEA_PARSE_H__
|
||||
|
||||
#include "sentence.h"
|
||||
|
||||
int nmea_pack_type(const char *buff, int buff_sz);
|
||||
int nmea_find_tail(const char *buff, int buff_sz, int *res_crc);
|
||||
|
||||
int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack);
|
||||
int nmea_parse_GPGSA(const char *buff, int buff_sz, nmeaGPGSA *pack);
|
||||
int nmea_parse_GPGSV(const char *buff, int buff_sz, nmeaGPGSV *pack);
|
||||
int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack);
|
||||
int nmea_parse_GPVTG(const char *buff, int buff_sz, nmeaGPVTG *pack);
|
||||
|
||||
void nmea_GPGGA2info(nmeaGPGGA *pack, nmeaINFO *info);
|
||||
void nmea_GPGSA2info(nmeaGPGSA *pack, nmeaINFO *info);
|
||||
void nmea_GPGSV2info(nmeaGPGSV *pack, nmeaINFO *info);
|
||||
void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info);
|
||||
void nmea_GPVTG2info(nmeaGPVTG *pack, nmeaINFO *info);
|
||||
|
||||
#endif /* __NMEA_PARSE_H__ */
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_PARSER_H__
|
||||
#define __NMEA_PARSER_H__
|
||||
|
||||
#include "info.h"
|
||||
#include "context.h"
|
||||
|
||||
/*
|
||||
* high level
|
||||
*/
|
||||
|
||||
typedef struct _nmeaPARSER
|
||||
{
|
||||
void *top_node;
|
||||
void *end_node;
|
||||
unsigned char buffer[NMEA_DEF_PARSEBUFF];
|
||||
int buff_size;
|
||||
int buff_use;
|
||||
|
||||
} nmeaPARSER;
|
||||
|
||||
int nmea_parser_init(nmeaPARSER *parser);
|
||||
void nmea_parser_destroy(nmeaPARSER *parser);
|
||||
|
||||
int nmea_parse(
|
||||
nmeaPARSER *parser,
|
||||
const char *buff, int buff_sz,
|
||||
nmeaINFO *info
|
||||
);
|
||||
|
||||
/*
|
||||
* low level
|
||||
*/
|
||||
|
||||
int nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz);
|
||||
int nmea_parser_top(nmeaPARSER *parser);
|
||||
int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr);
|
||||
int nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr);
|
||||
int nmea_parser_drop(nmeaPARSER *parser);
|
||||
int nmea_parser_buff_clear(nmeaPARSER *parser);
|
||||
int nmea_parser_queue_clear(nmeaPARSER *parser);
|
||||
|
||||
#endif /* __NMEA_PARSER_H__ */
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_SENTENCE_H__
|
||||
#define __NMEA_SENTENCE_H__
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/**
|
||||
* NMEA packets type which parsed and generated by library
|
||||
*/
|
||||
enum nmeaPACKTYPE
|
||||
{
|
||||
/**< Unknown packet type. */
|
||||
GPNON = 0x0000,
|
||||
|
||||
/**< GGA - Essential fix data which provide 3D location and accuracy data. */
|
||||
GPGGA = 0x0001,
|
||||
|
||||
/**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
|
||||
GPGSA = 0x0002,
|
||||
|
||||
/**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
|
||||
GPGSV = 0x0004,
|
||||
|
||||
/**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
|
||||
GPRMC = 0x0008,
|
||||
|
||||
/**< VTG - Actual track made good and speed over ground. */
|
||||
GPVTG = 0x0010
|
||||
};
|
||||
|
||||
/**
|
||||
* GGA packet information structure (Global Positioning System Fix Data)
|
||||
*/
|
||||
typedef struct _nmeaGPGGA
|
||||
{
|
||||
nmeaTIME utc; /**< UTC of position (just time) */
|
||||
double lat; /**< Latitude in NDEG - [degree][min].[sec/60] */
|
||||
char ns; /**< [N]orth or [S]outh */
|
||||
double lon; /**< Longitude in NDEG - [degree][min].[sec/60] */
|
||||
char ew; /**< [E]ast or [W]est */
|
||||
int 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 */
|
||||
|
||||
} nmeaGPGGA;
|
||||
|
||||
/**
|
||||
* GSA packet information structure (Satellite status)
|
||||
*/
|
||||
typedef struct _nmeaGPGSA
|
||||
{
|
||||
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 */
|
||||
|
||||
} nmeaGPGSA;
|
||||
|
||||
/**
|
||||
* GSV packet information structure (Satellites in view)
|
||||
*/
|
||||
typedef struct _nmeaGPGSV
|
||||
{
|
||||
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 */
|
||||
nmeaSATELLITE sat_data[NMEA_SATINPACK];
|
||||
|
||||
} nmeaGPGSV;
|
||||
|
||||
/**
|
||||
* RMC packet information structure (Recommended Minimum sentence C)
|
||||
*/
|
||||
typedef struct _nmeaGPRMC
|
||||
{
|
||||
nmeaTIME utc; /**< UTC of position */
|
||||
char status; /**< Status (A = active or V = void) */
|
||||
double lat; /**< Latitude in NDEG - [degree][min].[sec/60] */
|
||||
char ns; /**< [N]orth or [S]outh */
|
||||
double lon; /**< Longitude in NDEG - [degree][min].[sec/60] */
|
||||
char ew; /**< [E]ast or [W]est */
|
||||
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) */
|
||||
|
||||
} nmeaGPRMC;
|
||||
|
||||
/**
|
||||
* VTG packet information structure (Track made good and ground speed)
|
||||
*/
|
||||
typedef struct _nmeaGPVTG
|
||||
{
|
||||
double dir; /**< True track made good (degrees) */
|
||||
char dir_t; /**< Fixed text 'T' indicates that track made good is relative to true north */
|
||||
double dec; /**< Magnetic track made good */
|
||||
char dec_m; /**< Fixed text 'M' */
|
||||
double spn; /**< Ground speed, knots */
|
||||
char spn_n; /**< Fixed text 'N' indicates that speed over ground is in knots */
|
||||
double spk; /**< Ground speed, kilometers per hour */
|
||||
char spk_k; /**< Fixed text 'K' indicates that speed over ground is in kilometers/hour */
|
||||
|
||||
} nmeaGPVTG;
|
||||
|
||||
void nmea_zero_GPGGA(nmeaGPGGA *pack);
|
||||
void nmea_zero_GPGSA(nmeaGPGSA *pack);
|
||||
void nmea_zero_GPGSV(nmeaGPGSV *pack);
|
||||
void nmea_zero_GPRMC(nmeaGPRMC *pack);
|
||||
void nmea_zero_GPVTG(nmeaGPVTG *pack);
|
||||
|
||||
#endif /* __NMEA_SENTENCE_H__ */
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_TIME_H__
|
||||
#define __NMEA_TIME_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* Date and time data
|
||||
*/
|
||||
typedef struct _nmeaTIME
|
||||
{
|
||||
int year; /**< Years since 1900 */
|
||||
int mon; /**< Months since January - [0,11] */
|
||||
int day; /**< Day of the month - [1,31] */
|
||||
int hour; /**< Hours since midnight - [0,23] */
|
||||
int min; /**< Minutes after the hour - [0,59] */
|
||||
int sec; /**< Seconds after the minute - [0,59] */
|
||||
int hsec; /**< Hundredth part of second - [0,99] */
|
||||
|
||||
} nmeaTIME;
|
||||
|
||||
#endif /* __NMEA_TIME_H__ */
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_TOK_H__
|
||||
#define __NMEA_TOK_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
int nmea_calc_crc(const char *buff, int buff_sz);
|
||||
int nmea_atoi(const char *str, int str_sz, int radix);
|
||||
double nmea_atof(const char *str, int str_sz);
|
||||
int nmea_printf(char *buff, int buff_sz, const char *format, ...);
|
||||
int nmea_scanf(const char *buff, int buff_sz, const char *format, ...);
|
||||
|
||||
#endif /* __NMEA_TOK_H__ */
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NMEA_UNITS_H__
|
||||
#define __NMEA_UNITS_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* Distance units
|
||||
*/
|
||||
|
||||
/**< Yards, meter * NMEA_TUD_YARDS = yard */
|
||||
#define NMEA_TUD_YARDS (1.0936)
|
||||
|
||||
/**< Knots, kilometer / NMEA_TUD_KNOTS = knot */
|
||||
#define NMEA_TUD_KNOTS (1.852)
|
||||
|
||||
/**< Miles, kilometer / NMEA_TUD_MILES = mile */
|
||||
#define NMEA_TUD_MILES (1.609)
|
||||
|
||||
/*
|
||||
* Speed units
|
||||
*/
|
||||
|
||||
/**< Meters per seconds, (k/h) / NMEA_TUS_MS= (m/s) */
|
||||
#define NMEA_TUS_MS (3.6)
|
||||
|
||||
#endif /* __NMEA_UNITS_H__ */
|
|
@ -1,506 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nmea/context.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
nmeaPROPERTY * nmea_property()
|
||||
{
|
||||
static nmeaPROPERTY prop = {
|
||||
0, NMEA_DEF_PARSEBUFF
|
||||
};
|
||||
|
||||
return ∝
|
||||
}
|
||||
|
||||
void nmea_error(nmea_error_t err)
|
||||
{
|
||||
nmeaErrorFunc func = nmea_property()->error_func;
|
||||
|
||||
if(func) {
|
||||
(*func)(err);
|
||||
}
|
||||
}
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nmea/tok.h"
|
||||
#include "nmea/sentence.h"
|
||||
#include "nmea/generate.h"
|
||||
#include "nmea/units.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
int nmea_gen_GPGGA(char *buff, int buff_sz, nmeaGPGGA *pack)
|
||||
{
|
||||
return nmea_printf(buff, buff_sz,
|
||||
"$GPGGA,%02d%02d%02d.%02d,%07.4f,%C,%07.4f,%C,%1d,%02d,"
|
||||
"%03.1f,%03.1f,%C,%03.1f,%C,%03.1f,%04d",
|
||||
|
||||
pack->utc.hour, pack->utc.min, pack->utc.sec,
|
||||
pack->utc.hsec, pack->lat, pack->ns, pack->lon, pack->ew,
|
||||
pack->sig, pack->satinuse, pack->HDOP,
|
||||
pack->elv, pack->elv_units, pack->diff, pack->diff_units,
|
||||
pack->dgps_age, pack->dgps_sid);
|
||||
}
|
||||
|
||||
int nmea_gen_GPGSA(char *buff, int buff_sz, nmeaGPGSA *pack)
|
||||
{
|
||||
return nmea_printf(buff, buff_sz,
|
||||
"$GPGSA,%C,%1d,%02d,%02d,%02d,%02d,%02d,%02d,"
|
||||
"%02d,%02d,%02d,%02d,%02d,%02d,%03.1f,%03.1f,%03.1f",
|
||||
|
||||
pack->fix_mode, pack->fix_type,
|
||||
pack->sat_prn[0], pack->sat_prn[1], pack->sat_prn[2],
|
||||
pack->sat_prn[3], pack->sat_prn[4], pack->sat_prn[5],
|
||||
pack->sat_prn[6], pack->sat_prn[7], pack->sat_prn[8],
|
||||
pack->sat_prn[9], pack->sat_prn[10], pack->sat_prn[11],
|
||||
pack->PDOP, pack->HDOP, pack->VDOP);
|
||||
}
|
||||
|
||||
int nmea_gen_GPGSV(char *buff, int buff_sz, nmeaGPGSV *pack)
|
||||
{
|
||||
return nmea_printf(buff, buff_sz,
|
||||
"$GPGSV,%1d,%1d,%02d,"
|
||||
"%02d,%02d,%03d,%02d,"
|
||||
"%02d,%02d,%03d,%02d,"
|
||||
"%02d,%02d,%03d,%02d,"
|
||||
"%02d,%02d,%03d,%02d",
|
||||
|
||||
pack->pack_count, pack->pack_index + 1, pack->sat_count,
|
||||
pack->sat_data[0].id, pack->sat_data[0].elv,
|
||||
pack->sat_data[0].azimuth, pack->sat_data[0].sig,
|
||||
pack->sat_data[1].id, pack->sat_data[1].elv,
|
||||
pack->sat_data[1].azimuth, pack->sat_data[1].sig,
|
||||
pack->sat_data[2].id, pack->sat_data[2].elv,
|
||||
pack->sat_data[2].azimuth, pack->sat_data[2].sig,
|
||||
pack->sat_data[3].id, pack->sat_data[3].elv,
|
||||
pack->sat_data[3].azimuth, pack->sat_data[3].sig);
|
||||
}
|
||||
|
||||
int nmea_gen_GPRMC(char *buff, int buff_sz, nmeaGPRMC *pack)
|
||||
{
|
||||
return nmea_printf(buff, buff_sz,
|
||||
"$GPRMC,%02d%02d%02d.%02d,%C,%07.4f,%C,%07.4f,%C,"
|
||||
"%03.1f,%03.1f,%02d%02d%02d,%03.1f,%C,%C",
|
||||
|
||||
pack->utc.hour, pack->utc.min, pack->utc.sec,
|
||||
pack->utc.hsec, pack->status,
|
||||
pack->lat, pack->ns, pack->lon, pack->ew,
|
||||
pack->speed, pack->direction,
|
||||
pack->utc.day, pack->utc.mon + 1, pack->utc.year - 100,
|
||||
pack->declination, pack->declin_ew, pack->mode);
|
||||
}
|
||||
|
||||
int nmea_gen_GPVTG(char *buff, int buff_sz, nmeaGPVTG *pack)
|
||||
{
|
||||
return nmea_printf(buff, buff_sz,
|
||||
"$GPVTG,%.1f,%C,%.1f,%C,%.1f,%C,%.1f,%C",
|
||||
|
||||
pack->dir, pack->dir_t,
|
||||
pack->dec, pack->dec_m,
|
||||
pack->spn, pack->spn_n,
|
||||
pack->spk, pack->spk_k);
|
||||
}
|
||||
|
||||
void nmea_info2GPGGA(const nmeaINFO *info, nmeaGPGGA *pack)
|
||||
{
|
||||
nmea_zero_GPGGA(pack);
|
||||
|
||||
pack->utc = info->utc;
|
||||
pack->lat = fabs(info->lat);
|
||||
pack->ns = ((info->lat > 0)?'N':'S');
|
||||
pack->lon = fabs(info->lon);
|
||||
pack->ew = ((info->lon > 0)?'E':'W');
|
||||
pack->sig = info->sig;
|
||||
pack->satinuse = info->satinfo.inuse;
|
||||
pack->HDOP = info->HDOP;
|
||||
pack->elv = info->elv;
|
||||
}
|
||||
|
||||
void nmea_info2GPGSA(const nmeaINFO *info, nmeaGPGSA *pack)
|
||||
{
|
||||
int it;
|
||||
|
||||
nmea_zero_GPGSA(pack);
|
||||
|
||||
pack->fix_type = info->fix;
|
||||
pack->PDOP = info->PDOP;
|
||||
pack->HDOP = info->HDOP;
|
||||
pack->VDOP = info->VDOP;
|
||||
|
||||
for(it = 0; it < NMEA_MAXSAT; ++it) {
|
||||
pack->sat_prn[it] =
|
||||
((info->satinfo.sat[it].in_use)?info->satinfo.sat[it].id:0);
|
||||
}
|
||||
}
|
||||
|
||||
int nmea_gsv_npack(int sat_count)
|
||||
{
|
||||
int pack_count = (int)ceil(((double)sat_count) / NMEA_SATINPACK);
|
||||
|
||||
if(0 == pack_count) {
|
||||
pack_count = 1;
|
||||
}
|
||||
|
||||
return pack_count;
|
||||
}
|
||||
|
||||
void nmea_info2GPGSV(const nmeaINFO *info, nmeaGPGSV *pack, int pack_idx)
|
||||
{
|
||||
int sit, pit;
|
||||
|
||||
nmea_zero_GPGSV(pack);
|
||||
|
||||
pack->sat_count = (info->satinfo.inview <= NMEA_MAXSAT)?info->satinfo.inview:NMEA_MAXSAT;
|
||||
pack->pack_count = nmea_gsv_npack(pack->sat_count);
|
||||
|
||||
if(pack->pack_count == 0) {
|
||||
pack->pack_count = 1;
|
||||
}
|
||||
|
||||
if(pack_idx >= pack->pack_count) {
|
||||
pack->pack_index = pack_idx % pack->pack_count;
|
||||
} else {
|
||||
pack->pack_index = pack_idx;
|
||||
}
|
||||
|
||||
for(pit = 0, sit = pack->pack_index * NMEA_SATINPACK; pit < NMEA_SATINPACK; ++pit, ++sit) {
|
||||
pack->sat_data[pit] = info->satinfo.sat[sit];
|
||||
}
|
||||
}
|
||||
|
||||
void nmea_info2GPRMC(const nmeaINFO *info, nmeaGPRMC *pack)
|
||||
{
|
||||
nmea_zero_GPRMC(pack);
|
||||
|
||||
pack->utc = info->utc;
|
||||
pack->status = ((info->sig > 0)?'A':'V');
|
||||
pack->lat = fabs(info->lat);
|
||||
pack->ns = ((info->lat > 0)?'N':'S');
|
||||
pack->lon = fabs(info->lon);
|
||||
pack->ew = ((info->lon > 0)?'E':'W');
|
||||
pack->speed = info->speed / NMEA_TUD_KNOTS;
|
||||
pack->direction = info->direction;
|
||||
pack->declination = info->declination;
|
||||
pack->declin_ew = 'E';
|
||||
pack->mode = ((info->sig > 0)?'A':'N');
|
||||
}
|
||||
|
||||
void nmea_info2GPVTG(const nmeaINFO *info, nmeaGPVTG *pack)
|
||||
{
|
||||
nmea_zero_GPVTG(pack);
|
||||
|
||||
pack->dir = info->direction;
|
||||
pack->dec = info->declination;
|
||||
pack->spn = info->speed / NMEA_TUD_KNOTS;
|
||||
pack->spk = info->speed;
|
||||
}
|
||||
|
||||
int nmea_generate(char *buff, int buff_sz,
|
||||
const nmeaINFO *info, int generate_mask)
|
||||
{
|
||||
int gen_count = 0, gsv_it, gsv_count;
|
||||
int pack_mask = generate_mask;
|
||||
|
||||
nmeaGPGGA gga;
|
||||
nmeaGPGSA gsa;
|
||||
nmeaGPGSV gsv;
|
||||
nmeaGPRMC rmc;
|
||||
nmeaGPVTG vtg;
|
||||
|
||||
if(!buff) return 0;
|
||||
|
||||
while(pack_mask) {
|
||||
if(pack_mask & GPGGA) {
|
||||
nmea_info2GPGGA(info, &gga);
|
||||
gen_count += nmea_gen_GPGGA(buff + gen_count, buff_sz - gen_count, &gga);
|
||||
pack_mask &= ~GPGGA;
|
||||
|
||||
} else if(pack_mask & GPGSA) {
|
||||
nmea_info2GPGSA(info, &gsa);
|
||||
gen_count += nmea_gen_GPGSA(buff + gen_count, buff_sz - gen_count, &gsa);
|
||||
pack_mask &= ~GPGSA;
|
||||
|
||||
} else if(pack_mask & GPGSV) {
|
||||
gsv_count = nmea_gsv_npack(info->satinfo.inview);
|
||||
|
||||
for(gsv_it = 0; gsv_it < gsv_count && buff_sz - gen_count > 0; ++gsv_it) {
|
||||
nmea_info2GPGSV(info, &gsv, gsv_it);
|
||||
gen_count += nmea_gen_GPGSV(buff + gen_count, buff_sz - gen_count, &gsv);
|
||||
}
|
||||
|
||||
pack_mask &= ~GPGSV;
|
||||
|
||||
} else if(pack_mask & GPRMC) {
|
||||
nmea_info2GPRMC(info, &rmc);
|
||||
gen_count += nmea_gen_GPRMC(buff + gen_count, buff_sz - gen_count, &rmc);
|
||||
pack_mask &= ~GPRMC;
|
||||
|
||||
} else if(pack_mask & GPVTG) {
|
||||
nmea_info2GPVTG(info, &vtg);
|
||||
gen_count += nmea_gen_GPVTG(buff + gen_count, buff_sz - gen_count, &vtg);
|
||||
pack_mask &= ~GPVTG;
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if(buff_sz - gen_count <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return gen_count;
|
||||
}
|
|
@ -1,419 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nmea/gmath.h"
|
||||
#include "nmea/generate.h"
|
||||
#include "nmea/generator.h"
|
||||
#include "nmea/context.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
double nmea_random(double min, double max)
|
||||
{
|
||||
static double rand_max = RAND_MAX;
|
||||
double rand_val = rand();
|
||||
double bounds = max - min;
|
||||
return min + (rand_val * bounds) / rand_max;
|
||||
}
|
||||
|
||||
/*
|
||||
* low level
|
||||
*/
|
||||
|
||||
int nmea_gen_init(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
int RetVal = 1; int smask = info->smask;
|
||||
nmeaGENERATOR *igen = gen;
|
||||
|
||||
nmea_zero_INFO(info);
|
||||
info->smask = smask;
|
||||
|
||||
info->lat = NMEA_DEF_LAT;
|
||||
info->lon = NMEA_DEF_LON;
|
||||
|
||||
while(RetVal && igen) {
|
||||
if(igen->init_call) {
|
||||
RetVal = (*igen->init_call)(igen, info);
|
||||
}
|
||||
|
||||
igen = igen->next;
|
||||
}
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
int nmea_gen_loop(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
int RetVal = 1;
|
||||
|
||||
if(gen->loop_call) {
|
||||
RetVal = (*gen->loop_call)(gen, info);
|
||||
}
|
||||
|
||||
if(RetVal && gen->next) {
|
||||
RetVal = nmea_gen_loop(gen->next, info);
|
||||
}
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
int nmea_gen_reset(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
int RetVal = 1;
|
||||
|
||||
if(gen->reset_call) {
|
||||
RetVal = (*gen->reset_call)(gen, info);
|
||||
}
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
void nmea_gen_destroy(nmeaGENERATOR *gen)
|
||||
{
|
||||
if(gen->next) {
|
||||
nmea_gen_destroy(gen->next);
|
||||
gen->next = 0;
|
||||
}
|
||||
|
||||
if(gen->destroy_call) {
|
||||
(*gen->destroy_call)(gen);
|
||||
}
|
||||
|
||||
free(gen);
|
||||
}
|
||||
|
||||
void nmea_gen_add(nmeaGENERATOR *to, nmeaGENERATOR *gen)
|
||||
{
|
||||
if(to->next) {
|
||||
nmea_gen_add(to->next, gen);
|
||||
} else {
|
||||
to->next = gen;
|
||||
}
|
||||
}
|
||||
|
||||
int nmea_generate_from(char *buff, int buff_sz,
|
||||
nmeaINFO *info, nmeaGENERATOR *gen, int generate_mask)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if(0 != (retval = nmea_gen_loop(gen, info))) {
|
||||
retval = nmea_generate(buff, buff_sz, info, generate_mask);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOISE generator
|
||||
*/
|
||||
|
||||
int nmea_igen_noise_init(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
(void)gen;
|
||||
(void)info;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nmea_igen_noise_loop(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
int it;
|
||||
int in_use;
|
||||
|
||||
(void)gen;
|
||||
|
||||
info->sig = (int)nmea_random(1, 3);
|
||||
info->PDOP = nmea_random(0, 9);
|
||||
info->HDOP = nmea_random(0, 9);
|
||||
info->VDOP = nmea_random(0, 9);
|
||||
info->fix = (int)nmea_random(2, 3);
|
||||
info->lat = nmea_random(0, 100);
|
||||
info->lon = nmea_random(0, 100);
|
||||
info->speed = nmea_random(0, 100);
|
||||
info->direction = nmea_random(0, 360);
|
||||
info->declination = nmea_random(0, 360);
|
||||
info->elv = (int)nmea_random(-100, 100);
|
||||
|
||||
info->satinfo.inuse = 0;
|
||||
info->satinfo.inview = 0;
|
||||
|
||||
for(it = 0; it < 12; ++it) {
|
||||
info->satinfo.sat[it].id = it;
|
||||
info->satinfo.sat[it].in_use = in_use = (int)nmea_random(0, 3);
|
||||
info->satinfo.sat[it].elv = (int)nmea_random(0, 90);
|
||||
info->satinfo.sat[it].azimuth = (int)nmea_random(0, 359);
|
||||
info->satinfo.sat[it].sig = (int)(in_use?nmea_random(40, 99):nmea_random(0, 40));
|
||||
|
||||
if(in_use) {
|
||||
info->satinfo.inuse++;
|
||||
}
|
||||
|
||||
if(info->satinfo.sat[it].sig > 0) {
|
||||
info->satinfo.inview++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nmea_igen_noise_reset(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
(void)gen;
|
||||
(void)info;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* STATIC generator
|
||||
*/
|
||||
|
||||
int nmea_igen_static_loop(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
(void)gen;
|
||||
(void)info;
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
int nmea_igen_static_reset(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
(void)gen;
|
||||
|
||||
info->satinfo.inuse = 4;
|
||||
info->satinfo.inview = 4;
|
||||
|
||||
info->satinfo.sat[0].id = 1;
|
||||
info->satinfo.sat[0].in_use = 1;
|
||||
info->satinfo.sat[0].elv = 50;
|
||||
info->satinfo.sat[0].azimuth = 0;
|
||||
info->satinfo.sat[0].sig = 99;
|
||||
|
||||
info->satinfo.sat[1].id = 2;
|
||||
info->satinfo.sat[1].in_use = 1;
|
||||
info->satinfo.sat[1].elv = 50;
|
||||
info->satinfo.sat[1].azimuth = 90;
|
||||
info->satinfo.sat[1].sig = 99;
|
||||
|
||||
info->satinfo.sat[2].id = 3;
|
||||
info->satinfo.sat[2].in_use = 1;
|
||||
info->satinfo.sat[2].elv = 50;
|
||||
info->satinfo.sat[2].azimuth = 180;
|
||||
info->satinfo.sat[2].sig = 99;
|
||||
|
||||
info->satinfo.sat[3].id = 4;
|
||||
info->satinfo.sat[3].in_use = 1;
|
||||
info->satinfo.sat[3].elv = 50;
|
||||
info->satinfo.sat[3].azimuth = 270;
|
||||
info->satinfo.sat[3].sig = 99;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nmea_igen_static_init(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
info->sig = 3;
|
||||
info->fix = 3;
|
||||
|
||||
nmea_igen_static_reset(gen, info);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* SAT_ROTATE generator
|
||||
*/
|
||||
|
||||
int nmea_igen_rotate_loop(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
int it;
|
||||
int count = info->satinfo.inview;
|
||||
double deg = 360 / (count?count:1);
|
||||
double srt = (count?(info->satinfo.sat[0].azimuth):0) + 5;
|
||||
|
||||
(void)gen;
|
||||
|
||||
for(it = 0; it < count; ++it) {
|
||||
info->satinfo.sat[it].azimuth = (int)((srt >= 360)?srt - 360:srt);
|
||||
srt += deg;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
int nmea_igen_rotate_reset(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
int it;
|
||||
double deg = 360 / 8;
|
||||
double srt = 0;
|
||||
|
||||
(void)gen;
|
||||
|
||||
info->satinfo.inuse = 8;
|
||||
info->satinfo.inview = 8;
|
||||
|
||||
for(it = 0; it < info->satinfo.inview; ++it) {
|
||||
info->satinfo.sat[it].id = it + 1;
|
||||
info->satinfo.sat[it].in_use = 1;
|
||||
info->satinfo.sat[it].elv = 5;
|
||||
info->satinfo.sat[it].azimuth = (int)srt;
|
||||
info->satinfo.sat[it].sig = 80;
|
||||
srt += deg;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nmea_igen_rotate_init(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
info->sig = 3;
|
||||
info->fix = 3;
|
||||
|
||||
nmea_igen_rotate_reset(gen, info);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* POS_RANDMOVE generator
|
||||
*/
|
||||
|
||||
int nmea_igen_pos_rmove_init(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
(void)gen;
|
||||
|
||||
info->sig = 3;
|
||||
info->fix = 3;
|
||||
info->direction = info->declination = 0;
|
||||
info->speed = 20;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nmea_igen_pos_rmove_loop(nmeaGENERATOR *gen, nmeaINFO *info)
|
||||
{
|
||||
nmeaPOS crd;
|
||||
|
||||
(void)gen;
|
||||
|
||||
info->direction += nmea_random(-10, 10);
|
||||
info->speed += nmea_random(-2, 3);
|
||||
|
||||
if(info->direction < 0)
|
||||
info->direction = 359 + info->direction;
|
||||
if(info->direction > 359)
|
||||
info->direction -= 359;
|
||||
|
||||
if(info->speed > 40)
|
||||
info->speed = 40;
|
||||
if(info->speed < 1)
|
||||
info->speed = 1;
|
||||
|
||||
nmea_info2pos(info, &crd);
|
||||
nmea_move_horz(&crd, &crd, info->direction, info->speed / 3600);
|
||||
nmea_pos2info(&crd, info);
|
||||
|
||||
info->declination = info->direction;
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
int nmea_igen_pos_rmove_destroy(nmeaGENERATOR *gen)
|
||||
{
|
||||
(void)gen;
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
/*
|
||||
* generator create
|
||||
*/
|
||||
|
||||
nmeaGENERATOR * __nmea_create_generator(int type, nmeaINFO *info)
|
||||
{
|
||||
nmeaGENERATOR *gen = 0;
|
||||
|
||||
switch(type) {
|
||||
case NMEA_GEN_NOISE:
|
||||
if(0 == (gen = malloc(sizeof(nmeaGENERATOR)))) {
|
||||
nmea_error(NMEA_ERROR_MEMORY);
|
||||
} else {
|
||||
|
||||
memset(gen, 0, sizeof(nmeaGENERATOR));
|
||||
gen->init_call = &nmea_igen_noise_init;
|
||||
gen->loop_call = &nmea_igen_noise_loop;
|
||||
gen->reset_call = &nmea_igen_noise_reset;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMEA_GEN_STATIC:
|
||||
case NMEA_GEN_SAT_STATIC:
|
||||
if(0 == (gen = malloc(sizeof(nmeaGENERATOR)))) {
|
||||
nmea_error(NMEA_ERROR_MEMORY);
|
||||
} else {
|
||||
|
||||
memset(gen, 0, sizeof(nmeaGENERATOR));
|
||||
gen->init_call = &nmea_igen_static_init;
|
||||
gen->loop_call = &nmea_igen_static_loop;
|
||||
gen->reset_call = &nmea_igen_static_reset;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMEA_GEN_SAT_ROTATE:
|
||||
if(0 == (gen = malloc(sizeof(nmeaGENERATOR)))) {
|
||||
nmea_error(NMEA_ERROR_MEMORY);
|
||||
} else {
|
||||
|
||||
memset(gen, 0, sizeof(nmeaGENERATOR));
|
||||
gen->init_call = &nmea_igen_rotate_init;
|
||||
gen->loop_call = &nmea_igen_rotate_loop;
|
||||
gen->reset_call = &nmea_igen_rotate_reset;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMEA_GEN_POS_RANDMOVE:
|
||||
if(0 == (gen = malloc(sizeof(nmeaGENERATOR)))) {
|
||||
nmea_error(NMEA_ERROR_MEMORY);
|
||||
} else {
|
||||
|
||||
memset(gen, 0, sizeof(nmeaGENERATOR));
|
||||
gen->init_call = &nmea_igen_pos_rmove_init;
|
||||
gen->loop_call = &nmea_igen_pos_rmove_loop;
|
||||
gen->destroy_call = &nmea_igen_pos_rmove_destroy;
|
||||
}
|
||||
break;
|
||||
|
||||
case NMEA_GEN_ROTATE:
|
||||
gen = __nmea_create_generator(NMEA_GEN_SAT_ROTATE, info);
|
||||
nmea_gen_add(gen, __nmea_create_generator(NMEA_GEN_POS_RANDMOVE, info));
|
||||
break;
|
||||
};
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
nmeaGENERATOR * nmea_create_generator(int type, nmeaINFO *info)
|
||||
{
|
||||
nmeaGENERATOR *gen = __nmea_create_generator(type, info);
|
||||
|
||||
if(gen) {
|
||||
nmea_gen_init(gen, info);
|
||||
}
|
||||
|
||||
return gen;
|
||||
}
|
||||
|
||||
void nmea_destroy_generator(nmeaGENERATOR *gen)
|
||||
{
|
||||
nmea_gen_destroy(gen);
|
||||
}
|
|
@ -1,397 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nmea/gmath.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
/**
|
||||
* \fn nmea_degree2radian
|
||||
* \brief Convert degree to radian
|
||||
*/
|
||||
double nmea_degree2radian(double val)
|
||||
{
|
||||
return (val * NMEA_PI180);
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn nmea_radian2degree
|
||||
* \brief Convert radian to degree
|
||||
*/
|
||||
double nmea_radian2degree(double val)
|
||||
{
|
||||
return (val / NMEA_PI180);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert NDEG (NMEA degree) to fractional degree
|
||||
*/
|
||||
double nmea_ndeg2degree(double val)
|
||||
{
|
||||
double deg = ((int)(val / 100));
|
||||
val = deg + (val - deg * 100) / 60;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert fractional degree to NDEG (NMEA degree)
|
||||
*/
|
||||
double nmea_degree2ndeg(double val)
|
||||
{
|
||||
double int_part;
|
||||
double fra_part;
|
||||
fra_part = modf(val, &int_part);
|
||||
val = int_part * 100 + fra_part * 60;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn nmea_ndeg2radian
|
||||
* \brief Convert NDEG (NMEA degree) to radian
|
||||
*/
|
||||
double nmea_ndeg2radian(double val)
|
||||
{
|
||||
return nmea_degree2radian(nmea_ndeg2degree(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn nmea_radian2ndeg
|
||||
* \brief Convert radian to NDEG (NMEA degree)
|
||||
*/
|
||||
double nmea_radian2ndeg(double val)
|
||||
{
|
||||
return nmea_degree2ndeg(nmea_radian2degree(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate PDOP (Position Dilution Of Precision) factor
|
||||
*/
|
||||
double nmea_calc_pdop(double hdop, double vdop)
|
||||
{
|
||||
return sqrt(pow(hdop, 2) + pow(vdop, 2));
|
||||
}
|
||||
|
||||
double nmea_dop2meters(double dop)
|
||||
{
|
||||
return (dop * NMEA_DOP_FACTOR);
|
||||
}
|
||||
|
||||
double nmea_meters2dop(double meters)
|
||||
{
|
||||
return (meters / NMEA_DOP_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate distance between two points
|
||||
* \return Distance in meters
|
||||
*/
|
||||
double nmea_distance(
|
||||
const nmeaPOS *from_pos, /**< From position in radians */
|
||||
const nmeaPOS *to_pos /**< To position in radians */
|
||||
)
|
||||
{
|
||||
double dist = ((double)NMEA_EARTHRADIUS_M) * acos(
|
||||
sin(to_pos->lat) * sin(from_pos->lat) +
|
||||
cos(to_pos->lat) * cos(from_pos->lat) * cos(to_pos->lon - from_pos->lon)
|
||||
);
|
||||
return dist;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate distance between two points
|
||||
* This function uses an algorithm for an oblate spheroid earth model.
|
||||
* The algorithm is described here:
|
||||
* http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
|
||||
* \return Distance in meters
|
||||
*/
|
||||
double nmea_distance_ellipsoid(
|
||||
const nmeaPOS *from_pos, /**< From position in radians */
|
||||
const nmeaPOS *to_pos, /**< To position in radians */
|
||||
double *from_azimuth, /**< (O) azimuth at "from" position in radians */
|
||||
double *to_azimuth /**< (O) azimuth at "to" position in radians */
|
||||
)
|
||||
{
|
||||
/* All variables */
|
||||
double f, a, b, sqr_a, sqr_b;
|
||||
double L, phi1, phi2, U1, U2, sin_U1, sin_U2, cos_U1, cos_U2;
|
||||
double sigma, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, sqr_cos_alpha, lambda, sin_lambda, cos_lambda, delta_lambda;
|
||||
int remaining_steps;
|
||||
double sqr_u, A, B, delta_sigma;
|
||||
|
||||
/* Check input */
|
||||
NMEA_ASSERT(from_pos != 0);
|
||||
NMEA_ASSERT(to_pos != 0);
|
||||
|
||||
if ((from_pos->lat == to_pos->lat) && (from_pos->lon == to_pos->lon)) {
|
||||
/* Identical points */
|
||||
|
||||
if ( from_azimuth != 0 ) {
|
||||
*from_azimuth = 0;
|
||||
}
|
||||
|
||||
if ( to_azimuth != 0 ) {
|
||||
*to_azimuth = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* Identical points */
|
||||
|
||||
/* Earth geometry */
|
||||
f = NMEA_EARTH_FLATTENING;
|
||||
a = NMEA_EARTH_SEMIMAJORAXIS_M;
|
||||
b = (1 - f) * a;
|
||||
sqr_a = a * a;
|
||||
sqr_b = b * b;
|
||||
|
||||
/* Calculation */
|
||||
L = to_pos->lon - from_pos->lon;
|
||||
phi1 = from_pos->lat;
|
||||
phi2 = to_pos->lat;
|
||||
U1 = atan((1 - f) * tan(phi1));
|
||||
U2 = atan((1 - f) * tan(phi2));
|
||||
sin_U1 = sin(U1);
|
||||
sin_U2 = sin(U2);
|
||||
cos_U1 = cos(U1);
|
||||
cos_U2 = cos(U2);
|
||||
|
||||
/* Initialize iteration */
|
||||
sigma = 0;
|
||||
sin_sigma = sin(sigma);
|
||||
cos_sigma = cos(sigma);
|
||||
cos_2_sigmam = 0;
|
||||
sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
|
||||
sqr_cos_alpha = 0;
|
||||
lambda = L;
|
||||
sin_lambda = sin(lambda);
|
||||
cos_lambda = cos(lambda);
|
||||
delta_lambda = lambda;
|
||||
remaining_steps = 20;
|
||||
|
||||
while ((delta_lambda > 1e-12) && (remaining_steps > 0)) { /* Iterate */
|
||||
/* Variables */
|
||||
double tmp1, tmp2, tan_sigma, sin_alpha, cos_alpha, C, lambda_prev;
|
||||
|
||||
(void)tan_sigma;
|
||||
|
||||
/* Calculation */
|
||||
tmp1 = cos_U2 * sin_lambda;
|
||||
tmp2 = cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda;
|
||||
sin_sigma = sqrt(tmp1 * tmp1 + tmp2 * tmp2);
|
||||
cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda;
|
||||
tan_sigma = sin_sigma / cos_sigma;
|
||||
sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma;
|
||||
cos_alpha = cos(asin(sin_alpha));
|
||||
sqr_cos_alpha = cos_alpha * cos_alpha;
|
||||
cos_2_sigmam = cos_sigma - 2 * sin_U1 * sin_U2 / sqr_cos_alpha;
|
||||
sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
|
||||
C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha));
|
||||
lambda_prev = lambda;
|
||||
sigma = asin(sin_sigma);
|
||||
lambda = L +
|
||||
(1 - C) * f * sin_alpha
|
||||
* (sigma + C * sin_sigma * (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam)));
|
||||
delta_lambda = lambda_prev - lambda;
|
||||
if ( delta_lambda < 0 ) delta_lambda = -delta_lambda;
|
||||
sin_lambda = sin(lambda);
|
||||
cos_lambda = cos(lambda);
|
||||
remaining_steps--;
|
||||
} /* Iterate */
|
||||
|
||||
/* More calculation */
|
||||
sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b;
|
||||
A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u)));
|
||||
B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u)));
|
||||
delta_sigma = B * sin_sigma * (
|
||||
cos_2_sigmam + B / 4 * (
|
||||
cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) -
|
||||
B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam)
|
||||
));
|
||||
|
||||
/* Calculate result */
|
||||
if (from_azimuth != 0) {
|
||||
double tan_alpha_1 = cos_U2 * sin_lambda / (cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda);
|
||||
*from_azimuth = atan(tan_alpha_1);
|
||||
}
|
||||
if (to_azimuth != 0) {
|
||||
double tan_alpha_2 = cos_U1 * sin_lambda / (-sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda);
|
||||
*to_azimuth = atan(tan_alpha_2);
|
||||
}
|
||||
|
||||
return b * A * (sigma - delta_sigma);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Horizontal move of point position
|
||||
*/
|
||||
int nmea_move_horz(
|
||||
const nmeaPOS *start_pos, /**< Start position in radians */
|
||||
nmeaPOS *end_pos, /**< Result position in radians */
|
||||
double azimuth, /**< Azimuth (degree) [0, 359] */
|
||||
double distance /**< Distance (km) */
|
||||
)
|
||||
{
|
||||
nmeaPOS p1 = *start_pos;
|
||||
int RetVal = 1;
|
||||
|
||||
distance /= NMEA_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */
|
||||
azimuth = nmea_degree2radian(azimuth);
|
||||
|
||||
end_pos->lat = asin(
|
||||
sin(p1.lat) * cos(distance) + cos(p1.lat) * sin(distance) * cos(azimuth));
|
||||
end_pos->lon = p1.lon + atan2(
|
||||
sin(azimuth) * sin(distance) * cos(p1.lat), cos(distance) - sin(p1.lat) * sin(end_pos->lat));
|
||||
|
||||
if(NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon)) {
|
||||
end_pos->lat = 0; end_pos->lon = 0;
|
||||
RetVal = 0;
|
||||
}
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Horizontal move of point position
|
||||
* This function uses an algorithm for an oblate spheroid earth model.
|
||||
* The algorithm is described here:
|
||||
* http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
|
||||
*/
|
||||
int nmea_move_horz_ellipsoid(
|
||||
const nmeaPOS *start_pos, /**< Start position in radians */
|
||||
nmeaPOS *end_pos, /**< (O) Result position in radians */
|
||||
double azimuth, /**< Azimuth in radians */
|
||||
double distance, /**< Distance (km) */
|
||||
double *end_azimuth /**< (O) Azimuth at end position in radians */
|
||||
)
|
||||
{
|
||||
/* Variables */
|
||||
double f, a, b, sqr_a, sqr_b;
|
||||
double phi1, tan_U1, sin_U1, cos_U1, s, alpha1, sin_alpha1, cos_alpha1;
|
||||
double tan_sigma1, sigma1, sin_alpha, cos_alpha, sqr_cos_alpha, sqr_u, A, B;
|
||||
double sigma_initial, sigma, sigma_prev, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, delta_sigma;
|
||||
int remaining_steps;
|
||||
double tmp1, phi2, lambda, C, L;
|
||||
|
||||
(void)cos_alpha;
|
||||
(void)tan_sigma1;
|
||||
|
||||
/* Check input */
|
||||
NMEA_ASSERT(start_pos != 0);
|
||||
NMEA_ASSERT(end_pos != 0);
|
||||
|
||||
if (fabs(distance) < 1e-12)
|
||||
{ /* No move */
|
||||
*end_pos = *start_pos;
|
||||
if ( end_azimuth != 0 ) *end_azimuth = azimuth;
|
||||
return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon));
|
||||
} /* No move */
|
||||
|
||||
/* Earth geometry */
|
||||
f = NMEA_EARTH_FLATTENING;
|
||||
a = NMEA_EARTH_SEMIMAJORAXIS_M;
|
||||
b = (1 - f) * a;
|
||||
sqr_a = a * a;
|
||||
sqr_b = b * b;
|
||||
|
||||
/* Calculation */
|
||||
phi1 = start_pos->lat;
|
||||
tan_U1 = (1 - f) * tan(phi1);
|
||||
cos_U1 = 1 / sqrt(1 + tan_U1 * tan_U1);
|
||||
sin_U1 = tan_U1 * cos_U1;
|
||||
s = distance;
|
||||
alpha1 = azimuth;
|
||||
sin_alpha1 = sin(alpha1);
|
||||
cos_alpha1 = cos(alpha1);
|
||||
tan_sigma1 = tan_U1 / cos_alpha1;
|
||||
sigma1 = atan2(tan_U1, cos_alpha1);
|
||||
sin_alpha = cos_U1 * sin_alpha1;
|
||||
sqr_cos_alpha = 1 - sin_alpha * sin_alpha;
|
||||
cos_alpha = sqrt(sqr_cos_alpha);
|
||||
sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b;
|
||||
A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u)));
|
||||
B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u)));
|
||||
|
||||
/* Initialize iteration */
|
||||
sigma_initial = s / (b * A);
|
||||
sigma = sigma_initial;
|
||||
sin_sigma = sin(sigma);
|
||||
cos_sigma = cos(sigma);
|
||||
cos_2_sigmam = cos(2 * sigma1 + sigma);
|
||||
sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
|
||||
delta_sigma = 0;
|
||||
sigma_prev = 2 * NMEA_PI;
|
||||
remaining_steps = 20;
|
||||
|
||||
while ((fabs(sigma - sigma_prev) > 1e-12) && (remaining_steps > 0)) {
|
||||
/* Iterate */
|
||||
cos_2_sigmam = cos(2 * sigma1 + sigma);
|
||||
sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
|
||||
sin_sigma = sin(sigma);
|
||||
cos_sigma = cos(sigma);
|
||||
delta_sigma = B * sin_sigma * (
|
||||
cos_2_sigmam + B / 4 * (
|
||||
cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) -
|
||||
B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam)
|
||||
));
|
||||
sigma_prev = sigma;
|
||||
sigma = sigma_initial + delta_sigma;
|
||||
remaining_steps --;
|
||||
} /* Iterate */
|
||||
|
||||
/* Calculate result */
|
||||
tmp1 = (sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_alpha1);
|
||||
phi2 = atan2(
|
||||
sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_alpha1,
|
||||
(1 - f) * sqrt(sin_alpha * sin_alpha + tmp1 * tmp1)
|
||||
);
|
||||
lambda = atan2(
|
||||
sin_sigma * sin_alpha1,
|
||||
cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_alpha1
|
||||
);
|
||||
C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha));
|
||||
L = lambda -
|
||||
(1 - C) * f * sin_alpha * (
|
||||
sigma + C * sin_sigma *
|
||||
(cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam))
|
||||
);
|
||||
|
||||
/* Result */
|
||||
end_pos->lon = start_pos->lon + L;
|
||||
end_pos->lat = phi2;
|
||||
|
||||
if (end_azimuth != 0) {
|
||||
*end_azimuth = atan2(
|
||||
sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_alpha1
|
||||
);
|
||||
}
|
||||
|
||||
return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert position from INFO to radians position
|
||||
*/
|
||||
void nmea_info2pos(const nmeaINFO *info, nmeaPOS *pos)
|
||||
{
|
||||
pos->lat = nmea_ndeg2radian(info->lat);
|
||||
pos->lon = nmea_ndeg2radian(info->lon);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert radians position to INFOs position
|
||||
*/
|
||||
void nmea_pos2info(const nmeaPOS *pos, nmeaINFO *info)
|
||||
{
|
||||
info->lat = nmea_radian2ndeg(pos->lat);
|
||||
info->lon = nmea_radian2ndeg(pos->lon);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "nmea/info.h"
|
||||
|
||||
void nmea_zero_INFO(nmeaINFO *info)
|
||||
{
|
||||
memset(info, 0, sizeof(nmeaINFO));
|
||||
info->sig = NMEA_SIG_BAD;
|
||||
info->fix = NMEA_FIX_BAD;
|
||||
}
|
|
@ -1,509 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file parse.h
|
||||
* \brief Functions of a low level for analysis of
|
||||
* packages of NMEA stream.
|
||||
*
|
||||
* \code
|
||||
* ...
|
||||
* ptype = nmea_pack_type(
|
||||
* (const char *)parser->buffer + nparsed + 1,
|
||||
* parser->buff_use - nparsed - 1);
|
||||
*
|
||||
* if(0 == (node = malloc(sizeof(nmeaParserNODE))))
|
||||
* goto mem_fail;
|
||||
*
|
||||
* node->pack = 0;
|
||||
*
|
||||
* switch(ptype)
|
||||
* {
|
||||
* case GPGGA:
|
||||
* if(0 == (node->pack = malloc(sizeof(nmeaGPGGA))))
|
||||
* goto mem_fail;
|
||||
* node->packType = GPGGA;
|
||||
* if(!nmea_parse_GPGGA(
|
||||
* (const char *)parser->buffer + nparsed,
|
||||
* sen_sz, (nmeaGPGGA *)node->pack))
|
||||
* {
|
||||
* free(node);
|
||||
* node = 0;
|
||||
* }
|
||||
* break;
|
||||
* case GPGSA:
|
||||
* if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
|
||||
* goto mem_fail;
|
||||
* node->packType = GPGSA;
|
||||
* if(!nmea_parse_GPGSA(
|
||||
* (const char *)parser->buffer + nparsed,
|
||||
* sen_sz, (nmeaGPGSA *)node->pack))
|
||||
* {
|
||||
* free(node);
|
||||
* node = 0;
|
||||
* }
|
||||
* break;
|
||||
* ...
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "nmea/tok.h"
|
||||
#include "nmea/parse.h"
|
||||
#include "nmea/context.h"
|
||||
#include "nmea/gmath.h"
|
||||
#include "nmea/units.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int _nmea_parse_time(const char *buff, int buff_sz, nmeaTIME *res)
|
||||
{
|
||||
int success = 0;
|
||||
|
||||
switch(buff_sz) {
|
||||
case sizeof("hhmmss") - 1:
|
||||
success = (3 == nmea_scanf(buff, buff_sz,
|
||||
"%2d%2d%2d",
|
||||
&(res->hour),
|
||||
&(res->min),
|
||||
&(res->sec)));
|
||||
break;
|
||||
|
||||
case sizeof("hhmmss.s") - 1:
|
||||
case sizeof("hhmmss.ss") - 1:
|
||||
case sizeof("hhmmss.sss") - 1:
|
||||
success = (4 == nmea_scanf(buff, buff_sz,
|
||||
"%2d%2d%2d.%d",
|
||||
&(res->hour),
|
||||
&(res->min),
|
||||
&(res->sec),
|
||||
&(res->hsec)));
|
||||
break;
|
||||
|
||||
default:
|
||||
nmea_error(NMEA_ERROR_PARSE_TIME);
|
||||
success = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return (success?0:-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Define packet type by header (nmeaPACKTYPE).
|
||||
* @param buff a constant character pointer of packet buffer.
|
||||
* @param buff_sz buffer size.
|
||||
* @return The defined packet type
|
||||
* @see nmeaPACKTYPE
|
||||
*/
|
||||
int nmea_pack_type(const char *buff, int buff_sz)
|
||||
{
|
||||
static const char *pheads[] = {
|
||||
"GPGGA",
|
||||
"GPGSA",
|
||||
"GPGSV",
|
||||
"GPRMC",
|
||||
"GPVTG",
|
||||
};
|
||||
|
||||
NMEA_ASSERT(buff);
|
||||
|
||||
if(buff_sz < 5) {
|
||||
return GPNON;
|
||||
|
||||
} else if(0 == memcmp(buff, pheads[0], 5)) {
|
||||
return GPGGA;
|
||||
|
||||
} else if(0 == memcmp(buff, pheads[1], 5)) {
|
||||
return GPGSA;
|
||||
|
||||
} else if(0 == memcmp(buff, pheads[2], 5)) {
|
||||
|
||||
return GPGSV;
|
||||
} else if(0 == memcmp(buff, pheads[3], 5)) {
|
||||
return GPRMC;
|
||||
|
||||
} else if(0 == memcmp(buff, pheads[4], 5)) {
|
||||
return GPVTG;
|
||||
}
|
||||
|
||||
return GPNON;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Find tail of packet ("\r\n") in buffer and check control sum (CRC).
|
||||
* @param buff a constant character pointer of packets buffer.
|
||||
* @param buff_sz buffer size.
|
||||
* @param res_crc a integer pointer for return CRC of packet (must be defined).
|
||||
* @return Number of bytes to packet tail.
|
||||
*/
|
||||
int nmea_find_tail(const char *buff, int buff_sz, int *res_crc)
|
||||
{
|
||||
static const int tail_sz = 3 /* *[CRC] */ + 2 /* \r\n */;
|
||||
|
||||
const char *end_buff = buff + buff_sz;
|
||||
int nread = 0;
|
||||
int crc = 0;
|
||||
|
||||
NMEA_ASSERT(buff && res_crc);
|
||||
|
||||
*res_crc = -1;
|
||||
|
||||
for(;buff < end_buff; ++buff, ++nread) {
|
||||
|
||||
if(('$' == *buff) && nread) {
|
||||
buff = 0;
|
||||
break;
|
||||
|
||||
} else if('*' == *buff) {
|
||||
|
||||
if(buff + tail_sz <= end_buff && '\r' == buff[3] && '\n' == buff[4]) {
|
||||
*res_crc = nmea_atoi(buff + 1, 2, 16);
|
||||
nread = buff_sz - (int)(end_buff - (buff + tail_sz));
|
||||
|
||||
if(*res_crc != crc) {
|
||||
*res_crc = -1;
|
||||
buff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
} else if(nread) {
|
||||
crc ^= (int)*buff;
|
||||
}
|
||||
}
|
||||
|
||||
if(*res_crc < 0 && buff) {
|
||||
nread = 0;
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse GGA packet from buffer.
|
||||
* @param buff a constant character pointer of packet buffer.
|
||||
* @param buff_sz buffer size.
|
||||
* @param pack a pointer of packet which will filled by function.
|
||||
* @return 1 (true) - if parsed successfully or 0 (false) - if fail.
|
||||
*/
|
||||
int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack)
|
||||
{
|
||||
char time_buff[NMEA_TIMEPARSE_BUF];
|
||||
|
||||
NMEA_ASSERT(buff && pack);
|
||||
|
||||
memset(pack, 0, sizeof(nmeaGPGGA));
|
||||
|
||||
if(14 != nmea_scanf(buff, buff_sz,
|
||||
"$GPGGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
|
||||
&(time_buff[0]),
|
||||
&(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
|
||||
&(pack->sig), &(pack->satinuse), &(pack->HDOP),
|
||||
&(pack->elv), &(pack->elv_units), &(pack->diff),
|
||||
&(pack->diff_units), &(pack->dgps_age), &(pack->dgps_sid)))
|
||||
{
|
||||
nmea_error(NMEA_ERROR_PARSE_GPGGA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc))) {
|
||||
nmea_error(NMEA_ERROR_PARSE_GPGAA_TIME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse GSA packet from buffer.
|
||||
* @param buff a constant character pointer of packet buffer.
|
||||
* @param buff_sz buffer size.
|
||||
* @param pack a pointer of packet which will filled by function.
|
||||
* @return 1 (true) - if parsed successfully or 0 (false) - if fail.
|
||||
*/
|
||||
int nmea_parse_GPGSA(const char *buff, int buff_sz, nmeaGPGSA *pack)
|
||||
{
|
||||
NMEA_ASSERT(buff && pack);
|
||||
|
||||
memset(pack, 0, sizeof(nmeaGPGSA));
|
||||
|
||||
if(17 != nmea_scanf(buff, buff_sz,
|
||||
"$GPGSA,%C,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f*",
|
||||
&(pack->fix_mode), &(pack->fix_type),
|
||||
&(pack->sat_prn[0]), &(pack->sat_prn[1]),
|
||||
&(pack->sat_prn[2]), &(pack->sat_prn[3]),
|
||||
&(pack->sat_prn[4]), &(pack->sat_prn[5]),
|
||||
&(pack->sat_prn[6]), &(pack->sat_prn[7]),
|
||||
&(pack->sat_prn[8]), &(pack->sat_prn[9]),
|
||||
&(pack->sat_prn[10]), &(pack->sat_prn[11]),
|
||||
&(pack->PDOP), &(pack->HDOP), &(pack->VDOP)))
|
||||
{
|
||||
nmea_error(NMEA_ERROR_PARSE_GPGSA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse GSV packet from buffer.
|
||||
* @param buff a constant character pointer of packet buffer.
|
||||
* @param buff_sz buffer size.
|
||||
* @param pack a pointer of packet which will filled by function.
|
||||
* @return 1 (true) - if parsed successfully or 0 (false) - if fail.
|
||||
*/
|
||||
int nmea_parse_GPGSV(const char *buff, int buff_sz, nmeaGPGSV *pack)
|
||||
{
|
||||
int nsen, nsat;
|
||||
|
||||
NMEA_ASSERT(buff && pack);
|
||||
|
||||
memset(pack, 0, sizeof(nmeaGPGSV));
|
||||
|
||||
nsen = nmea_scanf(buff, buff_sz,
|
||||
"$GPGSV,%d,%d,%d,"
|
||||
"%d,%d,%d,%d,"
|
||||
"%d,%d,%d,%d,"
|
||||
"%d,%d,%d,%d,"
|
||||
"%d,%d,%d,%d*",
|
||||
&(pack->pack_count), &(pack->pack_index), &(pack->sat_count),
|
||||
&(pack->sat_data[0].id), &(pack->sat_data[0].elv),
|
||||
&(pack->sat_data[0].azimuth), &(pack->sat_data[0].sig),
|
||||
&(pack->sat_data[1].id), &(pack->sat_data[1].elv),
|
||||
&(pack->sat_data[1].azimuth), &(pack->sat_data[1].sig),
|
||||
&(pack->sat_data[2].id), &(pack->sat_data[2].elv),
|
||||
&(pack->sat_data[2].azimuth), &(pack->sat_data[2].sig),
|
||||
&(pack->sat_data[3].id), &(pack->sat_data[3].elv),
|
||||
&(pack->sat_data[3].azimuth), &(pack->sat_data[3].sig));
|
||||
|
||||
nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
|
||||
nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
|
||||
nsat = nsat * 4 + 3 /* first three sentence`s */;
|
||||
|
||||
if(nsen < nsat || nsen > (NMEA_SATINPACK * 4 + 3)) {
|
||||
nmea_error(NMEA_ERROR_PARSE_GPGSV);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse RMC packet from buffer.
|
||||
* @param buff a constant character pointer of packet buffer.
|
||||
* @param buff_sz buffer size.
|
||||
* @param pack a pointer of packet which will filled by function.
|
||||
* @return 1 (true) - if parsed successfully or 0 (false) - if fail.
|
||||
*/
|
||||
int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack)
|
||||
{
|
||||
int nsen;
|
||||
char time_buff[NMEA_TIMEPARSE_BUF];
|
||||
|
||||
NMEA_ASSERT(buff && pack);
|
||||
|
||||
memset(pack, 0, sizeof(nmeaGPRMC));
|
||||
|
||||
nsen = nmea_scanf(buff, buff_sz,
|
||||
"$GPRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C*",
|
||||
&(time_buff[0]),
|
||||
&(pack->status),
|
||||
&(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
|
||||
&(pack->speed), &(pack->direction),
|
||||
&(pack->utc.day), &(pack->utc.mon), &(pack->utc.year),
|
||||
&(pack->declination), &(pack->declin_ew), &(pack->mode));
|
||||
|
||||
if(nsen != 13 && nsen != 14) {
|
||||
nmea_error(NMEA_ERROR_PARSE_GPRMC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc))) {
|
||||
nmea_error(NMEA_ERROR_PARSE_GPGAA_TIME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pack->utc.year < 90) {
|
||||
pack->utc.year += 100;
|
||||
}
|
||||
pack->utc.mon -= 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse VTG packet from buffer.
|
||||
* @param buff a constant character pointer of packet buffer.
|
||||
* @param buff_sz buffer size.
|
||||
* @param pack a pointer of packet which will filled by function.
|
||||
* @return 1 (true) - if parsed successfully or 0 (false) - if fail.
|
||||
*/
|
||||
int nmea_parse_GPVTG(const char *buff, int buff_sz, nmeaGPVTG *pack)
|
||||
{
|
||||
NMEA_ASSERT(buff && pack);
|
||||
|
||||
memset(pack, 0, sizeof(nmeaGPVTG));
|
||||
|
||||
if(8 != nmea_scanf(buff, buff_sz,
|
||||
"$GPVTG,%f,%C,%f,%C,%f,%C,%f,%C*",
|
||||
&(pack->dir), &(pack->dir_t),
|
||||
&(pack->dec), &(pack->dec_m),
|
||||
&(pack->spn), &(pack->spn_n),
|
||||
&(pack->spk), &(pack->spk_k))) {
|
||||
nmea_error(NMEA_ERROR_PARSE_GPVTG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( pack->dir_t != 'T' ||
|
||||
pack->dec_m != 'M' ||
|
||||
pack->spn_n != 'N' ||
|
||||
pack->spk_k != 'K') {
|
||||
nmea_error(NMEA_ERROR_PARSE_GPVTG_FORMAT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Fill nmeaINFO structure by GGA packet data.
|
||||
* @param pack a pointer of packet structure.
|
||||
* @param info a pointer of summary information structure.
|
||||
*/
|
||||
void nmea_GPGGA2info(nmeaGPGGA *pack, nmeaINFO *info)
|
||||
{
|
||||
NMEA_ASSERT(pack && info);
|
||||
|
||||
info->utc.hour = pack->utc.hour;
|
||||
info->utc.min = pack->utc.min;
|
||||
info->utc.sec = pack->utc.sec;
|
||||
info->utc.hsec = pack->utc.hsec;
|
||||
info->sig = pack->sig;
|
||||
info->HDOP = pack->HDOP;
|
||||
info->elv = pack->elv;
|
||||
info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
|
||||
info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
|
||||
info->smask |= GPGGA;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Fill nmeaINFO structure by GSA packet data.
|
||||
* @param pack a pointer of packet structure.
|
||||
* @param info a pointer of summary information structure.
|
||||
*/
|
||||
void nmea_GPGSA2info(nmeaGPGSA *pack, nmeaINFO *info)
|
||||
{
|
||||
int i, j, nuse = 0;
|
||||
|
||||
NMEA_ASSERT(pack && info);
|
||||
|
||||
info->fix = pack->fix_type;
|
||||
info->PDOP = pack->PDOP;
|
||||
info->HDOP = pack->HDOP;
|
||||
info->VDOP = pack->VDOP;
|
||||
|
||||
for(i = 0; i < NMEA_MAXSAT; ++i) {
|
||||
for(j = 0; j < info->satinfo.inview; ++j) {
|
||||
if(pack->sat_prn[i] && pack->sat_prn[i] == info->satinfo.sat[j].id) {
|
||||
info->satinfo.sat[j].in_use = 1;
|
||||
nuse++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info->satinfo.inuse = nuse;
|
||||
info->smask |= GPGSA;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Fill nmeaINFO structure by GSV packet data.
|
||||
* @param pack a pointer of packet structure.
|
||||
* @param info a pointer of summary information structure.
|
||||
*/
|
||||
void nmea_GPGSV2info(nmeaGPGSV *pack, nmeaINFO *info)
|
||||
{
|
||||
int isat, isi, nsat;
|
||||
|
||||
NMEA_ASSERT(pack && info);
|
||||
|
||||
if(pack->pack_index > pack->pack_count ||
|
||||
pack->pack_index * NMEA_SATINPACK > NMEA_MAXSAT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(pack->pack_index < 1) {
|
||||
pack->pack_index = 1;
|
||||
}
|
||||
|
||||
info->satinfo.inview = pack->sat_count;
|
||||
|
||||
nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
|
||||
nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
|
||||
|
||||
for(isat = 0; isat < nsat; ++isat) {
|
||||
isi = (pack->pack_index - 1) * NMEA_SATINPACK + isat;
|
||||
info->satinfo.sat[isi].id = pack->sat_data[isat].id;
|
||||
info->satinfo.sat[isi].elv = pack->sat_data[isat].elv;
|
||||
info->satinfo.sat[isi].azimuth = pack->sat_data[isat].azimuth;
|
||||
info->satinfo.sat[isi].sig = pack->sat_data[isat].sig;
|
||||
}
|
||||
|
||||
info->smask |= GPGSV;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Fill nmeaINFO structure by RMC packet data.
|
||||
* @param pack a pointer of packet structure.
|
||||
* @param info a pointer of summary information structure.
|
||||
*/
|
||||
void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info)
|
||||
{
|
||||
NMEA_ASSERT(pack && info);
|
||||
|
||||
if('A' == pack->status) {
|
||||
if(NMEA_SIG_BAD == info->sig) {
|
||||
info->sig = NMEA_SIG_MID;
|
||||
}
|
||||
|
||||
if(NMEA_FIX_BAD == info->fix) {
|
||||
info->fix = NMEA_FIX_2D;
|
||||
}
|
||||
} else if('V' == pack->status) {
|
||||
|
||||
info->sig = NMEA_SIG_BAD;
|
||||
info->fix = NMEA_FIX_BAD;
|
||||
}
|
||||
|
||||
info->utc = pack->utc;
|
||||
info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
|
||||
info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
|
||||
info->speed = pack->speed * NMEA_TUD_KNOTS;
|
||||
info->direction = pack->direction;
|
||||
info->smask |= GPRMC;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Fill nmeaINFO structure by VTG packet data.
|
||||
* @param pack a pointer of packet structure.
|
||||
* @param info a pointer of summary information structure.
|
||||
*/
|
||||
void nmea_GPVTG2info(nmeaGPVTG *pack, nmeaINFO *info)
|
||||
{
|
||||
NMEA_ASSERT(pack && info);
|
||||
|
||||
info->direction = pack->dir;
|
||||
info->declination = pack->dec;
|
||||
info->speed = pack->spk;
|
||||
info->smask |= GPVTG;
|
||||
}
|
|
@ -1,392 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nmea/tok.h"
|
||||
#include "nmea/parse.h"
|
||||
#include "nmea/parser.h"
|
||||
#include "nmea/context.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct _nmeaParserNODE
|
||||
{
|
||||
int packType;
|
||||
void *pack;
|
||||
struct _nmeaParserNODE *next_node;
|
||||
|
||||
} nmeaParserNODE;
|
||||
|
||||
/*
|
||||
* high level
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Initialization of parser object
|
||||
* @return true (1) - success or false (0) - fail
|
||||
*/
|
||||
int nmea_parser_init(nmeaPARSER *parser)
|
||||
{
|
||||
int resv = 0;
|
||||
int buff_size = nmea_property()->parse_buff_size;
|
||||
|
||||
NMEA_ASSERT(parser);
|
||||
|
||||
memset(parser, 0, sizeof(nmeaPARSER));
|
||||
|
||||
parser->buff_size = buff_size;
|
||||
resv = 1;
|
||||
|
||||
return resv;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Destroy parser object
|
||||
*/
|
||||
void nmea_parser_destroy(nmeaPARSER *parser)
|
||||
{
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
nmea_parser_queue_clear(parser);
|
||||
memset(parser, 0, sizeof(nmeaPARSER));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Analysis of buffer and put results to information structure
|
||||
* @return Number of packets wos parsed
|
||||
*/
|
||||
int nmea_parse(nmeaPARSER *parser,
|
||||
const char *buff, int buff_sz,
|
||||
nmeaINFO *info) {
|
||||
int ptype, nread = 0;
|
||||
void *pack = 0;
|
||||
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
|
||||
nmea_parser_push(parser, buff, buff_sz);
|
||||
|
||||
while(GPNON != (ptype = nmea_parser_pop(parser, &pack))) {
|
||||
nread++;
|
||||
|
||||
switch(ptype) {
|
||||
case GPGGA:
|
||||
nmea_GPGGA2info((nmeaGPGGA*)pack, info);
|
||||
break;
|
||||
case GPGSA:
|
||||
nmea_GPGSA2info((nmeaGPGSA*)pack, info);
|
||||
break;
|
||||
case GPGSV:
|
||||
nmea_GPGSV2info((nmeaGPGSV*)pack, info);
|
||||
break;
|
||||
case GPRMC:
|
||||
nmea_GPRMC2info((nmeaGPRMC*)pack, info);
|
||||
break;
|
||||
case GPVTG:
|
||||
nmea_GPVTG2info((nmeaGPVTG*)pack, info);
|
||||
break;
|
||||
};
|
||||
|
||||
free(pack);
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
/*
|
||||
* low level
|
||||
*/
|
||||
|
||||
int nmea_parser_real_push(nmeaPARSER *parser, const char *buff, int buff_sz)
|
||||
{
|
||||
int nparsed = 0, crc, sen_sz, ptype;
|
||||
nmeaParserNODE *node = 0;
|
||||
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
|
||||
/* add */
|
||||
if(parser->buff_use + buff_sz >= parser->buff_size) {
|
||||
nmea_parser_buff_clear(parser);
|
||||
}
|
||||
|
||||
memcpy(parser->buffer + parser->buff_use, buff, buff_sz);
|
||||
parser->buff_use += buff_sz;
|
||||
|
||||
/* parse */
|
||||
for(;;node = 0) {
|
||||
sen_sz = nmea_find_tail(
|
||||
(const char *)parser->buffer + nparsed,
|
||||
(int)parser->buff_use - nparsed, &crc);
|
||||
|
||||
if(!sen_sz) {
|
||||
if(nparsed) {
|
||||
memcpy(
|
||||
parser->buffer,
|
||||
parser->buffer + nparsed,
|
||||
parser->buff_use -= nparsed);
|
||||
break;
|
||||
}
|
||||
} else if(crc >= 0) {
|
||||
ptype = nmea_pack_type(
|
||||
(const char *)parser->buffer + nparsed + 1,
|
||||
parser->buff_use - nparsed - 1);
|
||||
|
||||
if(0 == (node = malloc(sizeof(nmeaParserNODE)))) {
|
||||
goto mem_fail;
|
||||
}
|
||||
|
||||
node->pack = 0;
|
||||
|
||||
switch(ptype) {
|
||||
case GPGGA:
|
||||
if(0 == (node->pack = malloc(sizeof(nmeaGPGGA)))) {
|
||||
goto mem_fail;
|
||||
}
|
||||
node->packType = GPGGA;
|
||||
if(!nmea_parse_GPGGA(
|
||||
(const char *)parser->buffer + nparsed,
|
||||
sen_sz, (nmeaGPGGA *)node->pack)) {
|
||||
free(node);
|
||||
node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GPGSA:
|
||||
if(0 == (node->pack = malloc(sizeof(nmeaGPGSA)))) {
|
||||
goto mem_fail;
|
||||
}
|
||||
node->packType = GPGSA;
|
||||
if(!nmea_parse_GPGSA(
|
||||
(const char *)parser->buffer + nparsed,
|
||||
sen_sz, (nmeaGPGSA *)node->pack)) {
|
||||
free(node);
|
||||
node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GPGSV:
|
||||
if(0 == (node->pack = malloc(sizeof(nmeaGPGSV)))) {
|
||||
goto mem_fail;
|
||||
}
|
||||
node->packType = GPGSV;
|
||||
if(!nmea_parse_GPGSV(
|
||||
(const char *)parser->buffer + nparsed,
|
||||
sen_sz, (nmeaGPGSV *)node->pack)) {
|
||||
free(node);
|
||||
node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GPRMC:
|
||||
if(0 == (node->pack = malloc(sizeof(nmeaGPRMC)))) {
|
||||
goto mem_fail;
|
||||
}
|
||||
node->packType = GPRMC;
|
||||
if(!nmea_parse_GPRMC(
|
||||
(const char *)parser->buffer + nparsed,
|
||||
sen_sz, (nmeaGPRMC *)node->pack)) {
|
||||
free(node);
|
||||
node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GPVTG:
|
||||
if(0 == (node->pack = malloc(sizeof(nmeaGPVTG)))) {
|
||||
goto mem_fail;
|
||||
}
|
||||
node->packType = GPVTG;
|
||||
if(!nmea_parse_GPVTG(
|
||||
(const char *)parser->buffer + nparsed,
|
||||
sen_sz, (nmeaGPVTG *)node->pack)) {
|
||||
free(node);
|
||||
node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
free(node);
|
||||
node = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(node) {
|
||||
if(parser->end_node) {
|
||||
((nmeaParserNODE *)parser->end_node)->next_node = node;
|
||||
}
|
||||
parser->end_node = node;
|
||||
|
||||
if(!parser->top_node) {
|
||||
parser->top_node = node;
|
||||
}
|
||||
node->next_node = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nparsed += sen_sz;
|
||||
}
|
||||
|
||||
return nparsed;
|
||||
|
||||
mem_fail:
|
||||
if(node) {
|
||||
free(node);
|
||||
}
|
||||
|
||||
nmea_error(NMEA_ERROR_MEMORY);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Analysis of buffer and keep results into parser
|
||||
* @return Number of bytes wos parsed from buffer
|
||||
*/
|
||||
int nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz)
|
||||
{
|
||||
int nparse, nparsed = 0;
|
||||
|
||||
do {
|
||||
if(buff_sz > parser->buff_size) {
|
||||
nparse = parser->buff_size;
|
||||
} else {
|
||||
nparse = buff_sz;
|
||||
}
|
||||
|
||||
nparsed += nmea_parser_real_push(parser, buff, nparse);
|
||||
|
||||
buff_sz -= nparse;
|
||||
|
||||
} while(buff_sz);
|
||||
|
||||
return nparsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get type of top packet keeped into parser
|
||||
* @return Type of packet
|
||||
* @see nmeaPACKTYPE
|
||||
*/
|
||||
int nmea_parser_top(nmeaPARSER *parser)
|
||||
{
|
||||
int retval = GPNON;
|
||||
nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
|
||||
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
|
||||
if(node) {
|
||||
retval = node->packType;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Withdraw top packet from parser
|
||||
* @return Received packet type
|
||||
* @see nmeaPACKTYPE
|
||||
*/
|
||||
int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr)
|
||||
{
|
||||
int retval = GPNON;
|
||||
nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
|
||||
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
|
||||
if(node) {
|
||||
*pack_ptr = node->pack;
|
||||
retval = node->packType;
|
||||
parser->top_node = node->next_node;
|
||||
|
||||
if(!parser->top_node) {
|
||||
parser->end_node = 0;
|
||||
}
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get top packet from parser without withdraw
|
||||
* @return Received packet type
|
||||
* @see nmeaPACKTYPE
|
||||
*/
|
||||
int nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr)
|
||||
{
|
||||
int retval = GPNON;
|
||||
nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
|
||||
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
|
||||
if(node) {
|
||||
*pack_ptr = node->pack;
|
||||
retval = node->packType;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Delete top packet from parser
|
||||
* @return Deleted packet type
|
||||
* @see nmeaPACKTYPE
|
||||
*/
|
||||
int nmea_parser_drop(nmeaPARSER *parser)
|
||||
{
|
||||
int retval = GPNON;
|
||||
nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
|
||||
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
|
||||
if(node) {
|
||||
if(node->pack) {
|
||||
free(node->pack);
|
||||
}
|
||||
|
||||
retval = node->packType;
|
||||
parser->top_node = node->next_node;
|
||||
if(!parser->top_node) {
|
||||
parser->end_node = 0;
|
||||
}
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear cache of parser
|
||||
* @return true (1) - success
|
||||
*/
|
||||
int nmea_parser_buff_clear(nmeaPARSER *parser)
|
||||
{
|
||||
NMEA_ASSERT(parser && parser->buffer);
|
||||
|
||||
parser->buff_use = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear packets queue into parser
|
||||
* @return true (1) - success
|
||||
*/
|
||||
int nmea_parser_queue_clear(nmeaPARSER *parser)
|
||||
{
|
||||
NMEA_ASSERT(parser);
|
||||
|
||||
while(parser->top_node) {
|
||||
nmea_parser_drop(parser);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nmea/sentence.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void nmea_zero_GPGGA(nmeaGPGGA *pack)
|
||||
{
|
||||
memset(pack, 0, sizeof(nmeaGPGGA));
|
||||
pack->ns = 'N';
|
||||
pack->ew = 'E';
|
||||
pack->elv_units = 'M';
|
||||
pack->diff_units = 'M';
|
||||
}
|
||||
|
||||
void nmea_zero_GPGSA(nmeaGPGSA *pack)
|
||||
{
|
||||
memset(pack, 0, sizeof(nmeaGPGSA));
|
||||
pack->fix_mode = 'A';
|
||||
pack->fix_type = NMEA_FIX_BAD;
|
||||
}
|
||||
|
||||
void nmea_zero_GPGSV(nmeaGPGSV *pack)
|
||||
{
|
||||
memset(pack, 0, sizeof(nmeaGPGSV));
|
||||
}
|
||||
|
||||
void nmea_zero_GPRMC(nmeaGPRMC *pack)
|
||||
{
|
||||
memset(pack, 0, sizeof(nmeaGPRMC));
|
||||
pack->status = 'V';
|
||||
pack->ns = 'N';
|
||||
pack->ew = 'E';
|
||||
pack->declin_ew = 'E';
|
||||
}
|
||||
|
||||
void nmea_zero_GPVTG(nmeaGPVTG *pack)
|
||||
{
|
||||
memset(pack, 0, sizeof(nmeaGPVTG));
|
||||
pack->dir_t = 'T';
|
||||
pack->dec_m = 'M';
|
||||
pack->spn_n = 'N';
|
||||
pack->spk_k = 'K';
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* NMEA library
|
||||
* URL: http://nmea.sourceforge.net
|
||||
* Author: Tim (xtimor@gmail.com)
|
||||
* Licence: http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
* Modified for the Bristol Longshot program
|
||||
* URL:
|
||||
* Author: Richard Meadows 2014
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nmea/tok.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define NMEA_TOKS_COMPARE (1)
|
||||
#define NMEA_TOKS_PERCENT (2)
|
||||
#define NMEA_TOKS_WIDTH (3)
|
||||
#define NMEA_TOKS_TYPE (4)
|
||||
|
||||
/**
|
||||
* \brief Calculate control sum of binary buffer
|
||||
*/
|
||||
int nmea_calc_crc(const char *buff, int buff_sz)
|
||||
{
|
||||
int chsum = 0, it;
|
||||
|
||||
for(it = 0; it < buff_sz; ++it) {
|
||||
chsum ^= (int)buff[it];
|
||||
}
|
||||
|
||||
return chsum;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert string to number
|
||||
*/
|
||||
int nmea_atoi(const char *str, int str_sz, int radix)
|
||||
{
|
||||
char *tmp_ptr;
|
||||
char buff[NMEA_CONVSTR_BUF];
|
||||
int res = 0;
|
||||
|
||||
if(str_sz < NMEA_CONVSTR_BUF) {
|
||||
memcpy(&buff[0], str, str_sz);
|
||||
buff[str_sz] = '\0';
|
||||
res = strtol(&buff[0], &tmp_ptr, radix);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert string to fraction number
|
||||
*/
|
||||
double nmea_atof(const char *str, int str_sz)
|
||||
{
|
||||
char *tmp_ptr;
|
||||
char buff[NMEA_CONVSTR_BUF];
|
||||
double res = 0;
|
||||
|
||||
if(str_sz < NMEA_CONVSTR_BUF) {
|
||||
memcpy(&buff[0], str, str_sz);
|
||||
buff[str_sz] = '\0';
|
||||
res = strtod(&buff[0], &tmp_ptr);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Formating string (like standart printf) with CRC tail (*CRC)
|
||||
*/
|
||||
int nmea_printf(char *buff, int buff_sz, const char *format, ...)
|
||||
{
|
||||
int retval, add = 0;
|
||||
va_list arg_ptr;
|
||||
|
||||
if(buff_sz <= 0)
|
||||
return 0;
|
||||
|
||||
va_start(arg_ptr, format);
|
||||
|
||||
retval = NMEA_POSIX(vsnprintf)(buff, buff_sz, format, arg_ptr);
|
||||
|
||||
if(retval > 0) {
|
||||
add = NMEA_POSIX(snprintf)(
|
||||
buff + retval, buff_sz - retval, "*%02x\r\n",
|
||||
nmea_calc_crc(buff + 1, retval - 1));
|
||||
}
|
||||
|
||||
retval += add;
|
||||
|
||||
if(retval < 0 || retval > buff_sz) {
|
||||
memset(buff, ' ', buff_sz);
|
||||
retval = buff_sz;
|
||||
}
|
||||
|
||||
va_end(arg_ptr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Analyse string (specificate for NMEA sentences)
|
||||
*/
|
||||
int nmea_scanf(const char *buff, int buff_sz, const char *format, ...)
|
||||
{
|
||||
const char *beg_tok;
|
||||
const char *end_buf = buff + buff_sz;
|
||||
|
||||
va_list arg_ptr;
|
||||
int tok_type = NMEA_TOKS_COMPARE;
|
||||
int width = 0;
|
||||
const char *beg_fmt = 0;
|
||||
int snum = 0, unum = 0;
|
||||
|
||||
int tok_count = 0;
|
||||
void *parg_target;
|
||||
|
||||
va_start(arg_ptr, format);
|
||||
|
||||
for(; *format && buff < end_buf; ++format) {
|
||||
switch(tok_type) {
|
||||
case NMEA_TOKS_COMPARE:
|
||||
if('%' == *format) {
|
||||
tok_type = NMEA_TOKS_PERCENT;
|
||||
} else if(*buff++ != *format) {
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case NMEA_TOKS_PERCENT:
|
||||
width = 0;
|
||||
beg_fmt = format;
|
||||
tok_type = NMEA_TOKS_WIDTH;
|
||||
case NMEA_TOKS_WIDTH:
|
||||
if(isdigit(*format)) {
|
||||
break;
|
||||
}
|
||||
|
||||
tok_type = NMEA_TOKS_TYPE;
|
||||
if(format > beg_fmt) {
|
||||
width = nmea_atoi(beg_fmt, (int)(format - beg_fmt), 10);
|
||||
}
|
||||
case NMEA_TOKS_TYPE:
|
||||
beg_tok = buff;
|
||||
|
||||
if(!width && ('c' == *format || 'C' == *format) && *buff != format[1])
|
||||
width = 1;
|
||||
|
||||
if(width) {
|
||||
if(buff + width <= end_buf) {
|
||||
buff += width;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if(!format[1] || (0 == (buff = (char *)memchr(buff, format[1], end_buf - buff)))) {
|
||||
buff = end_buf;
|
||||
}
|
||||
}
|
||||
|
||||
if(buff > end_buf) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tok_type = NMEA_TOKS_COMPARE;
|
||||
tok_count++;
|
||||
|
||||
parg_target = 0; width = (int)(buff - beg_tok);
|
||||
|
||||
switch(*format) {
|
||||
case 'c':
|
||||
case 'C':
|
||||
parg_target = (void *)va_arg(arg_ptr, char *);
|
||||
if(width && 0 != (parg_target))
|
||||
*((char *)parg_target) = *beg_tok;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
parg_target = (void *)va_arg(arg_ptr, char *);
|
||||
if(width && 0 != (parg_target))
|
||||
{
|
||||
memcpy(parg_target, beg_tok, width);
|
||||
((char *)parg_target)[width] = '\0';
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'e':
|
||||
case 'E':
|
||||
parg_target = (void *)va_arg(arg_ptr, double *);
|
||||
if(width && 0 != (parg_target))
|
||||
*((double *)parg_target) = nmea_atof(beg_tok, width);
|
||||
break;
|
||||
};
|
||||
|
||||
if(parg_target) {
|
||||
break;
|
||||
}
|
||||
if(0 == (parg_target = (void *)va_arg(arg_ptr, int *))) {
|
||||
break;
|
||||
}
|
||||
if(!width) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(*format) {
|
||||
case 'd':
|
||||
case 'i':
|
||||
snum = nmea_atoi(beg_tok, width, 10);
|
||||
memcpy(parg_target, &snum, sizeof(int));
|
||||
break;
|
||||
case 'u':
|
||||
unum = nmea_atoi(beg_tok, width, 10);
|
||||
memcpy(parg_target, &unum, sizeof(unsigned int));
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
unum = nmea_atoi(beg_tok, width, 16);
|
||||
memcpy(parg_target, &unum, sizeof(unsigned int));
|
||||
break;
|
||||
case 'o':
|
||||
unum = nmea_atoi(beg_tok, width, 8);
|
||||
memcpy(parg_target, &unum, sizeof(unsigned int));
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
|
||||
va_end(arg_ptr);
|
||||
|
||||
return tok_count;
|
||||
}
|
|
@ -34,40 +34,6 @@
|
|||
|
||||
#endif
|
||||
|
||||
/****************************//* nmea_decode_tc *//****************************/
|
||||
|
||||
/* Includes */
|
||||
#include <nmea/nmea.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Parameters in */
|
||||
struct nmea_tc_params {
|
||||
char buff[2048];
|
||||
} nmea_tc_params;
|
||||
|
||||
/* Results out */
|
||||
nmeaINFO nmea_tc_results;
|
||||
|
||||
/* Function */
|
||||
__verification__ void nmea_tc(void) {
|
||||
|
||||
nmeaPARSER parser;
|
||||
int size;
|
||||
|
||||
/* Get input buffer size */
|
||||
size = strlen(nmea_tc_params.buff);
|
||||
|
||||
/* Init nmea */
|
||||
nmea_zero_INFO(&nmea_tc_results);
|
||||
nmea_parser_init(&parser);
|
||||
|
||||
/* Parse */
|
||||
nmea_parse(&parser, nmea_tc_params.buff, size, &nmea_tc_results);
|
||||
|
||||
/* Cleanup */
|
||||
nmea_parser_destroy(&parser);
|
||||
}
|
||||
|
||||
/****************************//* times_two_tc *//****************************/
|
||||
/* The simplest test case. ever. Used to check for sanity */
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue