def determine_outlanding_location(self, competition_day): task_pointM1 = competition_day.task[self.outlanding_leg].LCU_line task_point = competition_day.task[self.outlanding_leg+1].LCU_line if self.outlanding_b_record != "": b_rec = self.outlanding_b_record # outlanding distance = distance between tps minus distance from next tp to outlanding outlanding_dist = determine_distance(task_pointM1, task_point, 'tsk', 'tsk') outlanding_dist -= determine_distance(task_point, b_rec, 'tsk', 'pnt') self.outlanding_distance = outlanding_dist else: last_tp_i = self.first_start_i if self.outlanding_leg == 0 else self.tsk_i[-1] max_dist = 0 self.outlanding_b_record = self.b_records[last_tp_i] # default for i in range(len(self.b_records)): if i > last_tp_i: b_rec = self.b_records[i] # outlanding distance = distance between tps minus distance from next tp to outlanding outlanding_dist = determine_distance(task_pointM1, task_point, 'tsk', 'tsk') outlanding_dist -= determine_distance(task_point, b_rec, 'tsk', 'pnt') if outlanding_dist > max_dist: max_dist = outlanding_dist self.outlanding_b_record = b_rec self.outlanding_distance = max_dist
def taskpoint_completed(self, brecord1, brecord2): from generalFunctions import det_bearing, det_bearing_change, determine_distance, det_local_time, ss2hhmmss distance1 = determine_distance(brecord1, self.LCU_line, 'pnt', 'tsk') distance2 = determine_distance(brecord2, self.LCU_line, 'pnt', 'tsk') if self.line: if distance2 > self.r_max or distance1 > self.r_max: return False else: # both fixes within circle bearing1 = det_bearing(self.LCU_line, brecord1, 'tsk', 'pnt') bearing2 = det_bearing(self.LCU_line, brecord2, 'tsk', 'pnt') angle_wrt_orientation1 = abs( det_bearing_change(self.orientation_angle, bearing1)) angle_wrt_orientation2 = abs( det_bearing_change(self.orientation_angle, bearing2)) if self.sector_orientation == "next": # start line return angle_wrt_orientation1 < 90 < angle_wrt_orientation2 elif self.sector_orientation == "previous": # finish line return angle_wrt_orientation2 < 90 < angle_wrt_orientation1 else: print "A line with this orientation is not implemented!" else: # general sector bearing1 = det_bearing(self.LCU_line, brecord1, 'tsk', 'pnt') angle_wrt_orientation1 = abs( det_bearing_change(self.orientation_angle, bearing1)) bearing2 = det_bearing(self.LCU_line, brecord2, 'tsk', 'pnt') angle_wrt_orientation2 = abs( det_bearing_change(self.orientation_angle, bearing2)) if self.sector_orientation == "next": if self.r_min is not None: if self.r_min < distance1 < self.r_max and angle_wrt_orientation1 < self.angle_max: return (not self.r_min < distance2 < self.r_max ) or angle_wrt_orientation2 > self.angle_max elif distance1 < self.r_min and angle_wrt_orientation1 < self.angle_min: return distance2 > self.r_min or angle_wrt_orientation2 > self.angle_max else: return False else: # self.r_min is None if distance1 < self.r_max and angle_wrt_orientation1 < self.angle_max: return distance2 > self.r_min or angle_wrt_orientation2 > self.angle_max else: return False else: # normal turnpoint or finish if self.r_min is not None: if distance2 > self.r_max: return False elif self.r_min < distance2 < self.r_max: return angle_wrt_orientation2 < self.angle_max else: # distance_2 < self.r_min return angle_wrt_orientation2 < self.angle_min elif distance2 > self.r_max: return False else: # distance2 <= self.r_max return angle_wrt_orientation2 < self.angle_max
def taskpoint_completed(self, brecord1, brecord2): from generalFunctions import det_bearing, det_bearing_change, determine_distance, det_local_time, ss2hhmmss distance1 = determine_distance(brecord1, self.LCU_line, 'pnt', 'tsk') distance2 = determine_distance(brecord2, self.LCU_line, 'pnt', 'tsk') if self.line: if distance2 > self.r_max or distance1 > self.r_max: return False else: # both fixes within circle bearing1 = det_bearing(self.LCU_line, brecord1, 'tsk', 'pnt') bearing2 = det_bearing(self.LCU_line, brecord2, 'tsk', 'pnt') angle_wrt_orientation1 = abs(det_bearing_change(self.orientation_angle, bearing1)) angle_wrt_orientation2 = abs(det_bearing_change(self.orientation_angle, bearing2)) if self.sector_orientation == "next": # start line return angle_wrt_orientation1 < 90 < angle_wrt_orientation2 elif self.sector_orientation == "previous": # finish line return angle_wrt_orientation2 < 90 < angle_wrt_orientation1 else: print "A line with this orientation is not implemented!" else: # general sector bearing1 = det_bearing(self.LCU_line, brecord1, 'tsk', 'pnt') angle_wrt_orientation1 = abs(det_bearing_change(self.orientation_angle, bearing1)) bearing2 = det_bearing(self.LCU_line, brecord2, 'tsk', 'pnt') angle_wrt_orientation2 = abs(det_bearing_change(self.orientation_angle, bearing2)) if self.sector_orientation == "next": if self.r_min is not None: if self.r_min < distance1 < self.r_max and angle_wrt_orientation1 < self.angle_max: return (not self.r_min < distance2 < self.r_max) or angle_wrt_orientation2 > self.angle_max elif distance1 < self.r_min and angle_wrt_orientation1 < self.angle_min: return distance2 > self.r_min or angle_wrt_orientation2 > self.angle_max else: return False else: # self.r_min is None if distance1 < self.r_max and angle_wrt_orientation1 < self.angle_max: return distance2 > self.r_min or angle_wrt_orientation2 > self.angle_max else: return False else: # normal turnpoint or finish if self.r_min is not None: if distance2 > self.r_max: return False elif self.r_min < distance2 < self.r_max: return angle_wrt_orientation2 < self.angle_max else: # distance_2 < self.r_min return angle_wrt_orientation2 < self.angle_min elif distance2 > self.r_max: return False else: # distance2 <= self.r_max return angle_wrt_orientation2 < self.angle_max
def distance_moved_turnpoint(self, distance, current, currentP1, moved_point): from math import sqrt, cos, pi, acos if moved_point == "current": moved = current other = currentP1 angle_reduction = 0 elif moved_point == "currentP1": moved = currentP1 other = current angle_reduction = 0 elif moved_point == "both_currentP1": moved = currentP1 other = current original_distance = determine_distance(current.LCU_line, currentP1.LCU_line, 'tsk', 'tsk') distance_moved_current = current.r_max if current.angle_max == 180 else current.r_min angle_reduction = abs( acos((distance_moved_current**2 - distance**2 - original_distance**2) / (-2 * distance * original_distance))) * 180 / pi else: print "Displaced point is not recognized! " + moved_point displacement_dist = moved.r_max if moved.angle_max == 180 else moved.r_min bearing1 = moved.orientation_angle bearing2 = det_bearing(other.LCU_line, moved.LCU_line, 'tsk', 'tsk') angle = abs(det_bearing_change(bearing1, bearing2)) - angle_reduction distance = sqrt(distance**2 + displacement_dist**2 - 2 * distance * displacement_dist * cos(angle * pi / 180)) return distance
def distance_moved_turnpoint(self, distance, current, currentP1, moved_point): from math import sqrt, cos, pi, acos if moved_point == "current": moved = current other = currentP1 angle_reduction = 0 elif moved_point == "currentP1": moved = currentP1 other = current angle_reduction = 0 elif moved_point == "both_currentP1": moved = currentP1 other = current original_distance = determine_distance(current.LCU_line, currentP1.LCU_line, 'tsk', 'tsk') distance_moved_current = current.r_max if current.angle_max == 180 else current.r_min angle_reduction = abs(acos((distance_moved_current ** 2 - distance ** 2 - original_distance ** 2) / (-2 * distance * original_distance))) * 180 / pi else: print "Displaced point is not recognized! " + moved_point displacement_dist = moved.r_max if moved.angle_max == 180 else moved.r_min bearing1 = moved.orientation_angle bearing2 = det_bearing(other.LCU_line, moved.LCU_line, 'tsk', 'tsk') angle = abs(det_bearing_change(bearing1, bearing2)) - angle_reduction distance = sqrt(distance**2 + displacement_dist**2 - 2 * distance * displacement_dist * cos(angle * pi / 180)) return distance
def determine_outlanding_location(self, competition_day): task_pointM1 = competition_day.task[self.outlanding_leg].LCU_line task_point = competition_day.task[self.outlanding_leg + 1].LCU_line if self.outlanding_b_record != "": b_rec = self.outlanding_b_record # outlanding distance = distance between tps minus distance from next tp to outlanding outlanding_dist = determine_distance(task_pointM1, task_point, 'tsk', 'tsk') outlanding_dist -= determine_distance(task_point, b_rec, 'tsk', 'pnt') self.outlanding_distance = outlanding_dist else: last_tp_i = self.first_start_i if self.outlanding_leg == 0 else self.tsk_i[ -1] max_dist = 0 self.outlanding_b_record = self.b_records[last_tp_i] # default for i in range(len(self.b_records)): if i > last_tp_i: b_rec = self.b_records[i] # outlanding distance = distance between tps minus distance from next tp to outlanding outlanding_dist = determine_distance( task_pointM1, task_point, 'tsk', 'tsk') outlanding_dist -= determine_distance( task_point, b_rec, 'tsk', 'pnt') if outlanding_dist > max_dist: max_dist = outlanding_dist self.outlanding_b_record = b_rec self.outlanding_distance = max_dist
def determine_point_statistics(self, flight, competition_day): self.pointwise_all = self.get_difference_bib() for leg in range(competition_day.no_legs): self.pointwise_leg.append(self.get_difference_bib()) phase_number = 0 leg = 0 phase = self.all[phase_number]['phase'] for i in range(flight.b_records.__len__()): if flight.tsk_i[0] <= i < flight.tsk_i[-1]: if self.all[phase_number]['i_end'] == i: phase_number += 1 phase = self.all[phase_number]['phase'] if i == flight.tsk_i[leg]: leg += 1 height_difference = det_height(flight.b_records[i+1], flight.gps_altitude) -\ det_height(flight.b_records[i], flight.gps_altitude) height = det_height(flight.b_records[i], flight.gps_altitude) distance = determine_distance(flight.b_records[i], flight.b_records[i+1], 'pnt', 'pnt') time_difference = det_local_time(flight.b_records[i+1], competition_day.utc_to_local) -\ det_local_time(flight.b_records[i], competition_day.utc_to_local) time_secs = det_local_time(flight.b_records[i], competition_day.utc_to_local) date_obj = datetime.datetime(2014, 6, 21) + datetime.timedelta(seconds=time_secs) distance_task = determine_flown_task_distance(leg, flight.b_records[i], competition_day) difference_indicators = {'height_difference': height_difference, 'height': height, 'distance': distance, 'distance_task': distance_task, 'time_difference': time_difference, 'time': date_obj, 'phase': phase} self.append_differences(difference_indicators, leg)
def write_task(self): date_raw = self.LCU_lines[0][6:12] self.task_date = date_raw[0:2] + "-" + date_raw[2:4] + "-" + date_raw[ 4::] for index in range(len(self.LSEEYOU_lines)): taskpoint = Taskpoint(self.LCU_lines[index + 2], self.LSEEYOU_lines[index]) self.task.append(taskpoint) for index in range(len(self.task)): if index == 0: # necessary for index out of bounds angle = det_final_bearing(self.task[index + 1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') self.task[index].orientation_angle = angle elif index == len( self.task) - 1: # necessary for index out of bounds angle = det_final_bearing(self.task[index - 1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') self.task[index].orientation_angle = angle else: angle_start = det_final_bearing(self.task[0].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') angle_previous = det_final_bearing( self.task[index - 1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') angle_next = det_final_bearing(self.task[index + 1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') if self.task[index].sector_orientation == "fixed": pass elif self.task[index].sector_orientation == "symmetrical": self.task[index].orientation_angle = det_average_bearing( angle_previous, angle_next) elif self.task[index].sector_orientation == "next": self.task[index].orientation_angle = angle_next elif self.task[index].sector_orientation == "previous": self.task[index].orientation_angle = angle_previous elif self.task[index].sector_orientation == "start": self.task[index].orientation_angle = angle_start else: print "Unknown sector orientation! " + str( self.task[index].sector_orientation) self.no_tps = len(self.task) - 2 # excluding start and finish self.no_legs = self.no_tps + 1 for index in range(len(self.task) - 1): current = self.task[index] currentP1 = self.task[index + 1] # next is built in name distance = determine_distance(current.LCU_line, currentP1.LCU_line, 'tsk', 'tsk') if current.distance_correction is "shorten_legs": if currentP1.distance_correction is "shorten_legs": distance = self.distance_shortened_leg( distance, current, currentP1, "current") distance = self.distance_shortened_leg( distance, current, currentP1, "currentP1") elif currentP1.distance_correction is "move_tp": distance = self.distance_moved_turnpoint( distance, current, currentP1, "currentP1") distance = self.distance_shortened_leg( distance, current, currentP1, "current") elif currentP1.distance_correction is None: distance = self.distance_shortened_leg( distance, current, currentP1, "current") else: print "This distance correction does not exist! " + currentP1.distance_correction elif current.distance_correction is "move_tp": if currentP1.distance_correction is "shorten_legs": distance = self.distance_moved_turnpoint( distance, current, currentP1, "current") distance = self.distance_shortened_leg( distance, current, currentP1, "currentP1") elif currentP1.distance_correction is "move_tp": distance = self.distance_moved_turnpoint( distance, current, currentP1, "current") distance = self.distance_moved_turnpoint( distance, current, currentP1, "both_currentP1") elif currentP1.distance_correction is None: distance = self.distance_moved_turnpoint( distance, current, currentP1, "current") else: print "This distance correction does not exist! " + currentP1.distance_correction elif current.distance_correction is None: if currentP1.distance_correction is "shorten_legs": distance = self.distance_shortened_leg( distance, current, currentP1, "currentP1") elif currentP1.distance_correction is "move_tp": distance = self.distance_moved_turnpoint( distance, current, currentP1, "currentP1") elif currentP1.distance_correction is None: pass else: print "This distance correction does not exist! " + currentP1.distance_correction else: print "This distance correction does not exist! " + self.task[ index].distance_correction self.task_distances.append(distance)
def write_task(self): date_raw = self.LCU_lines[0][6:12] self.task_date = date_raw[0:2] + "-" + date_raw[2:4] + "-" + date_raw[4::] for index in range(len(self.LSEEYOU_lines)): taskpoint = Taskpoint(self.LCU_lines[index+2], self.LSEEYOU_lines[index]) self.task.append(taskpoint) for index in range(len(self.task)): if index == 0: # necessary for index out of bounds angle = det_final_bearing(self.task[index+1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') self.task[index].orientation_angle = angle elif index == len(self.task) - 1: # necessary for index out of bounds angle = det_final_bearing(self.task[index-1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') self.task[index].orientation_angle = angle else: angle_start = det_final_bearing(self.task[0].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') angle_previous = det_final_bearing(self.task[index-1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') angle_next = det_final_bearing(self.task[index+1].LCU_line, self.task[index].LCU_line, 'tsk', 'tsk') if self.task[index].sector_orientation == "fixed": pass elif self.task[index].sector_orientation == "symmetrical": self.task[index].orientation_angle = det_average_bearing(angle_previous, angle_next) elif self.task[index].sector_orientation == "next": self.task[index].orientation_angle = angle_next elif self.task[index].sector_orientation == "previous": self.task[index].orientation_angle = angle_previous elif self.task[index].sector_orientation == "start": self.task[index].orientation_angle = angle_start else: print "Unknown sector orientation! " + str(self.task[index].sector_orientation) self.no_tps = len(self.task) - 2 # excluding start and finish self.no_legs = self.no_tps + 1 for index in range(len(self.task)-1): current = self.task[index] currentP1 = self.task[index+1] # next is built in name distance = determine_distance(current.LCU_line, currentP1.LCU_line, 'tsk', 'tsk') if current.distance_correction is "shorten_legs": if currentP1.distance_correction is "shorten_legs": distance = self.distance_shortened_leg(distance, current, currentP1, "current") distance = self.distance_shortened_leg(distance, current, currentP1, "currentP1") elif currentP1.distance_correction is "move_tp": distance = self.distance_moved_turnpoint(distance, current, currentP1, "currentP1") distance = self.distance_shortened_leg(distance, current, currentP1, "current") elif currentP1.distance_correction is None: distance = self.distance_shortened_leg(distance, current, currentP1, "current") else: print "This distance correction does not exist! " + currentP1.distance_correction elif current.distance_correction is "move_tp": if currentP1.distance_correction is "shorten_legs": distance = self.distance_moved_turnpoint(distance, current, currentP1, "current") distance = self.distance_shortened_leg(distance, current, currentP1, "currentP1") elif currentP1.distance_correction is "move_tp": distance = self.distance_moved_turnpoint(distance, current, currentP1, "current") distance = self.distance_moved_turnpoint(distance, current, currentP1, "both_currentP1") elif currentP1.distance_correction is None: distance = self.distance_moved_turnpoint(distance, current, currentP1, "current") else: print "This distance correction does not exist! " + currentP1.distance_correction elif current.distance_correction is None: if currentP1.distance_correction is "shorten_legs": distance = self.distance_shortened_leg(distance, current, currentP1, "currentP1") elif currentP1.distance_correction is "move_tp": distance = self.distance_moved_turnpoint(distance, current, currentP1, "currentP1") elif currentP1.distance_correction is None: pass else: print "This distance correction does not exist! " + currentP1.distance_correction else: print "This distance correction does not exist! " + self.task[index].distance_correction self.task_distances.append(distance)
def determine_phases(self, settings, competitionday, flight): b_record_m1 = flight.b_records[flight.tsk_i[0] - 2] time_m1 = det_local_time(b_record_m1, competitionday.utc_to_local) b_record = flight.b_records[flight.tsk_i[0] - 1] time = det_local_time(b_record, competitionday.utc_to_local) bearing = det_bearing(b_record_m1, b_record, 'pnt', 'pnt') cruise = True possible_cruise_start = 0 possible_thermal_start = 0 cruise_distance = 0 temp_bearing_change = 0 possible_turn_dir = 'left' sharp_thermal_entry_found = False bearing_change_tot = 0 leg = 0 self.create_entry(flight.tsk_i[0], time_m1, 'cruise', -2) self.create_entry(flight.tsk_i[0], time_m1, 'cruise', leg) for i in range(len(flight.b_records)): if flight.tsk_i[0] < i < flight.tsk_i[-1]: time_m2 = time_m1 time_m1 = time bearing_m1 = bearing b_record_m1 = b_record b_record = flight.b_records[i] time = det_local_time(b_record, competitionday.utc_to_local) bearing = det_bearing(b_record_m1, b_record, 'pnt', 'pnt') bearing_change = det_bearing_change(bearing_m1, bearing) bearing_change_rate = bearing_change / (time - 0.5*time_m1 - 0.5*time_m2) if i == flight.tsk_i[leg+1]: phase = 'cruise' if cruise else 'thermal' leg += 1 self.close_entry(i, time, leg-1) self.create_entry(i, time, phase, leg) if cruise: if (possible_turn_dir == 'left' and bearing_change_rate < 1e-2) or\ (possible_turn_dir == 'right' and bearing_change_rate > -1e-2): bearing_change_tot += det_bearing_change(bearing_m1, bearing) if possible_thermal_start == 0: possible_thermal_start = i elif (not sharp_thermal_entry_found) and abs(bearing_change_rate) > settings.cruise_threshold_bearingRate: sharp_thermal_entry_found = True possible_thermal_start = i else: # sign change bearing_change_tot = det_bearing_change(bearing_m1, bearing) if bearing_change_rate < 0: possible_turn_dir = 'left' else: possible_turn_dir = 'right' possible_thermal_start = i if abs(bearing_change_tot) > settings.cruise_threshold_bearingTot: cruise = False thermal_start_time = det_local_time(flight.b_records[possible_thermal_start], competitionday.utc_to_local) self.close_entry(possible_thermal_start, thermal_start_time, -2) self.close_entry(possible_thermal_start, thermal_start_time, leg) self.create_entry(possible_thermal_start, thermal_start_time, 'thermal', -2) self.create_entry(possible_thermal_start, thermal_start_time, 'thermal', leg) possible_thermal_start = 0 sharp_thermal_entry_found = False bearing_change_tot = 0 else: # thermal if abs(bearing_change_rate) > settings.thermal_threshold_bearingRate: if possible_cruise_start != 0: cruise_distance = 0 temp_bearing_change = 0 else: # possible cruise if cruise_distance == 0: possible_cruise_start = i possible_cruise_t = time temp_bearing_change += bearing_change temp_bearing_rate_avg = 0 else: temp_bearing_change += bearing_change temp_bearing_rate_avg = temp_bearing_change / (time-possible_cruise_t) cruise_distance = determine_distance(flight.b_records[possible_cruise_start-1], b_record, 'pnt', 'pnt') if cruise_distance > settings.thermal_threshold_distance and \ abs(temp_bearing_rate_avg) < settings.thermal_threshold_bearingRateAvg: cruise = True self.close_entry(possible_cruise_start, possible_cruise_t, -2) self.close_entry(possible_cruise_start, possible_cruise_t, leg) self.create_entry(possible_cruise_start, possible_cruise_t, 'cruise', -2) self.create_entry(possible_cruise_start, possible_cruise_t, 'cruise', leg) possible_cruise_start = 0 cruise_distance = 0 temp_bearing_change = 0 bearing_change_tot = 0 time = det_local_time(flight.b_records[flight.tsk_i[-1]], competitionday.utc_to_local) self.close_entry(flight.tsk_i[-1], time, -2) self.close_entry(flight.tsk_i[-1], time, leg)
def determine_performance(self, flight, competitionday): thermal_altitude_gain_tot = 0 thermal_altitude_loss_tot = 0 thermal_time_tot = 0 thermal_distance_tot = 0 thermal_drift_tot = 0 cruise_time_tot = 0 cruise_distance_tot = 0 cruise_height_diff_tot = 0 for leg in range(competitionday.no_legs): thermal_altitude_gain = 0 thermal_altitude_loss = 0 thermal_time = 0 thermal_distance = 0 thermal_drift = 0 cruise_time = 0 cruise_distance = 0 cruise_height_diff = 0 for point in range(len(flight.phases.pointwise_leg[leg]['phase'])): leg_pointwise = flight.phases.pointwise_leg[leg] cruise = True if leg_pointwise["phase"][point] == 'cruise' else False if cruise: cruise_time += leg_pointwise["time_difference"][point] cruise_distance += leg_pointwise["distance"][point] cruise_height_diff += leg_pointwise["height_difference"][point] else: thermal_time += leg_pointwise["time_difference"][point] thermal_distance += leg_pointwise["distance"][point] if leg_pointwise["height_difference"][point] > 0: thermal_altitude_gain += leg_pointwise["height_difference"][point] else: thermal_altitude_loss += leg_pointwise["height_difference"][point] for entry in flight.phases.leg[leg]: if entry["phase"] == "thermal": i_st = entry["i_start"] i_end = entry["i_end"] thermal_drift += determine_distance(flight.b_records[i_st], flight.b_records[i_end], 'pnt', 'pnt') # write to total performance values thermal_altitude_gain_tot += thermal_altitude_gain thermal_altitude_loss_tot += thermal_altitude_loss thermal_time_tot += thermal_time thermal_distance_tot += thermal_distance thermal_drift_tot += thermal_drift cruise_time_tot += cruise_time cruise_distance_tot += cruise_distance cruise_height_diff_tot += cruise_height_diff self.write_perfs(leg, thermal_altitude_gain, thermal_altitude_loss, thermal_time, thermal_distance, thermal_drift, cruise_time, cruise_distance, cruise_height_diff) self.write_perfs(-1, thermal_altitude_gain_tot, thermal_altitude_loss_tot, thermal_time_tot, thermal_distance_tot, thermal_drift_tot, cruise_time_tot, cruise_distance_tot, cruise_height_diff_tot)