コード例 #1
0
 protected override void correct_steering()
 {
     if (BRC != null && BRC.IsActive)
     {
         steering = Vector3.ProjectOnPlane(steering, VSL.LocalDir(VSL.Engines.CurrentDefThrustDir));
     }
 }
コード例 #2
0
        //        ThrottleControl THR;
        //
        //        OscillationDetector3D OD = new OscillationDetector3D(3, 30, 100, 200, 1);
        //        Timer test_timer = new Timer(1);
        //        static readonly Vector3[] axes = {Vector3.up, Vector3.right};
        //        Vector3 needed_thrust;
        //        int direction = 1, axis = 0;
        //        float throttle = 0.1f, dThrottle = 0.1f;
        //        float curAAf = 0.1f, dAAf = 0.05f;
        //        enum TestStage {START, TESTING, KILL_ROT, NEXT_AAf, NEXT_THROTTLE, NEXT_AXIS, DONE};
        //        TestStage stage = TestStage.START;
        //
        //        void tune_steering_test(Vector3 AAf)
        //        {
        //            VSL.Controls.GimbalLimit = 0;//VSL.OnPlanetParams.TWRf*100;
        //            //tune PID parameters
        //            var angularV = VSL.vessel.angularVelocity;
        //            var angularM = Vector3.Scale(angularV, VSL.Physics.MoI);
        //            var slow = VSL.Engines.Slow?
        //                (Vector3.one+Vector3.Scale(VSL.Torque.EnginesResponseTime,
        //                                           VSL.Torque.Engines.SpecificTorque)*ATCB.SlowTorqueF)
        //                .ClampComponentsH(ATCB.MaxSlowF) : Vector3.one;
        //            var slowi = slow.Inverse();
        //            var iErr = (Vector3.one-angle_error);
        //            var PIf = AAf.ScaleChain(iErr.ClampComponentsL(1/ATCB.MaxEf)*ATCB.MaxEf, slowi);
        ////            var AA_clamped = AA.ClampComponentsH(ATCB.MaxAA);
        //            steering_pid.P = Vector3.Scale(ATCB.PID.P, PIf);
        //            steering_pid.I = Vector3.Scale(ATCB.PID.I, PIf);
        //            steering_pid.D = ATCB.PID.D.ScaleChain((iErr
        ////                                                    + (Vector3.one-AA_clamped/ATCB.MaxAA)
        //                                                    + angularM.AbsComponents()*ATCB.AngularMf
        //                                                   ).ClampComponentsH(1),
        //
        //                                                   AAf, slow,slow).ClampComponentsL(0);
        //            //add inertia to handle constantly changing needed direction
        //            var inertia = angularM.Sign()
        //                .ScaleChain(iErr,
        //                            angularM, angularM,
        //                            Vector3.Scale(VSL.Torque.MaxCurrent.Torque, VSL.Physics.MoI).Inverse(0))
        //                .ClampComponents(-Mathf.PI, Mathf.PI)
        //                /Mathf.Lerp(ATCB.InertiaFactor, 1, VSL.Physics.MoI.magnitude*ATCB.MoIFactor);
        //            steering += inertia;
        //            //update PID
        //            steering_pid.Update(steering, angularV);
        //            steering = Vector3.Scale(steering_pid.Action, slowi);
        //            //postprocessing by derived classes
        //            correct_steering();
        //        }
        //
        //
        //        protected override void OnAutopilotUpdate(FlightCtrlState s)
        //        {
        //            if(!(CFG.Enabled && stage != TestStage.DONE && VSL.refT != null && VSL.orbit != null)) return;
        //            if(VSL.AutopilotDisabled) { reset(); return; }
        //            lthrust = VSL.LocalDir(VSL.Engines.CurrentDefThrustDir).normalized;
        //            if(VSL.IsActiveVessel)
        //                TCAGui.DebugMessage = Utils.Format("stage: {}, axis: {}\ntimer: {}\ncur AAf {}, throttle {}\n",
        //                                                   stage, axis, test_timer, curAAf, throttle);
        //            switch(stage)
        //            {
        //            case TestStage.START:
        //                CheatOptions.InfinitePropellant = true;
        //                CheatOptions.InfiniteElectricity = true;
        //                CheatOptions.IgnoreMaxTemperature = true;
        //                VSL.vessel.ActionGroups.SetGroup(KSPActionGroup.RCS, true);
        //                Debug.ClearDeveloperConsole();
        //                needed_thrust = VSL.WorldDir(Quaternion.AngleAxis(120*direction, axes[axis])*lthrust);
        //                OD.Reset();
        //                test_timer.Reset();
        //                direction = -direction;
        //                stage = TestStage.TESTING;
        //                break;
        //            case TestStage.KILL_ROT:
        //                THR.Throttle = 0;
        //                CFG.AT.Off();
        //                VSL.vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);
        //                if(VSL.vessel.angularVelocity.sqrMagnitude > 1e-4) break;
        //                VSL.vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, false);
        //                stage = TestStage.START;
        //                break;
        //            case TestStage.TESTING:
        //                CFG.AT.OnIfNot(Attitude.Custom);
        //                THR.Throttle = throttle;
        //                needed_lthrust = VSL.LocalDir(needed_thrust);
        //                compute_steering(lthrust, needed_lthrust);
        //                tune_steering_test(Vector3.one*curAAf);
        //                VSL.Controls.AddSteering(steering);
        //                //detect oscillations
        //                OD.Update(steering, TimeWarp.fixedDeltaTime);
        //                if(VSL.IsActiveVessel)
        //                    TCAGui.DebugMessage +=
        //                        string.Format("pid: {0}\nsteering: {1}%\ngimbal limit: {2}\nOD: {3}",
        //                                      steering_pid, steering_pid.Action*100, VSL.Controls.GimbalLimit, OD.Value);
        //
        //                if(OD.Value.x > 0.1 ||
        //                   OD.Value.y > 0.1 ||
        //                   OD.Value.z > 0.1)
        //                    stage = TestStage.NEXT_THROTTLE;
        //                else if(VSL.Controls.AttitudeError < 1)
        //                    stage = TestStage.NEXT_AAf;
        //                break;
        //            case TestStage.NEXT_AAf:
        //                curAAf += dAAf;
        //                stage = curAAf > 5+dAAf/2 ? TestStage.NEXT_THROTTLE : TestStage.KILL_ROT;
        //                break;
        //            case TestStage.NEXT_THROTTLE:
        //                CSV(axes[axis] == Vector3.up? 0 : 1, throttle, AA, OD.Value, steering_pid.D, curAAf-dAAf);
        //                curAAf = 0.1f;
        //                throttle += dThrottle;
        //                if(throttle > 1 && throttle < 1+dThrottle/2)
        //                    throttle = 1;
        //                stage = throttle > 1 ? TestStage.NEXT_AXIS : TestStage.KILL_ROT;
        //                break;
        //            case TestStage.NEXT_AXIS:
        //                throttle = 0.1f;
        //                axis += 1;
        //                stage = axis < axes.Length ? TestStage.KILL_ROT : TestStage.DONE;
        //                break;
        //            }
        //        }


        public void DrawDebugLines()
        {
            if (!CFG.AT || VSL == null || VSL.vessel == null || VSL.refT == null)
            {
                return;
            }
//			Utils.GLVec(VSL.refT.position, VSL.OnPlanetParams.Heading.normalized*2500, Color.white);
            Utils.GLVec(VSL.refT.position, VSL.WorldDir(lthrust.normalized) * 20, Color.yellow);
            Utils.GLVec(VSL.refT.position, VSL.WorldDir(needed_lthrust.normalized) * 20, Color.red);
            Utils.GLVec(VSL.refT.position, VSL.WorldDir(VSL.vessel.angularVelocity * 20), Color.cyan);
            Utils.GLVec(VSL.refT.position, VSL.WorldDir(new Vector3(pid_pitch.atPID.Action * rotation_axis.x,
                                                                    pid_roll.atPID.Action * rotation_axis.y,
                                                                    pid_yaw.atPID.Action * rotation_axis.z) * 20), Color.green);
//			Utils.GLVec(VSL.refT.position, VSL.WorldDir(steering*20), Color.cyan);
//			Utils.GLVec(VSL.refT.position, VSL.WorldDir(steering_pid.Action*20), Color.magenta);

//			Utils.GLVec(VSL.refT.position, VSL.refT.right*2, Color.red);
//			Utils.GLVec(VSL.refT.position, VSL.refT.forward*2, Color.blue);
//			Utils.GLVec(VSL.refT.position, VSL.refT.up*2, Color.green);

//			if(VSL.Target != null)
//				Utils.GLDrawPoint(VSL.Target.GetTransform().position, Color.red, 5);
//
//			VSL.Engines.All.ForEach(e =>
//			{
//				Utils.GLVec(e.wThrustPos, e.wThrustDir*2, Color.red);
//				Utils.GLVec(e.wThrustPos, e.defThrustDir*2, Color.yellow);
//			});
        }
