Exemple #1
0
def cfunc(x, params):
    """
    this function returns the constraint violation of the 3seg leg.
    it must be zeroed!

    Parameters
    ----------

    x
        configuration of the leg: Fy, h1, h2, tau1, tau2

    params
        parameter of the system: l, l1, l2, l3, c1, c2


    Returns
    -------
    eq : *array* (1x5)
        the non-fulfilment of the constraints (subject to root finding)

    """

    l, l1, l2, l3, c1, c2 = params
    # print l, l1, l2, l3, c1, c2
    Fy, h1, h2, tau1, tau2 = array(x).squeeze()
    # print Fy, h1, h2, tau1, tau2

    if h1 > l1:
        print "warning: invalid h1"
        h1 = l1
        return [
            5000,
        ] * 5
    if h2 > l3:
        print "warning: invalid h2"
        h2 = l2
        return [
            5000,
        ] * 5
    if h1 + h2 > l2:
        print "warning: invalid h1 + h2"
        return [
            5000,
        ] * 5
        while h1 + h2 > l2:
            h1 = .8 * h1
            h2 = .8 * h2

    eq1 = Fy * h1 - tau1
    eq2 = tau1 - Fy * h1 - Fy * h2 + tau2
    eq3 = Fy * h2 - tau2
    eq4 = -1. * c1 * (arccos(h1 / l1) + arccos(
        (h1 + h2) / l2) - .9 * pi) - tau1
    eq5 = -1. * c2 * (arccos(h2 / l3) + arccos(
        (h1 + h2) / l2) - .9 * pi) - tau2
    eq6 = sqrt(l1**2 - h1**2) + sqrt(l2**2 -
                                     (h1 + h2)**2) + sqrt(l3**2 - h2**2) - l

    # note: eq2 is omitted because of equality to - (eq1 + eq3)!
    return array([eq1, eq3, eq4, eq5, eq6])
def FreezeDuration_calculator(pointing_altitude1, pointing_altitude2, TLE2):
    """Function that calculates the angle between two tangential altitudes and then calculates
    the time it takes for orbital position angle of a satellite in a circular orbit to change by the same amount.
    
    Used to estimate the duration of an attitude freeze for which the pointing altitude reorients itself to the standard pointing altitude.
    
    Arguments:
        pointing_altitude1 (int): First tangential pointing altitude in m
        pointing_altitude2 (int): Second tangential pointing altitude in m
        TLE2 (str): Second row of a TLE.
        
    Returns:
        (int): FreezeDuration, Time [s] it takes for the satellites orbital position angle to change 
        by the same amount as the angle between the two tangential pointing altitudes as seen from the satellite.
    """

    U = 398600.4418  # Earth gravitational parameter
    MATS_P = 24 * 3600 / float(TLE2[52:63])  # Orbital Period of MATS [s]
    MATS_p = ((MATS_P / 2 / pi)**2 * U)**(
        1 / 3)  # Semi-major axis of MATS assuming circular orbit [km]
    R_mean = 6371  # Mean Earth radius [km]
    pitch1 = arccos((R_mean + pointing_altitude1 / 1000) / (MATS_p)) / pi * 180
    pitch2 = arccos((R_mean + pointing_altitude2 / 1000) / (MATS_p)) / pi * 180
    pitch_angle_difference = abs(pitch1 - pitch2)

    "#The time it takes for the orbital position angle to change by the same amount as"
    "#the angle between the pointing axes"
    FreezeDuration = int(round(MATS_P * (pitch_angle_difference) / 360, 0))

    return FreezeDuration
Exemple #3
0
def match_SIFT(desc1, desc2):
    '''For each descriptor in the first image, select its match in the second image.
    input: desc1 (descriptors for the first image),
    desc2 (same for the second image).'''

    desc1 = np.array([d / plt.linalg.norm(d) for d in desc1])
    desc2 = np.array([d / plt.linalg.norm(d) for d in desc2])

    dist_ratio = 0.6
    desc1_size = desc1.shape

    matchscores = np.zeros((desc1_size[0], 1), 'int')
    desc2t = desc2.T  #precompute matrix transpose
    for i in range(desc1_size[0]):
        dotprods = np.dot(desc1[i, :], desc2t)  #vector of dot products
        dotprods = 0.9999 * dotprods
        # inverse cosine and sort, return index for features in second Image
        indx = np.argsort(plt.arccos(dotprods))

        # check if nearest neighbor has angle less than dist_ratio times 2nd
        if plt.arccos(dotprods)[
                indx[0]] < dist_ratio * plt.arccos(dotprods)[indx[1]]:
            matchscores[i] = np.int(indx[0])

    return matchscores
def cartesian2polar(xyz):
    """cartesian2polar(x, y, z)
converts coordinate from xyz to r\theta\phi"""
    x, y, z = xyz
    ## if z == 0:
    ##     raise exceptions.ValueError("cartesian " + str(xyz) + " z must be nonzero.")

    r = pylab.sqrt(sum(map(lambda x: x**2, [x, y, z])))
    theta = pylab.arccos(z / r)
    phi = pylab.arccos(x / pylab.sqrt(sum(map(lambda x: x**2, [x, y]))))
    if y < 0: phi *= -1

    return (r, theta, phi)
def cartesian2polar(xyz):
    """cartesian2polar(x, y, z)
converts coordinate from xyz to r\theta\phi"""
    x, y, z = xyz
    ## if z == 0:
    ##     raise exceptions.ValueError("cartesian " + str(xyz) + " z must be nonzero.")

    r = pylab.sqrt(sum(map(lambda x: x**2, [x, y, z])))
    theta = pylab.arccos(z/r)
    phi = pylab.arccos(x / pylab.sqrt(sum(map(lambda x: x**2, [x, y]))))
    if y < 0: phi *= -1

    return (r, theta, phi)
Exemple #6
0
 def vectors_to_Angle(self, aV1, aV2):
     mVect1 = pylab.matrix(aV1)
     mVect2 = pylab.matrix(aV2)
     nNorms = (pylab.norm(mVect1) * pylab.norm(mVect2))
     if nNorms == 0: return "-"
     nAngle = pylab.arccos(mVect1 * mVect2.T / nNorms)
     return float(nAngle)
Exemple #7
0
 def vectors_to_Angle(self, aV1, aV2):
     mVect1 = pylab.matrix(aV1);
     mVect2 = pylab.matrix(aV2);
     nNorms = (pylab.norm(mVect1)*pylab.norm(mVect2));
     if nNorms==0: return float('nan');
     nAngle = pylab.arccos(mVect1*mVect2.T/nNorms);
     return float(nAngle);
Exemple #8
0
def getMohoEvePA(t):
    moho = tk.Moho.eph(t)[0][:2]
    eve = tk.Eve.eph(t)[0][:2]
    
    moho = moho / norm(moho)
    eve = eve / norm(eve)
    
    return degrees(arccos(moho.dot(eve)))
Exemple #9
0
def getMohoKerbinPA(t):
    moho = tk.Moho.eph(t)[0][:2]
    kerbin = tk.Kerbin.eph(t)[0][:2]
    
    moho = moho / norm(moho)
    kerbin = kerbin / norm(kerbin)
    
    return degrees(arccos(moho.dot(kerbin)))
Exemple #10
0
def sine_single(mini, maxi):
    """
    generator function for psudo random numbers from a single seed
    under pdf = 0.5*pl.sin(x)
    to be used in rejection method
    """
    f = lambda x: pl.arccos(1 - 2 * x)
    while True:
        yield f(random.uniform(mini, maxi))
Exemple #11
0
def my_hor_to_eq(az, el, lat, lsts):
    dec = arcsin(sin(el) * sin(lat) + cos(el) * cos(lat) * cos(az))
    argument = (sin(el) - sin(lat) * sin(dec)) / (cos(lat) * cos(dec))
    argument = clip(argument, -1.0, 1.0)
    H = arccos(argument)
    flag = sin(az) > 0
    H[flag] = 2.0*pi - H[flag]
    ra = lsts - H
    ra %= 2*pi
    return ra,dec
Exemple #12
0
def eq_to_hor(ra, dec, lat, lst):
    H = lst - ra
    el = arcsin(sin(dec) * sin(lat) + cos(dec) * cos(lat) * cos(H))
    az = arccos((sin(dec) - sin(lat) * sin(el)) / (cos(lat) * cos(el)))
    flag = sin(H) > 0
    if type(flag) is ndarray:
        az[flag] = 2.0 * pi - az[flag]
    elif flag:
        az = 2.0 * pi - az
    return az, el
Exemple #13
0
    def draw_rand_sphere_pos(self):
        azimuth = (pl.rand(self.n) - 0.5) * 2 * pl.pi
        zenith = pl.arccos(2 * pl.rand(self.n) - 1)
        r = pl.rand(self.n)**(2. / 3.) * self.radius

        x = r * pl.sin(zenith) * pl.cos(azimuth)
        y = r * pl.sin(zenith) * pl.sin(azimuth)
        z = r * pl.cos(zenith)

        soma_pos = {'xpos': x, 'ypos': y, 'zpos': z, 'r': r}
        return soma_pos
Exemple #14
0
def transformation(N, mini, maxi, bins):
    start_time = time.time()

    a = uniform(N, mini, maxi, bins)[0]
    f = lambda x: pl.arccos(1 - 2 * x)  #implements calculated cdf
    l = [f(i) for i in a]

    print("Time for transformation method with %s points: %s" %
          (N, time.time() - start_time))
    transformation.time = time.time() - start_time
    return l
Exemple #15
0
def hor_to_eq(az, el, lat, lst):
    dec = arcsin(sin(el) * sin(lat) + cos(el) * cos(lat) * cos(az))
    argument = (sin(el) - sin(lat) * sin(dec)) / (cos(lat) * cos(dec))
    argument = pylab.clip(argument, -1.0, 1.0)
    H = arccos(argument)
    flag = sin(az) > 0
    if type(flag) is ndarray:
        H[flag] = 2.0 * pi - H[flag]
    elif flag:
        H = 2.0 * pi - H
    ra = lst - H
    ra %= 2 * pi
    return ra, dec
Exemple #16
0
    def fitOscillations(self, harmonics=None):
        """"""
        t = self.variableArray
        dt = t[1] - t[0]
        data = self.orders[0]

        amp_guess = (data.max() - data.min()) / 2
        weights = abs(py.fft(data))**2
        index = weights.argmax() if harmonics is None else harmonics
        f_guess = py.fftfreq(t[-1] - t[0], dt)[index]
        offset_guess = data.mean()
        phi_guess = py.arccos(data[0] - offset_guess)
        guesses = [amp_guess, f_guess, phi_guess, offset_guess]
        self.guesses = guesses

        coeffs, matcov = curve_fit(self.func, t, data, self.guesses)
        self.coeffs = coeffs
        self.matcov = matcov
Exemple #17
0
def branch_angle(G, parent, child1, child2):
    parent_coord = pylab.array(G.node[parent]['coord'])
    child1_coord = pylab.array(G.node[child1]['coord'])
    child2_coord = pylab.array(G.node[child2]['coord'])

    v1 = child1_coord - parent_coord
    v2 = child2_coord - parent_coord

    m1 = ((v1**2).sum())**0.5
    m2 = ((v2**2).sum())**0.5

    dp = pylab.dot(v1, v2)

    cos = dp / (m1 * m2)
    if cos < -1:
        cos = 1
    elif cos > 1:
        cos = 1
    theta = pylab.arccos(cos)

    return theta
Exemple #18
0
def SunAngle(PositionVector, SimulationTime):
    """Calculates angle between a position vector and the position vector of the Sun.

    Simulates a single point in time for the Sun observed from Earth using Skyfield and then calculates the angle between the position vector of the Sun and the given input position vector.
    Used to determine the eclipse angle of the Sun angle of the position.

    Arguments:
        PositionVector (array): Position vector.
        SimulationTime (:obj:`ephem.Date`): The time of the simulation.

    Returns:
        (float): The sun angle [degrees].

    """

    current_time_datetime = ephem.Date(SimulationTime).datetime()
    year = current_time_datetime.year
    month = current_time_datetime.month
    day = current_time_datetime.day
    hour = current_time_datetime.hour
    minute = current_time_datetime.minute
    second = current_time_datetime.second + current_time_datetime.microsecond / 1000000

    current_time_skyfield = timescale_skyfield.utc(
        year, month, day, hour, minute, second
    )

    Sun = database_skyfield["Sun"]
    Earth = database_skyfield["Earth"]

    SunFromEarth = Earth.at(current_time_skyfield).observe(Sun)
    r_SunFromEarth_km = SunFromEarth.position.km

    SunAngle = arccos(
        dot(PositionVector, r_SunFromEarth_km)
        / (norm(r_SunFromEarth_km) * norm(PositionVector))
    )
    SunAngle = SunAngle / pi * 180

    return SunAngle
Exemple #19
0
def generate_datafile(name,departures,depart_planet,arrive_planet,errors=0):
    f = open(name,'w')
    last = departures[-1]
    lasty = int(last[0] / 60.0 / 60.0 / 24.0 / 365.0)
    inacc = 0.0
    for departure in departures:
        if departure[1]:
            inacc += 1.0
            
    f.write("// Phase angles for the next %i years for %s - %s Hohmann transfers\n"%(lasty,depart_planet.name,arrive_planet.name))
    f.write("// Calculated using the KSP Mission Control toolkit\n")
    f.write("// Angles are valid for Kerbal Space Program 0.19\n")
    f.write("// Total windows: %i\n"%len(departures))
    f.write("// Inaccuracies during calculation: %i (%i%%)\n\n"%(inacc,inacc / len(departures) * 100))
    f.write("UT Departure\tPhase angle\tDate time\tAccurate (Error in seconds)\n")
    for departure in departures:
        accurate = departure[1]
        if accurate == 0:
            accurate = "Yes"
        else:
            accurate = str(accurate)
            
        departure = departure[0]
        
        e1 = depart_planet.eph(departure)[0]
        e2 = arrive_planet.eph(departure)[0]
        e1 /= norm(e1)
        e2 /= norm(e2)
        PA = degrees(arccos(e1.dot(e2))) * sign(cross(e1,e2)[2])
        
        years = floor(departure/60.0/60.0/24.0/365.0)+1
        days = floor((departure/60.0/60.0/24.0)%365.0)+1
        
        f.write("%f\t%f\tYear %i, Day %i\t%s\n"%(departure,PA,years,days,accurate))
        
    f.close()
Exemple #20
0
 def __init__(self,celestialFrom,celestialTo,timeRange,multiplier=86400.0):
     self.figure = figure(figsize=(8,8))
     self.axis = self.figure.gca(projection="rectilinear")#,aspect='equal')
     
     X = []
     Y = []        
     
     for t in timeRange:
         t *= multiplier
         
         ephFrom = celestialFrom.eph(t)
         ephTo= celestialTo.eph(t)
         
         pFrom = ephFrom[0] / norm(ephFrom[0])
         pTo = ephTo[0] / norm(ephTo[0])
         print pFrom
         print pTo
         print "ye",t
         angle = degrees(arccos(pFrom.dot(pTo)))
         
         X.append(t/multiplier)
         Y.append(angle)
         
     self.axis.plot(X,Y)
A = ma * mb * Ta
B = mB + mb
C = (mB + mb) / mb
D = C * 2. * mb * Tb
E = 2. * ma * Ta
F0 = 2. * mB * (Q0 + Ta)
F1 = 2. * mB * (Q1 + Ta)
F2 = 2. * mB * (Q2 + Ta)
G = 2. * py.sqrt(2. * ma * Ta) * py.sqrt(2. * mb * Tb)

primer = (py.sqrt(A)) / (B)
segundo0 = (B) * (mB * Q0 + (mB - ma) * Ta)
segundo1 = (B) * (mB * Q1 + (mB - ma) * Ta)
segundo2 = (B) * (mB * Q2 + (mB - ma) * Ta)

thetamin0 = py.arccos(py.sqrt(-segundo0 / A))
thetamin1 = py.arccos(py.sqrt(-segundo1 / A))
thetamin2 = py.arccos(py.sqrt(-segundo2 / A))
print('thetamin0=', thetamin0)
print('thetamin1=', thetamin1)
print('thetamin2=', thetamin2)
print('')

x = py.arange(0, thetamin0, 0.000005)
y1 = (py.cos(x) * primer + (py.sqrt(A * (py.cos(x)**2) + segundo0) / B))**2
y2 = (py.cos(x) * primer - (py.sqrt(A * (py.cos(x)**2) + segundo0) / B))**2
y3 = (py.cos(x) * primer + (py.sqrt(A * (py.cos(x)**2) + segundo1) / B))**2
y4 = (py.cos(x) * primer - (py.sqrt(A * (py.cos(x)**2) + segundo1) / B))**2
y5 = (py.cos(x) * primer + (py.sqrt(A * (py.cos(x)**2) + segundo2) / B))**2
y6 = (py.cos(x) * primer - (py.sqrt(A * (py.cos(x)**2) + segundo2) / B))**2
Exemple #22
0
def lambert(r1vec,r2vec,tf,m,muC):
# original documentation:
# ·············································
#
# This routine implements a new algorithm that solves Lambert's problem. The
# algorithm has two major characteristics that makes it favorable to other
# existing ones.
#
# 1) It describes the generic orbit solution of the boundary condition
# problem through the variable X=log(1+cos(alpha/2)). By doing so the
# graph of the time of flight become defined in the entire real axis and
# resembles a straight line. Convergence is granted within few iterations
# for all the possible geometries (except, of course, when the transfer
# angle is zero). When multiple revolutions are considered the variable is
# X=tan(cos(alpha/2)*pi/2).
#
# 2) Once the orbit has been determined in the plane, this routine
# evaluates the velocity vectors at the two points in a way that is not
# singular for the transfer angle approaching to pi (Lagrange coefficient
# based methods are numerically not well suited for this purpose).
#
# As a result Lambert's problem is solved (with multiple revolutions
# being accounted for) with the same computational effort for all
# possible geometries. The case of near 180 transfers is also solved
# efficiently.
#
#  We note here that even when the transfer angle is exactly equal to pi
# the algorithm does solve the problem in the plane (it finds X), but it
# is not able to evaluate the plane in which the orbit lies. A solution
# to this would be to provide the direction of the plane containing the
# transfer orbit from outside. This has not been implemented in this
# routine since such a direction would depend on which application the
# transfer is going to be used in.
#
# please report bugs to [email protected]    
#
# adjusted documentation:
# ·······················
#
# By default, the short-way solution is computed. The long way solution
# may be requested by giving a negative value to the corresponding
# time-of-flight [tf].
#
# For problems with |m| > 0, there are generally two solutions. By
# default, the right branch solution will be returned. The left branch
# may be requested by giving a negative value to the corresponding
# number of complete revolutions [m].

