Beispiel #1
0
def D(c,f,X):
    '''
    The derived elastica energy as in sharon
    E= a**2 etc.
    '''    
    # either c or f can be an array! not both
    # c: current bar orientation
    # f: flanker orientation
    # x: relative flanker distance and position orientation             
    x = X[0]
    y = X[1]

    ## 'Affinity' D
    # D = Ba^2 + Bb^2 -BaBb
    # Here Ba is the angle of the flanker with the line connecting it with the center
    # and Bb is the reverse for the center
    # See figure 5 in Leung & Malik (1998) for intuitive figure

    # flanker positional angles
    theta = pl.arctan2(x,y)
#        if theta > pi/2: theta-=pi   
#        if theta < -pi/2: theta+=pi

    # B values normalized within -pi to pi
    Ba = pl.arctan(pl.tan(0.5*(-f+theta)))*2     
    Bb = pl.arctan(pl.tan(0.5*(c-theta)))*2


    D = 4*(Ba**2 + Bb**2 - Ba*Bb)
    return D
def cart2pol(z):
    """
    Convertit les coordonnées cartésiennes en coordonées polaires
    """
    if z.real < 0:
        return (abs(z), pl.pi + pl.arctan(z.imag/z.real))
    elif z.real > 0:
        return (abs(z), pl.arctan(z.imag/z.real))
    elif z.real == 0:
        return (abs(z), pl.pi/2)
Beispiel #3
0
    def _get_angles(steps,track_length):
        angles = pl.zeros(track_length-2)
        polar = pl.zeros(pl.shape(steps))
        for i in range(track_length-1):
            polar[i,0] = pl.norm(steps[i,:])
            polar[i,1] = pl.arctan(steps[i,0]/steps[i,1])

            if pl.isnan( polar[i,1]):
                polar[i,1] = 0

            if (steps[i,0] >= 0):
                if (steps[i,1] >= 0):
                    pass
                elif (steps[i,1] < 0):
                    polar[i,1] += 2.*pl.pi
            elif (steps[i,0] < 0):
                if (steps[i,1] >= 0):
                    polar[i,1] += pl.pi
                elif (steps[i,1] < 0):
                    polar[i,1] += pl.pi

        for i in range(track_length-2):
            angles[i] = polar[i+1,1] - polar[i,1]

        return angles
Beispiel #4
0
def hillshade(data, scale=10.0, azdeg=165.0, altdeg=45.0):
    '''
    Convert data to hillshade based on matplotlib.colors.LightSource class.

    Args:
        data - a 2-d array of data
        scale - scaling value of the data. higher number = lower gradient
        azdeg - where the light comes from: 0 south ; 90 east ; 180 north ;
                        270 west
        altdeg - where the light comes from: 0 horison ; 90 zenith

    Returns:
        a 2-d array of normalized hilshade
    '''
    # convert alt, az to radians
    az = azdeg*pi/180.0
    alt = altdeg*pi/180.0
    # gradient in x and y directions
    dx, dy = gradient(data/float(scale))
    slope = 0.5*pi - arctan(hypot(dx, dy))
    aspect = arctan2(dx, dy)
    az = -az - aspect - 0.5*pi
    intensity = sin(alt)*sin(slope) + cos(alt)*cos(slope)*cos(az)
    mi, ma = intensity.min(), intensity.max()
    intensity = (intensity - mi)/(ma - mi)
    return intensity
Beispiel #5
0
def hillshade(data,scale=10.0,azdeg=165.0,altdeg=45.0):
  ''' 
    This code thanks to Ran Novitsky Nof
  http://rnovitsky.blogspot.co.uk/2010/04/using-hillshade-image-as-intensity.html
  Repeated here to make my cyclopean uk_map code prettier.

  convert data to hillshade based on matplotlib.colors.LightSource class.
    input:
         data - a 2-d array of data
         scale - scaling value of the data. higher number = lower gradient
         azdeg - where the light comes from: 0 south ; 90 east ; 180 north ;
                      270 west
         altdeg - where the light comes from: 0 horison ; 90 zenith
    output: a 2-d array of normalized hilshade
  '''
  
  from pylab import pi, gradient, arctan, hypot, arctan2, sin, cos
  # convert alt, az to radians
  az = azdeg*pi/180.0
  alt = altdeg*pi/180.0
  # gradient in x and y directions
  dx, dy = gradient(data/float(scale))
  slope = 0.5*pi - arctan(hypot(dx, dy))
  aspect = arctan2(dx, dy)
  intensity = sin(alt)*sin(slope) + cos(alt)*cos(slope)*cos(-az - aspect - 0.5*pi)
  intensity = (intensity - intensity.min())/(intensity.max() - intensity.min())
  return intensity
Beispiel #6
0
 def _determineLockinPhase(self,rawtdData):
     #determine the phase difference from X and Y channel (at maximum signal)
     
     ix_max=py.argmax(rawtdData[:,1])
     #take 9 datapoints to evaluate theta
     no=4
     XCs=rawtdData[max(0,ix_max-no):min(rawtdData.shape[0],ix_max+no),1]
     YCs=rawtdData[max(0,ix_max-no):min(rawtdData.shape[0],ix_max+no),2]
     return py.arctan(py.mean(YCs/XCs))
Beispiel #7
0
 def pos2angles(self, armPos, armLen):
     x = armPos[0]
     y = armPos[1]
     l1 = armLen[0]
     l2 = armLen[1]
     elang = abs(2*arctan(sqrt(((l1 + l2)**2 - (x**2 + y**2))/((x**2 + y**2) - (l1 - l2)**2)))); 
     phi = arctan2(y,x); 
     psi = arctan2(l2 * sin(elang), l1 + (l2 * cos(elang)));
     shang = phi - psi; 
     return [shang,elang]
Beispiel #8
0
 def _fillOneSlot(self, point):
     '''
     point, 3-dim array
     '''
     #pdb.set_trace()
     rotDeg = pl.arctan(point[1]/point[0]) * RAD2DEG
     if point[0]<0 and point[1]>0:
         rotDeg+=180
     elif point[0]<0 and point[1]<0:
         rotDeg-=180
     col=pl.floor((rotDeg - self.rotDegMin)/self.rotDegRes)
     
     xyDist=pl.norm(point[:2])
     row=pl.floor((pl.arctan(point[2]/xyDist) * RAD2DEG - self.vertDegMin)/self.vertDegRes)
     
     try:
         self.valSlots[row, col]+=pl.norm(point)
         self.cntSlots[row, col]+=1
     except IndexError:
         exit(0)
 
     return row, col
Beispiel #9
0
def cart2pol(x,y):
    """
    Cartesian coordinates to polar

    (C) 2013 Noah D. Brenowitz
    """
    from pylab import sqrt, arctan, pi
    r = sqrt(x**2 + y**2)
    theta = arctan(y/x)
    theta[x<0] = pi + theta[x<0]
    theta[theta <0 ] = theta[theta<0] +2*pi

    return (r, theta)
Beispiel #10
0
    def findE(self,c,f,X):
        ''' find E, the approximated sharon energy
        Inputss
        ----------
        - c: current bar orientation, relative to the vertical (can be double or array, if array D returns an array of D values)
        - f: flanker orientation, relative to the vertical  (double)
        - X: flanker position, relative to the current bar (x,y)

	So, as examples...
	findE(0,0,[0,1]) would be two vertical bars, positioned vertically in a line. 
	findE(pi/2,pi/2,[1,0]) would be two horizontal bars, positioned horizontally in a line.        
        '''
        # define x and y 
        x = X[0]
        y = X[1]      
        
        # flanker positional angle
        theta = pl.arctan2(x,y)
        
        # find and return D
        Ba = pl.arctan(tan(0.5*(-f+theta)))*2     
        Bb = pl.arctan(tan(0.5*(c-theta)))*2
        return  4*(Ba**2 + Bb**2 - Ba*Bb)
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
Beispiel #12
0
total_bits=50
samples_per_cycle=float(sampling_rate)/float(local_osc)
samples_per_bit=cycles_per_bit*samples_per_cycle
len_iq_samples=int(float(total_bits)*samples_per_bit)
total_samples_to_read=len_iq_samples*2
fileh=open(sys.argv[1],'rb')
samples=bytearray(fileh.read(total_samples_to_read))
print len(samples)
iq_samples=pl.array([complex(samples[i*2]-128, samples[i*2+1]-128) for i in range(0,len_iq_samples) ])
dc_component=pl.sum(iq_samples)/len_iq_samples
for i in range(-5,5):
    lo=pl.exp(-1j*pl.frange(0,len_iq_samples-1)*(local_osc+i*1000)*2*pl.pi/sampling_rate)
