def Lnl(self, v, alpha): '''Nonlinear lift including post stall''' Lpeak = self.W * (self.vb / self.vStall) ** 2 Lsteady = Lpeak * .67 A = Lpeak - Lsteady w = 0.36 * self.alphaStall p = 2 alphaTrans = rad(6.0 - 1.25) # after stall w2 = 1.0 * self.alphaStall p2 = 2.0 # final drop coefficient c = 0.6 alphaTrans3 = rad(25) # negative lift stall cn2 = 100.0 B = 0.5 shift = rad(2) if alpha < self.alphaNegStall + shift: x = abs(alpha - (self.alphaNegStall + shift)) # *Lsteady + L = self.W * (-B * (1 - exp(-x / w)) + exp(-x / w) * (1 + self.ralpha * alpha + cn2 * x ** 2)) * ( v / self.vb) ** 2 # negative stall # sys.exit('Stop. Negative lift stall. Lift not calculated at angle {} deg'.format(deg(alpha))) elif self.alphaNegStall < alpha < alphaTrans: L = self.W * (1 + self.ralpha * alpha) * (v / self.vb) ** 2 elif alpha < self.alphaStall: L = (Lsteady + A * exp(-(abs((alpha - self.alphaStall)) / w) ** p2)) * (v / self.vb) ** 2 elif alpha < alphaTrans3: L = (Lsteady + A * exp(-(abs((alpha - self.alphaStall)) / w2) ** p2)) * (v / self.vb) ** 2 else: # a decline toward 90 degrees L = (Lsteady * (1 - c * (alpha - alphaTrans3) ** 1.5) + A * exp( -(abs((alpha - self.alphaStall)) / w2) ** p2)) * (v / self.vb) ** 2 return L
def main(args): trAng5 = rad(5.0) trAng6 = rad(6.0) c_f_water = 1481.0 c_air = 343 c1 = c_f_water c2 = c_air ang5 = np.arcsin((c1 / c2) * trAng5) ang6 = np.arcsin((c1 / c2) * trAng6) print deg(ang5) print deg(ang6) d = 1.0/(tan(ang6)-tan(ang5)) print d R = d*tan(ang5) print R return 0
def __init__(self): rospy.init_node('ptu_teleop') pan_lim = rospy.get_param('~pan_lim', 2.775) tilt_hi_lim = rospy.get_param('~tilt_hi_lim', 0.82) tilt_lo_lim = -rospy.get_param('~tilt_lo_lim', -0.52) tilt_scale = rospy.get_param('~tilt_scale', 1) pan_scale = rospy.get_param('~pan_scale', 1) self.pan_speed = rospy.get_param('~pan_speed', 1) self.tilt_speed = rospy.get_param('~tilt_speed', 1) self.ptu_button = rospy.get_param('~ptu_button', 2) self.home_button = rospy.get_param('~home_button', 7) # Desired PTU behaviour - set by joystick callback self.des_pan_vel = 0 self.des_tilt_vel = 0 self.ptu_changed = False self.ptu_reset = False pan_setpt = 0 tilt_setpt = 0 cmd_ptu_pub = rospy.Publisher('ptu/cmd', JointState) announce_pub = rospy.Publisher('/clearpath/announce/teleops', String, latch=True) announce_pub.publish(rospy.get_namespace()); rospy.Subscriber("joy", Joy, self.callback) freq = rospy.get_param('~hz',50) rate = rospy.Rate(freq) while not rospy.is_shutdown(): rate.sleep() if self.ptu_reset or self.des_pan_vel != 0 or self.des_tilt_vel != 0: ptu = JointState() ptu.name.append("Pan") ptu.name.append("Tilt") # If we want to home, home if self.ptu_reset: pan_setpt = 0 tilt_setpt = 0 else: pan_setpt += pan_scale*self.des_pan_vel*freq/1000.0 tilt_setpt += tilt_scale*self.des_tilt_vel*freq/1000.0 pan_setpt = min(pan_lim,pan_setpt) pan_setpt = max(-pan_lim,pan_setpt) tilt_setpt = min(tilt_hi_lim,tilt_setpt) tilt_setpt = max(-tilt_lo_lim,tilt_setpt) ptu.position.append(pan_setpt) ptu.position.append(tilt_setpt) ptu.velocity.append(rad(self.pan_speed)) ptu.velocity.append(rad(self.tilt_speed)) cmd_ptu_pub.publish(ptu)
def xcp(self, alpha): '''wing center of pressure measured vs leading edge''' alphaMin = -2 # deg alphaMax = 9.5 # deg if alpha < rad(alphaMin): alpha = rad(alphaMin) elif alpha > rad(alphaMax): alpha = rad(alphaMax) return self.xCP[0] + self.xCP[1] * deg(alpha) + self.xCP[2] * deg(alpha) ** 2 + self.xCP[3] * deg(alpha) ** 3
def calculateArms(self): ''' Method for calculating the arms required for getting the momments of each slice with respect to a rotation point. This function does not return any output, just modifies the structure of each slice by setting new attributes. ''' import numpy as np from numpy import radians as rad from shapely.geometry import LineString for n, slice_ in enumerate(self.slices.slices): setattr(slice_, 'n', n) # Vertical linestring that splits the slice through the cetroid xMean = (slice_.xMin + slice_.xMax) / 2 vertLine = LineString([(xMean, -self.slices.rotationPt[1]), (xMean, self.slices.rotationPt[1])]) # Arms for external loads loadPt1 = np.array(slice_.terrainLS.intersection(vertLine)) theta = np.arctan((self.slices.rotationPt[1] - loadPt1[1]) / (self.slices.rotationPt[0] - loadPt1[0])) % np.pi alpha = abs(rad(slice_.w) - theta) loadPt2RotPt = np.linalg.norm(self.slices.rotationPt - loadPt1) proy = loadPt2RotPt * abs(np.cos(alpha)) d = (loadPt2RotPt**2 - proy**2)**0.5 if rad(slice_.w) < theta: d *= -1 setattr(slice_, 'd', d) # Arms for normal loads at the base loadPt2 = slice_.slipSurfLS.intersection(vertLine) if loadPt2.type is not 'Point': loadPt2 = [xMean, loadPt1[1] - slice_.midHeight] loadPt2 = np.array(loadPt2) theta = np.arctan((self.slices.rotationPt[1] - loadPt2[1]) / (self.slices.rotationPt[0] - loadPt2[0])) % np.pi alpha = abs(0.5 * np.pi - rad(slice_.alpha) - theta) loadPt2RotPt = np.linalg.norm(self.slices.rotationPt - loadPt2) proy = loadPt2RotPt * abs(np.cos(alpha)) f = (loadPt2RotPt**2 - proy**2)**0.5 if 0.5 * np.pi - rad(slice_.alpha) < theta: f *= -1 setattr(slice_, 'f', f) setattr(slice_, 'R', proy) # Arm for the mobilized shear force # Arms for horizontal seismic force e = self.slices.rotationPt[1] - (loadPt2[1] + 0.5 * slice_.midHeight) setattr(slice_, 'e', e) # Arms for the weight of the slice x = self.slices.rotationPt[0] - xMean setattr(slice_, 'x', x) return
def alphaControl(self, t, time, setpoint, ti, tFiltPilot): if t > 7.1: dummy = True if gl.state == 'onGnd' and gl.theta >= gl.theta0 - rad( 1): # no elevator authority pp = 0 pd = 0 pint = 0 elif gl.state == 'onGnd' and gl.theta < gl.theta0 - rad(1): pp = -0 pd = -0 pint = -0 else: if self.tStartClimb is None: self.tStartClimb = t # one-time switch to climb if gl.state == 'preClimb': pp = pr['alphaPreClimbpp'] pd = pr['alphaPreClimbpd'] pint = pr['alphaPreClimbpint'] elif gl.state == 'initClimb': pp = pr['alphaInitClimbpp'] pd = pr['alphaInitClimbpd'] pint = pr['alphaInitClimbpint'] elif gl.state == 'inRot': pp = pr['alphaInRotpp'] pd = pr['alphaInRotpd'] pint = pr['alphaInRotpint'] elif gl.state in ['postRot', 'prepRelease' ]: #keep flying during prepRelease pp = pr['alphaPostRotpp'] pd = pr['alphaPostRotpd'] pint = pr['alphaPostRotpint'] else: sys.exit('Stop. Glider state is not recognized') k = array([pp, pd, pint]) # kSmooth = k # if self.tStartClimb is not None: # self.cCurr = k # kSmooth = self.cCurr - (self.cCurr - self.cOld) * exp(-(t - self.tStartClimb) / self.pilotRespT) # else: # kSmooth = k # self.cOld = k if t > 5: dummy = True if all((k == 0)): [control, err, derr, interr] = [0, 0, 0, 0] else: [control, err, derr, interr] = pid(gl.data['alpha'], setpoint, rad(10), gl.elevLimits[1], time, k, ti, self.integTime, tFiltPilot) #(valueArr, valueSet, valueScale, controlScale, time, k, ti, tInteg, tfilt): self.data[ti.i]['err'] = err self.data[ti.i]['derr'] = derr self.data[ti.i]['interr'] = interr return control
def handle_ATTITUDE(self, angx, angy, heading): self.roll_pitch_yaw = rad(angx / 10), -rad(angy / 10), rad(heading) self.gotimu = True # As soon as we handle the callback from one request, send another # request, if receiver dialog is running if self.imu.running: self._send_attitude_request()
class ldm_kbh: Name = 'ldm_kbh' f1 = 88.4596 f2 = 1.27 GrazingAngleDeg = 2 GrazingAngle = rad(GrazingAngleDeg) z=f1
class ldm_kbv: Name = 'ldm_kbv' f1 = 87.9102 f2 = 1.82 GrazingAngleDeg = 2 GrazingAngle = rad(GrazingAngleDeg) z=f1
class dpi_kbv: Name = 'dpi_kbh' f1 = 91.1066 f2 = 1.75 GrazingAngleDeg = 2 GrazingAngle = rad(GrazingAngleDeg) z=f1
def draw_arc_arrow(ax, angle_, theta2_, center=(0., 0.), text="", text_offset=(0., 0.), radius=1., color='white', is_rad=True, flip=False): if(is_rad): angle_ = deg(angle_) theta2_ = deg(theta2_) #========Line if(flip): head_angle = 180+angle_ direction = 1. arc = Arc([center[0],center[1]],radius*2.,radius*2.,angle=angle_, theta1=0., theta2=theta2_-angle_, capstyle='round', linestyle='-', lw=1, color=color) else: head_angle = angle_ direction = -1. arc = Arc([center[0],center[1]],radius*2.,radius*2.,angle=theta2_, theta1=0., theta2=angle_-theta2_, capstyle='round', linestyle='-', lw=1, color=color) ax.add_patch(arc) #========Create the arrow head arrow_scale = radius/30. delta_angle = arrow_scale/(radius) endX=center[0]+(radius)*(np.cos(rad(angle_) + direction*delta_angle) ) #Do trig to determine end position endY=center[1]+(radius)*(np.sin(rad(angle_) + direction*delta_angle) ) ax.add_patch( #Create triangle as arrow head RegularPolygon( (endX, endY), # (x,y) 3, # number of vertices arrow_scale, # radius rad(head_angle), # orientation color=color ) ) #========text middle_angle = theta2_ - (theta2_ - angle_)/2. endX=center[0]+(radius*1.05)*(np.cos(rad(middle_angle)) ) endY=center[1]+(radius*1.05)*(np.sin(rad(middle_angle)) ) ax.text(endX+text_offset[0], endY+text_offset[1], text, size=20) return
def out_of_range_condition(t): b = (t - joint_positions['shoulder']).length c = (31/b)*(t - joint_positions['shoulder']) + joint_positions['shoulder'] # new_elbow joint_positions['elbow'] = c theta_shoulder = arcsin(joint_positions['shoulder'][1]/13.7) # theta_shoulder = 0 # new_elbow judgement theta3, theta_arm_oc = get_oc_angle() theta_arm_ud = get_ud_angle(theta3) if((deg(theta_arm_ud) > 32) or (deg(theta_arm_ud) < 0) or (deg(theta_arm_oc) > 30) or (deg(theta_arm_oc) < 0)): if(deg(theta_arm_ud) > 32): theta_arm_ud = rad(32) elif(deg(theta_arm_ud < 0)): theta_arm_ud = 0 if(deg(theta_arm_oc) > 30): theta_arm_oc = rad(30) elif(deg(theta_arm_oc) < 0): theta_arm_oc = 0 arr = get_elbow_position([theta_shoulder, theta_arm_ud, theta_arm_oc]) joint_positions['elbow']= vector(arr) c = joint_positions['elbow'] e = (t - c).length f = (26.1/e)*(t - c) + c # new_wrist joint_positions['wrist'] = f # new_wrist judgement theta_elbow = get_elbow_angle() theta_uturn = get_uturn_angle(theta_shoulder, theta_arm_ud, theta_arm_oc, theta_elbow) if ((deg(theta_uturn) > 90) or (deg(theta_uturn < 0))): if(deg(theta_uturn) > 90): theta_uturn = rad(90) else: theta_uturn = 0 arr = get_wrist_position([theta_shoulder, theta_arm_ud, theta_arm_oc, theta_uturn, theta_elbow]) f = vector(arr) joint_positions['wrist'] = f return(deg([theta_shoulder, theta_arm_ud, theta_arm_oc, theta_uturn, theta_elbow]))
def R_AP(self): """ Rotation matrix to describe rotation with AP as axis. """ tilt_AP = rad(self.tilt_AP) return np.array([ [cos(tilt_AP), -sin(tilt_AP), 0], [sin(tilt_AP), cos(tilt_AP), 0], [0, 0, 1], ])
def R_ML(self): """ Rotation matrix to describe rotation with ML as axis. """ tilt_ML = rad(self.tilt_ML) return np.array([ [1, 0, 0], [0, cos(tilt_ML), -sin(tilt_ML)], [0, sin(tilt_ML), cos(tilt_ML)], ])
def __init__(self, pr, tEnd, ntime): # Rope parameters self.thetaMax = rad(pr['ropeThetaMax']) # release angle of rope self.breakTime = pr['ropeBreakTime'] self.breakAngle = rad(pr['ropeBreakAngle']) # break angle of rope self.broken = False self.thetaCutThr = pr[ 'releasePrepFactor'] * self.thetaMax #when to cut throttle (why not in engine control?) self.d = pr['d'] # rope diameter (m) self.A = pi * self.d**2 / 4 # rope area (m2) self.Apara = pr['Apara'] # drag area (m^2) of parachute along rope self.Ys = float(pr['Ys']) # 2400*9.8/(pi*(0.005/2)^2)/0.035 # effective static Young's modulus 30 GPa for rope from Dyneema # datasheet 3.5% average elongation at break, # average breaking load of 2400 kg (5000 lbs) self.hystRate = pr[ 'hystRate'] # hysteresis rate (1/sec) for dynamic stiffness. To turn this effect off, make this rate large, not small self.Twl = pr['Twl'] #Newtons strength of weak link (Brown) self.a = pr['a'] # horizontal distance (m) of rope attachment below CG self.b = pr[ 'b'] # vertical distance (m) of rope attachment below CG # horizontal distance (m) of rope attachment in front of CG, for Grob self.lo = pr['ropeLength'] print('Rope length', self.lo) self.Cdr = pr['Cdr'] # rope drag coefficient, long cylinder self.mu = pr['mu'] # rope linear mass density (kg/meter) #variables self.thetaRG = None # state variables self.T = 0 # data self.data = zeros(ntime, dtype=[('T', float), ('Tglider', float), ('torq', float), \ ('theta', float), ('Pdeliv', float), ('Edeliv', float), ('sm', float), ('stretch', float)]) if self.breakAngle < self.thetaMax: print('Rope break simulation at angle {} deg'.format( self.ropeBreakAngle)) if self.breakTime < tEnd: print('Rope break simulation at time {} sec'.format( self.ropeBreakTime))
def calculateNormalForce(self, seedFS): ''' Method for calculating the normal force to the base; this is done by using the Equation [16] of `Fredlund & Krahn (1977) <https://doi.org/10.1139/t77-045>`_. Since the normal forces are updated with each iteration, is necessary to input a factor of safety as a seed. Args: seedFS (`int` or `float`): Seed factor of safety. Returns: (`list`): Values of all the normal forces at the slice's bases Examples: >>> from numpy import array >>> import matplotlib.pyplot as plt >>> from pybimstab.slope import AnthropicSlope >>> from pybimstab.slipsurface import CircularSurface >>> from pybimstab.watertable import WaterTable >>> from pybimstab.slices import MaterialParameters, Slices >>> from pybimstab.slopestabl import SlopeStabl >>> slope = AnthropicSlope(slopeHeight=40, slopeDip=[2, 1], >>> crownDist=60, toeDist=30, depth=20) >>> surface = CircularSurface(slopeCoords=slope.coords, >>> dist1=45.838, dist2=158.726, >>> radius=80) >>> material = MaterialParameters(cohesion=600, frictAngle=20, >>> unitWeight=120, >>> wtUnitWeight=62.4) >>> slices = Slices( >>> material=material, slipSurfCoords=surface.coords, >>> slopeCoords=slope.coords, numSlices=5) >>> stabAnalysis = SlopeStabl(slices, seedFS=1, Kh=0) >>> stabAnalysis.calculateNormalForce(stabAnalysis.FS['fs']) [45009.409630951726, 68299.77910530512, 70721.13554871723, 57346.7578530581, 22706.444365285253] ''' from numpy import sin, cos, tan from numpy import radians as rad listP = list() for slice_ in self.slices.slices: # Calculating the normal force 'P' at the base of the slice_. c = slice_.material.cohesion phi = rad(slice_.material.frictAngle) if seedFS == 0: seedFS = 1 mAlpha = cos(rad(slice_.alpha)) + sin(rad(slice_.alpha)) * \ sin(rad(slice_.material.frictAngle)) / seedFS P = (slice_.weight + slice_.Xr - slice_.Xl - (c * slice_.l - slice_.U * tan(phi)) * sin(rad(slice_.alpha)) / seedFS + slice_.extL * sin(rad(slice_.w))) / mAlpha setattr(slice_, 'P', P) listP.append(P) return listP
def findState(self, t, ti, rp, pl): '''Determine where in the launch the glider is''' gd = self.data[ti.i] v = gd['v'] climb = gd['gamma'] # print(t, 'climb',deg(climb)) # One-time switches: minHeightRotate = 2 if not self.leftGround and gd['L'] > self.W: print('lift off at {:3.1f}s'.format(t)) self.leftGround = True # state if not self.leftGround : self.state = 'onGnd' elif self.beforePreClimb and climb < self.preClimbAngle: self.state = 'preClimb' self.beforePreClimb = False # elif self.beforeInitClimb and self.theta >= rad(10): elif not self.beforePreClimb and self.beforeInitClimb and v > 25 and climb > self.initClimbAngle: self.state = 'initClimb' self.beforeInitClimb = False elif not self.beforeInitClimb and self.beforeInRot and climb > rad(20): # and t > 7.5: #rad(30) < self.theta < rad(40) and rp.data[ti.i]['theta'] < rp.thetaCutThr: self.state = 'inRot' self.beforeInRot = False elif not self.beforeInitClimb and self.beforeInRot and climb > rad(20): # and t > 7.5: #rad(30) < self.theta < rad(40) and rp.data[ti.i]['theta'] < rp.thetaCutThr: self.state = 'inRot' self.beforeInRot = False elif self.beforeDoneRot and not self.beforeInRot and abs(self.thetaD) < rad(0.5): #deg/sec: self.state = 'postRot' self.beforeDoneRot = False elif rp.data[ti.i]['theta'] >= rp.thetaCutThr: self.state = 'prepRelease' pl.tPrepRelease = t if self.state != self.oldState: print('Glider state : {} at {:3.1f} s'.format(self.state, t)) self.oldState = self.state
def get_uturn_angle(ts,tud,toc,te): a = get_0T3([ts, tud, toc]) a11, a12 = a[0,0], a[0,1] a21, a22 = a[1,0], a[1,1] a31, a32 = a[2,0], a[2,1] zw, yw, xw = joint_positions['wrist'][2], joint_positions['wrist'][1], joint_positions['wrist'][0] ys, xs = joint_positions['shoulder'][1], joint_positions['shoulder'][0] lala1 = a11*(xw-xs) + a21*(yw-ys) + a31*zw lala2 = a12*(xw-xs) + a22*(yw-ys) + a32*zw denominator = -26.1*sin(te + np.pi) try: test_1 = -arccos(lala1/denominator) except: test_1 = 0 try: test_2 = arcsin(lala2/denominator) except: test_2 = 0 theta_uturn_c = test_1 + np.pi/2 theta_uturn_s = test_2 + np.pi/2 test_list = [theta_uturn_c, theta_uturn_s, 'stop'] for i in test_list: if(i == 'stop'): theta_uturn = rad(-361) else: testing = [ts, tud, toc, i, te] test = vector(get_wrist_position(testing)) if ((test - joint_positions['wrist']).length < 1): theta_uturn = i break return theta_uturn
def intersliceForces(self, seedFS, lambda_): ''' Method for getting the shear and normal interslice forces, ; this is done by using the Equation of section 14.8 of `GeoSlope (2015) <http://downloads.geo-slope.com/geostudioresources/books/8/15/slope%20modeling.pdf>`_ for the rigth normal force and the Equation [16] of `Fredlund & Krahn (1977) <https://doi.org/10.1139/t77-045>`_ for the shear force. Since the interslice forces are updated with each iteration, is necessary to input a factor of safety as a seed and the current value of lambda to relate the interslice normal force and the interslice force function with respect to the interslice shear force (Eq. [16] of `Fredlund & Krahn (1977) <https://doi.org/10.1139/t77-045>`_). Args: seedFS (`int` or `float`): Seed factor of safety. lambda_ (`int` or `float`): Seed value of lambda. ``0`` is the default value. Returns: (`tuple`): tuple with the interslice forces. the first element\ contains the normal interslice forces and the second contains\ the shear interslice forces. Examples: >>> from numpy import array >>> import matplotlib.pyplot as plt >>> from pybimstab.slope import AnthropicSlope >>> from pybimstab.slipsurface import CircularSurface >>> from pybimstab.watertable import WaterTable >>> from pybimstab.slices import MaterialParameters, Slices >>> from pybimstab.slopestabl import SlopeStabl >>> slope = AnthropicSlope(slopeHeight=40, slopeDip=[2, 1], >>> crownDist=60, toeDist=30, depth=20) >>> surface = CircularSurface(slopeCoords=slope.coords, >>> dist1=45.838, dist2=158.726, >>> radius=80) >>> material = MaterialParameters(cohesion=600, frictAngle=20, >>> unitWeight=120, >>> wtUnitWeight=62.4) >>> slices = Slices( >>> material=material, slipSurfCoords=surface.coords, >>> slopeCoords=slope.coords, numSlices=5) >>> stabAnalysis = SlopeStabl(slices, seedFS=1, Kh=0) >>> stabAnalysis.intersliceForces(stabAnalysis.FS['fs'], >>> stabAnalysis.FS['lambda']) ([0, -24561.260979675248, -42085.32887504204, -38993.844201424305, -18464.723052348225, -61.4153504520018], [0, -5511.202498703704, -15279.673506543182, -14157.266298947989, -4143.22489013017, -2.8712090198929304e-15]) ''' from numpy import tan, cos, sin from numpy import radians as rad forcesE = [self.slices.slices[0].El] forcesX = [self.slices.slices[0].Xl] for i in range(self.slices.numSlices): slice_ = self.slices.slices[i] c = slice_.material.cohesion phi = rad(slice_.material.frictAngle) Sm = (c * slice_.l + (slice_.P - slice_.U) * tan(phi)) / seedFS setattr(slice_, 'Sm', Sm) # Eq. [19] of Fredlund & Kranh (1977) does not work for now # slice_.Er = slice_.El + (slice_.weight - slice_.Xr + slice_.Xl) *\ # tan(rad(slice_.alpha)) - Sm / cos(rad(slice_.alpha)) + \ # self.Kh * slice_.weight # Eq. gotten from the section 14.8 of GEO-SLOPE (2015) slice_.Er = slice_.El - slice_.P * sin(rad(slice_.alpha)) + \ Sm * cos(rad(slice_.alpha)) - self.Kh * slice_.weight + \ slice_.extL * cos(rad(slice_.w)) slice_.Xr = slice_.Er * lambda_ * slice_.fR if i < self.slices.numSlices - 1: nextSlice = self.slices.slices[i + 1] nextSlice.El = slice_.Er nextSlice.Xl = slice_.Xr forcesE.append(slice_.Er) forcesX.append(slice_.Xr) return (forcesE, forcesX)
def getFf(self, seedFS, lambda_=0): ''' Method for getting the factor of safety with respect to the forces equilimrium; this is done by using the Equation [23] of `Fredlund & Krahn (1977) <https://doi.org/10.1139/t77-045>`_. Since the factor of safety is updated with each iteration, is necessary to input a factor of safety as a seed and the current value of lambda to relate the interslice normal force and the interslice force function with respect to the interslice shear force (Eq. [16] of `Fredlund & Krahn (1977) <https://doi.org/10.1139/t77-045>`_). Args: seedFS (`int` or `float`): Seed factor of safety. lambda_ (`int` or `float`): Seed value of lambda. ``0`` is the default value. Returns: (`dict`): Dictionary with the value of the factor of safety and a\ tuple with the boolean that indicated if the toleranfe was\ reached and the number of the iteration. Examples: >>> # Example Case 1 - Fig. 9 (Fredlund & Krahn, 1977) >>> from pybimstab.slope import AnthropicSlope >>> from pybimstab.slipsurface import CircularSurface >>> from pybimstab.slices import MaterialParameters, Slices >>> from pybimstab.slopestabl import SlopeStabl >>> slope = AnthropicSlope(slopeHeight=40, slopeDip=[2, 1], >>> crownDist=60, toeDist=30, depth=20) >>> surface = CircularSurface(slopeCoords=slope.coords, >>> dist1=45.838, dist2=158.726, >>> radius=80) >>> material = MaterialParameters(cohesion=600, frictAngle=20, >>> unitWeight=120, >>> wtUnitWeight=62.4) >>> slices = Slices( >>> material=material, slipSurfCoords=surface.coords, >>> slopeCoords=slope.coords, numSlices=50, >>> watertabCoords=None, bim=None) >>> stabAnalysis = SlopeStabl(slices, seedFS=1, Kh=0, minLambda=0, >>> interSlcFunc=1, nLambda=10) >>> stabAnalysis.getFf(stabAnalysis.FS['fs'], >>> stabAnalysis.FS['lambda']) (2.0741545445738296, True) ''' from numpy import tan, cos, sin from numpy import radians as rad # Doing the iteration toleraceReached = False fs = [seedFS] for i in range(self.maxIter): # Calculating the normal force at each base slice_. self.calculateNormalForce(fs[-1]) num = 0 den1, den2, den3 = 0, 0, 0 for slice_ in self.slices.slices: c = slice_.material.cohesion phi = rad(slice_.material.frictAngle) num += c * slice_.width + (slice_.P - slice_.U) * tan(phi) * \ cos(rad(slice_.alpha)) den1 += slice_.P * sin(rad(slice_.alpha)) den2 += slice_.extL * cos(rad(slice_.w)) den3 += self.Kh * slice_.weight fs.append(num / (den1 - den2 + den3)) # Recalculating the interslice forces self.intersliceForces(fs[-1], lambda_) self.calculateNormalForce(fs[-1]) self.intersliceForces(fs[-1], lambda_) # Verifying if the tolerance is reached if i > 5 and all((fs[-1] - fs[-2], fs[-2] - fs[-3])) <= self.tol: toleraceReached = True break return fs[-1], toleraceReached
def get_oc_angle(): theta3 = -arccos((joint_positions['elbow'].length**2 - 1148.69) / (849.4*sin(rad(72)))) return theta3, (theta3 + np.pi/2)
def get_ud_angle(t3): R = np.sqrt((sin(rad(72))*sin(t3))**2 + (cos(rad(72)))**2) phi = np.arctan(1/(sin(t3)*np.tan(rad(72)))) return (arcsin(joint_positions['elbow'][2] / ((-31)*R)) + phi)
from numpy import cos as cos from numpy import sin as sin from numpy import radians as rad from numpy import array as arr from numpy import pi as pi from vectormath import Vector3 as vector oc = rad(72) half = pi/2 def getTransformMatrix(theta, d, a, alpha): T = arr([[cos(theta) , -sin(theta)*cos(alpha) , sin(theta)*sin(alpha) , a*cos(theta)], [sin(theta) , cos(theta)*cos(alpha) , -cos(theta)*sin(alpha) , a*sin(theta)], [0 , sin(alpha) , cos(alpha) , d ], [0 , 0 , 0 , 1 ] ]) return T def get_0T3(params): t_12 = getTransformMatrix(params[0]+half , 0 , 0 , half) t_23 = getTransformMatrix(params[1]+pi , 13.7 , 0 , half) t_34 = getTransformMatrix(params[2]-half , 0 , 0 , oc) return (t_12.dot(t_23).dot(t_34)) def get_elbow_position(params): # Create the transformation matrices for the respective joints t_12 = getTransformMatrix(params[0]+half , 0 , 0 , half) t_23 = getTransformMatrix(params[1]+pi , 13.7 , 0 , half) t_34 = getTransformMatrix(params[2]-half , 0 , 0 , oc) t_45 = getTransformMatrix( -half , -31 , 0 , half)
# set info for compute the baricentric correction iers = GLOBALutils.JPLiers( baryc_dir, scmjd-999.0, scmjd+999.0 ) obsradius, R0 = GLOBALutils.JPLR0( latitude, altitude) obpos = GLOBALutils.obspos( longitude, obsradius, R0 ) jplephem.set_ephemeris_dir( baryc_dir , ephemeris ) jplephem.set_observer_coordinates( obpos[0], obpos[1], obpos[2] ) res = jplephem.doppler_fraction(RA/15.0, DEC, int(scmjd), scmjd%1, 1, 0.0) lbary_ltopo = 1.0 + res['frac'][0] bcvel_baryc = ( lbary_ltopo - 1.0 ) * 2.99792458E5 #This in the barycentric velocity res = jplephem.pulse_delay(RA/15.0, DEC, int(scmjd), scmjd%1, 1, 0.0) scmbjd = scmjd + res['delay'][0] / (3600.0 * 24.0) #This is the modified barycentric julian day of the observation # set observatory info to retrive info about the moon gobs = ephem.Observer() gobs.name = 'VBT' gobs.lat = rad(latitude) gobs.long = rad(longitude) #gobs.date = hd['UT-DATE'] + ' ' + hd['UT-TIME'].replace(':','_') gobs.date = hd['DATE-OBS'].replace('T',' ') mephem = ephem.Moon() mephem.compute(gobs) Mcoo = jplephem.object_track("Moon", int(scmjd), float(scmjd%1), 1, 0.0) Mp = jplephem.barycentric_object_track("Moon", int(scmjd), float(scmjd%1), 1, 0.0) Sp = jplephem.barycentric_object_track("Sun", int(scmjd), float(scmjd%1), 1, 0.0) res = jplephem.object_doppler("Moon", int(scmjd), scmjd%1, 1, 0.0) lunation,moon_state,moonsep2,moonvel = GLOBALutils.get_lunar_props(ephem,gobs,Mcoo,Mp,Sp,res,RA,DEC) refvel = bcvel_baryc + moonvel #This is the velocity of the spectrum of the moon with the applied barycentric correction in the direction of the target. print '\t\t\tBarycentric velocity:',refvel
class pm2a: z = 41.4427 GrazingAngleDeg = 2.5 GrazingAngle = rad(GrazingAngleDeg )
def transform_motion(motion, newref, rotunit="deg"): """ Transform motion to new reference position. The following sequence of rotation is used: z-y-z (known as yaw-pitch-roll). For more detailed description, see https://en.wikipedia.org/wiki/Euler_angles or SIMO Theory Manual (ch. 6.2 in version 4.14.0). Parameters ---------- motion : tuple or np.ndarray Motion of old reference point, 6 dofs (hence shape (6, nt), where nt is number of time steps): - x (position of old reference point in global coord. system) - y (position of old reference point in global coord. system) - z (position of old reference point in global coord. system) - rx (rotation about local x-axis, aka. roll) - ry (rotation about local x-axis, aka. roll) - rz (rotation about local x-axis, aka. roll) newref : 3-tuple Position vector (in body coordinate system) of new reference point: (x, y, z). rotunit : {'deg', 'rad'} Unit of rotations. Default is degrees. Returns ------- xyz : np.ndarray Position vector for new reference position, shape (3, n). """ motion = np.asarray(motion) # ensure motion is numpy array newref = np.asarray( newref ) # ensure newref is numpy array, for efficiency in loop with np.dot ndof, nt = motion.shape # number of dofs and time steps assert ndof == 6, f"Motion must be of shape (6, nt) (6-dof motion), got {motion.shape}" assert newref.size == 3, f"Specified position must be list/tuple with three values, got {len(newref)}" # extract rotations, scale to radians if needed given as degrees if rotunit == "deg": rx, ry, rz = rad(motion[-3:, :]) elif rotunit == "rad": rx, ry, rz = motion[-3:, :] else: raise ValueError( f"Parameter `rotunit` must be 'deg' or 'rad', not '{rotunit}'") # calculate transformation matrix -> shape (3, 3, nt) trans = np.array([ [ cos(rz) * cos(ry), -sin(rz) * cos(rx) + cos(rz) * sin(ry) * sin(rx), sin(rz) * sin(rx) + cos(rz) * sin(ry) * cos(rx) ], [ sin(rz) * cos(ry), cos(rz) * cos(rx) + sin(rz) * sin(ry) * sin(rx), -cos(rz) * sin(rx) + sin(rz) * sin(ry) * cos(rx) ], [-sin(ry), cos(ry) * sin(rx), cos(ry) * cos(rx)], ]) # transform to new reference position for each time step -> shape (3, nt) xyz = np.zeros((3, nt)) for i in range(nt): xyz[:, i] = np.dot(trans[:, :, i], newref) # ... and add xyz motion of old reference point xyz += motion[:3, :] return xyz
def plotsImp(figures, path, preppedData, pr, gl, ai, rp, dr, tc, en, op, pl): close('all') showPlot = pr['impPlotsShow'] save = pr['impPlotsSave'] path = os.path.join(path, 'imperial') if not os.path.exists(path): os.mkdir(path) lbsPernewt = 1 / 4.44822 hpPerW = 1.34102 / 1000.0 ftlbPerNm = 0.738 ktPerms = 1.94384 ftPerm = 3.28084 rpmPerRadPs = 60 / 2 / pi g = 9.8 [t, x, y, xD, yD, v, vD, alpha, theta, thetaD, gamma, elev, Sth, omegd, omege, L, D, T, Tg, vgw, \ torqWing,torqStab, Me, Few, engP, omegrel, rdrum, tctorqueDrum, winP, ropP, gliP, gndTorq, ropeTheta, ropeTorq, \ smRope, smStall, smStruct, smRecov, vGust, gData, dData, oData, pData, eData, rData, aData, tData] = preppedData iColor = 0 # counter for plots, so each variable has a different color # plot engine power and torque curves from model parameters if pr['plotPowerTorque']: omegeng = linspace(0, 1.1 * en.omegapeakP, 100) powr = linspace(0, 1.1 * en.omegapeakP, 100) torq = linspace(0, 1.1 * en.omegapeakP, 100) rpm = omegeng * 60 / 2.0 / pi for i, omegr in enumerate(omegeng): powr[i] = hpPerW * en.Pavail(omegr) torq[i] = ftlbPerNm * en.torqAvail(omegr) figures.append( xy(False, showPlot, save, path, iColor, [rpm], [powr, torq], 'Engine speed (rpm)', 'Power (HP), Torque(Ftlbs)', ['Pistons power', 'Pistons torque'], 'Engine curves')) if pr['plotLift']: ##plot lift curve vs alpha at v_best alphaList = linspace(-20, 80, 100) lift = array([gl.Lnl(gl.vb, rad(alph)) for alph in alphaList]) figures.append(xy(False, showPlot, save, path, iColor, [alphaList], [lift/gl.W], \ 'Angle of attack (deg)', 'Lift/Weight', [''], 'Lift vs angle of attack')) alphaList = linspace(-4, pr['alphaStallVsWing'], 100) drag = array([gl.coeffDrag(rad(alph)) for alph in alphaList]) figures.append(xy(False, showPlot, save, path, iColor, [alphaList], [drag], \ 'Angle of attack (deg)', 'Drag coefficient', [''], 'Drag vs angle of attack')) if pr['plotTorqCov']: vrelList = linspace(0, 1.5, 100) tcGearingList = array([tc.torqMult(vrel) for vrel in vrelList]) # tcEfficiencyList = array([vrel * tc.torqMult(vrel) for vrel in vrelList]) tcInvKform = array([tc.invKform(vrel) for vrel in vrelList]) figures.append(xy(False, showPlot, save, path, iColor, [vrelList], \ [tcGearingList, tcInvKform], 'vDrum/vEngine', '' ,['torque factor','inverse capacity form'], 'Torque converter')) # def xy(holdOpen, showPlot, save, path, iColor, xs, ys, xlbl, ylbl, legendLabels, titlestr, xmin=None, xmax=None): #presentation figures #height, T, L, y vs x figures.append( xy(False, showPlot, save, path, iColor, [ftPerm * x], [ftPerm * y, Tg / gl.W * 1000, L / gl.W * 1000], 'x (ft)', 'y (ft), forces', ['height', 'tension/Weight x 1000', 'lift/Weight x 1000'], 'Height and forces vs x')) # glider v, climb, alpha, elevator vs x figures.append(xy(False, showPlot, save, path, iColor, [ftPerm * x], [ktPerms*v, deg(alpha),deg(gamma), deg(elev)], \ 'x (ft)', 'velocity (kts), angles (deg)', ['v', 'angle of attack', 'climb', 'elevator'], 'Glider speed and angles vs x')) # engine rpm, vrel, thr vs x figures.append(xy(False, showPlot, save, path, iColor, [ftPerm*x], [omege * 60 / 2 / pi/10, hpPerW*engP, 10 * 100 * omegrel, 10 * 100 * Sth], \ 'x (ft)', 'Speeds (rpm,kts), %', ['eng rpm/10', 'engine HP', \ 'TC speed vs engine % x10', 'throttle % x10'], 'Engine vs x')) #height, T, L, y vs t figures.append( xy(False, showPlot, save, path, iColor, [t], [ftPerm * y, Tg / gl.W * 1000, L / gl.W * 1000], 't (sec)', 'y (ft), forces', ['height', 'tension/Weight x 1000', 'lift/Weight x 1000'], 'Height and forces vs t')) # glider v, climb, alpha, elevator vs t figures.append(xy(False, showPlot, save, path, iColor, [t], [ktPerms*v, deg(alpha),deg(gamma), deg(elev)], \ 't (sec)', 'velocity (kts), angles (deg)', ['v', 'angle of attack', 'climb', 'elevator'], 'Glider speed and angles vs t')) # engine rpm, vrel, thr vs t figures.append(xy(False, showPlot, save, path, iColor, [t], [omege * 60 / 2 / pi/10, hpPerW*engP, 10 * 100 * omegrel, 10 * 100 * Sth], \ 't (sec)', 'Speeds (rpm,kts), %', ['eng rpm/10', 'engine HP', \ 'TC speed vs engine % x10', 'throttle % x10'], 'Engine vs t')) # glider position vs time figures.append( xy(False, showPlot, save, path, iColor, [t], [ftPerm * x, ftPerm * y], 'time (sec)', 'position (ft)', ['x', 'y'], 'Glider position vs time')) figures.append( xy(False, showPlot, save, path, iColor, [ftPerm * x], [ftPerm * y], 'x (ft)', 'y (ft)', [''], 'Glider y vs x')) # glider speed and angles figures.append(xy(False, showPlot, save, path, iColor, [t, t, t, t, t, t, t, t], [ktPerms*xD, ktPerms*yD, ktPerms*v, deg(alpha), deg(theta), deg(gamma), deg(elev), deg(thetaD)], \ 'time (sec)', 'Velocity (kts), Angles (deg)', ['vx', 'vy', 'v', 'angle of attack', 'pitch', 'climb', 'elevator', 'pitch rate (deg/sec)'], 'Glider velocities and angles')) # iColor = 0 #restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t, t, t, t, t], [ktPerms*v, ktPerms * dr.rdrum * omegd, y/rp.lo, Tg/gl.W, L/gl.W, divide(L, D), deg(alpha), deg(gamma), deg(thetaD)], \ [0, 0, 1, 1, 1, 0, 0, 0, 0], 'time (sec)', ['Velocity (kt), Angles (deg), L/D', 'Relative forces and height'], ['v (glider)', r'$v_r$ (rope)', \ 'height/' + r'$\l_o $', 'T/W at glider', 'L/W', 'L/D', 'angle of attack', 'climb angle', 'rot. rate (deg/sec)'], 'Glider and rope')) # Forces figures.append(xy(False, showPlot, save, path, iColor, [t, t, t, t, t], [L/gl.W, D/gl.W, T/gl.W, Tg/gl.W, Few/gl.W], \ 'time (sec)', 'Forces/Weight', ['lift', 'drag', 'tension at drum', 'tension at glider', 'tc-drum'], 'Forces')) # torques figures.append( xy(False, showPlot, save, path, iColor, [t], [ ftlbPerNm * ropeTorq, ftlbPerNm * (torqWing + torqStab), ftlbPerNm * Me, ftlbPerNm * gndTorq ], 'time (sec)', 'Torque (ft-lbs)', ['rope', 'stabilizer+wing', 'elevator', 'ground'], 'Torques on glider')) figures.append( xy(False, showPlot, save, path, iColor, [t], [ftlbPerNm * torqWing, ftlbPerNm * torqStab], 'time (sec)', 'Torque (ft-lbs)', ['wing', 'stabilizer'], 'Torques wing and stabilzer')) # Engine, rope and drum figures.append(xy(False, showPlot, save, path, iColor, [t, t, t, t, t, t, t], [ktPerms*multiply(omege,rdrum)/dr.gear/dr.diff, ktPerms*multiply(omegd,rdrum), \ ktPerms*vgw, deg(ropeTheta), ftlbPerNm * tctorqueDrum/10, -ftlbPerNm * multiply(T,rdrum)/10, 100 * Sth], 'time (sec)', 'Speeds (effective: kt), Torque/10 (Ft-lbs) Angle (deg), Throttle %', ['engine speed', 'rope speed', 'glider radial speed', 'rope angle', 'TC torque on drum', 'Rope torque on drum','throttle'], 'Engine, drum and rope')) # Engine figures.append(xy(False, showPlot, save, path, iColor, [t], [omege * 60 / 2 / pi/10, hpPerW*engP, ftlbPerNm*engP/(omege + 1e-6), ftlbPerNm*tctorqueDrum/dr.gear/ dr.diff, 10 * 100 * omegrel, 10 * 100 * Sth], \ 'time (sec)', 'Speeds (rpm,kts), Torque (ft-lbs), %', ['eng rpm/10', 'engine HP', 'engine torque', 'TC torque out',\ 'TC speed vs engine % x10', 'throttle % x10'], 'Engine')) figures.append( xy(False, showPlot, save, path, iColor, [t], [ eData['Edeliv'] / 1e6, dData['Edeliv'] / 1e6, rData['Edeliv'] / 1e6, gData['Edeliv'] / 1e6, gData['Emech'] / 1e6 ], 'time (sec)', 'Energy (MJ)', ['to engine', 'to drum', 'to rope', 'to glider', 'in glider'], 'Energy delivered and kept')) figures.append( xy(False, showPlot, save, path, iColor, [t], [engP / en.Pmax, winP / en.Pmax, ropP / en.Pmax, gliP / en.Pmax], 'time (sec)', 'Power/Pmax', ['to engine', 'to drum', 'to rope', 'to glider'], 'Power delivered')) zoom = pr['zoom'] if zoom: # if not ai.startGust is None and 's' in ai.startGust: # t1 = float(ai.startGust.split()[0])-0.5 # t2 = t1 + 2*ai.widthGust/2.05.0 + 2.0 -1.5 [t1, t2] = zoom if ai.vGustPeak > 0 and not ai.startGust is None: # without safety margins iColor = 0 # restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, T/gl.W, vGust], \ [0, 0, 0, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'T/W', 'vel gust'], 'Winch launch')) if zoom: iColor = 0 # restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, T/gl.W, vGust], \ [0, 0, 0, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'T/W', 'vel gust'], 'Winch launch expanded', t1, t2)) # with safety margins (T/W is redundant) iColor = 0 # restart color cycle figures.append(xyy(False and not zoom, showPlot, save, path, iColor, [t, t, t, t, t, t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, smStruct, smStall, smRope, smRecov, vGust], \ [0, 0, 0, 1, 1, 1, 1, 0, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'struct margin', 'stall margin', 'rope margin', 'recovery margin', 'vel gust'], 'Winch launch and safety margins')) if zoom: iColor = 0 # restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t, t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, smStruct, smStall, smRope, smRecov, vGust], \ [0, 0, 0, 1, 1, 1, 1, 0, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'struct margin', 'stall margin', 'rope margin', 'recovery margin', 'vel gust'], 'Winch launch and safety margins expanded', t1, t2)) else: # without gusts # without safety margins if zoom: iColor = 0 # restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, T/gl.W], \ [0, 0, 0, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'T/W'], 'Winch launch expanded', t1, t2)) iColor = 0 # restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, T/gl.W], \ [0, 0, 0, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'T/W'], 'Winch launch')) # with safety margins if zoom: iColor = 0 # restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, smStruct, smStall, smRope, smRecov], \ [0, 0, 0, 1, 1, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'struct margin', 'stall margin', 'rope margin', 'recovery margin'], 'Winch launch and safety margins expanded', t1, t2)) iColor = 0 # restart color cycle figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t, t, t, t, t], [ktPerms*v,ftPerm/10.0*y, deg(gamma), L/gl.W, smStruct, smStall, smRope, smRecov], \ [0, 0, 0, 1, 1, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['velocity', 'height', 'climb angle', 'L/W', 'struct margin', 'stall margin', 'rope margin', 'recovery margin'], 'Winch launch and safety margins')) # safety margins alone if zoom: iColor = 6 # choose color cycle start figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t], [smStruct, smStall, smRope, smRecov], \ [1, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['struct margin', 'stall margin', 'rope margin', 'recovery margin'], 'Safety margins expanded', t1, t2)) iColor = 6 # choose color cycle start figures.append(xyy(False, showPlot, save, path, iColor, [t, t, t, t], [smStruct, smStall, smRope, smRecov], \ [1, 1, 1, 0], 'time (sec)', ['Velocity (kt), Height/10 (ft), Angle (deg)', "Relative forces"], \ ['struct margin', 'stall margin', 'rope margin', 'recovery margin'], 'Safety margins')) ############# '''Looping over parameters is now done with multiprocessor pool. Below are plots from old looping''' # plot loop results (saved in last parameter's folder # if loop: # heightDiff = loopData['yfinal'] - min(loopData['yfinal']) # vs minimum in loop # iColor = 0 # restart color cycle # figures.append(xyy(False, showPlot, save, path, iColor, [loopData['alphaLoop']] * 12, # [loopData['xRoll'], 10 * loopData['tRoll'], loopData['yfinal']/rp.lo * 100, heightDiff, loopData['vmax'], # loopData['vDmax']/g, loopData['Sthmax'], loopData['Tmax'], loopData['Lmax'], loopData['alphaMax'], # loopData['gammaMax'], # loopData['thetaDmax']], \ # [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0], 'Angle of attack setting (deg)', # ['Velocity (kt), Angles (deg), m, sec, %', "Relative forces,g's"], \ # ['x gnd roll', 't gnd roll x 10', 'height/rope %', 'height diff', r'$v_{max}$', "max g's", 'max throttle', # r'$T_{max}/W$', r'$L_{max}/W$', r'$\alpha_{max}$', r'$\gamma_{max}$', 'rot. max (deg/sec)'], # 'Flight (all) vs target angle of attack')) # # fewer results, for presentation # iColor = 0 # restart color cycle # figures.append(xyy(False, showPlot, save, path, iColor, [loopData['alphaLoop']] * 4, # [loopData['vmax'], heightDiff, loopData['gammaMax'], loopData['Lmax']], \ # [0, 0, 0, 1], 'Angle of attack target (deg)', # ['Velocity (kt), Angle (deg), Height/10 (ft), %', "Relative forces"], \ # [r'$v_{max}$', 'height diff', 'climb angle max', r'$L_{max}/W$'], 'Flight vs target angle of attack')) # # With safety margins for presentation # iColor = 4 # match colors in previous plot # figures.append(xyy(False, [loopData['alphaLoop']] * 4, # [loopData['smStructMin'], loopData['smStallMin'], loopData['smRopeMin'], loopData['smRecovMin']], \ # [1, 1, 1, 0], 'Target angle of attack (deg)', ['Recovery height margin (ft)', "Safety margin (g's)"], \ # ['struct margin', 'stall margin', 'rope margin', 'recovery margin'], # 'Safety margins vs target angle of attack')) # print('Stop program to close plots!') return figures
def get_aoi(self, sun_zenith, sun_azimuth): if self.method == "pvlib": self.aoi = rad(self.syst.get_aoi(deg(sun_zenith), deg(sun_azimuth)))
class presto: z = 49.8466 GrazingAngleDeg = 2.5 GrazingAngle = rad(GrazingAngleDeg)
class Kbv: f1 = 98.0 # orizzontale f2 = 1.750 # orizzontale M = f1/f2 GrazingAngle = rad(2) Letter = 'v'
class dpi_kbh: Name = 'dpi_kbh' f1 = 91.6566 f2 = 1.200 GrazingAngle = rad(2) z=f1