# Authors
# .·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.·`·.
# Name       : Dr. Dario Izzo
# E-mail     : [email protected]
# Affiliation: ESA / Advanced Concepts Team (ACT)

# Made readible and optimized for speed by Rody P.S. Oldenhuis
# Code available in MGA.M on   http://www.esa.int/gsp/ACT/inf/op/globopt.htm

# last edited 12/Dec/2009

# ADJUSTED FOR EML-COMPILATION 24/Dec/2009
    
    # initial values        
    tol = 1e-12
    bad = False
    days = 1

    # work with non-dimensional units
    r1 = norm(r1vec) #sqrt(r1vec*r1vec.');  r1vec = r1vec/r1;
    r1vec = r1vec / r1
    r2vec = r2vec / r1
    
    V = sqrt(muC/r1)     
    T = r1/V              
    tf= tf*days/T # also transform to seconds

    # relevant geometry parameters (non dimensional)
    mr2vec = norm(r2vec)
    # make 100# sure it's in (-1 <= dth <= +1)
    dth = arccos( max(-1, min(1, (r1vec.dot(r2vec)/mr2vec))))  
    
        
    # decide whether to use the left or right branch (for multi-revolution
    # problems), and the long- or short way    
    leftbranch = sign(m)
    longway = sign(tf)
    m = abs(m)
    tf = abs(tf)
    if (longway < 0):
        dth = 2*pi - dth  

    # derived quantities        
    c      = sqrt(1.0 + mr2vec**2 - 2*mr2vec*cos(dth)) # non-dimensional chord
    s      = (1.0 + mr2vec + c)/2.0                    # non-dimensional semi-perimeter
    a_min  = s/2.0                              # minimum energy ellipse semi major axis
    Lambda = sqrt(mr2vec)*cos(dth/2.0)/s              # lambda parameter (from BATTIN's book)

    crossprd = cross(r1vec,r2vec)

    mcr       = norm(crossprd)           # magnitues thereof
    nrmunit   = crossprd/mcr                        # unit vector thereof
    
    # Initial values
    # ·························································

    # ELMEX requires this variable to be declared OUTSIDE the IF-statement
    logt = log(tf); # avoid re-computing the same value
    
    # single revolution (1 solution)
    if (m == 0):

        # initial values        
        inn1 = -0.5233      # first initial guess
        inn2 = +0.5233      # second initial guess
        x1   = log(1 + inn1)# transformed first initial guess
        x2   = log(1 + inn2)# transformed first second guess

        # multiple revolutions (0, 1 or 2 solutions)
        # the returned soltuion depends on the sign of [m]
    else:          
        # select initial values
        if (leftbranch < 0):
            inn1 = -0.5234 # first initial guess, left branch
            inn2 = -0.2234 # second initial guess, left branch
        else:
            inn1 = +0.7234 # first initial guess, right branch
            inn2 = +0.5234 # second initial guess, right branch
        x1 = tan(inn1*pi/2)# transformed first initial guess
        x2 = tan(inn2*pi/2)# transformed first second guess
    

    # since (inn1, inn2) < 0, initial estimate is always ellipse
    xx   = array([inn1, inn2])
    aa = a_min/(1 - xx**2)
    
    bbeta = longway * 2*arcsin(sqrt((s-c)/2./aa))
    # make 100.4% sure it's in (-1 <= xx <= +1)
    if xx[0] > 1: xx[0] = 1
    if xx[0] < -1: xx[0] = -1
    if xx[1] > 1: xx[1] = 1
    if xx[1] < -1: xx[1] = -1
    aalfa = 2*arccos( xx )

    # evaluate the time of flight via Lagrange expression
    y12  = aa*sqrt(aa)*((aalfa - sin(aalfa)) - (bbeta-sin(bbeta)) + 2*pi*m)

    # initial estimates for y
    if m == 0:
        y1 = log(y12[0]) - logt
        y2 = log(y12[1]) - logt
    else:
        y1 = y12[0] - tf
        y2 = y12[1] - tf
    

    # Solve for x
    # ·························································
    
    # Newton-Raphson iterations
    # NOTE - the number of iterations will go to infinity in case
    # m > 0  and there is no solution. Start the other routine in 
    # that case
    
    err = 1e99  
    iterations = 0
    xnew = 0
    while (err > tol):
        # increment number of iterations
        iterations += 1
        # new x
        xnew = (x1*y2 - y1*x2) / (y2-y1);
        # copy-pasted code (for performance)
        if m == 0:
            x = exp(xnew) - 1
        else:
            x = arctan(xnew)*2/pi
            
        a = a_min/(1 - x**2);
        if (x < 1): # ellipse
            beta = longway * 2*arcsin(sqrt((s-c)/2/a))
            # make 100.4% sure it's in (-1 <= xx <= +1)
            alfa = 2*arccos( max(-1, min(1, x)) )
        else: # hyperbola
            alfa = 2*arccosh(x);
            beta = longway * 2*arcsinh(sqrt((s-c)/(-2*a)))
        
        # evaluate the time of flight via Lagrange expression
        if (a > 0):
            tof = a*sqrt(a)*((alfa - sin(alfa)) - (beta-sin(beta)) + 2*pi*m)
        else:
            tof = -a*sqrt(-a)*((sinh(alfa) - alfa) - (sinh(beta) - beta))
        
        # new value of y
        if m ==0:
            ynew = log(tof) - logt
        else:
            ynew = tof - tf
        # save previous and current values for the next iterarion
        # (prevents getting stuck between two values)
        x1 = x2;  x2 = xnew;
        y1 = y2;  y2 = ynew;
        # update error
        err = abs(x1 - xnew);
        # escape clause
        if (iterations > 15):
            bad = True 
            break
    
    
  
    
    # If the Newton-Raphson scheme failed, try to solve the problem
    # with the other Lambert targeter. 
    if bad:
        # NOTE: use the original, UN-normalized quantities
        #[V1, V2, extremal_distances, exitflag] = ...
        #    lambert_high_LancasterBlanchard(r1vec*r1, r2vec*r1, longway*tf*T, leftbranch*m, muC);
        print "FAILZ0r"
        return
    
    
    # convert converged value of x
    if m==0:
        x = exp(xnew) - 1
    else:
        x = arctan(xnew)*2/pi
    
    #{
    #      The solution has been evaluated in terms of log(x+1) or tan(x*pi/2), we
    #      now need the conic. As for transfer angles near to pi the Lagrange-
    #      coefficients technique goes singular (dg approaches a zero/zero that is
    #      numerically bad) we here use a different technique for those cases. When
    #      the transfer angle is exactly equal to pi, then the ih unit vector is not
    #      determined. The remaining equations, though, are still valid.
    #}

    # Solution for the semi-major axis
    a = a_min/(1-x**2);

    # Calculate psi
    if (x < 1): # ellipse
        beta = longway * 2*arcsin(sqrt((s-c)/2/a))
        # make 100.4# sure it's in (-1 <= xx <= +1)
        alfa = 2*arccos( max(-1, min(1, x)) )
        psi  = (alfa-beta)/2
        eta2 = 2*a*sin(psi)**2/s
        eta  = sqrt(eta2);
    else:       # hyperbola
        beta = longway * 2*arcsinh(sqrt((c-s)/2/a))
        alfa = 2*arccosh(x)
        psi  = (alfa-beta)/2
        eta2 = -2*a*sinh(psi)**2/s
        eta  = sqrt(eta2)
    

    # unit of the normalized normal vector
    ih = longway * nrmunit;

    # unit vector for normalized [r2vec]
    r2n = r2vec/mr2vec;

    # cross-products
    # don't use cross() (emlmex() would try to compile it, and this way it
    # also does not create any additional overhead)
    #crsprd1 = [ih(2)*r1vec(3)-ih(3)*r1vec(2),...
    #           ih(3)*r1vec(1)-ih(1)*r1vec(3),...
    #           ih(1)*r1vec(2)-ih(2)*r1vec(1)];    
    crsprd1 = cross(ih,r1vec)
    #crsprd2 = [ih(2)*r2n(3)-ih(3)*r2n(2),...
    #           ih(3)*r2n(1)-ih(1)*r2n(3),...
    #           ih(1)*r2n(2)-ih(2)*r2n(1)];
    crsprd2 = cross(ih,r2n)

    # radial and tangential directions for departure velocity
    Vr1 = 1/eta/sqrt(a_min) * (2*Lambda*a_min - Lambda - x*eta)
    Vt1 = sqrt(mr2vec/a_min/eta2 * sin(dth/2)**2)

    # radial and tangential directions for arrival velocity
    Vt2 = Vt1/mr2vec
    Vr2 = (Vt1 - Vt2)/tan(dth/2) - Vr1
    
    # terminal velocities
    V1 = (Vr1*r1vec + Vt1*crsprd1)*V
    V2 = (Vr2*r2n + Vt2*crsprd2)*V
    
    # exitflag
    #exitflag = 1 # (success)
    #print "V1:",V1
    #print "V2:",V2
    return V1,V2
Exemple #23
0
def XML_generator_Mode2(root,
                        date,
                        duration,
                        relativeTime,
                        params=Mode2_default()):
    "Generates parameters and calls for macros, which will generate commands in the XML-file"

    from MATS_TIMELINE_macros import IR_night, IR_day

    "Load parameters from config function"
    params_default = Mode2_default()
    "Check if optional params were given"
    if (params != params_default):
        params_new = params_default
        "Loop through parameters given and exchange them for the default ones"
        for key in params.keys():
            params_new[key] = params[key]
        params = params_new

    Sun = ephem.Sun(date)
    MATS = ephem.readtle('MATS', getTLE()[0], getTLE()[1])

    "Pre-allocate space"
    sun_angle = zeros((duration, 1))

    R_mean = 6371
    pointing_altitude = str(params['pointing_altitude'])

    #Estimation of the angle between the sun and the FOV position when it enters eclipse
    MATS_nadir_eclipse_angle = arccos(R_mean / (R_mean + 90)) / pi * 180 + 90

    "Loop and calculate the relevant angle of each star to each direction of MATS's FOV"
    for t in range(duration):

        current_time = ephem.Date(date + ephem.second * t)

        MATS.compute(current_time)

        Sun.compute(current_time)
        sun_angle[t] = ephem.separation(Sun, MATS) / pi * 180

        ############# Initial Mode setup ##########################################

        if (t == 0):

            "Check if night or day"
            if (sun_angle[t] > MATS_nadir_eclipse_angle):
                current_state = "IR_night"
                IR_night(root, str(t + relativeTime), pointing_altitude)
            elif (sun_angle[t] < MATS_nadir_eclipse_angle):
                current_state = "IR_day"
                IR_day(root, str(t + relativeTime), pointing_altitude)

        ############# End of Initial Mode setup ###################################

        if (t != 0):
            ####################### SCI-mode Operation planner ################

            #Check if night or day
            if (sun_angle[t] > MATS_nadir_eclipse_angle
                    and current_state != "IR_night"):

                #Check dusk/dawn boundaries and if NLC is active
                if ((sun_angle[t] > MATS_nadir_eclipse_angle
                     and sun_angle[t - 1] < MATS_nadir_eclipse_angle)
                        or current_state == "NLC_night"):
                    IR_night(root, str(t + relativeTime), pointing_altitude)
                    current_state = "IR_night"

            #Check if night or day
            if (sun_angle[t] < MATS_nadir_eclipse_angle
                    and current_state != "IR_day"):

                #Check dusk/dawn boundaries and if NLC is active
                if ((sun_angle[t] < MATS_nadir_eclipse_angle
                     and sun_angle[t - 1] > MATS_nadir_eclipse_angle)
                        or current_state != "NLC_day"):
                    IR_day(root, str(t + relativeTime), pointing_altitude)
                    current_state = "IR_day"
def Limb_functional_test(
        root,
        date,
        duration,
        relativeTime,
        Timeline_settings,
        configFile,
        Test_settings={'ExpTimes': [1000, 2000, 4000, 8000, 16000]}):
    """Limb_functional_test. 

    Schedules Limb_functional_test with defined parameters and simulates MATS propagation from TLE.
    Scheduling of all daylight and nighttime commands are separated timewise and all commands for one of the two is scheduled first.
    """

    Logger.info('')
    Logger.info('Start of Limb_functional_test')

    Logger.debug('Test_settings from Science Mode List: ' + str(Test_settings))

    log_timestep = 500
    Logger.debug('log_timestep [s]: ' + str(log_timestep))

    TLE = configFile.getTLE()

    CCD_settings = configFile.CCD_macro_settings('FullReadout')

    duration_flag = 0

    JPEGQs = [100, 95]
    WDWs = [7, 128]
    altitudes = [50000, 70000, 90000, 110000, 130000, 160000, 200000]
    ExpTimes = Test_settings['ExpTimes']
    SnapshotSpacing = 5

    R_mean = 6371  # km
    Altitude_defining_night = 45  # km
    Altitude_defining_day = 25  # km

    #lat = Test_settings['lat']/180*pi
    lat = 30

    Mode_name = sys._getframe(0).f_code.co_name

    "Estimation of the angle [degrees] between the sun and the LP when it enters eclipse"
    #NightDayAngle = arccos(R_mean/(R_mean+Altitude_defining_night))/pi*180 + 90

    NightAngle = arccos(R_mean /
                        (R_mean + Altitude_defining_night)) / pi * 180 + 90
    DayAngle = arccos(R_mean /
                      (R_mean + Altitude_defining_day)) / pi * 180 + 90

    Logger.debug('')
    Logger.debug('NightAngle : ' + str(NightAngle))
    Logger.debug('DayAngle : ' + str(DayAngle))

    timestep = 4
    t = 0

    initial_relativeTime = relativeTime

    "Consecutively schedule all Macros for day, and then night"
    for mode in ['Day', 'Night']:

        "Altitudes that defines the LP"
        for altitude in altitudes:

            "Start looping the CCD settings and call for macros"
            for JPEGQ, WDW in zip(JPEGQs, WDWs):

                for key in CCD_settings.keys():
                    CCD_settings[key]['JPEGQ'] = JPEGQ
                    CCD_settings[key]['WDW'] = WDW

                for ExpTime in ExpTimes:

                    for key in CCD_settings.keys():
                        CCD_settings[key]['TEXPMS'] = ExpTime

                    ############################################################################
                    ########################## Orbit simulator #################################
                    ############################################################################

                    MATS_skyfield = skyfield.api.EarthSatellite(TLE[0], TLE[1])

                    "Calculate the current angle between MATS and the Sun and the latitude of the LP"
                    "and Loop until it is either day or night and the right latitude"
                    while (True):

                        mode_relativeTime = relativeTime - initial_relativeTime
                        current_time = ephem.Date(date + ephem.second *
                                                  mode_relativeTime)
                        current_time_datetime = current_time.datetime()

                        if (mode_relativeTime > duration
                                and duration_flag == 0):
                            Logger.warning(
                                'Warning!! The scheduled time for the Test has ran out.'
                            )
                            #input('Enter anything to continue:\n')
                            duration_flag = 1

                        if (t * timestep % log_timestep == 0):
                            LogFlag = True
                        else:
                            LogFlag = False

                        Satellite_dict = Library.Satellite_Simulator(
                            MATS_skyfield, current_time, Timeline_settings,
                            altitude / 1000, LogFlag, Logger)

                        r_MATS = Satellite_dict['Position [km]']
                        lat_MATS = Satellite_dict['Latitude [degrees]']
                        lat_LP = Satellite_dict[
                            'EstimatedLatitude_LP [degrees]']

                        sun_angle = Library.SunAngle(r_MATS, current_time)

                        if (LogFlag == True):
                            Logger.debug('sun_angle: ' + str(sun_angle))

                        if ((sun_angle < DayAngle and abs(lat_LP) <= lat
                             and mode == 'Day') or
                            (sun_angle > NightAngle and abs(lat_LP) <= lat
                             and mode == 'Night')):

                            Logger.debug('!!Break of Loop!!')
                            Logger.debug('Loop Counter (t): ' + str(t))
                            Logger.debug('current_time: ' + str(current_time))
                            Logger.debug('lat_MATS [degrees]: ' +
                                         str(lat_MATS))
                            Logger.debug('lat_LP [degrees]: ' + str(lat_LP))
                            Logger.debug('sun_angle [degrees]: ' +
                                         str(sun_angle))
                            Logger.debug('mode: ' + str(mode))
                            Logger.debug('')

                            break

                        "Increase Loop counter"
                        t = t + 1

                        "Timestep for propagation of MATS"
                        relativeTime = round(relativeTime + timestep, 2)

                    ############################################################################
                    ########################## End of Orbit simulator ##########################
                    ############################################################################

                    comment = (Mode_name + ', ' + str(date) + ', ' +
                               str(mode) + ', pointing_altitude = ' +
                               str(altitude) + ', ExpTime = ' + str(ExpTime) +
                               ', JPEGQ = ' + str(JPEGQ))
                    Logger.debug(comment)

                    relativeTime = Macros.Snapshot_Limb_Pointing_macro(
                        root,
                        round(relativeTime, 2),
                        CCD_settings,
                        pointing_altitude=altitude,
                        SnapshotSpacing=SnapshotSpacing,
                        Timeline_settings=Timeline_settings,
                        configFile=configFile,
                        comment=comment)

                    # relativeTime = Macros.Limb_functional_test_macro(root = root, relativeTime = str(relativeTime),
                    #                           pointing_altitude = str(altitude), ExpTime = str(ExpTime),
                    #                           JPEGQ = JPEGQ, comment=comment)

                    #"Postpone next command until at least the end of ExpTime"
                    #relativeTime = round(relativeTime + ExpTime/1000,2)

    mode_relativeTime = relativeTime - initial_relativeTime
    current_time = ephem.Date(date + ephem.second * mode_relativeTime)

    Logger.info('End of Limb_functional_test')

    return relativeTime, current_time