#pl.plot(iq_samples)
    down_convert=iq_samples*lo
    decimated_samples=[pl.sum(down_convert[i:i+samples_per_bit-1]) for i in range(0,len_iq_samples-int(samples_per_bit))]
    x_axis_range=pl.frange(len(decimated_samples)-1)/samples_per_bit
    print len(x_axis_range), len(decimated_samples)
    pl.subplot(211)
    pl.plot(x_axis_range,pl.real(decimated_samples),'b',
            x_axis_range,pl.imag(decimated_samples),'r')
    pl.title('IQ Samples')
    pl.subplot(212)
    pl.plot(x_axis_range,pl.arctan(pl.imag(decimated_samples)/pl.real(decimated_samples)))
    pl.title('Phase')
    pl.figure(2)
    f_range=pl.frange(-sampling_rate/2 , sampling_rate/2 ,(sampling_rate)/len_iq_samples)
    print len(f_range), len_iq_samples
    pl.plot(f_range[0:len_iq_samples],abs(pl.fft(iq_samples)))
    pl.plot('FFT of IQ Samples')
    pl.show()
Beispiel #13
0
    def draw(self, drawer, bool_draw_whole_model=False):

        drawer.getSketch(self.name, self.color)

        alpha_st = self.deg_alpha_st * np.pi / 180
        alpha_so = -self.deg_alpha_so * np.pi / 180
        r_si = self.mm_r_si
        d_so = self.mm_d_so
        d_sp = self.mm_d_sp
        d_st = self.mm_d_st
        d_sy = self.mm_d_sy
        w_st = self.mm_w_st
        r_st = self.mm_r_st
        r_sf = self.mm_r_sf
        r_sb = self.mm_r_sb
        Q = self.Q

        alpha_slot_span = 360 / Q * np.pi / 180

        P1 = [r_si, 0]
        P2 = [r_si * cos(alpha_st * 0.5), r_si * -sin(alpha_st * 0.5)]
        P3_temp = [d_so * cos(alpha_st * 0.5), d_so * -sin(alpha_st * 0.5)]
        P3_local_rotate = [
            cos(alpha_so) * P3_temp[0] + sin(alpha_so) * P3_temp[1],
            -sin(alpha_so) * P3_temp[0] + cos(alpha_so) * P3_temp[1]
        ]
        P3 = [P3_local_rotate[0] + P2[0], P3_local_rotate[1] + P2[1]]

        三角形的底 = r_si + d_sp
        三角形的高 = w_st * 0.5
        三角形的角度 = arctan(三角形的高 / 三角形的底)
        P4 = [三角形的底 * cos(三角形的角度), 三角形的底 * -sin(三角形的角度)]

        P5 = [P4[0] + d_st, P4[1]]

        # Option 1
        # 6 [94.01649113009418, -25.191642873516543] 97.33303383272235
        # Radius_InnerStatorYoke = r_si+d_sp+d_st
        # print('Radius_InnerStatorYoke #1:', Radius_InnerStatorYoke)
        # Option 2
        Radius_InnerStatorYoke = np.sqrt(P5[0]**2 + P5[1]**2)
        # print('Radius_InnerStatorYoke #2:', Radius_InnerStatorYoke)
        P6 = [
            Radius_InnerStatorYoke * cos(alpha_slot_span * 0.5),
            Radius_InnerStatorYoke * -sin(alpha_slot_span * 0.5)
        ]

        P7 = [(r_si + d_sp + d_st + d_sy) * cos(alpha_slot_span * 0.5),
              (r_si + d_sp + d_st + d_sy) * -sin(alpha_slot_span * 0.5)]
        P8 = [r_si + d_sp + d_st + d_sy, 0]

        list_segments = []
        if bool_draw_whole_model:
            P2_Mirror = [P2[0], -P2[1]]  # = iPark(P2, alpha_st)
            P3_Mirror = [P3[0], -P3[1]]
            P4_Mirror = [P4[0], -P4[1]]
            P5_Mirror = [P5[0], -P5[1]]

            def iPark(P, theta):
                return [
                    P[0] * np.cos(theta) + P[1] * -np.sin(theta),
                    P[0] * np.sin(theta) + P[1] * np.cos(theta)
                ]

            def draw_fraction(list_segments, P2, P3, P4, P5, P2_Mirror,
                              P3_Mirror, P4_Mirror, P5_Mirror):
                P5_Rotate = iPark(P5, alpha_slot_span)
                list_segments += drawer.drawArc([0, 0], P2, P2_Mirror)
                list_segments += drawer.drawLine(P2, P3)
                list_segments += drawer.drawLine(P2_Mirror, P3_Mirror)
                list_segments += drawer.drawLine(P3, P4)
                list_segments += drawer.drawLine(P3_Mirror, P4_Mirror)
                list_segments += drawer.drawLine(P4, P5)
                list_segments += drawer.drawLine(P4_Mirror, P5_Mirror)
                list_segments += drawer.drawArc([0, 0], P5_Mirror, P5_Rotate)

            for i in range(Q):
                draw_fraction(
                    list_segments,
                    iPark(P2, i * alpha_slot_span),
                    iPark(P3, i * alpha_slot_span),
                    iPark(P4, i * alpha_slot_span),
                    iPark(P5, i * alpha_slot_span),
                    iPark(P2_Mirror, i * alpha_slot_span),
                    iPark(P3_Mirror, i * alpha_slot_span),
                    iPark(P4_Mirror, i * alpha_slot_span),
                    iPark(P5_Mirror, i * alpha_slot_span),
                )
                # raise
            # draw a circle (this is officially suggested)
            list_segments += drawer.drawArc([0, 0], P8, [-P8[0], P8[1]])
            list_segments += drawer.drawArc([0, 0], [-P8[0], P8[1]], P8)
        else:
            list_segments += drawer.drawArc([0, 0], P2, P1)
            list_segments += drawer.drawLine(P2, P3)
            list_segments += drawer.drawLine(P3, P4)
            list_segments += drawer.drawLine(P4, P5)
            list_segments += drawer.drawArc([0, 0], P6, P5)
            list_segments += drawer.drawLine(P6, P7)
            list_segments += drawer.drawArc([0, 0], P7, P8)
            list_segments += drawer.drawLine(P8, P1)

        # DEBUG
        # for ind, point in enumerate([P1, P2, P3, P4, P5, P6, P7, P8]):
        #     print(ind+1, point, np.sqrt(point[0]**2+point[1]**2))

        self.innerCoord = (0.5 * (P1[0] + P5[0]), 0.5 * (P1[1] + P5[1]))

        # return [list_segments]
        return {
            'innerCoord': self.innerCoord,
            'list_regions': [list_segments],
            'mirrorAxis': [(P8[0] + 5, P8[1]), (P8[0] + 15, P8[1])]
        }
