generate.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. *
  3. * NMEA library
  4. * URL: http://nmea.sourceforge.net
  5. * Author: Tim (xtimor@gmail.com)
  6. * Licence: http://www.gnu.org/licenses/lgpl.html
  7. * $Id: generate.c 17 2008-03-11 11:56:11Z xtimor $
  8. *
  9. */
  10. #include "nmea/tok.h"
  11. #include "nmea/sentence.h"
  12. #include "nmea/generate.h"
  13. #include "nmea/units.h"
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <math.h>
  17. int nmea_gen_GPGGA(char *buff, int buff_sz, nmeaGPGGA *pack)
  18. {
  19. return nmea_printf(buff, buff_sz,
  20. "$GPGGA,%02d%02d%02d.%02d,%07.4f,%C,%07.4f,%C,%1d,%02d,%03.1f,%03.1f,%C,%03.1f,%C,%03.1f,%04d",
  21. pack->utc.hour, pack->utc.min, pack->utc.sec, pack->utc.hsec,
  22. pack->lat, pack->ns, pack->lon, pack->ew,
  23. pack->sig, pack->satinuse, pack->HDOP, pack->elv, pack->elv_units,
  24. pack->diff, pack->diff_units, pack->dgps_age, pack->dgps_sid);
  25. }
  26. int nmea_gen_GPGSA(char *buff, int buff_sz, nmeaGPGSA *pack)
  27. {
  28. return nmea_printf(buff, buff_sz,
  29. "$GPGSA,%C,%1d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%03.1f,%03.1f,%03.1f",
  30. pack->fix_mode, pack->fix_type,
  31. pack->sat_prn[0], pack->sat_prn[1], pack->sat_prn[2], pack->sat_prn[3], pack->sat_prn[4], pack->sat_prn[5],
  32. pack->sat_prn[6], pack->sat_prn[7], pack->sat_prn[8], pack->sat_prn[9], pack->sat_prn[10], pack->sat_prn[11],
  33. pack->PDOP, pack->HDOP, pack->VDOP);
  34. }
  35. int nmea_gen_GPGSV(char *buff, int buff_sz, nmeaGPGSV *pack)
  36. {
  37. return nmea_printf(buff, buff_sz,
  38. "$GPGSV,%1d,%1d,%02d,"
  39. "%02d,%02d,%03d,%02d,"
  40. "%02d,%02d,%03d,%02d,"
  41. "%02d,%02d,%03d,%02d,"
  42. "%02d,%02d,%03d,%02d",
  43. pack->pack_count, pack->pack_index + 1, pack->sat_count,
  44. pack->sat_data[0].id, pack->sat_data[0].elv, pack->sat_data[0].azimuth, pack->sat_data[0].sig,
  45. pack->sat_data[1].id, pack->sat_data[1].elv, pack->sat_data[1].azimuth, pack->sat_data[1].sig,
  46. pack->sat_data[2].id, pack->sat_data[2].elv, pack->sat_data[2].azimuth, pack->sat_data[2].sig,
  47. pack->sat_data[3].id, pack->sat_data[3].elv, pack->sat_data[3].azimuth, pack->sat_data[3].sig);
  48. }
  49. int nmea_gen_GPRMC(char *buff, int buff_sz, nmeaGPRMC *pack)
  50. {
  51. return nmea_printf(buff, buff_sz,
  52. "$GPRMC,%02d%02d%02d.%02d,%C,%07.4f,%C,%07.4f,%C,%03.1f,%03.1f,%02d%02d%02d,%03.1f,%C,%C",
  53. pack->utc.hour, pack->utc.min, pack->utc.sec, pack->utc.hsec,
  54. pack->status, pack->lat, pack->ns, pack->lon, pack->ew,
  55. pack->speed, pack->direction,
  56. pack->utc.day, pack->utc.mon + 1, pack->utc.year - 100,
  57. pack->declination, pack->declin_ew, pack->mode);
  58. }
  59. int nmea_gen_GPVTG(char *buff, int buff_sz, nmeaGPVTG *pack)
  60. {
  61. return nmea_printf(buff, buff_sz,
  62. "$GPVTG,%.1f,%C,%.1f,%C,%.1f,%C,%.1f,%C",
  63. pack->dir, pack->dir_t,
  64. pack->dec, pack->dec_m,
  65. pack->spn, pack->spn_n,
  66. pack->spk, pack->spk_k);
  67. }
  68. void nmea_info2GPGGA(const nmeaINFO *info, nmeaGPGGA *pack)
  69. {
  70. nmea_zero_GPGGA(pack);
  71. pack->utc = info->utc;
  72. pack->lat = fabs(info->lat);
  73. pack->ns = ((info->lat > 0)?'N':'S');
  74. pack->lon = fabs(info->lon);
  75. pack->ew = ((info->lon > 0)?'E':'W');
  76. pack->sig = info->sig;
  77. pack->satinuse = info->satinfo.inuse;
  78. pack->HDOP = info->HDOP;
  79. pack->elv = info->elv;
  80. }
  81. void nmea_info2GPGSA(const nmeaINFO *info, nmeaGPGSA *pack)
  82. {
  83. int it;
  84. nmea_zero_GPGSA(pack);
  85. pack->fix_type = info->fix;
  86. pack->PDOP = info->PDOP;
  87. pack->HDOP = info->HDOP;
  88. pack->VDOP = info->VDOP;
  89. for(it = 0; it < NMEA_MAXSAT; ++it)
  90. {
  91. pack->sat_prn[it] =
  92. ((info->satinfo.sat[it].in_use)?info->satinfo.sat[it].id:0);
  93. }
  94. }
  95. int nmea_gsv_npack(int sat_count)
  96. {
  97. int pack_count = (int)ceil(((double)sat_count) / NMEA_SATINPACK);
  98. if(0 == pack_count)
  99. pack_count = 1;
  100. return pack_count;
  101. }
  102. void nmea_info2GPGSV(const nmeaINFO *info, nmeaGPGSV *pack, int pack_idx)
  103. {
  104. int sit, pit;
  105. nmea_zero_GPGSV(pack);
  106. pack->sat_count = (info->satinfo.inview <= NMEA_MAXSAT)?info->satinfo.inview:NMEA_MAXSAT;
  107. pack->pack_count = nmea_gsv_npack(pack->sat_count);
  108. if(pack->pack_count == 0)
  109. pack->pack_count = 1;
  110. if(pack_idx >= pack->pack_count)
  111. pack->pack_index = pack_idx % pack->pack_count;
  112. else
  113. pack->pack_index = pack_idx;
  114. for(pit = 0, sit = pack->pack_index * NMEA_SATINPACK; pit < NMEA_SATINPACK; ++pit, ++sit)
  115. pack->sat_data[pit] = info->satinfo.sat[sit];
  116. }
  117. void nmea_info2GPRMC(const nmeaINFO *info, nmeaGPRMC *pack)
  118. {
  119. nmea_zero_GPRMC(pack);
  120. pack->utc = info->utc;
  121. pack->status = ((info->sig > 0)?'A':'V');
  122. pack->lat = fabs(info->lat);
  123. pack->ns = ((info->lat > 0)?'N':'S');
  124. pack->lon = fabs(info->lon);
  125. pack->ew = ((info->lon > 0)?'E':'W');
  126. pack->speed = info->speed / NMEA_TUD_KNOTS;
  127. pack->direction = info->direction;
  128. pack->declination = info->declination;
  129. pack->declin_ew = 'E';
  130. pack->mode = ((info->sig > 0)?'A':'N');
  131. }
  132. void nmea_info2GPVTG(const nmeaINFO *info, nmeaGPVTG *pack)
  133. {
  134. nmea_zero_GPVTG(pack);
  135. pack->dir = info->direction;
  136. pack->dec = info->declination;
  137. pack->spn = info->speed / NMEA_TUD_KNOTS;
  138. pack->spk = info->speed;
  139. }
  140. int nmea_generate(
  141. char *buff, int buff_sz,
  142. const nmeaINFO *info,
  143. int generate_mask
  144. )
  145. {
  146. int gen_count = 0, gsv_it, gsv_count;
  147. int pack_mask = generate_mask;
  148. nmeaGPGGA gga;
  149. nmeaGPGSA gsa;
  150. nmeaGPGSV gsv;
  151. nmeaGPRMC rmc;
  152. nmeaGPVTG vtg;
  153. if(!buff)
  154. return 0;
  155. while(pack_mask)
  156. {
  157. if(pack_mask & GPGGA)
  158. {
  159. nmea_info2GPGGA(info, &gga);
  160. gen_count += nmea_gen_GPGGA(buff + gen_count, buff_sz - gen_count, &gga);
  161. pack_mask &= ~GPGGA;
  162. }
  163. else if(pack_mask & GPGSA)
  164. {
  165. nmea_info2GPGSA(info, &gsa);
  166. gen_count += nmea_gen_GPGSA(buff + gen_count, buff_sz - gen_count, &gsa);
  167. pack_mask &= ~GPGSA;
  168. }
  169. else if(pack_mask & GPGSV)
  170. {
  171. gsv_count = nmea_gsv_npack(info->satinfo.inview);
  172. for(gsv_it = 0; gsv_it < gsv_count && buff_sz - gen_count > 0; ++gsv_it)
  173. {
  174. nmea_info2GPGSV(info, &gsv, gsv_it);
  175. gen_count += nmea_gen_GPGSV(buff + gen_count, buff_sz - gen_count, &gsv);
  176. }
  177. pack_mask &= ~GPGSV;
  178. }
  179. else if(pack_mask & GPRMC)
  180. {
  181. nmea_info2GPRMC(info, &rmc);
  182. gen_count += nmea_gen_GPRMC(buff + gen_count, buff_sz - gen_count, &rmc);
  183. pack_mask &= ~GPRMC;
  184. }
  185. else if(pack_mask & GPVTG)
  186. {
  187. nmea_info2GPVTG(info, &vtg);
  188. gen_count += nmea_gen_GPVTG(buff + gen_count, buff_sz - gen_count, &vtg);
  189. pack_mask &= ~GPVTG;
  190. }
  191. else
  192. break;
  193. if(buff_sz - gen_count <= 0)
  194. break;
  195. }
  196. return gen_count;
  197. }