コード例 #3
0
        public void ControlCallback(Multiplexer.Command cmd)
        {
            translation_pid.Reset();
            switch (cmd)
            {
            case Multiplexer.Command.Resume:
                RegisterTo <SASBlocker>();
                NeedRadarWhenMooving();
                break;

            case Multiplexer.Command.On:
                VSL.UpdateOnPlanetStats();
                if (CFG.HF[HFlight.Stop])
                {
                    VSL.HorizontalSpeed.SetNeeded(Vector3d.zero);
                    CFG.Nav.Off();                     //any kind of navigation conflicts with the Stop program; obviously.
                }
                else if (CFG.HF[HFlight.NoseOnCourse])
                {
                    CFG.BR.OnIfNot(BearingMode.Auto);
                }
                CFG.AT.OnIfNot(Attitude.Custom);
                goto case Multiplexer.Command.Resume;

            case Multiplexer.Command.Off:
                UnregisterFrom <SASBlocker>();
                UnregisterFrom <Radar>();
                CFG.AT.OffIfOn(Attitude.Custom);
                CFG.BR.OffIfOn(BearingMode.Auto);
                EnableManualTranslation(false);
                break;
            }
        }
コード例 #4
0
 public void ActivateEnginesAndRun(Callback action)
 {
     if (NoActiveEngines)
     {
         if (CFG.AutoStage)
         {
             if (HaveNextStageEngines)
             {
                 VSL.ActivateNextStageImmidiate();
                 VSL.TCA.StartCoroutine(CallbackUtil.WaitUntil(() => !NoActiveEngines, action));
             }
             else
             {
                 Utils.Message("No engines left to activate");
             }
         }
         else
         {
             Utils.Message("Automatic staging is disabled");
         }
     }
     else
     {
         action();
     }
 }