Beispiel #14
0
    def draw(self,
             drawer,
             bool_re_evaluate=False,
             bool_draw_whole_model=False):

        if False == bool_re_evaluate:
            drawer.getSketch(self.name, self.color)

        alpha_st = self.stator_core.deg_alpha_st * np.pi / 180
        alpha_so = self.stator_core.deg_alpha_so * np.pi / 180
        r_si = self.stator_core.mm_r_si
        d_so = self.stator_core.mm_d_so
        d_sp = self.stator_core.mm_d_sp
        d_st = self.stator_core.mm_d_st
        d_sy = self.stator_core.mm_d_sy
        w_st = self.stator_core.mm_w_st
        r_st = self.stator_core.mm_r_st
        r_sf = self.stator_core.mm_r_sf
        r_sb = self.stator_core.mm_r_sb
        Q = self.stator_core.Q

        alpha_slot_span = 360 / Q * np.pi / 180

        P1 = [r_si, 0]

        # 乘以0.99或0.95避免上层导体和下层导体重合导致导入Designer时产生多余的Parts。
        POpen = [(r_si + d_sp) * cos(alpha_slot_span * 0.5 * 1.00),
                 (r_si + d_sp) * -sin(alpha_slot_span * 0.5 * 1.00)]

        # P2 = [r_si*cos(alpha_st*0.5), r_si*-sin(alpha_st*0.5)]

        # P3_temp = [ d_so*cos(alpha_st*0.5),
        #             d_so*-sin(alpha_st*0.5)]
        # P3_local_rotate = [  cos(alpha_so)*P3_temp[0] + sin(alpha_so)*P3_temp[1],
        #                      -sin(alpha_so)*P3_temp[0] + cos(alpha_so)*P3_temp[1] ]
        # P3 = [  P3_local_rotate[0] + P2[0],
        #         P3_local_rotate[1] + P2[1] ]

        三角形的底 = r_si + d_sp
        三角形的高 = w_st * 0.5
        三角形的角度 = arctan(三角形的高 / 三角形的底)
        P4 = [三角形的底 * cos(三角形的角度), 三角形的底 * -sin(三角形的角度)]

        P5 = [P4[0] + d_st, P4[1]]

        PMiddle45 = [0.5 * (P4[0] + P5[0]), P4[1]]
        TheRadius = (P5[0] - P4[0]) * 0.45

        # 为了使得槽和导体之间不要接触,试着添加5%的clearance?
        P6 = [(r_si + d_sp + d_st) * cos(alpha_slot_span * 0.5) * 1.00,
              (r_si + d_sp + d_st) * -sin(alpha_slot_span * 0.5) * 1.00]

        self.mm2_slot_area = 2 * get_area_polygon(P4, P5, P6, POpen)
        print('[CrossSectStator.py] Stator slot area is %g mm^2' %
              (self.mm2_slot_area))
        if bool_re_evaluate:
            return self.mm2_slot_area

        PMiddle6Open = [0.5 * (P6[0] + POpen[0]), 0.5 * (P6[1] + POpen[1])]
        self.PCoil = PCoil = [
            0.5 * (PMiddle45[0] + PMiddle6Open[0]),
            0.5 * (PMiddle45[1] + PMiddle6Open[1])
        ]

        # P7 = [ (r_si+d_sp+d_st+d_sy)*cos(alpha_slot_span*0.5),
        #        (r_si+d_sp+d_st+d_sy)*-sin(alpha_slot_span*0.5) ]
        # P8 = [  r_si+d_sp+d_st+d_sy, 0]

        # Compute the vector starting from PCoil to one of the corner of the polygon.
        def shrink(PC, P):
            vector = [P[0] - PC[0], P[1] - PC[1]]
            return [PC[0] + 0.900 * vector[0], PC[1] + 0.900 * vector[1]]

        P6_Shrink = shrink(PCoil, P6)
        P5_Shrink = shrink(PCoil, P5)
        P4_Shrink = shrink(PCoil, P4)
        POpen_Shrink = shrink(PCoil, POpen)

        list_regions = []

        list_segments = []
        if bool_draw_whole_model:
            P6_Shrink_Mirror = [P6_Shrink[0], -P6_Shrink[1]]
            P5_Shrink_Mirror = [P5_Shrink[0], -P5_Shrink[1]]
            P4_Shrink_Mirror = [P4_Shrink[0], -P4_Shrink[1]]
            POpen_Shrink_Mirror = [POpen_Shrink[0], -POpen_Shrink[1]]

            def iPark(P, theta):
                return [
                    P[0] * np.cos(theta) + P[1] * -np.sin(theta),
                    P[0] * np.sin(theta) + P[1] * np.cos(theta)
                ]

            def draw_fraction(list_segments, P6_Shrink, P5_Shrink, P4_Shrink,
                              POpen_Shrink, P6_Shrink_Mirror, P5_Shrink_Mirror,
                              P4_Shrink_Mirror, POpen_Shrink_Mirror):
                list_segments += drawer.drawArc([0, 0], P6_Shrink, P5_Shrink)
                list_segments += drawer.drawLine(P5_Shrink, P4_Shrink)
                list_segments += drawer.drawLine(P4_Shrink, POpen_Shrink)
                list_segments += drawer.drawLine(POpen_Shrink, P6_Shrink)
                list_regions.append(list_segments)
                list_segments = []

                list_segments += drawer.drawArc([0, 0], P5_Shrink_Mirror,
                                                P6_Shrink_Mirror)
                list_segments += drawer.drawLine(P5_Shrink_Mirror,
                                                 P4_Shrink_Mirror)
                list_segments += drawer.drawLine(P4_Shrink_Mirror,
                                                 POpen_Shrink_Mirror)
                list_segments += drawer.drawLine(POpen_Shrink_Mirror,
                                                 P6_Shrink_Mirror)
                list_regions.append(list_segments)
                list_segments = []

            for i in range(Q):
                draw_fraction(
                    list_segments,
                    iPark(P6_Shrink, i * alpha_slot_span),
                    iPark(P5_Shrink, i * alpha_slot_span),
                    iPark(P4_Shrink, i * alpha_slot_span),
                    iPark(POpen_Shrink, i * alpha_slot_span),
                    iPark(P6_Shrink_Mirror, i * alpha_slot_span),
                    iPark(P5_Shrink_Mirror, i * alpha_slot_span),
                    iPark(P4_Shrink_Mirror, i * alpha_slot_span),
                    iPark(POpen_Shrink_Mirror, i * alpha_slot_span),
                )
                # raise
        else:
            # list_segments += drawer.drawCircle(PCoil, TheRadius)
            list_segments += drawer.drawArc([0, 0], P6_Shrink, P5_Shrink)
            list_segments += drawer.drawLine(P5_Shrink, P4_Shrink)
            list_segments += drawer.drawLine(P4_Shrink, POpen_Shrink)
            list_segments += drawer.drawLine(POpen_Shrink, P6_Shrink)
            list_regions.append(list_segments)

            PCoil[1] *= -1
            P6_Shrink[1] *= -1
            P5_Shrink[1] *= -1
            P4_Shrink[1] *= -1
            POpen_Shrink[1] *= -1
            list_segments = []
            # list_segments += drawer.drawCircle(PCoil, TheRadius)
            list_segments += drawer.drawArc([0, 0], P5_Shrink, P6_Shrink)
            list_segments += drawer.drawLine(P5_Shrink, P4_Shrink)
            list_segments += drawer.drawLine(P4_Shrink, POpen_Shrink)
            list_segments += drawer.drawLine(POpen_Shrink, P6_Shrink)
            list_regions.append(list_segments)
            list_segments = []

        # 我乱给的
        self.innerCoord = (0.5 * (POpen[0] + P6[0]), 0.5 * (POpen[1] + P6[1]))

        # return [list_segments]
        return {
            'innerCoord': self.innerCoord,
            'list_regions': list_regions,
            'mirrorAxis': None
        }
Beispiel #15
0
    def draw(self, drawer):

        drawer.getSketch(self.name, self.color)

        alpha_st = self.deg_alpha_st * np.pi/180
        alpha_so = -self.deg_alpha_so * np.pi/180
        r_si = self.mm_r_si
        d_so = self.mm_d_so
        d_sp = self.mm_d_sp
        d_st = self.mm_d_st
        d_sy = self.mm_d_sy
        w_st = self.mm_w_st
        r_st = self.mm_r_st
        r_sf = self.mm_r_sf
        r_sb = self.mm_r_sb
        Q    = self.Q

        alpha_slot_span = 360/Q * np.pi/180

        P1 = [r_si, 0]
        P2 = [r_si*cos(alpha_st*0.5), r_si*-sin(alpha_st*0.5)]
        P3_temp = [ d_so*cos(alpha_st*0.5), 
                    d_so*-sin(alpha_st*0.5)]
        P3_local_rotate = [  cos(alpha_so)*P3_temp[0] + sin(alpha_so)*P3_temp[1],
                             -sin(alpha_so)*P3_temp[0] + cos(alpha_so)*P3_temp[1] ]
        P3 = [  P3_local_rotate[0] + P2[0],
                P3_local_rotate[1] + P2[1] ]

        三角形的底 = r_si + d_sp
        三角形的高 = w_st*0.5
        三角形的角度 = arctan(三角形的高 / 三角形的底)
        P4 = [  三角形的底*cos(三角形的角度), 
                三角形的底*-sin(三角形的角度)]

        P5 = [ P4[0] + d_st, 
               P4[1]]

        P6 = [ (r_si+d_sp+d_st)*cos(alpha_slot_span*0.5),
               (r_si+d_sp+d_st)*-sin(alpha_slot_span*0.5) ]

        P7 = [ (r_si+d_sp+d_st+d_sy)*cos(alpha_slot_span*0.5),
               (r_si+d_sp+d_st+d_sy)*-sin(alpha_slot_span*0.5) ]
        P8 = [  r_si+d_sp+d_st+d_sy, 0]

        list_segments = []
        list_segments += drawer.drawArc([0,0], P2, P1)
        list_segments += drawer.drawLine(P2, P3)
        list_segments += drawer.drawLine(P3, P4)
        list_segments += drawer.drawLine(P4, P5)
        list_segments += drawer.drawArc([0,0], P6, P5)
        list_segments += drawer.drawLine(P6, P7)
        # l, vA = drawer.drawArc([0,0], P6, P5, returnVertexName=True)
        # list_segments += l
        # l, vB = drawer.drawLine(P6, P7, returnVertexName=True)
        # list_segments += l
        # drawer.addConstraintCocentricity(vA[0], vB[0])
        # raise

        list_segments += drawer.drawArc([0,0], P7, P8)
        list_segments += drawer.drawLine(P8, P1)

        return [list_segments]
Beispiel #16
0
def sim(vx0,y0,L01,a0,k1,dE,m,ygrd,t,fs,steps):

