protected override void WindowGUI(int windowID) { GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); GUILayout.Label("Name", GUILayout.ExpandWidth(true)); GUILayout.Label("Orbiting", GUILayout.ExpandWidth(true)); GUILayout.Label("Orbital Speed", GUILayout.ExpandWidth(true)); GUILayout.Label("Apoapsis", GUILayout.ExpandWidth(true)); GUILayout.Label("Periapsis", GUILayout.ExpandWidth(true)); GUILayout.Label("Period", GUILayout.ExpandWidth(true)); GUILayout.Label("Time to Apoapsis", GUILayout.ExpandWidth(true)); GUILayout.Label("Time to Periapsis", GUILayout.ExpandWidth(true)); GUILayout.Label("LAN", GUILayout.ExpandWidth(true)); GUILayout.Label("LPe", GUILayout.ExpandWidth(true)); GUILayout.Label("Inclination", GUILayout.ExpandWidth(true)); GUILayout.Label("Eccentricity", GUILayout.ExpandWidth(true)); GUILayout.Label("Semimajor Axis", GUILayout.ExpandWidth(true)); GUILayout.Label(showingRetrograde ? "Angle to Retrograde" : "Angle to Prograde", GUILayout.ExpandWidth(true)); if ((Event.current.type == EventType.repaint) && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) && Input.GetMouseButtonDown(0)) { showingRetrograde = !showingRetrograde; } GUILayout.EndVertical(); GUILayout.BeginVertical(); if (part.vessel.vesselName.Length > 10) { GUILayout.Label(part.vessel.vesselName.Remove(10), GUILayout.ExpandWidth(true)); } else { GUILayout.Label(part.vessel.vesselName, GUILayout.ExpandWidth(true)); } GUILayout.Label(part.vessel.orbit.referenceBody.name); GUILayout.Label(MuUtils.ToSI(vesselState.speedOrbital) + "m/s"); GUILayout.Label(MuUtils.ToSI(vesselState.orbitApA) + "m"); GUILayout.Label(MuUtils.ToSI(vesselState.orbitPeA) + "m"); GUILayout.Label(MuUtils.ToSI(vesselState.orbitPeriod) + "s"); GUILayout.Label(MuUtils.ToSI(vesselState.orbitTimeToAp) + "s"); GUILayout.Label(MuUtils.ToSI(vesselState.orbitTimeToPe) + "s"); GUILayout.Label(vesselState.orbitLAN.ToString("F6") + "°"); GUILayout.Label(((vesselState.orbitLAN + vesselState.orbitArgumentOfPeriapsis) % 360.0).ToString("F6") + "°"); GUILayout.Label(vesselState.orbitInclination.ToString("F6") + "°"); GUILayout.Label(vesselState.orbitEccentricity.ToString("F6")); GUILayout.Label(MuUtils.ToSI(vesselState.orbitSemiMajorAxis) + "m"); GUILayout.Label(ARUtils.clampDegrees360(vesselState.angleToPrograde + (showingRetrograde?180:0)).ToString("F3") + "°"); GUILayout.EndVertical(); if (core.targetType != MechJebCore.TargetType.NONE) { GUILayout.BeginVertical(); if (core.targetName().Length > 10) { GUILayout.Label(core.targetName().Remove(10), GUILayout.ExpandWidth(true)); } else { GUILayout.Label(core.targetName(), GUILayout.ExpandWidth(true)); } GUILayout.Label(core.targetOrbit().referenceBody.name); GUILayout.Label(MuUtils.ToSI(core.targetOrbit().GetVel().magnitude) + "m/s"); GUILayout.Label(MuUtils.ToSI(core.targetOrbit().ApA) + "m"); GUILayout.Label(MuUtils.ToSI(core.targetOrbit().PeA) + "m"); GUILayout.Label(MuUtils.ToSI(core.targetOrbit().period) + "s"); GUILayout.Label(MuUtils.ToSI(core.targetOrbit().timeToAp) + "s"); GUILayout.Label(MuUtils.ToSI(core.targetOrbit().timeToPe) + "s"); GUILayout.Label(core.targetOrbit().LAN.ToString("F6") + "°"); GUILayout.Label(((core.targetOrbit().LAN + core.targetOrbit().argumentOfPeriapsis) % 360.0).ToString("F6") + "°"); GUILayout.Label(core.targetOrbit().inclination.ToString("F6") + "°"); GUILayout.Label(core.targetOrbit().eccentricity.ToString("F6")); GUILayout.Label(MuUtils.ToSI(core.targetOrbit().semiMajorAxis) + "m"); GUILayout.Label(""); GUILayout.EndVertical(); } GUILayout.EndHorizontal(); base.WindowGUI(windowID); }
public void Update(Vessel vessel) { time = Planetarium.GetUniversalTime(); deltaT = TimeWarp.fixedDeltaTime; CoM = vessel.findWorldCenterOfMass(); up = (CoM - vessel.mainBody.position).normalized; north = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - CoM).normalized; east = vessel.mainBody.getRFrmVel(CoM).normalized; forward = vessel.transform.up; rotationSurface = Quaternion.LookRotation(north, up); rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.transform.rotation) * rotationSurface); velocityVesselOrbit = vessel.orbit.GetVel(); velocityVesselOrbitUnit = velocityVesselOrbit.normalized; velocityVesselSurface = velocityVesselOrbit - vessel.mainBody.getRFrmVel(CoM); velocityVesselSurfaceUnit = velocityVesselSurface.normalized; velocityMainBodySurface = rotationSurface * velocityVesselSurface; angularVelocity = Quaternion.Inverse(vessel.transform.rotation) * vessel.rigidbody.angularVelocity; upNormalToVelSurface = Vector3d.Exclude(velocityVesselSurfaceUnit, up).normalized; upNormalToVelOrbit = Vector3d.Exclude(velocityVesselOrbit, up).normalized; leftSurface = -Vector3d.Cross(upNormalToVelSurface, velocityVesselSurfaceUnit); leftOrbit = -Vector3d.Cross(upNormalToVelOrbit, velocityVesselOrbitUnit);; gravityForce = FlightGlobals.getGeeForceAtPosition(CoM); localg = gravityForce.magnitude; speedOrbital.value = velocityVesselOrbit.magnitude; speedSurface.value = velocityVesselSurface.magnitude; speedVertical.value = Vector3d.Dot(velocityVesselSurface, up); speedHorizontal.value = (velocityVesselSurface - (speedVertical * up)).magnitude; vesselHeading.value = rotationVesselSurface.eulerAngles.y; vesselPitch.value = (rotationVesselSurface.eulerAngles.x > 180) ? (360.0 - rotationVesselSurface.eulerAngles.x) : -rotationVesselSurface.eulerAngles.x; vesselRoll.value = (rotationVesselSurface.eulerAngles.z > 180) ? (rotationVesselSurface.eulerAngles.z - 360.0) : rotationVesselSurface.eulerAngles.z; altitudeASL.value = vessel.mainBody.GetAltitude(CoM); RaycastHit sfc; if (Physics.Raycast(CoM, -up, out sfc, (float)altitudeASL + 10000.0F, 1 << 15)) { altitudeTrue.value = sfc.distance; } else if (vessel.mainBody.pqsController != null) { // from here: http://kerbalspaceprogram.com/forum/index.php?topic=10324.msg161923#msg161923 altitudeTrue.value = vessel.mainBody.GetAltitude(CoM) - (vessel.mainBody.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(vessel.mainBody.GetLongitude(CoM), Vector3d.down) * QuaternionD.AngleAxis(vessel.mainBody.GetLatitude(CoM), Vector3d.forward) * Vector3d.right) - vessel.mainBody.pqsController.radius); } else { altitudeTrue.value = vessel.mainBody.GetAltitude(CoM); } double surfaceAltitudeASL = altitudeASL - altitudeTrue; altitudeBottom = altitudeTrue; foreach (Part p in vessel.parts) { if (p.collider != null) { Vector3d bottomPoint = p.collider.ClosestPointOnBounds(vessel.mainBody.position); double partBottomAlt = vessel.mainBody.GetAltitude(bottomPoint) - surfaceAltitudeASL; altitudeBottom = Math.Max(0, Math.Min(altitudeBottom, partBottomAlt)); } } atmosphericDensity = FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(altitudeASL, vessel.mainBody)); orbitApA.value = vessel.orbit.ApA; orbitPeA.value = vessel.orbit.PeA; orbitPeriod.value = vessel.orbit.period; orbitTimeToAp.value = vessel.orbit.timeToAp; if (vessel.orbit.eccentricity < 1) { orbitTimeToPe.value = vessel.orbit.timeToPe; } else { orbitTimeToPe.value = -vessel.orbit.meanAnomaly / (2 * Math.PI / vessel.orbit.period); //orbit.timeToPe is bugged for ecc > 1 and timewarp > 2x } orbitLAN.value = vessel.orbit.LAN; orbitArgumentOfPeriapsis.value = vessel.orbit.argumentOfPeriapsis; orbitInclination.value = vessel.orbit.inclination; orbitEccentricity.value = vessel.orbit.eccentricity; orbitSemiMajorAxis.value = vessel.orbit.semiMajorAxis; latitude.value = vessel.mainBody.GetLatitude(CoM); longitude.value = ARUtils.clampDegrees(vessel.mainBody.GetLongitude(CoM)); if (vessel.mainBody != Planetarium.fetch.Sun) { Vector3d delta = vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() + 1) - vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() - 1); Vector3d plUp = Vector3d.Cross(vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime()) - vessel.mainBody.referenceBody.getPositionAtUT(Planetarium.GetUniversalTime()), vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() + vessel.mainBody.orbit.period / 4) - vessel.mainBody.referenceBody.getPositionAtUT(Planetarium.GetUniversalTime() + vessel.mainBody.orbit.period / 4)).normalized; angleToPrograde = ARUtils.clampDegrees360((((vessel.orbit.inclination > 90) || (vessel.orbit.inclination < -90)) ? 1 : -1) * ((Vector3)up).AngleInPlane(plUp, delta)); } else { angleToPrograde = 0; } radius = (CoM - vessel.mainBody.position).magnitude; mass = thrustAvailable = thrustMinimum = massDrag = torqueRAvailable = torquePYAvailable = torqueThrustPYAvailable = 0; MoI = vessel.findLocalMOI(CoM); foreach (Part p in vessel.parts) { if (p.physicalSignificance != Part.PhysicalSignificance.NONE) { mass += p.mass; massDrag += p.mass * p.maximum_drag; } MoI += p.Rigidbody.inertiaTensor; if (((p.State == PartStates.ACTIVE) || ((Staging.CurrentStage > Staging.lastStage) && (p.inverseStage == Staging.lastStage))) && ((p is LiquidEngine) || (p is LiquidFuelEngine) || (p is SolidRocket) || (p is AtmosphericEngine))) { if (p is LiquidEngine && ARUtils.engineHasFuel(p)) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((LiquidEngine)p).thrustVector).normalized, forward); thrustAvailable += ((LiquidEngine)p).maxThrust * usableFraction; thrustMinimum += ((LiquidEngine)p).minThrust * usableFraction; if (((LiquidEngine)p).thrustVectoringCapable) { torqueThrustPYAvailable += Math.Sin(Math.Abs(((LiquidEngine)p).gimbalRange) * Math.PI / 180) * ((LiquidEngine)p).maxThrust * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } } else if (p is LiquidFuelEngine && ARUtils.engineHasFuel(p)) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((LiquidFuelEngine)p).thrustVector).normalized, forward); thrustAvailable += ((LiquidFuelEngine)p).maxThrust * usableFraction; thrustMinimum += ((LiquidFuelEngine)p).minThrust * usableFraction; if (((LiquidFuelEngine)p).thrustVectoringCapable) { torqueThrustPYAvailable += Math.Sin(Math.Abs(((LiquidFuelEngine)p).gimbalRange) * Math.PI / 180) * ((LiquidFuelEngine)p).maxThrust * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } } else if (p is SolidRocket && !p.ActivatesEvenIfDisconnected) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((SolidRocket)p).thrustVector).normalized, forward); thrustAvailable += ((SolidRocket)p).thrust * usableFraction; thrustMinimum += ((SolidRocket)p).thrust * usableFraction; } else if (p is AtmosphericEngine && ARUtils.engineHasFuel(p)) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((AtmosphericEngine)p).thrustVector).normalized, forward); thrustAvailable += ((AtmosphericEngine)p).maximumEnginePower * ((AtmosphericEngine)p).totalEfficiency * usableFraction; if (((AtmosphericEngine)p).thrustVectoringCapable) { torqueThrustPYAvailable += Math.Sin(Math.Abs(((AtmosphericEngine)p).gimbalRange) * Math.PI / 180) * ((AtmosphericEngine)p).maximumEnginePower * ((AtmosphericEngine)p).totalEfficiency * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } } } if ((!FlightInputHandler.RCSLock) && (p is RCSModule)) { double maxT = 0; for (int i = 0; i < 6; i++) { if (((RCSModule)p).thrustVectors[i] != Vector3.zero) { maxT = Math.Max(maxT, ((RCSModule)p).thrusterPowers[i]); } } // torqueRAvailable += maxT; torquePYAvailable += maxT * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } if (p is CommandPod) { torqueRAvailable += Math.Abs(((CommandPod)p).rotPower); torquePYAvailable += Math.Abs(((CommandPod)p).rotPower); } } angularMomentum = new Vector3d(angularVelocity.x * MoI.x, angularVelocity.y * MoI.y, angularVelocity.z * MoI.z); maxThrustAccel = thrustAvailable / mass; minThrustAccel = thrustMinimum / mass; }
public void Update(Vessel vessel) { time = Planetarium.GetUniversalTime(); deltaT = TimeWarp.fixedDeltaTime; //Only update if (time - _updateTime < 0.25) { return; } _updateTime = time; CoM = vessel.findWorldCenterOfMass(); up = (CoM - vessel.mainBody.position).normalized; north = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - CoM).normalized; east = vessel.mainBody.getRFrmVel(CoM).normalized; forward = vessel.GetTransform().up; rotationSurface = Quaternion.LookRotation(north, up); rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface); velocityVesselOrbit = vessel.orbit.GetVel(); velocityVesselOrbitUnit = velocityVesselOrbit.normalized; velocityVesselSurface = velocityVesselOrbit - vessel.mainBody.getRFrmVel(CoM); velocityVesselSurfaceUnit = velocityVesselSurface.normalized; velocityMainBodySurface = rotationSurface * velocityVesselSurface; angularVelocity = Quaternion.Inverse(vessel.GetTransform().rotation) * vessel.rigidbody.angularVelocity; upNormalToVelSurface = Vector3d.Exclude(velocityVesselSurfaceUnit, up).normalized; upNormalToVelOrbit = Vector3d.Exclude(velocityVesselOrbit, up).normalized; leftSurface = -Vector3d.Cross(upNormalToVelSurface, velocityVesselSurfaceUnit); leftOrbit = -Vector3d.Cross(upNormalToVelOrbit, velocityVesselOrbitUnit);; gravityForce = FlightGlobals.getGeeForceAtPosition(CoM); localg = gravityForce.magnitude; speedOrbital.value = velocityVesselOrbit.magnitude; speedSurface.value = velocityVesselSurface.magnitude; speedVertical.value = Vector3d.Dot(velocityVesselSurface, up); speedHorizontal.value = (velocityVesselSurface - (speedVertical * up)).magnitude; vesselHeading.value = rotationVesselSurface.eulerAngles.y; vesselPitch.value = (rotationVesselSurface.eulerAngles.x > 180) ? (360.0 - rotationVesselSurface.eulerAngles.x) : -rotationVesselSurface.eulerAngles.x; vesselRoll.value = (rotationVesselSurface.eulerAngles.z > 180) ? (rotationVesselSurface.eulerAngles.z - 360.0) : rotationVesselSurface.eulerAngles.z; altitudeASL.value = vessel.mainBody.GetAltitude(CoM); RaycastHit sfc; if (Physics.Raycast(CoM, -up, out sfc, (float)altitudeASL + 10000.0F, 1 << 15)) { altitudeTrue.value = sfc.distance; } else if (vessel.mainBody.pqsController != null) { // from here: http://kerbalspaceprogram.com/forum/index.php?topic=10324.msg161923#msg161923 altitudeTrue.value = vessel.mainBody.GetAltitude(CoM) - (vessel.mainBody.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(vessel.mainBody.GetLongitude(CoM), Vector3d.down) * QuaternionD.AngleAxis(vessel.mainBody.GetLatitude(CoM), Vector3d.forward) * Vector3d.right) - vessel.mainBody.pqsController.radius); } else { altitudeTrue.value = vessel.mainBody.GetAltitude(CoM); } double surfaceAltitudeASL = altitudeASL - altitudeTrue; altitudeBottom = altitudeTrue; foreach (Part p in vessel.parts) { if (p.collider != null) { Vector3d bottomPoint = p.collider.ClosestPointOnBounds(vessel.mainBody.position); double partBottomAlt = vessel.mainBody.GetAltitude(bottomPoint) - surfaceAltitudeASL; altitudeBottom = Math.Max(0, Math.Min(altitudeBottom, partBottomAlt)); } } atmosphericDensity = FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(altitudeASL, vessel.mainBody)); orbitApA.value = vessel.orbit.ApA; orbitPeA.value = vessel.orbit.PeA; orbitPeriod.value = vessel.orbit.period; orbitTimeToAp.value = vessel.orbit.timeToAp; if (vessel.orbit.eccentricity < 1) { orbitTimeToPe.value = vessel.orbit.timeToPe; } else { orbitTimeToPe.value = -vessel.orbit.meanAnomaly / (2 * Math.PI / vessel.orbit.period); //orbit.timeToPe is bugged for ecc > 1 and timewarp > 2x } orbitLAN.value = vessel.orbit.LAN; orbitArgumentOfPeriapsis.value = vessel.orbit.argumentOfPeriapsis; orbitInclination.value = vessel.orbit.inclination; orbitEccentricity.value = vessel.orbit.eccentricity; orbitSemiMajorAxis.value = vessel.orbit.semiMajorAxis; latitude.value = vessel.mainBody.GetLatitude(CoM); longitude.value = ARUtils.clampDegrees(vessel.mainBody.GetLongitude(CoM)); if (vessel.mainBody != Planetarium.fetch.Sun) { Vector3d delta = vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() + 1) - vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() - 1); Vector3d plUp = Vector3d.Cross(vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime()) - vessel.mainBody.referenceBody.getPositionAtUT(Planetarium.GetUniversalTime()), vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() + vessel.mainBody.orbit.period / 4) - vessel.mainBody.referenceBody.getPositionAtUT(Planetarium.GetUniversalTime() + vessel.mainBody.orbit.period / 4)).normalized; angleToPrograde = ARUtils.clampDegrees360((((vessel.orbit.inclination > 90) || (vessel.orbit.inclination < -90)) ? 1 : -1) * ((Vector3)up).AngleInPlane(plUp, delta)); } else { angleToPrograde = 0; } radius = (CoM - vessel.mainBody.position).magnitude; cost = mass = thrustAvailable = thrustMinimum = massDrag = torqueRAvailable = torquePYAvailable = torqueThrustPYAvailable = 0; MoI = vessel.findLocalMOI(CoM); foreach (Part p in vessel.parts) { cost += p.partInfo.cost; if (p.physicalSignificance != Part.PhysicalSignificance.NONE) { double partMass = p.totalMass(); mass += partMass; massDrag += partMass * p.maximum_drag; } MoI += p.Rigidbody.inertiaTensor; if ((p.State == PartStates.ACTIVE) || ((Staging.CurrentStage > Staging.lastStage) && (p.inverseStage == Staging.lastStage))) { if (p is LiquidEngine && ARUtils.engineHasFuel(p)) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((LiquidEngine)p).thrustVector).normalized, forward); thrustAvailable += ((LiquidEngine)p).maxThrust * usableFraction; thrustMinimum += ((LiquidEngine)p).minThrust * usableFraction; if (((LiquidEngine)p).thrustVectoringCapable) { torqueThrustPYAvailable += Math.Sin(Math.Abs(((LiquidEngine)p).gimbalRange) * Math.PI / 180) * ((LiquidEngine)p).maxThrust * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } } else if (p is LiquidFuelEngine && ARUtils.engineHasFuel(p)) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((LiquidFuelEngine)p).thrustVector).normalized, forward); thrustAvailable += ((LiquidFuelEngine)p).maxThrust * usableFraction; thrustMinimum += ((LiquidFuelEngine)p).minThrust * usableFraction; if (((LiquidFuelEngine)p).thrustVectoringCapable) { torqueThrustPYAvailable += Math.Sin(Math.Abs(((LiquidFuelEngine)p).gimbalRange) * Math.PI / 180) * ((LiquidFuelEngine)p).maxThrust * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } } else if (p is SolidRocket && !p.ActivatesEvenIfDisconnected) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((SolidRocket)p).thrustVector).normalized, forward); thrustAvailable += ((SolidRocket)p).thrust * usableFraction; thrustMinimum += ((SolidRocket)p).thrust * usableFraction; } else if (p is AtmosphericEngine && ARUtils.engineHasFuel(p)) { double usableFraction = Vector3d.Dot((p.transform.rotation * ((AtmosphericEngine)p).thrustVector).normalized, forward); thrustAvailable += ((AtmosphericEngine)p).maximumEnginePower * ((AtmosphericEngine)p).totalEfficiency * usableFraction; if (((AtmosphericEngine)p).thrustVectoringCapable) { torqueThrustPYAvailable += Math.Sin(Math.Abs(((AtmosphericEngine)p).gimbalRange) * Math.PI / 180) * ((AtmosphericEngine)p).maximumEnginePower * ((AtmosphericEngine)p).totalEfficiency * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } } else if (p.Modules.Contains("ModuleEngines")) { foreach (PartModule pm in p.Modules) { if ((pm is ModuleEngines) && (pm.isEnabled) && ARUtils.engineHasFuel(p) && ((ModuleEngines)p.Modules["ModuleEngines"]).getIgnitionState) { ModuleEngines e = (ModuleEngines)pm; double usableFraction = 1; // Vector3d.Dot((p.transform.rotation * e.thrustTransform.forward).normalized, forward); // TODO: Fix usableFraction thrustAvailable += e.maxThrust * usableFraction; if (e.throttleLocked) { thrustMinimum += e.maxThrust * usableFraction; } else { thrustMinimum += e.minThrust * usableFraction; } if (p.Modules.OfType <ModuleGimbal>().Count() > 0) { torqueThrustPYAvailable += Math.Sin(Math.Abs(p.Modules.OfType <ModuleGimbal>().First().gimbalRange) * Math.PI / 180) * e.maxThrust * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; // TODO: close enough? } } } } else { foreach (PartModule pm in p.Modules) { CenterOfThrustQuery ctq = new CenterOfThrustQuery(); pm.BroadcastMessage("OnCenterOfThrustQuery", ctq, SendMessageOptions.DontRequireReceiver); if (ctq.thrust > 0) { double usableFraction = 1; // Vector3d.Dot((p.transform.rotation * e.thrustTransform.forward).normalized, forward); // TODO: Fix usableFraction thrustAvailable += ctq.thrust * usableFraction; } } } } if (vessel.ActionGroups[KSPActionGroup.RCS]) { if (p is RCSModule) { double maxT = 0; for (int i = 0; i < 6; i++) { if (((RCSModule)p).thrustVectors[i] != Vector3.zero) { maxT = Math.Max(maxT, ((RCSModule)p).thrusterPowers[i]); } } torqueRAvailable += maxT; torquePYAvailable += maxT * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } if (p.Modules.Contains("ModuleRCS")) { foreach (ModuleRCS pm in p.Modules.OfType <ModuleRCS>()) { double maxT = pm.thrustForces.Max(); if ((pm.isEnabled) && (!pm.isJustForShow)) { torqueRAvailable += maxT; torquePYAvailable += maxT * (p.Rigidbody.worldCenterOfMass - CoM).magnitude; } } } } if (p is CommandPod) { torqueRAvailable += Math.Abs(((CommandPod)p).rotPower); torquePYAvailable += Math.Abs(((CommandPod)p).rotPower); } } angularMomentum = new Vector3d(angularVelocity.x * MoI.x, angularVelocity.y * MoI.y, angularVelocity.z * MoI.z); maxThrustAccel = thrustAvailable / mass; minThrustAccel = thrustMinimum / mass; double throttle = vessel.ctrlState.mainThrottle; thrust = ((1.0 - throttle) * thrustMinimum + throttle * thrustAvailable); //Update the acceleration (1 is one 1Hz update, 0.1 is 10Hz) if (time - _lastUpdate > 0.5) { double mag = vessel.srf_velocity.magnitude; //Don't update on first pass if (_lastUpdate > 0) { double new_accel = (mag - _lastVel) / (time - _lastUpdate); surface_accel_delta = new_accel - surface_accel; surface_accel = new_accel; if (surface_accel < 0 && _lastAltitude > altitudeTrue.value) { stop_distance = -(mag * mag) / (2.0 * surface_accel); } else { stop_distance = 0; } //How long will we burn to stop stop_time = 2.0 * stop_distance / mag; } //Calc how much fuel we are using fuelAmount = 0; fuelConsumption = 0; fuelTotalAmount = 0; foreach (Part p in vessel.GetActiveParts()) { foreach (ModuleEngines engine in p.Modules.OfType <ModuleEngines>()) { if (!engine.isEnabled || !engine.EngineIgnited || engine.engineShutdown) { continue; } double thr = engine.finalThrust; double Isp = engine.realIsp; double massFlowRate = thr / (Isp * 9.81); double sumRatioTimesDensity = 0; foreach (ModuleEngines.Propellant propellant in engine.propellants) { sumRatioTimesDensity += propellant.ratio * PartResourceLibrary.Instance.GetDefinition(propellant.id).density; } foreach (ModuleEngines.Propellant propellant in engine.propellants) { if (propellant.name != "ElectricCharge") { fuelConsumption += propellant.ratio * massFlowRate / sumRatioTimesDensity; fuelAmount += propellant.currentAmount; } } } //Total amount fuelTotalAmount = 0; foreach (PartResource r in p.Resources) { if (r.resourceName != "ElectricCharge") { fuelTotalAmount += r.maxAmount; } } } //Update my info _lastAltitude = altitudeTrue.value; _lastUpdate = time; _lastVel = mag; } }
protected override void WindowGUI(int windowID) { if (minimized) { if (GUILayout.Button("Maximize")) { minimized = false; } } else { GUILayout.BeginVertical(); if (GUILayout.Button("Minimize")) { minimized = true; } targetHeading = ARUtils.doGUITextInput("Heading:", 70.0F, targetHeadingString, 70.0F, "d", 40.0F, out targetHeadingString, targetHeading); targetAltitude = ARUtils.doGUITextInput("Altitude:", 70.0F, targetAltitudeString, 70.0F, "m", 40.0F, out targetAltitudeString, targetAltitude); bool oldHold = holdHeadingAndAlt; holdHeadingAndAlt = GUILayout.Toggle(holdHeadingAndAlt, "Hold Heading + Alt"); if (holdHeadingAndAlt && !oldHold) { autoLand = false; core.controlClaim(this); } if (!holdHeadingAndAlt && oldHold) { core.attitudeDeactivate(this); core.controlRelease(this); } ilsOn = GUILayout.Toggle(ilsOn, "ILS", new GUIStyle(GUI.skin.button)); if (ilsOn) { GUILayout.Label(String.Format("Lateral speed = {0:0.00} m/s " + (leftSpeed < 0 ? "right" : "left"), Math.Abs(leftSpeed))); GUILayout.Label(String.Format("Lateral displacement = {0:0} m " + (leftDisplacement < 0 ? "right" : "left"), Math.Abs(leftDisplacement))); GUILayout.Label(String.Format("Flight Path Angle = {0:0.00}°", flightPathAngle)); GUILayout.Label(String.Format("FPA to runway = {0:0.00}°", flightPathAngleToRunway)); GUILayout.Label(String.Format("Distance to runway = {0:0.00} km", horizontalDistanceToRunway / 1000.0)); GUILayout.Label("The purple circle on the navball points toward the runway. Align your velocity vector with the purple circle and you'll land on the runway, properly aligned with it."); bool oldAutoLand = autoLand; autoLand = GUILayout.Toggle(autoLand, "Auto Land"); if (autoLand && !oldAutoLand) { holdHeadingAndAlt = false; core.controlClaim(this); loweredGear = false; } if (!autoLand && oldAutoLand) { core.attitudeDeactivate(this); core.controlRelease(this); } if (autoLand) { glideslope = ARUtils.doGUITextInput("Glideslope:", 70.0F, glideslopeString, 70.0F, "d", 40.0F, out glideslopeString, glideslope); } } else { autoLand = false; } GUILayout.EndVertical(); } GUI.DragWindow(); }