コード例 #5
0
        public void CruiseControlCallback(Multiplexer.Command cmd)
        {
            UpdateTimer.Reset();
            switch (cmd)
            {
            case Multiplexer.Command.Resume:
                RegisterTo <SASBlocker>();
                NeedCPSWhenMooving();
                break;

            case Multiplexer.Command.On:
                VSL.UpdateOnPlanetStats();
                var nV = VSL.HorizontalSpeed.Absolute;
                if (nV > PointNavigator.C.MaxSpeed)
                {
                    nV = PointNavigator.C.MaxSpeed;
                }
                var nVdir = nV > C.MaxIdleSpeed?
                            (Vector3)VSL.HorizontalSpeed.Vector.normalized :
                            VSL.OnPlanetParams.Fwd;
                CFG.BR.OnIfNot(BearingMode.User);
                BRC.UpdateBearing((float)VSL.Physics.Bearing(nVdir));
                VSL.HorizontalSpeed.SetNeeded(nVdir * nV);
                CFG.MaxNavSpeed = needed_velocity = nV;
                goto case Multiplexer.Command.Resume;

            case Multiplexer.Command.Off:
                VSL.HorizontalSpeed.SetNeeded(Vector3d.zero);
                UnregisterFrom <SASBlocker>();
                ReleaseCPS();
                CFG.BR.OffIfOn(BearingMode.User);
                break;
            }
        }
コード例 #6
0
 public override void Init()
 {
     base.Init();
     Dtol = LTRJ.Dtol;
     CorrectionTimer.Period = LTRJ.CorrectionTimer;
     StageTimer.action      = () =>
     {
         VSL.ActivateNextStage();
         Message("Have to drop ballast to decelerate...");
     };
     dP_up_timer.action = () =>
     {
         dP_threshold = Utils.ClampL(dP_threshold * 0.9, LTRJ.MinDPressure);
         last_dP      = VSL.vessel.dynamicPressurekPa;
     };
     dP_down_timer.action = () =>
     {
         dP_threshold = Utils.ClampH(dP_threshold * 1.1, LTRJ.MaxDPressure);
         last_dP      = VSL.vessel.dynamicPressurekPa;
     };
     NoEnginesTimer.action = () =>
     {
         landing_stage = LandingStage.HardLanding;
     };
     sim                  = new AtmoSim(VSL);
     Executor             = new ManeuverExecutor(TCA);
     scanner              = new PQS_Scanner(VSL);
     scanner.MaxUnevennes = GLB.LND.MaxUnevenness / 3;
     dP_threshold         = LTRJ.MaxDPressure;
     last_Err             = 0;
     last_dP              = 0;
     Working              = false;
 }