# function for using fmin    
#    def optfunc_dE(par):
#        return abs(-.5*k1*c**2+.5*(k1+par)*(c-(c*par/(k1+par)))**2-dE)
# function for using fsolve
    def optfunc_dE(par, spring_par):
        k1 = spring_par['k']
        c = spring_par['c']
        return abs(-.5*k1*c**2+.5*(k1+par)*(c-(c*par/(k1+par)))**2-dE)
       
    g = -9.81 # gravitational force
    betaTO_sim = zeros(steps)
    xF=0
    
    print 'x'
    
    x_sim = [0]
    y_sim = [0]
    vx_sim = [0]
    vy_sim = [0]
    t_sim = [0]
    
    k2 = 0
    L02 = 0
    
    skip_all = False
    st_lo_idx = -1
    # leg orientation
    xL = L01 * cos(a0 * pi/180.)
    yL = L01 * sin(a0 * pi/180.)
    
    # first ground contact
    t_gc = sqrt(2.*(L01*sin(a0*pi/180.)-y0)/g)
    
    if isnan(t_gc) == True:
        
        skip_all = True
    
    if skip_all == False:
        x_gc = vx0*t_gc
        y_gc = .5*g*t_gc**2 + y0
        
        # system parameter for first step
        s = zeros(4)
        s[0] = 0
        s[1] = y0
        s[2] = vx0
        s[3] = 0
        
        # definitions for calculation
        end_sim = False
        
        res = zeros([1,4])
        res_app = []
        t_v = [0]
        skip_stance = False
        
        # start loop
        while end_sim == False:
            st_lo_idx += 1 
            
            if st_lo_idx != 0: # if not first step
                t_gc = (-res[-1,3]/g) + \
                          sqrt( ((res[-1,3]**2)/(g**2)) - \
                          ((2*res[-1,1])/g-(2*L01*sin(a0*pi/180)/g)) )
                if isnan(t_gc) == False and isinf(t_gc) == False:
                    
                    y_gc = 0.5*g*t_gc**2 + res[-1,3]*t_gc + res[-1,1]
                    
                    t_vec = linspace(0,t_gc,ceil(t_gc*fs)+1)
                    #print len(t_vec)
                                    
                    s[0] = res[-1,2]*t_gc + res[-1,0]
                    s[1] = y_gc
                    s[2] = res[-1,2]
                    s[3] = g*t_gc +res[-1,3] 
                else:
                    t_gc = 1
                    t_vec = linspace(0,t_gc,ceil(t_gc*fs)+1)
                    end_sim = True
                    skip_stance = True
                    #break
                
                vx = zeros_like(t_vec)
                vy = zeros_like(t_vec)
                x =  zeros_like(t_vec)
                y =  zeros_like(t_vec)    
                
                vx[0] = res[-1,2]
                vy[0] = res[-1,3]
                x[0] = res[-1,0]
                y[0] = res[-1,1]
            else: # if first step
                t_vec = linspace(0,t_gc,ceil(t_gc*fs)+1)
                #print t_vec
                vx = zeros_like(t_vec)
                vy = zeros_like(t_vec)
                x =  zeros_like(t_vec)
                y =  zeros_like(t_vec) 
                #print vx
                vx[0] = s[2]
                vy[0] = s[3]
                x[0] = s[0]
                y[0] = s[1]
                
        ### flight phase 
            x[1:] = vx[0]*t_vec[1:] + x[0]
            y[1:] = .5*g*(t_vec[1:]**2)+vy[0]*t_vec[1:] + y[0]
            vy[1:] = g*t_vec[1:] + vy[0]
            vx[1:] = vx[0]*ones_like(t_vec[1:])
            
            # end at apex
            if st_lo_idx == steps or skip_stance == True:
                tapex = vy[0]/-g
                #print 'y0=',y0,'vy0=',vy[0],' tapex=',tapex
                tvec_apex = linspace(0,tapex,ceil(tapex*fs)+1)
                vyapex = g*tvec_apex+vy[0]
                #print 'vyapex=',vyapex
                yapex = .5*g*(tvec_apex**2) + vyapex[0]*tvec_apex + y[0]
                xapex = vx[0] * tvec_apex + x[0]
                vxapex = vx[0] * ones_like(tvec_apex)
                #print 'lvy:',len(vyapex),' lvx:',len(vxapex)
                
                x_sim = append(x_sim,xapex[1:])
                y_sim = append(y_sim,yapex[1:])
                vx_sim = append(vx_sim,vxapex[1:])
                vy_sim = append(vy_sim,vyapex[1:])
                t_sim = append(t_sim,tvec_apex[1:]+t_sim[-1])
                skip_stance = True
                
                """
                for kk in arange(2,len(y)):
                    if y[kk-2]<y[kk-1] and y[kk-1]>y[kk]:
                        end_sim = True
                        
                        x_sim = append(x_sim,x[1:kk])
                        y_sim = append(y_sim,y[1:kk])
                        vx_sim = append(vx_sim,vx[1:kk])
                        vy_sim = append(vy_sim,vy[1:kk])
                        t_sim = append(t_sim,t_vec[1:kk]+t_sim[-1])
                """
                    
        ### stance phase
            
            if skip_stance == False:
                # system parameter
                if st_lo_idx == 0: # if first step
                    s[0] = x_gc         # x
                    s[1] = y_gc         # y
                    s[2] = vx0          # vx
                    s[3] = g*t_gc + 0   # vy
                    
                xF = s[0]+xL
                yF = ygrd
                
                
                parameter = {'k':k1,'L0':L01,'m':m,'g':g,'xF':xF,'yF':yF}
                calc_length = 0.1*fs
                
                find_pos = False
                round_prec = 11 # precision of rounding
                #print 'round_prec = ', round_prec
                
                step_size = 1./fs
        
                res = zeros([1,4]) 
                t_v = [0] 
                
                res_app = False
                skip = False  
                
                L0 = L01
                
                FinMin = False
                # start integration of stance phase
                while find_pos == False:
                    t_vint = (step_size) * arange(calc_length)
                    res_int = odeint(s_dot,s,t_vint, args=(parameter,), rtol=1e-11)
                    
                    # stop condition vx or y < 0
                    if res_int[-1,1] < 0 or res_int[-1,2] < 0: 
                        find_pos = True
                        end_sim = True
                        skip = True  
                    
                    # if ymin: calculation of new k and L for energy changes
                    for idx in arange(1,len(res_int[:,1])-1):
                        if res_int[idx,1]<res_int[idx-1,1] and  res_int[idx,1]<res_int[idx+1,1]:
                            res_int=delete(res_int,s_[idx+1::],0)
                            t_vint = delete(t_vint,s_[idx+1::],0)
                            c= L0-(sqrt(res_int[-1,1]**2 + (xF-res_int[-1,0])**2))
                            #dk = fmin(optfunc_dE,0,full_output=1,disp=0,xtol=1e-12)
                            spring_par = {'k':k1,'c':c}
                            dk = fsolve(optfunc_dE,x0=[0],args=(spring_par,))                            
                            #print '###### dk ####',dk
                            # if not find a minimum stop loop --> no step
                            #if dk[-1] <> 0:
                            #    find_pos = True
                            #    end_sim = True
                            #    skip = True
                            #    raise ValueError, 'no energy management possible'
                            #    break
                            k2 = k1+dk[0]
                            L02 = L01 - c*dk[0]/(k1+dk[0])
                            #print 'delta L = ',L0 - L02, ' delta k = ', dk[0]
                            L0 = L02
                            parameter = {'k':k2,'L0':L02,'m':m,'g':g,'xF':xF,'yF':yF}
                            FinMin = True
                            break
                    
                    # if not ymin: start one before to avoid ignoring while change
                    if FinMin == False:
                        res_int = res_int[:-1]
                        t_vint = t_vint[:-1]
                    
                    # virtual leg after integration
                    L_virt = sqrt(res_int[-1,1]**2 + (xF-res_int[-1,0])**2)
                    
                    if L_virt < L0 and skip == False:
                        s[0] = res_int[-1,0]
                        s[1] = res_int[-1,1]
                        s[2] = res_int[-1,2]
                        s[3] = res_int[-1,3]
                        
                    elif L_virt >= L0 and skip == False:
                        for jj in arange(1,len(res_int)):
                            L_virt_1 = sqrt(res_int[jj,1]**2 + abs(xF-res_int[jj,0])**2)
                            L_virt_2 = sqrt(res_int[jj-1,1]**2 + abs(xF-res_int[jj-1,0])**2)
                            
                            if round(L_virt_2,round_prec) == round(L0,round_prec):
                                find_pos = True
                                res_int = res_int[0:jj,:]
                                res_app = True                 
                                t_vint = t_vint[0:jj]
                                if res_int[-1,3] <=0: end_sim = True
                                break
                            elif L_virt_2 < L0 and L_virt_1 > L0:
                                s[0] = res_int[jj-1,0]
                                s[1] = res_int[jj-1,1]
                                s[2] = res_int[jj-1,2]
                                s[3] = res_int[jj-1,3]
                                res_int = res_int[0:jj,:]
                                res_app = True
                                t_vint = t_vint[0:jj]
                                step_size = step_size / 10.
                                break
                    # append arrays
                    if res_app == False:
                        res = res_int
                        t_v = t_vint 
                        res_app = True
                    else:
                        res = append(res,res_int[1::],0)
                        t_v = append(t_v,t_vint[1::]+t_v[-1])
                
                # take of angle
                #print st_lo_idx
                betaTO_sim[st_lo_idx] = arctan(res[-1,1]/(res[-1,0]-xF))*180./pi 
                
                # append arrays 
                x_sim = append(x_sim,append(x,res[:,0]))
                y_sim = append(y_sim,append(y,res[:,1]))
                vx_sim = append(vx_sim,append(vx,res[:,2]))
                vy_sim = append(vy_sim,append(vy,res[:,3]))
                t_sim = append(t_sim,append(t_vec,t_v+t_gc)+t_sim[-1])
            
            else: #skip_stance == True because of ending at apex
                end_sim = True
        
        # cut array
        x_sim = x_sim[1::]
        y_sim = y_sim[1::]
        vx_sim = vx_sim[1::]
        vy_sim = vy_sim[1::]
        t_sim = t_sim[1::]
    
    
    #print 'vor return'
    return x_sim,y_sim,vx_sim,vy_sim,t_sim,st_lo_idx,betaTO_sim,xF,k2,L02
    asdf0 = sp1.plot(vj,
                     uv,
                     ls='',
                     marker='o',
                     ms=1,
                     mec='r',
                     label='zmag < 22.5\n%.1f < z < %.1f' % (zlo, zhi))
    asdf = sp1.plot([-0.5, 2.5],
                    pylab.array([-0.5, 2.5]) * m_diagonal + b_diagonal,
                    color='#666666',
                    lw=3)
    sp1.legend(loc=2, numpoints=4, fontsize=18)

    for p_off in [-0.5, 0.5]:
        y_off = p_off / pylab.sin(pylab.arctan(1. / m_diagonal))
        sp1.plot([-0.5, 2.5],
                 pylab.array([-0.5, 2.5]) * m_diagonal + b_diagonal + y_off,
                 color='#666666',
                 ls='--',
                 lw=3)
        sp2.axvline(p_off, color='#666666', ls='--', lw=3)

    ###  plotting histogram of offsets from diagonal
    inds = pylab.find((f.fout.z > zlo) & (f.fout.z < zhi)
                      & (f.zmagnitude < zmag_lim) & (f.cat.weight_B > 0.05)
                      & (f.cat.use == 1)
                      & (f.UV_color > m_perp * f.VJ_color + b_perp))

    uv = f.UV_color[inds]
    vj = f.VJ_color[inds]
