Example #1
0
def AnalyticalFindTP(s, h, v1, v2):
    """ Finds solution for the given parameters, solving the rearranged EOM
    analytically. Returns T and pitch needed """

    # find the flight path angle
    gamma = math.degrees(math.atan2(v2, v1))

    # find the total velocity
    V = math.sqrt(v1**2 + v2**2)

    # if v1 is above the zero-pitch flight velocity this should be negative
    if ZeroPitchCruiseV(s, 0) < v2:
        initialGuess = -1

    else:
        initialGuess = 1


    f = lambda p: 0.5 * Density(h) * AC['S'] * V ** 2 *\
                   ( GetCl(p-gamma) * (dsin(gamma)/dcos(p) + dcos(gamma)/dsin(p)) +\
                   GetCd(p-gamma, h) * (dcos(gamma)/dcos(p) - dsin(gamma)/dsin(p)) )\
                   - s.totalMass * AC['g'] / dsin(p)

    pitch = fsolve(f, initialGuess)

    # fsolve fails sometimes, can't figure out why. Initial guess changing doesnt seem to work

    if abs(f(pitch)) > 0.1:
        pitch = fsolve(f, -initialGuess)
        if abs(f(pitch)) > 0.1:
            print(
                'AnalyticalFindTP() could not find the zero on the second attempt.',
                pitch, v1, v2, f(pitch))
            raise ValueError('fsolve failed \n')


    T = 0.5 * Density(h) * AC['S'] * V ** 2 / dcos(pitch) * \
        (GetCl(pitch-gamma) * dsin(gamma) + GetCd(pitch-gamma, h) * dcos(gamma))

    T2 = 0.5 * Density(h) * AC['S'] * V ** 2 / dsin(pitch) *\
        (GetCd(pitch-gamma, h) * dsin(gamma) - GetCl(pitch-gamma) * dcos(gamma)) + \
        s.totalMass * AC['g'] / dsin(pitch)

    if abs(T - T2) > 1e-5:
        print('Error calculating T in AnalyticalFindTP()')
        print(T, T2, pitch, v1, v2)

    return T, pitch
Example #2
0
def GetCoeffB(alpha, gamma, h):
    """
    Returns a coefficient for the (vertical) equations of motion.Written out here to
    keep the EOMs shorter and neater. Should only be called the function which implements
    the EOMs for scipy.integrate.ode(int).

    Parameters
    ----------
    alpha : int or float
        Angle of attack.
    gamma : int or float
        Flight path angle.
    h : int or float
        Altitude.

    Raises
    ------
    ValueError
        When args of wrong type are passed

    Returns
    -------
    float
        Value of the coefficient.

    """

    return (0.5 * Density(h) * AC['S'] *
            (GetCl(alpha) * dcos(gamma) - GetCd(alpha, h) * dsin(gamma)))
Example #3
0
def LevelFlight(s, h, vReq):
    """Equations of motion for alpha = pitch, v1 = vReq and
    v2 = 0 = a2 = a1 = 0 to return the correct pitch and thrust to 
    obtain the required cruise velocity
    

    Parameters
    ----------
    s : simulate OBJECT
    h : int or float
        Altitude.
    vReq : int or float
        Required cruise velocity.

    Returns
    -------
    T : float
        Needed thrust signal.
    pitch : float
        Needed pitch signal.

    """

    # Determine on which side of the discontinuity to start the numerical root finder
    levelFlightV = ZeroPitchCruiseV(s)

    if levelFlightV > vReq:
        initialGuess = 0.1
    else:
        initialGuess = -0.1

    W = s.totalMass * AC['g']

    pitch = fsolve(lambda p: -0.5 * Density(h) * AC['S'] * vReq ** 2 * \
                   (GetCl(p) + dtan(p) * GetCd(p, h)) + W,
                   initialGuess)
    T = 0.5 * Density(h) * AC['S'] * vReq**2 * GetCd(pitch, h) / dcos(pitch)

    return T, pitch