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)
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
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
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
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))
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]
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
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)
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
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()
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])] }
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 }
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]
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]
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
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
def fqu_arctan(lmassax, m0, beta): return pylab.arctan(beta * (lmassax - m0)) * (1. / pylab.pi) + 0.5
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')
def f(x): return pyl.arctan(x)