Beispiel #18
0
 if RT:
     for line in lines:
         if isinstance(line, Multiplet):
             if hasattr(line, 'lines'):
                 for idx, line in enumerate(line.lines):
                     term_l = line.lower.remove_label_term(line.lower.term)
                     term_u = line.upper.remove_label_term(line.upper.term) 
                     e_l = line.lower.e/EV_TO_CM
                     e_u = line.upper.e/EV_TO_CM
                     x_l = terms.index(term_l)+1
                     x_u = terms.index(term_u)+1
                     rt_line, = pl.plot([x_l, x_u], [e_l, e_u], 'r-')  
                      # Display lambda value on the radiative line
                     if e_l < LBD:
                         slope = (e_u-e_l)/(x_u-x_l)
                         angle = pl.arctan(slope)*180./pl.pi
                         offset = 0.15*idx
                         x_c, y_c = (x_l+x_u)/2. + offset, (e_l+e_u)/2. + offset
                         trans_angle = pl.gca().transData.transform_angles(pl.array((angle,)), pl.array((x_c, y_c)).reshape((1, 2)))[0]
                         pl.text(x_c, y_c, format(line.compute_lbd(med='air'), '.1f'), fontsize=6, rotation=trans_angle, horizontalalignment='center', verticalalignment='center')                       
         elif isinstance(line, Line):
             term_l = line.lower.remove_label_term(line.lower.term)
             term_u = line.upper.remove_label_term(line.upper.term) 
             e_l = line.lower.e/EV_TO_CM
             e_u = line.upper.e/EV_TO_CM
             x_l = terms.index(term_l)+1
             x_u = terms.index(term_u)+1
             rt_line, = pl.plot([x_l, x_u], [e_l, e_u], 'r-')
             # Display lambda value on the radiative line
             if e_l < LBD:
                 slope = (e_u-e_l)/(x_u-x_l)
    def draw(self, drawer):

        drawer.getSketch(self.name, self.color)

        alpha_st = self.deg_alpha_st * np.pi / 180
        alpha_so = -self.deg_alpha_so * np.pi / 180
        r_si = self.mm_r_si
        d_so = self.mm_d_so
        d_sp = self.mm_d_sp
        d_st = self.mm_d_st
        d_sy = self.mm_d_sy
        w_st = self.mm_w_st
        r_st = self.mm_r_st
        r_sf = self.mm_r_sf
        r_sb = self.mm_r_sb
        Q = self.Q

        alpha_slot_span = 360 / Q * np.pi / 180

        P1 = [r_si, 0]
        P2 = [r_si * cos(alpha_st * 0.5), r_si * -sin(alpha_st * 0.5)]
        P3_temp = [d_so * cos(alpha_st * 0.5), d_so * -sin(alpha_st * 0.5)]
        P3_local_rotate = [
            cos(alpha_so) * P3_temp[0] + sin(alpha_so) * P3_temp[1],
            -sin(alpha_so) * P3_temp[0] + cos(alpha_so) * P3_temp[1]
        ]
        P3 = [P3_local_rotate[0] + P2[0], P3_local_rotate[1] + P2[1]]

        三角形的底 = r_si + d_sp
        三角形的高 = w_st * 0.5
        三角形的角度 = arctan(三角形的高 / 三角形的底)
        P4 = [三角形的底 * cos(三角形的角度), 三角形的底 * -sin(三角形的角度)]

        P5 = [P4[0] + d_st, P4[1]]

        # Option 1
        # 6 [94.01649113009418, -25.191642873516543] 97.33303383272235
        # Radius_InnerStatorYoke = r_si+d_sp+d_st
        # print('Radius_InnerStatorYoke #1:', Radius_InnerStatorYoke)
        # Option 2
        Radius_InnerStatorYoke = np.sqrt(P5[0]**2 + P5[1]**2)
        # print('Radius_InnerStatorYoke #2:', Radius_InnerStatorYoke)
        P6 = [
            Radius_InnerStatorYoke * cos(alpha_slot_span * 0.5),
            Radius_InnerStatorYoke * -sin(alpha_slot_span * 0.5)
        ]

        P7 = [(r_si + d_sp + d_st + d_sy) * cos(alpha_slot_span * 0.5),
              (r_si + d_sp + d_st + d_sy) * -sin(alpha_slot_span * 0.5)]
        P8 = [r_si + d_sp + d_st + d_sy, 0]

        list_segments = []
        list_segments += drawer.drawArc([0, 0], P2, P1)
        list_segments += drawer.drawLine(P2, P3)
        list_segments += drawer.drawLine(P3, P4)
        list_segments += drawer.drawLine(P4, P5)
        list_segments += drawer.drawArc([0, 0], P6, P5)
        # print(P4, P5)
        # print(P6, P5)
        list_segments += drawer.drawLine(P6, P7)

        # l, vA = drawer.drawArc([0,0], P6, P5, returnVertexName=True)
        # list_segments += l
        # l, vB = drawer.drawLine(P6, P7, returnVertexName=True)
        # list_segments += l
        # drawer.addConstraintCocentricity(vA[0], vB[0])
        # raise

        list_segments += drawer.drawArc([0, 0], P7, P8)
        list_segments += drawer.drawLine(P8, P1)

        # DEBUG
        # for ind, point in enumerate([P1, P2, P3, P4, P5, P6, P7, P8]):
        #     print(ind+1, point, np.sqrt(point[0]**2+point[1]**2))

        innerCoord = (0.5 * (P1[0] + P5[0]), 0.5 * (P1[1] + P5[1]))

        # return [list_segments]
        return {
            'innerCoord': innerCoord,
            'list_regions': [list_segments],
            'mirrorAxis': [(P8[0] + 5, P8[1]), (P8[0] + 15, P8[1])]
        }
    def plotCrossSection(self, withArrows=True, withNotes=True):
        '''
        @brief: plot the tire cross section, with or w/out figure labels
        Usage: myTire = TireCrossSection([15.0,5.0])
        myTire.plotCrossSection(withArrows=False)
        '''
        if (self._OA_nodes == 0 or self._AB_nodes == 0):
            print 'cant plot a crossSection when there are no Nodes!\n'
            return

        else:
            # OK to plot, set some vals. that will be used
            ys = self._ds
            OA_x_off = self._r_tire - self._r_OA
            AB_x_off = self._AB_x_off
            AB_y_off = self._AB_y_off
            OA_nodes = self._OA_nodes
            AB_nodes = self._AB_nodes
            phi_incr = self._phi_incr
            r_tire = self._r_tire
            AB_rad = self._r_AB
            th_incr = self._th_incr * (self._r_OA / r_tire)
            # now do the plotting
            prop = fm.FontProperties(size=18)
            fig = plt.figure()
            ax = plt.subplot(111, aspect='equal')
            fig.canvas.set_window_title('Tire Cross section, s_bar = ' +
                                        str(ys))
            # plot OA
            ax.plot(self._yOA[0, :], self._xOA[0, :], 'k-*', self._yOA[1, :],
                    self._xOA[1, :], 'k-*')
            # plot AB
            ax.plot(self._yAB[0, :], self._xAB[0, :], 'r-*', self._yAB[1, :],
                    self._xAB[1, :], 'r-*')

            # plot r_OA
            if (OA_x_off < 0):
                arrow_y0 = (
                    self._yOA[0, OA_nodes / 2] /
                    (self._xOA[0, OA_nodes / 2] - OA_x_off)) * abs(OA_x_off)
            else:
                arrow_y0 = OA_x_off
            # ax.plot( (0.0,self._yOA[1,0]),(0.0,self._xOA[0,0]),'b--o',linewidth=1.5)
            # ax.arrow(arrow_y0,0.0, self._yOA[0,OA_nodes/2]-arrow_y0,self._xOA[0,self._OA_nodes/2],
            #          head_width = 0.5, head_length = 0.5, fc='b',ec='b',length_includes_head=True)
            ax.plot((0.0, self._yOA[1, 0]), (OA_x_off, self._xOA[0, 0]),
                    'b--o',
                    linewidth=1.5)
            ax.arrow(0.0,
                     OA_x_off,
                     self._yOA[0, OA_nodes / 2],
                     self._xOA[0, self._OA_nodes / 2] - OA_x_off,
                     head_width=0.5,
                     head_length=0.5,
                     fc='b',
                     ec='b',
                     length_includes_head=True)

            #plot r_AB
            ax.plot((AB_y_off, self._yOA[0, OA_nodes - 1]),
                    (AB_x_off, self._xOA[0, OA_nodes - 1]),
                    'r--o',
                    linewidth=1.5)
            ax.arrow(AB_y_off,
                     AB_x_off,
                     self._yAB[0, AB_nodes / 2] - AB_y_off,
                     self._xAB[0, AB_nodes / 2] - AB_x_off,
                     head_width=0.5,
                     head_length=0.5,
                     fc='r',
                     ec='r',
                     length_includes_head=True)
            # plot the spin axis
            ax.plot(-self._w_tire / 2. + self._w_tire * py.arange(0, 30) / 29.,
                    py.zeros(30),
                    'k--',
                    linewidth=1.5)
            leg = ax.legend(
                ('sec. OA', 'sec. OA', 'AB', 'AB', r'$\vec r_\overline{OA}$',
                 r'$\vec r_\overline{AB}$', 'wheel axis'),
                loc=3,
                prop=prop)
            leg.draggable()

            # plot the angles, annotate them
            ax.plot(
                r_tire * py.sin(th_incr * py.arange(0, OA_nodes / 2 - 1)),
                r_tire * (py.cos(th_incr * py.arange(0, OA_nodes / 2 - 1))) -
                r_tire / 2.0)
            ax.annotate(r'$\theta$',
                        xy=(0.5, r_tire / 2.0),
                        xytext=(-25, 30),
                        size=22,
                        textcoords='offset points',
                        arrowprops=dict(arrowstyle="-|>", color='black'))
            AB_dx = self._xOA[0, OA_nodes - 1] - AB_x_off
            AB_dy = self._yOA[0, OA_nodes - 1] - AB_y_off
            phi0_idx = (int)(
                (py.pi / 2.0 - py.arctan(AB_dx / AB_dy)) / phi_incr) + 1
            py.plot(AB_y_off + (AB_rad / 2.0) *
                    py.sin(phi_incr * py.arange(phi0_idx, AB_nodes)),
                    AB_x_off + (AB_rad / 2.0) *
                    (py.cos(phi_incr * py.arange(phi0_idx, AB_nodes))),
                    'r--',
                    linewidth=2.)

            ax.annotate(r'$\phi$',
                        xy=(AB_y_off + AB_rad / 3.0, AB_x_off + AB_rad / 3.0),
                        xytext=(-5, -55),
                        size=22,
                        textcoords='offset points',
                        arrowprops=dict(arrowstyle="-|>", color='black'))

            ax.annotate('O= ' + str([r_tire, 0.0]),
                        xy=(0.0, r_tire),
                        xytext=(25, 45),
                        size=16,
                        textcoords='offset points',
                        arrowprops=dict(arrowstyle="-|>", color='black'))
            ax.annotate("A= [%.2f" % self._xOA[0, OA_nodes - 1] +
                        ", %.2f" % self._yOA[0, OA_nodes - 1] + ']',
                        xy=(self._yOA[0,
                                      OA_nodes - 1], self._xOA[0,
                                                               OA_nodes - 1]),
                        xytext=(60, 25),
                        size=16,
                        textcoords='offset points',
                        arrowprops=dict(arrowstyle="-|>", color='black'))
            ax.annotate("B= [%.2f" % self._xAB[0, AB_nodes - 1] +
                        ", %.2f" % self._yAB[0, AB_nodes - 1] + ']',
                        xy=(self._yAB[0,
                                      AB_nodes - 1], self._xAB[0,
                                                               AB_nodes - 1]),
                        xytext=(40, 35),
                        size=16,
                        textcoords='offset points',
                        arrowprops=dict(arrowstyle="-|>", color='black'))
            py.xlabel('y-dir [inches]', size=14)
            py.ylabel('x-dir [inches]', size=14)
            py.grid('on')
