def getMoment(self, fp): """Compute the mass of the object, already taking into account the type of subentities. Position arguments: fp -- Part::FeaturePython object affected. Returned value: List of moments toward x, y and z """ m = [Units.parseQuantity('0 kg*m'), Units.parseQuantity('0 kg*m'), Units.parseQuantity('0 kg*m')] for s in fp.Shape.Solids: mom = self._getVolumetricMoment(fp, s) for i in range(len(m)): m[i] = m[i] + mom[i] for f in fp.Shape.Faces: mom = self._getAreaMoment(fp, f) for i in range(len(m)): m[i] = m[i] + mom[i] for e in fp.Shape.Edges: mom = self._getLinearMoment(fp, e) for i in range(len(m)): m[i] = m[i] + mom[i] for v in fp.Shape.Vertexes: mom = self._getPuntualMoment(fp, v) for i in range(len(m)): m[i] = m[i] + mom[i] return m
def accept(self): if not self.ship: return False self.save() # Plot data mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.num = self.widget(QtGui.QSpinBox, "Num") draft = Units.parseQuantity(Locale.fromString(form.draft.text())) trim = Units.parseQuantity(Locale.fromString(form.trim.text())) num = form.num.value() disp, B, _ = Hydrostatics.displacement(self.ship, draft, Units.parseQuantity("0 deg"), trim) xcb = Units.Quantity(B.x, Units.Length) data = Hydrostatics.areas(self.ship, num, draft=draft, trim=trim) x = [] y = [] for i in range(0, len(data)): x.append(data[i][0].getValueAs("m").Value) y.append(data[i][1].getValueAs("m^2").Value) PlotAux.Plot(x, y, disp, xcb, self.ship) self.preview.clean() return True
def func(): player = input("Please, choose and enter your username: "******"Привет, " + player + "!") i = 0 while True: i += 1 try: race = input( "Выбери страну, в которой хочешь играть: Carfagen, Serb ") if race.lower() == "carfagen": player = Units.CorfagenArmyFactory() print("Поздравляю! Твой стартовый капитал 100 монет\n") print(phr) break elif race.lower() == "serb": player = Units.SerbianArmyFactory() print("Поздравляю! Твой стартовый капитал 100 монет\n") print(phr) break else: print("Unknown race!") raise ValueError except ValueError: if i < 2: print("Choose again.") elif i == 2: print("Too many times entered wrong line, bye-bye baby)") print("I'm just joke, choose one more time!") else: return continue print() playing.play(player)
def turn(gc, unit): Units.shoot_at_best_target(gc, unit) if gc.is_move_ready(unit.id): planet = unit.location.map_location().planet path = get_closest_fact(unit) if planet == bc.Planet.Earth else Globals.updatePathMars Navigation.path_with_bfs(gc, unit, path) return
def tankCapacityCurve(tank, n): """Create a tank capacity curve Position arguments: tank -- Tank object (see createTank) ship -- n Number of filling levels to test Returned value: List of computed points. Each point contains the filling level percentage (interval [0, 1]), the the filling level (0 for the bottom of the tank), and the volume. """ bbox = tank.Shape.BoundBox dz = Units.Quantity(bbox.ZMax - bbox.ZMin, Units.Length) dlevel = 1.0 / (n - 1) out = [(0.0, Units.parseQuantity("0 m"), Units.parseQuantity("0 m^3"))] msg = QtGui.QApplication.translate( "ship_console", "Computing capacity curves", None) App.Console.PrintMessage(msg + '...\n') for i in range(1, n): App.Console.PrintMessage("\t{} / {}\n".format(i + 1, n)) level = i * dlevel vol = tank.Proxy.getVolume(tank, level) out.append((level, level * dz, level * vol)) return out
def moment(ship, draft=None, roll=Units.parseQuantity("0 deg"), trim=Units.parseQuantity("0 deg")): """Compute the moment required to trim the ship 1cm Position arguments: ship -- Ship object (see createShip) Keyword arguments: draft -- Ship draft (Design ship draft by default) roll -- Roll angle (0 degrees by default) trim -- Trim angle (0 degrees by default) Returned value: Moment required to trim the ship 1cm. Such moment is positive if it cause a positive trim angle. The moment is expressed as a mass by a distance, not as a force by a distance """ disp_orig, B_orig, _ = displacement(ship, draft, roll, trim) xcb_orig = Units.Quantity(B_orig.x, Units.Length) factor = 10.0 x = 0.5 * ship.Length.getValueAs('cm').Value y = 1.0 angle = math.atan2(y, x) * Units.Radian trim_new = trim + factor * angle disp_new, B_new, _ = displacement(ship, draft, roll, trim_new) xcb_new = Units.Quantity(B_new.x, Units.Length) mom0 = -disp_orig * xcb_orig mom1 = -disp_new * xcb_new return (mom1 - mom0) / factor
def print_metrics(cpu_state: CpuState): """ CPU UTILIZATION - idle time/ run time Throughput - processes completed per time unity Waiting Time - time in ready queue Turnaround Time - time of arrival to time of running queue exit Response Time - time of submission to time or process started """ print("\n================= METRICS =================\n") uti = cpu_state.idle_ticks / cpu_state.last_exit_tick uti = 1 - uti uti = round_three(uti) print(f"UTI: {uti}%") runtime_seconds = Units.MiS_to_seconds(cpu_state.last_exit_tick) tpt = CONFIG.total_jobs / runtime_seconds tpt = round_three(tpt) print(f"TPT: {tpt} Processes per Second") tot_wait_time = Units.MiS_to_seconds(cpu_state.wtt_rolling_time_sum) wtt = tot_wait_time / CONFIG.total_jobs wtt = round_three(wtt) print(f"WTT: {wtt} Seconds") tot_tut_time = Units.MiS_to_seconds(cpu_state.tut_rolling_time_sum) tut = tot_tut_time / CONFIG.total_jobs tut = round_three(tut) print(f"TUT: {tut} Seconds")
def generateParametersAndState(airports, entry): # TODO (niwang) # airports: a dict of AirportID to Airport object # the original list of Airport is a tuple of Airport and Environment, now we only keep # the Airport Object # entry: FlightEntry aircraftType = Aircraft.mediumRange departureAirport = airports[entry.DepartureAirport] #['Airport.Code'] arrivalAirport = airports[entry.ArrivalAirport] #['Airport.Code'] timeElapsed = Units.timeDifference(0.0, entry.ActualGateDepartureTime) maximumFuel = Units.fuelGallonsToFuelPounds(aircraftType.FuelCapacity) initialFuel = entry.InitialFuel fuelConsumed = entry.ConsumedFuel flightParameters = FlightParameters( entry.Id, 'Eastbound' if departureAirport.Position.PositionX < \ arrivalAirport.Position.PositionX else 'Westbound', aircraftType, arrivalAirport, entry.Payload, initialFuel, entry.ScheduledGateDepartureTime, entry.ActualGateDepartureTime, entry.ScheduledGateArrivalTime, entry.ScheduledRunwayArrivalTime) flightState = FlightState(entry.Position, 0.0, 0.0, timeElapsed, fuelConsumed, Airspace.emptyIntersection, 0.0, []) return (flightParameters, flightState)
def onData(self, value): """ Method called when the tool input data is touched. @param value Changed value. """ if not self.ship: return mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") # Get the values (or fix them in bad setting case) try: draft = Units.parseQuantity(Locale.fromString(form.draft.text())) except: draft = self.ship.Draft form.draft.setText(draft.UserString) try: trim = Units.parseQuantity(Locale.fromString(form.trim.text())) except: trim = Units.parseQuantity("0 deg") form.trim.setText(trim.UserString) bbox = self.ship.Shape.BoundBox draft_min = Units.Quantity(bbox.ZMin, Units.Length) draft_max = Units.Quantity(bbox.ZMax, Units.Length) draft = self.clampValue(form.draft, draft_min, draft_max, draft) trim_min = Units.parseQuantity("-180 deg") trim_max = Units.parseQuantity("180 deg") trim = self.clampValue(form.trim, trim_min, trim_max, trim) self.onUpdate() self.preview.update(draft, trim, self.ship)
def getMoment(self, fp): """Compute the mass of the object, already taking into account the type of subentities. Position arguments: fp -- Part::FeaturePython object affected. Returned value: List of moments toward x, y and z """ m = [ Units.parseQuantity('0 kg*m'), Units.parseQuantity('0 kg*m'), Units.parseQuantity('0 kg*m') ] for s in fp.Shape.Solids: mom = self._getVolumetricMoment(fp, s) for i in range(len(m)): m[i] = m[i] + mom[i] for f in fp.Shape.Faces: mom = self._getAreaMoment(fp, f) for i in range(len(m)): m[i] = m[i] + mom[i] for e in fp.Shape.Edges: mom = self._getLinearMoment(fp, e) for i in range(len(m)): m[i] = m[i] + mom[i] for v in fp.Shape.Vertexes: mom = self._getPuntualMoment(fp, v) for i in range(len(m)): m[i] = m[i] + mom[i] return m
def export_to_text(self): """Creates a string that describes the workout.""" unit_system = self.user_mgr.retrieve_user_setting( self.user_id, Keys.PREFERRED_UNITS_KEY) result = "Workout Type: " result += self.type result += "\nSport: " result += self.sport_type result += "\n" # Add the warmup (if applicable). if self.warmup is not None and ZwoTags.ZWO_ATTR_NAME_DURATION in self.warmup: result += "Warmup: " result += str(self.warmup[ZwoTags.ZWO_ATTR_NAME_DURATION]) result += " seconds.\n" # Add each interval. for interval in self.intervals: interval_meters = interval[Keys.INTERVAL_DISTANCE_KEY] interval_pace_minute = interval[Keys.INTERVAL_PACE_KEY] recovery_meters = interval[Keys.INTERVAL_RECOVERY_DISTANCE_KEY] recovery_pace_minute = interval[Keys.INTERVAL_RECOVERY_PACE_KEY] result += "Interval: " result += Units.convert_to_string_in_specified_unit_system( unit_system, interval_meters, Units.UNITS_DISTANCE_METERS, None, Keys.TOTAL_DISTANCE) result += " at " result += Units.convert_to_string_in_specified_unit_system( unit_system, interval_pace_minute, Units.UNITS_DISTANCE_METERS, Units.UNITS_TIME_MINUTES, Keys.INTERVAL_PACE_KEY) if recovery_meters > 0: result += " with " result += Units.convert_to_string_in_specified_unit_system( unit_system, recovery_meters, Units.UNITS_DISTANCE_METERS, None, Keys.TOTAL_DISTANCE) result += " recovery at " result += Units.convert_to_string_in_specified_unit_system( unit_system, recovery_pace_minute, Units.UNITS_DISTANCE_METERS, Units.UNITS_TIME_MINUTES, Keys.INTERVAL_PACE_KEY) result += ".\n" # Add the cooldown (if applicable). if self.cooldown is not None and ZwoTags.ZWO_ATTR_NAME_DURATION in self.cooldown: result += "Cooldown: " result += str(self.cooldown[ZwoTags.ZWO_ATTR_NAME_DURATION]) result += " seconds.\n" # Add an string that describes how this workout fits into the big picture. if self.type == Keys.WORKOUT_TYPE_INTERVAL_SESSION: result += "Purpose: Interval sessions are designed to build speed and strength.\n" elif self.type == Keys.WORKOUT_TYPE_TEMPO_RUN: result += "Purpose: Tempo runs build a combination of speed and endurance. They should be performed at a pace you can hold for roughly one hour.\n" elif self.type == Keys.WORKOUT_TYPE_EASY_RUN: result += "Purpose: Easy runs build aerobic capacity while keeping the wear and tear on the body to a minimum.\n" return result
def accept(self): if not self.ship: return False self.save() # Plot data mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") draft = Units.Quantity(Locale.fromString( form.draft.text())).getValueAs('m').Value trim = Units.Quantity(Locale.fromString( form.trim.text())).getValueAs('deg').Value data = Hydrostatics.displacement(self.ship, draft, 0.0, trim) disp = data[0] xcb = data[1].x data = Hydrostatics.areas(self.ship, draft, 0.0, trim) x = [] y = [] for i in range(0, len(data)): x.append(data[i][0]) y.append(data[i][1]) PlotAux.Plot(x, y, disp, xcb, self.ship) self.preview.clean() return True
def _initialize_secondary(self): """Helper method to initializes sources from secondary source file""" units = PointSourceContainer.units try: secondary_sources = open(self.secondary_file_name) except IOError as error: err_string = "Unable to open file {0}".format(self.secondary_file_name) raise IOError(err_string) secondary_list = [] headers = secondary_sources.readline() line = secondary_sources.readline() while line!="": line_list = line.split(',') name=line_list[0] parent = line_list[1] parentSource = getattr(self,parent) lat=float(line_list[2]) lon=float(line_list[3]) emissions = float(line_list[4]) yearly_emissions = {2014: Units.SciVal(emissions, units), 2015: Units.SciVal(emissions, units), 2016: Units.SciVal(emissions, units) } height = float(line_list[5]) source = PST.PointSource(name,lat,lon,name,emissions,yearly_emissions,height) setattr(self,name,source) secondary_list.append(source) parentSource.secondary.append(source) line=secondary_sources.readline() secondary_sources.close() return secondary_list
def __init__(self, **kwargs): self.__units = [ Units.Solder() for _ in range(1, kwargs['soldiers'] + 1) ] self.__units += [ Units.Vehicles() for _ in range(1, kwargs['vehicles'] + 1) ]
def __init__(self, ship, faces, draft, trim): """Compute all the hydrostatics. Position argument: ship -- Ship instance faces -- Ship external faces draft -- Ship draft trim -- Trim angle """ disp, B, cb = displacement(ship, draft=draft, trim=trim) if not faces: wet = 0.0 else: wet = wettedArea(faces, draft=draft, trim=trim) mom = moment(ship, draft=draft, trim=trim) farea, cf = floatingArea(ship, draft=draft, trim=trim) bm = BMT(ship, draft=draft, trim=trim) cm = mainFrameCoeff(ship, draft=draft) # Store final data self.draft = draft self.trim = trim self.disp = disp self.xcb = Units.Quantity(B.x, Units.Length) self.wet = wet self.farea = farea self.mom = mom self.KBt = Units.Quantity(B.z, Units.Length) self.BMt = bm self.Cb = cb self.Cf = cf self.Cm = cm
def onData(self, value): """Updates the 3D preview on data changes. Keyword arguments: value -- Edited value. This parameter is required in order to use this method as a callback function, but it is unuseful. """ mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.length = self.widget(QtGui.QLineEdit, "Length") form.breadth = self.widget(QtGui.QLineEdit, "Breadth") form.draft = self.widget(QtGui.QLineEdit, "Draft") qty = Units.Quantity(form.length.text()) val_min = 0.001 val_max = self.bounds[0] / Units.Metre.Value val = qty.getValueAs('m').Value self.L = self.clampVal(form.length, val_min, val_max, val) qty = Units.Quantity(form.breadth.text()) val_min = 0.001 val_max = self.bounds[1] / Units.Metre.Value val = qty.getValueAs('m').Value self.B = self.clampVal(form.breadth, val_min, val_max, val) qty = Units.Quantity(form.draft.text()) val_min = 0.001 val_max = self.bounds[2] / Units.Metre.Value val = qty.getValueAs('m').Value self.T = self.clampVal(form.draft, val_min, val_max, val) self.preview.update(self.L, self.B, self.T)
def save(self): """ Saves the data into ship instance. """ mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.num = self.widget(QtGui.QSpinBox, "Num") draft = Units.parseQuantity(Locale.fromString(form.draft.text())) trim = Units.parseQuantity(Locale.fromString(form.trim.text())) num = form.num.value() props = self.ship.PropertiesList try: props.index("AreaCurveDraft") except ValueError: try: tooltip = str(QtGui.QApplication.translate( "ship_areas", "Areas curve tool draft selected [m]", None)) except: tooltip = "Areas curve tool draft selected [m]" self.ship.addProperty("App::PropertyLength", "AreaCurveDraft", "Ship", tooltip) self.ship.AreaCurveDraft = draft try: props.index("AreaCurveTrim") except ValueError: try: tooltip = str(QtGui.QApplication.translate( "ship_areas", "Areas curve tool trim selected [deg]", None)) except: tooltip = "Areas curve tool trim selected [deg]" self.ship.addProperty("App::PropertyAngle", "AreaCurveTrim", "Ship", tooltip) self.ship.AreaCurveTrim = trim try: props.index("AreaCurveNum") except ValueError: try: tooltip = str(QtGui.QApplication.translate( "ship_areas", "Areas curve tool number of points", None)) except: tooltip = "Areas curve tool number of points" self.ship.addProperty("App::PropertyInteger", "AreaCurveNum", "Ship", tooltip) self.ship.AreaCurveNum = num
def prepUnitsForBattle(teamList): toRet = [] teamOn = 0 corner = 1 for team in teamList: toRet += [[team[0], []]] unitOn = 0 line = 1 #unit[3] is a list of abilities. for unit in team[1]: if unit[0] in UNITSTATS and "CLASS" in UNITSTATS[unit[0]]: c = UNITSTATS[unit[0]]["CLASS"] if corner == 1: #topLeft pos = [line * 30 - unitOn * 30, 30 + unitOn * 30] elif corner == 2: #bottomRight pos = [ CONST["BATTLESIZE"][0] - (line * 30 - unitOn * 30), CONST["BATTLESIZE"][1] - (30 + unitOn * 30) ] elif corner == 3: #topRight pos = [ CONST["BATTLESIZE"][0] - (line * 30 - unitOn * 30), (30 + unitOn * 30) ] elif corner == 4: #bottomLeft pos = [(line * 30 - unitOn * 30), CONST["BATTLESIZE"][1] - (30 + unitOn * 30)] if c == "Tank": newUnit = Units.Warrior(pos, unit[0], unit[1], unit[2], unit[3]) elif c == "Heal": newUnit = Units.Healer(pos, unit[0], unit[1], unit[2], unit[3]) elif c == "Ranger": newUnit = Units.Ranger(pos, unit[0], unit[1], unit[2], unit[3]) elif c == "Egg": newUnit = Units.Egg(pos, unit[0], unit[1], unit[2], unit[3]) else: print "NOT IMPLEMENTED: unit AI of '" + c + "'" newUnit = Units.NoAI(pos, unit[0], unit[1], unit[2], unit[3]) toRet[teamOn][1] += [newUnit] unitOn += 1 if unitOn >= line: line += 1 unitOn = 0 else: print "Error creating unit '" + unit[ 0] + "'. It is not in UNITSTATS" teamOn += 1 corner += 1 return toRet
def _getAreaMass(self, fp, shape): """Compute the mass of an area element. Position arguments: fp -- Part::FeaturePython object affected. shape -- Face shape object. """ rho = Units.parseQuantity('{0} kg/m^2'.format(fp.AreaDens)) a = Units.Quantity(shape.Area, Units.Area) return rho * a
def _getLinearMass(self, fp, shape): """Compute the mass of a linear element. Position arguments: fp -- Part::FeaturePython object affected. shape -- Edge shape object. """ rho = Units.parseQuantity('{0} kg/m'.format(fp.LineDens)) l = Units.Quantity(shape.Length, Units.Length) return rho * l
def recruit_unit(self, n): if n == 0: unit = Units.Infantry(self.current_player) elif n == 1: unit = Units.Tank(self.current_player) if self.current_player not in self.purchases: self.purchases[self.current_player] = [] self.purchases[self.current_player].append(unit)
def _getVolumetricMass(self, fp, shape): """Compute the mass of a volumetric element. Position arguments: fp -- Part::FeaturePython object affected. shape -- Solid shape object. """ rho = Units.parseQuantity('{0} kg/m^3'.format(fp.Dens)) v = Units.Quantity(shape.Volume, Units.Volume) return rho * v
def __init__(self, activity_type): self.is_foot_based_activity = activity_type in Keys.FOOT_BASED_ACTIVITIES if self.is_foot_based_activity: self.key = Keys.STEPS_PER_MINUTE self.units = Units.get_running_cadence_units_str() else: self.key = Keys.APP_CADENCE_KEY self.units = Units.get_cadence_units_str() SensorAnalyzer.SensorAnalyzer.__init__(self, self.key, self.units, activity_type)
def solve(ship, weights, tanks, rolls, var_trim=True): """Compute the ship GZ stability curve Position arguments: ship -- Ship object weights -- List of weights to consider tanks -- List of tanks to consider (each one should be a tuple with the tank instance, the density of the fluid inside, and the filling level ratio) rolls -- List of roll angles Keyword arguments: var_trim -- True if the equilibrium trim should be computed for each roll angle, False if null trim angle can be used instead. Returned value: List of GZ curve points. Each point contains the GZ stability length, the equilibrium draft, and the equilibrium trim angle (0 deg if var_trim is False) """ # Get the unloaded weight (ignoring the tanks for the moment). W = Units.parseQuantity("0 kg") mom_x = Units.parseQuantity("0 kg*m") mom_y = Units.parseQuantity("0 kg*m") mom_z = Units.parseQuantity("0 kg*m") for w in weights: W += w.Proxy.getMass(w) m = w.Proxy.getMoment(w) mom_x += m[0] mom_y += m[1] mom_z += m[2] COG = Vector(mom_x / W, mom_y / W, mom_z / W) W = W * G # Get the tanks weight TW = Units.parseQuantity("0 kg") VOLS = [] for t in tanks: # t[0] = tank object # t[1] = load density # t[2] = filling level vol = t[0].Proxy.getVolume(t[0], t[2]) VOLS.append(vol) TW += vol * t[1] TW = TW * G points = [] for i,roll in enumerate(rolls): App.Console.PrintMessage("{0} / {1}\n".format(i + 1, len(rolls))) point = solve_point(W, COG, TW, VOLS, ship, tanks, roll, var_trim) if point is None: return [] points.append(point) return points
def __init__(self,game,f): self.dieties = dict([(i,Diety.Computer(game)) for i in Diety.RACE]) self.game = game self.Units = Units # an ugly hack to avoid circular imports Units.generateUnits() self.U=self.Units.U self.L = [[None]*self.HEIGHT for dummy in xrange(self.WIDTH)] self.M = [(x,y) for y in xrange(self.HEIGHT) for x in xrange(self.WIDTH)] if f: self.load(f)
def PlayGame(fileNum): MG = Game.MainGame() if FORCERELOAD or "-r" in sys.argv: units = [Units.PlayerUnit("asdf", 1)] if NUMPLAYERS == 2: units += [Units.PlayerUnit("asdf2", 1)] MG.playStreamingGame(units) else: units = [pickle.load(open(os.path.join("Profiles", "asdf.prof")))] if NUMPLAYERS == 2: units += [pickle.load(open(os.path.join("Profiles", "asdf2.prof")))] MG.playStreamingGame(units)
def _getPuntualMoment(self, fp, shape): """Compute the moment of a puntual element (respect to 0, 0, 0). Position arguments: fp -- Part::FeaturePython object affected. shape -- Vertex shape object. """ m = self._getPuntualMass(fp, shape) x = Units.Quantity(shape.X, Units.Length) y = Units.Quantity(shape.Y, Units.Length) z = Units.Quantity(shape.Z, Units.Length) return (m * x, m * y, m * z)
def proximityCorrection(self, uList=[], uList2=[]): for uIndex in range(len(uList)): for uIndex2 in range(len(uList)): if uIndex != uIndex2: if Units.getDist(uList[uIndex], uList[uIndex2]) <= 8: uList[uIndex].x += randint(0, 2) - 1 uList[uIndex].y += randint(0, 2) - 1 for uIndex in range(len(uList2)): for uIndex2 in range(len(uList2)): if uIndex != uIndex2: if Units.getDist(uList2[uIndex], uList2[uIndex2]) <= 8: uList2[uIndex].x += randint(0, 2) - 1 uList2[uIndex].y += randint(0, 2) - 1
def _getAreaMoment(self, fp, shape): """Compute the mass of an area element (respect to 0, 0, 0). Keyword arguments: fp -- Part::FeaturePython object affected. shape -- Face shape object. """ m = self._getAreaMass(fp, shape) cog = shape.CenterOfMass x = Units.Quantity(cog.x, Units.Length) y = Units.Quantity(cog.y, Units.Length) z = Units.Quantity(cog.z, Units.Length) return (m * x, m * y, m * z)
def _getVolumetricMoment(self, fp, shape): """Compute the mass of a volumetric element (respect to 0, 0, 0). Position arguments: fp -- Part::FeaturePython object affected. shape -- Solid shape object. """ m = self._getVolumetricMass(fp, shape) cog = shape.CenterOfMass x = Units.Quantity(cog.x, Units.Length) y = Units.Quantity(cog.y, Units.Length) z = Units.Quantity(cog.z, Units.Length) return (m * x, m * y, m * z)
def floatingArea(ship, draft=None, roll=Units.parseQuantity("0 deg"), trim=Units.parseQuantity("0 deg")): """Compute the ship floating area Position arguments: ship -- Ship object (see createShip) Keyword arguments: draft -- Ship draft (Design ship draft by default) roll -- Roll angle (0 degrees by default) trim -- Trim angle (0 degrees by default) Returned values: area -- Ship floating area cf -- Floating area coefficient """ if draft is None: draft = ship.Draft # We wanna intersect the whole ship with the free surface, so in this case # we must not use the underwater side (or the tool will fail) shape, _ = placeShipShape(ship.Shape.copy(), draft, roll, trim) try: f = Part.Face(shape.slice(Vector(0,0,1), 0.0)) area = Units.Quantity(f.Area, Units.Area) except Part.OCCError: msg = QtGui.QApplication.translate( "ship_console", "Part.OCCError: Floating area cannot be computed", None, QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') area = Units.Quantity(0.0, Units.Area) bbox = shape.BoundBox Area = (bbox.XMax - bbox.XMin) * (bbox.YMax - bbox.YMin) try: cf = area.Value / Area except ZeroDivisionError: msg = QtGui.QApplication.translate( "ship_console", "ZeroDivisionError: Null area found during the floating area" " computation!", None, QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') cf = 0.0 return area, cf
def mainFrameCoeff(ship, draft=None): """Compute the main frame coefficient Position arguments: ship -- Ship object (see createShip) Keyword arguments: draft -- Ship draft (Design ship draft by default) Returned value: Ship main frame area coefficient """ if draft is None: draft = ship.Draft shape, _ = placeShipShape(ship.Shape.copy(), draft, Units.parseQuantity("0 deg"), Units.parseQuantity("0 deg")) shape = getUnderwaterSide(shape) try: f = Part.Face(shape.slice(Vector(1,0,0), 0.0)) area = f.Area except Part.OCCError: msg = QtGui.QApplication.translate( "ship_console", "Part.OCCError: Main frame area cannot be computed", None, QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') area = 0.0 bbox = shape.BoundBox Area = (bbox.YMax - bbox.YMin) * (bbox.ZMax - bbox.ZMin) try: cm = area / Area except ZeroDivisionError: msg = QtGui.QApplication.translate( "ship_console", "ZeroDivisionError: Null area found during the main frame area" " coefficient computation!", None, QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') cm = 0.0 return cm
def floatingArea(ship, draft=None, roll=Units.parseQuantity("0 deg"), trim=Units.parseQuantity("0 deg")): """Compute the ship floating area Position arguments: ship -- Ship object (see createShip) Keyword arguments: draft -- Ship draft (Design ship draft by default) roll -- Roll angle (0 degrees by default) trim -- Trim angle (0 degrees by default) Returned values: area -- Ship floating area cf -- Floating area coefficient """ if draft is None: draft = ship.Draft # We want to intersect the whole ship with the free surface, so in this case # we must not use the underwater side (or the tool will fail) shape, _ = placeShipShape(ship.Shape.copy(), draft, roll, trim) try: f = Part.Face(shape.slice(Vector(0, 0, 1), 0.0)) area = Units.Quantity(f.Area, Units.Area) except Part.OCCError: msg = QtGui.QApplication.translate( "ship_console", "Part.OCCError: Floating area cannot be computed", None) App.Console.PrintError(msg + '\n') area = Units.Quantity(0.0, Units.Area) bbox = shape.BoundBox Area = (bbox.XMax - bbox.XMin) * (bbox.YMax - bbox.YMin) try: cf = area.Value / Area except ZeroDivisionError: msg = QtGui.QApplication.translate( "ship_console", "ZeroDivisionError: Null area found during the floating area" " computation!", None) App.Console.PrintError(msg + '\n') cf = 0.0 return area, cf
def processFluidProperties(self): # self.material_obj stores everything as a string for compatibility with FreeCAD material objects. # Convert to SI numbers settings = self.settings for material_obj in self.material_objs: mp = {} mp['Name'] = material_obj.Label mp['Density'] = \ Units.Quantity(material_obj.Material['Density']).getValueAs("kg/m^3").Value if self.physics_model['Turbulence'] == 'Inviscid': mp['DynamicViscosity'] = 0.0 else: mp['DynamicViscosity'] = \ Units.Quantity(material_obj.Material['DynamicViscosity']).getValueAs("kg/m/s").Value mp['KinematicViscosity'] = mp['DynamicViscosity'] / mp['Density'] settings['fluidProperties'].append(mp)
def turn(gc, unit): # t = time.time() result = Units.shoot_at_best_target(gc, unit) # Globals.ranger_find_time += time.time() - t # print("find target time", Globals.ranger_find_time) if isinstance(result, bc.Unit): return elif isinstance(result, bc.VecUnit): nearby_enemies = result else: nearby_enemies = send_radar_info(unit, gc) # t = time.time() if gc.is_move_ready(unit.id): e, should_retreat = ranger_retreat(unit, nearby_enemies) if should_retreat: moved = Navigation.retreatFromKnownEnemy(gc, unit, Globals.radar.get_enemy_center(unit.location.map_location().planet)) if moved: return if gc.is_attack_ready(unit.id): planet = unit.location.map_location().planet path = Globals.updatePath if planet == bc.Planet.Earth else Globals.updatePathMars Navigation.path_with_bfs(gc, unit, path) # Globals.ranger_else_time += time.time() - t # print("other ranger time", Globals.ranger_else_time) return
def pr_changed(self, value): import Units old_pr = Units.Quantity(self.obj.Material['PoissonRatio']) if old_pr != value: material = self.obj.Material material['PoissonRatio'] = unicode(value) self.obj.Material = material
def __init__(self, parent, ft_parameter): ViewFrame.__init__(self, parent) ft_parameter.add_view(self) self.flag_var = IntVar() self.flag_var.trace('w', self.flag_changed) cbf = Checkbutton(self, text=ft_parameter.label + ":", font=Layout.params.entry_label_font, variable=self.flag_var) cbf.sticky = 'w' eiv = self.init_value_view = \ NumberView(self, ft_parameter.initial_value, format="unlimited") eiv.sticky = 'ew' muv = Units.UnitView(self, ft_parameter.unit) bfb = Button(self, text="<<", padx=0, pady=1, command=self.feed_back) efv = self.fitted_value_box = \ NumberView(self, ft_parameter.fitted_value, readonly = 1) ese = self.std_err_box = \ NumberView(self, ft_parameter.standard_error, readonly = 1) self.columnconfigure(0, minsize=90) # check box self.columnconfigure(2, minsize=25) # measurement unit self.columnconfigure(3, minsize=30) # feedback button self.columnconfigure( 5, minsize=14) # space between fitted value & stderror grid([cbf, eiv, muv, bfb, efv, 0, ese]) self.update()
def drawHUD(self, unitOn, camera): HEALTHSIZE = 100 unit = PTRS["UNITS"].alliedUnits[unitOn] if unit: if unit.getTargetHealth() > 0 or unit.getHealth() > 0: healthBarRect = [[10, camera.Height() - 20], [HEALTHSIZE, 12]] expBarRect = [[10, camera.Height() - 40], [HEALTHSIZE, 12]] self.drawStatusBar(unit, camera, unit.getHealth(), unit.getTargetHealth(), unit.getMaxHealth(), healthBarRect, [255, 0, 0], [0, 255, 0], [155, 0, 0]) self.drawStatusBar(unit, camera, unit.guilds.getActiveGuild().experience, unit.guilds.getActiveGuild().targetExperience, unit.guilds.getActiveGuild().getExperienceRequirement(), expBarRect, EXPERIENCECOLOUR, DARKEXPERIENCECOLOUR, [255, 255, 255]) for i in range(ABILITYSLOTS): abil = unit.getSelectedAbil(i) if abil: icon = abil.icon if i == unit.selectedAbil: frameIcon = "SelectedFrame" else: frameIcon = "BattleFrame" pos = (5 + i * 45, 5) if abil.cooldown[0] > 0: drawAbilIcon(camera.getSurface(), pos, icon, frameIcon, abil.cooldown[0] / float(abil.cooldown[1])) else: drawAbilIcon(camera.getSurface(), pos, icon, frameIcon) if unit.lastHitTargets: on = len(unit.lastHitTargets) done = 0 for u in unit.lastHitTargets: if not u.isTrainingDummy(): pos = [camera.Width() - HEALTHSIZE - 10, camera.Height() - 20 - done * 15] hPct = u.getHealth() / float(u.getMaxHealth()) hAmt = min(max(int(HEALTHSIZE * hPct), 1), HEALTHSIZE) clr = [150, 0, 0] if u == unit.target: clr = [255, 0, 0] pygame.draw.rect(camera.getSurface(), clr, [pos, [hAmt, 10]]) #Bright red health pygame.draw.rect(camera.getSurface(), [255] * 3, [pos, [HEALTHSIZE, 10]], 1) if unit.team == 1: Units.drawEnemyPic(camera.getSurface(), u.picture, [pos[0] - 15, pos[1]], int(u.animationFrames[int(u.frame)])) on -= 1 done += 1 if done > 5: break
def _getPuntualMass(self, fp, shape): """Compute the mass of a puntual element. Position arguments: fp -- Part::FeaturePython object affected. shape -- Vertex shape object. """ return Units.parseQuantity('{0} kg'.format(fp.Mass))
def onUpdate(self): """ Method called when the data update is requested. """ if not self.ship: return mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.output = self.widget(QtGui.QTextEdit, "OutputData") draft = Units.parseQuantity(Locale.fromString(form.draft.text())) trim = Units.parseQuantity(Locale.fromString(form.trim.text())) # Calculate the drafts at each perpendicular angle = trim.getValueAs("rad").Value L = self.ship.Length.getValueAs('m').Value B = self.ship.Breadth.getValueAs('m').Value draftAP = draft + 0.5 * self.ship.Length * math.tan(angle) if draftAP < 0.0: draftAP = 0.0 draftFP = draft - 0.5 * self.ship.Length * math.tan(angle) if draftFP < 0.0: draftFP = 0.0 # Calculate the involved hydrostatics disp, B, _ = Hydrostatics.displacement(self.ship, draft, Units.parseQuantity("0 deg"), trim) xcb = Units.Quantity(B.x, Units.Length) # Setup the html string string = u'L = {0}<BR>'.format(self.ship.Length.UserString) string += u'B = {0}<BR>'.format(self.ship.Breadth.UserString) string += u'T = {0}<HR>'.format(draft.UserString) string += u'Trim = {0}<BR>'.format(trim.UserString) string += u'T<sub>AP</sub> = {0}<BR>'.format(draftAP.UserString) string += u'T<sub>FP</sub> = {0}<HR>'.format(draftFP.UserString) dispText = QtGui.QApplication.translate( "ship_areas", 'Displacement', None, QtGui.QApplication.UnicodeUTF8) string += dispText + u' = {0}<BR>'.format(disp.UserString) string += u'XCB = {0}'.format(xcb.UserString) form.output.setHtml(string)
def accept(self): """Create the ship instance""" mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.ship = self.widget(QtGui.QComboBox, "Ship") form.weight = self.widget(QtGui.QLineEdit, "Weight") ship = self.ships[form.ship.currentIndex()] density = Units.parseQuantity(Locale.fromString(form.weight.text())) Tools.createWeight(self.shapes, ship, density) return True
def wettedArea(shape, draft, roll=Units.parseQuantity("0 deg"), trim=Units.parseQuantity("0 deg")): """Compute the ship wetted area Position arguments: shape -- External faces of the ship hull draft -- Ship draft Keyword arguments: roll -- Roll angle (0 degrees by default) trim -- Trim angle (0 degrees by default) Returned value: The wetted area, i.e. The underwater side area """ shape, _ = placeShipShape(shape.copy(), draft, roll, trim) shape = getUnderwaterSide(shape, force=False) area = 0.0 for f in shape.Faces: area = area + f.Area return Units.Quantity(area, Units.Area)
def BMT(ship, draft=None, trim=Units.parseQuantity("0 deg")): """Calculate "ship Bouyance center" - "transversal metacenter" radius Position arguments: ship -- Ship object (see createShip) Keyword arguments: draft -- Ship draft (Design ship draft by default) trim -- Trim angle (0 degrees by default) Returned value: BMT radius """ if draft is None: draft = ship.Draft roll = Units.parseQuantity("0 deg") _, B0, _ = displacement(ship, draft, roll, trim) nRoll = 2 maxRoll = Units.parseQuantity("7 deg") BM = 0.0 for i in range(nRoll): roll = (maxRoll / nRoll) * (i + 1) _, B1, _ = displacement(ship, draft, roll, trim) # * M # / \ # / \ BM ==|> BM = (BB/2) / sin(alpha/2) # / \ # *-------* # BB BB = B1 - B0 BB.x = 0.0 # nRoll is actually representing the weight function BM += 0.5 * BB.Length / math.sin(math.radians(0.5 * roll)) / nRoll return Units.Quantity(BM, Units.Length)
def generateParametersAndState(airports, entry): # TODO (niwang) # airports: a dict of AirportID to Airport object # the original list of Airport is a tuple of Airport and Environment, now we only keep # the Airport Object # entry: FlightEntry aircraftType = Aircraft.mediumRange departureAirport = airports[entry.DepartureAirport] #['Airport.Code'] arrivalAirport = airports[entry.ArrivalAirport] #['Airport.Code'] timeElapsed = Units.timeDifference(0.0, entry.ActualGateDepartureTime) maximumFuel = Units.fuelGallonsToFuelPounds(aircraftType.FuelCapacity) initialFuel = entry.InitialFuel fuelConsumed = entry.ConsumedFuel flightParameters = FlightParameters( entry.Id, 'Eastbound' if departureAirport.Position.PositionX < \ arrivalAirport.Position.PositionX else 'Westbound', aircraftType, arrivalAirport, entry.Payload, initialFuel, entry.ScheduledGateDepartureTime, entry.ActualGateDepartureTime, entry.ScheduledGateArrivalTime, entry.ScheduledRunwayArrivalTime) flightState = FlightState( entry.Position, 0.0, 0.0, timeElapsed, fuelConsumed, Airspace.emptyIntersection, 0.0, []) return (flightParameters, flightState)
def setFillingLevel(self, fp, level): """Compute the mass of the object, already taking into account the type of subentities. Keyword arguments: fp -- Part::FeaturePython object affected. level -- Percentage of filling level (from 0 to 100). """ shape = fp.Shape solids = shape.Solids # Get the cutting box bbox = shape.BoundBox z_min = bbox.ZMin z_max = bbox.ZMax dx = bbox.XMax - bbox.XMin dy = bbox.YMax - bbox.YMin dz = level / 100.0 * (z_max - z_min) z = z_min + dz try: box = Part.makeBox( 3.0 * dx, 3.0 * dy, (z_max - z_min) + dz, Vector(bbox.XMin - dx, bbox.YMin - dy, bbox.ZMin - (z_max - z_min)), ) except: fp.Vol = 0.0 return Units.parseQuantity("0 m^3") # Start computing the common part of each solid component with the # cutting box, adding the volume vol = 0.0 for s in solids: try: fluid = s.common(box) v = fluid.Volume except: v = 0.0 vol += v # Get the volume quantity and store it with the right units vol = Units.Quantity(vol, Units.Volume) fp.Vol = vol.getValueAs("m^3").Value return vol
def getMass(self, fp): """Compute the mass of the object, already taking into account the type of subentities. Keyword arguments: fp -- Part::FeaturePython object affected. """ m = Units.parseQuantity('0 kg') for s in fp.Shape.Solids: m = m + self._getVolumetricMass(fp, s) for f in fp.Shape.Faces: m = m + self._getAreaMass(fp, f) for e in fp.Shape.Edges: m = m + self._getLinearMass(fp, e) for v in fp.Shape.Vertexes: m = m + self._getPuntualMass(fp, v) return m
def accept(self): """Create the ship instance""" mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.ship = self.widget(QtGui.QComboBox, "Ship") form.weight = self.widget(QtGui.QLineEdit, "Weight") # Create the object ship = self.ships[form.ship.currentIndex()] obj = App.ActiveDocument.addObject("Part::FeaturePython", "Weight") weight = Instance.Weight(obj, self.shapes, ship) Instance.ViewProviderWeight(obj.ViewObject) # Set the mass/density m_unit = USys.getMassUnits() l_unit = USys.getLengthUnits() qty = Units.parseQuantity(form.weight.text()) if self.elem_type == 1: w_unit = m_unit obj.Mass = qty.getValueAs(w_unit).Value elif self.elem_type == 2: w_unit = m_unit + '/' + l_unit obj.LineDens = qty.getValueAs(w_unit).Value elif self.elem_type == 3: w_unit = m_unit + '/' + l_unit + '^2' obj.AreaDens = qty.getValueAs(w_unit).Value elif self.elem_type == 4: w_unit = m_unit + '/' + l_unit + '^3' obj.Dens = qty.getValueAs(w_unit).Value # Set it as a child of the ship weights = ship.Weights[:] weights.append(obj.Name) ship.Weights = weights App.ActiveDocument.recompute() return True
def _boundLongitude (angle): return Units.boundAngle(angle) * 1.0 # <Longitude>
#*************************************************************************** import math import random from FreeCAD import Vector, Rotation, Matrix, Placement import Part import Units import FreeCAD as App import FreeCADGui as Gui from PySide import QtGui, QtCore import Instance from shipUtils import Math import shipUtils.Units as USys DENS = Units.parseQuantity("1025 kg/m^3") # Salt water COMMON_BOOLEAN_ITERATIONS = 10 def placeShipShape(shape, draft, roll, trim): """Move the ship shape such that the free surface matches with the plane z=0. The transformation will be applied on the input shape, so copy it before calling this method if it should be preserved. Position arguments: shape -- Ship shape draft -- Ship draft roll -- Roll angle trim -- Trim angle Returned values:
def displacement(ship, draft=None, roll=Units.parseQuantity("0 deg"), trim=Units.parseQuantity("0 deg")): """Compute the ship displacement Position arguments: ship -- Ship object (see createShip) Keyword arguments: draft -- Ship draft (Design ship draft by default) roll -- Roll angle (0 degrees by default) trim -- Trim angle (0 degrees by default) Returned values: disp -- The ship displacement (a density of the water of 1025 kg/m^3 is assumed) B -- Bouyance application point, i.e. Center of mass of the underwater side Cb -- Block coefficient The Bouyance center is refered to the original ship position. """ if draft is None: draft = ship.Draft shape, base_z = placeShipShape(ship.Shape.copy(), draft, roll, trim) shape = getUnderwaterSide(shape) vol = 0.0 cog = Vector() if len(shape.Solids) > 0: for solid in shape.Solids: vol += solid.Volume sCoG = solid.CenterOfMass cog.x = cog.x + sCoG.x * solid.Volume cog.y = cog.y + sCoG.y * solid.Volume cog.z = cog.z + sCoG.z * solid.Volume cog.x = cog.x / vol cog.y = cog.y / vol cog.z = cog.z / vol bbox = shape.BoundBox Vol = (bbox.XMax - bbox.XMin) * (bbox.YMax - bbox.YMin) * abs(bbox.ZMin) # Undo the transformations on the bouyance point B = Part.Point(Vector(cog.x, cog.y, cog.z)) m = Matrix() m.move(Vector(0.0, 0.0, draft)) m.move(Vector(-draft * math.sin(trim.getValueAs("rad")), 0.0, 0.0)) m.rotateY(trim.getValueAs("rad")) m.move(Vector(0.0, -draft * math.sin(roll.getValueAs("rad")), base_z)) m.rotateX(-roll.getValueAs("rad")) B.transform(m) try: cb = vol / Vol except ZeroDivisionError: msg = QtGui.QApplication.translate( "ship_console", "ZeroDivisionError: Null volume found during the displacement" " computation!", None, QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') cb = 0.0 # Return the computed data return (DENS * Units.Quantity(vol, Units.Volume), Vector(B.X, B.Y, B.Z), cb)
def areas(ship, n, draft=None, roll=Units.parseQuantity("0 deg"), trim=Units.parseQuantity("0 deg")): """Compute the ship transversal areas Position arguments: ship -- Ship object (see createShip) n -- Number of points to compute Keyword arguments: draft -- Ship draft (Design ship draft by default) roll -- Roll angle (0 degrees by default) trim -- Trim angle (0 degrees by default) Returned value: List of sections, each section contains 2 values, the x longitudinal coordinate, and the transversal area. If n < 2, an empty list will be returned. """ if n < 2: return [] if draft is None: draft = ship.Draft shape, _ = placeShipShape(ship.Shape.copy(), draft, roll, trim) shape = getUnderwaterSide(shape) # Sections distance computation bbox = shape.BoundBox xmin = bbox.XMin xmax = bbox.XMax dx = (xmax - xmin) / (n - 1.0) # Since we are computing the sections in the total length (not in the # length between perpendiculars), we can grant that the starting and # ending sections have null area areas = [(Units.Quantity(xmin, Units.Length), Units.Quantity(0.0, Units.Area))] # And since we just need to compute areas we will create boxes with its # front face at the desired transversal area position, computing the # common solid part, dividing it by faces, and getting only the desired # ones. App.Console.PrintMessage("Computing transversal areas...\n") App.Console.PrintMessage("Some Inventor representation errors can be" " shown, please ignore them.\n") for i in range(1, n - 1): App.Console.PrintMessage("{0} / {1}\n".format(i, n - 2)) x = xmin + i * dx try: f = Part.Face(shape.slice(Vector(1,0,0), x)) except Part.OCCError: msg = QtGui.QApplication.translate( "ship_console", "Part.OCCError: Transversal area computation failed", None, QtGui.QApplication.UnicodeUTF8) App.Console.PrintError(msg + '\n') areas.append((Units.Quantity(x, Units.Length), Units.Quantity(0.0, Units.Area))) continue # It is a valid face, so we can add this area areas.append((Units.Quantity(x, Units.Length), Units.Quantity(f.Area, Units.Area))) # Last area is equal to zero (due to the total length usage) areas.append((Units.Quantity(xmax, Units.Length), Units.Quantity(0.0, Units.Area))) App.Console.PrintMessage("Done!\n") return areas
def solve_point(W, COG, TW, VOLS, ship, tanks, roll, var_trim=True): """ Compute the ship GZ value. @param W Empty ship weight. @param COG Empty ship Center of mass. @param TW Tanks weights. @param VOLS List of tank volumes. @param tanks Considered tanks. @param roll Roll angle. @param var_trim True if the trim angle should be recomputed at each roll angle, False otherwise. @return GZ value, equilibrium draft, and equilibrium trim angle (0 if variable trim has not been requested) """ # Look for the equilibrium draft (and eventually the trim angle too) max_draft = Units.Quantity(ship.Shape.BoundBox.ZMax, Units.Length) draft = ship.Draft max_disp = Units.Quantity(ship.Shape.Volume, Units.Volume) * DENS * G if max_disp < W + TW: msg = QtGui.QApplication.translate( "ship_console", "Too much weight! The ship will never displace water enough", None) App.Console.PrintError(msg + ' ({} vs. {})\n'.format( (max_disp / G).UserString, ((W + TW) / G).UserString)) return None trim = Units.parseQuantity("0 deg") for i in range(MAX_EQUILIBRIUM_ITERS): # Get the displacement, and the bouyance application point disp, B, _ = Hydrostatics.displacement(ship, draft, roll, trim) disp *= G # Add the tanks effect on the center of gravity mom_x = Units.Quantity(COG.x, Units.Length) * W mom_y = Units.Quantity(COG.y, Units.Length) * W mom_z = Units.Quantity(COG.z, Units.Length) * W for i,t in enumerate(tanks): tank_weight = VOLS[i] * t[1] * G tank_cog = t[0].Proxy.getCoG(t[0], VOLS[i], roll, trim) mom_x += Units.Quantity(tank_cog.x, Units.Length) * tank_weight mom_y += Units.Quantity(tank_cog.y, Units.Length) * tank_weight mom_z += Units.Quantity(tank_cog.z, Units.Length) * tank_weight cog_x = mom_x / (W + TW) cog_y = mom_y / (W + TW) cog_z = mom_z / (W + TW) # Compute the errors draft_error = -((disp - W - TW) / max_disp).Value R_x = cog_x - Units.Quantity(B.x, Units.Length) R_y = cog_y - Units.Quantity(B.y, Units.Length) R_z = cog_z - Units.Quantity(B.z, Units.Length) if not var_trim: trim_error = 0.0 else: trim_error = -TRIM_RELAX_FACTOR * R_x / ship.Length # Check if we can tolerate the errors if abs(draft_error) < 0.01 and abs(trim_error) < 0.1: break # Get the new draft and trim draft += draft_error * max_draft trim += trim_error * Units.Degree # GZ should be provided in the Free surface oriented frame of reference c = math.cos(roll.getValueAs('rad')) s = math.sin(roll.getValueAs('rad')) return c * R_y - s * R_z, draft, trim