def compute_next_flight_point(self, flight_points: List[FlightPoint], time_step: float) -> FlightPoint: """ Computes time, altitude, speed, mass and ground distance of next flight point. :param flight_points: previous flight points :param time_step: time step for computing next point :return: the computed next flight point """ start = flight_points[0] previous = flight_points[-1] next_point = FlightPoint() next_point.mass = previous.mass - self.propulsion.get_consumed_mass( previous, time_step) next_point.time = previous.time + time_step next_point.ground_distance = ( previous.ground_distance + previous.true_airspeed * time_step * np.cos(previous.slope_angle)) self._compute_next_altitude(next_point, previous) if self.target.true_airspeed == self.CONSTANT_VALUE: next_point.true_airspeed = previous.true_airspeed elif self.target.equivalent_airspeed == self.CONSTANT_VALUE: next_point.equivalent_airspeed = start.equivalent_airspeed elif self.target.mach == self.CONSTANT_VALUE: next_point.mach = start.mach else: next_point.true_airspeed = previous.true_airspeed + time_step * previous.acceleration # The naming is not done in complete_flight_point for not naming the start point next_point.name = self.name return next_point
def compute_from(self, start: FlightPoint) -> pd.DataFrame: self.complete_flight_point( start) # needed to ensure all speed values are computed. if self.target.altitude is not None: if isinstance(self.target.altitude, str): # Target altitude will be modified along the process, so we keep track # of the original order in target CL, that is not used otherwise. self.target.CL = self.target.altitude # pylint: disable=invalid-name # let's put a numerical, negative value in self.target.altitude to # ensure there will be no problem in self._get_distance_to_target() self.target.altitude = -1000.0 self.interrupt_if_getting_further_from_target = False else: # Target altitude is fixed, back to original settings (in case # this instance is used more than once) self.target.CL = None self.interrupt_if_getting_further_from_target = True atm = AtmosphereSI(start.altitude) if self.target.equivalent_airspeed == self.CONSTANT_VALUE: atm.equivalent_airspeed = start.equivalent_airspeed start.true_airspeed = atm.true_airspeed elif self.target.mach == self.CONSTANT_VALUE: atm.mach = start.mach start.true_airspeed = atm.true_airspeed return super().compute_from(start)
def _complete_speed_values(flight_point: FlightPoint): """ Computes consistent values between TAS, EAS and Mach, assuming one of them is defined. """ atm = AtmosphereSI(flight_point.altitude) if flight_point.true_airspeed is None: if flight_point.mach is not None: atm.mach = flight_point.mach elif flight_point.equivalent_airspeed is not None: atm.equivalent_airspeed = flight_point.equivalent_airspeed else: raise FastFlightSegmentIncompleteFlightPoint( "Flight point should be defined for true_airspeed, " "equivalent_airspeed, or mach.") flight_point.true_airspeed = atm.true_airspeed else: atm.true_airspeed = flight_point.true_airspeed flight_point.mach = atm.mach flight_point.equivalent_airspeed = atm.equivalent_airspeed