kopia lustrzana https://github.com/projecthorus/chasemapper
Better handling of zero time-step data
rodzic
9fe136bbdf
commit
8c284eaa31
|
@ -105,7 +105,11 @@ class GenericTrack(object):
|
|||
_time_delta = (self.track_history[-1][0] - self.track_history[-2][0]).total_seconds()
|
||||
_altitude_delta = self.track_history[-1][3] - self.track_history[-2][3]
|
||||
|
||||
return _altitude_delta/_time_delta
|
||||
if _time_delta == 0:
|
||||
logging.warning("Zero time-step encountered in ascent rate calculation - are multiple receivers reporting telemetry simultaneously?")
|
||||
return 0.0
|
||||
else:
|
||||
return _altitude_delta/_time_delta
|
||||
|
||||
|
||||
else:
|
||||
|
@ -115,7 +119,12 @@ class GenericTrack(object):
|
|||
for _i in range(-1*(_num_samples-1), 0):
|
||||
_time_delta = (self.track_history[_i][0] - self.track_history[_i-1][0]).total_seconds()
|
||||
_altitude_delta = self.track_history[_i][3] - self.track_history[_i-1][3]
|
||||
_asc_rates.append(_altitude_delta/_time_delta)
|
||||
try:
|
||||
_asc_rates.append(_altitude_delta/_time_delta)
|
||||
except ZeroDivisionError:
|
||||
logging.warning("Zero time-step encountered in ascent rate calculation - are multiple receivers reporting telemetry simultaneously?")
|
||||
continue
|
||||
|
||||
|
||||
return np.mean(_asc_rates)
|
||||
|
||||
|
@ -142,7 +151,11 @@ class GenericTrack(object):
|
|||
|
||||
_pos_info = position_info((_pos_1[1],_pos_1[2],_pos_1[3]), (_pos_2[1],_pos_2[2],_pos_2[3]))
|
||||
|
||||
_speed = _pos_info['great_circle_distance']/_time_delta
|
||||
try:
|
||||
_speed = _pos_info['great_circle_distance']/_time_delta
|
||||
except ZeroDivisionError:
|
||||
logging.warning("Zero time-step encountered in speed calculation - are multiple receivers reporting telemetry simultaneously?")
|
||||
return 0.0
|
||||
|
||||
return _speed
|
||||
|
||||
|
|
|
@ -607,7 +607,12 @@ def udp_listener_summary_callback(data):
|
|||
output['alt'] = float(data['altitude'])
|
||||
output['callsign'] = data['callsign']
|
||||
|
||||
logging.info("Horus UDP Data: %.5f, %.5f, %.1f" % (output['lat'], output['lon'], output['alt']))
|
||||
if 'time' in data.keys():
|
||||
_time = data['time']
|
||||
else:
|
||||
_time = "??:??:??"
|
||||
|
||||
logging.info("Horus UDP Data: %s, %s, %.5f, %.5f, %.1f" % (output['callsign'], _time, output['lat'], output['lon'], output['alt']))
|
||||
|
||||
# Process the 'short time' value if we have been provided it.
|
||||
if 'time' in data.keys():
|
||||
|
|
48
log_parse.py
48
log_parse.py
|
@ -36,8 +36,12 @@ def read_file(filename):
|
|||
return _output
|
||||
|
||||
|
||||
def stringify_entry(entry):
|
||||
""" Convert a balloon telemetry entry to a string """
|
||||
_out = "%s,%.6f,%.6f,%d\n" % (entry['time'], entry['lat'], entry['lon'], entry['alt'])
|
||||
return _out
|
||||
|
||||
def extract_data(log_entries):
|
||||
def extract_data(log_entries, csv_dump=None):
|
||||
""" Step through the log entries, and extract:
|
||||
- Car position telemetry
|
||||
- Balloon positions
|
||||
|
@ -49,6 +53,9 @@ def extract_data(log_entries):
|
|||
# We might have more than one balloon though, so we use a dictionary, with one entry per callsign.
|
||||
_telemetry = {}
|
||||
|
||||
if csv_dump is not None:
|
||||
csv_out = open(csv_dump, 'w')
|
||||
|
||||
for _entry in log_entries:
|
||||
|
||||
if _entry['log_type'] == "CAR POSITION":
|
||||
|
@ -63,6 +70,9 @@ def extract_data(log_entries):
|
|||
|
||||
_telemetry[_call]['telemetry'].append(_entry)
|
||||
|
||||
if csv_dump is not None:
|
||||
csv_out.write(stringify_entry(_entry))
|
||||
|
||||
elif _entry['log_type'] == "PREDICTION":
|
||||
# Extract the callsign.
|
||||
_call = _entry['callsign']
|
||||
|
@ -76,6 +86,10 @@ def extract_data(log_entries):
|
|||
for _call in _telemetry:
|
||||
logging.info("Callsign %s: Extracted %d telemetry positions, %d predictions." % (_call, len(_telemetry[_call]['telemetry']), len(_telemetry[_call]['predictions'])))
|
||||
|
||||
|
||||
if csv_dump is not None:
|
||||
csv_out.close()
|
||||
|
||||
return (_car, _telemetry)
|
||||
|
||||
|
||||
|
@ -124,7 +138,7 @@ def flight_stats(telemetry, ascent_threshold = 3.0, descent_threshold=-5.0, lan
|
|||
_stats['positions'].append([_position['time'], _position['lat'], _position['lon'], _position['alt']])
|
||||
_state = _track.add_telemetry(_position)
|
||||
|
||||
print(_state)
|
||||
#print(_state)
|
||||
|
||||
if _state == None:
|
||||
continue
|
||||
|
@ -167,6 +181,7 @@ def flight_stats(telemetry, ascent_threshold = 3.0, descent_threshold=-5.0, lan
|
|||
_stats['burst_position'][2],
|
||||
_stats['burst_position'][3]
|
||||
))
|
||||
logging.info("Average ascent rate: %.2f" % np.mean(_stats['raw_ascent_rates']))
|
||||
|
||||
if _mean_asc_rate < descent_threshold:
|
||||
_flight_segment = "DESCENT"
|
||||
|
@ -183,7 +198,7 @@ def flight_stats(telemetry, ascent_threshold = 3.0, descent_threshold=-5.0, lan
|
|||
_flight_segment = "LANDED"
|
||||
return _stats
|
||||
|
||||
print(_flight_segment)
|
||||
#print(_flight_segment)
|
||||
|
||||
return _stats
|
||||
|
||||
|
@ -216,7 +231,7 @@ def calculate_predictor_error(predictions, landing_time, lat, lon, alt):
|
|||
|
||||
_pos_info = position_info(_landing, _predict_landing)
|
||||
|
||||
logging.info("Prediction %s: Altitude %d, Predicted Landing: %.4f, %.4f Prediction Error: %.1f km, %s" % (
|
||||
logging.debug("Prediction %s: Altitude %d, Predicted Landing: %.4f, %.4f Prediction Error: %.1f km, %s" % (
|
||||
_predict_time,
|
||||
int(_predict_altitude),
|
||||
_predict['pred_landing'][0],
|
||||
|
@ -269,7 +284,7 @@ def calculate_abort_error(predictions, landing_time, lat, lon, alt):
|
|||
|
||||
_pos_info = position_info(_landing, _predict_landing)
|
||||
|
||||
logging.info("Abort Prediction %s: Altitude %d, Predicted Landing: %.4f, %.4f Prediction Error: %.1f km, %s" % (
|
||||
logging.debug("Abort Prediction %s: Altitude %d, Predicted Landing: %.4f, %.4f Prediction Error: %.1f km, %s" % (
|
||||
_predict_time,
|
||||
int(_predict_altitude),
|
||||
_predict['abort_landing'][0],
|
||||
|
@ -353,7 +368,7 @@ def plot_predictor_error(flight_stats, predictor_errors, abort_predictor_errors=
|
|||
plt.grid()
|
||||
|
||||
|
||||
def plot_wind_trace(stats, title="", gfs_file=None, landing=None):
|
||||
def plot_wind_trace(stats, title="", gfs_file=None, landing=None, ascent=True):
|
||||
""" Plot the wind trace for the descent part of the flight """
|
||||
|
||||
_altitude = stats['altitudes']
|
||||
|
@ -363,10 +378,16 @@ def plot_wind_trace(stats, title="", gfs_file=None, landing=None):
|
|||
# Find peak altitude
|
||||
_peak_idx = np.argmax(_altitude)
|
||||
|
||||
# Only use descent data
|
||||
_altitude = np.array(_altitude[_peak_idx:])
|
||||
_speed = np.array(_speed[_peak_idx:])
|
||||
_heading = np.array(_heading[_peak_idx:])
|
||||
if ascent:
|
||||
# Only use descent data
|
||||
_altitude = np.array(_altitude[:_peak_idx])
|
||||
_speed = np.array(_speed[:_peak_idx])
|
||||
_heading = np.array(_heading[:_peak_idx])
|
||||
else:
|
||||
# Only use descent data
|
||||
_altitude = np.array(_altitude[_peak_idx:])
|
||||
_speed = np.array(_speed[_peak_idx:])
|
||||
_heading = np.array(_heading[_peak_idx:])
|
||||
|
||||
if gfs_file is not None:
|
||||
# Read in supplied GFS file.
|
||||
|
@ -390,7 +411,7 @@ def plot_wind_trace(stats, title="", gfs_file=None, landing=None):
|
|||
|
||||
plt.ylabel("Altitude (m)")
|
||||
plt.xlabel("Absolute Speed (m/s)")
|
||||
plt.title("Descent Wind Speed - " + title)
|
||||
plt.title("Wind Speed - " + title)
|
||||
plt.grid()
|
||||
plt.legend()
|
||||
|
||||
|
@ -403,7 +424,7 @@ def plot_wind_trace(stats, title="", gfs_file=None, landing=None):
|
|||
|
||||
plt.ylabel("Altitude (m)")
|
||||
plt.xlabel("Wind Heading (Degrees True)")
|
||||
plt.title("Descent Wind Heading - " + title)
|
||||
plt.title("Wind Heading - " + title)
|
||||
plt.grid()
|
||||
plt.legend()
|
||||
|
||||
|
@ -419,6 +440,7 @@ if __name__ == "__main__":
|
|||
parser.add_argument("--landing-lon", type=float, default=None, help="Override Landing Longitude")
|
||||
parser.add_argument("--wind-trace", action="store_true", default=False, help="Plot wind trace.")
|
||||
parser.add_argument("--gfs-file", type=str, default=None, help="Overlay GFS data on wind trace.")
|
||||
parser.add_argument("--csv-dump", type=str, default=None, help="Dump telemetry to CSV file.")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Configure logging
|
||||
|
@ -432,7 +454,7 @@ if __name__ == "__main__":
|
|||
|
||||
_log_entries = read_file(args.filename)
|
||||
|
||||
_car, _telemetry = extract_data(_log_entries)
|
||||
_car, _telemetry = extract_data(_log_entries, csv_dump=args.csv_dump)
|
||||
|
||||
for _call in _telemetry:
|
||||
logging.info("Processing Callsign: %s" % _call)
|
||||
|
|
Ładowanie…
Reference in New Issue