N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/OrbisQuartus/server/gps_sensor.cpp

Go to the documentation of this file.
00001 
00014 /*
00015  * Copyright 2007. Los Alamos National Security, LLC. This material
00016  * was produced under U.S. Government contract DE-AC52-06NA25396 for
00017  * Los Alamos National Laboratory (LANL), which is operated by Los
00018  * Alamos National Security, LLC, for the Department of Energy. The
00019  * U.S. Government has rights to use, reproduce, and distribute this
00020  * software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY,
00021  * LLC, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
00022  * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
00023  * produce derivative works, such modified software should be clearly
00024  * marked, so as not to confuse it with the version available from LANL.
00025  *
00026  * Additionally, this program is free software; you can redistribute
00027  * it and/or modify it under the terms of the GNU General Public
00028  * License as published by the Free Software Foundation; version 2 of
00029  * the License. Accordingly, this program is distributed in the hope
00030  * it will be useful, but WITHOUT ANY WARRANTY; without even the
00031  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00032  * PURPOSE. See the GNU General Public License for more details.
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, // knots
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 }


© 2007, Los Alamos National Security, LLC.