Skip to content

Commit

Permalink
changes in 1.4.1.2
Browse files Browse the repository at this point in the history
Createenginesims changes for better multimode mod engine support.
Show alternate node rendevous time when landed and targeting body in
same system.
Format negative time values.
  • Loading branch information
jrbudda committed Mar 23, 2018
1 parent 49b42df commit 80ce519
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 54 deletions.
5 changes: 5 additions & 0 deletions Documents/CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
1.1.4.2, 2018-03-23, KSP 1.4.1 #2089
Changed active engine detection code for multimode engines. Fixes GTI Multi Mode Engines mod.
When landed and targeting something in the same SOI, the 'rel time to AN/DN' rendevous readouts now show the time until the landed ship comes under the target body's orbit.
Negative times now display in year/day/hr/min/s format instead of just seconds.

1.1.4.1, 2018-03-22, KSP 1.4.1 #2089
Fix VAB mass calculation with non-zero kerbal crew weight
Fix NPE when surface attaching a part to an engine plate
Expand Down
2 changes: 1 addition & 1 deletion KerbalEngineer/EngineerGlobals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static class EngineerGlobals
/// <summary>
/// Current version of the Kerbal Engineer assembly.
/// </summary>
public const string ASSEMBLY_VERSION = "1.1.4.1";
public const string ASSEMBLY_VERSION = "1.1.4.2";

private static string assemblyFile;
private static string assemblyName;
Expand Down
83 changes: 78 additions & 5 deletions KerbalEngineer/Flight/Readouts/Rendezvous/RendezvousProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,32 @@ public static RendezvousProcessor Instance
/// </summary>
public static double TimeToRendezvous { get; private set; }

/// <summary>
/// Gets time for landed ship to intersect target orbital plane in system.
/// </summary>
public static double TimeToPlane { get; private set; }

/// <summary>
/// If the target body is ascending at the point of planar intersect.
/// </summary>
public static bool TimeToPlaneisAsc { get; private set; }

/// <summary>
/// Is the Ship landed.
/// </summary>
public static bool isLanded { get; private set; }

/// <summary>
/// If the current target is in the same SOI as the ship.
/// </summary>
public static bool inSystem { get; private set; }

/// <summary>
/// The current ship's reference body rotation period.
/// </summary>
public static double bodyRotationPeriod { get; private set; }


/// <summary>
/// Gets and sets whether the updatable object should be updated.
/// </summary>
Expand Down Expand Up @@ -175,11 +201,11 @@ public void Update()

ShowDetails = true;

inSystem = FlightGlobals.ship_orbit.referenceBody == FlightGlobals.ActiveVessel.targetObject.GetOrbit().referenceBody;

var targetOrbit = FlightGlobals.fetch.VesselTarget.GetOrbit();
var 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;
var originOrbit = (FlightGlobals.ship_orbit.referenceBody == Planetarium.fetch.Sun || inSystem) ?
FlightGlobals.ship_orbit : FlightGlobals.ship_orbit.referenceBody.orbit;

RelativeInclination = originOrbit.GetRelativeInclination(targetOrbit);
RelativeVelocity = FlightGlobals.ship_tgtSpeed;
Expand All @@ -198,6 +224,11 @@ public void Update()
SemiMajorAxis = targetOrbit.semiMajorAxis;
SemiMinorAxis = targetOrbit.semiMinorAxis;

TimeToPlane = CalcTimeToPlane(FlightGlobals.ship_orbit.referenceBody, FlightGlobals.ship_latitude, FlightGlobals.ship_longitude, targetOrbit);
// TimeToPlaneisAsc = ?? No idea how to detemine this.
bodyRotationPeriod = FlightGlobals.ship_orbit.referenceBody.rotationPeriod;

isLanded = FlightGlobals.ActiveVessel.LandedOrSplashed;
Distance = Vector3d.Distance(targetOrbit.pos, originOrbit.pos);
OrbitalPeriod = targetOrbit.period;