def ChAngle(n, m, v, w):
    """Returns Cherenkov angle as function of refraction coefficient, mass, velocity, and frequency."""
    return py.arccos(CosCh(n, m, v, w))  # Angle is always positive
def MinAlpha(n, m, v, w):
    """Returns polarization basis parameter, a, which minimizes left-handed polarization amplitude at chi=MinChi."""
    A = 0.5 * (v * SinCh(n, m, v, w))**2
    B = 0.5 * w / (Gamma(v) * m)
    den = A + (n**2 - 1) * B**2
    return 0.5 * py.arccos(A / den)  # alpha always positive, <= pi/2
Exemple #27
0
def Mode120_date_calculator():
    """Subfunction, Simulates MATS FOV and stars.
    
    Determines when stars are entering the FOV at an vertical offset-angle equal to *#V-offset*, and also being 
    located at a horizontal off-set angle equal to less than *#H-offset*, when pointing at the LP located at an altitude equal to *#pointing_altitude*. \n
    
    (# as defined in the *Configuration File*). \n
    
    Saves the date and parameters regarding the spotting of a star.
    Also saves relevant data to an .csv file located in Output/.
    
    Arguments:
        
    Returns:
        SpottedStarList ((:obj:`list` of :obj:`dict`)) or (str): A list containing dictionaries containing parameters for each time a star is spotted.
    
    """
    
    Timeline_settings = OPT_Config_File.Timeline_settings()
    Mode120_settings = OPT_Config_File.Mode120_settings()
    
    ######################################################
    "Check how many times Mode120 have been scheduled"
    Mode120Iteration = _Globals.Mode120Iteration
    "Make the V_offset_Index go from 0 to len(Mode120_settings['V_offset'] for each time Mode120 is scheduled"
    V_offset_Index = (Mode120Iteration-1) % (len(Mode120_settings['V_offset']))
    
    "Constants"
    V_offset = Mode120_settings['V_offset'][V_offset_Index]
    H_offset = Mode120_settings['H_offset']
    
    pointing_altitude = Mode120_settings['pointing_altitude']/1000 
    yaw_correction = Timeline_settings['yaw_correction']
    
    Logger.debug('H_offset set to [degrees]: '+str(H_offset))
    Logger.debug('V_offset set to [degrees]: '+str(V_offset))
    Logger.debug('yaw_correction set to: '+str(yaw_correction))
    
    TLE = OPT_Config_File.getTLE()
    Logger.debug('TLE used: '+TLE[0]+TLE[1])
    
    TimeSkips = 0
    Timeskip = Mode120_settings['TimeSkip']
    
    ####################################################
    
    "Simulation length and timestep"
    log_timestep = Mode120_settings['log_timestep']
    Logger.debug('log_timestep: '+str(log_timestep))

    timestep = Mode120_settings['timestep'] #In seconds
    Logger.info('timestep set to: '+str(timestep)+' s')
    
    if( Mode120_settings['TimeToConsider'] <= Timeline_settings['duration']):
        duration = Mode120_settings['TimeToConsider']
    else:
        duration = Timeline_settings['duration']
    Logger.info('Duration set to: '+str(duration)+' s')
    
    timesteps = int(ceil(duration / timestep)) + 2
    Logger.info('Maximum number of timesteps set to: '+str(timesteps))
    
    timeline_start = ephem.Date(Timeline_settings['start_date'])
    initial_time = ephem.Date( timeline_start + ephem.second*Mode120_settings['freeze_start'] )
    current_time = initial_time
    Logger.info('Initial simulation date set to: '+str(initial_time))
    
    
    "Get relevant stars"
    result = Vizier(columns=['all'], row_limit=3000).query_constraints(catalog='I/239/hip_main',Vmag=Mode120_settings['Vmag'])
    star_cat = result[0]
    ROWS = star_cat[0][:].count()
    stars = []
    stars_dec = zeros((ROWS,1))
    stars_ra = zeros((ROWS,1))
    
    "Insert stars into Pyephem"
    for t in range(ROWS):
        s = "{},f|M|F7,{},{},{},2000/01/01 11:58:55.816"
        s = s.format(star_cat[t]['HIP'], deg2HMS(ra=star_cat[t]['_RA.icrs']), deg2HMS(dec=star_cat[t]['_DE.icrs']), star_cat[t]['Vmag'])
        stars.append(ephem.readdb(s))
        stars[t].compute(epoch='2000/01/01 11:58:55.816')
        stars_dec[t] = stars[t].dec
        stars_ra[t] = stars[t].ra
    
    Logger.debug('')
    Logger.debug('List of stars used: '+str(star_cat))
    Logger.debug('')
    
    "Calculate unit-vectors of stars"
    stars_x = cos(stars_dec)* cos(stars_ra)
    stars_y = cos(stars_dec)* sin(stars_ra)
    stars_z = sin(stars_dec)
    stars_r = array([stars_x,stars_y,stars_z])
    stars_r = stars_r.transpose()
    
    "Prepare the .csv file output"
    star_list_excel = []
    star_list_excel.append(['Name'])
    star_list_excel.append(['t1'])
    star_list_excel.append(['long'])
    star_list_excel.append(['lat'])
    star_list_excel.append(['mag'])
    star_list_excel.append(['H_offset'])
    star_list_excel.append(['V_offset'])
    star_list_excel.append(['e_Hpmag'])
    star_list_excel.append(['Hpscat'])
    star_list_excel.append(['o_Hpmag'])
    star_list_excel.append(['Classification'])
    star_list_excel.append(['Optical Axis Dec (ICRS J2000, eq)'])
    star_list_excel.append(['Optical Axis RA (ICRS J2000, eq)'])
    star_list_excel.append(['Star Dec (ICRS J2000, eq)'])
    star_list_excel.append(['Star RA (ICRS J2000, eq)'])
    
    "Prepare the output"
    SpottedStarList = []
    
    "Pre-allocate space"
    lat_MATS = zeros((timesteps,1))
    long_MATS = zeros((timesteps,1))
    optical_axis = zeros((timesteps,3))
    stars_r_V_offset_plane = zeros((ROWS,3))
    stars_r_H_offset_plane = zeros((ROWS,3))
    stars_vert_offset = zeros((timesteps,ROWS))
    stars_hori_offset = zeros((timesteps,ROWS))
    stars_offset = zeros((timesteps,ROWS))
    r_V_offset_normal = zeros((timesteps,3))
    r_H_offset_normal = zeros((timesteps,3))
    star_counter = 0
    spotted_star_name = []
    spotted_star_timestamp = []
    spotted_star_timecounter = []
    skip_star_list = []
    MATS_P = zeros((timesteps,1))
    
    Dec_optical_axis = zeros((timesteps,1))
    RA_optical_axis = zeros((timesteps,1))
    
    angle_between_orbital_plane_and_star = zeros((timesteps,ROWS))
    
    
    
    MATS_skyfield = api.EarthSatellite(TLE[0], TLE[1])
    
    t = 0
    
    Logger.info('')
    Logger.info('Start of simulation of MATS for Mode120')
    ################## Start of Simulation ########################################
    "Loop and calculate the relevant angle of each star to each direction of MATS's FOV"
    while( current_time-initial_time < ephem.second*duration):
        
        
        #current_time = ephem.Date(date+ephem.second*timestep*t)
        
        if( t*timestep % log_timestep == 0):
            LogFlag = True
        else:
            LogFlag = False
        
        Satellite_dict = Satellite_Simulator( 
                MATS_skyfield, current_time, Timeline_settings, pointing_altitude, LogFlag, Logger )
        
        MATS_P[t] = Satellite_dict['OrbitalPeriod [s]']
        lat_MATS[t] =  Satellite_dict['Latitude [degrees]']
        long_MATS[t] =  Satellite_dict['Longitude [degrees]']
        optical_axis[t] = Satellite_dict['OpticalAxis']
        Dec_optical_axis[t] = Satellite_dict['Dec_OpticalAxis [degrees]']
        RA_optical_axis[t] = Satellite_dict['RA_OpticalAxis [degrees]']
        r_H_offset_normal[t] = Satellite_dict['Normal2H_offset']
        r_V_offset_normal[t] = Satellite_dict['Normal2V_offset']
        
        OrbitalAngularVelocity = 360 / MATS_P[t]
        AngularChangePerTimestep = OrbitalAngularVelocity * timestep
        
        ###################### Star-mapper ####################################
        
        if(t != 0):
            "Check position of stars relevant to pointing direction"
            for x in range(ROWS):
                
                "Skip star if it is not visible during this epoch"
                if(stars[x].name in skip_star_list):
                    continue
                
                "Check if a star has already been spotted during this orbit."
                if( stars[x].name in spotted_star_name ):
                    
                    time_until_far_outside_of_FOV = ephem.second*(180*MATS_P[t]/360)
                    
                    "If enough time has passed (half an orbit), the star can be removed from the exception list"
                    if((current_time - spotted_star_timestamp[spotted_star_name.index(stars[x].name)]) >= time_until_far_outside_of_FOV):
                        spotted_star_timestamp.pop(spotted_star_name.index(stars[x].name))
                        spotted_star_timecounter.pop(spotted_star_name.index(stars[x].name))
                        spotted_star_name.remove(stars[x].name)
                    continue
                
                
                
                "Total angle offset of the star compared to MATS's FOV"
                stars_offset[t][x] = arccos(dot(optical_axis[t],stars_r[0][x]) / (norm(optical_axis[t]) * norm(stars_r[0][x]))) /pi*180
                
                "Project 'star vectors' ontop pointing H-offset and V-offset plane"
                stars_r_V_offset_plane[x] = stars_r[0][x] - (dot(stars_r[0][x],r_V_offset_normal[t,0:3]) * r_V_offset_normal[t,0:3])
                
                stars_r_H_offset_plane[x] = stars_r[0][x] - (dot(stars_r[0][x],r_H_offset_normal[t]) * r_H_offset_normal[t]) 
                
                "Dot product to get the Vertical and Horizontal angle offset of the star in the FOV"
                stars_vert_offset[t][x] = arccos(dot(optical_axis[t],stars_r_V_offset_plane[x]) / (norm(optical_axis[t]) * norm(stars_r_V_offset_plane[x]))) /pi*180
                stars_hori_offset[t][x] = arccos(dot(optical_axis[t],stars_r_H_offset_plane[x]) / (norm(optical_axis[t]) * norm(stars_r_H_offset_plane[x]))) /pi*180
                
                "Determine sign of off-set angle where positive V-offset angle is when looking at higher altitude"
                if( dot(cross(optical_axis[t],stars_r_V_offset_plane[x]),r_V_offset_normal[t,0:3]) > 0 ):
                    stars_vert_offset[t][x] = -stars_vert_offset[t][x]
                if( dot(cross(optical_axis[t],stars_r_H_offset_plane[x]),r_H_offset_normal[t]) > 0 ):
                    stars_hori_offset[t][x] = -stars_hori_offset[t][x]
                
                
                "To be able to skip stars far outside the orbital plane of MATS"
                if( t == 1 ):
                    "For first loop of stars, calculate angle between stars and orbital plane"
                    angle_between_orbital_plane_and_star[t][x] = arccos( dot(stars_r[0][x], stars_r_V_offset_plane[x]) / norm(stars_r_V_offset_plane[x])) /pi*180
                    
                    "Make exception list for stars not visible during this epoch (relativiely far outside of orbital plane)"
                    if( ( abs(angle_between_orbital_plane_and_star[t][x]) > H_offset+(duration)/(365*24*3600)*360 and yaw_correction == False ) or 
                       ( abs(angle_between_orbital_plane_and_star[t][x]) > H_offset + abs(Timeline_settings['yaw_amplitude']) + (duration)/(365*24*3600)*360 and yaw_correction == True )):
                        
                        Logger.debug('Skip star: '+stars[x].name+', with angle_between_orbital_plane_and_star of: '+str(angle_between_orbital_plane_and_star[t][x])+' degrees')
                        skip_star_list.append(stars[x].name)
                        continue
                
                
                "Check that the star is entering at V-offset degrees with a standard timestep and within the H-offset angle"
                if( V_offset - AngularChangePerTimestep  <= stars_vert_offset[t][x] <= V_offset and stars_vert_offset[t-1][x] > V_offset and abs(stars_hori_offset[t][x]) < H_offset):
                    
                    if( t % log_timestep == 0):
                        Logger.debug('Star: '+stars[x].name+', with H-offset: '+str(stars_hori_offset[t][x])+' V-offset: '+str(stars_vert_offset[t][x])+' in degrees is available')
                    
                    "Add the spotted star to the exception list and timestamp it"
                    spotted_star_name.append(stars[x].name)
                    spotted_star_timestamp.append(current_time)
                    spotted_star_timecounter.append(t) 
                    
                    
                    "Append all relevent data for the star"
                    star_list_excel[0].append(stars[x].name)
                    star_list_excel[1].append(str(current_time))
                    star_list_excel[2].append(str(float(long_MATS[t])))
                    star_list_excel[3].append(str(float(lat_MATS[t])))
                    star_list_excel[4].append(str(stars[x].mag))
                    star_list_excel[5].append(str(stars_hori_offset[t][x]))
                    star_list_excel[6].append(str(stars_vert_offset[t][x]))
                    star_list_excel[7].append(str(star_cat[x]['e_Hpmag']))
                    star_list_excel[8].append(str(star_cat[x]['Hpscat']))
                    star_list_excel[9].append(str(star_cat[x]['o_Hpmag']))
                    star_list_excel[10].append(str(star_cat[x]['SpType']))
                    star_list_excel[11].append(str(Dec_optical_axis[t]))
                    star_list_excel[12].append(str(RA_optical_axis[t]))
                    star_list_excel[13].append(str(stars_dec[x]/pi*180))
                    star_list_excel[14].append(str(stars_ra[x]/pi*180))
                    
                    "Log data of star relevant to filtering process"
                    SpottedStarList.append({ 'Date': str(current_time), 'V-offset': stars_vert_offset[t][x], 'H-offset': stars_hori_offset[t][x], 
                                      'long_MATS': float(long_MATS[t]), 'lat_MATS': float(lat_MATS[t]), 
                                      'Dec_optical_axis': Dec_optical_axis[t], 'RA_optical_axis': RA_optical_axis[t], 
                                      'Vmag': stars[x].mag, 'Name': stars[x].name, 'Dec': stars_dec[x]/pi*180, 'RA': stars_ra[x]/pi*180 })
                    
                    star_counter = star_counter + 1
                    
            ######################### End of star_mapper #############################
        
        "Increase Simulation Time with a timestep, or skip ahead if 1 orbit is completed"
        t += 1
        if( t*timestep > MATS_P[t-1]*(TimeSkips+1) ):
            current_time = ephem.Date(current_time+ephem.second*Timeskip)
            TimeSkips += 1
        else:
            current_time = ephem.Date(current_time+ephem.second*timestep)
        
        
    ########################## END OF SIMULATION ############################
    
    Logger.info('')
    Logger.info('End of simulation for Mode120')
    Logger.info('')
    
    "Write spotted stars to file"
    try:
        os.mkdir('Output')
    except:
        pass
    
    while(True):
        try:
            file_directory = os.path.join('Output',sys._getframe(1).f_code.co_name+'_Visible_Stars__'+_Globals.Config_File+'__V_offset'+str(V_offset)+'.csv')
            with open(file_directory, 'w', newline='') as write_file:
                writer = csv.writer(write_file, dialect='excel-tab')
                writer.writerows(star_list_excel)
            Logger.info('Available Stars data saved to: '+file_directory)
            #print('Available Stars data saved to: '+file_directory)
            break
        except PermissionError:
            Logger.error(file_directory+' cannot be overwritten. Please close it')
            data = input('Enter anything to try again or 1 to exit')
            if( data == '1'):
                sys.exit()
    
    Logger.debug('Visible star list to be filtered:')
    for x in range(len(SpottedStarList)):
        Logger.debug(str(SpottedStarList[x]))
    Logger.debug('')
    
    Logger.debug('Exit '+str(__name__))
    Logger.debug('')
    
    
    return(SpottedStarList)