コード例 #7
0
 public void Add(EngineWrapper e)
 {
     Engines.Add(e);
     MaxThrust   = MaxThrust + VSL.LocalDir(e.defThrustDir) * e.engine.maxThrust;
     MaxMassFlow = MaxMassFlow + e.engine.maxFuelFlow;
     Dir         = MaxThrust.normalized;
 }
コード例 #8
0
        public EngineCluster BestForManeuver(Vector3 dV)
        {
            var           dVm       = dV.magnitude;
            var           loc_dV    = -VSL.LocalDir(dV);
            var           min_score = float.MaxValue;
            EngineCluster best      = null;

            for (int j = 0, clustersCount = clusters.Count; j < clustersCount; j++)
            {
                var c      = clusters[j];
                var score  = VSL.Torque.NoEngines.RotationTime2Phase(Utils.Angle2(loc_dV, c.Dir), 1);
                var thrust = c.MaxThrust.magnitude;
                var ttb    = VSL.Engines.TTB(dVm, thrust, (float)c.MaxMassFlow, 1);
                if (VSL.Info.Countdown > 0 && score + ttb / 2 > VSL.Info.Countdown)
                {
                    continue;
                }
                if (ttb < ManeuverAutopilot.C.ClosestCluster)
                {
                    ttb = 0;
                }
                score += ttb;
                var fuel = VSL.Engines.FuelNeeded(dVm, (float)(thrust / c.MaxMassFlow));
                if (fuel / VSL.Physics.M > ManeuverAutopilot.C.EfficientCluster)
                {
                    score += fuel * ManeuverAutopilot.C.EfficiencyWeight;
                }
                if (score < min_score)
                {
                    min_score = score;
                    best      = c;
                }
            }
            return(best ?? Closest(loc_dV));
        }
コード例 #9
0
 public void OnPostAutopilotUpdate(FlightCtrlState s)
 {
     if (!Valid || !CFG.Enabled)
     {
         return;
     }
     //handle engines
     VSL.PostUpdateState(s);
     VSL.Engines.Tune();
     if (VSL.Engines.NumActive > 0)
     {
         //:preset manual limits for translation if needed
         if (VSL.Controls.ManualTranslationSwitch.On)
         {
             ENG.PresetLimitsForTranslation(VSL.Engines.Active.Manual, VSL.Controls.ManualTranslation);
             if (CFG.VSCIsActive)
             {
                 ENG.LimitInDirection(VSL.Engines.Active.Manual, VSL.Physics.UpL);
             }
         }
         //:optimize limits for steering
         ENG.PresetLimitsForTranslation(VSL.Engines.Active.Maneuver, VSL.Controls.Translation);
         ENG.Steer();
     }
     RCS.Steer();
     VSL.Engines.SetControls();
     VSL.FinalUpdate();
 }
コード例 #10
0
 void start_to(WayPoint wp)
 {
     VSL.UpdateOnPlanetStats();
     wp.Update(VSL);
     if (CFG.Nav[Navigation.GoToTarget] && wp.CloseEnough(VSL))
     {
         CFG.Nav.Off();
         return;
     }
     if (VSL.LandedOrSplashed)
     {
         CFG.AltitudeAboveTerrain = true;
         CFG.VF.OnIfNot(VFlight.AltitudeControl);
         CFG.DesiredAltitude = PN.TakeoffAltitude + VSL.Geometry.H;
     }
     else if (CFG.VTOLAssistON)
     {
         VSL.GearOn(false);
     }
     reset_formation();
     SetTarget(wp);
     DistancePID.Reset();
     LateralPID.Reset();
     CFG.HF.OnIfNot(HFlight.NoseOnCourse);
     RegisterTo <Radar>();
 }
コード例 #11
0
 public void TargetUI()
 {
     if (SelectingTarget)
     {
         SelectingTarget &= !GUILayout.Button("Cancel", Styles.close_button, GUILayout.ExpandWidth(true));
     }
     else if (CFG.Target != null)
     {
         if (VSL.TargetUsers.Count > 0)
         {
             GUILayout.Label(new GUIContent("Del Target", "Target point is in use"),
                             Styles.grey_button, GUILayout.ExpandWidth(true));
         }
         else if (GUILayout.Button(new GUIContent("Del Target", "Remove target point"),
                                   Styles.danger_button, GUILayout.ExpandWidth(true)))
         {
             VSL.SetTarget(null);
         }
     }
     else if (GUILayout.Button(new GUIContent("Set Surface Target", "Select target point on the surface"),
                               Styles.active_button, GUILayout.ExpandWidth(true)))
     {
         select_single   = true;
         SelectingTarget = true;
         CFG.GUIVisible  = true;
         CFG.ShowPath    = true;
         MapView.EnterMapView();
     }
 }
