if x["data"]["msgtype"] == 17 and 9 <= (x["data"]["longdata"] >> 51) & 0x1F <= 18 ] offset_list = [] #there's probably a way to list-comprehension-ify this but it looks hard for msg in position_reports: data = msg["data"] [alt, lat, lon, rng, bearing] = sfparse.parseBDS05(data["shortdata"], data["longdata"], data["parity"], data["ecc"]) ac_pos = [lat, lon, feet_to_meters(alt)] rel_times = [] for time, station in zip(msg["times"], stations): #here we get the estimated time at the aircraft when it transmitted range_to_ac = numpy.linalg.norm( numpy.array(mlat.llh2ecef(station)) - numpy.array(mlat.llh2ecef(ac_pos))) timestamp_at_ac = time - range_to_ac / mlat.c rel_times.append(timestamp_at_ac) offset_list.append({ "aircraft": data["shortdata"] & 0xffffff, "times": rel_times }) #this is a list of unique aircraft, heard by all stations, which transmitted position packets #we do drift calcs separately for each aircraft in the set because mixing them seems to screw things up #i haven't really sat down and figured out why that is yet unique_aircraft = list(set([x["aircraft"] for x in offset_list])) print "Aircraft heard for clock drift estimate: %s" % [ str("%x" % ac) for ac in unique_aircraft ]
#17 8da12615 903bf4bd3eb2c0 36ac95 000000 0.003357535461 00.1817445 #17 8d4b190a 682de4acf8c177 5b8f55 000000 0.002822938375 000.446215 sf_station = [37.762236, -122.442525, 100] mv_station = [37.409348, -122.07732, 100] report1_location = [37.737804, -122.485139, 3345] report1_sf_tstamp = 0.1817445 report1_mv_tstamp = 2.54791875 report2_location = [37.640836, -122.260218, 2484] report2_sf_tstamp = 0.446215 report2_mv_tstamp = 2.81227225 report1_tof_sf = numpy.linalg.norm( numpy.array(mlat.llh2ecef(sf_station)) - numpy.array(mlat.llh2ecef(report1_location))) / mlat.c report1_tof_mv = numpy.linalg.norm( numpy.array(mlat.llh2ecef(mv_station)) - numpy.array(mlat.llh2ecef(report1_location))) / mlat.c report1_sf_tstamp_abs = report1_sf_tstamp - report1_tof_sf report1_mv_tstamp_abs = report1_mv_tstamp - report1_tof_mv report2_tof_sf = numpy.linalg.norm( numpy.array(mlat.llh2ecef(sf_station)) - numpy.array(mlat.llh2ecef(report2_location))) / mlat.c report2_tof_mv = numpy.linalg.norm( numpy.array(mlat.llh2ecef(mv_station)) - numpy.array(mlat.llh2ecef(report2_location))) / mlat.c
all_heard.append({"data": station0_report["data"], "times": stamps}) #print all_heard #ok, now let's pull out the location-bearing packets so we can find our time offset position_reports = [x for x in all_heard if x["data"]["msgtype"] == 17 and 9 <= (x["data"]["longdata"] >> 51) & 0x1F <= 18] offset_list = [] #there's probably a way to list-comprehension-ify this but it looks hard for msg in position_reports: data = msg["data"] [alt, lat, lon, rng, bearing] = sfparse.parseBDS05(data["shortdata"], data["longdata"], data["parity"], data["ecc"]) ac_pos = [lat, lon, feet_to_meters(alt)] rel_times = [] for time, station in zip(msg["times"], stations): #here we get the estimated time at the aircraft when it transmitted range_to_ac = numpy.linalg.norm(numpy.array(mlat.llh2ecef(station))-numpy.array(mlat.llh2ecef(ac_pos))) timestamp_at_ac = time - range_to_ac / mlat.c rel_times.append(timestamp_at_ac) offset_list.append({"aircraft": data["shortdata"] & 0xffffff, "times": rel_times}) #this is a list of unique aircraft, heard by all stations, which transmitted position packets #we do drift calcs separately for each aircraft in the set because mixing them seems to screw things up #i haven't really sat down and figured out why that is yet unique_aircraft = list(set([x["aircraft"] for x in offset_list])) print "Aircraft heard for clock drift estimate: %s" % [str("%x" % ac) for ac in unique_aircraft] print "Total reports used: %d over %.2f seconds" % (len(position_reports), position_reports[-1]["times"][0]-position_reports[0]["times"][0]) #get a list of reported times gathered by the unique aircraft that transmitted them #abs_unique_times = [report["times"] for ac in unique_aircraft for report in offset_list if report["aircraft"] == ac] #print abs_unique_times #todo: the below can probably be done cleaner with nested list comprehensions
#!/usr/bin/python import mlat import numpy #here's some test data to validate the algorithm teststations = [[37.76225, -122.44254, 100], [37.680016,-121.772461, 100], [37.385844,-122.083082, 100], [37.701207,-122.309418, 100]] testalt = 8000 testplane = numpy.array(mlat.llh2ecef([37.617175,-122.400843, testalt])) testme = mlat.llh2geoid(teststations[0]) teststamps = [10, 10 + numpy.linalg.norm(testplane-numpy.array(mlat.llh2geoid(teststations[1]))) / mlat.c, 10 + numpy.linalg.norm(testplane-numpy.array(mlat.llh2geoid(teststations[2]))) / mlat.c, 10 + numpy.linalg.norm(testplane-numpy.array(mlat.llh2geoid(teststations[3]))) / mlat.c, ] print teststamps replies = [] for i in range(0, len(teststations)): replies.append((teststations[i], teststamps[i])) ans = mlat.mlat(replies, testalt) error = numpy.linalg.norm(numpy.array(mlat.llh2ecef(ans))-numpy.array(testplane)) range = numpy.linalg.norm(mlat.llh2geoid(ans)-numpy.array(testme)) print testplane-testme print ans print "Error: %.2fm" % (error) print "Range: %.2fkm (from first station in list)" % (range/1000)
#sf says: #17 8da12615 903bf4bd3eb2c0 36ac95 000000 0.003357535461 00.1817445 #17 8d4b190a 682de4acf8c177 5b8f55 000000 0.002822938375 000.446215 sf_station = [37.762236,-122.442525, 100] mv_station = [37.409348,-122.07732, 100] report1_location = [37.737804, -122.485139, 3345] report1_sf_tstamp = 0.1817445 report1_mv_tstamp = 2.54791875 report2_location = [37.640836, -122.260218, 2484] report2_sf_tstamp = 0.446215 report2_mv_tstamp = 2.81227225 report1_tof_sf = numpy.linalg.norm(numpy.array(mlat.llh2ecef(sf_station))-numpy.array(mlat.llh2ecef(report1_location))) / mlat.c report1_tof_mv = numpy.linalg.norm(numpy.array(mlat.llh2ecef(mv_station))-numpy.array(mlat.llh2ecef(report1_location))) / mlat.c report1_sf_tstamp_abs = report1_sf_tstamp - report1_tof_sf report1_mv_tstamp_abs = report1_mv_tstamp - report1_tof_mv report2_tof_sf = numpy.linalg.norm(numpy.array(mlat.llh2ecef(sf_station))-numpy.array(mlat.llh2ecef(report2_location))) / mlat.c report2_tof_mv = numpy.linalg.norm(numpy.array(mlat.llh2ecef(mv_station))-numpy.array(mlat.llh2ecef(report2_location))) / mlat.c report2_sf_tstamp_abs = report2_sf_tstamp - report2_tof_sf report2_mv_tstamp_abs = report2_mv_tstamp - report2_tof_mv dt1 = report1_sf_tstamp_abs - report1_mv_tstamp_abs dt2 = report2_sf_tstamp_abs - report2_mv_tstamp_abs error = abs((dt1-dt2) * mlat.c)
#!/usr/bin/python import mlat import numpy replies = [] for i in range(0, len(mlat.teststations)): replies.append((mlat.teststations[i], mlat.teststamps[i])) ans = mlat.mlat(replies, mlat.testalt) error = numpy.linalg.norm(numpy.array(mlat.llh2ecef(ans))-numpy.array(mlat.testplane)) range = numpy.linalg.norm(mlat.llh2geoid(ans)-numpy.array(mlat.llh2geoid(mlat.teststations[0]))) print "Error: %.2fm" % (error) print "Range: %.2fkm (from first station in list)" % (range/1000)