Expand All @@ -206,7 +237,7 @@ public void Update()
Vector3d x = targetOrbit.pos - originOrbit.pos;
Vector3d v = targetOrbit.vel - originOrbit.vel;
double xv = Vector3d.Dot(x, v);
TimeToRendezvous = - xv / Vector3d.SqrMagnitude(v);
TimeToRendezvous = -xv / Vector3d.SqrMagnitude(v);
RelativeRadialVelocity = xv / Vector3d.Magnitude(x);
}

Expand All @@ -228,5 +259,47 @@ private Vector3d GetDescendingNode(Orbit targetOrbit, Orbit originOrbit)
{
return Vector3d.Cross(originOrbit.GetOrbitNormal(), targetOrbit.GetOrbitNormal());
}

//From MechJeb2
//Computes the time required for the given launch location to rotate under the target orbital plane.
//If the latitude is too high for the launch location to ever actually rotate under the target plane,
//returns the time of closest approach to the target plane.
//I have a wonderful proof of this formula which this comment is too short to contain.
private double CalcTimeToPlane(CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target)
{
double inc = Math.Abs(Vector3d.Angle(SwappedOrbitNormal(target), launchBody.angularVelocity));
Vector3d b = Vector3d.Exclude(launchBody.angularVelocity, SwappedOrbitNormal(target)).normalized; // I don't understand the sign here, but this seems to work
b *= launchBody.Radius * Math.Sin(Math.PI / 180 * launchLatitude) / Math.Tan(Math.PI / 180 * inc);
Vector3d c = Vector3d.Cross(SwappedOrbitNormal(target), launchBody.angularVelocity).normalized;
double cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(Math.PI / 180 * launchLatitude), 2) - b.sqrMagnitude;
if (cMagnitudeSquared < 0) cMagnitudeSquared = 0;
c *= Math.Sqrt(cMagnitudeSquared);
Vector3d a1 = b + c;
Vector3d a2 = b - c;

Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude);

double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1));
if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0) angle1 = 360 - angle1;

double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2));
if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0) angle2 = 360 - angle2;

double angle = Math.Min(angle1, angle2);
return (angle / 360) * launchBody.rotationPeriod;
}

//normalized vector perpendicular to the orbital plane
//convention: as you look down along the orbit normal, the satellite revolves counterclockwise
public static Vector3d SwappedOrbitNormal(Orbit o)
{
return -SwapYZ(o.GetOrbitNormal()).normalized;
}

