public void FixedUpdate() { if (!(HighLogic.LoadedSceneIsFlight && FlightGlobals.ready)) { return; } vm = vessel.vesselModules.OfType <VesselModuleRotation>().First(); tc = part.Modules.GetModule <ModuleTorqueController>(); rw = part.Modules.GetModule <ModuleReactionWheel>(); angularVelocity = vessel.angularVelocity.magnitude; rollTorque = rw.RollTorque; pitchTorque = rw.PitchTorque; yawTorque = rw.YawTorque; inputVectorDelta = (rw.inputVector * TimeWarp.fixedDeltaTime).ToString("0.0000"); }
// Apply torque in OnFlyByWire because the module FixedUpdate() is called too late, // resulting in a 1 frame lag in torque updates, leading to having torque when you shouldn't. private void UpdateTorque(FlightCtrlState st) { // autopilot can be null just before vessel is destroyed if (vessel.Autopilot == null) { return; } // Not sure why but in some cases the reference the the module can be null if acquired in OnStart. // To be on the safe side we acquire it here if (rwmodule == null) { // Get the reaction wheel module rwmodule = part.Modules.GetModule <ModuleReactionWheel>(); if (rwmodule == null) { return; } // Get the module config torque value maxTorque.x = rwmodule.PitchTorque; maxTorque.y = rwmodule.RollTorque; maxTorque.z = rwmodule.YawTorque; // Hide RW control modes and enable/disable toggle from GUI and action groups TweakUI(rwmodule); } // do this only once, and check for null // note : not caching it because keeping track of vesselModule changes is a mess VesselModuleRotation vRotModule = vessel.vesselModules.OfType <VesselModuleRotation>().FirstOrDefault(); if (vRotModule == null) { return; } // We have everything we need, now do the nerf if (FlightGlobals.ready && vessel.loaded && !vessel.packed) { // Get the saturation factor calculated from the vessel rotation saturationFactor = vRotModule.velSaturationTorqueFactor; // On pilot rotation requests, use nerfed torque output if (pilotInput) { SetNerfedTorque(); // SAS is disabled } else { if (vessel.Autopilot.Enabled) { if (vessel.Autopilot.Mode.Equals(VesselAutopilot.AutopilotMode.StabilityAssist)) { SetStockTorque(); // SAS is in stability assist mode } else { // SAS is in target mode, enable full torque if the target is near. // orientationDiff : 1.0 = toward target, 0.0 = target is at a 90° angle // float orientationDiff = Math.Max(Vector3.Dot(vessel.Autopilot.SAS.targetOrientation.normalized, vessel.GetTransform().up.normalized), 0); float orientationDiff = Math.Max(Vector3.Dot(vRotModule.targetDirection.normalized, vessel.GetTransform().up.normalized), 0); if (!isOnTarget && orientationDiff > 0.999f) { isOnTarget = true; } if (isOnTarget && orientationDiff < 0.90f) { isOnTarget = false; } if (isOnTarget) { // Torque output is maximal when on target and decrease to zero quickly according to the floatcurve float orientationTorqueFactor = Math.Max(torqueOutput.Evaluate(orientationDiff), 0); if (orientationTorqueFactor < Single.Epsilon || orientationTorqueFactor <= saturationFactor * MandatoryRCSSettings.torqueOutputFactor) { SetNerfedTorque(); // We are locked but too far } else { SetTargetTorque(orientationTorqueFactor); // We are locked, apply the torque curve } } else { SetNerfedTorque(); // Target hasn't been reached } } } else { SetNerfedTorque(); // SAS is disabled } } } }