def Mode200_date_calculator():
#if(True):
    Logger = logging.getLogger(Logger_name())
    
    log_timestep = 2000
    
    "Simulation length and timestep"
    duration = Timeline_params()['duration']
    Logger.info('Duration set to [s]: '+str(duration))
    timestep = Mode200_calculator_defaults()['timestep'] #In seconds
    Logger.info('Timestep set to [s]: '+str(timestep))
    
    
    date = Timeline_params()['start_time']
    Logger.info('date set to: '+str(date))
    
    MATS = ephem.readtle('MATS',getTLE()[0],getTLE()[1])
    
    Moon = ephem.Moon()
    
    "Pre-allocate space"
    lat_MATS = zeros((duration,1))
    long_MATS = zeros((duration,1))
    altitude_MATS = zeros((duration,1))
    g_ra_MATS = zeros((duration,1))
    g_dec_MATS = zeros((duration,1))
    x_MATS = zeros((duration,1))
    y_MATS = zeros((duration,1))
    z_MATS = zeros((duration,1))
    r_MATS = zeros((duration,3))
    r_MATS_unit_vector = zeros((duration,3))
    r_FOV = zeros((duration,3))
    normal_orbit = zeros((duration,3))
    normal_H_offset = zeros((duration,3))
    normal_H_offset_unit_vector = zeros((duration,3))
    pitch_array = zeros((duration,1))
    MATS_p = zeros((duration,1))
    MATS_P = zeros((duration,1))
    
    g_ra_Moon = zeros((duration,1))
    g_dec_Moon = zeros((duration,1))
    distance_Moon = zeros((duration,1))
    x_Moon = zeros((duration,1))
    y_Moon = zeros((duration,1))
    z_Moon = zeros((duration,1))
    r_Moon = zeros((duration,3))
    r_MATS_2_Moon = zeros((duration,3))
    r_MATS_2_Moon_norm = zeros((duration,3))
    Moon_r_orbital_plane = zeros((duration,3))
    Moon_r_H_offset_plane = zeros((duration,3))
    Moon_vert_offset = zeros((duration,1))
    Moon_hori_offset = zeros((duration,1))
    angle_between_orbital_plane_and_moon = zeros((duration,1))
    Moon_list = []
    r_Moon_unit_vector = zeros((duration,3))
    
    
    
    "Constants"
    AU = 149597871 #km
    R_mean = 6371 #Earth radius
    U = 398600.4418 #Earth gravitational parameter
    FOV_altitude = Mode200_calculator_defaults()['default_pointing_altitude']/1000  #Altitude at which MATS center of FOV is looking
    Logger.info('FOV_altitude set to [km]: '+str(FOV_altitude))
    pointing_adjustment = 3 #Angle in degrees that the pointing can be adjusted
    V_FOV = Mode200_calculator_defaults()['V_FOV'] #0.91 is actual V_FOV
    H_FOV = Mode200_calculator_defaults()['H_FOV']  #5.67 is actual H_FOV
    Logger.info('V_FOV set to [degrees]: '+str(V_FOV))
    Logger.info('H_FOV set to [degrees]: '+str(H_FOV))
    V_offset = 0
    H_offset = 0
    Moon_orbital_period = 3600*24*27.32
    
    
    t=0
    
    current_time = date
    
    Logger.info('')
    Logger.info('Start of simulation for Mode200')
    
    while(current_time < date+ephem.second*duration):
        
        MATS.compute(current_time)
        Moon.compute(current_time)
        
        
        (lat_MATS[t],long_MATS[t],altitude_MATS[t],g_ra_MATS[t],g_dec_MATS[t])= (
        MATS.sublat,MATS.sublong,MATS.elevation/1000,MATS.g_ra,MATS.g_dec)
        
        R = lat_2_R(lat_MATS[t])
        
        z_MATS[t] = sin(g_dec_MATS[t])*(altitude_MATS[t]+R)
        x_MATS[t] = cos(g_dec_MATS[t])*(altitude_MATS[t]+R)* cos(g_ra_MATS[t])
        y_MATS[t] = cos(g_dec_MATS[t])*(altitude_MATS[t]+R)* sin(g_ra_MATS[t])
       
        r_MATS[t,0:3] = [x_MATS[t], y_MATS[t], z_MATS[t]]
        r_MATS_unit_vector[t] = r_MATS[t]/norm(r_MATS[t])
        
        
        #Semi-Major axis of MATS, assuming circular orbit
        MATS_p[t] = norm(r_MATS[t,0:3])
        
        #Orbital Period of MATS
        MATS_P[t] = 2*pi*sqrt(MATS_p[t]**3/U)
        
        #Estimated pitch angle for MATS pointing
        pitch_array[t]= array(arccos((R_mean+FOV_altitude)/(R+altitude_MATS[t]))/pi*180)
        pitch = pitch_array[t][0]
        
        (g_ra_Moon[t],g_dec_Moon[t],distance_Moon[t])= (Moon.g_ra,Moon.g_dec,Moon.earth_distance*AU)
        
        z_Moon[t] = sin(g_dec_Moon[t]) * distance_Moon[t]
        x_Moon[t] = cos(g_dec_Moon[t])*cos(g_ra_Moon[t]) * distance_Moon[t]
        y_Moon[t] = cos(g_dec_Moon[t])*sin(g_ra_Moon[t]) * distance_Moon[t]
       
        r_Moon[t,0:3] = [x_Moon[t], y_Moon[t], z_Moon[t]]
        r_Moon_unit_vector[t,0:3] = r_Moon[t,0:3]/norm(r_Moon[t,0:3])
        
        r_MATS_2_Moon[t] = r_Moon[t]-r_MATS[t]
        r_MATS_2_Moon_norm[t] = r_MATS_2_Moon[t]/norm(r_MATS_2_Moon[t])
        
        if( t*timestep % log_timestep == 0 ):
            Logger.debug('')
            Logger.debug('log_timestep: '+str(log_timestep))
            Logger.debug('timestep: '+str(timestep))
            Logger.debug('t (loop iteration number): '+str(t))
            Logger.debug('Current time: '+str(current_time))
            Logger.debug('Semimajor axis in km: '+str(MATS_p[t]))
            Logger.debug('Orbital Period in s: '+str(MATS_P[t]))
            Logger.debug('Vector to MATS [km]: '+str(r_MATS[t,0:3]))
            Logger.debug('Latitude in radians: '+str(lat_MATS[t]))
            Logger.debug('Longitude in radians: '+str(long_MATS[t]))
            Logger.debug('Altitude in km: '+str(altitude_MATS[t]))
            Logger.debug('FOV pitch in degrees: '+str(pitch))
        
        if(t != 0):
            
            
            ############# Calculations of orbital and pointing vectors ############
            "Vector normal to the orbital plane of MATS"
            normal_orbit[t,0:3] = cross(r_MATS[t],r_MATS[t-1])
            normal_orbit[t,0:3] = normal_orbit[t,0:3] / norm(normal_orbit[t,0:3])
            
            "Rotate 'vector to MATS', to represent pointing direction, includes vertical offset change"
            rot_mat = rot_arbit(-pi/2+(-pitch+V_offset)/180*pi, normal_orbit[t,0:3])
            r_FOV[t,0:3] = (r_MATS[t] @ rot_mat)
            
            "Rotate 'vector to MATS', to represent a vector normal to the H-offset pointing plane, includes vertical offset change (Parallax is negligable)"
            rot_mat = rot_arbit((-pitch+V_offset)/180*pi, normal_orbit[t,0:3])
            normal_H_offset[t,0:3] = (r_MATS[t] @ rot_mat) /2
            normal_H_offset_unit_vector[t,0:3] = normal_H_offset[t,0:3] / norm(normal_H_offset[t,0:3])
            
            ############# End of Calculations of orbital and pointing vectors #####
            
            "Project 'r_MATS_2_Moon' ontop pointing H-offset and orbital plane"
            Moon_r_orbital_plane[t] = r_MATS_2_Moon_norm[t] - dot(r_MATS_2_Moon_norm[t],normal_orbit[t]) * normal_orbit[t]
            Moon_r_H_offset_plane[t] = r_MATS_2_Moon_norm[t] - dot(r_MATS_2_Moon_norm[t],normal_H_offset_unit_vector[t]) * normal_H_offset_unit_vector[t]
            
            
            "Dot product to get the Vertical and Horizontal angle offset of the Moon"
            Moon_vert_offset[t] = arccos(dot(r_FOV[t],Moon_r_orbital_plane[t]) / (norm(r_FOV[t])*norm(Moon_r_orbital_plane[t]))) /pi*180
            Moon_hori_offset[t] = arccos(dot(r_FOV[t],Moon_r_H_offset_plane[t]) / (norm(r_FOV[t])*norm(Moon_r_H_offset_plane[t]))) /pi*180
            
            "Get the offset angle sign correct"
            if( dot(cross(r_FOV[t],Moon_r_orbital_plane[t]),normal_orbit[t,0:3]) > 0 ):
                Moon_vert_offset[t] = -Moon_vert_offset[t]
            if( dot(cross(r_FOV[t],Moon_r_H_offset_plane[t]),normal_H_offset[t]) > 0 ):
                Moon_hori_offset[t] = -Moon_hori_offset[t]
            
            
            "Angle between orbital plane and moon"
            angle_between_orbital_plane_and_moon[t] = arccos( dot(r_MATS_2_Moon_norm[t], Moon_r_orbital_plane[t]) / norm(Moon_r_orbital_plane[t])) /pi*180
            
            
            if( t*timestep % log_timestep == 0 ):
                Logger.debug('angle_between_orbital_plane_and_moon [degrees]: '+str(angle_between_orbital_plane_and_moon[t]))
                Logger.debug('Moon_vert_offset [degrees]: '+str(Moon_vert_offset[t]))
                Logger.debug('Moon_hori_offset [degrees]: '+str(Moon_hori_offset[t]))
                Logger.debug('normal_orbit: '+str(normal_orbit[t,0:3]))
                Logger.debug('normal_H_offset: '+str(normal_H_offset[t,0:3]))
                Logger.debug('r_FOV [km]: '+str(r_FOV[t,0:3]))
        
            
            #print('angle_between_orbital_plane_and_moon = ' + str(angle_between_orbital_plane_and_moon[t]))
            
            "Save data when Moon is visible in specified FOV. "
            #if(abs(Moon_vert_offset[t]) <= timestep/MATS_P[t]*360 and abs(Moon_hori_offset[t]) < H_FOV/2):
            if(abs(Moon_vert_offset[t]) <= V_FOV/2 and abs(Moon_hori_offset[t]) < H_FOV/4):
                
                Logger.debug('')
                Logger.debug('!!!!!!!!Moon visible!!!!!!!!!!')
                Logger.debug('angle_between_orbital_plane_and_moon [degrees]: '+str(angle_between_orbital_plane_and_moon[t]))
                Logger.debug('Moon_vert_offset [degrees]: '+str(Moon_vert_offset[t]))
                Logger.debug('Moon_hori_offset [degrees]: '+str(Moon_hori_offset[t]))
                Logger.debug('normal_orbit: '+str(normal_orbit[t,0:3]))
                Logger.debug('normal_H_offset: '+str(normal_H_offset[t,0:3]))
                Logger.debug('r_FOV: '+str(r_FOV[t,0:3]))
                Logger.debug('')
                
                Moon_list.append({ 'Date': str(current_time), 'V-offset': Moon_vert_offset[t], 'H-offset': Moon_hori_offset[t], 
                                  'long_MATS': float(long_MATS[t]/pi*180), 'lat_MATS': float(lat_MATS[t]/pi*180)})
                current_time = ephem.Date(current_time+ephem.second*MATS_P[t]/2)
                
            
        
        "To be able to make time skips when the moon is far outside the orbital plane of MATS"
        if( angle_between_orbital_plane_and_moon[t] > H_FOV/2):
            t= t + 1
            current_time = ephem.Date(current_time+ephem.second * H_FOV/4 / 360 * Moon_orbital_period)
            #if( t*timestep % floor(log_timestep/400) == 0 ):
            Logger.info('Moon currently not visible -> jump ahead')
            Logger.info('current_time is: '+str(current_time))
        else:
            t= t + 1
            current_time = ephem.Date(current_time+ephem.second*timestep)
            
        
        
    Logger.info('End of simulation for Mode200')
    Logger.info('Moon_list: '+str(Moon_list))
    
    
    ########################## Optional plotter ###########################################
    
    from mpl_toolkits.mplot3d import axes3d
    from pylab import figure
    
    "Orbital points to plot"
    points_2_plot_start = 0#0*24*120
    points_2_plot = points_2_plot_start+1000
    
    "Plotting of orbit and FOV"
    fig = figure(1)
    ax = fig.add_subplot(111,projection='3d')
    ax.set_xlim3d(-1, 1)
    ax.set_ylim3d(-1, 1)
    ax.set_zlim3d(-1, 1)
    
    ax.scatter(r_MATS_unit_vector[points_2_plot_start:points_2_plot,0],r_MATS_unit_vector[points_2_plot_start:points_2_plot,1],r_MATS_unit_vector[points_2_plot_start:points_2_plot,2])
    ax.scatter(r_Moon_unit_vector[points_2_plot_start:points_2_plot,0],r_Moon_unit_vector[points_2_plot_start:points_2_plot,1],r_Moon_unit_vector[points_2_plot_start:points_2_plot,2])
    
    
    ########################### END of Optional plotter ########################################
    
    
    return Moon_list
Exemple #29
0
    def eph2D(self,epoch):
        
        if self.ref == None:
            return ([0,0,0],[0,0,0])
                
        dt = epoch-self.epoch  
        #print "dT",dt
        
        # Step 1 - Determine mean anomaly at epoch
        if self.e == 0:
            M = self.M0 + dt * sqrt(self.ref.mu / self.a**3)
            M %= PI2
            E = M
            ta = E
            r3 = (self.h**2/self.ref.mu)
            rv = r3 * array([cos(ta),sin(ta),0])
            v3 = self.ref.mu / self.h
            vv = v3 * array([-sin(ta),self.e+cos(ta),0])
            
            return (rv,vv)
            
        if self.e < 1:
            if epoch == self.epoch:
                M = self.M0
            else:
                M = self.M0 + dt * sqrt(self.ref.mu / self.a**3)
                M %= PI2
             
             # Step 2a - Eccentric anomaly
            try:
                E = so.newton(lambda x: x-self.e * sin(x) - M,M)
            except RuntimeError: # Debugging a bug here, disregard
                print "Eccentric anomaly failed for",self.obj.name
                print "On epoch",epoch
                print "Made error available at self.ERROR"
                self.ERROR = [lambda x: x-self.e * sin(x) - M,M]
                raise
            
            # Step 3a - True anomaly, method 1
            ta = 2 * arctan2(sqrt(1+self.e)*sin(E/2.0), sqrt(1-self.e)*cos(E/2.0))
            #print "Ta:",ta
            # Method b is faster
            cosE = cos(E)
            
            ta2 = arccos((cosE - self.e) / (1-self.e*cosE))
            #print "e",self.e
            #print "M",M
            #print "E",E
            #print "TA:",ta
            #print "T2:",ta2
            
            # Step 4a - distance to central body (eccentric anomaly).
            r = self.a*(1-self.e * cos(E))
            
            # Alternative (true anomaly)
            r2 = (self.a*(1-self.e**2) / (1.0 + self.e * cos(ta)))
            
            # Things get crazy
            #h = sqrt(self.a*self.ref.mu*(1-self.e**2))
            r3 = (self.h**2/self.ref.mu)*(1.0/(1.0+self.e*cos(ta)))
            
        
            #print "R1:",r
            #print "R2:",r2
            #print "R3:",r3
            rv = r3 * array([cos(ta),sin(ta),0])
            
            #v1 = sqrt(self.ref.mu * (2.0/r - 1.0/self.a))
            #v2 = sqrt(self.ref.mu * self.a) / r
            v3 = self.ref.mu / self.h
            #meanmotion = sqrt(self.ref.mu / self.a**3)
            #v2 = sqrt(self.ref.mu * self.a)/r
            
            #print "v1",v1
            #print "v2",v2
            #print "v3",v3
            #print "mm",meanmotion
            
            
            # Velocity can be calculated from the eccentric anomaly            
            #vv = v1 * array([-sin(E),sqrt(1-self.e**2) * cos(E),0])
            
            # Or from the true anomaly (this one has an error..)
            #vv = sqrt(self.ref.mu * self.a)/r * array([-sin(ta),self.e+cos(ta),0])
            
            vv = v3 * array([-sin(ta),self.e+cos(ta),0])
            
            #print "rv",rv
            #print "vv",vv
            #print "check",E,-sin(E),v1*-sin(E)
            #print "V1:",vv
            #print "V2:",vv2

            return (rv,vv)
            
        elif self.e > 1:
            # Hyperbolic orbits
            # Reference: Stephen Kemble: Interplanetary Mission Analysis and Design, Pg 220-221
            M = self.M0 + dt * sqrt(-(self.ref.mu / self.a**3))
            #print "M0",self.M0
            #print "M",M
            #print "M",M
            #print "M0",self.M0
            # Step 2b - Hyperbolic eccentric anomaly
            #print "Hyperbolic mean anomaly:",M
            F = so.newton(lambda x: self.e * sinh(x) - x - M,M,maxiter=1000)
            #F = -F
            H = M / (self.e-1)
            #print "AAAA"*10
            #print "F:",F
            #print "H:",H
            #F=H
            #print "Hyperbolic eccentric anomaly:",F
            
            # Step 3b - Hyperbolic true anomaly?
            # This is wrong prooobably            
            #hta = arccos((cosh(F) - self.e) / (1-self.e*cosh(F)))
            #hta = arccos((self.e-cosh(F)) / (self.e*cosh(F) - 1))
            # TÄSSÄ ON BUGI
            hta = arccos((cosh(F) - self.e) / (1 - self.e*cosh(F)))
            hta2 = 2 * arctan2(sqrt(self.e+1)*sinh(F/2.0),sqrt(self.e-1)*cosh(F/2.0))
            hta3 = 2 * arctan2(sqrt(1+self.e)*sinh(F/2.0),sqrt(self.e-1)*cosh(F/2.0))
            hta4 = 2 * arctan2(sqrt(self.e-1)*cosh(F/2.0),sqrt(1+self.e)*sinh(F/2.0))
            #print "Hyperbolic true anomaly:",degrees(hta)
            # This is wrong too            
            #hta2 = 2 * arctan2(sqrt(1+self.e)*sin(F/2.0), sqrt(1-self.e)*cos(F/2.0))
            if M == self.M0:
                print "HTA1:",degrees(hta)
                print "HTA2:",degrees(hta2)
                print "HTA3:",degrees(hta3)
                print "HTA4:",degrees(hta4)
            
            # According to http://mmae.iit.edu/~mpeet/Classes/MMAE441/Spacecraft/441Lecture17.pdf
            # this is right..
            hta = hta2
            #print cos(hta)
            #print cosh(hta)
            
            #####hta = arctan(sqrt((self.e-1.0)/self.e+1.0) * tanh(F/2.0)) / 2.0
            #print "Mean anomaly:",M
            #print "Hyperbolic eccentric anomaly:",F
            #print "HTA:",hta
            #raise
            # Step 4b - Distance from central body?
            # Can calculate it from hyperbolic true anomaly..
            #p = self.a*(1-self.e**2)
            #r = p / (1+self.e * cos(hta))
            r3 = (self.h**2/self.ref.mu)*(1.0/(1.0+self.e*cos(hta)))
            v3 = self.ref.mu / self.h
            # But it's faster to calculate from eccentric anomaly
            #r = self.a*(1-self.e * cos(F))
            
            #print "Hyper r1:",r
            #print "Hyper r2:",r2
            
            rv = r3 * array([cos(hta),sin(hta),0])
            #http://en.wikipedia.org/wiki/Hyperbola
            #rv = array([ r * sin(hta),-self.a*self.e + r * cos(hta), 0])
            #sinhta = sin(hta)
            #coshta = cos(hta)
            #print self.ref.mu,r,self.a,hta
            #vv = sqrt(self.ref.mu *(2.0/r - 1.0/self.a)) * array([-sin(hta),self.e+cos(hta),0])
            vv = v3 * array([-sin(hta),self.e+cos(hta),0])
            
            return (rv,vv)