def Satellite_Simulator(
    Satellite_skyfield,
    SimulationTime,
    Timeline_settings,
    pointing_altitude,
    LogFlag=False,
    Logger=None,
):
    """Simulates a single point in time for a Satellite using Skyfield and also the pointing of the satellite.
    
    Only estimates the actual pointing definition used by OHB as it is uncertain if the algorithm to calculate the LP here is the same as the one OHB uses. 
    The LP is calculated with an algorithm derived by Nick Lloyd at University of Saskatchewan, 
    Canada ([email protected]), and is part of
    the operational code for both OSIRIS and SMR on-board- the Odin satellite. An offset is added to the pointing altitude to better mimic OHBs actual LP.
    
    Arguments:
        Satellite_skyfield (:obj:`skyfield.sgp4lib.EarthSatellite`): A Skyfield object representing an EarthSatellite defined by a TLE.
        SimulationTime (:obj:`ephem.Date`): The time of the simulation.
        Timeline_settings (dict): A dictionary containing relevant settings to the simulation.
        pointing_altitude (float): Contains the pointing altitude of the simulation [km].
        LogFlag (bool): If data from the simulation shall be logged.
        Logger (:obj:`logging.Logger`): Logger used to log the result from the simulation if LogFlag == True.
        
    Returns:
        (dict): Dictionary containing simulated data.
        
    """

    U = 398600.441800000  # Earth gravitational parameter
    R_mean = 6371.000
    celestial_eq = [0, 0, 1]

    "Offset the pointing altitude slightly which improves the estimation of OHBs actual pointing"
    pointing_altitude = pointing_altitude + 0.3

    yaw_correction = Timeline_settings["yaw_correction"]

    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)

    Satellite_geo = Satellite_skyfield.at(current_time_skyfield)
    v_Satellite = Satellite_geo.velocity.km_per_s
    r_Satellite = Satellite_geo.position.km
    Satellite_distance = Satellite_geo.distance().km
    Satellite_subpoint = Satellite_geo.subpoint()
    lat_Satellite = Satellite_subpoint.latitude.degrees
    long_Satellite = Satellite_subpoint.longitude.degrees
    alt_Satellite = Satellite_subpoint.elevation.km

    r_Satellite_unit_vector = r_Satellite / norm(r_Satellite)

    "Semi-Major axis of Satellite, assuming circular orbit"
    Satellite_p = norm(r_Satellite)

    "Orbital Period of Satellite"
    orbital_period = 2 * pi * sqrt(Satellite_p**3 / U)

    "Initial Estimated pitch or elevation angle for Satellite pointing (angle between negativ velocity vector and optical axis in the orbital plane)"
    OrbAngleBetweenSatelliteAndLP = (arccos(
        (R_mean + pointing_altitude) / (Satellite_distance)) / pi * 180)

    time_between_LP_and_Satellite = orbital_period * OrbAngleBetweenSatelliteAndLP / 360

    "Estimation of lat of LP using the position of Satellite at a previous time"
    date_of_Satellitelat_is_equal_2_current_LPlat = ephem.Date(
        SimulationTime -
        ephem.second * time_between_LP_and_Satellite).datetime()
    lat_LP = lat_calculator(Satellite_skyfield,
                            date_of_Satellitelat_is_equal_2_current_LPlat)
    R_earth_LP = lat_2_R(lat_LP)

    "More accurate estimated pitch or elevation angle for Satellite pointing"
    OrbAngleBetweenSatelliteAndLP = (arccos(
        (R_earth_LP + pointing_altitude) / (Satellite_distance)) / pi * 180)

    Pitch = 90 + OrbAngleBetweenSatelliteAndLP

    "############# Calculations of orbital and pointing vectors ############"
    "Vector normal to the orbital plane of Satellite"
    normal_orbit = cross(r_Satellite, v_Satellite)
    normal_orbit = normal_orbit / norm(normal_orbit)

    "Calculate intersection between the orbital plane and the equator"
    ascending_node = cross(celestial_eq, normal_orbit)

    "Argument of latitude"
    arg_of_lat = (arccos(
        dot(ascending_node, r_Satellite) / norm(r_Satellite) /
        norm(ascending_node)) / pi * 180)

    "To determine if Satellite is moving towards the ascending node"
    if dot(cross(ascending_node, r_Satellite), normal_orbit) <= 0:
        arg_of_lat = 360 - arg_of_lat

    if yaw_correction == True:
        yaw_offset_angle = Timeline_settings["yaw_amplitude"] * cos(
            arg_of_lat / 180 * pi - (Pitch - 90) / 180 * pi -
            Timeline_settings["yaw_phase"] / 180 * pi)
    elif yaw_correction == False:
        yaw_offset_angle = 0

    "Rotate 'vector to Satellite', to represent pointing direction"
    rot_mat = rot_arbit(Pitch / 180 * pi, -normal_orbit)
    optical_axis = rot_mat @ (r_Satellite)

    "Apply yaw to optical_axis, meaning to rotate around the vector to Satellite"
    rot_mat = rot_arbit(yaw_offset_angle / 180 * pi, -r_Satellite_unit_vector)
    optical_axis = rot_mat @ optical_axis
    optical_axis_unit_vector = optical_axis / norm(optical_axis)

    "Rotate 'vector to Satellite', to represent vector normal to satellite H-offset "
    rot_mat = rot_arbit((Pitch - 90) / 180 * pi, -normal_orbit)
    r_H_offset_normal = rot_mat @ r_Satellite
    r_H_offset_normal = r_H_offset_normal / norm(r_H_offset_normal)

    "If pointing direction has a Yaw defined, Rotate yaw of normal to pointing direction H-offset plane, meaning to rotate around the vector to Satellite"
    rot_mat = rot_arbit(yaw_offset_angle / 180 * pi, -r_Satellite_unit_vector)
    r_H_offset_normal = rot_mat @ r_H_offset_normal
    r_H_offset_normal = r_H_offset_normal / norm(r_H_offset_normal)

    "Rotate negative orbital plane normal to make it into a normal to the V-offset plane"
    r_V_offset_normal = rot_mat @ -normal_orbit
    r_V_offset_normal = r_V_offset_normal / norm(r_V_offset_normal)

    "Calculate Dec and RA of optical axis"
    Dec_optical_axis = (arctan(
        optical_axis[2] / sqrt(optical_axis[0]**2 + optical_axis[1]**2)) / pi *
                        180)
    RA_optical_axis = (arccos(
        dot([1, 0, 0], [optical_axis[0], optical_axis[1], 0]) /
        norm([optical_axis[0], optical_axis[1], 0])) / pi * 180)
    if optical_axis[1] < 0:
        RA_optical_axis = 360 - RA_optical_axis

    if LogFlag == True and Logger != None:
        Logger.debug("")

        Logger.debug("SimulationTime time: " + str(SimulationTime))
        Logger.debug("Semimajor axis in km: " + str(Satellite_p))
        Logger.debug("Orbital Period in s: " + str(orbital_period))
        Logger.debug("Vector to Satellite [km]: " + str(r_Satellite))
        Logger.debug("Latitude in degrees: " + str(lat_Satellite))
        Logger.debug("Longitude in degrees: " + str(long_Satellite))
        Logger.debug("Altitude in km: " + str(alt_Satellite))
        Logger.debug("Satellite_distance [km]: " + str(Satellite_distance))

        Logger.debug("R_earth_LP [km]: " + str(R_earth_LP))

        Logger.debug("Pitch [degrees]: " + str(Pitch))
        Logger.debug("Yaw [degrees]: " + str(yaw_offset_angle))
        Logger.debug("ArgOfLat [degrees]: " + str(arg_of_lat))
        Logger.debug("Latitude of LP: " + str(lat_LP))
        Logger.debug("Optical Axis: " + str(optical_axis_unit_vector))
        Logger.debug("Orthogonal direction to H-offset plane: " +
                     str(r_H_offset_normal))
        Logger.debug("Orthogonal direction to V-offset plane: " +
                     str(r_V_offset_normal))
        Logger.debug("Orthogonal direction to the orbital plane: " +
                     str(normal_orbit))

    Satellite_dict = {
        "Position [km]": r_Satellite,
        "Velocity [km/s]": v_Satellite,
        "OrbitNormal": normal_orbit,
        "OrbitalPeriod [s]": orbital_period,
        "Latitude [degrees]": lat_Satellite,
        "Longitude [degrees]": long_Satellite,
        "Altitude [km]": alt_Satellite,
        "AscendingNode": ascending_node,
        "ArgOfLat [degrees]": arg_of_lat,
        "Yaw [degrees]": yaw_offset_angle,
        "Pitch [degrees]": Pitch,
        "OpticalAxis": optical_axis_unit_vector,
        "Dec_OpticalAxis [degrees]": Dec_optical_axis,
        "RA_OpticalAxis [degrees]": RA_optical_axis,
        "Normal2H_offset": r_H_offset_normal,
        "Normal2V_offset": r_V_offset_normal,
        "EstimatedLatitude_LP [degrees]": lat_LP,
    }

    # return r_Satellite, lat_Satellite, long_Satellite, alt_Satellite, optical_axis_unit_vector, Dec_optical_axis, RA_optical_axis, r_H_offset_normal, r_V_offset_normal, orbital_period
    return Satellite_dict
