public void DriveUntargetedLanding(FlightCtrlState s) { if (vessel.LandedOrSplashed) { core.thrust.ThrustOff(); core.thrust.users.Remove(this); StopLanding(); return; } double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue)); if (!deployedGears && (minalt < 1000)) { DeployLandingGears(); } if (vesselState.limitedMaxThrustAccel < vesselState.gravityForce.magnitude) { //if we have TWR < 1, just try as hard as we can to decelerate: //(we need this special case because otherwise the calculations spit out NaN's) core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL; core.thrust.trans_kill_h = true; core.thrust.trans_spd_act = 0; } else if (minalt > 200) { if ((vesselState.velocityVesselSurface.magnitude > 5) && (Vector3d.Angle(vesselState.velocityVesselSurface, vesselState.up) < 80)) { //if we have positive vertical velocity, point up and don't thrust: core.attitude.attitudeTo(Vector3d.up, AttitudeReference.SURFACE_NORTH, null); core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT; core.thrust.trans_spd_act = 0; } else if ((vesselState.velocityVesselSurface.magnitude > 5) && (Vector3d.Angle(vesselState.forward, -vesselState.velocityVesselSurface) > 45)) { //if we're not facing approximately retrograde, turn to point retrograde and don't thrust: core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null); core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT; core.thrust.trans_spd_act = 0; } else { //if we're above 200m, point retrograde and control surface velocity: core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null); core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE; //core.thrust.trans_spd_act = (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.90F; Vector3d estimatedLandingPosition = vesselState.CoM + vesselState.velocityVesselSurface.sqrMagnitude / (2 * vesselState.limitedMaxThrustAccel) * vesselState.velocityVesselSurfaceUnit; double terrainRadius = mainBody.Radius + mainBody.TerrainAltitude(estimatedLandingPosition); IDescentSpeedPolicy aggressivePolicy = new GravityTurnDescentSpeedPolicy(terrainRadius, mainBody.GeeASL * 9.81, vesselState.limitedMaxThrustAccel); core.thrust.trans_spd_act = (float)(aggressivePolicy.MaxAllowedSpeed(vesselState.CoM - mainBody.position, vesselState.velocityVesselSurface)); } } else { //last 200 meters: core.thrust.trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.limitedMaxThrustAccel - vesselState.gravityForce.magnitude) * 2 * 200) * 0.90F, (float)minalt / 200); //take into account desired landing speed: core.thrust.trans_spd_act = (float)Math.Min(-touchdownSpeed, core.thrust.trans_spd_act); if (Math.Abs(Vector3d.Angle(-vesselState.velocityVesselSurface, vesselState.up)) < 10) { //if we're falling more or less straight down, control vertical speed and //kill horizontal velocity core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL; core.thrust.trans_kill_h = true; } else { //if we're falling at a significant angle from vertical, our vertical speed might be //quite small but we might still need to decelerate. Control the total speed instead //by thrusting directly retrograde core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null); core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE; core.thrust.trans_spd_act *= -1; } } status = "Final descent: " + vesselState.altitudeBottom.ToString("F0") + "m above terrain"; }
public void DriveUntargetedLanding(FlightCtrlState s) { if (vessel.LandedOrSplashed) { core.thrust.ThrustOff(); core.thrust.users.Remove(this); StopLanding(); return; } // TODO perhaps we should pop the parachutes at this point, or at least consider it depending on the altitude. double minalt = Math.Min(vesselState.altitudeBottom, Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue)); if (vesselState.limitedMaxThrustAccel < vesselState.gravityForce.magnitude) { //if we have TWR < 1, just try as hard as we can to decelerate: //(we need this special case because otherwise the calculations spit out NaN's) core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL; core.thrust.trans_kill_h = true; core.thrust.trans_spd_act = 0; } else if (minalt > 200) { if ((vessel.srf_velocity.magnitude > 5) && (Vector3d.Angle(vessel.srf_velocity, vesselState.up) < 80)) { //if we have positive vertical velocity, point up and don't thrust: core.attitude.attitudeTo(Vector3d.up, AttitudeReference.SURFACE_NORTH, null); core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT; core.thrust.trans_spd_act = 0; } else if ((vessel.srf_velocity.magnitude > 5) && (Vector3d.Angle(vesselState.forward, -vessel.srf_velocity) > 45)) { //if we're not facing approximately retrograde, turn to point retrograde and don't thrust: core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null); core.thrust.tmode = MechJebModuleThrustController.TMode.DIRECT; core.thrust.trans_spd_act = 0; } else { //if we're above 200m, point retrograde and control surface velocity: core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null); core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE; //core.thrust.trans_spd_act = (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.90F; Vector3d estimatedLandingPosition = vesselState.CoM + vessel.srf_velocity.sqrMagnitude / (2 * vesselState.limitedMaxThrustAccel) * vessel.srf_velocity.normalized; double terrainRadius = mainBody.Radius + mainBody.TerrainAltitude(estimatedLandingPosition); IDescentSpeedPolicy aggressivePolicy = new GravityTurnDescentSpeedPolicy(terrainRadius, mainBody.GeeASL * 9.81, vesselState.limitedMaxThrustAccel); core.thrust.trans_spd_act = (float)(aggressivePolicy.MaxAllowedSpeed(vesselState.CoM - mainBody.position, vessel.srf_velocity)); } } else { //last 200 meters: core.thrust.trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.limitedMaxThrustAccel - vesselState.localg) * 2 * 200) * 0.90F, (float)minalt / 200); //take into account desired landing speed: core.thrust.trans_spd_act = (float)Math.Min(-touchdownSpeed, core.thrust.trans_spd_act); // core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL; // core.thrust.trans_kill_h = true; // if (Math.Abs(Vector3d.Angle(-vessel.srf_velocity, vesselState.up)) < 10) if (vesselState.speedSurfaceHorizontal < 5) { //if we're falling more or less straight down, control vertical speed and //kill horizontal velocity core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_VERTICAL; core.thrust.trans_kill_h = true; } else { //if we're falling at a significant angle from vertical, our vertical speed might be //quite small but we might still need to decelerate. Control the total speed instead //by thrusting directly retrograde core.attitude.attitudeTo(Vector3d.back, AttitudeReference.SURFACE_VELOCITY, null); core.thrust.tmode = MechJebModuleThrustController.TMode.KEEP_SURFACE; core.thrust.trans_spd_act *= -1; } } status = "Final descent: " + vesselState.altitudeBottom.ToString("F0") + "m above terrain"; }