Exemple #30
0
 def initFromStateVectors(self,epoch,pV,vV):
     self.epoch = epoch
     
     # 1) Calculate auxilary vector h
     hV = cross(pV,vV)
     
     
     # 2) Normalize position,velocity, specific angular momentum, calculate radial velocity 
     
     p = linalg.norm(pV)
     v = linalg.norm(vV)
     h = linalg.norm(hV)
     print "H:",h
     radv = pV.dot(vV) / p
     hVu = hV / h
     pVu = pV / p
     nV = cross(array([0,0,1]),hV)
     n = linalg.norm(nV)
     if n == 0:
         nVu = array([0,0,0])
     else:
         nVu = nV/n
     # 3) Calculate inclination
     #self.i = arccos(hV[2]/h)
     self.i = arcsin(linalg.norm(cross(array([0,0,1]),hVu)))
     print "i1",self.i
     print "RADVEL",radv
     self.i = arccos(array([0,0,1]).dot(hV)/h)
     #if radv < 0:
     #    self.i = PI2 - self.i 
     print "i2",self.i
     # 4) Calculate node line
     
     
     # 5) Calculate longitude of ascending node = right ascension of ascending node
     '''
     if self.i == 0:
         self.lan=0
     elif nV[1] >= 0:
         self.lan = arccos(nV[0] / n)
     else:
         self.lan = PI2 - arccos(nV[0] / n)
     '''
     
     if self.i == 0:
         self.lan = 0
     else:
         self.lan = arcsin(cross(array([1,0,0]),nVu).dot(array([0,0,1])))
         print "lan1",self.lan
         self.lan = arccos(array([1,0,0]).dot(nV)/n)
         if nV[1] < 0:
             self.lan = PI2-self.lan
         print "lan2",self.lan
     
     # 6) Eccentricity vector
     #eV = (1.0 / self.ref.mu)*((v**2 - (self.ref.mu / p))*pV - radv*vV)
     #eV2 = (1.0 / self.ref.mu) * ( hV - self.ref.mu * (pV/p))
     #eV3 = hV/self.ref.mu - (pV/p)
     
     # Source: cdeagle
     eV = cross(vV,hV)/self.ref.mu - pVu
     #print "eV1:",eV,linalg.norm(eV)
     #print "eV2:",eV2,linalg.norm(eV2)
     #print "eV3:",eV3,linalg.norm(eV3)
     print "eV3:",eV,linalg.norm(eV)
     self._e = linalg.norm(eV)
     #eVu = eV / self.e
     
     print "h",h
     print "u",self.ref.mu
     print "v",v
     print "r",p
     
     print "alte:",sqrt(1+(h**2/self.ref.mu**2)*(v**2-(2*self.ref.mu)/p)**2)
     # 7) Argument of perigree
     '''
     if self.e == 0:
         self.aop = 0
     elif self.i == 0:
       self.aop = arccos(eV[0] / self.e)  
     elif eV[2] >= 0:
         print "AOP AOP AOP"
         #self.aop = arccos(nV.dot(eV) / (n*self.e))
         print cross(nV,eV).dot(hV)
         self.aop = arcsin(cross(nVu,eVu).dot(hVu))
         #self.aop = arccos(n*self.e)
     else:
         self.aop = PI2 - arccos(nV.dot(eV) / (n*self.e))
     '''
     #CDEagle method
     # TODO CHECK how KSP handles this. 
     if self.e == 0:
         self.aop = 0
     elif self.i == 0 and self.e != 0:            
         #self.aop = arccos(eV[0] / self.e)
         #self.aop = arctan2(eV[1],eV[0])
         self.aop = arccos(array([1,0,0]).dot(eV) / self.e)
         print eV
         if eV[2] < 0:
             #self.aop = -self.aop
             self.aop = PI2-self.aop
         
         #print "BOOM",eV
         #if eV[2] < 0:
         #    print "BAM N***A"
         #    self.aop = PI2 - self.aop
     elif self.i == 0 and self.e == 0:
         #raise AttributeError("Perfectly circular orbits are not supported atm")
         self.aop = 0
     else:
         #self.aop = arcsin(cross(nVu,eVu).dot(hVu))
         self.aop = arccos(nV.dot(eV)/(n*self.e))
         if eV[2] < 0:
             self.aop = PI2-self.aop
     
     # 8) Semi major axis
     aE = v**2/2.0 - self.ref.mu / p
     self._a = -self.ref.mu / (2*aE)
     print "Old method for semi-major",self.a
     self._a = h**2 / (self.ref.mu * (1-self.e**2))
     print "New method for semi-major",self.a  
     #if self.e > 1:
     #    self._a = h**2 / (self.ref.mu * (self.e**2 - 1))
     
     if self.e == 0:
         if self.i == 0: #TODO update document to this
             print "JEA JEA JEA JEA"*10
             
             ta = arccos(array([1,0,0]).dot(pV) / p)
             if pV[1] < 0: # Vallado pg. 111
                 ta = PI2 - ta
         else: #TODO VERIFY THIS CASE
             ta = arccos((nV.dot(pV))/(n*p))
             if pV[2] < 0: # Vallado pg. 110
                 ta = PI2 - ta
         E = ta
         self.M0 = E
           
     elif self.e < 1:
         # 9) True anomaly, eccentric anomaly and mean anomaly
         if radv >= 0:
             ta = arccos((eV / self.e).dot(pV/p))
         else:
             ta = PI2 - arccos((eV / self.e).dot(pV/p))
         
         
         E = arccos((self.e+cos(ta))/(1+ self.e*cos(ta)))
         if radv < 0:
             E = PI2 - E
     
         self.M0 = E - self.e * sin(E)
         
     elif self.e > 1:
         # 9) Hyperbolic True anomaly, eccentric anomaly and mean anomaly
         # http://scienceworld.wolfram.com/physics/HyperbolicOrbit.html
         V = arccos((abs(self.a)*(self.e**2 - 1)) /(self.e * p) - 1/self.e)
         ta = arccos((eV / self.e).dot(pV/p))
         
         if radv < 0: #TODO: Should affect F too?
             # Negative = heading towards periapsis
             print "PI2"
             V = PI2 - V
             ta = PI2-ta
         print "V",V
         print "TA",ta
         # http://www.bogan.ca/orbits/kepler/orbteqtn.html In you I trust
         # Hyperbolic eccentric anomaly
         cosV = cos(V)
         F = arccosh((self.e+cosV)/(1+self.e*cosV))
         if radv < 0:
             F = -F
         F2 = arcsinh((sqrt(self.e-1)*sin(V))/(1+self.e*cos(V)))
         ##F1 = F2
         print "F1:",F
         print "F2:",F2
         self.M0 = self.e * sinh(F) - F
         
     
  
     
     
     self.h = h
     
     print "Semi-major:",self.a
     print "Eccentricity:",self.e
     print "Inclination:",degrees(self.i),"deg"
     print "LAN:",degrees(self.lan),"deg"
     print "AoP:",degrees(self.aop),"deg"
     print "Mean anomaly:",self.M0
     print "Specific angular momentum:",self.h
     if self.e < 1:
         print "Eccentric anomaly",E
         print "True anomaly",ta
     else:
         print "Hyperbolic eccentric anomaly",F
         print "Hyperbolic true anomaly",degrees(V)
         
     print "Distance from object:",p
     print "Velocity:",v
Exemple #31
0
# Plot a bunch of randomly distributed points on the earth.

# set up stereographic map centered on N. Pole.
m = Basemap(lon_0=-105,boundinglat=30.,
            resolution='l',area_thresh=10000.,projection='npstere')
# number of points to plot.
npts = 750
# generate random points on a sphere,
# so that every small area on the sphere is expected
# to have the same number of points.
# http://mathworld.wolfram.com/SpherePointPicking.html
u = uniform(0.,1.,size=npts)
v = uniform(0.,1.,size=npts)
z = uniform(0,100,size=npts)
lons = 360.*u
lats = (180./pi)*arccos(2*v-1) - 90.
# transform lons and lats to map coordinates.
x,y = m(lons,lats)
# plot them as filled circles on the map.
# first, create a figure.
fig=figure()
# background color will be used for 'wet' areas.
fig.add_axes([0.1,0.1,0.8,0.8],axisbg='aqua')
# draw colored markers.
# use zorder=10 to make sure markers are drawn last.
# (otherwise they are covered up when continents are filled)
#m.scatter(x,y,25,z,cmap=cm.jet,marker='o',faceted=False,zorder=10) 
# create a list of strings containing z values
# or, plot actual numbers as color-coded text strings.
zn = [ '%2i' % zz for zz in z ]
# plot numbers on map, colored by value.
Exemple #32
0
def angle(a,b):
    return arccos(dot(a,b) / (l2norm(a) * l2norm(b)))
Exemple #33
0
def get_angle_between_3_points(pc, p1, p2):
    """ pc=point center, p1,p2 """
    vl = vector_length
    return arccos(
        ( vl(pc, p1) ** 2 + vl(pc, p2) ** 2 - vl(p1, p2) ** 2 ) / (
            2 * vl(pc, p1) * vl(pc, p2)))
Exemple #34
0
def arcdistance(d, R):
    return R * pl.arccos(1 - 0.5 * d * d / (R * R))
def ChAngleCl(n, v):
    """Returns classical Cherenkov angle as function of refraction coefficient, mass, velocity, and frequency."""
    return py.arccos(CosChCl(n, v))  # Angle is always positive
Exemple #36
0
m = Basemap(lon_0=-105,
            boundinglat=30.,
            resolution='l',
            area_thresh=10000.,
            projection='npstere')
# number of points to plot.
npts = 750
# generate random points on a sphere,
# so that every small area on the sphere is expected
# to have the same number of points.
# http://mathworld.wolfram.com/SpherePointPicking.html
u = uniform(0., 1., size=npts)
v = uniform(0., 1., size=npts)
z = uniform(0, 100, size=npts)
lons = 360. * u
lats = (180. / pi) * arccos(2 * v - 1) - 90.
# transform lons and lats to map coordinates.
x, y = m(lons, lats)
# plot them as filled circles on the map.
# first, create a figure.
fig = figure()
# background color will be used for 'wet' areas.
fig.add_axes([0.1, 0.1, 0.8, 0.8], axisbg='aqua')
# draw colored markers.
# use zorder=10 to make sure markers are drawn last.
# (otherwise they are covered up when continents are filled)
#m.scatter(x,y,25,z,cmap=cm.jet,marker='o',faceted=False,zorder=10)
# create a list of strings containing z values
# or, plot actual numbers as color-coded text strings.
zn = ['%2i' % zz for zz in z]
# plot numbers on map, colored by value.
Exemple #37
0
def arcdistance(d,R):
    return R * pl.arccos(1 - 0.5*d*d / (R*R))
Exemple #38
0
import pylab
import numpy
from scipy.optimize import curve_fit
t,T,Tr=pylab.loadtxt('pendulum.txt',unpack='True')
lmax=118. # sigma 0.1cm
lcm=113.26#sigma 0.1cm
dl=0.1
g=980
s=2.09 #sigma 0.005cm
ds=0.005
v=(s/Tr)*(lcm/lmax)
Theta=pylab.arccos(1.-(v**2)/(2*980.*lcm))
def vel(x,v0,tau):
	return v0*pylab.exp(-x/tau)
def theta(x,p1,p2):
	return 2*pylab.pi*pylab.sqrt(lcm/980.)*(1+p1*(x**2)+p2*(x**4))
popt,pcov=curve_fit(vel,t,v,sigma=s/t)
v0_fit,tau_fit=popt
dv0_fit, dtau_fit=pylab.sqrt(pcov.diagonal())
print(f"v0={v0_fit} +- {dv0_fit}")
print(f"tau={tau_fit} +- {dtau_fit}")
def errorel(vi):
        return (vi**2)/(2*g*(lcm**2)*numpy.sqrt(1-(1-((vi**2)/(2*g*lcm)))**2))
def errores(ti):
        return (s)/(g*lcm*numpy.sqrt(1-((1-((s**2)/(2*g*lcm*(ti**2))))**2))*(ti**2))
errs=(errores(Tr)*ds)
errl=errorel(v)*dl
errtheta=numpy.sqrt(errs**2+errl**2)
def erroret(x):
        return 2*numpy.sqrt(lcm/980.)*numpy.pi*(x/8+(11/768)*x**3)
erry=erroret(Theta)*errtheta
def Nadir_functional_test(
        root,
        date,
        duration,
        relativeTime,
        Timeline_settings,
        configFile,
        Test_settings={'ExpTimes': [1000, 2000, 4000, 8000, 16000]}):
    """Nadir_functional_test

    Schedules Nadir_functional_test with defined parameters and simulates MATS propagation from TLE.
    Scheduling of all daylight and nighttime commands are separated timewise and all commands for one of the two is scheduled first.
    """

    Logger.info('')
    Logger.info('Start of Nadir_functional_test')

    Logger.debug('Test_settings from Science Mode List: ' + str(Test_settings))

    CCD_settings = configFile.CCD_macro_settings('FullReadout')
    altitude = Timeline_settings['StandardPointingAltitude']

    ExpTimes = Test_settings['ExpTimes']

    log_timestep = 500
    Logger.debug('log_timestep [s]: ' + str(log_timestep))

    duration_flag = 0

    JPEGQs = [100, 95]
    WDWs = [7, 128]

    initial_relativeTime = relativeTime

    TLE = configFile.getTLE()
    MATS_skyfield = skyfield.api.EarthSatellite(TLE[0], TLE[1])

    Altitude_defining_night = 45  # km
    Altitude_defining_day = 25  # km
    R_mean = 6371

    # Estimation of the angle [degrees] between the sun and the FOV position when it enters eclipse
    NightAngle = arccos(R_mean /
                        (R_mean + Altitude_defining_night)) / pi * 180 + 90
    DayAngle = arccos(R_mean /
                      (R_mean + Altitude_defining_day)) / pi * 180 + 90

    Logger.debug('')
    Logger.debug('DayAngle : ' + str(DayAngle))
    Logger.debug('NightAngle : ' + str(NightAngle))
    Logger.debug('')

    withinLat = 30

    Mode_name = sys._getframe(0).f_code.co_name

    t = 0
    timestep = 4

    # latMargin = 360/5400 * timestep * 5 #Overly estimated change of latitude per timestep

    "Start looping the CCD nadir settings and call for macros"
    for mode in ['Day', 'Night']:

        for JPEGQ, WDW in zip(JPEGQs, WDWs):

            CCD_settings[64]['JPEGQ'] = JPEGQ
            CCD_settings[64]['WDW'] = WDW

            for ExpTime in ExpTimes:

                CCD_settings[64]['TEXPMS'] = ExpTime

                ############################################################################
                ########################## Orbit simulator #################################
                ############################################################################

                # for lat in [-30, 0, 30]:

                "Calculate the current angle between MATS and the Sun"
                "and Loop until it is either day or night and the right latitude"
                while (True):

                    mode_relativeTime = relativeTime - initial_relativeTime
                    current_time = ephem.Date(date +
                                              ephem.second * mode_relativeTime)

                    if (mode_relativeTime > duration and duration_flag == 0):
                        Logger.warning(
                            'Warning!! The scheduled time for the Test has ran out.'
                        )
                        #input('Enter anything to continue:\n')
                        duration_flag = 1

                    if (t * timestep % log_timestep == 0):
                        LogFlag = True
                    else:
                        LogFlag = False

                    Satellite_dict = Library.Satellite_Simulator(
                        MATS_skyfield, current_time, Timeline_settings,
                        altitude / 1000, LogFlag, Logger)

                    r_MATS = Satellite_dict['Position [km]']
                    lat_MATS = Satellite_dict['Latitude [degrees]']

                    sun_angle = Library.SunAngle(r_MATS, current_time)

                    if (t * timestep % log_timestep == 0 == 0 or t == 1):
                        Logger.debug('')
                        Logger.debug('current_time: ' + str(current_time))
                        Logger.debug('lat_MATS [degrees]: ' + str(lat_MATS))
                        Logger.debug('sun_angle [degrees]: ' + str(sun_angle))
                        Logger.debug('mode: ' + str(mode))
                        Logger.debug('')

                    # if( (sun_angle < DayAngle and lat-latMargin <= lat_MATS <= lat+latMargin and mode == 'Day' ) or
                    #   (sun_angle > NightAngle and lat-latMargin <= lat_MATS <= lat+latMargin and mode == 'Night' )):
                    if ((sun_angle < DayAngle and abs(lat_MATS) < withinLat
                         and mode == 'Day') or
                        (sun_angle > NightAngle and abs(lat_MATS) < withinLat
                         and mode == 'Night')):

                        Logger.debug('!!Break of Loop!!')
                        Logger.debug('Loop Counter (t): ' + str(t))
                        Logger.debug('current_time: ' + str(current_time))
                        Logger.debug('lat_MATS [degrees]: ' + str(lat_MATS))
                        Logger.debug('sun_angle [degrees]: ' + str(sun_angle))
                        Logger.debug('mode: ' + str(mode))

                        Logger.debug('')
                        break

                    "Increase Loop counter"
                    t = t + 1

                    "Timestep for propagation of MATS"
                    relativeTime = round(relativeTime + timestep, 1)

                ############################################################################
                ########################## End of Orbit simulator ##########################
                ############################################################################

                comment = (Mode_name + ', ' + str(date) + ', ' +
                           ', pointing_altitude = ' + str(altitude) +
                           ', ExpTime = ' + str(ExpTime) + ', JPEGQ = ' +
                           str(JPEGQ))

                Logger.debug(comment)

                relativeTime = Macros.NadirSnapshot_Limb_Pointing_macro(
                    root=root,
                    relativeTime=relativeTime,
                    pointing_altitude=altitude,
                    CCD_settings=CCD_settings,
                    Timeline_settings=Timeline_settings,
                    configFile=configFile,
                    comment=comment)

                #"Postpone next command until at least the end of ExpTime"
                #relativeTime = round(float(relativeTime) + ExpTime/1000,2)

    mode_relativeTime = relativeTime - initial_relativeTime
    current_time = ephem.Date(date + ephem.second * mode_relativeTime)

    Logger.info('End of Nadir_functional_test')

    return relativeTime, current_time
