@@ -1,48 +1,48 | |||||
1 | /* |
|
1 | /* | |
2 | * nemeaCode.cpp |
|
2 | * nemeaCode.cpp | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #include "nmeaCode.h" |
|
8 | #include "nmeaCode.h" | |
9 |
|
9 | |||
10 | #include <string.h> |
|
10 | #include <string.h> | |
11 | #include <stdarg.h> |
|
11 | #include <stdarg.h> | |
12 | #include <stdio.h> |
|
12 | #include <stdio.h> | |
13 | #include <time.h> |
|
13 | #include <time.h> | |
14 | #include <math.h> |
|
14 | #include <math.h> | |
15 | #include <float.h> |
|
15 | #include <float.h> | |
16 | #include <limits.h> |
|
16 | #include <limits.h> | |
17 | #include <ctype.h> |
|
17 | #include <ctype.h> | |
18 | #include <stdlib.h> |
|
18 | #include <stdlib.h> | |
19 |
|
19 | |||
20 | nmeaCode::nmeaCode(char* name=nullptr): |
|
20 | nmeaCode::nmeaCode(char* name=nullptr): | |
21 | codebuff(nullptr){ |
|
21 | codebuff(nullptr){ | |
22 |
|
22 | |||
23 | } |
|
23 | } | |
24 |
|
24 | |||
25 | nmeaCode::~nmeaCode() { |
|
25 | nmeaCode::~nmeaCode() { | |
26 | // TODO Auto-generated destructor stub |
|
26 | // TODO Auto-generated destructor stub | |
27 | } |
|
27 | } | |
28 |
|
28 | |||
29 | virtual void nmeaCode::code_init() { |
|
|||
30 |
|
29 | |||
31 | } |
|
30 | bool nmeaCode::nmea_code_set(const char* cd) { | |
32 | virtual int nmeaCode::code_gen(char *buff, int buff_sz) { |
|
31 | size_t sz = strlen(cd); | |
33 | return 0; |
|
32 | codebuff = new char[sz]; | |
|
33 | strcpy(codebuff, cd); | |||
|
34 | return true; | |||
34 | } |
|
35 | } | |
35 |
|
36 | |||
36 | virtual int nmeaCode::code_parse(const char *buff, int buff_sz) { |
|
37 | bool nmeaCode::nmea_code_get(char* cd) { | |
37 |
return |
|
38 | return true; | |
38 | } |
|
39 | } | |
39 |
|
||||
40 |
|
40 | |||
41 | //////////////////////////////////////////////////////////////////////////////////////// |
|
41 | //////////////////////////////////////////////////////////////////////////////////////// | |
42 |
|
42 | |||
43 |
|
43 | |||
44 |
|
44 | |||
45 |
|
45 | |||
46 |
|
46 | |||
47 |
|
47 | |||
48 |
|
48 |
@@ -1,32 +1,29 | |||||
1 | /* |
|
1 | /* | |
2 | * nemeaCode.h |
|
2 | * nemeaCode.h | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #ifndef NMEALIB_NMEALIB___NMEACODE_H_ |
|
8 | #ifndef NMEALIB_NMEALIB___NMEACODE_H_ | |
9 | #define NMEALIB_NMEALIB___NMEACODE_H_ |
|
9 | #define NMEALIB_NMEALIB___NMEACODE_H_ | |
10 |
|
10 | |||
11 | #include "nmea_defs.h" |
|
11 | #include "nmea_defs.h" | |
12 |
|
12 | |||
13 | class nmeaCode { |
|
13 | class nmeaCode { | |
14 | public: |
|
14 | public: | |
15 | nmeaCode(char* name=nullptr); |
|
15 | nmeaCode(char* name=nullptr); | |
16 | virtual ~nmeaCode(); |
|
16 | virtual ~nmeaCode(); | |
17 |
|
17 | |||
18 | virtual void code_init(void); |
|
18 | bool nmea_code_set(const char* cd); | |
19 | virtual int code_gen(char *buff, int buff_sz);// TODO para generator |
|
19 | bool nmea_code_get(char* cd); | |
20 | virtual int code_parse(const char *buff, int buff_sz);// TODO para parser |
|
|||
21 |
|
||||
22 |
|
||||
23 |
|
||||
24 |
|
20 | |||
25 | private: |
|
21 | private: | |
|
22 | size_t size; | |||
26 | const char codename[8]; |
|
23 | const char codename[8]; | |
27 | const int type; |
|
24 | const int type; | |
28 | char *codebuff; |
|
25 | char *codebuff; | |
29 |
|
26 | |||
30 | }; |
|
27 | }; | |
31 |
|
28 | |||
32 | #endif /* NMEALIB_NMEALIB___NMEACODE_H_ */ |
|
29 | #endif /* NMEALIB_NMEALIB___NMEACODE_H_ */ |
@@ -1,194 +1,194 | |||||
1 | /* |
|
1 | /* | |
2 | * nmeaGenerator.cpp |
|
2 | * nmeaGenerator.cpp | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #include <string.h> |
|
8 | #include <string.h> | |
9 | #include <stdlib.h> |
|
9 | #include <stdlib.h> | |
10 | #include "nmeaGenerator.h" |
|
10 | #include "nmeaGenerator.h" | |
11 |
|
11 | |||
12 |
|
12 | |||
13 | nmeaGenerator::nmeaGenerator() { |
|
13 | nmeaGenerator::nmeaGenerator() { | |
14 | // TODO Auto-generated constructor stub |
|
14 | // TODO Auto-generated constructor stub | |
15 |
|
15 | |||
16 | } |
|
16 | } | |
17 |
|
17 | |||
18 | nmeaGenerator::~nmeaGenerator() { |
|
18 | nmeaGenerator::~nmeaGenerator() { | |
19 | // TODO Auto-generated destructor stub |
|
19 | // TODO Auto-generated destructor stub | |
20 | } |
|
20 | } | |
21 |
|
21 | |||
22 |
|
22 | |||
23 |
virtual int nmeaGenerator:: |
|
23 | virtual int nmeaGenerator::nmea_gen_info2code(const nmeaInfo *info, nmeaCode* code) | |
24 | { |
|
24 | { | |
25 | return 1; |
|
25 | return 1; | |
26 | } |
|
26 | } | |
27 |
|
27 | |||
28 |
|
28 | |||
29 | /* |
|
29 | /* | |
30 | * low level |
|
30 | * low level | |
31 | */ |
|
31 | */ | |
32 |
|
32 | |||
33 | int nmeaGenerator::nmea_gen_init(nmeaInfo *info) |
|
33 | int nmeaGenerator::nmea_gen_init(nmeaInfo *info) | |
34 | { |
|
34 | { | |
35 | int RetVal = 1; int smask = info->smask; |
|
35 | int RetVal = 1; int smask = info->smask; | |
36 |
|
36 | |||
37 |
info-> |
|
37 | info->nmea_info_init_INFO(); | |
38 | info->smask = smask; |
|
38 | info->smask = smask; | |
39 |
|
39 | |||
40 | info->lat = NMEA_DEF_LAT; |
|
40 | info->lat = NMEA_DEF_LAT; | |
41 | info->lon = NMEA_DEF_LON; |
|
41 | info->lon = NMEA_DEF_LON; | |
42 |
|
42 | |||
43 | if(init_call) |
|
43 | if(init_call) | |
44 | RetVal = (*init_call)(this, info); |
|
44 | RetVal = (*init_call)(this, info); | |
45 |
|
45 | |||
46 | if(RetVal && next) |
|
46 | if(RetVal && next) | |
47 | RetVal = next->nmea_gen_init(info); |
|
47 | RetVal = next->nmea_gen_init(info); | |
48 |
|
48 | |||
49 | return RetVal; |
|
49 | return RetVal; | |
50 | } |
|
50 | } | |
51 |
|
51 | |||
52 | int nmeaGenerator::nmea_gen_loop( nmeaInfo *info) |
|
52 | int nmeaGenerator::nmea_gen_loop( nmeaInfo *info) | |
53 | { |
|
53 | { | |
54 | int RetVal = 1; |
|
54 | int RetVal = 1; | |
55 |
|
55 | |||
56 | if(loop_call) |
|
56 | if(loop_call) | |
57 | RetVal = (*loop_call)(this, info); |
|
57 | RetVal = (*loop_call)(this, info); | |
58 |
|
58 | |||
59 | if(RetVal && next) |
|
59 | if(RetVal && next) | |
60 | RetVal = next->nmea_gen_loop(info); |
|
60 | RetVal = next->nmea_gen_loop(info); | |
61 |
|
61 | |||
62 | return RetVal; |
|
62 | return RetVal; | |
63 | } |
|
63 | } | |
64 |
|
64 | |||
65 | int nmeaGenerator::nmea_gen_reset(nmeaInfo *info) |
|
65 | int nmeaGenerator::nmea_gen_reset(nmeaInfo *info) | |
66 | { |
|
66 | { | |
67 | int RetVal = 1; |
|
67 | int RetVal = 1; | |
68 |
|
68 | |||
69 | if(reset_call) |
|
69 | if(reset_call) | |
70 | RetVal = (*reset_call)(this, info); |
|
70 | RetVal = (*reset_call)(this, info); | |
71 |
|
71 | |||
72 | return RetVal; |
|
72 | return RetVal; | |
73 | } |
|
73 | } | |
74 |
|
74 | |||
75 | void nmeaGenerator::nmea_gen_destroy() |
|
75 | void nmeaGenerator::nmea_gen_destroy() | |
76 | { |
|
76 | { | |
77 | if(next) |
|
77 | if(next) | |
78 | { |
|
78 | { | |
79 | next->nmea_gen_destroy(); |
|
79 | next->nmea_gen_destroy(); | |
80 | next = 0; |
|
80 | next = 0; | |
81 | } |
|
81 | } | |
82 |
|
82 | |||
83 | if(destroy_call) |
|
83 | if(destroy_call) | |
84 | (*destroy_call)(this); |
|
84 | (*destroy_call)(this); | |
85 |
|
85 | |||
86 | free(this); |
|
86 | free(this); | |
87 | } |
|
87 | } | |
88 |
|
88 | |||
89 | void nmeaGenerator::nmea_gen_add(nmeaGenerator *gen) |
|
89 | void nmeaGenerator::nmea_gen_add(nmeaGenerator *gen) | |
90 | { |
|
90 | { | |
91 | if(next) |
|
91 | if(next) | |
92 | next->nmea_gen_add(gen); |
|
92 | next->nmea_gen_add(gen); | |
93 | else |
|
93 | else | |
94 | next = gen; |
|
94 | next = gen; | |
95 | } |
|
95 | } | |
96 |
|
96 | |||
97 | int nmeaGenerator::nmea_generate_from( |
|
97 | int nmeaGenerator::nmea_generate_from( | |
98 | char *buff, int buff_sz, |
|
98 | char *buff, int buff_sz, | |
99 | nmeaInfo *info, |
|
99 | nmeaInfo *info, | |
100 | nmeaCode *code |
|
100 | nmeaCode *code | |
101 | ) |
|
101 | ) | |
102 | { |
|
102 | { | |
103 | int retval; |
|
103 | int retval; | |
104 |
|
104 | |||
105 | if(0 != (retval = nmea_gen_loop(info))) |
|
105 | if(0 != (retval = nmea_gen_loop(info))) | |
106 | retval = nmea_generate(buff, buff_sz, info, code); |
|
106 | retval = nmea_generate(buff, buff_sz, info, code); | |
107 |
|
107 | |||
108 | return retval; |
|
108 | return retval; | |
109 | } |
|
109 | } | |
110 |
|
110 | |||
111 |
|
111 | |||
112 |
|
112 | |||
113 | int nmeaGenerator::nmea_igen_pos_rmove_destroy(void) |
|
113 | int nmeaGenerator::nmea_igen_pos_rmove_destroy(void) | |
114 | { |
|
114 | { | |
115 | return 1; |
|
115 | return 1; | |
116 | }; |
|
116 | }; | |
117 |
|
117 | |||
118 | /* |
|
118 | /* | |
119 | * generator create |
|
119 | * generator create | |
120 | */ |
|
120 | */ | |
121 |
|
121 | |||
122 | nmeaGenerator* nmeaGenerator::__nmea_create_generator(int type, nmeaInfo *info) |
|
122 | nmeaGenerator* nmeaGenerator::__nmea_create_generator(int type, nmeaInfo *info) | |
123 | { |
|
123 | { | |
124 | nmeaGenerator* gen = nullptr; |
|
124 | nmeaGenerator* gen = nullptr; | |
125 | switch(type) |
|
125 | switch(type) | |
126 | { |
|
126 | { | |
127 | case NMEA_GEN_NOISE: |
|
127 | case NMEA_GEN_NOISE: | |
128 | gen = new nmeaGenerator(); |
|
128 | gen = new nmeaGenerator(); | |
129 | gen->init_call = &info->nmea_igen_noise_init; |
|
129 | gen->init_call = &info->nmea_igen_noise_init; | |
130 | gen->loop_call = &info->nmea_igen_noise_loop; |
|
130 | gen->loop_call = &info->nmea_igen_noise_loop; | |
131 | gen->reset_call = &info->nmea_igen_noise_reset; |
|
131 | gen->reset_call = &info->nmea_igen_noise_reset; | |
132 | break; |
|
132 | break; | |
133 | case NMEA_GEN_STATIC: |
|
133 | case NMEA_GEN_STATIC: | |
134 | case NMEA_GEN_SAT_STATIC: |
|
134 | case NMEA_GEN_SAT_STATIC: | |
135 | gen = new nmeaGenerator(); |
|
135 | gen = new nmeaGenerator(); | |
136 | gen->init_call = &info->nmea_igen_static_init; |
|
136 | gen->init_call = &info->nmea_igen_static_init; | |
137 | gen->loop_call = &info->nmea_igen_static_loop; |
|
137 | gen->loop_call = &info->nmea_igen_static_loop; | |
138 | gen->reset_call = &info->nmea_igen_static_reset; |
|
138 | gen->reset_call = &info->nmea_igen_static_reset; | |
139 | break; |
|
139 | break; | |
140 | case NMEA_GEN_SAT_ROTATE: |
|
140 | case NMEA_GEN_SAT_ROTATE: | |
141 | gen = new nmeaGenerator(); |
|
141 | gen = new nmeaGenerator(); | |
142 | gen->init_call = &info->nmea_igen_rotate_init; |
|
142 | gen->init_call = &info->nmea_igen_rotate_init; | |
143 | gen->loop_call = &info->nmea_igen_rotate_loop; |
|
143 | gen->loop_call = &info->nmea_igen_rotate_loop; | |
144 | gen->reset_call = &info->nmea_igen_rotate_reset; |
|
144 | gen->reset_call = &info->nmea_igen_rotate_reset; | |
145 | break; |
|
145 | break; | |
146 | case NMEA_GEN_POS_RANDMOVE: |
|
146 | case NMEA_GEN_POS_RANDMOVE: | |
147 | gen = new nmeaGenerator(); |
|
147 | gen = new nmeaGenerator(); | |
148 | gen->init_call = &info->nmea_igen_pos_rmove_init; |
|
148 | gen->init_call = &info->nmea_igen_pos_rmove_init; | |
149 | gen->loop_call = &info->nmea_igen_pos_rmove_loop; |
|
149 | gen->loop_call = &info->nmea_igen_pos_rmove_loop; | |
150 | gen->destroy_call = &nmea_igen_pos_rmove_destroy; |
|
150 | gen->destroy_call = &nmea_igen_pos_rmove_destroy; | |
151 | break; |
|
151 | break; | |
152 | case NMEA_GEN_ROTATE: |
|
152 | case NMEA_GEN_ROTATE: | |
153 | gen = new nmeaGenerator(); |
|
153 | gen = new nmeaGenerator(); | |
154 | gen = __nmea_create_generator(NMEA_GEN_SAT_ROTATE, info); |
|
154 | gen = __nmea_create_generator(NMEA_GEN_SAT_ROTATE, info); | |
155 | gen->nmea_gen_add(__nmea_create_generator(NMEA_GEN_POS_RANDMOVE, info)); |
|
155 | gen->nmea_gen_add(__nmea_create_generator(NMEA_GEN_POS_RANDMOVE, info)); | |
156 | break; |
|
156 | break; | |
157 | }; |
|
157 | }; | |
158 | return this; |
|
158 | return this; | |
159 | } |
|
159 | } | |
160 |
|
160 | |||
161 | nmeaGenerator * nmeaGenerator::nmea_create_generator(int type, nmeaInfo *info) |
|
161 | nmeaGenerator * nmeaGenerator::nmea_create_generator(int type, nmeaInfo *info) | |
162 | { |
|
162 | { | |
163 | nmeaGenerator *gen = __nmea_create_generator(type, info); |
|
163 | nmeaGenerator *gen = __nmea_create_generator(type, info); | |
164 |
|
164 | |||
165 | if(gen) |
|
165 | if(gen) | |
166 | gen->nmea_gen_init(info); |
|
166 | gen->nmea_gen_init(info); | |
167 |
|
167 | |||
168 | return gen; |
|
168 | return gen; | |
169 | } |
|
169 | } | |
170 |
|
170 | |||
171 | void nmeaGenerator::nmea_destroy_generator(void) |
|
171 | void nmeaGenerator::nmea_destroy_generator(void) | |
172 | { |
|
172 | { | |
173 | nmea_gen_destroy(); |
|
173 | nmea_gen_destroy(); | |
174 | } |
|
174 | } | |
175 |
|
175 | |||
176 |
|
176 | |||
177 |
|
177 | |||
178 | int nmeaGenerator::nmea_generate(char *buff, int buff_sz, const nmeaInfo *info, nmeaCode *code) |
|
178 | int nmeaGenerator::nmea_generate(char *buff, int buff_sz, const nmeaInfo *info, nmeaCode *code) | |
179 | { |
|
179 | { | |
180 | int gen_count = 0; |
|
180 | int gen_count = 0; | |
181 |
|
181 | |||
182 | if(!buff) |
|
182 | if(!buff) | |
183 | return 0; |
|
183 | return 0; | |
184 |
|
184 | |||
185 | while(code) |
|
185 | while(code) | |
186 | { |
|
186 | { | |
187 |
|
|
187 | nmea_gen_info2code(info, code) | |
188 | gen_count += code->code_gen(buff + gen_count, buff_sz - gen_count); |
|
188 | gen_count += code->code_gen(buff + gen_count, buff_sz - gen_count); | |
189 | code += 1; |
|
189 | code += 1; | |
190 | if(buff_sz - gen_count <= 0) |
|
190 | if(buff_sz - gen_count <= 0) | |
191 | break; |
|
191 | break; | |
192 | } |
|
192 | } | |
193 | return gen_count; |
|
193 | return gen_count; | |
194 | } |
|
194 | } |
@@ -1,70 +1,70 | |||||
1 | /* |
|
1 | /* | |
2 | * nmeaGenerator.h |
|
2 | * nmeaGenerator.h | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #ifndef NMEALIB_NMEALIB___NMEAGENERATOR_H_ |
|
8 | #ifndef NMEALIB_NMEALIB___NMEAGENERATOR_H_ | |
9 | #define NMEALIB_NMEALIB___NMEAGENERATOR_H_ |
|
9 | #define NMEALIB_NMEALIB___NMEAGENERATOR_H_ | |
10 |
|
10 | |||
11 | #include "nmea_defs.h" |
|
11 | #include "nmea_defs.h" | |
12 | #include "nmeaCode.h" |
|
12 | #include "nmeaCode.h" | |
13 | #include "nmeaInfo.h" |
|
13 | #include "nmeaInfo.h" | |
14 |
|
14 | |||
15 | /* |
|
15 | /* | |
16 | * low level |
|
16 | * low level | |
17 | */ |
|
17 | */ | |
18 |
|
18 | |||
19 | typedef int (*nmeaNMEA_GEN_INIT)(nmeaGenerator *gen, nmeaInfo *info); |
|
19 | typedef int (*nmeaNMEA_GEN_INIT)(nmeaGenerator *gen, nmeaInfo *info); | |
20 | typedef int (*nmeaNMEA_GEN_LOOP)(nmeaGenerator *gen, nmeaInfo *info); |
|
20 | typedef int (*nmeaNMEA_GEN_LOOP)(nmeaGenerator *gen, nmeaInfo *info); | |
21 | typedef int (*nmeaNMEA_GEN_RESET)(nmeaGenerator *gen, nmeaInfo *info); |
|
21 | typedef int (*nmeaNMEA_GEN_RESET)(nmeaGenerator *gen, nmeaInfo *info); | |
22 | typedef int (*nmeaNMEA_GEN_DESTROY)(nmeaGenerator *gen); |
|
22 | typedef int (*nmeaNMEA_GEN_DESTROY)(nmeaGenerator *gen); | |
23 |
|
23 | |||
24 | enum nmeaGENTYPE |
|
24 | enum nmeaGENTYPE | |
25 | { |
|
25 | { | |
26 | NMEA_GEN_NOISE = 0, |
|
26 | NMEA_GEN_NOISE = 0, | |
27 | NMEA_GEN_STATIC, |
|
27 | NMEA_GEN_STATIC, | |
28 | NMEA_GEN_ROTATE, |
|
28 | NMEA_GEN_ROTATE, | |
29 |
|
29 | |||
30 | NMEA_GEN_SAT_STATIC, |
|
30 | NMEA_GEN_SAT_STATIC, | |
31 | NMEA_GEN_SAT_ROTATE, |
|
31 | NMEA_GEN_SAT_ROTATE, | |
32 | NMEA_GEN_POS_RANDMOVE, |
|
32 | NMEA_GEN_POS_RANDMOVE, | |
33 |
|
33 | |||
34 | NMEA_GEN_LAST |
|
34 | NMEA_GEN_LAST | |
35 | }; |
|
35 | }; | |
36 |
|
36 | |||
37 | class nmeaGenerator { |
|
37 | class nmeaGenerator { | |
38 | public: |
|
38 | public: | |
39 | nmeaGenerator(); |
|
39 | nmeaGenerator(); | |
40 | virtual ~nmeaGenerator(); |
|
40 | virtual ~nmeaGenerator(); | |
41 |
|
41 | |||
42 |
|
42 | |||
43 |
virtual int |
|
43 | virtual int nmea_gen_info2code(const nmeaInfo *info, nmeaCode* code); | |
44 |
|
44 | |||
45 | int nmea_gen_init(nmeaInfo *info); |
|
45 | int nmea_gen_init(nmeaInfo *info); | |
46 | int nmea_gen_loop(nmeaInfo *info); |
|
46 | int nmea_gen_loop(nmeaInfo *info); | |
47 | int nmea_gen_reset(nmeaInfo *info); |
|
47 | int nmea_gen_reset(nmeaInfo *info); | |
48 | void nmea_gen_destroy(void); |
|
48 | void nmea_gen_destroy(void); | |
49 | void nmea_gen_add(nmeaGenerator *from); |
|
49 | void nmea_gen_add(nmeaGenerator *from); | |
50 | int nmea_generate(char *buff, int buff_sz, const nmeaInfo *info, nmeaCode* code); |
|
50 | int nmea_generate(char *buff, int buff_sz, const nmeaInfo *info, nmeaCode* code); | |
51 |
|
51 | |||
52 | private: |
|
52 | private: | |
53 | void *gen_data; |
|
53 | void *gen_data; | |
54 | nmeaNMEA_GEN_INIT init_call; |
|
54 | nmeaNMEA_GEN_INIT init_call; | |
55 | nmeaNMEA_GEN_LOOP loop_call; |
|
55 | nmeaNMEA_GEN_LOOP loop_call; | |
56 | nmeaNMEA_GEN_RESET reset_call; |
|
56 | nmeaNMEA_GEN_RESET reset_call; | |
57 | nmeaNMEA_GEN_DESTROY destroy_call; |
|
57 | nmeaNMEA_GEN_DESTROY destroy_call; | |
58 | nmeaGenerator *next; |
|
58 | nmeaGenerator *next; | |
59 |
|
59 | |||
60 | int nmea_generate_from(char *buff, int buff_sz,nmeaInfo *info, nmeaCode *code); |
|
60 | int nmea_generate_from(char *buff, int buff_sz,nmeaInfo *info, nmeaCode *code); | |
61 | int nmea_igen_pos_rmove_destroy(void); |
|
61 | int nmea_igen_pos_rmove_destroy(void); | |
62 |
|
62 | |||
63 |
|
63 | |||
64 | nmeaGenerator * __nmea_create_generator(int type, nmeaInfo *info); |
|
64 | nmeaGenerator * __nmea_create_generator(int type, nmeaInfo *info); | |
65 | nmeaGenerator * nmea_create_generator(int type, nmeaInfo *info); |
|
65 | nmeaGenerator * nmea_create_generator(int type, nmeaInfo *info); | |
66 | void nmea_destroy_generator(void); |
|
66 | void nmea_destroy_generator(void); | |
67 |
|
67 | |||
68 | }; |
|
68 | }; | |
69 |
|
69 | |||
70 | #endif /* NMEALIB_NMEALIB___NMEAGENERATOR_H_ */ |
|
70 | #endif /* NMEALIB_NMEALIB___NMEAGENERATOR_H_ */ |
@@ -1,257 +1,257 | |||||
1 | /* |
|
1 | /* | |
2 | * nmeaInfo.cpp |
|
2 | * nmeaInfo.cpp | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #include "utils.h" |
|
8 | #include "utils.h" | |
9 | #include "nmeaInfo.h" |
|
9 | #include "nmeaInfo.h" | |
10 |
|
10 | |||
11 | nmeaInfo::nmeaInfo() { |
|
11 | nmeaInfo::nmeaInfo() { | |
12 | // TODO Auto-generated constructor stub |
|
12 | // TODO Auto-generated constructor stub | |
13 |
|
13 | |||
14 | } |
|
14 | } | |
15 |
|
15 | |||
16 | nmeaInfo::~nmeaInfo() { |
|
16 | nmeaInfo::~nmeaInfo() { | |
17 | // TODO Auto-generated destructor stub |
|
17 | // TODO Auto-generated destructor stub | |
18 | } |
|
18 | } | |
19 |
|
19 | |||
20 |
void nmeaInfo:: |
|
20 | void nmeaInfo::nmea_info_init_INFO() | |
21 | { |
|
21 | { | |
22 |
|
22 | |||
23 |
|
|
23 | nmea_info_time_now(); | |
24 | sig = NMEA_SIG_BAD; |
|
24 | sig = NMEA_SIG_BAD; | |
25 | fix = NMEA_FIX_BAD; |
|
25 | fix = NMEA_FIX_BAD; | |
26 | } |
|
26 | } | |
27 |
|
27 | |||
28 |
static void nmeaInfo:: |
|
28 | static void nmeaInfo::nmea_info_time_now() { | |
29 | time_t lt; |
|
29 | time_t lt; | |
30 | struct tm *tt; |
|
30 | struct tm *tt; | |
31 |
|
31 | |||
32 | time(<); |
|
32 | time(<); | |
33 | tt = gmtime(<); |
|
33 | tt = gmtime(<); | |
34 |
|
34 | |||
35 | utc.year = tt->tm_year; |
|
35 | utc.year = tt->tm_year; | |
36 | utc.mon = tt->tm_mon; |
|
36 | utc.mon = tt->tm_mon; | |
37 | utc.day = tt->tm_mday; |
|
37 | utc.day = tt->tm_mday; | |
38 | utc.hour = tt->tm_hour; |
|
38 | utc.hour = tt->tm_hour; | |
39 | utc.min = tt->tm_min; |
|
39 | utc.min = tt->tm_min; | |
40 | utc.sec = tt->tm_sec; |
|
40 | utc.sec = tt->tm_sec; | |
41 | utc.hsec = 0; |
|
41 | utc.hsec = 0; | |
42 | } |
|
42 | } | |
43 |
|
43 | |||
44 | /** |
|
44 | /** | |
45 | * \brief Convert position from INFO to radians position |
|
45 | * \brief Convert position from INFO to radians position | |
46 | */ |
|
46 | */ | |
47 |
void nmeaInfo:: |
|
47 | void nmeaInfo::nmea_info_info2pos(nmeaPOS *pos) { | |
48 | pos->lat = code_ndeg2radian(lat); |
|
48 | pos->lat = code_ndeg2radian(lat); | |
49 | pos->lon = code_ndeg2radian(lon); |
|
49 | pos->lon = code_ndeg2radian(lon); | |
50 | } |
|
50 | } | |
51 |
|
51 | |||
52 | /** |
|
52 | /** | |
53 | * \brief Convert radians position to INFOs position |
|
53 | * \brief Convert radians position to INFOs position | |
54 | */ |
|
54 | */ | |
55 |
void nmeaInfo:: |
|
55 | void nmeaInfo::nmea_info_pos2info(const nmeaPOS *pos) { | |
56 | lat = code_radian2ndeg(pos->lat); |
|
56 | lat = code_radian2ndeg(pos->lat); | |
57 | lon = code_radian2ndeg(pos->lon); |
|
57 | lon = code_radian2ndeg(pos->lon); | |
58 | } |
|
58 | } | |
59 |
|
59 | |||
60 |
|
60 | |||
61 |
|
61 | |||
62 | /* |
|
62 | /* | |
63 | * NOISE generator |
|
63 | * NOISE generator | |
64 | */ |
|
64 | */ | |
65 |
|
65 | |||
66 | int nmeaInfo::nmea_igen_noise_init() |
|
66 | int nmeaInfo::nmea_igen_noise_init() | |
67 | { |
|
67 | { | |
68 | return 1; |
|
68 | return 1; | |
69 | } |
|
69 | } | |
70 |
|
70 | |||
71 | int nmeaInfo::nmea_igen_noise_loop() |
|
71 | int nmeaInfo::nmea_igen_noise_loop() | |
72 | { |
|
72 | { | |
73 | int it; |
|
73 | int it; | |
74 | int in_use; |
|
74 | int in_use; | |
75 |
|
75 | |||
76 | sig = (int)nmea_random(1, 3); |
|
76 | sig = (int)nmea_random(1, 3); | |
77 | PDOP = nmea_random(0, 9); |
|
77 | PDOP = nmea_random(0, 9); | |
78 | HDOP = nmea_random(0, 9); |
|
78 | HDOP = nmea_random(0, 9); | |
79 | VDOP = nmea_random(0, 9); |
|
79 | VDOP = nmea_random(0, 9); | |
80 | fix = (int)nmea_random(2, 3); |
|
80 | fix = (int)nmea_random(2, 3); | |
81 | lat = nmea_random(0, 100); |
|
81 | lat = nmea_random(0, 100); | |
82 | lon = nmea_random(0, 100); |
|
82 | lon = nmea_random(0, 100); | |
83 | speed = nmea_random(0, 100); |
|
83 | speed = nmea_random(0, 100); | |
84 | direction = nmea_random(0, 360); |
|
84 | direction = nmea_random(0, 360); | |
85 | declination = nmea_random(0, 360); |
|
85 | declination = nmea_random(0, 360); | |
86 | elv = (int)nmea_random(-100, 100); |
|
86 | elv = (int)nmea_random(-100, 100); | |
87 |
|
87 | |||
88 | satinfo.inuse = 0; |
|
88 | satinfo.inuse = 0; | |
89 | satinfo.inview = 0; |
|
89 | satinfo.inview = 0; | |
90 |
|
90 | |||
91 | for(it = 0; it < 12; ++it) |
|
91 | for(it = 0; it < 12; ++it) | |
92 | { |
|
92 | { | |
93 | satinfo.sat[it].id = it; |
|
93 | satinfo.sat[it].id = it; | |
94 | satinfo.sat[it].in_use = in_use = (int)nmea_random(0, 3); |
|
94 | satinfo.sat[it].in_use = in_use = (int)nmea_random(0, 3); | |
95 | satinfo.sat[it].elv = (int)nmea_random(0, 90); |
|
95 | satinfo.sat[it].elv = (int)nmea_random(0, 90); | |
96 | satinfo.sat[it].azimuth = (int)nmea_random(0, 359); |
|
96 | satinfo.sat[it].azimuth = (int)nmea_random(0, 359); | |
97 | satinfo.sat[it].sig = (int)(in_use?nmea_random(40, 99):nmea_random(0, 40)); |
|
97 | satinfo.sat[it].sig = (int)(in_use?nmea_random(40, 99):nmea_random(0, 40)); | |
98 |
|
98 | |||
99 | if(in_use) |
|
99 | if(in_use) | |
100 | satinfo.inuse++; |
|
100 | satinfo.inuse++; | |
101 | if(satinfo.sat[it].sig > 0) |
|
101 | if(satinfo.sat[it].sig > 0) | |
102 | satinfo.inview++; |
|
102 | satinfo.inview++; | |
103 | } |
|
103 | } | |
104 |
|
104 | |||
105 | return 1; |
|
105 | return 1; | |
106 | } |
|
106 | } | |
107 |
|
107 | |||
108 | int nmeaInfo::nmea_igen_noise_reset() |
|
108 | int nmeaInfo::nmea_igen_noise_reset() | |
109 | { |
|
109 | { | |
110 | return 1; |
|
110 | return 1; | |
111 | } |
|
111 | } | |
112 |
|
112 | |||
113 | /* |
|
113 | /* | |
114 | * STATIC generator |
|
114 | * STATIC generator | |
115 | */ |
|
115 | */ | |
116 |
|
116 | |||
117 | int nmeaInfo::nmea_igen_static_loop() |
|
117 | int nmeaInfo::nmea_igen_static_loop() | |
118 | { |
|
118 | { | |
119 |
|
|
119 | nmea_info_time_now(); | |
120 | return 1; |
|
120 | return 1; | |
121 | }; |
|
121 | }; | |
122 |
|
122 | |||
123 | int nmeaInfo::nmea_igen_static_reset() |
|
123 | int nmeaInfo::nmea_igen_static_reset() | |
124 | { |
|
124 | { | |
125 | satinfo.inuse = 4; |
|
125 | satinfo.inuse = 4; | |
126 | satinfo.inview = 4; |
|
126 | satinfo.inview = 4; | |
127 |
|
127 | |||
128 | satinfo.sat[0].id = 1; |
|
128 | satinfo.sat[0].id = 1; | |
129 | satinfo.sat[0].in_use = 1; |
|
129 | satinfo.sat[0].in_use = 1; | |
130 | satinfo.sat[0].elv = 50; |
|
130 | satinfo.sat[0].elv = 50; | |
131 | satinfo.sat[0].azimuth = 0; |
|
131 | satinfo.sat[0].azimuth = 0; | |
132 | satinfo.sat[0].sig = 99; |
|
132 | satinfo.sat[0].sig = 99; | |
133 |
|
133 | |||
134 | satinfo.sat[1].id = 2; |
|
134 | satinfo.sat[1].id = 2; | |
135 | satinfo.sat[1].in_use = 1; |
|
135 | satinfo.sat[1].in_use = 1; | |
136 | satinfo.sat[1].elv = 50; |
|
136 | satinfo.sat[1].elv = 50; | |
137 | satinfo.sat[1].azimuth = 90; |
|
137 | satinfo.sat[1].azimuth = 90; | |
138 | satinfo.sat[1].sig = 99; |
|
138 | satinfo.sat[1].sig = 99; | |
139 |
|
139 | |||
140 | satinfo.sat[2].id = 3; |
|
140 | satinfo.sat[2].id = 3; | |
141 | satinfo.sat[2].in_use = 1; |
|
141 | satinfo.sat[2].in_use = 1; | |
142 | satinfo.sat[2].elv = 50; |
|
142 | satinfo.sat[2].elv = 50; | |
143 | satinfo.sat[2].azimuth = 180; |
|
143 | satinfo.sat[2].azimuth = 180; | |
144 | satinfo.sat[2].sig = 99; |
|
144 | satinfo.sat[2].sig = 99; | |
145 |
|
145 | |||
146 | satinfo.sat[3].id = 4; |
|
146 | satinfo.sat[3].id = 4; | |
147 | satinfo.sat[3].in_use = 1; |
|
147 | satinfo.sat[3].in_use = 1; | |
148 | satinfo.sat[3].elv = 50; |
|
148 | satinfo.sat[3].elv = 50; | |
149 | satinfo.sat[3].azimuth = 270; |
|
149 | satinfo.sat[3].azimuth = 270; | |
150 | satinfo.sat[3].sig = 99; |
|
150 | satinfo.sat[3].sig = 99; | |
151 |
|
151 | |||
152 | return 1; |
|
152 | return 1; | |
153 | } |
|
153 | } | |
154 |
|
154 | |||
155 | int nmeaInfo::nmea_igen_static_init() |
|
155 | int nmeaInfo::nmea_igen_static_init() | |
156 | { |
|
156 | { | |
157 | sig = 3; |
|
157 | sig = 3; | |
158 | fix = 3; |
|
158 | fix = 3; | |
159 |
|
159 | |||
160 | nmea_igen_static_reset(); |
|
160 | nmea_igen_static_reset(); | |
161 |
|
161 | |||
162 | return 1; |
|
162 | return 1; | |
163 | } |
|
163 | } | |
164 |
|
164 | |||
165 | /* |
|
165 | /* | |
166 | * SAT_ROTATE generator |
|
166 | * SAT_ROTATE generator | |
167 | */ |
|
167 | */ | |
168 |
|
168 | |||
169 | int nmeaInfo::nmea_igen_rotate_loop() |
|
169 | int nmeaInfo::nmea_igen_rotate_loop() | |
170 | { |
|
170 | { | |
171 | int it; |
|
171 | int it; | |
172 | int count = satinfo.inview; |
|
172 | int count = satinfo.inview; | |
173 | double deg = 360 / (count?count:1); |
|
173 | double deg = 360 / (count?count:1); | |
174 | double srt = (count?(satinfo.sat[0].azimuth):0) + 5; |
|
174 | double srt = (count?(satinfo.sat[0].azimuth):0) + 5; | |
175 |
|
175 | |||
176 |
|
|
176 | nmea_info_time_now(); | |
177 |
|
177 | |||
178 | for(it = 0; it < count; ++it) |
|
178 | for(it = 0; it < count; ++it) | |
179 | { |
|
179 | { | |
180 | satinfo.sat[it].azimuth = |
|
180 | satinfo.sat[it].azimuth = | |
181 | (int)((srt >= 360)?srt - 360:srt); |
|
181 | (int)((srt >= 360)?srt - 360:srt); | |
182 | srt += deg; |
|
182 | srt += deg; | |
183 | } |
|
183 | } | |
184 |
|
184 | |||
185 | return 1; |
|
185 | return 1; | |
186 | }; |
|
186 | }; | |
187 |
|
187 | |||
188 | int nmeaInfo::nmea_igen_rotate_reset() |
|
188 | int nmeaInfo::nmea_igen_rotate_reset() | |
189 | { |
|
189 | { | |
190 | int it; |
|
190 | int it; | |
191 | double deg = 360 / 8; |
|
191 | double deg = 360 / 8; | |
192 | double srt = 0; |
|
192 | double srt = 0; | |
193 |
|
193 | |||
194 | satinfo.inuse = 8; |
|
194 | satinfo.inuse = 8; | |
195 | satinfo.inview = 8; |
|
195 | satinfo.inview = 8; | |
196 |
|
196 | |||
197 | for(it = 0; it < satinfo.inview; ++it) |
|
197 | for(it = 0; it < satinfo.inview; ++it) | |
198 | { |
|
198 | { | |
199 | satinfo.sat[it].id = it + 1; |
|
199 | satinfo.sat[it].id = it + 1; | |
200 | satinfo.sat[it].in_use = 1; |
|
200 | satinfo.sat[it].in_use = 1; | |
201 | satinfo.sat[it].elv = 5; |
|
201 | satinfo.sat[it].elv = 5; | |
202 | satinfo.sat[it].azimuth = (int)srt; |
|
202 | satinfo.sat[it].azimuth = (int)srt; | |
203 | satinfo.sat[it].sig = 80; |
|
203 | satinfo.sat[it].sig = 80; | |
204 | srt += deg; |
|
204 | srt += deg; | |
205 | } |
|
205 | } | |
206 |
|
206 | |||
207 | return 1; |
|
207 | return 1; | |
208 | } |
|
208 | } | |
209 |
|
209 | |||
210 | int nmeaInfo::nmea_igen_rotate_init() |
|
210 | int nmeaInfo::nmea_igen_rotate_init() | |
211 | { |
|
211 | { | |
212 | sig = 3; |
|
212 | sig = 3; | |
213 | fix = 3; |
|
213 | fix = 3; | |
214 |
|
214 | |||
215 | nmea_igen_rotate_reset(); |
|
215 | nmea_igen_rotate_reset(); | |
216 |
|
216 | |||
217 | return 1; |
|
217 | return 1; | |
218 | } |
|
218 | } | |
219 |
|
219 | |||
220 | /* |
|
220 | /* | |
221 | * POS_RANDMOVE generator |
|
221 | * POS_RANDMOVE generator | |
222 | */ |
|
222 | */ | |
223 |
|
223 | |||
224 | int nmeaInfo::nmea_igen_pos_rmove_init() |
|
224 | int nmeaInfo::nmea_igen_pos_rmove_init() | |
225 | { |
|
225 | { | |
226 | sig = 3; |
|
226 | sig = 3; | |
227 | fix = 3; |
|
227 | fix = 3; | |
228 | direction = declination = 0; |
|
228 | direction = declination = 0; | |
229 | speed = 20; |
|
229 | speed = 20; | |
230 | return 1; |
|
230 | return 1; | |
231 | } |
|
231 | } | |
232 |
|
232 | |||
233 | int nmeaInfo::nmea_igen_pos_rmove_loop() |
|
233 | int nmeaInfo::nmea_igen_pos_rmove_loop() | |
234 | { |
|
234 | { | |
235 | nmeaPOS crd; |
|
235 | nmeaPOS crd; | |
236 |
|
236 | |||
237 | direction += nmea_random(-10, 10); |
|
237 | direction += nmea_random(-10, 10); | |
238 | speed += nmea_random(-2, 3); |
|
238 | speed += nmea_random(-2, 3); | |
239 |
|
239 | |||
240 | if(direction < 0) |
|
240 | if(direction < 0) | |
241 | direction = 359 + direction; |
|
241 | direction = 359 + direction; | |
242 | if(direction > 359) |
|
242 | if(direction > 359) | |
243 | direction -= 359; |
|
243 | direction -= 359; | |
244 |
|
244 | |||
245 | if(speed > 40) |
|
245 | if(speed > 40) | |
246 | speed = 40; |
|
246 | speed = 40; | |
247 | if(speed < 1) |
|
247 | if(speed < 1) | |
248 | speed = 1; |
|
248 | speed = 1; | |
249 |
|
249 | |||
250 |
|
|
250 | nmea_info_info2pos(&crd); | |
251 | code_move_horz(&crd, &crd, direction, speed / 3600); |
|
251 | code_move_horz(&crd, &crd, direction, speed / 3600); | |
252 |
|
|
252 | nmea_info_pos2info(&crd); | |
253 |
|
253 | |||
254 | declination = direction; |
|
254 | declination = direction; | |
255 |
|
255 | |||
256 | return 1; |
|
256 | return 1; | |
257 | }; |
|
257 | }; |
@@ -1,84 +1,92 | |||||
1 | /* |
|
1 | /* | |
2 | * nmeaInfo.h |
|
2 | * nmeaInfo.h | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #ifndef NMEALIB___NMEAINFO_H_ |
|
8 | #ifndef NMEALIB___NMEAINFO_H_ | |
9 | #define NMEALIB___NMEAINFO_H_ |
|
9 | #define NMEALIB___NMEAINFO_H_ | |
10 |
|
10 | |||
11 | #include "nmea_defs.h" |
|
11 | #include "nmea_defs.h" | |
12 | /** |
|
12 | /** | |
13 | * Information about satellite |
|
13 | * Information about satellite | |
14 | * @see nmeaSATINFO |
|
14 | * @see nmeaSATINFO | |
15 | * @see nmeaGPGSV |
|
15 | * @see nmeaGPGSV | |
16 | */ |
|
16 | */ | |
17 | typedef struct _nmeaSATELLITE |
|
17 | typedef struct _nmeaSATELLITE | |
18 | { |
|
18 | { | |
19 | int id; /**< Satellite PRN number */ |
|
19 | int id; /**< Satellite PRN number */ | |
20 | int in_use; /**< Used in position fix */ |
|
20 | int in_use; /**< Used in position fix */ | |
21 | int elv; /**< Elevation in degrees, 90 maximum */ |
|
21 | int elv; /**< Elevation in degrees, 90 maximum */ | |
22 | int azimuth; /**< Azimuth, degrees from true north, 000 to 359 */ |
|
22 | int azimuth; /**< Azimuth, degrees from true north, 000 to 359 */ | |
23 | int sig; /**< Signal, 00-99 dB */ |
|
23 | int sig; /**< Signal, 00-99 dB */ | |
24 |
|
24 | |||
25 | } nmeaSATELLITE; |
|
25 | } nmeaSATELLITE; | |
26 |
|
26 | |||
27 | /** |
|
27 | /** | |
28 | * Information about all satellites in view |
|
28 | * Information about all satellites in view | |
29 | * @see nmeaINFO |
|
29 | * @see nmeaINFO | |
30 | * @see nmeaGPGSV |
|
30 | * @see nmeaGPGSV | |
31 | */ |
|
31 | */ | |
32 | typedef struct _nmeaSATINFO |
|
32 | typedef struct _nmeaSATINFO | |
33 | { |
|
33 | { | |
34 | int inuse; /**< Number of satellites in use (not those in view) */ |
|
34 | int inuse; /**< Number of satellites in use (not those in view) */ | |
35 | int inview; /**< Total number of satellites in view */ |
|
35 | int inview; /**< Total number of satellites in view */ | |
36 | nmeaSATELLITE sat[NMEA_MAXSAT]; /**< Satellites information */ |
|
36 | nmeaSATELLITE sat[NMEA_MAXSAT]; /**< Satellites information */ | |
37 |
|
37 | |||
38 | } nmeaSATINFO; |
|
38 | } nmeaSATINFO; | |
39 |
|
39 | |||
40 | /** |
|
40 | /** | |
41 | * Summary GPS information from all parsed packets, |
|
41 | * Summary GPS information from all parsed packets, | |
42 | * used also for generating NMEA stream |
|
42 | * used also for generating NMEA stream | |
43 | * @see nmea_parse |
|
43 | * @see nmea_parse | |
44 | * @see nmea_GPGGA2info, nmea_...2info |
|
44 | * @see nmea_GPGGA2info, nmea_...2info | |
45 | */ |
|
45 | */ | |
46 | class nmeaInfo { |
|
46 | class nmeaInfo { | |
47 | public: |
|
47 | public: | |
48 | nmeaInfo(); |
|
48 | nmeaInfo(); | |
49 | virtual ~nmeaInfo(); |
|
49 | virtual ~nmeaInfo(); | |
50 |
void |
|
50 | void nmea_info_init_INFO(); | |
51 |
static void |
|
51 | static void nmea_info_time_now(); | |
52 |
void |
|
52 | void nmea_info_info2pos(nmeaPOS *pos); | |
53 |
void |
|
53 | void nmea_info_pos2info(const nmeaPOS *pos); | |
54 |
|
54 | |||
55 |
int nmea_i |
|
55 | int nmea_info_noise_init(); | |
56 |
int nmea_i |
|
56 | int nmea_info_noise_loop(); | |
57 |
int nmea_i |
|
57 | int nmea_info_noise_reset(); | |
58 |
int nmea_i |
|
58 | int nmea_info_static_loop(); | |
59 |
int nmea_i |
|
59 | int nmea_info_static_reset(); | |
60 |
int nmea_i |
|
60 | int nmea_info_static_init(); | |
61 |
int nmea_i |
|
61 | int nmea_info_rotate_loop(); | |
62 |
int nmea_i |
|
62 | int nmea_info_rotate_reset(); | |
63 |
int nmea_i |
|
63 | int nmea_info_rotate_init(); | |
64 |
int nmea_i |
|
64 | int nmea_info_pos_rmove_init(); | |
65 |
int nmea_i |
|
65 | int nmea_info_pos_rmove_loop(); | |
66 |
|
66 | |||
67 | private: |
|
67 | private: | |
68 | int smask; /**< Mask specifying types of packages from which data have been obtained */ |
|
68 | int smask; /**< Mask specifying types of packages from which data have been obtained */ | |
69 | nmeaTIME utc; /**< UTC of position */ |
|
69 | nmeaTIME utc; /**< UTC of position */ | |
70 | int sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */ |
|
70 | int sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */ | |
71 | int fix; /**< Operating mode, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */ |
|
71 | int fix; /**< Operating mode, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */ | |
72 | double PDOP; /**< Position Dilution Of Precision */ |
|
72 | double PDOP; /**< Position Dilution Of Precision */ | |
73 | double HDOP; /**< Horizontal Dilution Of Precision */ |
|
73 | double HDOP; /**< Horizontal Dilution Of Precision */ | |
74 | double VDOP; /**< Vertical Dilution Of Precision */ |
|
74 | double VDOP; /**< Vertical Dilution Of Precision */ | |
75 | double lat; /**< Latitude in NDEG - +/-[degree][min].[sec/60] */ |
|
75 | double lat; /**< Latitude in NDEG - +/-[degree][min].[sec/60] */ | |
76 | double lon; /**< Longitude in NDEG - +/-[degree][min].[sec/60] */ |
|
76 | double lon; /**< Longitude in NDEG - +/-[degree][min].[sec/60] */ | |
77 | double elv; /**< Antenna altitude above/below mean sea level (geoid) in meters */ |
|
77 | double elv; /**< Antenna altitude above/below mean sea level (geoid) in meters */ | |
78 | double speed; /**< Speed over the ground in kilometers/hour */ |
|
78 | double speed; /**< Speed over the ground in kilometers/hour */ | |
79 | double direction; /**< Track angle in degrees True */ |
|
79 | double direction; /**< Track angle in degrees True */ | |
80 | double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */ |
|
80 | double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */ | |
|
81 | char ns; | |||
|
82 | char ew; | |||
|
83 | double satinuse; | |||
|
84 | char elv_units; | |||
|
85 | double diff; | |||
|
86 | char diff_units; | |||
|
87 | double dgps_age; | |||
|
88 | double dgps_sid; | |||
81 | nmeaSATINFO satinfo; /**< Satellites information */ |
|
89 | nmeaSATINFO satinfo; /**< Satellites information */ | |
82 | }; |
|
90 | }; | |
83 |
|
91 | |||
84 | #endif /* NMEALIB___NMEAINFO_H_ */ |
|
92 | #endif /* NMEALIB___NMEAINFO_H_ */ |
@@ -1,46 +1,120 | |||||
1 | /* |
|
1 | /* | |
2 | * nmeaParser.h |
|
2 | * nmeaParser.h | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #ifndef NMEALIB_NMEALIB___NMEAPARSER_H_ |
|
8 | #ifndef NMEALIB_NMEALIB___NMEAPARSER_H_ | |
9 | #define NMEALIB_NMEALIB___NMEAPARSER_H_ |
|
9 | #define NMEALIB_NMEALIB___NMEAPARSER_H_ | |
10 |
|
10 | |||
11 | typedef struct _nmeaParserNODE |
|
11 | typedef struct _nmeaParserNODE | |
12 | { |
|
12 | { | |
13 | nmeaCode* pack; |
|
13 | nmeaCode* pack; | |
14 | struct _nmeaParserNODE *next_node; |
|
14 | struct _nmeaParserNODE *next_node; | |
15 |
|
15 | |||
16 | } nmeaParserNODE; |
|
16 | } nmeaParserNODE; | |
17 |
|
17 | |||
18 | class nmeaParser { |
|
18 | class nmeaParser { | |
19 | public: |
|
19 | public: | |
20 | nmeaParser(); |
|
20 | nmeaParser(); | |
21 | virtual ~nmeaParser(); |
|
21 | virtual ~nmeaParser(); | |
22 |
|
22 | |||
23 | int nmea_find_tail(const char *buff, int buff_sz, int *res_crc) |
|
23 | int nmea_find_tail(const char *buff, int buff_sz, int *res_crc) | |
24 | int nmea_parse( const char *buff, int buff_sz, nmeaInfo *info ); |
|
24 | int nmea_parse( const char *buff, int buff_sz, nmeaInfo *info ); | |
25 |
|
25 | |||
26 | int nmea_parser_push(const char *buff, int buff_sz); |
|
26 | int nmea_parser_push(const char *buff, int buff_sz); | |
27 | int nmea_parser_top(void); |
|
27 | int nmea_parser_top(void); | |
28 | int nmea_parser_pop(nmeaCode **pack_ptr); |
|
28 | int nmea_parser_pop(nmeaCode **pack_ptr); | |
29 | int nmea_parser_peek(nmeaCode **pack_ptr); |
|
29 | int nmea_parser_peek(nmeaCode **pack_ptr); | |
30 | int nmea_parser_drop(void); |
|
30 | int nmea_parser_drop(void); | |
31 | int nmea_parser_buff_clear(void); |
|
31 | int nmea_parser_buff_clear(void); | |
32 | int nmea_parser_queue_clear(void); |
|
32 | int nmea_parser_queue_clear(void); | |
33 |
|
33 | |||
34 |
virtual void code |
|
34 | virtual void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |
35 |
|
35 | |||
36 | private: |
|
36 | private: | |
37 | void *top_node; |
|
37 | void *top_node; | |
38 | void *end_node; |
|
38 | void *end_node; | |
39 | unsigned char *buffer; |
|
39 | unsigned char *buffer; | |
40 | int buff_size; |
|
40 | int buff_size; | |
41 | int buff_use; |
|
41 | int buff_use; | |
42 |
|
42 | |||
43 | int nmea_parser_real_push(const char *buff, int buff_sz); |
|
43 | int nmea_parser_real_push(const char *buff, int buff_sz); | |
44 | }; |
|
44 | }; | |
45 |
|
45 | |||
|
46 | ||||
|
47 | class nmeaGPALMParser:nmeaParser { | |||
|
48 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
49 | }; | |||
|
50 | ||||
|
51 | //codigos NMEA que se pueden enviar al receptor GPS GARMIN | |||
|
52 | class nmeaPGRMIParser:nmeaParser { | |||
|
53 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
54 | }; | |||
|
55 | ||||
|
56 | class nmeaPGRMCParser:nmeaParser { | |||
|
57 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
58 | }; | |||
|
59 | ||||
|
60 | class nmeaPGRMC1Parser:nmeaParser { | |||
|
61 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
62 | }; | |||
|
63 | ||||
|
64 | class nmeaPGRMOParser:nmeaParser { | |||
|
65 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
66 | }; | |||
|
67 | ||||
|
68 | ||||
|
69 | //Codigos NMEA que puede transmitir el receptor GNSS | |||
|
70 | ||||
|
71 | class nmeaGPGGAParser:nmeaParser { | |||
|
72 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
73 | }; | |||
|
74 | ||||
|
75 | class nmeaGPGSAParser:nmeaParser { | |||
|
76 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
77 | }; | |||
|
78 | ||||
|
79 | class nmeaGPGSVParser:nmeaParser { | |||
|
80 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
81 | }; | |||
|
82 | ||||
|
83 | class nmeaGPRMCParser:nmeaParser { | |||
|
84 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
85 | }; | |||
|
86 | ||||
|
87 | class nmeaGPVTGParser:nmeaParser { | |||
|
88 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
89 | }; | |||
|
90 | ||||
|
91 | class nmeaGPGLLParser:nmeaParser { | |||
|
92 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
93 | }; | |||
|
94 | ||||
|
95 | //codigos de propiedad de GARMIN | |||
|
96 | class nmeaPGRMEParser:nmeaParser { | |||
|
97 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
98 | }; | |||
|
99 | ||||
|
100 | class nmeaPGRMFParser:nmeaParser { | |||
|
101 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
102 | }; | |||
|
103 | ||||
|
104 | class nmeaPGRMMParser:nmeaParser { | |||
|
105 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
106 | }; | |||
|
107 | ||||
|
108 | class nmeaPGRMTParser:nmeaParser { | |||
|
109 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
110 | }; | |||
|
111 | ||||
|
112 | class nmeaPGRMVParser:nmeaParser { | |||
|
113 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
114 | }; | |||
|
115 | ||||
|
116 | class nmeaPGRMBParser:nmeaParser { | |||
|
117 | void nmea_parser_code2info(nmeaCode* code, nmeaInfo* info); | |||
|
118 | }; | |||
|
119 | ||||
46 | #endif /* NMEALIB_NMEALIB___NMEAPARSER_H_ */ |
|
120 | #endif /* NMEALIB_NMEALIB___NMEAPARSER_H_ */ |
@@ -1,590 +1,590 | |||||
1 | /* |
|
1 | /* | |
2 | * utils.cpp |
|
2 | * utils.cpp | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #include <stdlib.h> |
|
8 | #include <stdlib.h> | |
9 | #include <stdarg.h> |
|
9 | #include <stdarg.h> | |
10 | #include "utils.h" |
|
10 | #include "utils.h" | |
11 |
|
11 | |||
12 | /** |
|
12 | /** | |
13 | * \fn code_degree2radian |
|
13 | * \fn code_degree2radian | |
14 | * \brief Convert degree to radian |
|
14 | * \brief Convert degree to radian | |
15 | */ |
|
15 | */ | |
16 |
double |
|
16 | double nmea_utils_degree2radian(double val) { | |
17 | return (val * code_PI180); |
|
17 | return (val * code_PI180); | |
18 | } |
|
18 | } | |
19 |
|
19 | |||
20 | /** |
|
20 | /** | |
21 | * \fn code_radian2degree |
|
21 | * \fn code_radian2degree | |
22 | * \brief Convert radian to degree |
|
22 | * \brief Convert radian to degree | |
23 | */ |
|
23 | */ | |
24 |
double |
|
24 | double nmea_utils_radian2degree(double val) { | |
25 | return (val / code_PI180); |
|
25 | return (val / code_PI180); | |
26 | } |
|
26 | } | |
27 |
|
27 | |||
28 | /** |
|
28 | /** | |
29 | * \brief Convert NDEG (NMEA degree) to fractional degree |
|
29 | * \brief Convert NDEG (NMEA degree) to fractional degree | |
30 | */ |
|
30 | */ | |
31 |
double |
|
31 | double nmea_utils_ndeg2degree(double val) { | |
32 | double deg = ((int)(val / 100)); |
|
32 | double deg = ((int)(val / 100)); | |
33 | val = deg + (val - deg * 100) / 60; |
|
33 | val = deg + (val - deg * 100) / 60; | |
34 | return val; |
|
34 | return val; | |
35 | } |
|
35 | } | |
36 |
|
36 | |||
37 | /** |
|
37 | /** | |
38 | * \brief Convert fractional degree to NDEG (NMEA degree) |
|
38 | * \brief Convert fractional degree to NDEG (NMEA degree) | |
39 | */ |
|
39 | */ | |
40 |
double |
|
40 | double nmea_utils_degree2ndeg(double val) { | |
41 | double int_part; |
|
41 | double int_part; | |
42 | double fra_part; |
|
42 | double fra_part; | |
43 | fra_part = modf(val, &int_part); |
|
43 | fra_part = modf(val, &int_part); | |
44 | val = int_part * 100 + fra_part * 60; |
|
44 | val = int_part * 100 + fra_part * 60; | |
45 | return val; |
|
45 | return val; | |
46 | } |
|
46 | } | |
47 |
|
47 | |||
48 | /** |
|
48 | /** | |
49 | * \fn code_ndeg2radian |
|
49 | * \fn code_ndeg2radian | |
50 | * \brief Convert NDEG (NMEA degree) to radian |
|
50 | * \brief Convert NDEG (NMEA degree) to radian | |
51 | */ |
|
51 | */ | |
52 | double code_ndeg2radian(double val) { |
|
52 | double code_ndeg2radian(double val) { | |
53 |
return |
|
53 | return nmea_utils_degree2radian(nmea_utils_ndeg2degree(val)); | |
54 | } |
|
54 | } | |
55 |
|
55 | |||
56 | /** |
|
56 | /** | |
57 | * \fn code_radian2ndeg |
|
57 | * \fn code_radian2ndeg | |
58 | * \brief Convert radian to NDEG (NMEA degree) |
|
58 | * \brief Convert radian to NDEG (NMEA degree) | |
59 | */ |
|
59 | */ | |
60 |
double |
|
60 | double nmea_utils_radian2ndeg(double val) { | |
61 |
return |
|
61 | return nmea_utils_degree2ndeg(nmea_utils_radian2degree(val)); | |
62 | } |
|
62 | } | |
63 |
|
63 | |||
64 | /** |
|
64 | /** | |
65 | * \brief Calculate PDOP (Position Dilution Of Precision) factor |
|
65 | * \brief Calculate PDOP (Position Dilution Of Precision) factor | |
66 | */ |
|
66 | */ | |
67 |
double |
|
67 | double nmea_utils_calc_pdop(double hdop, double vdop) { | |
68 | return sqrt(pow(hdop, 2) + pow(vdop, 2)); |
|
68 | return sqrt(pow(hdop, 2) + pow(vdop, 2)); | |
69 | } |
|
69 | } | |
70 |
|
70 | |||
71 |
double |
|
71 | double nmea_utils_dop2meters(double dop) { | |
72 | return (dop * code_DOP_FACTOR); |
|
72 | return (dop * code_DOP_FACTOR); | |
73 | } |
|
73 | } | |
74 |
|
74 | |||
75 |
double |
|
75 | double nmea_utils_meters2dop(double meters) { | |
76 | return (meters / code_DOP_FACTOR); |
|
76 | return (meters / code_DOP_FACTOR); | |
77 | } |
|
77 | } | |
78 |
|
78 | |||
79 | /** |
|
79 | /** | |
80 | * \brief Calculate distance between two points |
|
80 | * \brief Calculate distance between two points | |
81 | * \return Distance in meters |
|
81 | * \return Distance in meters | |
82 | */ |
|
82 | */ | |
83 |
double |
|
83 | double nmea_utils_distance( | |
84 | const nmeaPOS *from_pos, /**< From position in radians */ |
|
84 | const nmeaPOS *from_pos, /**< From position in radians */ | |
85 | const nmeaPOS *to_pos /**< To position in radians */ |
|
85 | const nmeaPOS *to_pos /**< To position in radians */ | |
86 | ) |
|
86 | ) | |
87 | { |
|
87 | { | |
88 | double dist = ((double)code_EARTHRADIUS_M) * acos( |
|
88 | double dist = ((double)code_EARTHRADIUS_M) * acos( | |
89 | sin(to_pos->lat) * sin(from_pos->lat) + |
|
89 | sin(to_pos->lat) * sin(from_pos->lat) + | |
90 | cos(to_pos->lat) * cos(from_pos->lat) * cos(to_pos->lon - from_pos->lon) |
|
90 | cos(to_pos->lat) * cos(from_pos->lat) * cos(to_pos->lon - from_pos->lon) | |
91 | ); |
|
91 | ); | |
92 | return dist; |
|
92 | return dist; | |
93 | } |
|
93 | } | |
94 |
|
94 | |||
95 | /** |
|
95 | /** | |
96 | * \brief Calculate distance between two points |
|
96 | * \brief Calculate distance between two points | |
97 | * This function uses an algorithm for an oblate spheroid earth model. |
|
97 | * This function uses an algorithm for an oblate spheroid earth model. | |
98 | * The algorithm is described here: |
|
98 | * The algorithm is described here: | |
99 | * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf |
|
99 | * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf | |
100 | * \return Distance in meters |
|
100 | * \return Distance in meters | |
101 | */ |
|
101 | */ | |
102 |
double |
|
102 | double nmea_utils_distance_ellipsoid( | |
103 | const nmeaPOS *from_pos, /**< From position in radians */ |
|
103 | const nmeaPOS *from_pos, /**< From position in radians */ | |
104 | const nmeaPOS *to_pos, /**< To position in radians */ |
|
104 | const nmeaPOS *to_pos, /**< To position in radians */ | |
105 | double *from_azimuth, /**< (O) azimuth at "from" position in radians */ |
|
105 | double *from_azimuth, /**< (O) azimuth at "from" position in radians */ | |
106 | double *to_azimuth /**< (O) azimuth at "to" position in radians */ |
|
106 | double *to_azimuth /**< (O) azimuth at "to" position in radians */ | |
107 | ) |
|
107 | ) | |
108 | { |
|
108 | { | |
109 | /* All variables */ |
|
109 | /* All variables */ | |
110 | double f, a, b, sqr_a, sqr_b; |
|
110 | double f, a, b, sqr_a, sqr_b; | |
111 | double L, phi1, phi2, U1, U2, sin_U1, sin_U2, cos_U1, cos_U2; |
|
111 | double L, phi1, phi2, U1, U2, sin_U1, sin_U2, cos_U1, cos_U2; | |
112 | double sigma, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, sqr_cos_alpha, lambda, sin_lambda, cos_lambda, delta_lambda; |
|
112 | double sigma, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, sqr_cos_alpha, lambda, sin_lambda, cos_lambda, delta_lambda; | |
113 | int remaining_steps; |
|
113 | int remaining_steps; | |
114 | double sqr_u, A, B, delta_sigma; |
|
114 | double sqr_u, A, B, delta_sigma; | |
115 |
|
115 | |||
116 | /* Check input */ |
|
116 | /* Check input */ | |
117 | NMEA_ASSERT(from_pos != 0); |
|
117 | NMEA_ASSERT(from_pos != 0); | |
118 | NMEA_ASSERT(to_pos != 0); |
|
118 | NMEA_ASSERT(to_pos != 0); | |
119 |
|
119 | |||
120 | if ((from_pos->lat == to_pos->lat) && (from_pos->lon == to_pos->lon)) |
|
120 | if ((from_pos->lat == to_pos->lat) && (from_pos->lon == to_pos->lon)) | |
121 | { /* Identical points */ |
|
121 | { /* Identical points */ | |
122 | if ( from_azimuth != 0 ) |
|
122 | if ( from_azimuth != 0 ) | |
123 | *from_azimuth = 0; |
|
123 | *from_azimuth = 0; | |
124 | if ( to_azimuth != 0 ) |
|
124 | if ( to_azimuth != 0 ) | |
125 | *to_azimuth = 0; |
|
125 | *to_azimuth = 0; | |
126 | return 0; |
|
126 | return 0; | |
127 | } /* Identical points */ |
|
127 | } /* Identical points */ | |
128 |
|
128 | |||
129 | /* Earth geometry */ |
|
129 | /* Earth geometry */ | |
130 | f = code_EARTH_FLATTENING; |
|
130 | f = code_EARTH_FLATTENING; | |
131 | a = code_EARTH_SEMIMAJORAXIS_M; |
|
131 | a = code_EARTH_SEMIMAJORAXIS_M; | |
132 | b = (1 - f) * a; |
|
132 | b = (1 - f) * a; | |
133 | sqr_a = a * a; |
|
133 | sqr_a = a * a; | |
134 | sqr_b = b * b; |
|
134 | sqr_b = b * b; | |
135 |
|
135 | |||
136 | /* Calculation */ |
|
136 | /* Calculation */ | |
137 | L = to_pos->lon - from_pos->lon; |
|
137 | L = to_pos->lon - from_pos->lon; | |
138 | phi1 = from_pos->lat; |
|
138 | phi1 = from_pos->lat; | |
139 | phi2 = to_pos->lat; |
|
139 | phi2 = to_pos->lat; | |
140 | U1 = atan((1 - f) * tan(phi1)); |
|
140 | U1 = atan((1 - f) * tan(phi1)); | |
141 | U2 = atan((1 - f) * tan(phi2)); |
|
141 | U2 = atan((1 - f) * tan(phi2)); | |
142 | sin_U1 = sin(U1); |
|
142 | sin_U1 = sin(U1); | |
143 | sin_U2 = sin(U2); |
|
143 | sin_U2 = sin(U2); | |
144 | cos_U1 = cos(U1); |
|
144 | cos_U1 = cos(U1); | |
145 | cos_U2 = cos(U2); |
|
145 | cos_U2 = cos(U2); | |
146 |
|
146 | |||
147 | /* Initialize iteration */ |
|
147 | /* Initialize iteration */ | |
148 | sigma = 0; |
|
148 | sigma = 0; | |
149 | sin_sigma = sin(sigma); |
|
149 | sin_sigma = sin(sigma); | |
150 | cos_sigma = cos(sigma); |
|
150 | cos_sigma = cos(sigma); | |
151 | cos_2_sigmam = 0; |
|
151 | cos_2_sigmam = 0; | |
152 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; |
|
152 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; | |
153 | sqr_cos_alpha = 0; |
|
153 | sqr_cos_alpha = 0; | |
154 | lambda = L; |
|
154 | lambda = L; | |
155 | sin_lambda = sin(lambda); |
|
155 | sin_lambda = sin(lambda); | |
156 | cos_lambda = cos(lambda); |
|
156 | cos_lambda = cos(lambda); | |
157 | delta_lambda = lambda; |
|
157 | delta_lambda = lambda; | |
158 | remaining_steps = 20; |
|
158 | remaining_steps = 20; | |
159 |
|
159 | |||
160 | while ((delta_lambda > 1e-12) && (remaining_steps > 0)) |
|
160 | while ((delta_lambda > 1e-12) && (remaining_steps > 0)) | |
161 | { /* Iterate */ |
|
161 | { /* Iterate */ | |
162 | /* Variables */ |
|
162 | /* Variables */ | |
163 | double tmp1, tmp2, tan_sigma, sin_alpha, cos_alpha, C, lambda_prev; |
|
163 | double tmp1, tmp2, tan_sigma, sin_alpha, cos_alpha, C, lambda_prev; | |
164 |
|
164 | |||
165 | /* Calculation */ |
|
165 | /* Calculation */ | |
166 | tmp1 = cos_U2 * sin_lambda; |
|
166 | tmp1 = cos_U2 * sin_lambda; | |
167 | tmp2 = cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda; |
|
167 | tmp2 = cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda; | |
168 | sin_sigma = sqrt(tmp1 * tmp1 + tmp2 * tmp2); |
|
168 | sin_sigma = sqrt(tmp1 * tmp1 + tmp2 * tmp2); | |
169 | cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; |
|
169 | cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; | |
170 | tan_sigma = sin_sigma / cos_sigma; |
|
170 | tan_sigma = sin_sigma / cos_sigma; | |
171 | sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; |
|
171 | sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; | |
172 | cos_alpha = cos(asin(sin_alpha)); |
|
172 | cos_alpha = cos(asin(sin_alpha)); | |
173 | sqr_cos_alpha = cos_alpha * cos_alpha; |
|
173 | sqr_cos_alpha = cos_alpha * cos_alpha; | |
174 | cos_2_sigmam = cos_sigma - 2 * sin_U1 * sin_U2 / sqr_cos_alpha; |
|
174 | cos_2_sigmam = cos_sigma - 2 * sin_U1 * sin_U2 / sqr_cos_alpha; | |
175 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; |
|
175 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; | |
176 | C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha)); |
|
176 | C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha)); | |
177 | lambda_prev = lambda; |
|
177 | lambda_prev = lambda; | |
178 | sigma = asin(sin_sigma); |
|
178 | sigma = asin(sin_sigma); | |
179 | lambda = L + |
|
179 | lambda = L + | |
180 | (1 - C) * f * sin_alpha |
|
180 | (1 - C) * f * sin_alpha | |
181 | * (sigma + C * sin_sigma * (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam))); |
|
181 | * (sigma + C * sin_sigma * (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam))); | |
182 | delta_lambda = lambda_prev - lambda; |
|
182 | delta_lambda = lambda_prev - lambda; | |
183 | if ( delta_lambda < 0 ) delta_lambda = -delta_lambda; |
|
183 | if ( delta_lambda < 0 ) delta_lambda = -delta_lambda; | |
184 | sin_lambda = sin(lambda); |
|
184 | sin_lambda = sin(lambda); | |
185 | cos_lambda = cos(lambda); |
|
185 | cos_lambda = cos(lambda); | |
186 | remaining_steps--; |
|
186 | remaining_steps--; | |
187 | } /* Iterate */ |
|
187 | } /* Iterate */ | |
188 |
|
188 | |||
189 | /* More calculation */ |
|
189 | /* More calculation */ | |
190 | sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; |
|
190 | sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; | |
191 | A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u))); |
|
191 | A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u))); | |
192 | B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u))); |
|
192 | B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u))); | |
193 | delta_sigma = B * sin_sigma * ( |
|
193 | delta_sigma = B * sin_sigma * ( | |
194 | cos_2_sigmam + B / 4 * ( |
|
194 | cos_2_sigmam + B / 4 * ( | |
195 | cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) - |
|
195 | cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) - | |
196 | B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam) |
|
196 | B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam) | |
197 | )); |
|
197 | )); | |
198 |
|
198 | |||
199 | /* Calculate result */ |
|
199 | /* Calculate result */ | |
200 | if ( from_azimuth != 0 ) |
|
200 | if ( from_azimuth != 0 ) | |
201 | { |
|
201 | { | |
202 | double tan_alpha_1 = cos_U2 * sin_lambda / (cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); |
|
202 | double tan_alpha_1 = cos_U2 * sin_lambda / (cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); | |
203 | *from_azimuth = atan(tan_alpha_1); |
|
203 | *from_azimuth = atan(tan_alpha_1); | |
204 | } |
|
204 | } | |
205 | if ( to_azimuth != 0 ) |
|
205 | if ( to_azimuth != 0 ) | |
206 | { |
|
206 | { | |
207 | double tan_alpha_2 = cos_U1 * sin_lambda / (-sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda); |
|
207 | double tan_alpha_2 = cos_U1 * sin_lambda / (-sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda); | |
208 | *to_azimuth = atan(tan_alpha_2); |
|
208 | *to_azimuth = atan(tan_alpha_2); | |
209 | } |
|
209 | } | |
210 |
|
210 | |||
211 | return b * A * (sigma - delta_sigma); |
|
211 | return b * A * (sigma - delta_sigma); | |
212 |
|
212 | |||
213 | } |
|
213 | } | |
214 | /** |
|
214 | /** | |
215 | * \brief Horizontal move of point position |
|
215 | * \brief Horizontal move of point position | |
216 | */ |
|
216 | */ | |
217 |
int |
|
217 | int nmea_utils_move_horz( | |
218 | const nmeaPOS *start_pos, /**< Start position in radians */ |
|
218 | const nmeaPOS *start_pos, /**< Start position in radians */ | |
219 | nmeaPOS *end_pos, /**< Result position in radians */ |
|
219 | nmeaPOS *end_pos, /**< Result position in radians */ | |
220 | double azimuth, /**< Azimuth (degree) [0, 359] */ |
|
220 | double azimuth, /**< Azimuth (degree) [0, 359] */ | |
221 | double distance /**< Distance (km) */ |
|
221 | double distance /**< Distance (km) */ | |
222 | ) |
|
222 | ) | |
223 | { |
|
223 | { | |
224 | nmeaPOS p1 = *start_pos; |
|
224 | nmeaPOS p1 = *start_pos; | |
225 | int RetVal = 1; |
|
225 | int RetVal = 1; | |
226 |
|
226 | |||
227 | distance /= code_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */ |
|
227 | distance /= code_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */ | |
228 |
azimuth = |
|
228 | azimuth = nmea_utils_degree2radian(azimuth); | |
229 |
|
229 | |||
230 | end_pos->lat = asin( |
|
230 | end_pos->lat = asin( | |
231 | sin(p1.lat) * cos(distance) + cos(p1.lat) * sin(distance) * cos(azimuth)); |
|
231 | sin(p1.lat) * cos(distance) + cos(p1.lat) * sin(distance) * cos(azimuth)); | |
232 | end_pos->lon = p1.lon + atan2( |
|
232 | end_pos->lon = p1.lon + atan2( | |
233 | sin(azimuth) * sin(distance) * cos(p1.lat), cos(distance) - sin(p1.lat) * sin(end_pos->lat)); |
|
233 | sin(azimuth) * sin(distance) * cos(p1.lat), cos(distance) - sin(p1.lat) * sin(end_pos->lat)); | |
234 |
|
234 | |||
235 | if(NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon)) |
|
235 | if(NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon)) | |
236 | { |
|
236 | { | |
237 | end_pos->lat = 0; end_pos->lon = 0; |
|
237 | end_pos->lat = 0; end_pos->lon = 0; | |
238 | RetVal = 0; |
|
238 | RetVal = 0; | |
239 | } |
|
239 | } | |
240 |
|
240 | |||
241 | return RetVal; |
|
241 | return RetVal; | |
242 | } |
|
242 | } | |
243 |
|
243 | |||
244 | /** |
|
244 | /** | |
245 | * \brief Horizontal move of point position |
|
245 | * \brief Horizontal move of point position | |
246 | * This function uses an algorithm for an oblate spheroid earth model. |
|
246 | * This function uses an algorithm for an oblate spheroid earth model. | |
247 | * The algorithm is described here: |
|
247 | * The algorithm is described here: | |
248 | * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf |
|
248 | * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf | |
249 | */ |
|
249 | */ | |
250 |
int |
|
250 | int nmea_utils_move_horz_ellipsoid( | |
251 | const nmeaPOS *start_pos, /**< Start position in radians */ |
|
251 | const nmeaPOS *start_pos, /**< Start position in radians */ | |
252 | nmeaPOS *end_pos, /**< (O) Result position in radians */ |
|
252 | nmeaPOS *end_pos, /**< (O) Result position in radians */ | |
253 | double azimuth, /**< Azimuth in radians */ |
|
253 | double azimuth, /**< Azimuth in radians */ | |
254 | double distance, /**< Distance (km) */ |
|
254 | double distance, /**< Distance (km) */ | |
255 | double *end_azimuth /**< (O) Azimuth at end position in radians */ |
|
255 | double *end_azimuth /**< (O) Azimuth at end position in radians */ | |
256 | ) |
|
256 | ) | |
257 | { |
|
257 | { | |
258 | /* Variables */ |
|
258 | /* Variables */ | |
259 | double f, a, b, sqr_a, sqr_b; |
|
259 | double f, a, b, sqr_a, sqr_b; | |
260 | double phi1, tan_U1, sin_U1, cos_U1, s, alpha1, sin_alpha1, cos_alpha1; |
|
260 | double phi1, tan_U1, sin_U1, cos_U1, s, alpha1, sin_alpha1, cos_alpha1; | |
261 | double tan_sigma1, sigma1, sin_alpha, cos_alpha, sqr_cos_alpha, sqr_u, A, B; |
|
261 | double tan_sigma1, sigma1, sin_alpha, cos_alpha, sqr_cos_alpha, sqr_u, A, B; | |
262 | double sigma_initial, sigma, sigma_prev, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, delta_sigma; |
|
262 | double sigma_initial, sigma, sigma_prev, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, delta_sigma; | |
263 | int remaining_steps; |
|
263 | int remaining_steps; | |
264 | double tmp1, phi2, lambda, C, L; |
|
264 | double tmp1, phi2, lambda, C, L; | |
265 |
|
265 | |||
266 | /* Check input */ |
|
266 | /* Check input */ | |
267 | NMEA_ASSERT(start_pos != 0); |
|
267 | NMEA_ASSERT(start_pos != 0); | |
268 | NMEA_ASSERT(end_pos != 0); |
|
268 | NMEA_ASSERT(end_pos != 0); | |
269 |
|
269 | |||
270 | if (fabs(distance) < 1e-12) |
|
270 | if (fabs(distance) < 1e-12) | |
271 | { /* No move */ |
|
271 | { /* No move */ | |
272 | *end_pos = *start_pos; |
|
272 | *end_pos = *start_pos; | |
273 | if ( end_azimuth != 0 ) *end_azimuth = azimuth; |
|
273 | if ( end_azimuth != 0 ) *end_azimuth = azimuth; | |
274 | return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon)); |
|
274 | return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon)); | |
275 | } /* No move */ |
|
275 | } /* No move */ | |
276 |
|
276 | |||
277 | /* Earth geometry */ |
|
277 | /* Earth geometry */ | |
278 | f = code_EARTH_FLATTENING; |
|
278 | f = code_EARTH_FLATTENING; | |
279 | a = code_EARTH_SEMIMAJORAXIS_M; |
|
279 | a = code_EARTH_SEMIMAJORAXIS_M; | |
280 | b = (1 - f) * a; |
|
280 | b = (1 - f) * a; | |
281 | sqr_a = a * a; |
|
281 | sqr_a = a * a; | |
282 | sqr_b = b * b; |
|
282 | sqr_b = b * b; | |
283 |
|
283 | |||
284 | /* Calculation */ |
|
284 | /* Calculation */ | |
285 | phi1 = start_pos->lat; |
|
285 | phi1 = start_pos->lat; | |
286 | tan_U1 = (1 - f) * tan(phi1); |
|
286 | tan_U1 = (1 - f) * tan(phi1); | |
287 | cos_U1 = 1 / sqrt(1 + tan_U1 * tan_U1); |
|
287 | cos_U1 = 1 / sqrt(1 + tan_U1 * tan_U1); | |
288 | sin_U1 = tan_U1 * cos_U1; |
|
288 | sin_U1 = tan_U1 * cos_U1; | |
289 | s = distance; |
|
289 | s = distance; | |
290 | alpha1 = azimuth; |
|
290 | alpha1 = azimuth; | |
291 | sin_alpha1 = sin(alpha1); |
|
291 | sin_alpha1 = sin(alpha1); | |
292 | cos_alpha1 = cos(alpha1); |
|
292 | cos_alpha1 = cos(alpha1); | |
293 | tan_sigma1 = tan_U1 / cos_alpha1; |
|
293 | tan_sigma1 = tan_U1 / cos_alpha1; | |
294 | sigma1 = atan2(tan_U1, cos_alpha1); |
|
294 | sigma1 = atan2(tan_U1, cos_alpha1); | |
295 | sin_alpha = cos_U1 * sin_alpha1; |
|
295 | sin_alpha = cos_U1 * sin_alpha1; | |
296 | sqr_cos_alpha = 1 - sin_alpha * sin_alpha; |
|
296 | sqr_cos_alpha = 1 - sin_alpha * sin_alpha; | |
297 | cos_alpha = sqrt(sqr_cos_alpha); |
|
297 | cos_alpha = sqrt(sqr_cos_alpha); | |
298 | sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; |
|
298 | sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; | |
299 | A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u))); |
|
299 | A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u))); | |
300 | B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u))); |
|
300 | B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u))); | |
301 |
|
301 | |||
302 | /* Initialize iteration */ |
|
302 | /* Initialize iteration */ | |
303 | sigma_initial = s / (b * A); |
|
303 | sigma_initial = s / (b * A); | |
304 | sigma = sigma_initial; |
|
304 | sigma = sigma_initial; | |
305 | sin_sigma = sin(sigma); |
|
305 | sin_sigma = sin(sigma); | |
306 | cos_sigma = cos(sigma); |
|
306 | cos_sigma = cos(sigma); | |
307 | cos_2_sigmam = cos(2 * sigma1 + sigma); |
|
307 | cos_2_sigmam = cos(2 * sigma1 + sigma); | |
308 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; |
|
308 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; | |
309 | delta_sigma = 0; |
|
309 | delta_sigma = 0; | |
310 | sigma_prev = 2 * code_PI; |
|
310 | sigma_prev = 2 * code_PI; | |
311 | remaining_steps = 20; |
|
311 | remaining_steps = 20; | |
312 |
|
312 | |||
313 | while ((fabs(sigma - sigma_prev) > 1e-12) && (remaining_steps > 0)) |
|
313 | while ((fabs(sigma - sigma_prev) > 1e-12) && (remaining_steps > 0)) | |
314 | { /* Iterate */ |
|
314 | { /* Iterate */ | |
315 | cos_2_sigmam = cos(2 * sigma1 + sigma); |
|
315 | cos_2_sigmam = cos(2 * sigma1 + sigma); | |
316 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; |
|
316 | sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; | |
317 | sin_sigma = sin(sigma); |
|
317 | sin_sigma = sin(sigma); | |
318 | cos_sigma = cos(sigma); |
|
318 | cos_sigma = cos(sigma); | |
319 | delta_sigma = B * sin_sigma * ( |
|
319 | delta_sigma = B * sin_sigma * ( | |
320 | cos_2_sigmam + B / 4 * ( |
|
320 | cos_2_sigmam + B / 4 * ( | |
321 | cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) - |
|
321 | cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) - | |
322 | B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam) |
|
322 | B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam) | |
323 | )); |
|
323 | )); | |
324 | sigma_prev = sigma; |
|
324 | sigma_prev = sigma; | |
325 | sigma = sigma_initial + delta_sigma; |
|
325 | sigma = sigma_initial + delta_sigma; | |
326 | remaining_steps --; |
|
326 | remaining_steps --; | |
327 | } /* Iterate */ |
|
327 | } /* Iterate */ | |
328 |
|
328 | |||
329 | /* Calculate result */ |
|
329 | /* Calculate result */ | |
330 | tmp1 = (sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_alpha1); |
|
330 | tmp1 = (sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_alpha1); | |
331 | phi2 = atan2( |
|
331 | phi2 = atan2( | |
332 | sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_alpha1, |
|
332 | sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_alpha1, | |
333 | (1 - f) * sqrt(sin_alpha * sin_alpha + tmp1 * tmp1) |
|
333 | (1 - f) * sqrt(sin_alpha * sin_alpha + tmp1 * tmp1) | |
334 | ); |
|
334 | ); | |
335 | lambda = atan2( |
|
335 | lambda = atan2( | |
336 | sin_sigma * sin_alpha1, |
|
336 | sin_sigma * sin_alpha1, | |
337 | cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_alpha1 |
|
337 | cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_alpha1 | |
338 | ); |
|
338 | ); | |
339 | C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha)); |
|
339 | C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha)); | |
340 | L = lambda - |
|
340 | L = lambda - | |
341 | (1 - C) * f * sin_alpha * ( |
|
341 | (1 - C) * f * sin_alpha * ( | |
342 | sigma + C * sin_sigma * |
|
342 | sigma + C * sin_sigma * | |
343 | (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam)) |
|
343 | (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam)) | |
344 | ); |
|
344 | ); | |
345 |
|
345 | |||
346 | /* Result */ |
|
346 | /* Result */ | |
347 | end_pos->lon = start_pos->lon + L; |
|
347 | end_pos->lon = start_pos->lon + L; | |
348 | end_pos->lat = phi2; |
|
348 | end_pos->lat = phi2; | |
349 | if ( end_azimuth != 0 ) |
|
349 | if ( end_azimuth != 0 ) | |
350 | { |
|
350 | { | |
351 | *end_azimuth = atan2( |
|
351 | *end_azimuth = atan2( | |
352 | sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_alpha1 |
|
352 | sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_alpha1 | |
353 | ); |
|
353 | ); | |
354 | } |
|
354 | } | |
355 | return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon)); |
|
355 | return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon)); | |
356 | } |
|
356 | } | |
357 |
|
357 | |||
358 | /** |
|
358 | /** | |
359 | * \brief Calculate control sum of binary buffer |
|
359 | * \brief Calculate control sum of binary buffer | |
360 | */ |
|
360 | */ | |
361 |
int |
|
361 | int nmea_utils_calc_crc(const char *buff, int buff_sz) | |
362 | { |
|
362 | { | |
363 | int chsum = 0, |
|
363 | int chsum = 0, | |
364 | it; |
|
364 | it; | |
365 |
|
365 | |||
366 | for(it = 0; it < buff_sz; ++it) |
|
366 | for(it = 0; it < buff_sz; ++it) | |
367 | chsum ^= (int)buff[it]; |
|
367 | chsum ^= (int)buff[it]; | |
368 |
|
368 | |||
369 | return chsum; |
|
369 | return chsum; | |
370 | } |
|
370 | } | |
371 |
|
371 | |||
372 | /** |
|
372 | /** | |
373 | * \brief Convert string to number |
|
373 | * \brief Convert string to number | |
374 | */ |
|
374 | */ | |
375 |
int |
|
375 | int nmea_utils_atoi(const char *str, int str_sz, int radix) | |
376 | { |
|
376 | { | |
377 | char *tmp_ptr; |
|
377 | char *tmp_ptr; | |
378 | char buff[NMEA_CONVSTR_BUF]; |
|
378 | char buff[NMEA_CONVSTR_BUF]; | |
379 | int res = 0; |
|
379 | int res = 0; | |
380 |
|
380 | |||
381 | if(str_sz < NMEA_CONVSTR_BUF) |
|
381 | if(str_sz < NMEA_CONVSTR_BUF) | |
382 | { |
|
382 | { | |
383 | memcpy(&buff[0], str, str_sz); |
|
383 | memcpy(&buff[0], str, str_sz); | |
384 | buff[str_sz] = '\0'; |
|
384 | buff[str_sz] = '\0'; | |
385 | res = strtol(&buff[0], &tmp_ptr, radix); |
|
385 | res = strtol(&buff[0], &tmp_ptr, radix); | |
386 | } |
|
386 | } | |
387 |
|
387 | |||
388 | return res; |
|
388 | return res; | |
389 | } |
|
389 | } | |
390 |
|
390 | |||
391 | /** |
|
391 | /** | |
392 | * \brief Convert string to fraction number |
|
392 | * \brief Convert string to fraction number | |
393 | */ |
|
393 | */ | |
394 |
double |
|
394 | double nmea_utils_atof(const char *str, int str_sz) | |
395 | { |
|
395 | { | |
396 | char *tmp_ptr; |
|
396 | char *tmp_ptr; | |
397 | char buff[NMEA_CONVSTR_BUF]; |
|
397 | char buff[NMEA_CONVSTR_BUF]; | |
398 | double res = 0; |
|
398 | double res = 0; | |
399 |
|
399 | |||
400 | if(str_sz < NMEA_CONVSTR_BUF) |
|
400 | if(str_sz < NMEA_CONVSTR_BUF) | |
401 | { |
|
401 | { | |
402 | memcpy(&buff[0], str, str_sz); |
|
402 | memcpy(&buff[0], str, str_sz); | |
403 | buff[str_sz] = '\0'; |
|
403 | buff[str_sz] = '\0'; | |
404 | res = strtod(&buff[0], &tmp_ptr); |
|
404 | res = strtod(&buff[0], &tmp_ptr); | |
405 | } |
|
405 | } | |
406 |
|
406 | |||
407 | return res; |
|
407 | return res; | |
408 | } |
|
408 | } | |
409 |
|
409 | |||
410 | /** |
|
410 | /** | |
411 | * \brief Formating string (like standart printf) with CRC tail (*CRC) |
|
411 | * \brief Formating string (like standart printf) with CRC tail (*CRC) | |
412 | */ |
|
412 | */ | |
413 |
int |
|
413 | int nmea_utils_printf(char *buff, int buff_sz, const char *format, ...) | |
414 | { |
|
414 | { | |
415 | int retval, add = 0; |
|
415 | int retval, add = 0; | |
416 | va_list arg_ptr; |
|
416 | va_list arg_ptr; | |
417 |
|
417 | |||
418 | if(buff_sz <= 0) |
|
418 | if(buff_sz <= 0) | |
419 | return 0; |
|
419 | return 0; | |
420 |
|
420 | |||
421 | va_start(arg_ptr, format); |
|
421 | va_start(arg_ptr, format); | |
422 |
|
422 | |||
423 | retval = NMEA_POSIX(vsnprintf)(buff, buff_sz, format, arg_ptr); |
|
423 | retval = NMEA_POSIX(vsnprintf)(buff, buff_sz, format, arg_ptr); | |
424 |
|
424 | |||
425 | if(retval > 0) |
|
425 | if(retval > 0) | |
426 | { |
|
426 | { | |
427 | add = NMEA_POSIX(snprintf)( |
|
427 | add = NMEA_POSIX(snprintf)( | |
428 | buff + retval, buff_sz - retval, "*%02x\r\n", |
|
428 | buff + retval, buff_sz - retval, "*%02x\r\n", | |
429 |
|
|
429 | nmea_utils_calc_crc(buff + 1, retval - 1)); | |
430 | } |
|
430 | } | |
431 |
|
431 | |||
432 | retval += add; |
|
432 | retval += add; | |
433 |
|
433 | |||
434 | if(retval < 0 || retval > buff_sz) |
|
434 | if(retval < 0 || retval > buff_sz) | |
435 | { |
|
435 | { | |
436 | memset(buff, ' ', buff_sz); |
|
436 | memset(buff, ' ', buff_sz); | |
437 | retval = buff_sz; |
|
437 | retval = buff_sz; | |
438 | } |
|
438 | } | |
439 |
|
439 | |||
440 | va_end(arg_ptr); |
|
440 | va_end(arg_ptr); | |
441 |
|
441 | |||
442 | return retval; |
|
442 | return retval; | |
443 | } |
|
443 | } | |
444 |
|
444 | |||
445 | /** |
|
445 | /** | |
446 | * \brief Analyse string (specificate for NMEA sentences) |
|
446 | * \brief Analyse string (specificate for NMEA sentences) | |
447 | */ |
|
447 | */ | |
448 |
int |
|
448 | int nmea_utils_scanf(const char *buff, int buff_sz, const char *format, ...) | |
449 | { |
|
449 | { | |
450 | const char *beg_tok; |
|
450 | const char *beg_tok; | |
451 | const char *end_buf = buff + buff_sz; |
|
451 | const char *end_buf = buff + buff_sz; | |
452 |
|
452 | |||
453 | va_list arg_ptr; |
|
453 | va_list arg_ptr; | |
454 | int tok_type = NMEA_TOKS_COMPARE; |
|
454 | int tok_type = NMEA_TOKS_COMPARE; | |
455 | int width = 0; |
|
455 | int width = 0; | |
456 | const char *beg_fmt = 0; |
|
456 | const char *beg_fmt = 0; | |
457 | int snum = 0, unum = 0; |
|
457 | int snum = 0, unum = 0; | |
458 |
|
458 | |||
459 | int tok_count = 0; |
|
459 | int tok_count = 0; | |
460 | void *parg_target; |
|
460 | void *parg_target; | |
461 |
|
461 | |||
462 | va_start(arg_ptr, format); |
|
462 | va_start(arg_ptr, format); | |
463 |
|
463 | |||
464 | for(; *format && buff < end_buf; ++format) |
|
464 | for(; *format && buff < end_buf; ++format) | |
465 | { |
|
465 | { | |
466 | switch(tok_type) |
|
466 | switch(tok_type) | |
467 | { |
|
467 | { | |
468 | case NMEA_TOKS_COMPARE: |
|
468 | case NMEA_TOKS_COMPARE: | |
469 | if('%' == *format) |
|
469 | if('%' == *format) | |
470 | tok_type = NMEA_TOKS_PERCENT; |
|
470 | tok_type = NMEA_TOKS_PERCENT; | |
471 | else if(*buff++ != *format) |
|
471 | else if(*buff++ != *format) | |
472 | goto fail; |
|
472 | goto fail; | |
473 | break; |
|
473 | break; | |
474 | case NMEA_TOKS_PERCENT: |
|
474 | case NMEA_TOKS_PERCENT: | |
475 | width = 0; |
|
475 | width = 0; | |
476 | beg_fmt = format; |
|
476 | beg_fmt = format; | |
477 | tok_type = NMEA_TOKS_WIDTH; |
|
477 | tok_type = NMEA_TOKS_WIDTH; | |
478 | case NMEA_TOKS_WIDTH: |
|
478 | case NMEA_TOKS_WIDTH: | |
479 | if(isdigit(*format)) |
|
479 | if(isdigit(*format)) | |
480 | break; |
|
480 | break; | |
481 | { |
|
481 | { | |
482 | tok_type = NMEA_TOKS_TYPE; |
|
482 | tok_type = NMEA_TOKS_TYPE; | |
483 | if(format > beg_fmt) |
|
483 | if(format > beg_fmt) | |
484 |
width = |
|
484 | width = nmea_utils_atoi(beg_fmt, (int)(format - beg_fmt), 10); | |
485 | } |
|
485 | } | |
486 | case NMEA_TOKS_TYPE: |
|
486 | case NMEA_TOKS_TYPE: | |
487 | beg_tok = buff; |
|
487 | beg_tok = buff; | |
488 |
|
488 | |||
489 | if(!width && ('c' == *format || 'C' == *format) && *buff != format[1]) |
|
489 | if(!width && ('c' == *format || 'C' == *format) && *buff != format[1]) | |
490 | width = 1; |
|
490 | width = 1; | |
491 |
|
491 | |||
492 | if(width) |
|
492 | if(width) | |
493 | { |
|
493 | { | |
494 | if(buff + width <= end_buf) |
|
494 | if(buff + width <= end_buf) | |
495 | buff += width; |
|
495 | buff += width; | |
496 | else |
|
496 | else | |
497 | goto fail; |
|
497 | goto fail; | |
498 | } |
|
498 | } | |
499 | else |
|
499 | else | |
500 | { |
|
500 | { | |
501 | if(!format[1] || (0 == (buff = (char *)memchr(buff, format[1], end_buf - buff)))) |
|
501 | if(!format[1] || (0 == (buff = (char *)memchr(buff, format[1], end_buf - buff)))) | |
502 | buff = end_buf; |
|
502 | buff = end_buf; | |
503 | } |
|
503 | } | |
504 |
|
504 | |||
505 | if(buff > end_buf) |
|
505 | if(buff > end_buf) | |
506 | goto fail; |
|
506 | goto fail; | |
507 |
|
507 | |||
508 | tok_type = NMEA_TOKS_COMPARE; |
|
508 | tok_type = NMEA_TOKS_COMPARE; | |
509 | tok_count++; |
|
509 | tok_count++; | |
510 |
|
510 | |||
511 | parg_target = 0; width = (int)(buff - beg_tok); |
|
511 | parg_target = 0; width = (int)(buff - beg_tok); | |
512 |
|
512 | |||
513 | switch(*format) |
|
513 | switch(*format) | |
514 | { |
|
514 | { | |
515 | case 'c': |
|
515 | case 'c': | |
516 | case 'C': |
|
516 | case 'C': | |
517 | parg_target = (void *)va_arg(arg_ptr, char *); |
|
517 | parg_target = (void *)va_arg(arg_ptr, char *); | |
518 | if(width && 0 != (parg_target)) |
|
518 | if(width && 0 != (parg_target)) | |
519 | *((char *)parg_target) = *beg_tok; |
|
519 | *((char *)parg_target) = *beg_tok; | |
520 | break; |
|
520 | break; | |
521 | case 's': |
|
521 | case 's': | |
522 | case 'S': |
|
522 | case 'S': | |
523 | parg_target = (void *)va_arg(arg_ptr, char *); |
|
523 | parg_target = (void *)va_arg(arg_ptr, char *); | |
524 | if(width && 0 != (parg_target)) |
|
524 | if(width && 0 != (parg_target)) | |
525 | { |
|
525 | { | |
526 | memcpy(parg_target, beg_tok, width); |
|
526 | memcpy(parg_target, beg_tok, width); | |
527 | ((char *)parg_target)[width] = '\0'; |
|
527 | ((char *)parg_target)[width] = '\0'; | |
528 | } |
|
528 | } | |
529 | break; |
|
529 | break; | |
530 | case 'f': |
|
530 | case 'f': | |
531 | case 'g': |
|
531 | case 'g': | |
532 | case 'G': |
|
532 | case 'G': | |
533 | case 'e': |
|
533 | case 'e': | |
534 | case 'E': |
|
534 | case 'E': | |
535 | parg_target = (void *)va_arg(arg_ptr, double *); |
|
535 | parg_target = (void *)va_arg(arg_ptr, double *); | |
536 | if(width && 0 != (parg_target)) |
|
536 | if(width && 0 != (parg_target)) | |
537 |
*((double *)parg_target) = |
|
537 | *((double *)parg_target) = nmea_utils_atof(beg_tok, width); | |
538 | break; |
|
538 | break; | |
539 | }; |
|
539 | }; | |
540 |
|
540 | |||
541 | if(parg_target) |
|
541 | if(parg_target) | |
542 | break; |
|
542 | break; | |
543 | if(0 == (parg_target = (void *)va_arg(arg_ptr, int *))) |
|
543 | if(0 == (parg_target = (void *)va_arg(arg_ptr, int *))) | |
544 | break; |
|
544 | break; | |
545 | if(!width) |
|
545 | if(!width) | |
546 | break; |
|
546 | break; | |
547 |
|
547 | |||
548 | switch(*format) |
|
548 | switch(*format) | |
549 | { |
|
549 | { | |
550 | case 'd': |
|
550 | case 'd': | |
551 | case 'i': |
|
551 | case 'i': | |
552 |
snum = |
|
552 | snum = nmea_utils_atoi(beg_tok, width, 10); | |
553 | memcpy(parg_target, &snum, sizeof(int)); |
|
553 | memcpy(parg_target, &snum, sizeof(int)); | |
554 | break; |
|
554 | break; | |
555 | case 'u': |
|
555 | case 'u': | |
556 |
unum = |
|
556 | unum = nmea_utils_atoi(beg_tok, width, 10); | |
557 | memcpy(parg_target, &unum, sizeof(unsigned int)); |
|
557 | memcpy(parg_target, &unum, sizeof(unsigned int)); | |
558 | break; |
|
558 | break; | |
559 | case 'x': |
|
559 | case 'x': | |
560 | case 'X': |
|
560 | case 'X': | |
561 |
unum = |
|
561 | unum = nmea_utils_atoi(beg_tok, width, 16); | |
562 | memcpy(parg_target, &unum, sizeof(unsigned int)); |
|
562 | memcpy(parg_target, &unum, sizeof(unsigned int)); | |
563 | break; |
|
563 | break; | |
564 | case 'o': |
|
564 | case 'o': | |
565 |
unum = |
|
565 | unum = nmea_utils_atoi(beg_tok, width, 8); | |
566 | memcpy(parg_target, &unum, sizeof(unsigned int)); |
|
566 | memcpy(parg_target, &unum, sizeof(unsigned int)); | |
567 | break; |
|
567 | break; | |
568 | default: |
|
568 | default: | |
569 | goto fail; |
|
569 | goto fail; | |
570 | }; |
|
570 | }; | |
571 |
|
571 | |||
572 | break; |
|
572 | break; | |
573 | }; |
|
573 | }; | |
574 | } |
|
574 | } | |
575 |
|
575 | |||
576 | fail: |
|
576 | fail: | |
577 |
|
577 | |||
578 | va_end(arg_ptr); |
|
578 | va_end(arg_ptr); | |
579 |
|
579 | |||
580 | return tok_count; |
|
580 | return tok_count; | |
581 | } |
|
581 | } | |
582 |
|
582 | |||
583 |
|
583 | |||
584 |
double nmea |
|
584 | double nmea_utils_random(double min, double max) | |
585 | { |
|
585 | { | |
586 | static double rand_max = RAND_MAX; |
|
586 | static double rand_max = RAND_MAX; | |
587 | double rand_val = rand(); |
|
587 | double rand_val = rand(); | |
588 | double bounds = max - min; |
|
588 | double bounds = max - min; | |
589 | return min + (rand_val * bounds) / rand_max; |
|
589 | return min + (rand_val * bounds) / rand_max; | |
590 | } |
|
590 | } |
@@ -1,38 +1,38 | |||||
1 | /* |
|
1 | /* | |
2 | * utils.h |
|
2 | * utils.h | |
3 | * |
|
3 | * | |
4 | * Created on: Oct 21, 2014 |
|
4 | * Created on: Oct 21, 2014 | |
5 | * Author: Alan Aguilar Sologuren |
|
5 | * Author: Alan Aguilar Sologuren | |
6 | */ |
|
6 | */ | |
7 |
|
7 | |||
8 | #ifndef NMEALIB___UTILS_H_ |
|
8 | #ifndef NMEALIB___UTILS_H_ | |
9 | #define NMEALIB___UTILS_H_ |
|
9 | #define NMEALIB___UTILS_H_ | |
10 |
|
10 | |||
11 | #include "nmea_defs.h" |
|
11 | #include "nmea_defs.h" | |
12 |
|
12 | |||
13 |
double |
|
13 | double nmea_utils_degree2radian(double val); | |
14 |
double |
|
14 | double nmea_utils_radian2degree(double val); | |
15 |
double |
|
15 | double nmea_utils_ndeg2degree(double val); | |
16 |
double |
|
16 | double nmea_utils_degree2ndeg(double val); | |
17 |
double |
|
17 | double nmea_utils_ndeg2radian(double val); | |
18 |
double |
|
18 | double nmea_utils_radian2ndeg(double val); | |
19 |
double |
|
19 | double nmea_utils_calc_pdop(double hdop, double vdop); | |
20 |
double |
|
20 | double nmea_utils_dop2meters(double dop); | |
21 |
double |
|
21 | double nmea_utils_meters2dop(double meters); | |
22 |
double |
|
22 | double nmea_utils_distance(const nmeaPOS *from_pos, const nmeaPOS *to_pos); | |
23 |
double |
|
23 | double nmea_utils_distance_ellipsoid(const nmeaPOS *from_pos, const nmeaPOS *to_pos, | |
24 | double *from_azimuth, double *to_azimuth); |
|
24 | double *from_azimuth, double *to_azimuth); | |
25 |
int |
|
25 | int nmea_utils_move_horz(const nmeaPOS *start_pos, nmeaPOS *end_pos, | |
26 | double azimuth, double distance); |
|
26 | double azimuth, double distance); | |
27 |
int |
|
27 | int nmea_utils_move_horz_ellipsoid(const nmeaPOS *start_pos, nmeaPOS *end_pos, | |
28 | double azimuth, double distance, double *end_azimuth ); |
|
28 | double azimuth, double distance, double *end_azimuth ); | |
29 |
|
29 | |||
30 |
int |
|
30 | int nmea_utils_calc_crc(const char *buff, int buff_sz); | |
31 |
int |
|
31 | int nmea_utils_atoi(const char *str, int str_sz, int radix); | |
32 |
double |
|
32 | double nmea_utils_atof(const char *str, int str_sz); | |
33 |
int |
|
33 | int nmea_utils_printf(char *buff, int buff_sz, const char *format, ...); | |
34 |
int |
|
34 | int nmea_utils_scanf(const char *buff, int buff_sz, const char *format, ...); | |
35 |
|
35 | |||
36 | double nmea_random(double min, double max); |
|
36 | double nmea_utils_random(double min, double max); | |
37 |
|
37 | |||
38 | #endif /* NMEALIB___UTILS_H_ */ |
|
38 | #endif /* NMEALIB___UTILS_H_ */ |
General Comments 0
You need to be logged in to leave comments.
Login now