Fixed thrust and actualThrust calculations
--- a/KerbalEngineer/Flight/Readouts/Orbital/Eccentricity.cs
+++ b/KerbalEngineer/Flight/Readouts/Orbital/Eccentricity.cs
@@ -43,7 +43,7 @@
public override void Draw(SectionModule section)
{
- this.DrawLine(FlightGlobals.ship_orbit.eccentricity.ToString("F3"), section.IsHud);
+ this.DrawLine(FlightGlobals.ship_orbit.eccentricity.ToString("F5"), section.IsHud);
}
#endregion
--- a/KerbalEngineer/Flight/Readouts/Rendezvous/RendezvousProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Rendezvous/RendezvousProcessor.cs
@@ -1,7 +1,7 @@
//
// Kerbal Engineer Redux
//
-// Copyright (C) 2014 CYBUTEK
+// Copyright (C) 2015 CYBUTEK
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -17,30 +17,19 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#region Using Directives
-
-using System;
-
-using KerbalEngineer.Extensions;
-using KerbalEngineer.Helpers;
-
-#endregion
-
namespace KerbalEngineer.Flight.Readouts.Rendezvous
{
+ using System;
+ using Extensions;
+ using Helpers;
+
public class RendezvousProcessor : IUpdatable, IUpdateRequest
{
- #region Fields
-
private static readonly RendezvousProcessor instance = new RendezvousProcessor();
private Orbit originOrbit;
private Orbit targetOrbit;
- #endregion
-
- #region Properties
-
/// <summary>
/// Gets the target's altitude above its reference body.
/// </summary>
@@ -71,7 +60,10 @@
/// </summary>
public static RendezvousProcessor Instance
{
- get { return instance; }
+ get
+ {
+ return instance;
+ }
}
/// <summary>
@@ -149,10 +141,6 @@
/// </summary>
public bool UpdateRequested { get; set; }
- #endregion
-
- #region Methods: public
-
/// <summary>
/// Request and update to calculate the details.
/// </summary>
@@ -166,7 +154,13 @@
/// </summary>
public void Update()
{
- if (FlightGlobals.fetch.VesselTarget == null)
+ if (FlightGlobals.fetch == null ||
+ FlightGlobals.fetch.VesselTarget == null ||
+ FlightGlobals.ActiveVessel == null ||
+ FlightGlobals.ActiveVessel.targetObject == null ||
+ FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null ||
+ FlightGlobals.ship_orbit == null ||
+ FlightGlobals.ship_orbit.referenceBody == null)
{
ShowDetails = false;
return;
@@ -174,55 +168,50 @@
ShowDetails = true;
- this.targetOrbit = FlightGlobals.fetch.VesselTarget.GetOrbit();
- this.originOrbit = (FlightGlobals.ship_orbit.referenceBody == Planetarium.fetch.Sun || FlightGlobals.ship_orbit.referenceBody == FlightGlobals.ActiveVessel.targetObject.GetOrbit().referenceBody)
+ targetOrbit = FlightGlobals.fetch.VesselTarget.GetOrbit();
+ originOrbit = (FlightGlobals.ship_orbit.referenceBody == Planetarium.fetch.Sun ||
+ FlightGlobals.ship_orbit.referenceBody == FlightGlobals.ActiveVessel.targetObject.GetOrbit().referenceBody)
? FlightGlobals.ship_orbit
: FlightGlobals.ship_orbit.referenceBody.orbit;
- RelativeInclination = this.originOrbit.GetRelativeInclination(this.targetOrbit);
+ RelativeInclination = originOrbit.GetRelativeInclination(targetOrbit);
RelativeVelocity = FlightGlobals.ship_tgtSpeed;
- RelativeSpeed = FlightGlobals.ship_obtSpeed - this.targetOrbit.orbitalSpeed;
- PhaseAngle = this.originOrbit.GetPhaseAngle(this.targetOrbit);
- InterceptAngle = this.CalcInterceptAngle();
- TimeToAscendingNode = this.originOrbit.GetTimeToVector(this.GetAscendingNode());
- TimeToDescendingNode = this.originOrbit.GetTimeToVector(this.GetDescendingNode());
- AngleToAscendingNode = this.originOrbit.GetAngleToVector(this.GetAscendingNode());
- AngleToDescendingNode = this.originOrbit.GetAngleToVector(this.GetDescendingNode());
- AltitudeSeaLevel = this.targetOrbit.altitude;
- ApoapsisHeight = this.targetOrbit.ApA;
- PeriapsisHeight = this.targetOrbit.PeA;
- TimeToApoapsis = this.targetOrbit.timeToAp;
- TimeToPeriapsis = this.targetOrbit.timeToPe;
- SemiMajorAxis = this.targetOrbit.semiMajorAxis;
- SemiMinorAxis = this.targetOrbit.semiMinorAxis;
-
- Distance = Vector3d.Distance(this.targetOrbit.pos, this.originOrbit.pos);
- OrbitalPeriod = this.targetOrbit.period;
- }
-
- #endregion
-
- #region Methods: private
+ RelativeSpeed = FlightGlobals.ship_obtSpeed - targetOrbit.orbitalSpeed;
+ PhaseAngle = originOrbit.GetPhaseAngle(targetOrbit);
+ InterceptAngle = CalcInterceptAngle();
+ TimeToAscendingNode = originOrbit.GetTimeToVector(GetAscendingNode());
+ TimeToDescendingNode = originOrbit.GetTimeToVector(GetDescendingNode());
+ AngleToAscendingNode = originOrbit.GetAngleToVector(GetAscendingNode());
+ AngleToDescendingNode = originOrbit.GetAngleToVector(GetDescendingNode());
+ AltitudeSeaLevel = targetOrbit.altitude;
+ ApoapsisHeight = targetOrbit.ApA;
+ PeriapsisHeight = targetOrbit.PeA;
+ TimeToApoapsis = targetOrbit.timeToAp;
+ TimeToPeriapsis = targetOrbit.timeToPe;
+ SemiMajorAxis = targetOrbit.semiMajorAxis;
+ SemiMinorAxis = targetOrbit.semiMinorAxis;
+
+ Distance = Vector3d.Distance(targetOrbit.pos, originOrbit.pos);
+ OrbitalPeriod = targetOrbit.period;
+ }
private double CalcInterceptAngle()
{
- var originRadius = (this.originOrbit.semiMinorAxis + this.originOrbit.semiMajorAxis) * 0.5;
- var targetRadius = (this.targetOrbit.semiMinorAxis + this.targetOrbit.semiMajorAxis) * 0.5;
- var angle = 180.0 * (1.0 - Math.Pow((originRadius + targetRadius) / (2.0 * targetRadius), 1.5));
+ double originRadius = (originOrbit.semiMinorAxis + originOrbit.semiMajorAxis) * 0.5;
+ double targetRadius = (targetOrbit.semiMinorAxis + targetOrbit.semiMajorAxis) * 0.5;
+ double angle = 180.0 * (1.0 - Math.Pow((originRadius + targetRadius) / (2.0 * targetRadius), 1.5));
angle = PhaseAngle - angle;
return RelativeInclination < 90.0 ? AngleHelper.Clamp360(angle) : AngleHelper.Clamp360(360.0 - (180.0 - angle));
}
private Vector3d GetAscendingNode()
{
- return Vector3d.Cross(this.targetOrbit.GetOrbitNormal(), this.originOrbit.GetOrbitNormal());
+ return Vector3d.Cross(targetOrbit.GetOrbitNormal(), originOrbit.GetOrbitNormal());
}
private Vector3d GetDescendingNode()
{
- return Vector3d.Cross(this.originOrbit.GetOrbitNormal(), this.targetOrbit.GetOrbitNormal());
- }
-
- #endregion
+ return Vector3d.Cross(originOrbit.GetOrbitNormal(), targetOrbit.GetOrbitNormal());
+ }
}
}
--- a/KerbalEngineer/Flight/Readouts/Surface/Longitude.cs
+++ b/KerbalEngineer/Flight/Readouts/Surface/Longitude.cs
@@ -17,35 +17,25 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#region Using Directives
-
-using KerbalEngineer.Flight.Sections;
-
-#endregion
-
namespace KerbalEngineer.Flight.Readouts.Surface
{
+ using Helpers;
+ using Sections;
+
public class Longitude : ReadoutModule
{
- #region Constructors
-
public Longitude()
{
- this.Name = "Longitude";
- this.Category = ReadoutCategory.GetCategory("Surface");
- this.HelpString = "Shows the vessel's longitude around a celestial body. Longitude is the angle from the bodies prime meridian.";
- this.IsDefault = true;
+ Name = "Longitude";
+ Category = ReadoutCategory.GetCategory("Surface");
+ HelpString = "Shows the vessel's longitude around a celestial body. Longitude is the angle from the bodies prime meridian.";
+ IsDefault = true;
}
-
- #endregion
-
- #region Methods: public
public override void Draw(SectionModule section)
{
- this.DrawLine(KSPUtil.PrintLongitude(FlightGlobals.ship_longitude), section.IsHud);
+ double angle = AngleHelper.Clamp180(FlightGlobals.ship_longitude);
+ DrawLine(Units.ToAngleDMS(angle) + (angle < 0.0 ? "W" : " E"), section.IsHud);
}
-
- #endregion
}
}
--- a/KerbalEngineer/Helpers/AngleHelper.cs
+++ b/KerbalEngineer/Helpers/AngleHelper.cs
@@ -17,21 +17,30 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#region Using Directives
-
-using UnityEngine;
-
-#endregion
-
namespace KerbalEngineer.Helpers
{
+ using UnityEngine;
+
public static class AngleHelper
{
- #region Methods: public
+ public static double Clamp180(double angle)
+ {
+ angle = Clamp360(angle);
+ if (angle > 180.0)
+ {
+ angle = angle - 360.0;
+ }
+ return angle;
+ }
- public static double Clamp360(double value)
+ public static double Clamp360(double angle)
{
- return ClampBetween(value, 0.0, 360.0);
+ angle = angle % 360.0;
+ if (angle < 0.0)
+ {
+ angle = angle + 360.0;
+ }
+ return angle;
}
public static double ClampBetween(double value, double minimum, double maximum)
@@ -51,8 +60,8 @@
public static double GetAngleBetweenVectors(Vector3d left, Vector3d right)
{
- var angle = Vector3d.Angle(left, right);
- var rotated = QuaternionD.AngleAxis(90.0, Vector3d.forward) * right;
+ double angle = Vector3d.Angle(left, right);
+ Vector3d rotated = QuaternionD.AngleAxis(90.0, Vector3d.forward) * right;
if (Vector3d.Angle(rotated, left) > 90.0)
{
@@ -60,7 +69,5 @@
}
return angle;
}
-
- #endregion
}
}
--- a/KerbalEngineer/KerbalEngineer.csproj
+++ b/KerbalEngineer/KerbalEngineer.csproj
@@ -208,8 +208,7 @@
</ItemGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp">
- <HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\SteamApps\common\Kerbal Space Program\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>
- <Private>False</Private>
+ <HintPath>..\Game\KSP_Data\Managed\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="System">
<HintPath>..\Game\KSP_Data\Managed\System.dll</HintPath>
@@ -220,8 +219,7 @@
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine">
- <HintPath>..\..\..\..\..\..\Program Files (x86)\Steam\SteamApps\common\Kerbal Space Program\KSP_Data\Managed\UnityEngine.dll</HintPath>
- <Private>False</Private>
+ <HintPath>..\Game\KSP_Data\Managed\UnityEngine.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup />
--- a/KerbalEngineer/VesselSimulator/EngineSim.cs
+++ b/KerbalEngineer/VesselSimulator/EngineSim.cs
@@ -31,6 +31,7 @@
private static readonly Pool<EngineSim> pool = new Pool<EngineSim>(Create, Reset);
private readonly ResourceContainer resourceConsumptions = new ResourceContainer();
+ private readonly ResourceContainer resourceFlowModes = new ResourceContainer();
public double actualThrust = 0;
public bool isActive = false;
@@ -52,6 +53,7 @@
private static void Reset(EngineSim engineSim)
{
engineSim.resourceConsumptions.Reset();
+ engineSim.resourceFlowModes.Reset();
engineSim.actualThrust = 0;
engineSim.isActive = false;
engineSim.isp = 0;
@@ -86,11 +88,10 @@
List<Propellant> propellants,
bool active,
float resultingThrust,
- List<Transform> thrustTransforms)
+ List<Transform> thrustTransforms,
+ LogMsg log)
{
EngineSim engineSim = pool.Borrow();
-
- StringBuilder buffer = null;
engineSim.isp = 0.0;
engineSim.maxMach = 0.0f;
@@ -99,61 +100,75 @@
engineSim.isActive = active;
engineSim.thrustVec = vecThrust;
engineSim.resourceConsumptions.Reset();
+ engineSim.resourceFlowModes.Reset();
engineSim.appliedForces.Clear();
double flowRate = 0.0;
if (engineSim.partSim.hasVessel)
{
+ if (log != null) log.buf.AppendLine("hasVessel is true");
+
float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, engineSim.partSim.part.atmDensity, velCurve, machNumber, ref engineSim.maxMach);
engineSim.isp = atmosphereCurve.Evaluate((float)atmosphere);
engineSim.thrust = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, engineSim.isp);
engineSim.actualThrust = engineSim.isActive ? resultingThrust : 0.0;
+ if (log != null)
+ {
+ log.buf.AppendFormat("flowMod = {0:g6}\n", flowModifier);
+ log.buf.AppendFormat("isp = {0:g6}\n", engineSim.isp);
+ log.buf.AppendFormat("thrust = {0:g6}\n", engineSim.thrust);
+ log.buf.AppendFormat("actual = {0:g6}\n", engineSim.actualThrust);
+ }
if (throttleLocked)
{
+ if (log != null) log.buf.AppendLine("throttleLocked is true, using thrust for flowRate");
flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
}
else
{
if (currentThrottle > 0.0f && engineSim.partSim.isLanded == false)
{
+ if (log != null) log.buf.AppendLine("throttled up and not landed, using actualThrust for flowRate");
flowRate = GetFlowRate(engineSim.actualThrust, engineSim.isp);
}
else
{
+ if (log != null) log.buf.AppendLine("throttled down or landed, using thrust for flowRate");
flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
}
}
}
else
{
+ if (log != null) log.buf.AppendLine("hasVessel is false");
float flowModifier = GetFlowModifier(atmChangeFlow, atmCurve, CelestialBodies.SelectedBody.GetDensity(BuildAdvanced.Altitude), velCurve, machNumber, ref engineSim.maxMach);
engineSim.isp = atmosphereCurve.Evaluate((float)atmosphere);
engineSim.thrust = GetThrust(Mathf.Lerp(minFuelFlow, maxFuelFlow, GetThrustPercent(thrustPercentage)) * flowModifier, engineSim.isp);
+ engineSim.actualThrust = 0d;
+ if (log != null)
+ {
+ log.buf.AppendFormat("flowMod = {0:g6}\n", flowModifier);
+ log.buf.AppendFormat("isp = {0:g6}\n", engineSim.isp);
+ log.buf.AppendFormat("thrust = {0:g6}\n", engineSim.thrust);
+ log.buf.AppendFormat("actual = {0:g6}\n", engineSim.actualThrust);
+ }
+
+ if (log != null) log.buf.AppendLine("no vessel, using thrust for flowRate");
flowRate = GetFlowRate(engineSim.thrust, engineSim.isp);
}
- if (SimManager.logOutput)
- {
- buffer = new StringBuilder(1024);
- buffer.AppendFormat("flowRate = {0:g6}\n", flowRate);
- }
-
- engineSim.thrust = flowRate * (engineSim.isp * IspG);
- // I did not look into the diff between those 2 so I made them equal...
- engineSim.actualThrust = engineSim.thrust;
+ if (log != null) log.buf.AppendFormat("flowRate = {0:g6}\n", flowRate);
float flowMass = 0f;
for (int i = 0; i < propellants.Count; ++i)
{
Propellant propellant = propellants[i];
- flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id);
- }
-
- if (SimManager.logOutput)
- {
- buffer.AppendFormat("flowMass = {0:g6}\n", flowMass);
- }
+ if (!propellant.ignoreForIsp)
+ flowMass += propellant.ratio * ResourceContainer.GetResourceDensity(propellant.id);
+ }
+
+ if (log != null) log.buf.AppendFormat("flowMass = {0:g6}\n", flowMass);
for (int i = 0; i < propellants.Count; ++i)
{
@@ -165,21 +180,14 @@
}
double consumptionRate = propellant.ratio * flowRate / flowMass;
- if (SimManager.logOutput)
- {
- buffer.AppendFormat(
+ if (log != null) log.buf.AppendFormat(
"Add consumption({0}, {1}:{2:d}) = {3:g6}\n",
ResourceContainer.GetResourceName(propellant.id),
theEngine.name,
theEngine.partId,
consumptionRate);
- }
engineSim.resourceConsumptions.Add(propellant.id, consumptionRate);
- }
-
- if (SimManager.logOutput)
- {
- MonoBehaviour.print(buffer);
+ engineSim.resourceFlowModes.Add(propellant.id, (double)propellant.GetFlowMode());
}
double thrustPerThrustTransform = engineSim.thrust / thrustTransforms.Count;
@@ -285,7 +293,7 @@
sourcePartSets.Add(type, sourcePartSet);
}
- switch (ResourceContainer.GetResourceFlowMode(type))
+ switch ((ResourceFlowMode)this.resourceFlowModes[type])
{
case ResourceFlowMode.NO_FLOW:
if (partSim.resources[type] > SimManager.RESOURCE_MIN && partSim.resourceFlowStates[type] != 0)
--- a/KerbalEngineer/VesselSimulator/PartSim.cs
+++ b/KerbalEngineer/VesselSimulator/PartSim.cs
@@ -34,7 +34,9 @@
private readonly List<AttachNodeSim> attachNodes = new List<AttachNodeSim>();
+ public double realMass;
public double baseMass;
+ public double baseMassForCoM;
public Vector3d centerOfMass;
public double cost;
public int decoupledInStage;
@@ -89,6 +91,7 @@
partSim.resourceFlowStates.Reset();
partSim.resources.Reset();
partSim.baseMass = 0d;
+ partSim.baseMassForCoM = 0d;
partSim.startMass = 0d;
}
@@ -100,17 +103,13 @@
public static PartSim New(Part thePart, int id, double atmosphere, LogMsg log)
{
PartSim partSim = pool.Borrow();
-
partSim.part = thePart;
partSim.centerOfMass = thePart.transform.TransformPoint(thePart.CoMOffset);
partSim.partId = id;
partSim.name = partSim.part.partInfo.name;
- if (log != null)
- {
- log.buf.AppendLine("Create PartSim for " + partSim.name);
- }
+ if (log != null) log.buf.AppendLine("Create PartSim for " + partSim.name);
partSim.parent = null;
partSim.parentAttach = partSim.part.attachMode;
@@ -125,19 +124,27 @@
partSim.cost = partSim.part.GetCostWet();
+ if (log != null)
+ {
+ log.buf.AppendLine("Parent part = " + (partSim.part.parent == null ? "null" : partSim.part.parent.partInfo.name));
+ log.buf.AppendLine("physicalSignificance = " + partSim.part.physicalSignificance);
+ log.buf.AppendLine("PhysicsSignificance = " + partSim.part.PhysicsSignificance);
+ }
+
// Work out if the part should have no physical significance
- partSim.isNoPhysics = partSim.part.HasModule<LaunchClamp>() ||
- partSim.part.physicalSignificance == Part.PhysicalSignificance.NONE ||
- partSim.part.PhysicsSignificance == 1;
-
- if (!partSim.isNoPhysics)
- {
- partSim.baseMass = partSim.part.mass;
- }
-
- if (SimManager.logOutput)
- {
- MonoBehaviour.print((partSim.isNoPhysics ? "Ignoring" : "Using") + " part.mass of " + partSim.part.mass);
+ // The root part is never "no physics"
+ partSim.isNoPhysics = partSim.part.physicalSignificance == Part.PhysicalSignificance.NONE ||
+ partSim.part.PhysicsSignificance == 1;
+
+ if (partSim.part.HasModule<LaunchClamp>())
+ {
+ partSim.realMass = 0d;
+ if (log != null) log.buf.AppendLine("Ignoring mass of launch clamp");
+ }
+ else
+ {
+ partSim.realMass = partSim.part.mass;
+ if (log != null) log.buf.AppendLine("Using part.mass of " + partSim.part.mass);
}
for (int i = 0; i < partSim.part.Resources.Count; i++)
@@ -148,21 +155,17 @@
// This can happen if a resource capacity is 0 and tweakable
if (!Double.IsNaN(resource.amount))
{
- if (SimManager.logOutput)
- {
- MonoBehaviour.print(resource.resourceName + " = " + resource.amount);
- }
+ if (log != null)
+ log.buf.AppendLine(resource.resourceName + " = " + resource.amount);
partSim.resources.Add(resource.info.id, resource.amount);
partSim.resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
}
else
{
- MonoBehaviour.print(resource.resourceName + " is NaN. Skipping.");
- }
- }
-
- partSim.startMass = partSim.GetMass(-1);
+ if (log != null) log.buf.AppendLine(resource.resourceName + " is NaN. Skipping.");
+ }
+ }
partSim.hasVessel = (partSim.part.vessel != null);
partSim.isLanded = partSim.hasVessel && partSim.part.vessel.Landed;
@@ -179,10 +182,8 @@
partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEnginesFX || partSim.hasModuleEngines;
- if (SimManager.logOutput)
- {
- MonoBehaviour.print("Created " + partSim.name + ". Decoupled in stage " + partSim.decoupledInStage);
- }
+ if (log != null) log.buf.AppendLine("Created " + partSim.name + ". Decoupled in stage " + partSim.decoupledInStage);
+
return partSim;
}
@@ -229,10 +230,7 @@
ModuleEnginesFX engine = engines[i];
if (engine.engineID == mode)
{
- if (log != null)
- {
- log.buf.AppendLine("Module: " + engine.moduleName);
- }
+ if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);
Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);
@@ -254,7 +252,8 @@
engine.propellants,
engine.isOperational,
engine.resultingThrust,
- engine.thrustTransforms);
+ engine.thrustTransforms,
+ log);
allEngines.Add(engineSim);
}
}
@@ -267,10 +266,7 @@
for (int i = 0; i < engines.Count; ++i)
{
ModuleEngines engine = engines[i];
- if (log != null)
- {
- log.buf.AppendLine("Module: " + engine.moduleName);
- }
+ if (log != null) log.buf.AppendLine("Module: " + engine.moduleName);
Vector3 thrustvec = this.CalculateThrustVector(vectoredThrust ? engine.thrustTransforms : null, log);
@@ -292,7 +288,8 @@
engine.propellants,
engine.isOperational,
engine.resultingThrust,
- engine.thrustTransforms);
+ engine.thrustTransforms,
+ log);
allEngines.Add(engineSim);
}
}
@@ -351,9 +348,13 @@
buffer.Append(name);
buffer.AppendFormat(":[id = {0:d}, decouple = {1:d}, invstage = {2:d}", partId, decoupledInStage, inverseStage);
- buffer.AppendFormat(", vesselName = '{0}'", vesselName);
- buffer.AppendFormat(", vesselType = {0}", SimManager.GetVesselTypeString(vesselType));
- buffer.AppendFormat(", initialVesselName = '{0}'", initialVesselName);
+ //buffer.AppendFormat(", vesselName = '{0}'", vesselName);
+ //buffer.AppendFormat(", vesselType = {0}", SimManager.GetVesselTypeString(vesselType));
+ //buffer.AppendFormat(", initialVesselName = '{0}'", initialVesselName);
+
+ buffer.AppendFormat(", isNoPhys = {0}", isNoPhysics);
+ buffer.AppendFormat(", baseMass = {0}", baseMass);
+ buffer.AppendFormat(", baseMassForCoM = {0}", baseMassForCoM);
buffer.AppendFormat(", fuelCF = {0}", fuelCrossFeed);
buffer.AppendFormat(", noCFNKey = '{0}'", noCrossFeedNodeKey);
@@ -389,9 +390,7 @@
{
PartSim partSim = allParts[i];
if (partSim.parent == this)
- {
partSim.DumpPartToBuffer(buffer, newPrefix, allParts);
- }
}
}
}
@@ -401,17 +400,15 @@
foreach (int type in types)
{
if (resources.HasType(type) && resourceFlowStates[type] != 0 && resources[type] > SimManager.RESOURCE_PART_EMPTY_THRESH)
- {
return false;
- }
}
return true;
}
- public double GetMass(int currentStage)
- {
- double mass = baseMass;
+ public double GetMass(int currentStage, bool forCoM = false)
+ {
+ double mass = forCoM ? baseMassForCoM : baseMass;
for (int i = 0; i < resources.Types.Count; ++i)
{
@@ -445,14 +442,11 @@
// Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns as is.
if (visited.Contains(this))
{
- if (log != null)
- log.buf.AppendLine(indent + "Returning empty set, already visited (" + name + ":" + partId + ")");
-
+ if (log != null) log.buf.AppendLine(indent + "Returning empty set, already visited (" + name + ":" + partId + ")");
return;
}
- if (log != null)
- log.buf.AppendLine(indent + "Adding this to visited");
+ if (log != null) log.buf.AppendLine(indent + "Adding this to visited");
visited.Add(this);
@@ -469,13 +463,11 @@
{
if (visited.Contains(partSim))
{
- if (log != null)
- log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
+ if (log != null) log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
}
else
{
- if (log != null)
- log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");
+ if (log != null) log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");
partSim.GetSourceSet(type, allParts, visited, allSources, log, indent);
}
@@ -484,9 +476,7 @@
if (allSources.Count > lastCount)
{
- if (log != null)
- log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " fuel target sources (" + this.name + ":" + this.partId + ")");
-
+ if (log != null) log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " fuel target sources (" + this.name + ":" + this.partId + ")");
return;
}
@@ -515,13 +505,11 @@
{
if (visited.Contains(attachSim.attachedPartSim))
{
- if (log != null)
- log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
+ if (log != null) log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
}
else
{
- if (log != null)
- log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
+ if (log != null) log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
attachSim.attachedPartSim.GetSourceSet(type, allParts, visited, allSources, log, indent);
}
@@ -532,9 +520,7 @@
if (allSources.Count > lastCount)
{
- if (log != null)
- log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " attached sources (" + this.name + ":" + this.partId + ")");
-
+ if (log != null) log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " attached sources (" + this.name + ":" + this.partId + ")");
return;
}
}
@@ -549,16 +535,14 @@
{
allSources.Add(this);
- if (log != null)
- log.buf.AppendLine(indent + "Returning enabled tank as only source (" + name + ":" + partId + ")");
+ if (log != null) log.buf.AppendLine(indent + "Returning enabled tank as only source (" + name + ":" + partId + ")");
}
return;
}
else
{
- if (log != null)
- log.buf.AppendLine(indent + "Not fuel tank or disabled. HasType = " + resources.HasType(type) + " FlowState = " + resourceFlowStates[type]);
+ if (log != null) log.buf.AppendLine(indent + "Not fuel tank or disabled. HasType = " + resources.HasType(type) + " FlowState = " + resourceFlowStates[type]);
}
// Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its
@@ -569,8 +553,7 @@
{
if (visited.Contains(parent))
{
- if (log != null)
- log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
+ if (log != null) log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
}
else
{
@@ -578,9 +561,7 @@
this.parent.GetSourceSet(type, allParts, visited, allSources, log, indent);
if (allSources.Count > lastCount)
{
- if (log != null)
- log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " parent sources (" + this.name + ":" + this.partId + ")");
-
+ if (log != null) log.buf.AppendLine(indent + "Returning " + (allSources.Count - lastCount) + " parent sources (" + this.name + ":" + this.partId + ")");
return;
}
}
@@ -588,8 +569,7 @@
}
// Rule 8: If all preceding rules failed, part returns empty list.
- if (log != null)
- log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");
+ if (log != null) log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");
return;
}
@@ -626,10 +606,7 @@
public void SetupAttachNodes(Dictionary<Part, PartSim> partSimLookup, LogMsg log)
{
- if (log != null)
- {
- log.buf.AppendLine("SetupAttachNodes for " + name + ":" + partId + "");
- }
+ if (log != null) log.buf.AppendLine("SetupAttachNodes for " + name + ":" + partId + "");
attachNodes.Clear();
@@ -637,29 +614,20 @@
{
AttachNode attachNode = part.attachNodes[i];
- if (log != null)
- {
- log.buf.AppendLine("AttachNode " + attachNode.id + " = " + (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null"));
- }
+ if (log != null) log.buf.AppendLine("AttachNode " + attachNode.id + " = " + (attachNode.attachedPart != null ? attachNode.attachedPart.partInfo.name : "null"));
if (attachNode.attachedPart != null && attachNode.id != "Strut")
{
PartSim attachedSim;
if (partSimLookup.TryGetValue(attachNode.attachedPart, out attachedSim))
{
- if (log != null)
- {
- log.buf.AppendLine("Adding attached node " + attachedSim.name + ":" + attachedSim.partId + "");
- }
+ if (log != null) log.buf.AppendLine("Adding attached node " + attachedSim.name + ":" + attachedSim.partId + "");
attachNodes.Add(AttachNodeSim.New(attachedSim, attachNode.id, attachNode.nodeType));
}
else
{
- if (log != null)
- {
- log.buf.AppendLine("No PartSim for attached part (" + attachNode.attachedPart.partInfo.name + ")");
- }
+ if (log != null) log.buf.AppendLine("No PartSim for attached part (" + attachNode.attachedPart.partInfo.name + ")");
}
}
}
@@ -673,19 +641,13 @@
PartSim targetSim;
if (partSimLookup.TryGetValue(p, out targetSim))
{
- if (log != null)
- {
- log.buf.AppendLine("Fuel target: " + targetSim.name + ":" + targetSim.partId);
- }
+ if (log != null) log.buf.AppendLine("Fuel target: " + targetSim.name + ":" + targetSim.partId);
fuelTargets.Add(targetSim);
}
else
{
- if (log != null)
- {
- log.buf.AppendLine("No PartSim for fuel target (" + p.name + ")");
- }
+ if (log != null) log.buf.AppendLine("No PartSim for fuel target (" + p.name + ")");
}
}
}
@@ -698,17 +660,11 @@
parent = null;
if (partSimLookup.TryGetValue(part.parent, out parent))
{
- if (log != null)
- {
- log.buf.AppendLine("Parent part is " + parent.name + ":" + parent.partId);
- }
+ if (log != null) log.buf.AppendLine("Parent part is " + parent.name + ":" + parent.partId);
}
else
{
- if (log != null)
- {
- log.buf.AppendLine("No PartSim for parent part (" + part.parent.partInfo.name + ")");
- }
+ if (log != null) log.buf.AppendLine("No PartSim for parent part (" + part.parent.partInfo.name + ")");
}
}
}
@@ -746,43 +702,27 @@
{
Transform trans = thrustTransforms[i];
- if (log != null)
- {
- log.buf.AppendFormat("Transform = ({0:g6}, {1:g6}, {2:g6}) length = {3:g6}\n", trans.forward.x, trans.forward.y, trans.forward.z, trans.forward.magnitude);
- }
+ if (log != null) log.buf.AppendFormat("Transform = ({0:g6}, {1:g6}, {2:g6}) length = {3:g6}\n", trans.forward.x, trans.forward.y, trans.forward.z, trans.forward.magnitude);
thrustvec -= trans.forward;
}
- if (log != null)
- {
- log.buf.AppendFormat("ThrustVec = ({0:g6}, {1:g6}, {2:g6}) length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);
- }
+ if (log != null) log.buf.AppendFormat("ThrustVec = ({0:g6}, {1:g6}, {2:g6}) length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);
thrustvec.Normalize();
- if (log != null)
- {
- log.buf.AppendFormat("ThrustVecN = ({0:g6}, {1:g6}, {2:g6}) length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);
- }
+ if (log != null) log.buf.AppendFormat("ThrustVecN = ({0:g6}, {1:g6}, {2:g6}) length = {3:g6}\n", thrustvec.x, thrustvec.y, thrustvec.z, thrustvec.magnitude);
return thrustvec;
}
private int DecoupledInStage(Part thePart, int stage = -1)
{
- if (IsDecoupler(thePart))
- {
- if (thePart.inverseStage > stage)
- {
- stage = thePart.inverseStage;
- }
- }
+ if (IsDecoupler(thePart) && thePart.inverseStage > stage)
+ stage = thePart.inverseStage;
if (thePart.parent != null)
- {
stage = DecoupledInStage(thePart.parent, stage);
- }
return stage;
}
--- a/KerbalEngineer/VesselSimulator/Simulation.cs
+++ b/KerbalEngineer/VesselSimulator/Simulation.cs
@@ -119,7 +119,7 @@
for (int i = 0; i < allParts.Count; ++i)
{
PartSim partSim = allParts[i];
- vectorAverager.Add(partSim.centerOfMass, partSim.GetMass(currentStage));
+ vectorAverager.Add(partSim.centerOfMass, partSim.GetMass(currentStage, true));
}
return vectorAverager.Get();
@@ -139,6 +139,7 @@
log.buf.AppendLine("PrepareSimulation started");
dumpTree = true;
}
+ this._timer.Reset();
this._timer.Start();
// Store the parameters in members for ease of access in other functions
@@ -299,6 +300,7 @@
MonoBehaviour.print("RunSimulation started");
}
+ this._timer.Reset();
this._timer.Start();
LogMsg log = null;
@@ -394,6 +396,12 @@
this._timer.Start();
}
+ // Update the masses of the parts to correctly handle "no physics" parts
+ this.UpdatePartMasses();
+
+ if (log != null)
+ this.allParts[0].DumpPartToBuffer(log.buf, "", this.allParts);
+
// Update active engines and resource drains
this.UpdateResourceDrains();
@@ -413,11 +421,11 @@
// Store various things in the Stage object
stage.thrust = this.totalStageThrust;
- //MonoBehaviour.print("stage.thrust = " + stage.thrust);
+ if (log != null) log.buf.AppendLine("stage.thrust = " + stage.thrust);
stage.thrustToWeight = this.totalStageThrust / (this.stageStartMass * this.gravity);
stage.maxThrustToWeight = stage.thrustToWeight;
- //MonoBehaviour.print("StageMass = " + stageStartMass);
- //MonoBehaviour.print("Initial maxTWR = " + stage.maxThrustToWeight);
+ if (log != null) log.buf.AppendLine("StageMass = " + stageStartMass);
+ if (log != null) log.buf.AppendLine("Initial maxTWR = " + stage.maxThrustToWeight);
stage.actualThrust = this.totalStageActualThrust;
stage.actualThrustToWeight = this.totalStageActualThrust / (this.stageStartMass * this.gravity);
@@ -650,6 +658,40 @@
return stages;
}
+ public void UpdatePartMasses()
+ {
+ for (int i = 0; i < this.allParts.Count; i++)
+ {
+ this.allParts[i].baseMass = this.allParts[i].realMass;
+ this.allParts[i].baseMassForCoM = this.allParts[i].realMass;
+ }
+
+ for (int i = 0; i < this.allParts.Count; i++)
+ {
+ PartSim part = this.allParts[i];
+ // If the part has a parent
+ if (part.parent != null)
+ {
+ if (part.isNoPhysics)
+ {
+ if (part.parent.isNoPhysics && part.parent.parent != null)
+ {
+ part.baseMass = 0d;
+ part.baseMassForCoM = 0d;
+ }
+ else
+ {
+ part.parent.baseMassForCoM += part.baseMassForCoM;
+ part.baseMassForCoM = 0d;
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < this.allParts.Count; i++)
+ this.allParts[i].startMass = this.allParts[i].GetMass(currentStage);
+ }
+
// Make sure we free them all, even if they should all be free already at this point
public void FreePooledObject()
{
Binary files a/Output/KerbalEngineer/KerbalEngineer.dll and b/Output/KerbalEngineer/KerbalEngineer.dll differ