Exemple #40
0
def  q2tg( q ):
    global fz
    if not fz:
        qq = q
        q=q0

    slack = 1.0/1000
    t0  = 10.7/1000 #10.9124/1000
    P   = mm_array(5.725,13.215)
    PA  = mm_array(10.198,-2.0)
    B   = mm_array(15.087,5.585)
    C   = mm_array(51.43,3.878)
    D   = mm_array(60,0)
    E   = mm_array(-6.9,41)
    W   = mm_array(17.5,-6)

    rp = 4.0/1000    # POM is 3.96
    rb = 3.2/2/1000  # metal is 3.175/2, but loose, then tendon
    rc = rb
    rd = 3.1/1000
    qd2= -p.pi       # Abitrary.  Needs to be enough to stay wrapped.
    re0= 5.4/1000
    re1= 3.2/1000

    beta = twoDang(B)
    AB = twoDmag_ang(B,q+beta)
    PB = PA+AB
    gamma = twoDang(C)
    AC = twoDmag_ang(C,q+gamma)
    BC = AC-AB
    delta = twoDang(D)
    AD = twoDmag_ang(D,q+delta)
    CD = AD-AC
    DE = E
    WA = W
    WE = WA+AD+DE
    g = 2*WE[0]

    qp2 = twoDang(PB) + p.arccos((rp+rb)/p.norm(PB))
    fPB = hypleg(PB,rp+rb)
    qb1 = qp2 + p.pi

    fBC = p.norm(BC)
    qb2 = twoDang(BC)+3*p.pi/2
    sB  = rb*(qb2-qb1)

    qc1 = qb2
    qc2 = twoDang(CD) + 2*p.pi - p.arccos((rc+rd)/p.norm(CD))
    fCD = hypleg(CD,rc+rd)
    sC  = rc*(qc2-qc1)
    qd1 = qc2 - p.pi
    sD  = rd*(qd1-qd2)

    fBD = fPB + sB + fBC + sC + fCD + sD

    if not fz:
        # COMPUTE TOTAL TENDON LENGTH AT OPEN GRIPPER
        TP   = P+p.array([0.0,slack])
        fTP  = hypleg(TP,rp)
        qp1  = twoDang(TP) + p.pi - p.arccos(rp/p.norm(TP))
        sP   = rp*(qp1-qp2)
        fz   = fTP + sP + fBD
        # OUTPUT INFO ABOUT START POINT
        print ("t0=%.4f, TPz=[%.4f,%.4f], fTPz=%.4f, qp1=%.1f, fz=%.4f"%(t0,TP[0],TP[1],fTP,qp1*R2D,fz))

    # APPROX qp1 as constant
    qp1_approx = 173.0 * D2R
    qp1 = qp1_approx
    sP  = rp*(qp1-qp2)
    P1x = rp*p.cos(qp1)
    P1y = rp*p.sin(qp1)
    fTP = fz-sP-fBD
    fTPx = P[0] + P1x
    fTPy = hypleg(fTP,fTPx)
    t = P[1] + t0 + slack + P1y - fTPy

    # PLOT THE "SKELETON" OF IMPORTANT POINTS TO SANITY CHECK 
    skel = propkin([[0.0,t-t0],P+p.array([0.0,t0-t]),PA,AB,BC,CD,DE])
    p.figure(10); p.axis("equal")
    p.plot(skel[0,:],skel[1,:])

#    ####################
#    # FORCES FOR SPRING
#    Ft  = 1.0  # unit force
#
#    Fb  = twoDmag_ang( 2*Ft * p.sin((qb2-qb1)/2), (qb2+qb1)/2 - p.pi)
#    TQb = p.cross(AB,Fb)
#
#    Fc  = twoDmag_ang( 2*Ft * p.sin((qc2-qc1)/2), (qc2+qc1)/2 - p.pi)
#    TQc = p.cross(AC,Fc)
#
#    # NOTE: NET TORQUE ABOUT DISTAL IS ZERO.
#    # WE DO NOT SOLVE TORQUE ABOUT DISTAL PROBLEM.
#    # REACTION FORCES ON PROXIMAL LINK AXLE CAUSE TORQUES ON PROXIMAL
#
#    # FLEXOR TENDON FORCE ON DISTAL, TRANSFERED TO AXLE
#    Ff1 = twoDmag_ang( Ft, qd1 + p.pi/2 )
#    TQf = p.cross(AD,Ff1)
#
#    # SPRING TENDON FORCE ON DISTAL, TRANSFERED TO AXLE
#    Fs  = 1.0  # unit force
#    Fe1 = twoDmag_ang( Fs, q + p.arcsin((re0-re1)/p.norm(AD)) + p.pi )
#    TQFe= p.cross(AD,Fe1)
#
#    Ft_per_Fs = -TQFe/(TQb + TQc + TQf)

    ######################
    # Moment arm for proximal
    PP1 = twoDmag_ang( rp, qp1 )
    AB1 = AB + twoDmag_ang( rb, qb1 )
    PB1 = PA + AB1
    dirB1P1 = (PP1 - PB1)/p.norm(PP1 - PB1)
    mF = p.cross( AB1, dirB1P1 )

    return (t,q,g, mF)
def date_calculator():
    """Subfunction, Simulates MATS FOV and the Moon.
    
    Determines when the Moon is entering the FOV at an vertical offset-angle equal to *#V-offset* and also being 
    located at a horizontal off-set angle equal to less than *#H-offset* when pointing at an LP altitude equal to *#pointing_altitude*. \n
    
    A timeskip equal to 1/2 an orbit of MATS is applied after a successful spotting of the Moon to save processing time. \n
    
    A timeskip equal to the time it takes for the Moon orbital position to change by *#H-offset*/4 degrees are also applied if the Moon is 
    determined to be at an horizontal off-set angle larger then the horizontal FOV of the instrument, equal to *#HFOV*. \n
    
    (# as defined in the *Configuration File*). \n
    
    Saves the date and parameters regarding the spotting of the Moon to the variable SpottedMoonList.
    
    Arguments:
        
    Returns:
        SpottedMoonList ((:obj:`list` of :obj:`dict`)) or (str): A list containing dictionaries containing parameters for each time the Moon is spotted. Or just a date depending on 'automatic' in *Mode124_settings*.
    
    """

    Timeline_settings = OPT_Config_File.Timeline_settings()
    Mode124_settings = OPT_Config_File.Mode124_settings()

    log_timestep = Mode124_settings['log_timestep']
    Logger.debug('log_timestep: ' + str(log_timestep))

    ##################################################

    "Check how many times Mode124 have been scheduled"
    Mode124Iteration = _Globals.Mode124Iteration
    "Make the V_offset_Index go from 0 to len(Mode124_settings['V_offset']"
    V_offset_Index = (Mode124Iteration - 1) % (len(
        Mode124_settings['V_offset']))

    "Constants"
    V_offset = Mode124_settings['V_offset'][V_offset_Index]
    H_offset = Mode124_settings['H_offset']
    pointing_altitude = Mode124_settings['pointing_altitude'] / 1000

    Moon_orbital_period = 3600 * 24 * 27.32
    yaw_correction = Timeline_settings['yaw_correction']

    Logger.debug('H_offset set to [degrees]: ' + str(H_offset))
    Logger.debug('V_offset set to [degrees]: ' + str(V_offset))
    Logger.debug('Moon_orbital_period [s]: ' + str(Moon_orbital_period))
    Logger.debug('yaw_correction set to: ' + str(yaw_correction))

    TLE = OPT_Config_File.getTLE()
    Logger.debug('TLE used: ' + TLE[0] + TLE[1])

    ##########################################################

    "Simulation length and timestep"

    timestep = Mode124_settings['timestep']  #In seconds
    Logger.info('Timestep set to [s]: ' + str(timestep))

    if (Mode124_settings['TimeToConsider'] <= Timeline_settings['duration']):
        duration = Mode124_settings['TimeToConsider']
    else:
        duration = Timeline_settings['duration']
    Logger.info('Duration set to [s]: ' + str(duration))

    timesteps = int(ceil(duration / timestep)) + 2

    timeline_start = ephem.Date(Timeline_settings['start_date'])
    initial_time = ephem.Date(timeline_start +
                              ephem.second * Mode124_settings['freeze_start'])

    Logger.info('Initial simulation date set to: ' + str(initial_time))

    "Pre-allocate space"
    r_MATS = zeros((timesteps, 3))
    lat_MATS = zeros((timesteps, 1))
    long_MATS = zeros((timesteps, 1))
    optical_axis = zeros((timesteps, 3))
    negative_normal_orbit = zeros((timesteps, 3))
    r_H_offset_normal = zeros((timesteps, 3))
    r_V_offset_normal = zeros((timesteps, 3))
    MATS_P = zeros((timesteps, 1))

    r_Moon = zeros((timesteps, 3))
    r_MATS_2_Moon = zeros((timesteps, 3))
    r_MATS_2_Moon_norm = zeros((timesteps, 3))
    Moon_r_V_offset_plane = zeros((timesteps, 3))
    Moon_r_H_offset_plane = zeros((timesteps, 3))
    Moon_r_orbital_plane = zeros((timesteps, 3))
    Moon_vert_offset = zeros((timesteps, 1))
    Moon_hori_offset = zeros((timesteps, 1))
    angle_between_orbital_plane_and_moon = zeros((timesteps, 1))
    SpottedMoonList = []
    r_Moon_unit_vector = zeros((timesteps, 3))

    Dec_optical_axis = zeros((timesteps, 1))
    RA_optical_axis = zeros((timesteps, 1))

    ts = api.load.timescale(builtin=True)
    MATS_skyfield = api.EarthSatellite(TLE[0], TLE[1])

    planets = api.load('de421.bsp')
    Moon = planets['Moon']
    Earth = planets['Earth']

    t = 0

    current_time = initial_time

    Logger.info('')
    Logger.info('Start of simulation for Mode124')

    ######### SIMULATION ################
    while (current_time < initial_time + ephem.second * duration):

        if (t * timestep % log_timestep == 0):
            LogFlag = True
        else:
            LogFlag = False

        Satellite_dict = Satellite_Simulator(MATS_skyfield, current_time,
                                             Timeline_settings,
                                             pointing_altitude, LogFlag,
                                             Logger)

        r_MATS[t] = Satellite_dict['Position [km]']
        MATS_P[t] = Satellite_dict['OrbitalPeriod [s]']
        lat_MATS[t] = Satellite_dict['Latitude [degrees]']
        long_MATS[t] = Satellite_dict['Longitude [degrees]']

        optical_axis[t] = Satellite_dict['OpticalAxis']
        Dec_optical_axis[t] = Satellite_dict['Dec_OpticalAxis [degrees]']
        RA_optical_axis[t] = Satellite_dict['RA_OpticalAxis [degrees]']

        ascending_node = Satellite_dict['AscendingNode']
        yaw_offset_angle = Satellite_dict['Yaw [degrees]']
        arg_of_lat = Satellite_dict['ArgOfLat [degrees]']

        negative_normal_orbit[t] = -Satellite_dict['OrbitNormal']
        r_H_offset_normal[t] = Satellite_dict['Normal2H_offset']
        r_V_offset_normal[t] = Satellite_dict['Normal2V_offset']

        ############# End of Calculations of orbital and pointing vectors #####

        current_time_datetime = ephem.Date(current_time).datetime()
        year = current_time_datetime.year
        month = current_time_datetime.month
        day = current_time_datetime.day
        hour = current_time_datetime.hour
        minute = current_time_datetime.minute
        second = current_time_datetime.second + current_time_datetime.microsecond / 1000000

        current_time_skyfield = ts.utc(year, month, day, hour, minute, second)

        Moon_apparent_from_Earth = Earth.at(current_time_skyfield).observe(
            Moon).apparent()
        r_Moon[t, 0:3] = Moon_apparent_from_Earth.position.km

        r_Moon_unit_vector[t, 0:3] = r_Moon[t, 0:3] / norm(r_Moon[t, 0:3])

        r_MATS_2_Moon[t] = r_Moon[t] - r_MATS[t]
        r_MATS_2_Moon_norm[t] = r_MATS_2_Moon[t] / norm(r_MATS_2_Moon[t])

        "Calculate Dec and RA of moon"
        Dec_Moon = arctan(
            r_Moon[t, 2] / sqrt(r_Moon[t, 0]**2 + r_Moon[t, 1]**2)) / pi * 180
        RA_Moon = arccos(
            dot([1, 0, 0], [r_Moon[t, 0], r_Moon[t, 1], 0]) /
            norm([r_Moon[t, 0], r_Moon[t, 1], 0])) / pi * 180

        if (r_Moon[t, 1] < 0):
            RA_Moon = 360 - RA_Moon

        "Project 'r_MATS_2_Moon' ontop of orbital plane"
        Moon_r_orbital_plane[t] = r_MATS_2_Moon_norm[t] - dot(
            r_MATS_2_Moon_norm[t],
            negative_normal_orbit[t]) * negative_normal_orbit[t]

        "Project 'r_MATS_2_Moon' ontop pointing H-offset and V-offset plane"
        Moon_r_V_offset_plane[t] = r_MATS_2_Moon_norm[t] - dot(
            r_MATS_2_Moon_norm[t], r_V_offset_normal[t]) * r_V_offset_normal[t]
        Moon_r_H_offset_plane[t] = r_MATS_2_Moon_norm[t] - dot(
            r_MATS_2_Moon_norm[t], r_H_offset_normal[t]) * r_H_offset_normal[t]

        "Dot product to get the Vertical and Horizontal angle offset of the Moon"
        Moon_vert_offset[t] = arccos(
            dot(optical_axis[t], Moon_r_V_offset_plane[t]) /
            (norm(optical_axis[t]) *
             norm(Moon_r_V_offset_plane[t]))) / pi * 180
        Moon_hori_offset[t] = arccos(
            dot(optical_axis[t], Moon_r_H_offset_plane[t]) /
            (norm(optical_axis[t]) *
             norm(Moon_r_H_offset_plane[t]))) / pi * 180

        "Get the offset angle sign correct"
        if (dot(cross(optical_axis[t], Moon_r_V_offset_plane[t]),
                negative_normal_orbit[t, 0:3]) > 0):
            Moon_vert_offset[t] = -Moon_vert_offset[t]
        if (dot(cross(optical_axis[t], Moon_r_H_offset_plane[t]),
                r_H_offset_normal[t]) > 0):
            Moon_hori_offset[t] = -Moon_hori_offset[t]

        "Angle between orbital plane and moon"
        angle_between_orbital_plane_and_moon[t] = arccos(
            dot(r_MATS_2_Moon_norm[t], Moon_r_orbital_plane[t]) /
            norm(Moon_r_orbital_plane[t])) / pi * 180

        if (t * timestep % log_timestep == 0 or t == 1):
            Logger.debug('angle_between_orbital_plane_and_moon [degrees]: ' +
                         str(angle_between_orbital_plane_and_moon[t]))
            Logger.debug('Moon_vert_offset [degrees]: ' +
                         str(Moon_vert_offset[t]))
            Logger.debug('Moon_hori_offset [degrees]: ' +
                         str(Moon_hori_offset[t]))

        #print('angle_between_orbital_plane_and_moon = ' + str(angle_between_orbital_plane_and_moon[t]))

        if (t != 0):
            "Check that the Moon is entering at V-offset degrees and within the H-offset angle"
            if (Moon_vert_offset[t] <= V_offset
                    and Moon_vert_offset[t - 1] > V_offset
                    and abs(Moon_hori_offset[t]) < H_offset):

                Logger.debug('')
                Logger.debug('!!!!!!!!Moon available!!!!!!!!!!')
                Logger.debug('t (loop iteration number): ' + str(t))
                Logger.debug('Current time: ' + str(current_time))
                Logger.debug('Orbital Period in s: ' + str(MATS_P[t]))
                Logger.debug('Vector to MATS [km]: ' + str(r_MATS[t, 0:3]))
                Logger.debug('Latitude in radians: ' + str(lat_MATS[t]))
                Logger.debug('Longitude in radians: ' + str(long_MATS[t]))

                if (yaw_correction == True):
                    Logger.debug('ascending_node: ' + str(ascending_node))
                    Logger.debug('arg_of_lat [degrees]: ' + str(arg_of_lat))
                    Logger.debug('yaw_offset_angle [degrees]: ' +
                                 str(yaw_offset_angle))

                Logger.debug(
                    'angle_between_orbital_plane_and_moon [degrees]: ' +
                    str(angle_between_orbital_plane_and_moon[t]))
                Logger.debug('Moon_vert_offset [degrees]: ' +
                             str(Moon_vert_offset[t]))
                Logger.debug('Moon_hori_offset [degrees]: ' +
                             str(Moon_hori_offset[t]))
                Logger.debug('normal_orbit: ' +
                             str(-negative_normal_orbit[t, 0:3]))
                Logger.debug('r_V_offset_normal: ' +
                             str(r_V_offset_normal[t, 0:3]))
                Logger.debug('r_H_offset_normal: ' +
                             str(r_H_offset_normal[t, 0:3]))
                Logger.debug('optical_axis: ' + str(optical_axis[t, 0:3]))

                Logger.debug('')

                SpottedMoonList.append({
                    'Date': str(current_time),
                    'V-offset': Moon_vert_offset[t],
                    'H-offset': Moon_hori_offset[t],
                    'long_MATS': float(long_MATS[t]),
                    'lat_MATS': float(lat_MATS[t]),
                    'Dec': Dec_Moon,
                    'RA': RA_Moon,
                    'Dec FOV': Dec_optical_axis[t],
                    'RA FOV': RA_optical_axis[t]
                })

                Logger.debug('Jump ahead half an orbit in time')
                "Skip ahead half an orbit"
                current_time = ephem.Date(current_time +
                                          ephem.second * MATS_P[t] / 2)
                Logger.debug('Current time: ' + str(current_time))
                Logger.debug('')

        "To be able to make time skips when the moon is far outside the orbital plane of MATS"
        if ((angle_between_orbital_plane_and_moon[t] > H_offset
             and yaw_correction == False)
                or angle_between_orbital_plane_and_moon[t] >
                H_offset + abs(Timeline_settings['yaw_amplitude'])
                and yaw_correction == True):

            current_time = ephem.Date(current_time + ephem.second * H_offset /
                                      4 / 360 * Moon_orbital_period)
            #if( t*timestep % floor(log_timestep/400) == 0 ):
            Logger.debug('')
            Logger.debug('angle_between_orbital_plane_and_moon [degrees]: ' +
                         str(angle_between_orbital_plane_and_moon[t]))
            Logger.debug('Moon currently not visible -> jump ahead')
            Logger.debug('current_time after jump is is: ' + str(current_time))

            t = t + 1
        else:
            t = t + 1
            current_time = ephem.Date(current_time + ephem.second * timestep)

    Logger.info('End of simulation for Mode124')
    Logger.debug('SpottedMoonList: ' + str(SpottedMoonList))

    return SpottedMoonList