コード例 #12
0
 public void OnPostAutopilotUpdate(FlightCtrlState s)
 {
     if (!Valid || !CFG.Enabled)
     {
         return;
     }
     //handle engines
     VSL.PostUpdateState(s);
     VSL.Engines.Tune();
     if (VSL.Engines.NumActive > 0)
     {
         //:preset manual limits for translation if needed
         var translation = VSL.Controls.EnginesTranslation;
         if (VSL.Controls.HasTranslation)
         {
             translation += VSL.Controls.Translation;
         }
         if (!translation.IsZero())
         {
             EngineOptimizer.PresetLimitsForTranslation(VSL.Engines.Active.Maneuver, translation.normalized);
             if (CFG.VSCIsActive && !VSL.Controls.HasTranslation)
             {
                 EngineOptimizer.LimitInDirection(VSL.Engines.Active.Maneuver, VSL.Physics.UpL);
             }
         }
         ENG.Steer();
     }
     RCS.Steer();
     VSL.Engines.SetControls();
     VSL.FinalUpdate();
 }
コード例 #13
0
 public bool ActivateInactiveEngines()
 {
     if (CFG.AutoStage && NoActiveEngines && HaveNextStageEngines)
     {
         VSL.ActivateNextStage(); return(true);
     }
     return(false);
 }
コード例 #14
0
 public void OnReloadGlobals()
 {
     AllModules.ForEach(m => m.Reset());
     VSL.Reset();
     VSL.Init();
     AllModules.ForEach(m => m.Init());
     VSL.ConnectAutopilotOutput();
 }
コード例 #15
0
 public void FixedUpdate()
 {
     if (VSL == null)
     {
         return;
     }
     //initialize systems
     VSL.UpdateState();
     State = TCAState.Disabled;
     if (!CFG.Enabled)
     {
         return;
     }
     State = TCAState.Enabled;
     if (!VSL.Info.ElectricChargeAvailible)
     {
         return;
     }
     SetState(TCAState.HaveEC);
     ClearFrameState();
     //update VSL
     VSL.UpdatePhysics();
     if (VSL.Engines.Check())
     {
         SetState(TCAState.HaveActiveEngines);
     }
     Actions["onActionUpdate"].actionGroup = VSL.Engines.ActionGroups;
     VSL.UpdateCommons();
     VSL.UpdateOnPlanetStats();
     //update modules
     ModulePipeline.ForEach(m => m.OnFixedUpdate());
     //handle engines
     VSL.Engines.Tune();
     if (VSL.Engines.NumActive > 0)
     {
         //:preset manual limits for translation if needed
         if (VSL.Controls.ManualTranslationSwitch.On)
         {
             ENG.PresetLimitsForTranslation(VSL.Engines.Manual, VSL.Controls.ManualTranslation);
             if (CFG.VSCIsActive)
             {
                 ENG.LimitInDirection(VSL.Engines.Manual, VSL.Physics.UpL);
             }
         }
         //:balance-only engines
         if (VSL.Engines.Balanced.Count > 0)
         {
             VSL.Torque.UpdateImbalance(VSL.Engines.Manual, VSL.Engines.UnBalanced);
             ENG.OptimizeLimitsForTorque(VSL.Engines.Balanced, Vector3.zero);
         }
         VSL.Torque.UpdateImbalance(VSL.Engines.Manual, VSL.Engines.UnBalanced, VSL.Engines.Balanced);
         //:optimize limits for steering
         ENG.PresetLimitsForTranslation(VSL.Engines.Maneuver, VSL.Controls.Translation);
         ENG.Steer();
     }
     RCS.Steer();
     VSL.Engines.SetControls();
 }
コード例 #16
0
        IEnumerator <YieldInstruction> activeProfileUpdate()
        {
            ProfileSyncAllowed = false;
            yield return(new WaitForSeconds(0.5f));

            VSL.UpdateParts();
            CFG.ActiveProfile.Update(VSL.Engines.All, true);
            ProfileSyncAllowed = true;
        }
コード例 #17
0
 public ToOrbitExecutor(ModuleTCA tca) : base(tca)
 {
     InitModuleFields();
     Executor             = new ManeuverExecutor(tca);
     GearAction.action    = () => VSL.GearOn(false);
     ErrorThreshold.Lower = 2 * GLB.ORB.Dtol;
     ErrorThreshold.Upper = 4 * GLB.ORB.Dtol;
     GravityTurnStart     = 0;
 }
