public void AddComputerModuleLater(ComputerModule module) { //The actual loading is delayed to FixedUpdate because AddComputerModule can get called inside a foreach loop //over the modules, and modifying the list during the loop will cause an exception. Maybe there is a better //way to deal with this? modulesToLoad.Add(module); }
public T GetComputerModule <T>() where T : ComputerModule { for (int i = 0; i < unorderedComputerModules.Count; i++) { ComputerModule pm = unorderedComputerModules[i]; T module = pm as T; if (module != null) { return(module); } } return(null); }
public bool RecursiveUser(object user) { if (base.Contains(user)) { return(true); } else { foreach (object o in this) { ComputerModule c = o as ComputerModule; if (c != null && c != controlledModule) { if (c.users.RecursiveUser(user)) { return(true); } } } return(false); } }
public void RemoveComputerModule(ComputerModule module) { unorderedComputerModules.Remove(module); ClearModulesCache(); }
public bool landActivate(ComputerModule controller, double touchdownSpeed = 0.5) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } trans_land_touchdown_speed = touchdownSpeed; if (trans_land) { return true; } trans_land = true; trans_land_gears = false; tmode = TMode.KEEP_VERTICAL; return true; }
public bool controlClaim(ComputerModule newController, bool force = false) { if (controlModule == newController) { return true; } if (!controlRelease(newController, force)) { return false; } _controlModule = newController; return true; }
public bool attitudeTo(Quaternion attitude, AttitudeReference reference, ComputerModule controller) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } attitudeReference = reference; attitudeTarget = attitude; _attitudeActive = true; _attitudeRollMatters = true; return true; }
private void drive(FlightCtrlState s) { stress = 0; if (part.State == PartStates.DEAD) { return; } if (controlModule != null) { if (controlModule.enabled) { controlModule.drive(s); } else { _controlModule = null; } } if (TimeWarp.CurrentRate > TimeWarp.MaxPhysicsRate) { return; } if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0)) { double spd = 0; if (trans_land) { if (part.vessel.Landed || part.vessel.Splashed) { tmode = TMode.OFF; trans_land = false; } else { tmode = TMode.KEEP_VERTICAL; trans_kill_h = true; double minalt = Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue); if (vesselState.maxThrustAccel < vesselState.gravityForce.magnitude) { trans_spd_act = 0; } else { trans_spd_act = (float)-Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.50F; } if (!trans_land_gears && (minalt < 1000)) { foreach (Part p in part.vessel.parts) { if (p is LandingLeg) { LandingLeg l = (LandingLeg)p; if (l.legState == LandingLeg.LegStates.RETRACTED) { l.DeployOnActivate = true; l.force_activate(); } } } trans_land_gears = true; } if (minalt < 200) { minalt = Math.Min(vesselState.altitudeBottom, minalt); trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * 200) * 0.50F, (float)minalt / 200); trans_spd_act = (float)Math.Min(-trans_land_touchdown_speed, trans_spd_act); // if (minalt < 3.0 * trans_land_touchdown_speed) trans_spd_act = -(float)trans_land_touchdown_speed; /* if ((minalt >= 90) && (vesselState.speedHorizontal > 1)) { trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * 200) * 0.90F, (float)(minalt - 100) / 300); } else { trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * 200) * 0.90F, (float)minalt / 300); } */ } } } switch (tmode) { case TMode.KEEP_ORBITAL: spd = vesselState.speedOrbital; break; case TMode.KEEP_SURFACE: spd = vesselState.speedSurface; break; case TMode.KEEP_VERTICAL: spd = vesselState.speedVertical; Vector3d rot = Vector3d.up; if (trans_kill_h) { Vector3 hsdir = Vector3.Exclude(vesselState.up, part.vessel.orbit.GetVel() - part.vessel.mainBody.getRFrmVel(vesselState.CoM)); Vector3 dir = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * part.vessel.mainBody.GeeASL); if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * part.vessel.mainBody.GeeASL) * 2)) { tmode = TMode.DIRECT; trans_spd_act = 100; rot = -hsdir; } else { if (spd > 0) { rot = vesselState.up; } else { rot = dir.normalized; } } attitudeTo(rot, AttitudeReference.INERTIAL, null); } break; } double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel; t_integral += t_err * TimeWarp.fixedDeltaTime; double t_deriv = (t_err - t_prev_err) / TimeWarp.fixedDeltaTime; double t_act = (t_Kp * t_err) + (t_Ki * t_integral) + (t_Kd * t_deriv); t_prev_err = t_err; double int_error = Math.Abs(Vector3d.Angle(attitudeGetReferenceRotation(attitudeReference) * attitudeTarget * Vector3d.forward, vesselState.forward)); //print("int_error = " + int_error); if ((tmode != TMode.KEEP_VERTICAL) || (int_error < 2) || ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (int_error < 90))) { if (tmode == TMode.DIRECT) { trans_prev_thrust = s.mainThrottle = trans_spd_act / 100.0F; } else { trans_prev_thrust = s.mainThrottle = Mathf.Clamp(trans_prev_thrust + (float)t_act, 0, 1.0F); } } else { if ((int_error >= 2) && (vesselState.torqueThrustPYAvailable > vesselState.torquePYAvailable * 10)) { trans_prev_thrust = s.mainThrottle = 0.1F; } else { trans_prev_thrust = s.mainThrottle = 0; } } } if (attitudeActive) { int userCommanding = (Mathfx.Approx(s.pitch, 0, 0.1F) ? 0 : 1) + (Mathfx.Approx(s.yaw, 0, 0.1F) ? 0 : 2) + (Mathfx.Approx(s.roll, 0, 0.1F) ? 0 : 4); s.killRot = false; Quaternion target = attitudeGetReferenceRotation(attitudeReference) * attitudeTarget; Quaternion delta = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(part.vessel.transform.rotation) * target); /* if (Mathf.Abs(Quaternion.Angle(delta, Quaternion.identity)) > 30) { delta = Quaternion.Slerp(Quaternion.identity, delta, 0.1F); } */ Vector3d deltaEuler = delta.eulerAngles; Vector3d err = new Vector3d((deltaEuler.x > 180) ? (deltaEuler.x - 360.0F) : deltaEuler.x, -((deltaEuler.y > 180) ? (deltaEuler.y - 360.0F) : deltaEuler.y), (deltaEuler.z > 180) ? (deltaEuler.z - 360.0F) : deltaEuler.z) * Math.PI / 180.0F; Vector3d torque = new Vector3d(vesselState.torquePYAvailable + vesselState.torqueThrustPYAvailable * s.mainThrottle, vesselState.torqueRAvailable, vesselState.torquePYAvailable + vesselState.torqueThrustPYAvailable * s.mainThrottle); Vector3d inertia = Vector3d.Scale(MuUtils.Sign(vesselState.angularMomentum) * 1.1, Vector3d.Scale(Vector3d.Scale(vesselState.angularMomentum, vesselState.angularMomentum), MuUtils.Invert(Vector3d.Scale(torque, vesselState.MoI)))); err += MuUtils.Reorder(inertia, 132); err.Scale(Vector3d.Scale(vesselState.MoI, MuUtils.Invert(torque))); integral += err * TimeWarp.fixedDeltaTime; Vector3d deriv = (err - prev_err) / TimeWarp.fixedDeltaTime; act = Kp * err + Ki * integral + Kd * deriv; prev_err = err; if (userCommanding != 0) { if (attitudeKILLROT) { attitudeTo(Quaternion.LookRotation(part.vessel.transform.up, -part.vessel.transform.forward), AttitudeReference.INERTIAL, null); } } if ((userCommanding & 4) > 0) { prev_err = new Vector3d(prev_err.x, prev_err.y, 0); integral = new Vector3d(integral.x, integral.y, 0); if (!attitudeRollMatters) { attitudeTo(Quaternion.LookRotation(attitudeTarget * Vector3d.forward, attitudeWorldToReference(-part.vessel.transform.forward, attitudeReference)), attitudeReference, null); _attitudeRollMatters = false; } } else { if (!double.IsNaN(act.z)) s.roll = Mathf.Clamp(s.roll + act.z, -1.0F, 1.0F); } if ((userCommanding & 3) > 0) { prev_err = new Vector3d(0, 0, prev_err.z); integral = new Vector3d(0, 0, integral.z); } else { if (!double.IsNaN(act.x)) s.pitch = Mathf.Clamp(s.pitch + act.x, -1.0F, 1.0F); if (!double.IsNaN(act.y)) s.yaw = Mathf.Clamp(s.yaw + act.y, -1.0F, 1.0F); } stress = Mathf.Min(Mathf.Abs(act.x), 1.0F) + Mathf.Min(Mathf.Abs(act.y), 1.0F) + Mathf.Min(Mathf.Abs(act.z), 1.0F); } if (double.IsNaN(s.mainThrottle)) { print("MechJeb: caught throttle = NaN"); s.mainThrottle = 0; } }
public bool autoStageActivate(ComputerModule controller, double stagingDelay = 1.0, int stageLimit = 0) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } autoStage = true; autoStageDelay = stagingDelay; autoStageLimit = stageLimit; return true; }
public bool attitudeTo(double heading, double pitch, double roll, ComputerModule controller) { Quaternion attitude = Quaternion.AngleAxis((float)heading, Vector3.up) * Quaternion.AngleAxis(-(float)pitch, Vector3.right) * Quaternion.AngleAxis(-(float)roll, Vector3.forward); return attitudeTo(attitude, MechJebCore.AttitudeReference.SURFACE_NORTH, controller); }
private void drive(FlightCtrlState s) { stress = 0; if (part.State == PartStates.DEAD) { return; } if (controlModule != null) { if (controlModule.enabled) { controlModule.drive(s); } else { _controlModule = null; } } if ((TimeWarp.WarpMode == TimeWarp.Modes.HIGH) && (TimeWarp.CurrentRate > TimeWarp.MaxPhysicsRate)) { return; } driveThrust(s); driveAttitude(s); driveAutoStaging(); if (double.IsNaN(s.mainThrottle)) { print("MechJeb: caught throttle = NaN"); s.mainThrottle = 0; } lastThrottle = s.mainThrottle; }
public void warpTo(ComputerModule controller, double timeLeft, double[] lookaheadTimes, double maxRate = 100000.0) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) return; if ((TimeWarp.WarpMode == TimeWarp.Modes.HIGH) && ((timeLeft < lookaheadTimes[TimeWarp.CurrentRateIndex]) || (timeWarp.warpRates[TimeWarp.CurrentRateIndex] > maxRate))) { warpDecrease(controller, true); } else if ((TimeWarp.CurrentRateIndex < timeWarp.warpRates.Length - 1 && lookaheadTimes[TimeWarp.CurrentRateIndex + 1] < timeLeft && timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= maxRate) || (TimeWarp.WarpMode == TimeWarp.Modes.LOW)) { warpIncrease(controller, false, maxRate); } }
public void warpMinimum(ComputerModule controller, bool instant = false) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) return; if (TimeWarp.CurrentRateIndex <= 0) return; //Somehow setting TimeWarp.SetRate to 0 when already at 0 causes unexpected rapid separation (Kracken) TimeWarp.SetRate(0, instant); }
public bool thrustDeactivate(ComputerModule controller) { /* if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } */ if (tmode == TMode.OFF) { return true; } tmode = TMode.OFF; return true; }
public bool autoStageDeactivate(ComputerModule controller) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } autoStage = false; return true; }
public bool thrustActivate(ComputerModule controller, float value, TMode mode) { /* if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } */ trans_spd_act = value; tmode = mode; return true; }
public bool launch(ComputerModule controller) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } lastStageTime = vesselState.time; if (Staging.CurrentStage == Staging.StageCount) { Staging.ActivateNextStage(); return true; } return false; }
public bool attitudeDeactivate(ComputerModule controller) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } _attitudeActive = false; attitudeChanged = true; return true; }
public void AddComputerModule(ComputerModule module) { computerModules.Add(module); modulesUpdated = true; }
public bool attitudeTo(Vector3d direction, AttitudeReference reference, ComputerModule controller) { bool ok = false; double ang_diff = Math.Abs(Vector3d.Angle(attitudeGetReferenceRotation(attitudeReference) * attitudeTarget * Vector3d.forward, attitudeGetReferenceRotation(reference) * direction)); if (!attitudeActive || (ang_diff > 45)) { ok = attitudeTo(Quaternion.LookRotation(direction, attitudeWorldToReference(-part.vessel.transform.forward, reference)), reference, controller); } else { ok = attitudeTo(Quaternion.LookRotation(direction, attitudeWorldToReference(attitudeReferenceToWorld(attitudeTarget * Vector3d.up, attitudeReference), reference)), reference, controller); } if (ok) { _attitudeRollMatters = false; return true; } else { return false; } }
public void RemoveComputerModule(ComputerModule module) { computerModules.Remove(module); modulesUpdated = true; }
public bool controlRelease(ComputerModule controller, bool force = false) { if (controlModule != null) { controlModule.onControlLost(); } _controlModule = null; attitudeDeactivate(controller); landDeactivate(controller); tmode = TMode.OFF; return true; }
public void warpDecrease(ComputerModule controller, bool instant = true) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) return; if (TimeWarp.CurrentRateIndex > 0 /*&& timeWarp.warpRates[TimeWarp.CurrentRateIndex] == TimeWarp.CurrentRate*/) { TimeWarp.SetRate(TimeWarp.CurrentRateIndex - 1, instant); } }
public bool landDeactivate(ComputerModule controller) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } if (!trans_land) { return true; } trans_land = false; tmode = TMode.OFF; return true; }
public bool warpIncrease(ComputerModule controller, bool instant = true, double maxRate = 10000.0) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) return false; //need to use instantaneous altitude and not the time-averaged vesselState.altitudeASL, //because the game freaks out really hard if you try to violate the altitude limits double instantAltitudeASL = (vesselState.CoM - part.vessel.mainBody.position).magnitude - part.vessel.mainBody.Radius; //conditions to increase warp: //-we are not already at max warp //-the most recent non-instant warp change has completed //-the next warp rate is not greater than maxRate //-we are out of the atmosphere, or the next warp rate is still a physics rate, or we are landed //-increasing the rate is allowed by altitude limits, or we are landed //-we did not increase the warp within the last 2 seconds if (TimeWarp.CurrentRateIndex + 1 < timeWarp.warpRates.Length && (TimeWarp.CurrentRate == 0 || timeWarp.warpRates[TimeWarp.CurrentRateIndex] == TimeWarp.CurrentRate) && timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= maxRate && (instantAltitudeASL > part.vessel.mainBody.maxAtmosphereAltitude || timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= TimeWarp.MaxPhysicsRate || part.vessel.Landed) && (instantAltitudeASL > timeWarp.altitudeLimits[TimeWarp.CurrentRateIndex + 1] * part.vessel.mainBody.Radius || part.vessel.Landed) && vesselState.time - warpIncreaseAttemptTime > 2) { warpIncreaseAttemptTime = vesselState.time; TimeWarp.SetRate(TimeWarp.CurrentRateIndex + 1, instant); return true; } else { return false; } }
public UserPool(ComputerModule controlledModule) : base() { this.controlledModule = controlledModule; }
public void warpMinimum(ComputerModule controller, bool instant = true) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) return; TimeWarp.SetRate(0, instant); }
public void AddComputerModule(ComputerModule module) { unorderedComputerModules.Add(module); ClearModulesCache(); }
public void warpPhysics(ComputerModule controller, bool instant = true) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) return; if (timeWarp.warpRates[TimeWarp.CurrentRateIndex] <= TimeWarp.MaxPhysicsRate) { return; } else { int newIndex = TimeWarp.CurrentRateIndex; while (newIndex > 0 && timeWarp.warpRates[newIndex] > TimeWarp.MaxPhysicsRate) newIndex--; TimeWarp.SetRate(newIndex, instant); } }
public void AddComputerModule(ComputerModule module) { unorderedComputerModules.Add(module); sortedModules.Clear(); }
public void warpTo(ComputerModule controller, double timeLeft, double[] lookaheadTimes, double maxRate = 10000.0) { if (timeLeft < lookaheadTimes[TimeWarp.CurrentRateIndex] || timeWarp.warpRates[TimeWarp.CurrentRateIndex] > maxRate) { warpDecrease(controller, true); } else if (TimeWarp.CurrentRateIndex < timeWarp.warpRates.Length - 1 && lookaheadTimes[TimeWarp.CurrentRateIndex + 1] < timeLeft && timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= maxRate) { warpIncrease(controller, false, maxRate); } }
public void RemoveComputerModule(ComputerModule module) { unorderedComputerModules.Remove(module); sortedModules.Clear(); }
public bool stage(ComputerModule controller) { if ((controlModule != null) && (controller != null) && (controlModule != controller)) { return false; } lastStageTime = vesselState.time; Staging.ActivateNextStage(); return true; }