68 SGTime *t =
globals->get_time_params();
71 snprintf( utc,
sizeof(utc),
"%02d%02d%02d",
72 t->getGmt()->tm_hour, t->getGmt()->tm_min, t->getGmt()->tm_sec );
76 double latd =
mFdm.get_Latitude() * SGD_RADIANS_TO_DEGREES;
84 min = (latd - (double)deg) * 60.0;
85 snprintf( lat,
sizeof(lat),
"%02d%07.4f,%c", abs(deg),
min, dir);
90 double lond =
mFdm.get_Longitude() * SGD_RADIANS_TO_DEGREES;
98 min = (lond - (double)deg) * 60.0;
99 snprintf( lon,
sizeof(lon),
"%03d%07.4f,%c", abs(deg),
min, dir);
102 double vn =
fgGetDouble(
"/velocities/speed-north-fps" );
103 double ve =
fgGetDouble(
"/velocities/speed-east-fps" );
107 double fps = sqrt( vn*vn + ve*ve );
108 double mps = fps * SG_FEET_TO_METER;
109 double kts = mps * SG_METER_TO_NM * 3600;
110 snprintf( speed,
sizeof(speed),
"%.1f", kts );
115 double hdg_true = atan2( ve, vn ) * SGD_RADIANS_TO_DEGREES;
116 if ( hdg_true < 0 ) {
119 snprintf( heading,
sizeof(heading),
"%.1f", hdg_true );
122 double altitude_ft =
mFdm.get_Altitude();
126 unsigned short tm_mday = t->getGmt()->tm_mday;
127 unsigned short tm_mon = t->getGmt()->tm_mon + 1;
128 unsigned short tm_year = t->getGmt()->tm_year % 100;
129 snprintf(date,
sizeof(date),
"%02u%02u%02u", tm_mday, tm_mon, tm_year);
134 float magdeg =
fgGetDouble(
"/environment/magnetic-variation-deg" );
135 if ( magdeg < 0.0 ) {
141 snprintf( magvar,
sizeof(magvar),
"%.1f,%c", magdeg, dir );
148 snprintf( nmea,
sizeof(nmea),
"$GPRMC,%s,A,%s,%s,%s,%s,%s,%s,A",
149 utc, lat, lon, speed, heading, date, magvar );
157 snprintf( nmea,
sizeof(nmea),
"$GPGGA,%s,%s,%s,1,08,0.9,%.1f,M,0.0,M,,",
158 utc, lat, lon, altitude_ft * SG_FEET_TO_METER );
165 snprintf( nmea,
sizeof(nmea),
"%s%s",
166 "$GPGSA,A,3,01,02,03,,05,,07,,09,,11,12,0.9,0.9,2.0*38",
mLineFeed );
167 SG_LOG( SG_IO, SG_DEBUG, nmea );
230 double lon_deg, lon_min, lat_deg, lat_min;
234 if (tokens[0] ==
"GPRMC" ) {
236 if ( tokens.size()<9)
240 const std::string& utc = tokens[1];
241 SG_LOG( SG_IO, SG_DEBUG,
" utc = " << utc );
244 SG_LOG( SG_IO, SG_DEBUG,
" junk = " << tokens[2] );
247 lat_deg = std::stod(tokens[3].substr(0, 2));
248 lat_min = std::stod(tokens[3].substr(2));
249 lat = lat_deg + ( lat_min / 60.0 );
252 if ( tokens[4] ==
"S" )
255 mFdm.set_Latitude( lat * SGD_DEGREES_TO_RADIANS );
258 lon_deg = std::stod(tokens[5].substr(0, 3));
259 lon_min = std::stod(tokens[5].substr(3));
260 lon = lon_deg + ( lon_min / 60.0 );
263 if ( tokens[6] ==
"W" )
266 mFdm.set_Longitude( lon * SGD_DEGREES_TO_RADIANS );
267 SG_LOG( SG_IO, SG_DEBUG,
" lat = " << lat <<
", lon = " << lon );
271 sgGeodToGeoc(
mFdm.get_Latitude(),
275 mFdm.get_Longitude(),
276 sl_radius +
mFdm.get_Altitude() );
280 double speed = std::stod(tokens[7]);
281 mFdm.set_V_calibrated_kts( speed );
283 SG_LOG( SG_IO, SG_DEBUG,
" speed = " << speed );
286 double heading = std::stod(tokens[8]);
287 mFdm.set_Euler_Angles(
mFdm.get_Phi(),
289 heading * SGD_DEGREES_TO_RADIANS );
290 SG_LOG( SG_IO, SG_DEBUG,
" heading = " << heading );
292 if (tokens[0] ==
"GPGGA" ) {
293 if ( tokens.size()<11)
297 const std::string& utc = tokens[1];
298 SG_LOG( SG_IO, SG_DEBUG,
" utc = " << utc );
301 lat_deg = std::stod(tokens[2].substr(0, 2));
302 lat_min = std::stod(tokens[2].substr(2));
303 lat = lat_deg + ( lat_min / 60.0 );
306 if ( tokens[4] ==
"S" )
309 mFdm.set_Latitude( lat * SGD_DEGREES_TO_RADIANS );
312 lon_deg = std::stod(tokens[4].substr(0, 3));
313 lon_min = std::stod(tokens[4].substr(3));
314 lon = lon_deg + ( lon_min / 60.0 );
317 if ( tokens[5] ==
"W" )
320 mFdm.set_Longitude( lon * SGD_DEGREES_TO_RADIANS );
321 SG_LOG( SG_IO, SG_DEBUG,
" lat = " << lat <<
", lon = " << lon );
324 SG_LOG( SG_IO, SG_DEBUG,
" junk = " << tokens[6] );
327 SG_LOG( SG_IO, SG_DEBUG,
" junk = " << tokens[7] );
330 SG_LOG( SG_IO, SG_DEBUG,
" junk = " << tokens[8] );
333 double altitude = std::stod(tokens[9]);
336 const std::string& alt_units = tokens[10];
338 if ( alt_units !=
"F" && alt_units !=
"f" ) {
344 SG_LOG( SG_IO, SG_DEBUG,
" altitude = " <<
altitude );