Beispiel #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
Beispiel #23
0
def fqu_arctan(lmassax, m0, beta):
    return pylab.arctan(beta * (lmassax - m0)) * (1. / pylab.pi) + 0.5
Beispiel #24
0
    def draw(self, drawer, bool_re_evaluate=False):

        if False == bool_re_evaluate:
            drawer.getSketch(self.name, self.color)

        alpha_st = self.stator_core.deg_alpha_st * np.pi/180
        alpha_so = self.stator_core.deg_alpha_so * np.pi/180
        r_si     = self.stator_core.mm_r_si
        d_so     = self.stator_core.mm_d_so
        d_sp     = self.stator_core.mm_d_sp
        d_st     = self.stator_core.mm_d_st
        d_sy     = self.stator_core.mm_d_sy
        w_st     = self.stator_core.mm_w_st
        r_st     = self.stator_core.mm_r_st
        r_sf     = self.stator_core.mm_r_sf
        r_sb     = self.stator_core.mm_r_sb
        Q        = self.stator_core.Q

        alpha_slot_span = 360/Q * np.pi/180

        P1 = [r_si, 0]

            # 乘以0.99或0.95避免上层导体和下层导体重合导致导入Designer时产生多余的Parts。
        POpen = [(r_si+d_sp)*cos(alpha_slot_span*0.5*1.00), (r_si+d_sp)*-sin(alpha_slot_span*0.5*1.00)]

        # P2 = [r_si*cos(alpha_st*0.5), r_si*-sin(alpha_st*0.5)]

        # P3_temp = [ d_so*cos(alpha_st*0.5), 
        #             d_so*-sin(alpha_st*0.5)]
        # P3_local_rotate = [  cos(alpha_so)*P3_temp[0] + sin(alpha_so)*P3_temp[1],
        #                      -sin(alpha_so)*P3_temp[0] + cos(alpha_so)*P3_temp[1] ]
        # P3 = [  P3_local_rotate[0] + P2[0],
        #         P3_local_rotate[1] + P2[1] ]

        三角形的底 = r_si + d_sp
        三角形的高 = w_st*0.5
        三角形的角度 = arctan(三角形的高 / 三角形的底)
        P4 = [  三角形的底*cos(三角形的角度), 
                三角形的底*-sin(三角形的角度) ]

        P5 = [ P4[0] + d_st, 
               P4[1]]

        PMiddle45 = [0.5*(P4[0] + P5[0]), P4[1]]
        TheRadius = (P5[0] - P4[0])*0.45

            # 为了使得槽和导体之间不要接触,试着添加5%的clearance?
        P6 = [ (r_si+d_sp+d_st)*cos(alpha_slot_span*0.5) *1.00,
               (r_si+d_sp+d_st)*-sin(alpha_slot_span*0.5) *1.00 ]

        self.mm2_slot_area = 2 * get_area_polygon(P4, P5, P6, POpen)
        print('Slot area is %g mm^2'%(self.mm2_slot_area))
        if bool_re_evaluate:
            return self.mm2_slot_area

        PMiddle6Open = [ 0.5*(P6[0]+POpen[0]), 0.5*(P6[1]+POpen[1])]
        self.PCoil = PCoil = [ 0.5*(PMiddle45[0]+PMiddle6Open[0]), 0.5*(PMiddle45[1]+PMiddle6Open[1])]

        # P7 = [ (r_si+d_sp+d_st+d_sy)*cos(alpha_slot_span*0.5),
        #        (r_si+d_sp+d_st+d_sy)*-sin(alpha_slot_span*0.5) ]
        # P8 = [  r_si+d_sp+d_st+d_sy, 0]

        # Compute the vector starting from PCoil to one of the corner of the polygon.
        def shrink(PC, P):
            vector = [ P[0] - PC[0], P[1] - PC[1]]
            return [ PC[0]+0.95*vector[0], PC[1]+0.95*vector[1] ]
        P6_Shrink = shrink(PCoil, P6)
        P5_Shrink = shrink(PCoil, P5)
        P4_Shrink = shrink(PCoil, P4)
        POpen_Shrink = shrink(PCoil, POpen)

        list_regions = []

        list_segments = []
        # list_segments += drawer.drawCircle(PCoil, TheRadius)
        list_segments += drawer.drawArc([0,0], P6_Shrink, P5_Shrink)
        list_segments += drawer.drawLine(P5_Shrink, P4_Shrink)
        list_segments += drawer.drawLine(P4_Shrink, POpen_Shrink)
        list_segments += drawer.drawLine(POpen_Shrink, P6_Shrink)
        list_regions.append(list_segments)

        PCoil[1] *= -1
        P6_Shrink[1] *= -1
        P5_Shrink[1] *= -1
        P4_Shrink[1] *= -1
        POpen_Shrink[1] *= -1
        list_segments = []
        # list_segments += drawer.drawCircle(PCoil, TheRadius)
        list_segments += drawer.drawArc([0,0], P5_Shrink, P6_Shrink)
        list_segments += drawer.drawLine(P5_Shrink, P4_Shrink)
        list_segments += drawer.drawLine(P4_Shrink, POpen_Shrink)
        list_segments += drawer.drawLine(POpen_Shrink, P6_Shrink)
        list_regions.append(list_segments)
        list_segments = []

        return list_regions
    def plotCrossSection(self,withArrows=True,withNotes=True):
        '''
        @brief: plot the tire cross section, with or w/out figure labels
        Usage: myTire = TireCrossSection([15.0,5.0])
        myTire.plotCrossSection(withArrows=False)
        '''
        if( self._OA_nodes == 0 or self._AB_nodes == 0):
            print 'cant plot a crossSection when there are no Nodes!\n'
            return
            
        else:
            # OK to plot, set some vals. that will be used
            ys = self._ds
            OA_x_off = self._r_tire - self._r_OA
            AB_x_off = self._AB_x_off 
            AB_y_off = self._AB_y_off
            OA_nodes = self._OA_nodes
            AB_nodes = self._AB_nodes
            phi_incr = self._phi_incr
            r_tire = self._r_tire
            AB_rad = self._r_AB
            th_incr = self._th_incr * (self._r_OA / r_tire)
            # now do the plotting
            prop = fm.FontProperties(size=18)
            fig = plt.figure()
            ax = plt.subplot(111,aspect='equal')
            fig.canvas.set_window_title('Tire Cross section, s_bar = ' + str(ys))
            # plot OA
            ax.plot(self._yOA[0,:],self._xOA[0,:],'k-*',self._yOA[1,:],self._xOA[1,:],'k-*')
            # plot AB
            ax.plot( self._yAB[0,:],self._xAB[0,:], 'r-*',self._yAB[1,:],self._xAB[1,:],'r-*')
            
            
            # plot r_OA
            if(OA_x_off < 0):
                arrow_y0 = (self._yOA[0,OA_nodes/2]/(self._xOA[0,OA_nodes/2]-OA_x_off))*abs(OA_x_off)
            else:
                arrow_y0 = OA_x_off
            # ax.plot( (0.0,self._yOA[1,0]),(0.0,self._xOA[0,0]),'b--o',linewidth=1.5)
            # ax.arrow(arrow_y0,0.0, self._yOA[0,OA_nodes/2]-arrow_y0,self._xOA[0,self._OA_nodes/2],
            #          head_width = 0.5, head_length = 0.5, fc='b',ec='b',length_includes_head=True) 
            ax.plot( (0.0,self._yOA[1,0]),(OA_x_off,self._xOA[0,0]),'b--o',linewidth=1.5)
            ax.arrow(0.0, OA_x_off, self._yOA[0,OA_nodes/2],self._xOA[0,self._OA_nodes/2]-OA_x_off,
                      head_width = 0.5, head_length = 0.5, fc='b',ec='b',length_includes_head=True)

            #plot r_AB
            ax.plot( (AB_y_off,self._yOA[0,OA_nodes-1]),(AB_x_off,self._xOA[0,OA_nodes-1]),'r--o',linewidth=1.5)
            ax.arrow( AB_y_off,AB_x_off, self._yAB[0,AB_nodes/2]-AB_y_off, self._xAB[0,AB_nodes/2]-AB_x_off,
                     head_width = 0.5, head_length = 0.5, fc='r',ec='r',length_includes_head=True)
            # plot the spin axis
            ax.plot( -self._w_tire/2. + self._w_tire*py.arange(0,30)/29., py.zeros(30),'k--',linewidth=1.5)
            leg = ax.legend(('sec. OA','sec. OA','AB','AB',
                             r'$\vec r_\overline{OA}$',r'$\vec r_\overline{AB}$',
                            'wheel axis'),
                            loc=3,prop=prop)
            leg.draggable()
            
            # plot the angles, annotate them
            ax.plot( r_tire*py.sin(th_incr*py.arange(0,OA_nodes/2-1)), r_tire*(py.cos(th_incr*py.arange(0,OA_nodes/2-1)))-r_tire/2.0 )
            ax.annotate(r'$\theta$', xy=(0.5, r_tire/2.0), xytext=(-25,30),size=22,textcoords='offset points', arrowprops=dict(arrowstyle="-|>",color='black'))
            AB_dx = self._xOA[0,OA_nodes-1] - AB_x_off
            AB_dy = self._yOA[0,OA_nodes-1] - AB_y_off
            phi0_idx = (int)((py.pi/2.0 - py.arctan(AB_dx/AB_dy) ) / phi_incr)+1;
            py.plot( AB_y_off + (AB_rad/2.0)*py.sin(phi_incr*py.arange(phi0_idx,AB_nodes)), AB_x_off + (AB_rad/2.0)*(py.cos(phi_incr*py.arange(phi0_idx,AB_nodes))),'r--',linewidth=2. )

            ax.annotate(r'$\phi$', xy=(AB_y_off+AB_rad/3.0, AB_x_off + AB_rad/3.0), xytext=(-5,-55),size=22,textcoords='offset points', arrowprops=dict(arrowstyle="-|>",color='black'))
            
            ax.annotate('O= '+str([r_tire,0.0]), xy=(0.0,r_tire), xytext=(25,45),size=16,textcoords='offset points', arrowprops=dict(arrowstyle="-|>",color='black'))
            ax.annotate("A= [%.2f" % self._xOA[0,OA_nodes-1] + ", %.2f" % self._yOA[0,OA_nodes-1] +']', xy=(self._yOA[0,OA_nodes-1],self._xOA[0,OA_nodes-1]),
                        xytext=(60,25),size=16,textcoords='offset points', arrowprops=dict(arrowstyle="-|>",color='black'))
            ax.annotate("B= [%.2f" % self._xAB[0,AB_nodes-1]+ ", %.2f" % self._yAB[0,AB_nodes-1] +']', xy=(self._yAB[0,AB_nodes-1],self._xAB[0,AB_nodes-1]),
                        xytext=(40,35),size=16,textcoords='offset points', arrowprops=dict(arrowstyle="-|>",color='black'))
            py.xlabel('y-dir [inches]',size=14)
            py.ylabel('x-dir [inches]',size=14)
            py.grid('on')
Beispiel #26
0
def f(x):
    return pyl.arctan(x)