long=nvargrd['lon_rho'][:]
nlat,nlon=long.shape


cang=nvargrd['tide_Cangle'][:]
cangr=pl.zeros_like(cang)


u0=pl.ones_like (long)
v0=pl.zeros_like(latg)

ur=pl.zeros_like (long)
vr=pl.zeros_like(latg)

ur,vr=proj.rotate_vector(u0,v0,long,latg)
alpha=pl.arccos(ur)*180./pi

for id in range(len(cang)):
    cangr[id,:]=cang[id,:]-alpha

cangr[cangr<0.]  =cangr[cangr<0.]  +360.
cangr[cangr>360.]=cangr[cangr>360.]-360.


nvargrd['tide_Cangle'][:]=cangr

#dimensions:
#    two = 2 ;
#    eta_rho = 300 ;
#    xi_rho = 240 ;
#    tide_period = UNLIMITED ; // (8 currently)
def Mode120_date_calculator():
    #if(True):

    Logger = logging.getLogger(Logger_name())
    log_timestep = 3600

    "Simulation length and timestep"

    duration = Timeline_params()['duration']
    Logger.info('Duration set to: ' + str(duration) + ' s')

    timestep = Mode120_calculator_defaults()['timestep']  #In seconds
    Logger.info('timestep set to: ' + str(timestep) + ' s')
    timesteps = int(floor(duration / timestep))

    date = Timeline_params()['start_time']
    Logger.info('date set to: ' + str(date))

    "Get relevant stars"
    result = Vizier(columns=['all'], row_limit=200).query_constraints(
        catalog='I/239/hip_main', Vmag=Mode120_calculator_defaults()['Vmag'])
    star_cat = result[0]
    ROWS = star_cat[0][:].count()
    stars = []
    stars_dec = zeros((ROWS, 1))
    stars_ra = zeros((ROWS, 1))

    "Insert stars into Pyephem"
    for t in range(ROWS):
        s = "{},f|M|F7,{},{},{},2000"
        s = s.format(star_cat[t]['HIP'], deg2HMS(ra=star_cat[t]['_RA.icrs']),
                     deg2HMS(dec=star_cat[t]['_DE.icrs']), star_cat[t]['Vmag'])
        stars.append(ephem.readdb(s))
        stars[t].compute(epoch='2018')
        stars_dec[t] = stars[t].dec
        stars_ra[t] = stars[t].ra

    Logger.debug('List of stars used: ' + str(star_cat))

    "Calculate unit-vectors of stars"
    stars_x = cos(stars_dec) * cos(stars_ra)
    stars_y = cos(stars_dec) * sin(stars_ra)
    stars_z = sin(stars_dec)
    stars_r = array([stars_x, stars_y, stars_z])
    stars_r = stars_r.transpose()

    "Prepare the excel file output"
    star_list_excel = []
    star_list_excel.append(['Name;'])
    star_list_excel.append(['t1;'])
    star_list_excel.append(['t2;'])
    star_list_excel.append(['long1;'])
    star_list_excel.append(['lat1;'])
    star_list_excel.append(['long2;'])
    star_list_excel.append(['lat2;'])
    star_list_excel.append(['mag;'])
    star_list_excel.append(['H_offset;'])
    star_list_excel.append(['V_offset;'])
    star_list_excel.append(['H_offset2;'])
    star_list_excel.append(['V_offset2;'])
    star_list_excel.append(['e_Hpmag;'])
    star_list_excel.append(['Hpscat;'])
    star_list_excel.append(['o_Hpmag;'])
    star_list_excel.append(['Classification;'])

    "Prepare the output"
    star_list = []

    "Pre-allocate space"
    lat_MATS = zeros((timesteps, 1))
    long_MATS = zeros((timesteps, 1))
    altitude_MATS = zeros((timesteps, 1))
    g_ra_MATS = zeros((timesteps, 1))
    g_dec_MATS = zeros((timesteps, 1))
    x_MATS = zeros((timesteps, 1))
    y_MATS = zeros((timesteps, 1))
    z_MATS = zeros((timesteps, 1))
    r_MATS = zeros((timesteps, 3))
    r_FOV = zeros((timesteps, 3))
    r_FOV_unit_vector = zeros((timesteps, 3))
    r_FOV_norm = zeros((timesteps, 3))
    r_azi_norm = zeros((timesteps, 3))
    stars_r_V_offset_plane = zeros((ROWS, 3))
    stars_r_H_offset_plane = zeros((ROWS, 3))
    stars_vert_offset = zeros((timesteps, ROWS))
    stars_hori_offset = zeros((timesteps, ROWS))
    stars_offset = zeros((timesteps, ROWS))
    normal_orbital = zeros((timesteps, 3))
    r_V_offset_normal = zeros((timesteps, 3))
    r_H_offset_normal = zeros((timesteps, 3))
    pitch_sensor_array = zeros((timesteps, 1))
    star_counter = 0
    spotted_star_name = []
    spotted_star_timestamp = []
    spotted_star_timecounter = []
    skip_star_list = []
    MATS_p = zeros((timesteps, 1))
    MATS_P = zeros((timesteps, 1))

    angle_between_orbital_plane_and_star = zeros((timesteps, ROWS))

    "Constants"
    R_mean = 6371  #Earth radius
    Logger.info('Earth radius used [km]: ' + str(R_mean))

    U = 398600.4418  #Earth gravitational parameter

    FOV_altitude = Mode120_calculator_defaults(
    )['default_pointing_altitude'] / 1000  #Altitude at which MATS center of FOV is looking
    Logger.info('FOV_altitude set to [km]: ' + str(FOV_altitude))

    pointing_adjustment = 3  #Angle in degrees that the pointing can be adjusted
    V_FOV = Mode120_calculator_defaults()['V_FOV']  #0.91 is actual V_FOV
    H_FOV = Mode120_calculator_defaults()['H_FOV']  #5.67 is actual H_FOV
    Logger.info('V_FOV set to [degrees]: ' + str(V_FOV))
    Logger.info('H_FOV set to [degrees]: ' + str(H_FOV))

    pitch_offset_angle = 0
    yaw_offset_angle = 0

    Logger.info('TLE used: ' + getTLE()[0] + getTLE()[1])
    MATS = ephem.readtle('MATS', getTLE()[0], getTLE()[1])

    Logger.info('')
    Logger.info('Start of simulation of MATS for Mode120')
    ################## Start of Simulation ########################################
    "Loop and calculate the relevant angle of each star to each direction of MATS's FOV"
    for t in range(timesteps):

        current_time = ephem.Date(date + ephem.second * timestep * t)

        MATS.compute(current_time)

        (lat_MATS[t], long_MATS[t], altitude_MATS[t], g_ra_MATS[t],
         g_dec_MATS[t]) = (MATS.sublat, MATS.sublong, MATS.elevation / 1000,
                           MATS.g_ra, MATS.g_dec)

        R = lat_2_R(lat_MATS[t])

        z_MATS[t] = sin(g_dec_MATS[t]) * (altitude_MATS[t] + R)
        x_MATS[t] = cos(g_dec_MATS[t]) * (altitude_MATS[t] + R) * cos(
            g_ra_MATS[t])
        y_MATS[t] = cos(g_dec_MATS[t]) * (altitude_MATS[t] + R) * sin(
            g_ra_MATS[t])

        r_MATS[t, 0:3] = [x_MATS[t], y_MATS[t], z_MATS[t]]

        #Semi-Major axis of MATS, assuming circular orbit
        MATS_p[t] = norm(r_MATS[t, 0:3])

        #Orbital Period of MATS
        MATS_P[t] = 2 * pi * sqrt(MATS_p[t]**3 / U)

        #Estimated pitch or elevation angle for MATS pointing
        pitch_sensor_array[t] = array(
            arccos(
                (R_mean + FOV_altitude) / (R + altitude_MATS[t])) / pi * 180)
        pitch_sensor = pitch_sensor_array[t][0]

        if (t * timestep % log_timestep == 0):
            Logger.debug('')
            Logger.debug('log_timestep: ' + str(log_timestep))
            Logger.debug('timestep: ' + str(timestep))
            Logger.debug('t (loop iteration number): ' + str(t))
            Logger.debug('Current time: ' + str(current_time))
            Logger.debug('Semimajor axis in km: ' + str(MATS_p[t]))
            Logger.debug('Orbital Period in s: ' + str(MATS_P[t]))
            Logger.debug('Vector to MATS [km]: ' + str(r_MATS[t, 0:3]))
            Logger.debug('Latitude in radians: ' + str(lat_MATS[t]))
            Logger.debug('Longitude in radians: ' + str(long_MATS[t]))
            Logger.debug('Altitude in km: ' + str(altitude_MATS[t]))
            Logger.debug('FOV pitch in degrees: ' + str(pitch_sensor))

        if (t != 0):

            ############# Calculations of orbital and pointing vectors ############
            "Vector normal to the orbital plane of MATS"
            normal_orbital[t, 0:3] = cross(r_MATS[t], r_MATS[t - 1])
            normal_orbital[t, 0:3] = normal_orbital[t, 0:3] / norm(
                normal_orbital[t, 0:3])

            "Rotate 'vector to MATS', to represent pointing direction, includes vertical offset change (Parallax is negligable)"
            rot_mat = rot_arbit(
                -pi / 2 + (-pitch_sensor + pitch_offset_angle) / 180 * pi,
                normal_orbital[t, 0:3])
            r_FOV[t, 0:3] = (r_MATS[t] @ rot_mat) / 2

            "Rotate yaw of pointing direction, meaning to rotate around the vector to MATS"
            rot_mat = rot_arbit(yaw_offset_angle / 180 * pi, r_MATS[t, 0:3])
            r_FOV[t, 0:3] = (r_FOV[t, 0:3] @ rot_mat)
            r_FOV_unit_vector[t, 0:3] = r_FOV[t, 0:3] / norm(r_FOV[t, 0:3])
            '''Rotate 'vector to MATS', to represent vector normal to satellite H-offset plane,
            which will be used to project stars onto it which allows the H-offset of stars to be found'''
            rot_mat = rot_arbit((-pitch_sensor) / 180 * pi,
                                normal_orbital[t, 0:3])
            r_H_offset_normal[t, 0:3] = (r_MATS[t] @ rot_mat)
            r_H_offset_normal[t, 0:3] = r_H_offset_normal[t, 0:3] / norm(
                r_H_offset_normal[t, 0:3])

            "If pointing direction has a Yaw defined, Rotate yaw of normal to pointing direction H-offset plane, meaning to rotate around the vector to MATS"
            rot_mat = rot_arbit(yaw_offset_angle / 180 * pi, r_MATS[t, 0:3])
            r_H_offset_normal[t, 0:3] = (r_H_offset_normal[t, 0:3] @ rot_mat)
            r_H_offset_normal[t, 0:3] = r_H_offset_normal[t, 0:3] / norm(
                r_H_offset_normal[t, 0:3])

            "Rotate orbital plane normal to make it into pointing V-offset plane normal"
            r_V_offset_normal[t, 0:3] = (normal_orbital[t, 0:3] @ rot_mat)
            r_V_offset_normal[t, 0:3] = r_V_offset_normal[t, 0:3] / norm(
                r_V_offset_normal[t, 0:3])

            if (t * timestep % log_timestep == 0 or t == 1):
                Logger.debug('Pointing direction of FOV: ' +
                             str(r_FOV_unit_vector[t, 0:3]))
                Logger.debug('Orthogonal direction to H-offset plane: ' +
                             str(r_H_offset_normal[t, 0:3]))
                Logger.debug('Orthogonal direction to V-offset plane: ' +
                             str(r_V_offset_normal[t, 0:3]))
                Logger.debug('Orthogonal direction to the orbital plane: ' +
                             str(normal_orbital[t, 0:3]))
                Logger.debug('')

#            '''Rotate 'vector to MATS', to represent vector normal to satellite yaw plane,
#            which will be used to rotate the yaw of the pointing'''
#            rot_mat = rot_arbit((-pitch_sensor)/180*pi, normal_orbital[t,0:3])
#            r_azi_norm[t,0:3] = (r_MATS[t] @ rot_mat)
#            r_azi_norm[t,0:3] = r_azi_norm[t,0:3] / norm(r_azi_norm[t,0:3])
#
#            "Rotate horizontal offset of pointing direction, around satellite yaw plane"
#            rot_mat = rot_arbit(yaw_offset_angle/180*pi, r_azi_norm[t,0:3])
#            r_FOV[t,0:3] = (r_FOV[t,0:3] @ rot_mat)
#            r_FOV_unit_vector[t,0:3] = r_FOV[t,0:3]/norm(r_FOV[t,0:3])/2
#
#            "Rotate orbital plane normal to match pointing V-offset plane normal"
#            r_V_offset_normal[t,0:3] = (normal_orbital[t,0:3] @ rot_mat)
#
#            '''Rotate pointing vector 90 degrees in the pointing elevation plane to get a vector,
#            which is normal to pointing azimuth plane'''
#            rot_mat = rot_arbit(pi/2, r_V_offset_normal[t,0:3])
#            r_FOV_norm[t,0:3] = (r_FOV[t,0:3] @ rot_mat)
#            r_FOV_norm[t,0:3] = r_FOV_norm[t,0:3] / norm(r_FOV_norm[t,0:3])

############# End of Calculations of orbital and pointing vectors #####