//can probably be replaced with Vector3d.xzy?
public static Vector3d SwapYZ(Vector3d v)
{
return v.xzy;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,17 @@ public override void Draw(SectionModule section)
{
if (RendezvousProcessor.ShowDetails)
{
this.DrawLine(TimeFormatter.ConvertToString(RendezvousProcessor.TimeToAscendingNode), section.IsHud);
if (RendezvousProcessor.isLanded && RendezvousProcessor.inSystem)
{
double time = RendezvousProcessor.TimeToPlane;

if (time > RendezvousProcessor.bodyRotationPeriod / 4)
time = time - RendezvousProcessor.bodyRotationPeriod / 2 ; //let it go negative

this.DrawLine("(L) " + TimeFormatter.ConvertToString(time), section.IsHud);
}
else
this.DrawLine(TimeFormatter.ConvertToString(RendezvousProcessor.TimeToAscendingNode), section.IsHud);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,19 @@ public override void Draw(SectionModule section)
{
if (RendezvousProcessor.ShowDetails)
{
this.DrawLine(TimeFormatter.ConvertToString(RendezvousProcessor.TimeToDescendingNode), section.IsHud);
if (RendezvousProcessor.isLanded && RendezvousProcessor.inSystem)
{
double time = RendezvousProcessor.TimeToPlane;

if (time > RendezvousProcessor.bodyRotationPeriod / 4)
time = time - RendezvousProcessor.bodyRotationPeriod / 2; //let it go negative

time += RendezvousProcessor.bodyRotationPeriod / 2; //show next one.

this.DrawLine("(L) " + TimeFormatter.ConvertToString(time), section.IsHud);
}
else
this.DrawLine(TimeFormatter.ConvertToString(RendezvousProcessor.TimeToDescendingNode), section.IsHud);
}
}

Expand Down
14 changes: 10 additions & 4 deletions KerbalEngineer/Helpers/TimeFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

using System;

namespace KerbalEngineer.Helpers
{
public static class TimeFormatter
Expand All @@ -26,6 +28,10 @@ public static string ConvertToString(double seconds, string format = "F1")
int hours = 0;
int minutes = 0;

bool negative = seconds < 0;

seconds = Math.Abs(seconds);

if (seconds > 0.0)
{
years = (int)(seconds / KSPUtil.dateTimeFormatter.Year);
Expand All @@ -43,18 +49,18 @@ public static string ConvertToString(double seconds, string format = "F1")

if (years > 0)
{
return string.Format("{0}y {1}d {2}h {3}m {4}s", years, days, hours, minutes, seconds.ToString(format));
return (negative ? "-" : "") + string.Format("{0}y {1}d {2}h {3}m {4}s", years, days, hours, minutes, seconds.ToString(format));
}
if (days > 0)
{
return string.Format("{0}d {1}h {2}m {3}s", days, hours, minutes, seconds.ToString(format));
return (negative ? "-" : "") + string.Format("{0}d {1}h {2}m {3}s", days, hours, minutes, seconds.ToString(format));
}
if (hours > 0)
{
return string.Format("{0}h {1}m {2}s", hours, minutes, seconds.ToString(format));
return (negative ? "-" : "") + string.Format("{0}h {1}m {2}s", hours, minutes, seconds.ToString(format));
}

return minutes > 0 ? string.Format("{0}m {1}s", minutes, seconds.ToString(format)) : string.Format("{0}s", seconds.ToString(format));
return (negative ? "-" : "") + (minutes > 0 ? string.Format("{0}m {1}s", minutes, seconds.ToString(format)) : string.Format("{0}s", seconds.ToString(format)));
}
}
}
62 changes: 20 additions & 42 deletions KerbalEngineer/VesselSimulator/PartSim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,56 +237,34 @@ public ResourceContainer Resources
public void CreateEngineSims(List<EngineSim> allEngines, double atmosphere, double mach, bool vectoredThrust, bool fullThrust, LogMsg log)
{
if (log != null) log.AppendLine("CreateEngineSims for ", this.name);
var partMods = this.part.Modules;
var numMods = partMods.Count;
List<ModuleEngines> cacheModuleEngines = part.FindModulesImplementing<ModuleEngines>();

if (hasMultiModeEngine)
try
{
// A multi-mode engine has multiple ModuleEngines but only one is active at any point
// The mode of the engine is the engineID of the ModuleEngines that is (are?) active
string mode = part.GetModule<MultiModeEngine>().mode;

for (int i = 0; i < numMods; i++)
if (cacheModuleEngines.Count > 0)
{
//log.AppendLine("Module: ", partMods[i].moduleName);
var engine = partMods[i] as ModuleEngines;
if (engine != null && engine.engineID == mode)
//find first active engine, assuming that two are never active at the same time
foreach (ModuleEngines engine in cacheModuleEngines)
{
if (log != null) log.AppendLine("Module: ", engine.moduleName);

EngineSim engineSim = EngineSim.New(
this,
engine,
atmosphere,
(float)mach,
vectoredThrust,
fullThrust,
log);
allEngines.Add(engineSim);
if (engine.isEnabled)
{
if (log != null) log.AppendLine("Module: ", engine.moduleName);
EngineSim engineSim = EngineSim.New(
this,
engine,
atmosphere,
(float)mach,
vectoredThrust,
fullThrust,
log);
allEngines.Add(engineSim);
}
}
}
}
else if (hasModuleEngines)
catch
{
for (int i = 0; i < numMods; i++)
{
//log.AppendLine("Module: ", partMods[i].moduleName);
var engine = partMods[i] as ModuleEngines;
if (engine != null)
{
if (log != null) log.AppendLine("Module: ", engine.moduleName);

EngineSim engineSim = EngineSim.New(
this,
engine,
atmosphere,
(float)mach,
vectoredThrust,
fullThrust,
log);
allEngines.Add(engineSim);
}
}
Debug.Log("[KER] Error Catch in CreateEngineSims");
}
}

Expand Down

0 comments on commit 80ce519

Please sign in to comment.