コード例 #18
0
        public void UpdateAeroForces()
        {
            var lift   = Vector3.zero;
            var drag   = Vector3.zero;
            var torque = Vector3.zero;

            if (VSL.vessel.dynamicPressurekPa > 0)
            {
                for (int i = 0, VSLvesselPartsCount = VSL.vessel.Parts.Count; i < VSLvesselPartsCount; i++)
                {
                    var p = VSL.vessel.Parts[i];
                    var r = p.Rigidbody.worldCenterOfMass - VSL.Physics.wCoM;
                    var d = -p.dragVectorDir * p.dragScalar;
                    torque += Vector3.Cross(r, d);
                    drag   += d;
                    if (!p.hasLiftModule)
                    {
                        var lift_mod = p.transform.rotation * (p.bodyLiftScalar * p.DragCubes.LiftForce);
                        torque += Vector3.Cross(r, lift_mod);
                        lift   += lift_mod;
                    }
                    var lift_srf = p.Modules.GetModules <ModuleLiftingSurface>();
                    if (lift_srf.Count > 0)
                    {
                        var srf_lift = Vector3.zero;
                        var srf_drag = Vector3.zero;
                        lift_srf.ForEach(m => { srf_lift += m.liftForce; srf_drag += m.dragForce; });
                        torque += Vector3.Cross(r, srf_lift + srf_drag);
                        lift   += srf_lift;
                        drag   += srf_drag;
                    }
                }
            }
            Lift      = lift;
            Drag      = drag;
            AeroForce = Lift + Drag;
            var relAeroForce = AeroForce / (float)Utils.ClampL(VSL.vessel.dynamicPressurekPa, 1);

            if (relAeroForce.sqrMagnitude > MaxAeroForceL.sqrMagnitude)
            {
                MaxAeroForceL = VSL.LocalDir(relAeroForce);
            }
            vLift       = Vector3.Dot(AeroForce, VSL.Physics.Up);
            AeroTorque  = torque;
            AeroTorqueL = VSL.LocalDir(VSL.OnPlanetParams.AeroTorque);
            var aeroTorqueL = AeroTorqueL.AbsComponents();

            AeroTorqueRatio = Vector3.Scale(
                aeroTorqueL,
                (VSL.Torque.NoEngines.Torque + VSL.Torque.EnginesFinal.Torque).Inverse())
                              .MaxComponentF();
            MaxAeroTorqueRatio = Vector3.Scale(
                aeroTorqueL,
                VSL.Torque.MaxCurrent.Torque.Inverse())
                                 .MaxComponentF();
        }
コード例 #19
0
 public virtual void AttachTCA(ModuleTCA tca)
 {
     if (TCA == null)
     {
         TCA = tca;
         InitModuleFields();
         GearAction.action = () => VSL.GearOn(false);
         TimeToApA.Value   = Mathf.Max(TimeToApA, VSL.Torque.MaxCurrent.TurnTime);
     }
 }
コード例 #20
0
 public void ToggleTCA(KSPActionParam param = null)
 {
     CFG.Enabled = !CFG.Enabled;
     if (CFG.Enabled)
     {
         CFG.ActiveProfile.Update(VSL.Engines.All, true);
     }
     AllModules.ForEach(m => m.OnEnableTCA(CFG.Enabled));
     VSL.OnEnableTCA(CFG.Enabled);
 }
コード例 #21
0
        public bool Execute(Vector3d dV, float MinDeltaV = 0.1f, ManeuverCondition condition = null)
        {
            THR.Throttle = 0;
            dVrem.Value  = dV.magnitude;
            //end if below the minimum dV
            if (dVrem < MinDeltaV)
            {
                return(false);
            }
            VSL.Engines.ActivateEngines();
            //test: flameouted engines are automatically excluded from Active,
            //so this should work without this check; but this needs to be tested
            //in-game anyway with: MAN, REN, DEO
//			if(VSL.Engines.MaxThrustM.Equals(0))
//				return VSL.Engines.HaveNextStageEngines;
            //orient along the burning vector
            if (dVrem && VSL.Controls.RCSAvailableInDirection(-dV))
            {
                CFG.AT.OnIfNot(Attitude.KillRotation);
            }
            else
            {
                CFG.AT.OnIfNot(Attitude.Custom);
                ATC.SetThrustDirW(-dV);
                VSL.Engines.RequestClusterActivationForManeuver(-dV);
            }
            //check the condition
            if (condition != null && !condition((float)dVrem))
            {
                return(true);
            }
            if (VSL.Controls.TranslationAvailable)
            {
                if (dVrem || VSL.Controls.AttitudeError > GLB.ATCB.AttitudeErrorThreshold)
                {
                    TRA.AddDeltaV(-VSL.LocalDir(dV));
                }
                if (dVrem && CFG.AT[Attitude.KillRotation])
                {
                    var errorF = Utils.ClampL(Vector3.Dot(VSL.Engines.Thrust.normalized, -dV.normalized), 0);
                    THR.DeltaV = (float)dVrem * errorF * errorF;
                }
                else
                {
                    THR.DeltaV = (float)dVrem;
                }
            }
            else
            {
                THR.DeltaV = (float)dVrem;
            }
//			Log("\ndVrem: {}\nAttitudeError {}, DeltaV: {}, Throttle {}, RCS {}",
//			    dVrem, VSL.Controls.AttitudeError, THR.DeltaV, THR.Throttle, VSL.Controls.RCSAvailableInDirection(-dV));//debug
            return(true);
        }
