00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <time.h>
00037 #include <math.h>
00038 #include "gps_sensor.h"
00039
00040 #define SENTENCE_LEN 1024
00041
00042
00043 GPS_sensor::GPS_sensor(unsigned int ident, char *type)
00044 : Sensor_device(ident, type)
00045 {
00046 sentence = NMEA_GGA;
00047 satellites = 6;
00048 h_dilution = 0.9;
00049 v_dilution = 2.1;
00050 }
00051
00052
00053 GPS_sensor::GPS_sensor(unsigned int ident, char *type,
00054 unsigned int sats, double h, double v)
00055 : Sensor_device(ident, type)
00056 {
00057 sentence = NMEA_GGA;
00058 satellites = sats;
00059 h_dilution = h;
00060 v_dilution = v;
00061 }
00062
00063
00064 char *GPS_sensor::nmea_sentence(Sensor_node *node, Signal unused)
00065 {
00066 if (sentence == NMEA_GGA)
00067 return _nmea_gga(node);
00068 if (sentence == NMEA_GLL)
00069 return _nmea_gll(node);
00070 if (sentence == NMEA_GSA)
00071 return _nmea_gsa(node);
00072 if (sentence == NMEA_GSV)
00073 return _nmea_gsv(node);
00074 if (sentence == NMEA_RMC)
00075 return _nmea_rmc(node);
00076 return "";
00077 }
00078
00079
00080
00081 static char __latitude_direction(double lat)
00082 {
00083 if (lat < 0)
00084 return 'S';
00085 else
00086 return 'N';
00087 }
00088
00089
00090 static char __longitude_direction(double lon)
00091 {
00092 if (lon < 0)
00093 return 'W';
00094 else
00095 return 'E';
00096 }
00097
00098
00099 static int __UTC_hhmmss(void)
00100 {
00101 time_t tick = time(NULL);
00102 struct tm *now = gmtime(&tick);
00103 int utc = now->tm_hour * 10000;
00104 utc += (now->tm_min * 100);
00105 utc += now->tm_sec;
00106 return utc;
00107 }
00108
00109
00110 static int __UTC_date(void)
00111 {
00112 time_t tick = time(NULL);
00113 struct tm *now = gmtime(&tick);
00114 int utc = now->tm_mday * 10000;
00115 utc += (now->tm_mon * 100);
00116 utc += (now->tm_year % 100);
00117 return utc;
00118 }
00119
00120 static double __coord_transform(double value)
00121 {
00122 int degrees = (int) floor(fabs(value));
00123 double minutes = (fabs(value) - degrees) * 60;
00124 degrees *= 100;
00125 return degrees + minutes;
00126 }
00127
00128
00129 char *GPS_sensor::_nmea_gga(Sensor_node *node)
00130 {
00131 int chksum = 0;
00132 char *gps_string;
00133 char temp[SENTENCE_LEN];
00134
00135 sprintf(temp, "$GPGGA,%06d,%.3lf,%c,%.3lf,%c,1,%02d,"
00136 "%.1f,%.1f,M,%.1f,M,,",
00137 __UTC_hhmmss(),
00138 __coord_transform(node->coords.lat),
00139 __latitude_direction(node->coords.lat),
00140 __coord_transform(node->coords.lon),
00141 __longitude_direction(node->coords.lon),
00142 satellites,
00143 h_dilution,
00144 node->coords.altitude,
00145 node->coords.get_geoid_diff());
00146 chksum = strlen(temp);
00147 gps_string = new char[chksum + 32];
00148 sprintf(gps_string, "%s*%d\n", temp, chksum);
00149
00150 return gps_string;
00151 }
00152
00153
00154 char *GPS_sensor::_nmea_gll(Sensor_node *node)
00155 {
00156 int chksum = 0;
00157 char *gps_string;
00158 char temp[SENTENCE_LEN];
00159
00160 sprintf(temp, "$GPGLL,%.2f,%c,%.2f,%c,%6d,A,",
00161 __coord_transform(node->coords.lat),
00162 __latitude_direction(node->coords.lat),
00163 __coord_transform(node->coords.lon),
00164 __longitude_direction(node->coords.lon),
00165 __UTC_hhmmss());
00166 chksum = strlen(temp);
00167 gps_string = new char[chksum + 32];
00168 sprintf(gps_string, "%s*%d\n", temp, chksum);
00169
00170 return gps_string;
00171 }
00172
00174 char *GPS_sensor::_nmea_gsa(Sensor_node *node)
00175 {
00176 int chksum = 0;
00177 char *gps_string;
00178 char temp[SENTENCE_LEN];
00179
00180 sprintf(temp, "$GPGSA,A,3,,,,,,,,,,,,,2.1,%f,%f",
00181 h_dilution, v_dilution);
00182 chksum = strlen(temp);
00183 gps_string = new char[chksum + 32];
00184 sprintf(gps_string, "%s*%d\n", temp, chksum);
00185
00186 return gps_string;
00187 }
00188
00190 char *GPS_sensor::_nmea_gsv(Sensor_node *node)
00191 {
00192 int chksum = 0;
00193 char *gps_string;
00194 char temp[SENTENCE_LEN];
00195
00196 sprintf(temp, "$GPGSV,1,1,0%d,01,40,083,46",
00197 satellites > 9 ? 9 : satellites);
00198 chksum = strlen(temp);
00199 gps_string = new char[chksum + 32];
00200 sprintf(gps_string, "%s*%d\n", temp, chksum);
00201
00202 return gps_string;
00203 }
00204
00206 char *GPS_sensor::_nmea_rmc(Sensor_node *node)
00207 {
00209 double speed = 0, angle = 0;
00210 double mag_var = 3.1;
00211 char mag_dir = 'W';
00212
00213 int chksum = 0;
00214 char *gps_string;
00215 char temp[SENTENCE_LEN];
00216
00217 sprintf(temp, "$GPRMC,%06d,A,%.3f,%c,%.3f,%c,"
00218 "%3.1f,%3.1f,%06d,%3.1f,%c",
00219 __UTC_hhmmss(),
00220 __coord_transform(node->coords.lat),
00221 __latitude_direction(node->coords.lat),
00222 __coord_transform(node->coords.lon),
00223 __longitude_direction(node->coords.lon),
00224 speed,
00225 angle,
00226 __UTC_date(),
00227 mag_var, mag_dir);
00228 chksum = strlen(temp);
00229 gps_string = new char[chksum + 32];
00230 sprintf(gps_string, "%s*%d\n", temp, chksum);
00231
00232 return gps_string;
00233 }