aera.c
Go to the documentation of this file.
1 // AERA extension for dump1090
2 //
3 // Copyright (C) 2013-14 by Andreas Lang <andreas.lang3@student.kit.edu>
4 // Version 1.1.1 - 04.07.2014
5 //
6 #include "dump1090.h"
7 #include "aera.h"
8 #include <errno.h>
9 //
10 // ===================== AERA extension ===================
11 //
12 uint64_t mstime(void)
13 {
14  struct timeval tv;
15  uint64_t mst;
16 
17  gettimeofday(&tv, NULL);
18  mst = ((uint64_t)tv.tv_sec)*1000;
19  mst += round(tv.tv_usec/1000.0);
20  return mst;
21 }
22 
23 // Calculate GroundDistance with haversine formula
24 double aeraCalcGroundDistance(double lat1, double lon1, double lat2, double lon2)
25 {
26  double latitudeArc = (lat2 - lat1) * AERA_DEG_TO_RAD;
27  double longitudeArc = (lon2 - lon1) * AERA_DEG_TO_RAD;
28  double latitudeH = sin(latitudeArc * 0.5);
29  latitudeH *= latitudeH;
30  double lontitudeH = sin(longitudeArc * 0.5);
31  lontitudeH *= lontitudeH;
32  double tmp = cos(lat1*AERA_DEG_TO_RAD) * cos(lat2*AERA_DEG_TO_RAD);
33  double arcInRadians = 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
34  return AERA_EARTH_RADIUS_IN_METERS*arcInRadians;
35 }
36 
37 // Calculate CorrectedAltitude with curvature of the earth
38 double aeraCalcCorrectedAltitude(double alt1, double alt2, double groundDistance)
39 {
40  if (alt1 == 0.0) {
41  return 0.0;
42  } else {
43  return (alt1 - alt2) - sqrt((groundDistance * groundDistance) + (AERA_EARTH_RADIUS_IN_METERS * AERA_EARTH_RADIUS_IN_METERS)) + AERA_EARTH_RADIUS_IN_METERS;
44  }
45 }
46 
47 /*
48 // Calculate Zenith with haversine formula
49 double aeraCalcZenith(double lat1, double lon1, double alt1, double lat2, double lon2, double alt2)
50 {
51  double latitudeArc = (lat2 - lat1) * AERA_DEG_TO_RAD;
52  double longitudeArc = (lon2 - lon1) * AERA_DEG_TO_RAD;
53  double latitudeH = sin(latitudeArc * 0.5);
54  latitudeH *= latitudeH;
55  double lontitudeH = sin(longitudeArc * 0.5);
56  lontitudeH *= lontitudeH;
57  double tmp = cos(lat1*AERA_DEG_TO_RAD) * cos(lat2*AERA_DEG_TO_RAD);
58  double arcInRadians = 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
59  double distanceInMeters = AERA_EARTH_RADIUS_IN_METERS*arcInRadians;
60  return 90.0 - atan((alt1 - alt2) / distanceInMeters) / AERA_DEG_TO_RAD;
61 }
62 
63 double aeraCalcDistance(double lat1, double lon1, double alt1, double lat2, double lon2, double alt2)
64 {
65  double latitudeArc = (lat2 - lat1) * AERA_DEG_TO_RAD;
66  double longitudeArc = (lon2 - lon1) * AERA_DEG_TO_RAD;
67  double latitudeH = sin(latitudeArc * 0.5);
68  latitudeH *= latitudeH;
69  double lontitudeH = sin(longitudeArc * 0.5);
70  lontitudeH *= lontitudeH;
71  double tmp = cos(lat1*AERA_DEG_TO_RAD) * cos(lat2*AERA_DEG_TO_RAD);
72  double arcInRadians = 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
73  return sqrt(AERA_EARTH_RADIUS_IN_METERS*arcInRadians * AERA_EARTH_RADIUS_IN_METERS*arcInRadians + (alt1 - alt2)*(alt1 - alt2));
74 }
75 */
76 double aeraCalcAzimuth(double lat1, double lon1, double lat2, double lon2)
77 {
78  double lat1Arc = lat1 * AERA_DEG_TO_RAD;
79  double lat2Arc = lat2 * AERA_DEG_TO_RAD;
80  double longitudeArc = (lon1 - lon2) * AERA_DEG_TO_RAD;
81  double z = sin(longitudeArc) * cos(lat2Arc);
82  double n = cos(lat1Arc) * sin(lat2Arc) - sin(lat1Arc) * cos(lat2Arc) * cos(longitudeArc);
83  return fmod(630. + atan2(z, n) / AERA_DEG_TO_RAD, 360);
84 }
85 
87  struct aircraft *a = Modes.aircrafts;
88 
89  while(a) {
90  if (a->addr == addr) return (a);
91  a = a->next;
92  }
93  return (NULL);
94 }
95 
96 void aera(struct modesMessage *mm)
97 {
98  uint32_t airplaneAddr;
99  double airplaneLat; // Coordinates of Airplane
100  double airplaneLon; // Coordinates of Airplane
101  double airplaneAltitude; // Coordinates of Airplane
102  double groundDistance;
103  double correctedAltitude;
104  double zenith;
105  double azimuth;
106  double distance;
107  int heading = -1; // Heading of Airplane (-1 if there is no information)
108  int velocity = -1; // Velocity of Airplane (-1 if there is no information)
109  int lengthHex;
110  char time[30];
111  char hex[256];
112  char logMessage[256];
113  // char socketMessage[40];
114  struct timeval timeVal;
115  time_t curtime;
116  uint32_t gpsSec, uSec;
117  uint64_t curtimeWithmSec;
118  struct aircraft *aircraft;
119 
120  //printf("msgtype :%d\n", mm->msgtype);
121  if ((mm->msgtype == 17 || mm->msgtype == 18) && mm->metype >= 9 && mm->metype <= 18 && (mm->bFlags & MODES_ACFLAGS_LATLON_VALID)) { // Airborne position Baro
122 
123  int sentToSocket = 0;
124 
125  // Initializing time in different formats
126  gettimeofday(&timeVal, 0x0);
127  curtime = timeVal.tv_sec;
128  gpsSec = timeVal.tv_sec - AERA_UTC_TO_GPS;
129  uSec = (uint32_t)(timeVal.tv_usec);
130  strftime(time, 30, "%Y %m %d %H %M %S", gmtime(&curtime));
131 
132  curtimeWithmSec = ((uint64_t)curtime)*1000;
133  curtimeWithmSec += round(uSec/1000.0);
134 
135  // Get ID of airplane
136  airplaneAddr = mm->addr;
137 
138  // Get heading and velocity for that airplane
139  aircraft = interactiveFindAircraft2(airplaneAddr);
140  if (aircraft) { // If it's an aircraft with that ID....
141  heading = 90 - aircraft->track; // Change coordinate system
142  if (heading < 0) { // from N = 0, E = 90, S = 180, W = 270
143  heading += 360; // to E = 0, N = 90, W = 180, S = 270
144  }
145  velocity = aircraft->speed; // speed is in knots
146  }
147 
148  // Read airplane position from modesMessage
149  airplaneLat = mm->fLat;
150  airplaneLon = mm->fLon;
151  airplaneAltitude = mm->altitude * 0.3048; //in meters
152 
153  // Calculate zenith, azimuth and distance of airplane relative to AERA
154  groundDistance = aeraCalcGroundDistance(airplaneLat, airplaneLon, AERA_STATION_LATITUDE, AERA_STATION_LONGITUDE);
155  correctedAltitude = aeraCalcCorrectedAltitude(airplaneAltitude, AERA_STATION_ALTITUDE, groundDistance);
156  zenith = 90.0 - atan(correctedAltitude / groundDistance) / AERA_DEG_TO_RAD;
157  azimuth = aeraCalcAzimuth(airplaneLat, airplaneLon, AERA_STATION_LATITUDE, AERA_STATION_LONGITUDE);
158  distance = sqrt((groundDistance * groundDistance) + (correctedAltitude * correctedAltitude));
159 
160  if (Modes.aera_net && zenith <= 80.) { // write data to socket if zenith <= 80. degrees
161  // Format output message for socket
162  /*
163  AIRPLANE = 8 bytes
164  Airplane Adress = 4 bytes (unsigned int)
165  GPSsecond = 4 bytes (unsigned int)
166  microsecond = 4 bytes (unsigned int)
167  latitude = 4 bytes (float)
168  longitude = 4 bytes (float)
169  altutude = 4 bytes (float)
170  zenith = 4 bytes (float)
171  azimuth = 4 bytes (float)
172  distance = 4 bytes (float)
173  heading = 4 bytes (int)
174  velocity = 4 bytes (int)
175  = total of 52 bytes
176  */
177 
178  float airplaneLatF = (float)(airplaneLat);
179  float airplaneLonF = (float)(airplaneLon);
180  float airplaneAltitudeF = (float)(airplaneAltitude);
181  float zenithF = (float)(zenith);
182  float azimuthF = (float)(azimuth);
183  float distanceF = (float)(distance);
184 
185  unsigned char socketMessage[52];
186  strncpy((char*)socketMessage,"AIRPLANE",8);
187  *(unsigned int*)&socketMessage[8] = htonl(airplaneAddr);
188  *(unsigned int*)&socketMessage[12] = htonl(gpsSec);
189  *(unsigned int*)&socketMessage[16] = htonl(uSec);
190  unsigned int tmp = *(unsigned int*)&airplaneLatF;
191  *(unsigned int*)&socketMessage[20] = htonl(tmp);
192  tmp = *(unsigned int*)&airplaneLonF;
193  *(unsigned int*)&socketMessage[24] = htonl(tmp);
194  tmp = *(unsigned int*)&airplaneAltitudeF;
195  *(unsigned int*)&socketMessage[28] = htonl(tmp);
196  tmp = *(unsigned int*)&zenithF;
197  *(unsigned int*)&socketMessage[32] = htonl(tmp);
198  tmp = *(unsigned int*)&azimuthF;
199  *(unsigned int*)&socketMessage[36] = htonl(tmp);
200  tmp = *(unsigned int*)&distanceF;
201  *(unsigned int*)&socketMessage[40] = htonl(tmp);
202  *(int*)&socketMessage[44] = htonl(heading);
203  *(int*)&socketMessage[48] = htonl(velocity);
204 
205 
206  // Write messages to socket
207  sentToSocket = aeraWriteToSocket(aeraSocketFD, socketMessage, 52);
208 
209  // if (sentToSocket == 0) aeraWriteLogfile("ERROR writing to socket:\n");
210  }
211  // Format output message for logfile
212  lengthHex = 0;
213  int j;
214  for (j = 0; j < mm->msgbits/8; j++) lengthHex += sprintf(hex + lengthHex, "%02x", mm->msg[j]);
215  sprintf(logMessage, "%llu *%s; %s %u %06u %06x %3.12f %3.12f %5.2f %f %f %f %d %d %d\n", curtimeWithmSec, hex, time, gpsSec, uSec, airplaneAddr, airplaneLat, airplaneLon, airplaneAltitude, zenith, azimuth, distance, heading, velocity, sentToSocket);
216 
217  aeraWriteLogfile(logMessage);
218  }
219 
220  return;
221 }
222 
223 void aeraWriteLogfile(char *logMessage)
224 {
225  FILE *file = NULL;
226  time_t curtime = time(NULL);
227  char logFile[128];
228 
229  strftime(logFile, 128, "%Y%m%d.log", gmtime(&curtime));
230 
231  file = fopen(logFile, "a");
232  fputs(logMessage, file);
233  fclose (file);
234 }
235 
236 int aeraConnectToSocket(int *aeraSocketFD, char host[], int port)
237 {
238  signal(SIGPIPE, SIG_IGN);
239  int ret = 1;
240 
241  struct sockaddr_in serv_addr;
242  struct hostent *server;
243  *aeraSocketFD = socket(AF_INET, SOCK_STREAM, 0);
244 
245  if (*aeraSocketFD < 0) {
246 // printf("ERROR opening socket\n");
247  ret = 0;
248  }
249 
250  server = gethostbyname(host);
251 
252  if (server == 0x0) {
253 // printf("ERROR, no such host\n");
254  ret = 0;
255  }
256 
257  bzero((char *) &serv_addr, sizeof(serv_addr));
258  serv_addr.sin_family = AF_INET;
259  bcopy((char*)server->h_addr,(char*)&serv_addr.sin_addr.s_addr,server->h_length);
260  serv_addr.sin_port = htons(port);
261 
262  if ( connect(*aeraSocketFD,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
263 // printf("ERROR connecting to socket\n");
264  ret = 0;
265  }
266 
267  return(ret);
268 }
269 
271 {
272  time_t current_time;
273  current_time = time(NULL);
274 
275  close(*aeraSocketFD);
276  if (current_time - aeraSocketReconnectTime > 10) { // Try to reconnect after 10s
277  int ret = aeraConnectToSocket(aeraSocketFD, Modes.aera_net, Modes.aera);
278  aeraSocketReconnectTime = time(NULL);
279  return(ret);
280  } else {
281  return(0);
282  }
283 }
284 
285 int aeraWriteToSocket(int *aeraSocketFD, unsigned char *socketMessage, int length)
286 {
287  int error;
288  int ret = 1;
289 
290  error = write(*aeraSocketFD, socketMessage, length);
291  if (error != length) { // retry
292 // printf("ERROR RECONNECT\n");
293  ret = aeraReconnectToSocket(aeraSocketFD);
294  if (ret == 1) {
295  error = write(*aeraSocketFD, socketMessage, length);
296  if (error != length) {
297  ret = 0;
298  }
299  }
300  }
301  return(ret);
302 }
int aeraReconnectToSocket(int *aeraSocketFD)
Definition: aera.c:270
constexpr double mm
Definition: AugerUnits.h:113
int track
Definition: dump1090.h:198
int * aeraSocketFD
Definition: aera.h:41
uint32_t addr
Definition: dump1090.h:193
uint64_t mstime(void)
Definition: aera.c:12
uint32_t addr
Definition: dump1090.h:353
#define AERA_STATION_LATITUDE
Definition: aera.h:25
#define AERA_DEG_TO_RAD
Definition: aera.h:23
void aeraWriteLogfile(char *logMessage)
Definition: aera.c:223
double fLon
Definition: dump1090.h:370
#define AERA_UTC_TO_GPS
Definition: aera.h:37
double aeraCalcAzimuth(double lat1, double lon1, double lat2, double lon2)
Definition: aera.c:76
double aeraCalcGroundDistance(double lat1, double lon1, double lat2, double lon2)
Definition: aera.c:24
double fLat
Definition: dump1090.h:369
struct aircraft * next
Definition: dump1090.h:220
struct @0 Modes
#define MODES_ACFLAGS_LATLON_VALID
Definition: dump1090.h:127
const string file
#define AERA_EARTH_RADIUS_IN_METERS
Definition: aera.h:24
double aeraCalcCorrectedAltitude(double alt1, double alt2, double groundDistance)
Definition: aera.c:38
struct aircraft * interactiveFindAircraft2(uint32_t addr)
Definition: aera.c:86
int aeraWriteToSocket(int *aeraSocketFD, unsigned char *socketMessage, int length)
Definition: aera.c:285
int aera
Definition: dump1090.h:272
unsigned char msg[14]
Definition: dump1090.h:346
int aeraSocketReconnectTime
Definition: aera.h:41
#define AERA_STATION_LONGITUDE
Definition: aera.h:26
int altitude
Definition: dump1090.h:382
#define AERA_STATION_ALTITUDE
Definition: aera.h:27
int aeraConnectToSocket(int *aeraSocketFD, char host[], int port)
Definition: aera.c:236
int speed
Definition: dump1090.h:197

, generated on Tue Sep 26 2023.