本文整理汇总了C#中Orbit.getOrbitalVelocityAtUT方法的典型用法代码示例。如果您正苦于以下问题:C# Orbit.getOrbitalVelocityAtUT方法的具体用法?C# Orbit.getOrbitalVelocityAtUT怎么用?C# Orbit.getOrbitalVelocityAtUT使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Orbit
的用法示例。
在下文中一共展示了Orbit.getOrbitalVelocityAtUT方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: ApplyVesselUpdate
//.........这里部分代码省略.........
//DarkLog.Debug("Skipping update, physics held");
return;
}
//Don't set the position while the vessel is unpacking / loading - It doesn't apply properly.
if (isUnpacking || isLoading)
{
//DarkLog.Debug("Skipping update, isUnpacking: " + isUnpacking + " isLoading: " + isLoading);
return;
}
if (updateVessel.packed)
{
updateVessel.latitude = update.position[0];
updateVessel.longitude = update.position[1];
updateVessel.altitude = update.position[2];
if (!updateVessel.LandedOrSplashed)
{
//Not landed but under 10km.
Vector3d orbitalPos = updatePostion - updateBody.position;
Vector3d surfaceOrbitVelDiff = updateBody.getRFrmVel(updatePostion);
Vector3d orbitalVel = updateVelocity + surfaceOrbitVelDiff;
updateVessel.orbitDriver.orbit.UpdateFromStateVectors(orbitalPos.xzy, orbitalVel.xzy, updateBody, Planetarium.GetUniversalTime());
updateVessel.orbitDriver.pos = updateVessel.orbitDriver.orbit.pos.xzy;
updateVessel.orbitDriver.vel = updateVessel.orbitDriver.orbit.vel;
/*
DarkLog.Debug("updateVelocity: " + (Vector3)updateVelocity + ", |vel| " + updateVelocity.magnitude);
DarkLog.Debug("surfaceOrbitVelDiff: " + (Vector3)surfaceOrbitVelDiff + ", |vel| " + surfaceOrbitVelDiff.magnitude);
*/
/*
if (HighLogic.LoadedScene == GameScenes.FLIGHT && FlightGlobals.fetch.activeVessel != null)
{
DarkLog.Debug("ourVel: " + (Vector3)FlightGlobals.fetch.activeVessel.orbitDriver.vel + ", |vel| " + updateVessel.orbitDriver.vel.magnitude);
}
DarkLog.Debug("theirVel: " + (Vector3)updateVessel.orbitDriver.vel + ", |vel| " + updateVessel.orbitDriver.vel.magnitude);
*/
}
}
else
{
Vector3d velocityOffset = updateVelocity - updateVessel.srf_velocity;
updateVessel.SetPosition(updatePostion, true);
updateVessel.ChangeWorldVelocity(velocityOffset);
}
}
else
{
Orbit updateOrbit = new Orbit(update.orbit[0], update.orbit[1], update.orbit[2], update.orbit[3], update.orbit[4], update.orbit[5], update.orbit[6], updateBody);
updateOrbit.Init();
updateOrbit.UpdateFromUT(Planetarium.GetUniversalTime());
if (updateVessel.packed)
{
//The OrbitDriver update call will set the vessel position on the next fixed update
CopyOrbit(updateOrbit, updateVessel.orbitDriver.orbit);
updateVessel.orbitDriver.pos = updateVessel.orbitDriver.orbit.pos.xzy;
updateVessel.orbitDriver.vel = updateVessel.orbitDriver.orbit.vel;
}
else
{
//Vessel.SetPosition is full of fun and games. Avoid at all costs.
//Also, It's quite difficult to figure out the world velocity due to Krakensbane, and the reference frame.
Vector3d posDelta = updateOrbit.getPositionAtUT(Planetarium.GetUniversalTime()) - updateVessel.orbitDriver.orbit.getPositionAtUT(Planetarium.GetUniversalTime());
Vector3d velDelta = updateOrbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy - updateVessel.orbitDriver.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy;
//Vector3d velDelta = updateOrbit.vel.xzy - updateVessel.orbitDriver.orbit.vel.xzy;
updateVessel.Translate(posDelta);
updateVessel.ChangeWorldVelocity(velDelta);
}
}
//Angular velocity
Vector3 angularVelocity = new Vector3(update.angularVelocity[0], update.angularVelocity[1], update.angularVelocity[2]);
if (updateVessel.parts != null)
{
Vector3 newAng = updateVessel.ReferenceTransform.rotation * angularVelocity;
foreach (Part vesselPart in updateVessel.parts)
{
if (vesselPart.rb != null && !vesselPart.rb.isKinematic && vesselPart.State == PartStates.ACTIVE)
{
//The parts can have different rotations - This transforms them into the root part direction which is where the angular velocity is transferred.
vesselPart.rb.angularVelocity = (Quaternion.Inverse(updateVessel.rootPart.rb.rotation) * vesselPart.rb.rotation) * newAng;
}
}
}
//Flight state controls (Throttle etc)
if (!isSpectating)
{
updateVessel.ctrlState.CopyFrom(update.flightState);
}
else
{
FlightInputHandler.state.CopyFrom(update.flightState);
}
//Action group controls
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Gear, update.actiongroupControls[0]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Light, update.actiongroupControls[1]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, update.actiongroupControls[2]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, update.actiongroupControls[3]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.RCS, update.actiongroupControls[4]);
}
示例2: timeOfLeastDVBurn
/// <summary>
/// Find the point on the orbit that includes the initial time where the ejection angle is closest to the suplied one
/// </summary>
/// <param name="oObject">Orbit of the vessel/body</param>
/// <param name="timeInitial">The UT you want to search around for the angle - will search 1/2 an orbit back and 1/2 forward</param>
/// <param name="numDivisions">Higher thisnumber the more precise the answer - and the longer it will take</param>
/// <param name="closestAngle">The output of the closest angle the method could find</param>
/// <param name="targetAngle">The ejection angle we are looking for</param>
/// <returns></returns>
internal static double timeOfLeastDVBurn(Orbit oObject, double timeInitial, Vector3d vectTransferInitial, double numDivisions, out Vector3d bestBurnEject)
{
double timeStart = timeInitial - oObject.period;// / 2;
double periodtoscan = oObject.period * 2;
double bestBurnTime = timeStart;
double bestBurnDV = Double.MaxValue;
bestBurnEject = new Vector3d();
double minTime = timeStart;
double maxTime = timeStart + periodtoscan;
//work out iterations for precision - we only really need to within a second - so how many iterations do we actually need
//Each iteration gets us 1/10th of the period to scan
LogFormatted("B");
try
{
System.IO.File.Delete(Resources.PathPlugin + "/DVTest.csv");
}
catch (Exception)
{
}
System.IO.File.AppendAllText(Resources.PathPlugin + "/DVTest.csv", "T,DV,Vect\r\n");
for (int iter = 0; iter < 10; iter++)
{
LogFormatted("Start:{0} - Stop:{1}", minTime, maxTime);
double dt = (maxTime - minTime) / numDivisions;
for (int i = 0; i < numDivisions; i++)
{
double t = minTime + i * dt;
//get the vessels velocity at the right time
Vector3d vel = oObject.getOrbitalVelocityAtUT(t);
Vector3d velPlanet = oObject.referenceBody.orbit.getOrbitalVelocityAtUT(t);
Vector3d velall = vel+velPlanet;
Vector3d Eject = vectTransferInitial - velall;
System.IO.File.AppendAllText(Resources.PathPlugin + "/DVTest.csv", String.Format("{0},{1},{2}\r\n",t,Eject.magnitude,Eject));
if (Math.Abs(Eject.magnitude) < bestBurnDV)
{
bestBurnDV = Math.Abs(Eject.magnitude);
bestBurnTime = t;
bestBurnEject = Eject;
LogFormatted("{0}-{1}-{2}", velall.magnitude, bestBurnEject.magnitude, t);
}
}
minTime = (bestBurnTime - dt).Clamp(timeStart, timeStart + periodtoscan);
maxTime = (bestBurnTime + dt).Clamp(timeStart, timeStart + periodtoscan);
}
return bestBurnTime;
}
示例3: Apply
//.........这里部分代码省略.........
updateVessel.protoVessel.altitude = altitude;
if (updateVessel.packed)
{
if (!updateVessel.LandedOrSplashed)
{
//Not landed but under 10km.
Vector3d orbitalPos = updatePostion - updateBody.position;
Vector3d surfaceOrbitVelDiff = updateBody.getRFrmVel(updatePostion);
Vector3d orbitalVel = updateVelocity + surfaceOrbitVelDiff;
updateVessel.orbitDriver.orbit.UpdateFromStateVectors(orbitalPos.xzy, orbitalVel.xzy, updateBody, Planetarium.GetUniversalTime());
updateVessel.orbitDriver.pos = updateVessel.orbitDriver.orbit.pos.xzy;
updateVessel.orbitDriver.vel = updateVessel.orbitDriver.orbit.vel;
}
}
else
{
Vector3d velocityOffset = updateVelocity - updateVessel.srf_velocity;
updateVessel.SetPosition(updatePostion, true);
updateVessel.ChangeWorldVelocity(velocityOffset);
}
}
else
{
Orbit updateOrbit = new Orbit(orbit[0], orbit[1], orbit[2], orbit[3], orbit[4], orbit[5], orbit[6], updateBody);
updateOrbit.Init();
updateOrbit.UpdateFromUT(Planetarium.GetUniversalTime());
double latitude = updateBody.GetLatitude(updateOrbit.pos);
double longitude = updateBody.GetLongitude(updateOrbit.pos);
double altitude = updateBody.GetAltitude(updateOrbit.pos);
updateVessel.latitude = latitude;
updateVessel.longitude = longitude;
updateVessel.altitude = altitude;
updateVessel.protoVessel.latitude = latitude;
updateVessel.protoVessel.longitude = longitude;
updateVessel.protoVessel.altitude = altitude;
if (updateVessel.packed)
{
//The OrbitDriver update call will set the vessel position on the next fixed update
VesselUtil.CopyOrbit(updateOrbit, updateVessel.orbitDriver.orbit);
updateVessel.orbitDriver.pos = updateVessel.orbitDriver.orbit.pos.xzy;
updateVessel.orbitDriver.vel = updateVessel.orbitDriver.orbit.vel;
}
else
{
//Vessel.SetPosition is full of fun and games. Avoid at all costs.
//Also, It's quite difficult to figure out the world velocity due to Krakensbane, and the reference frame.
Vector3d posDelta = updateOrbit.getPositionAtUT(Planetarium.GetUniversalTime()) - updateVessel.orbitDriver.orbit.getPositionAtUT(Planetarium.GetUniversalTime());
Vector3d velDelta = updateOrbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy - updateVessel.orbitDriver.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy;
//Vector3d velDelta = updateOrbit.vel.xzy - updateVessel.orbitDriver.orbit.vel.xzy;
updateVessel.Translate(posDelta);
updateVessel.ChangeWorldVelocity(velDelta);
}
}
//Rotation
Quaternion unfudgedRotation = new Quaternion(rotation[0], rotation[1], rotation[2], rotation[3]);
Quaternion updateRotation = normalRotate * unfudgedRotation;
updateVessel.SetRotation(updateVessel.mainBody.bodyTransform.rotation * updateRotation);
if (updateVessel.packed)
{
updateVessel.srfRelRotation = updateRotation;
updateVessel.protoVessel.rotation = updateVessel.srfRelRotation;
}
//Angular velocity
//Vector3 angularVelocity = new Vector3(this.angularVelocity[0], this.angularVelocity[1], this.angularVelocity[2]);
if (updateVessel.parts != null)
{
//Vector3 newAng = updateVessel.ReferenceTransform.rotation * angularVelocity;
foreach (Part vesselPart in updateVessel.parts)
{
if (vesselPart.rb != null && !vesselPart.rb.isKinematic && vesselPart.State == PartStates.ACTIVE)
{
//The parts can have different rotations - This transforms them into the root part direction which is where the angular velocity is transferred.
//vesselPart.rb.angularVelocity = (Quaternion.Inverse(updateVessel.rootPart.rb.rotation) * vesselPart.rb.rotation) * newAng;
vesselPart.rb.angularVelocity = Vector3.zero;
}
}
}
//Flight state controls (Throttle etc)
if (!VesselWorker.fetch.isSpectating)
{
updateVessel.ctrlState.CopyFrom(flightState);
}
else
{
FlightInputHandler.state.CopyFrom(flightState);
}
//Action group controls
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Gear, actiongroupControls[0]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Light, actiongroupControls[1]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, actiongroupControls[2]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, actiongroupControls[3]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.RCS, actiongroupControls[4]);
}
示例4: UpdateFromOrbitAtUT
public void UpdateFromOrbitAtUT(Orbit orbit, double UT, CelestialBody toBody)
{
pos = (orbit.getTruePositionAtUT(UT) - toBody.getTruePositionAtUT(UT)).xzy;
vel = orbit.getOrbitalVelocityAtUT(UT) + orbit.referenceBody.GetFrameVelAtUT(UT) - toBody.GetFrameVelAtUT(UT);
UpdateFromStateVectors(pos, vel, toBody, UT);
}
示例5: CreateRandomOrbitFlyBy
public static Orbit CreateRandomOrbitFlyBy(Orbit targetOrbit, double timeToPeriapsis, double periapsis, double deltaVatPeriapsis)
{
double universalTime = Planetarium.GetUniversalTime();
Vector3d relativePositionAtUT = targetOrbit.getRelativePositionAtUT(universalTime + timeToPeriapsis);
Vector3d orbitalVelocityAtUT = targetOrbit.getOrbitalVelocityAtUT(universalTime + timeToPeriapsis);
Orbit orbit = new Orbit();
Vector3d vector3d = relativePositionAtUT + (Vector3d)UnityEngine.Random.onUnitSphere * periapsis;
Vector3d vector3d2 = orbitalVelocityAtUT + (orbitalVelocityAtUT.normalized + UnityEngine.Random.onUnitSphere) * deltaVatPeriapsis;
orbit.UpdateFromStateVectors(vector3d, vector3d2, targetOrbit.referenceBody, universalTime + timeToPeriapsis);
return orbit;
}
示例6: mergeBurnVectors
// calculation function for mergeNodeDown
private static Vector3d mergeBurnVectors(double UT, ManeuverNode first, Orbit projOrbit)
{
Orbit curOrbit = first.findPreviousOrbit();
return difference(curOrbit.getOrbitalVelocityAtUT(UT), projOrbit.getOrbitalVelocityAtUT(UT));
}
示例7: ApplyVesselUpdate
private void ApplyVesselUpdate(VesselUpdate update)
{
if (HighLogic.LoadedScene == GameScenes.LOADING)
{
return;
}
//Get updating player
string updatePlayer = LockSystem.fetch.LockExists(update.vesselID) ? LockSystem.fetch.LockOwner(update.vesselID) : "Unknown";
//Ignore updates to our own vessel
if (!isSpectating && (FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.id.ToString() == update.vesselID : false))
{
DarkLog.Debug("ApplyVesselUpdate - Ignoring update for active vessel from " + updatePlayer);
return;
}
Vessel updateVessel = FlightGlobals.fetch.vessels.FindLast(v => v.id.ToString() == update.vesselID);
if (updateVessel == null)
{
//DarkLog.Debug("ApplyVesselUpdate - Got vessel update for " + update.vesselID + " but vessel does not exist");
return;
}
CelestialBody updateBody = FlightGlobals.Bodies.Find(b => b.bodyName == update.bodyName);
if (updateBody == null)
{
DarkLog.Debug("ApplyVesselUpdate - updateBody not found");
return;
}
if (update.isSurfaceUpdate)
{
double updateDistance = Double.PositiveInfinity;
if ((HighLogic.LoadedScene == GameScenes.FLIGHT) && (FlightGlobals.fetch.activeVessel != null))
{
updateDistance = Vector3.Distance(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), updateVessel.GetWorldPos3D());
}
bool isUnpacking = (updateDistance < updateVessel.distanceUnpackThreshold) && updateVessel.packed;
if (!updateVessel.packed && !isUnpacking)
{
Vector3d updatePostion = updateBody.GetWorldSurfacePosition(update.position[0], update.position[1], update.position[2]);
Vector3d updateVelocity = new Vector3d(update.velocity[0], update.velocity[1], update.velocity[2]);
Vector3d velocityOffset = updateVelocity - updateVessel.srf_velocity;
updateVessel.SetPosition(updatePostion);
updateVessel.ChangeWorldVelocity(velocityOffset);
}
}
else
{
Orbit updateOrbit = new Orbit(update.orbit[0], update.orbit[1], update.orbit[2], update.orbit[3], update.orbit[4], update.orbit[5], update.orbit[6], updateBody);
if (updateVessel.packed)
{
CopyOrbit(updateOrbit, updateVessel.orbitDriver.orbit);
}
else
{
updateVessel.SetPosition(updateOrbit.getPositionAtUT(Planetarium.GetUniversalTime()));
Vector3d velocityOffset = updateOrbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy - updateVessel.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy;
updateVessel.ChangeWorldVelocity(velocityOffset);
}
}
//Quaternion updateRotation = new Quaternion(update.rotation[0], update.rotation[1], update.rotation[2], update.rotation[3]);
//updateVessel.SetRotation(updateRotation);
Vector3 vesselForward = new Vector3(update.vesselForward[0], update.vesselForward[1], update.vesselForward[2]);
Vector3 vesselUp = new Vector3(update.vesselUp[0], update.vesselUp[1], update.vesselUp[2]);
updateVessel.transform.LookAt(updateVessel.transform.position + updateVessel.mainBody.transform.TransformDirection(vesselForward).normalized, updateVessel.mainBody.transform.TransformDirection(vesselUp));
updateVessel.SetRotation(updateVessel.transform.rotation);
if (!updateVessel.packed)
{
updateVessel.angularVelocity = new Vector3(update.angularVelocity[0], update.angularVelocity[1], update.angularVelocity[2]);
}
if (!isSpectating)
{
updateVessel.ctrlState.CopyFrom(update.flightState);
}
else
{
FlightInputHandler.state.CopyFrom(update.flightState);
}
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Gear, update.actiongroupControls[0]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Light, update.actiongroupControls[1]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, update.actiongroupControls[2]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, update.actiongroupControls[3]);
updateVessel.ActionGroups.SetGroup(KSPActionGroup.RCS, update.actiongroupControls[4]);
}
示例8: RTNFrame
// Quaternion functions used by reference frames
// RTN Frame
// Calculate RTN frame quaternion given an orbit and UT
public static Quaternion RTNFrame(Orbit orbit, double UT)
{
// Position
var r = orbit.getRelativePositionAtUT(UT).normalized.xzy;
// Velocity
var v = orbit.getOrbitalVelocityAtUT(UT).normalized.xzy;
// Unit orbit angular momentum
var h = Vector3d.Cross(r, v).normalized;
// Tangential
var t = Vector3d.Cross(h, r).normalized;
// QRTN
return Quaternion.LookRotation(t, r);
}
示例9: ComputeManeuverTime
public double ComputeManeuverTime(Orbit o, double UT, MechJebModuleTargetController target)
{
switch (allowedTimeRef[currentTimeRef])
{
case TimeReference.X_FROM_NOW:
UT += leadTime.val;
break;
case TimeReference.APOAPSIS:
if (o.eccentricity < 1)
{
UT = o.NextApoapsisTime(UT);
}
else
{
throw new OperationException("Warning: orbit is hyperbolic, so apoapsis doesn't exist.");
}
break;
case TimeReference.PERIAPSIS:
UT = o.NextPeriapsisTime(UT);
break;
case TimeReference.CLOSEST_APPROACH:
if (target.NormalTargetExists)
{
UT = o.NextClosestApproachTime(target.TargetOrbit, UT);
}
else
{
throw new OperationException("Warning: no target selected.");
}
break;
case TimeReference.ALTITUDE:
if (circularizeAltitude > o.PeA && (circularizeAltitude < o.ApA || o.eccentricity >= 1))
{
UT = o.NextTimeOfRadius(UT, o.referenceBody.Radius + circularizeAltitude);
}
else
{
throw new OperationException("Warning: can't circularize at this altitude, since current orbit does not reach it.");
}
break;
case TimeReference.EQ_ASCENDING:
if (o.AscendingNodeEquatorialExists())
{
UT = o.TimeOfAscendingNodeEquatorial(UT);
}
else
{
throw new OperationException("Warning: equatorial ascending node doesn't exist.");
}
break;
case TimeReference.EQ_DESCENDING:
if (o.DescendingNodeEquatorialExists())
{
UT = o.TimeOfDescendingNodeEquatorial(UT);
}
else
{
throw new OperationException("Warning: equatorial descending node doesn't exist.");
}
break;
case TimeReference.EQ_NEAREST_AD:
if(o.AscendingNodeEquatorialExists())
{
UT = o.DescendingNodeEquatorialExists()
? System.Math.Min(o.TimeOfAscendingNodeEquatorial(UT), o.TimeOfDescendingNodeEquatorial(UT))
: o.TimeOfAscendingNodeEquatorial(UT);
}
else if(o.DescendingNodeEquatorialExists())
{
UT = o.TimeOfDescendingNodeEquatorial(UT);
}
else
{
throw new OperationException("Warning: neither ascending nor descending node exists.");
}
break;
case TimeReference.EQ_HIGHEST_AD:
if(o.AscendingNodeEquatorialExists())
{
if(o.DescendingNodeEquatorialExists())
{
var anTime = o.TimeOfAscendingNodeEquatorial(UT);
var dnTime = o.TimeOfDescendingNodeEquatorial(UT);
UT = o.getOrbitalVelocityAtUT(anTime).magnitude <= o.getOrbitalVelocityAtUT(dnTime).magnitude
? anTime
: dnTime;
}
else
{
UT = o.TimeOfAscendingNodeEquatorial(UT);
}
}
//.........这里部分代码省略.........
示例10: ICNFrame
// In-track/Cross-track/normal frame
// Calculate ICN frame from orbit and universal time
public static Quaternion ICNFrame(Orbit orbit, double UT)
{
// Unit position
var r = orbit.getRelativePositionAtUT(UT).normalized.xzy;
// Unit velocity
var v = orbit.getOrbitalVelocityAtUT(UT).normalized.xzy;
// Unit orbit angular momentum
var h = Vector3d.Cross(r, v).normalized;
// Cross track unit vector
var c = Vector3d.Cross(h, v).normalized;
// QICN
return Quaternion.LookRotation(c,v);
}
示例11: projectFreefallEndTime
//In a landing, we are going to free fall some way and then either hit atmosphere or start
//decelerating with thrust. Until that happens we can project the orbit forward along a conic section.
//Given an orbit, this function figures out the time at which the free-fall phase will end
double projectFreefallEndTime(Orbit offsetOrbit, double startTime)
{
Vector3d currentPosition = offsetOrbit.getAbsolutePositionAtUT(startTime);
double currentAltitude = FlightGlobals.getAltitudeAtPos(currentPosition);
//check if we are already in the atmosphere or below the deceleration burn end altitude
if (currentAltitude < part.vessel.mainBody.maxAtmosphereAltitude || currentAltitude < decelerationEndAltitudeASL)
{
return vesselState.time;
}
Vector3d currentOrbitVelocity = offsetOrbit.getOrbitalVelocityAtUT(startTime);
Vector3d currentSurfaceVelocity = currentOrbitVelocity - part.vessel.mainBody.getRFrmVel(currentPosition);
//check if we already should be decelerating or will be momentarily:
//that is, if our velocity is downward and our speed is close to the nominal deceleration speed
if (Vector3d.Dot(currentSurfaceVelocity, currentPosition - part.vessel.mainBody.position) < 0
&& currentSurfaceVelocity.magnitude > 0.9 * decelerationSpeed(currentAltitude, vesselState.maxThrustAccel, part.vessel.mainBody))
{
return vesselState.time;
}
//check if the orbit reenters at all
double timeToPe = offsetOrbit.timeToPe;
Vector3d periapsisPosition = offsetOrbit.getAbsolutePositionAtUT(startTime + timeToPe);
if (FlightGlobals.getAltitudeAtPos(periapsisPosition) > part.vessel.mainBody.maxAtmosphereAltitude)
{
return startTime + timeToPe; //return the time of periapsis as a next best number
}
//determine time & velocity of reentry
double minReentryTime = startTime;
double maxReentryTime = startTime + timeToPe;
while (maxReentryTime - minReentryTime > 1.0)
{
double test = (maxReentryTime + minReentryTime) / 2.0;
Vector3d testPosition = offsetOrbit.getAbsolutePositionAtUT(test);
double testAltitude = FlightGlobals.getAltitudeAtPos(testPosition);
Vector3d testOrbitVelocity = offsetOrbit.getOrbitalVelocityAtUT(test);
Vector3d testSurfaceVelocity = testOrbitVelocity - part.vessel.mainBody.getRFrmVel(testPosition);
double testSpeed = testSurfaceVelocity.magnitude;
if (Vector3d.Dot(testSurfaceVelocity, testPosition - part.vessel.mainBody.position) < 0 &&
(testAltitude < part.vessel.mainBody.maxAtmosphereAltitude
|| testAltitude < decelerationEndAltitudeASL
|| testSpeed > 0.9 * decelerationSpeed(testAltitude, vesselState.maxThrustAccel, part.vessel.mainBody)))
{
maxReentryTime = test;
}
else
{
minReentryTime = test;
}
}
return (maxReentryTime + minReentryTime) / 2;
}
示例12: CalculateTargetLine
public void CalculateTargetLine()
{
// Selected target
var target = FlightGlobals.fetch.VesselTarget;
// If a target is selected...
if (target != null) {
orbitT = target.GetOrbit(); // Target orbit
// Spacecraft relative position at UTf
rFinalRel = orbitf.getRelativePositionAtUT(UTf).xzy;
// Target relative position at UTf
rTargetFinalRel = orbitT.getRelativePositionAtUT(UTf).xzy;
// Distance to target at UTf
targetD = Vector3d.Distance(rFinalRel, rTargetFinalRel);
// Relative speed to target at UTf
targetV = Vector3d.Distance(orbitf.getOrbitalVelocityAtUT(UTf), orbitT.getOrbitalVelocityAtUT(UTf));
// Destroy current line if present
if (lineT != null) {
UnityEngine.Object.Destroy(lineT);
}
// Make line to target at UTf
var objT = new GameObject("Line to target");
lineT = objT.AddComponent<LineRenderer>();
lineT.useWorldSpace = false;
objT.layer = 10; // Map
lineT.material = MapView.fetch.orbitLinesMaterial;
lineT.SetColors(Color.red, Color.red);
lineT.SetVertexCount(2);
// Target errors
ApErr = orbitf.ApR - orbitT.ApR;
PeErr = orbitf.PeR - orbitT.PeR;
TPErr = orbitf.period - orbitT.period;
IncErr = orbitf.inclination - orbitT.inclination;
EccErr = orbitf.eccentricity - orbitT.eccentricity;
LANErr = orbitf.LAN - orbitT.LAN;
AOPErr = orbitf.argumentOfPeriapsis - orbitT.argumentOfPeriapsis;
}
}
示例13: ComputeEjectionManeuver
static ManeuverParameters ComputeEjectionManeuver(Vector3d exit_velocity, Orbit initial_orbit, double UT_0)
{
double GM = initial_orbit.referenceBody.gravParameter;
double C3 = exit_velocity.sqrMagnitude;
double sma = -GM / C3;
double Rpe = initial_orbit.semiMajorAxis;
double ecc = 1 - Rpe / sma;
double theta = Math.Acos(-1 / ecc);
Vector3d intersect_1;
Vector3d intersect_2;
// intersect_1 is the optimal position on the orbit assuming the orbit is circular and the sphere of influence is infinite
IntersectConePlane(exit_velocity, theta, initial_orbit.h, out intersect_1, out intersect_2);
Vector3d eccvec = initial_orbit.GetEccVector();
double true_anomaly = AngleAboutAxis(eccvec, intersect_1, initial_orbit.h);
// GetMeanAnomalyAtTrueAnomaly expects degrees and returns radians
double mean_anomaly = initial_orbit.GetMeanAnomalyAtTrueAnomaly(true_anomaly * 180 / Math.PI);
double delta_mean_anomaly = MuUtils.ClampRadiansPi(mean_anomaly - initial_orbit.MeanAnomalyAtUT(UT_0));
double UT = UT_0 + delta_mean_anomaly / initial_orbit.MeanMotion();
Vector3d V_0 = initial_orbit.getOrbitalVelocityAtUT(UT);
Vector3d pos = initial_orbit.getRelativePositionAtUT(UT);
double final_vel = Math.Sqrt(C3 + 2 * GM / pos.magnitude);
Vector3d x = pos.normalized;
Vector3d z = Vector3d.Cross(x, exit_velocity).normalized;
Vector3d y = Vector3d.Cross(z, x);
theta = Math.PI / 2;
double dtheta = 0.001;
Orbit sample = new Orbit();
double theta_err = Double.MaxValue;
for (int iteration = 0 ; iteration < 50 ; ++iteration)
{
Vector3d V_1 = final_vel * (Math.Cos(theta) * x + Math.Sin(theta) * y);
sample.UpdateFromStateVectors(pos, V_1, initial_orbit.referenceBody, UT);
theta_err = AngleAboutAxis(exit_velocity, sample.getOrbitalVelocityAtUT(OrbitExtensions.NextTimeOfRadius(sample, UT, sample.referenceBody.sphereOfInfluence)), z);
if (double.IsNaN(theta_err))
return null;
if (Math.Abs(theta_err) <= Math.PI / 1800)
return new ManeuverParameters((V_1 - V_0).xzy, UT);
V_1 = final_vel * (Math.Cos(theta + dtheta) * x + Math.Sin(theta + dtheta) * y);
sample.UpdateFromStateVectors(pos, V_1, initial_orbit.referenceBody, UT);
double theta_err_2 = AngleAboutAxis(exit_velocity, sample.getOrbitalVelocityAtUT(OrbitExtensions.NextTimeOfRadius(sample, UT, sample.referenceBody.sphereOfInfluence)), z);
V_1 = final_vel * (Math.Cos(theta - dtheta) * x + Math.Sin(theta - dtheta) * y);
sample.UpdateFromStateVectors(pos, V_1, initial_orbit.referenceBody, UT);
double theta_err_3 = AngleAboutAxis(exit_velocity, sample.getOrbitalVelocityAtUT(OrbitExtensions.NextTimeOfRadius(sample, UT, sample.referenceBody.sphereOfInfluence)), z);
double derr = MuUtils.ClampRadiansPi(theta_err_2 - theta_err_3) / (2 * dtheta);
theta = MuUtils.ClampRadiansTwoPi(theta - theta_err / derr);
// if theta > pi, replace with 2pi - theta, the function ejection_angle=f(theta) is symmetrc wrt theta=pi
if (theta > Math.PI)
theta = 2 * Math.PI - theta;
}
return null;
}
示例14: ComputeEjectionManeuver
public static ManeuverParameters ComputeEjectionManeuver(Vector3d exit_velocity, Orbit initial_orbit, double UT_0)
{
double GM = initial_orbit.referenceBody.gravParameter;
double C3 = exit_velocity.sqrMagnitude;
double Mh = initial_orbit.referenceBody.sphereOfInfluence;
double Rpe = initial_orbit.semiMajorAxis;
double isma = 2 / Mh - C3 / GM; //inverted Semi-major Axis, will work for parabolic orbit
double ecc = 1.0 - Rpe * isma;
//double vstart = Math.Sqrt(GM * (2 / Rpe - isma)); //{ total start boost}
//double slat = Rpe * Rpe * vstart * vstart / GM;
//the problem here should be R for circular orbit instead of Rpe
double slat = 2 * Rpe - isma * Rpe * Rpe; //but we don't know start point (yet) in elliptic orbit
double theta = Math.Acos((slat / Mh - 1) / ecc);
/*
//old way infinity hyperbolic:
//problems: it's not necessary hyperbolic (in case of low speed exit_velocity),
//and exit_velocity appears not infinite far from celestial body, but only sphereOfInfluence far
//i.e. Mh in previous statements(theta, isma) is not infinity!
double sma = -GM / C3;
double ecc = 1 - Rpe / sma;
double theta = Math.Acos(-1 / ecc);
*/
Vector3d intersect_1;
Vector3d intersect_2;
// intersect_1 is the optimal position on the orbit assuming the orbit is circular and the sphere of influence is infinite
IntersectConePlane(exit_velocity, theta, initial_orbit.h, out intersect_1, out intersect_2);
Vector3d eccvec = initial_orbit.GetEccVector();
double true_anomaly = AngleAboutAxis(eccvec, intersect_1, initial_orbit.h);
// GetMeanAnomalyAtTrueAnomaly expects degrees and returns radians
double mean_anomaly = initial_orbit.GetMeanAnomalyAtTrueAnomaly(true_anomaly * 180 / Math.PI);
double delta_mean_anomaly = MuUtils.ClampRadiansPi(mean_anomaly - initial_orbit.MeanAnomalyAtUT(UT_0));
double UT = UT_0 + delta_mean_anomaly / initial_orbit.MeanMotion();
Vector3d V_0 = initial_orbit.getOrbitalVelocityAtUT(UT);
Vector3d pos = initial_orbit.getRelativePositionAtUT(UT);
double final_vel = Math.Sqrt(C3 + 2 * GM / pos.magnitude);
Vector3d x = pos.normalized;
Vector3d z = Vector3d.Cross(x, exit_velocity).normalized;
Vector3d y = Vector3d.Cross(z, x);
theta = Math.PI / 2;
double dtheta = 0.001;
Orbit sample = new Orbit();
double theta_err = Double.MaxValue;
for (int iteration = 0 ; iteration < 50 ; ++iteration)
{
Vector3d V_1 = final_vel * (Math.Cos(theta) * x + Math.Sin(theta) * y);
sample.UpdateFromStateVectors(pos, V_1, initial_orbit.referenceBody, UT);
theta_err = AngleAboutAxis(exit_velocity, sample.getOrbitalVelocityAtUT(OrbitExtensions.NextTimeOfRadius(sample, UT, sample.referenceBody.sphereOfInfluence)), z);
if (double.IsNaN(theta_err))
return null;
if (Math.Abs(theta_err) <= Math.PI / 1800)
return new ManeuverParameters((V_1 - V_0).xzy, UT);
V_1 = final_vel * (Math.Cos(theta + dtheta) * x + Math.Sin(theta + dtheta) * y);
sample.UpdateFromStateVectors(pos, V_1, initial_orbit.referenceBody, UT);
double theta_err_2 = AngleAboutAxis(exit_velocity, sample.getOrbitalVelocityAtUT(OrbitExtensions.NextTimeOfRadius(sample, UT, sample.referenceBody.sphereOfInfluence)), z);
V_1 = final_vel * (Math.Cos(theta - dtheta) * x + Math.Sin(theta - dtheta) * y);
sample.UpdateFromStateVectors(pos, V_1, initial_orbit.referenceBody, UT);
double theta_err_3 = AngleAboutAxis(exit_velocity, sample.getOrbitalVelocityAtUT(OrbitExtensions.NextTimeOfRadius(sample, UT, sample.referenceBody.sphereOfInfluence)), z);
double derr = MuUtils.ClampRadiansPi(theta_err_2 - theta_err_3) / (2 * dtheta);
theta = MuUtils.ClampRadiansTwoPi(theta - theta_err / derr);
// if theta > pi, replace with 2pi - theta, the function ejection_angle=f(theta) is symmetrc wrt theta=pi
if (theta > Math.PI)
theta = 2 * Math.PI - theta;
}
return null;
}