###################### Star-mapper ####################################

            "Check position of stars relevant to pointing direction"
            for x in range(ROWS):

                "Skip star if it is not visible during this epoch"
                if (stars[x].name in skip_star_list):

                    continue

                "Check if a star has already been spotted during this orbit."
                if (stars[x].name in spotted_star_name):
                    '''Check if not enough time has passed so that the star has not left FOV'''
                    if ((current_time -
                         spotted_star_timestamp[spotted_star_name.index(
                             stars[x].name)]) < ephem.second *
                        (V_FOV * 2 * MATS_P[t] / 360)):
                        '''Check if enough time has passed so that the star is roughly in the same
                        direction as original FOV and save lat,long, Hoffset, Voffset and time. Otherwise skip star.'''
                        if ((t -
                             spotted_star_timecounter[spotted_star_name.index(
                                 stars[x].name)]) * timestep == around(
                                     MATS_P[t] *
                                     (pitch_offset_angle + V_FOV / 2) / 360)):

                            "Project 'star vectors' ontop pointing H-offset and V-offset plane"
                            stars_r_V_offset_plane[x] = stars_r[0][x] - dot(
                                stars_r[0][x], r_V_offset_normal[
                                    t, 0:3]) * r_V_offset_normal[t, 0:3]

                            stars_r_H_offset_plane[x] = stars_r[0][x] - (
                                (dot(stars_r[0][x], r_H_offset_normal[t]) *
                                 r_H_offset_normal[t]) /
                                ((norm(r_H_offset_normal[t]))**2))

                            "Dot product to get the Vertical and Horizontal angle offset of the star in the FOV"
                            stars_vert_offset[t][x] = arccos(
                                dot(r_FOV[t], stars_r_V_offset_plane[x]) /
                                (norm(r_FOV[t]) *
                                 norm(stars_r_V_offset_plane[x]))) / pi * 180
                            stars_hori_offset[t][x] = arccos(
                                dot(r_FOV[t], stars_r_H_offset_plane[x]) /
                                (norm(r_FOV[t]) *
                                 norm(stars_r_H_offset_plane[x]))) / pi * 180

                            "Determine sign of off-set angle where positive V-offset angle is when looking at higher altitude"
                            if (dot(cross(r_FOV[t], stars_r_V_offset_plane[x]),
                                    r_V_offset_normal[t, 0:3]) > 0):
                                stars_vert_offset[t][
                                    x] = -stars_vert_offset[t][x]
                            if (dot(cross(r_FOV[t], stars_r_H_offset_plane[x]),
                                    r_H_offset_normal[t]) > 0):
                                stars_hori_offset[t][
                                    x] = -stars_hori_offset[t][x]

                            star_list_excel[2].append(str(current_time) + ';')
                            star_list_excel[5].append(
                                str(float(long_MATS[t] / pi * 180)) + ';')
                            star_list_excel[6].append(
                                str(float(lat_MATS[t] / pi * 180)) + ';')
                            star_list_excel[10].append(
                                str(stars_hori_offset[t][x]) + ';')
                            star_list_excel[11].append(
                                str(stars_vert_offset[t][x]) + ';')

                        continue

                        "If enough time has passed (half an orbit), the star can be removed from the exception list"
                    elif ((current_time -
                           spotted_star_timestamp[spotted_star_name.index(
                               stars[x].name)]) >= ephem.second *
                          (180 * MATS_P[t] / 360)):
                        spotted_star_timestamp.pop(
                            spotted_star_name.index(stars[x].name))
                        spotted_star_timecounter.pop(
                            spotted_star_name.index(stars[x].name))
                        spotted_star_name.remove(stars[x].name)

                "Total angle offset of the star compared to MATS's FOV"
                stars_offset[t][x] = arccos(
                    dot(r_FOV[t], stars_r[0][x]) /
                    (norm(r_FOV[t]) * norm(stars_r[0][x]))) / pi * 180

                "Project 'star vectors' ontop pointing H-offset and V-offset plane"
                stars_r_V_offset_plane[x] = stars_r[0][x] - (
                    dot(stars_r[0][x], r_V_offset_normal[t, 0:3]) *
                    r_V_offset_normal[t, 0:3])

                stars_r_H_offset_plane[x] = stars_r[0][x] - (
                    dot(stars_r[0][x], r_H_offset_normal[t]) *
                    r_H_offset_normal[t])

                "Dot product to get the Vertical and Horizontal angle offset of the star in the FOV"
                stars_vert_offset[t][x] = arccos(
                    dot(r_FOV[t], stars_r_V_offset_plane[x]) /
                    (norm(r_FOV[t]) *
                     norm(stars_r_V_offset_plane[x]))) / pi * 180
                stars_hori_offset[t][x] = arccos(
                    dot(r_FOV[t], stars_r_H_offset_plane[x]) /
                    (norm(r_FOV[t]) *
                     norm(stars_r_H_offset_plane[x]))) / pi * 180

                "Determine sign of off-set angle where positive V-offset angle is when looking at higher altitude"
                if (dot(cross(r_FOV[t], stars_r_V_offset_plane[x]),
                        r_V_offset_normal[t, 0:3]) > 0):
                    stars_vert_offset[t][x] = -stars_vert_offset[t][x]
                if (dot(cross(r_FOV[t], stars_r_H_offset_plane[x]),
                        r_H_offset_normal[t]) > 0):
                    stars_hori_offset[t][x] = -stars_hori_offset[t][x]

                "To be able to skip stars far outside the orbital plane of MATS"
                angle_between_orbital_plane_and_star[t][x] = arccos(
                    dot(stars_r[0][x], stars_r_V_offset_plane[x]) /
                    norm(stars_r_V_offset_plane[x])) / pi * 180

                "For first loop of stars, make exception list for stars not visible during this epoch"
                if (t == 1
                        and abs(angle_between_orbital_plane_and_star[t][x]) >
                        H_FOV / 2 + (duration * 2) / (365 * 24 * 3600) * 360):

                    Logger.debug(
                        'Skip star: ' + stars[x].name +
                        ', with H-offset of: ' +
                        str(angle_between_orbital_plane_and_star[t][x]) +
                        ' degrees')
                    skip_star_list.append(stars[x].name)
                    continue

                "Check if star is in FOV"
                if (abs(stars_vert_offset[t][x]) < V_FOV / 2
                        and abs(stars_hori_offset[t][x]) < H_FOV / 2):
                    #print('Star number:',stars[x].name,'is visible at',stars_vert_offset[t][x],'degrees VFOV and', \
                    #stars_hori_offset[t][x],'degrees HFOV','during',ephem.Date(current_time))

                    if (t % log_timestep == 0):
                        Logger.debug('Star: ' + stars[x].name +
                                     ', with H-offset: ' +
                                     str(stars_hori_offset[t][x]) +
                                     ' V-offset: ' +
                                     str(stars_vert_offset[t][x]) +
                                     ' in degrees is visible')

                    "Add the spotted star to the exception list and timestamp it"
                    spotted_star_name.append(stars[x].name)
                    spotted_star_timestamp.append(current_time)
                    spotted_star_timecounter.append(t)

                    "Log all relevent data for the star"
                    star_list_excel[0].append(stars[x].name + ';')
                    star_list_excel[1].append(str(current_time) + ';')
                    star_list_excel[3].append(
                        str(float(long_MATS[t] / pi * 180)) + ';')
                    star_list_excel[4].append(
                        str(float(lat_MATS[t] / pi * 180)) + ';')
                    star_list_excel[7].append(str(stars[x].mag) + ';')
                    star_list_excel[8].append(
                        str(stars_hori_offset[t][x]) + ';')
                    star_list_excel[9].append(
                        str(stars_vert_offset[t][x]) + ';')
                    star_list_excel[12].append(
                        str(star_cat[x]['e_Hpmag']) + ';')
                    star_list_excel[13].append(
                        str(star_cat[x]['Hpscat']) + ';')
                    star_list_excel[14].append(
                        str(star_cat[x]['o_Hpmag']) + ';')
                    star_list_excel[15].append(
                        str(star_cat[x]['SpType']) + ';')

                    "Log data of star relevant to filtering process"
                    star_list.append({
                        'Date':
                        str(current_time),
                        'V-offset':
                        stars_vert_offset[t][x],
                        'H-offset':
                        stars_hori_offset[t][x],
                        'long_MATS':
                        float(long_MATS[t] / pi * 180),
                        'lat_MATS':
                        float(lat_MATS[t] / pi * 180),
                        'Vmag':
                        stars[x].mag,
                        'Name':
                        stars[x].name
                    })

                    star_counter = star_counter + 1

            ######################### End of star_mapper #############################

    ########################## Optional plotter ###########################################
    '''
    from mpl_toolkits.mplot3d import axes3d
    
    "Orbital points to plot"
    points_2_plot_start = 0#0*24*120
    points_2_plot = points_2_plot_start+200
    
    "Plotting of orbit and FOV"
    fig = figure(1)
    ax = fig.add_subplot(111,projection='3d')
    ax.set_xlim3d(-7000, 7000)
    ax.set_ylim3d(-7000, 7000)
    ax.set_zlim3d(-7000, 7000)
    
    ax.scatter(x_MATS[points_2_plot_start:points_2_plot],y_MATS[points_2_plot_start:points_2_plot],z_MATS[points_2_plot_start:points_2_plot])
    ax.scatter(r_FOV[points_2_plot_start:points_2_plot,0],r_FOV[points_2_plot_start:points_2_plot,1],r_FOV[points_2_plot_start:points_2_plot,2])
    
    "Plotting of stars and FOV unit-vectors"
    fig = figure(2)
    ax = fig.add_subplot(111,projection='3d')
    ax.scatter(stars_r[0][:,0],stars_r[0][:,1],stars_r[0][:,2])
    ax.scatter(r_FOV_unit_vector[points_2_plot_start:points_2_plot,0],r_FOV_unit_vector[points_2_plot_start:points_2_plot,1],r_FOV_unit_vector[points_2_plot_start:points_2_plot,2])
    ax.scatter(r_V_offset_normal[points_2_plot_start:points_2_plot,0]/2, r_V_offset_normal[points_2_plot_start:points_2_plot,1]/2, r_V_offset_normal[points_2_plot_start:points_2_plot,2]/2)
    ax.scatter(normal_orbital[points_2_plot_start:points_2_plot,0]/2, normal_orbital[points_2_plot_start:points_2_plot,1]/2, normal_orbital[points_2_plot_start:points_2_plot,2]/2)
    ax.scatter(r_H_offset_normal[points_2_plot_start:points_2_plot,0]/2, r_H_offset_normal[points_2_plot_start:points_2_plot,1]/2, r_H_offset_normal[points_2_plot_start:points_2_plot,2]/2)
    '''
    ########################### END of Optional plotter ########################################

    "Write spotted stars to file"
    with open('MATS_Visible_Stars.csv', 'w', newline='') as write_file:
        writer = csv.writer(write_file, dialect='excel-tab')
        writer.writerows(star_list_excel)

    Logger.debug('Visible star list to be filtered:')
    Logger.debug(str(star_list))
    Logger.debug('')

    Logger.debug('Exit ' + str(__name__))
    Logger.debug('')

    return (star_list)
Exemple #44
0
def date_calculator(Settings):
    """Simulates MATS FOV and stars.
    
    Used by Mode121-123.
    Simuates MATS FOV and visible stars for one orbit then skips ahead for *Settings['Timeskip']* amount of days (as defined in the *Configuration File*). 
    Saves the date, pointing RA and Dec, and the magnitude of the brightest visible star at each timestep.
    
    Arguments:
        Settings (dict): Dictionary containing settings for this simulation.
        
    Returns:
        (array): Array containing date in first column and brightest magnitude visible in the second. Contains current Dec and RA in 3rd and 4th column respectively.
    
    """

    Timeline_settings = OPT_Config_File.Timeline_settings()

    "To either calculate when stars are visible and schedule from that data or just schedule at a given time given by Mode120_settings['start_date']"
    if (Settings['automatic'] == False):

        if (Settings['start_date'] == '0'):
            date = ephem.Date(Timeline_settings['start_date'])
        else:
            try:
                date = ephem.Date(Settings['start_date'])
            except:
                Logger.error(
                    'Could not get Settings["start_date"], exiting...')
                sys.exit()

        return date

    elif (Settings['automatic'] == True):

        "Simulation length and timestep"
        log_timestep = Settings['log_timestep']
        Logger.debug('log_timestep: ' + str(log_timestep))

        timestep = Settings['timestep']  #In seconds
        Logger.info('timestep set to: ' + str(timestep) + ' s')

        if (Settings['TimeToConsider'] <= Timeline_settings['duration']):
            duration = Settings['TimeToConsider']
        else:
            duration = Timeline_settings['duration']

        Logger.info('Duration set to: ' + str(duration) + ' s')

        timesteps = int(ceil(duration / timestep)) + 2
        Logger.info('Maximum number of timesteps set to: ' + str(timesteps))

        timeline_start = ephem.Date(Timeline_settings['start_date'])

        initial_time = ephem.Date(timeline_start +
                                  ephem.second * Settings['freeze_start'])
        Logger.info('initial_time set to: ' + str(initial_time))

        "Get relevant stars"
        result = Vizier(columns=['all'], row_limit=3000).query_constraints(
            catalog='I/239/hip_main', Vmag=Settings['Vmag'])
        star_cat = result[0]
        ROWS = star_cat[0][:].count()
        stars = []
        stars_dec = zeros((ROWS, 1))
        stars_ra = zeros((ROWS, 1))

        "Insert stars into Pyephem"
        for t in range(ROWS):
            s = "{},f|M|F7,{},{},{},2000/01/01 11:58:55.816"
            s = s.format(star_cat[t]['HIP'],
                         deg2HMS(ra=star_cat[t]['_RA.icrs']),
                         deg2HMS(dec=star_cat[t]['_DE.icrs']),
                         star_cat[t]['Vmag'])
            stars.append(ephem.readdb(s))
            stars[t].compute(epoch='2000/01/01 11:58:55.816')
            stars_dec[t] = stars[t].dec
            stars_ra[t] = stars[t].ra

        Logger.debug('')
        Logger.debug('List of stars used: ' + str(star_cat))
        Logger.debug('')

        "Calculate unit-vectors of stars"
        stars_x = cos(stars_dec) * cos(stars_ra)
        stars_y = cos(stars_dec) * sin(stars_ra)
        stars_z = sin(stars_dec)
        stars_r = array([stars_x, stars_y, stars_z])
        stars_r = stars_r.transpose()

        "Prepare the output"
        "Array containing date in first column and brightest magnitude visible in the second. Contains current Dec and RA in 3rd and 4th column"
        date_magnitude_array = zeros((timesteps, 4))
        "Set magntidues arbitrary large, which will correspond to no star being visible"
        date_magnitude_array[:, 1] = 100

        "Pre-allocate space"
        lat_MATS = zeros((timesteps, 1))
        long_MATS = zeros((timesteps, 1))
        optical_axis = zeros((timesteps, 3))
        stars_r_V_offset_plane = zeros((ROWS, 3))
        stars_r_H_offset_plane = zeros((ROWS, 3))
        stars_vert_offset = zeros((timesteps, ROWS))
        stars_hori_offset = zeros((timesteps, ROWS))
        r_V_offset_normal = zeros((timesteps, 3))
        r_H_offset_normal = zeros((timesteps, 3))
        star_counter = 0
        skip_star_list = []
        MATS_P = zeros((timesteps, 1))
        Dec_optical_axis = zeros((timesteps, 1))
        RA_optical_axis = zeros((timesteps, 1))

        angle_between_orbital_plane_and_star = zeros((timesteps, ROWS))

        "Constants"
        pointing_altitude = Settings['pointing_altitude'] / 1000
        V_FOV = Settings['V_FOV']
        H_FOV = Settings['H_FOV']  #5.67 is actual H_FOV

        yaw_correction = Timeline_settings['yaw_correction']

        Logger.debug('H_FOV set to [degrees]: ' + str(H_FOV))
        Logger.debug('V_FOV set to [degrees]: ' + str(V_FOV))
        Logger.debug('yaw_correction set to: ' + str(yaw_correction))

        TLE = OPT_Config_File.getTLE()
        Logger.debug('TLE used: ' + TLE[0] + TLE[1])

        MATS_skyfield = api.EarthSatellite(TLE[0], TLE[1])

        "Loop counter"
        t = 0

        TimeSkips = 0
        #time_skip_counter = 0
        Timeskip = Settings[
            'TimeSkip']  #Days to skip ahead after each completed orbit
        current_time = initial_time

        Logger.info('')
        Logger.info('Start of simulation of MATS for Mode121/122/123')

        ################## Start of Simulation ########################################
        "Loop and calculate the relevant angle of each star to each direction of MATS's FOV"
        while (current_time < timeline_start + ephem.second * duration):

            if (t * timestep % log_timestep == 0):
                LogFlag = True
            else:
                LogFlag = False

            Satellite_dict = Satellite_Simulator(MATS_skyfield, current_time,
                                                 Timeline_settings,
                                                 pointing_altitude, LogFlag,
                                                 Logger)

            MATS_P[t] = Satellite_dict['OrbitalPeriod [s]']
            lat_MATS[t] = Satellite_dict['Latitude [degrees]']
            long_MATS[t] = Satellite_dict['Longitude [degrees]']
            optical_axis[t] = Satellite_dict['OpticalAxis']
            Dec_optical_axis[t] = Satellite_dict['Dec_OpticalAxis [degrees]']
            RA_optical_axis[t] = Satellite_dict['RA_OpticalAxis [degrees]']
            r_H_offset_normal[t] = Satellite_dict['Normal2H_offset']
            r_V_offset_normal[t] = Satellite_dict['Normal2V_offset']

            ############# End of Calculations of orbital and pointing vectors #####

            "Add current date to date_magnitude_array"
            date_magnitude_array[t, 0] = current_time
            "Add optical axis Dec and RA to date_magnitude_array"
            date_magnitude_array[t, 2] = Dec_optical_axis[t]
            date_magnitude_array[t, 3] = RA_optical_axis[t]

            ###################### Star-mapper ####################################

            "Check position of stars relevant to pointing direction"
            for x in range(ROWS):

                "Skip star if it is not visible during this epoch"
                if (stars[x].name in skip_star_list):
                    continue

                "Project 'star vectors' ontop pointing H-offset and V-offset plane"
                stars_r_V_offset_plane[x] = stars_r[0][x] - (
                    dot(stars_r[0][x], r_V_offset_normal[t]) *
                    r_V_offset_normal[t])

                stars_r_H_offset_plane[x] = stars_r[0][x] - (
                    dot(stars_r[0][x], r_H_offset_normal[t]) *
                    r_H_offset_normal[t])

                "Dot product to get the Vertical and Horizontal angle offset of the star in the FOV"
                stars_vert_offset[t][x] = arccos(
                    dot(optical_axis[t], stars_r_V_offset_plane[x]) /
                    (norm(optical_axis[t]) *
                     norm(stars_r_V_offset_plane[x]))) / pi * 180
                stars_hori_offset[t][x] = arccos(
                    dot(optical_axis[t], stars_r_H_offset_plane[x]) /
                    (norm(optical_axis[t]) *
                     norm(stars_r_H_offset_plane[x]))) / pi * 180

                "For first loop of stars, make exception list for stars not visible during this epoch"
                if (t == 1):

                    "To be able to skip stars far outside the orbital plane of MATS"
                    angle_between_orbital_plane_and_star[t][x] = arccos(
                        dot(stars_r[0][x], stars_r_V_offset_plane[x]) /
                        norm(stars_r_V_offset_plane[x])) / pi * 180

                    if (abs(angle_between_orbital_plane_and_star[t][x]) >
                            H_FOV / 2 + (duration * 2) /
                        (365 * 24 * 3600) * 360):
                        Logger.debug(
                            'Skip star: ' + stars[x].name +
                            ', with angle_between_orbital_plane_and_star of: '
                            + str(angle_between_orbital_plane_and_star[t][x]) +
                            ' degrees')
                        skip_star_list.append(stars[x].name)
                        continue

                "Check if star is in FOV"
                if (abs(stars_vert_offset[t][x]) < V_FOV / 2
                        and abs(stars_hori_offset[t][x]) < H_FOV / 2):
                    #print('Star number:',stars[x].name,'is visible at',stars_vert_offset[t][x],'degrees VFOV and', \
                    #stars_hori_offset[t][x],'degrees HFOV','during',ephem.Date(current_time))

                    if (t % log_timestep == 0 or t == 1):
                        Logger.debug('Current time: ' + str(current_time))
                        Logger.debug('Star: ' + stars[x].name +
                                     ', with H-offset: ' +
                                     str(stars_hori_offset[t][x]) +
                                     ' V-offset: ' +
                                     str(stars_vert_offset[t][x]) +
                                     ' in degrees is visible')

                    "Check if it is the brightest star spotted in the current FOV at the current date, and if so, replace the current value"
                    if (stars[x].mag < date_magnitude_array[t, 1]):
                        date_magnitude_array[t, 1] = stars[x].mag

                    star_counter = star_counter + 1

            ######################### End of star_mapper #############################

            "Increase Simulation Time with a timestep, or skip ahead if 1 orbit is completed"
            t += 1
            if (t * timestep >= MATS_P[t - 1] * (TimeSkips + 1)):
                current_time = ephem.Date(current_time +
                                          ephem.second * Timeskip)
                TimeSkips += 1
            else:
                current_time = ephem.Date(current_time +
                                          ephem.second * timestep)
            '''
            "Increment time with timestep or jump ahead in time if a whole orbit was completed"
            if( (current_time - initial_time)/ephem.second > (timeskip/ephem.second * time_skip_counter + MATS_P[t] * (time_skip_counter+1)) ):
                "If one orbit has passed -> increment 'current_time' with 'timeskip' amount of days"
                time_skip_counter = time_skip_counter + 1
                current_time = ephem.Date(current_time + timeskip)
            else:
                "Else just increment the current_time with timestep"
                current_time = ephem.Date(current_time + ephem.second * timestep)
            
            "Loop counter"
            t = t + 1
            '''
        ################## End of Simulation ########################################

        return (date_magnitude_array)