コード例 #22
0
 void stop_aerobraking()
 {
     if (UseBrakes)
     {
         VSL.BrakesOn(false);
     }
     if (UseChutes && VSL.OnPlanetParams.ParachutesActive)
     {
         VSL.OnPlanetParams.CutActiveParachutes();
     }
 }
コード例 #23
0
 public void DrawDebugLines()
 {
     if (VSL == null || VSL.vessel == null || VSL.refT == null || !CFG.HF)
     {
         return;
     }
     Utils.GLVec(VSL.refT.position, VSL.HorizontalSpeed.NeededVector, Color.yellow);
     Utils.GLVec(VSL.refT.position, VSL.WorldDir(manual_thrust), Color.magenta);
     Utils.GLVec(VSL.refT.position + VSL.Physics.Up * VSL.Geometry.H, VSL.HorizontalSpeed.Vector, Color.red);
     Utils.GLVec(VSL.refT.position + VSL.Physics.Up * VSL.Geometry.H * 1.1, CourseCorrection, Color.green);
 }
コード例 #24
0
 void reset()
 {
     if (VSL != null)
     {
         VSL.Reset();
         AllModules.ForEach(m => m.Reset());
         CFG.ClearCallbacks();
     }
     DeleteModules();
     VSL = null;
 }
コード例 #25
0
        void ClearFrameState()
        {
            VSL.ClearFrameState();
            AllModules.ForEach(m => m.ClearFrameState());
#if DEBUG
            if (VSL.IsActiveVessel)
            {
                TCAGui.ClearDebugMessage();
            }
#endif
        }
コード例 #26
0
 public void Add(params EngineWrapper[] engines)
 {
     for (int i = 0, len = engines.Length; i < len; i++)
     {
         var e = engines[i];
         Engines.Add(e);
         MaxThrust   = MaxThrust + VSL.LocalDir(e.defThrustDir) * e.engine.maxThrust;
         MaxMassFlow = MaxMassFlow + e.engine.maxFuelFlow;
     }
     Dir = MaxThrust.normalized;
 }
コード例 #27
0
        public bool Execute(Vector3d dV, float MinDeltaV = 0.1f, ManeuverCondition condition = null)
        {
            THR.Throttle = 0;
            dVrem.Value  = dV.magnitude;
            //end if below the minimum dV
            if (dVrem < MinDeltaV)
            {
                return(false);
            }
            VSL.Engines.ActivateEngines();
            if (VSL.Engines.MaxThrustM.Equals(0))
            {
                return(true);
            }
            //orient along the burning vector
            if (dVrem && VSL.Controls.RCSAvailableInDirection(-dV))
            {
                CFG.AT.OnIfNot(Attitude.KillRotation);
            }
            else
            {
                CFG.AT.OnIfNot(Attitude.Custom);
                ATC.SetThrustDirW(-dV);
            }
            //check the condition
            if (condition != null && !condition((float)dVrem))
            {
                return(true);
            }
            if (VSL.Controls.TranslationAvailable)
            {
                if (dVrem || VSL.Controls.AttitudeError > GLB.ATCB.AttitudeErrorThreshold)
                {
                    TRA.AddDeltaV(-VSL.LocalDir(dV));
                }
                if (dVrem && CFG.AT[Attitude.KillRotation])
                {
                    var errorF = Utils.ClampL(Vector3.Dot(VSL.Engines.Thrust.normalized, -dV.normalized), 0);
                    THR.DeltaV = (float)dVrem * errorF * errorF;
                }
                else
                {
                    THR.DeltaV = (float)dVrem;
                }
            }
            else
            {
                THR.DeltaV = (float)dVrem;
            }
//			Log("\ndVrem: {}\nAttitudeError {}, DeltaV: {}, Throttle {}, RCS {}",
//			    dVrem, VSL.Controls.AttitudeError, THR.DeltaV, THR.Throttle, VSL.Controls.RCSAvailableInDirection(-dV));//debug
            return(true);
        }
コード例 #28
0
 protected override void DrawContent()
 {
     #if DEBUG
     ATC.DrawDebugLines();
     Utils.GLVec(VSL.refT.position, VSL.WorldDir(VSL.OnPlanetParams.MaxAeroForceL) * 10, Color.magenta);
     #endif
     if (GUILayout.Button(new GUIContent("T-SAS", "Push to toggle attitude controls"),
                          CFG.AT && !VSL.AutopilotDisabled? Styles.cyan : Styles.white, GUILayout.ExpandWidth(false)))
     {
         cues.Toggle();
     }
 }
コード例 #29
0
        protected override void OnAutopilotUpdate(FlightCtrlState s)
        {
            //need to check all the prerequisites, because the callback is called asynchroniously
            if (!(CFG.Enabled && IsActive && VSL.refT != null))
            {
                DirectionOverride = Vector3d.zero; return;
            }
            //allow user to intervene
            if (VSL.HasUserInput)
            {
                if (!s.yaw.Equals(0))
                {
                    UpdateBearing(Bearing.Value + s.yaw * BRC.YawFactor * CFG.ControlSensitivity);
                    if (CFG.HF[HFlight.CruiseControl] && !VSL.HorizontalSpeed.NeededVector.IsZero())
                    {
                        VSL.HorizontalSpeed.SetNeeded(ForwardDirection * CFG.MaxNavSpeed);
                    }
                    draw_forward_direction = BRC.DrawForwardDirection;
                    VSL.HasUserInput       = !(s.pitch.Equals(0) && s.roll.Equals(0));
                    VSL.AutopilotDisabled  = VSL.HasUserInput;
                    DirectionLineTimer.Reset();
                    bearing_pid.Reset();
                    s.yaw = 0;
                }
            }
            if (VSL.AutopilotDisabled)
            {
                DirectionOverride = Vector3d.zero; return;
            }
            //turn ship's nose in the direction of needed velocity
            var axis  = up_axis;
            var laxis = VSL.LocalDir(axis);
            var cDir  = H(VSL.OnPlanetParams.Fwd);
            var nDir  = DirectionOverride.IsZero()? H(ForwardDirection) : H(DirectionOverride);
            var angle = Vector3.Angle(cDir, nDir) * Mathf.Sign(Vector3.Dot(Vector3.Cross(nDir, cDir), axis));
            var eff   = Mathf.Abs(Vector3.Dot(VSL.Engines.CurrentMaxThrustDir.normalized, VSL.Physics.Up));
            var ADf   = (float)VSL.vessel.staticPressurekPa / VSL.Torque.MaxCurrent.AngularDragResistanceAroundAxis(laxis) * BRC.ADf + 1;

            AAf           = Utils.Clamp(1 / VSL.Torque.MaxCurrent.AngularAccelerationAroundAxis(laxis) / ADf, BRC.MinAAf, BRC.MaxAAf);
            bearing_pid.P = BRC.DirectionPID.P;
            bearing_pid.D = BRC.DirectionPID.D * AAf;
            bearing_pid.Update(angle * eff, Vector3.Dot(VSL.vessel.angularVelocity, laxis) * Mathf.Rad2Deg);
            steering = rotation2steering(world2local_rotation(Quaternion.AngleAxis(bearing_pid.Action, axis)));
            VSL.Controls.AddSteering(steering);
//			if(VSL.IsActiveVessel)
//				TCAGui.DebugMessage =
//					Utils.Format("angle {}deg, action {}deg, action*eff {}deg\n" +
//					             "AAf {}, ADf {}, result {}",
//					              angle, bearing_pid.Action, bearing_pid.Action*eff,
//					             1/VSL.Torque.MaxCurrent.AngularAccelerationAroundAxis(laxis), ADf, AAf);//debug
            DirectionOverride = Vector3d.zero;
        }
コード例 #30
0
        protected virtual void CreateTarget(System.Random RND)
        {
            Coordinates c = null;

            while (c == null || c.OnWater)
            {
                c = Coordinates.SurfacePoint(RND.NextDouble() * latSpread - latSpread / 2,
                                             RND.NextDouble() * 360,
                                             VSL.Body);
                c.SetAlt2Surface(VSL.Body);
            }
            VSL.SetTarget(MOD, new WayPoint(c));
        }