Beispiel #1
0
        public void TickTelemetry(IDataMiner data)
        {
            Enabled = true;
            Active = true;

            var f = 1.0;
            if (Main.Drivetrain.GearRatios != null && data.Telemetry.Gear >= 1)
                f = Main.Drivetrain.GearRatios[data.Telemetry.Gear - 1] / 5.5;
            var throttle = Math.Max(Main.GetAxisIn(JoyControls.Throttle), data.Telemetry.Throttle);
            TorqueLimit = 1;
            var NotGood = false;
            do
            {
                var wheelTorque = Main.Drivetrain.CalculateTorqueP(data.Telemetry.EngineRpm, TorqueLimit * throttle) * f;
                if (wheelTorque > 20000)
                {
                    TorqueLimit *= 0.999f;
                    NotGood = true;
                }
                else
                {
                    NotGood = false;
                }
                if (TorqueLimit <= 0.2f)
                {
                    TorqueLimit = 0.2f;
                    break;
                }
            } while (NotGood);

            TorqueLimit = 1.0f;
        }
Beispiel #2
0
        public WorldMapper(IDataMiner dataSource)
        {
            if (dataSource.Application == "eurotrucks2" && !dataSource.SelectManually)
            {
                source = dataSource as Ets2DataMiner;
                source.DataReceived += OnDataReceived;

                cells = new List<WorldMapCell>();

                Import();
            }
        }
Beispiel #3
0
        public void TickTelemetry(IDataMiner data)
        {
            if (data.Telemetry.Speed * 3.6 > 55)
                triggered = true;

            if (triggered && data.Telemetry.Speed * 3.6  < 35)
            {
                clutchctrl = true;
            }
            else if (data.Telemetry.Speed*3.6 > 35)
            {
                clutchctrl = false;
            }
            if (data.Telemetry.Speed*3.6 < 10 && Main.GetAxisIn(JoyControls.Throttle) > 0.1)
            {
                clutchctrl = false;
                triggered = false;
            }
        }
Beispiel #4
0
        public void TickTelemetry(IDataMiner data)
        {
            // TODO: Only supports TDU2.
            if (Main.Data.Active.Application != "TestDrive2")
            {
                Enabled = false;
                return;
            }
            else
            {
                Enabled = true;
            }
            if (CameraHackEnabled)
            {
                data.Write(TelemetryChannel.CameraHorizon, (float)(CameraAngle * CameraAngle * CameraAngle * -25));

            } else if (CameraAngle != 0)
            {
                CameraAngle = 0;
                data.Write(TelemetryChannel.CameraHorizon, 0.0f);
            }
        }
Beispiel #5
0
        public void TickTelemetry(IDataMiner data)
        {
            Speed = data.Telemetry.Speed;

            if (Main.GetAxisIn(JoyControls.Brake) > 0.05)
                Cruising = false;

            // Any tracked car?
            if (dlDebugInfo.TrackedCar != null)
            {
                // Gap control?
                var distanceTarget = 20;
                var distanceError = distanceTarget - dlDebugInfo.TrackedCar.Distance;

                var speedBias = 9*distanceError/distanceTarget; // 3m/s max decrement
                if (distanceError < 0)
                    speedBias /= 6;
                var targetSpeed = dlDebugInfo.TrackedCar.Speed - speedBias;

                if (targetSpeed >= SpeedCruise)
                    targetSpeed = (float)SpeedCruise;

                var speedErr = data.Telemetry.Speed - targetSpeed-2;
                if (speedErr > 0) // too fast
                {
                    t = 0;
                    if (speedErr>1.5f)
                        b = (float) Math.Pow(speedErr-1.5f,4)*0.015f;
                }
                else
                {
                    t = -speedErr*0.2f;
                    b = 0;
                }
            }
            else
            {
                // Speed control
                var speedErr = data.Telemetry.Speed - (float)SpeedCruise;
                if (speedErr > 0) // too fast
                {
                    t = 0;
                }
                else
                {
                    t = -speedErr * 0.4f;
                    b = 0;
                }
            }
        }
Beispiel #6
0
        public void Tick(IDataMiner data)
        {
            // We take all controller input
            var buttonValues = Buttons.ToDictionary(c => c, Main.GetButtonIn);
            var axisValues = Axis.ToDictionary(c => c, Main.GetAxisIn);

            foreach (var obj in chain)
            {
                obj.TickTelemetry(data);
            }

            // Put it serially through each control block
            // Each time a block requires a control, it receives the current value of that control
            foreach(var obj in chain.Where(FilterSimulators))
            {
                buttonValues = buttonValues.ToDictionary(c => c.Key, k => obj.Requires(k.Key) ? obj.GetButton(k.Key, k.Value) : k.Value);
                axisValues = axisValues.ToDictionary(c => c.Key, k => obj.Requires(k.Key) ? obj.GetAxis(k.Key, k.Value) : k.Value);

                foreach(var kvp in axisValues)
                    axisProgression[kvp.Key][obj.GetType().Name] = kvp.Value;

                obj.TickControls();
            }

            // And then put them onto our own controller.
            foreach (var b in buttonValues)
            {
                Main.SetButtonOut(b.Key, b.Value);
            }
            foreach (var b in axisValues)
            {
                var v = b.Value;
                if (v > 1) v = 1;
                if (v < 0) v = 0;
                Main.SetAxisOut(b.Key,v);
            }
        }
Beispiel #7
0
 public void TickTelemetry(IDataMiner data)
 {
     Speed = data.Telemetry.Speed;
 }
        public void TickTelemetry(IDataMiner data)
        {
            var rpm = data.Telemetry.EngineRpm;
            err = calRpm - rpm;
            if (err > 500)
                err = 500;
            if (err < -500)
                err = -500;

            switch (state)
            {
                case TransmissionCalibratorStatus.Idle:
                    Main.Transmission.OverruleShifts = false;

                    // If we're stationary for a few seconds, we can apply brakes and calibrate the clutch
                    bool wasStationary = isStationary;
                    isStationary = Math.Abs(data.Telemetry.Speed) < 1 && Main.GetAxisIn(JoyControls.Throttle) < 0.05 && data.Telemetry.EngineRpm > 200;

                    if (isStationary && !wasStationary)
                        stationary = DateTime.Now;

                    if (isStationary && DateTime.Now.Subtract(stationary).TotalMilliseconds > 2500)
                    {
                        clutch = 1.0f;

                        // CALIBRATE
                        state = TransmissionCalibratorStatus.IterateCalibrationCycle;
                    }
                    break;

                case TransmissionCalibratorStatus.FindThrottlePoint:

                    throttle += err/500000.0f;
                    if (throttle >= 0.8)
                    {
                        // Cannot rev the engine

                    }

                    var wasRpmInRange = rpmInRange;
                    rpmInRange = Math.Abs(err) < 5;

                    if (!wasRpmInRange && rpmInRange)
                        rpmInRangeTimer = DateTime.Now;

                    // stable at RPM
                    if (rpmInRange && DateTime.Now.Subtract(rpmInRangeTimer).TotalMilliseconds > 250)
                    {
                        // set error to 0
                        calRpm = rpm;
                        state = TransmissionCalibratorStatus.FindClutchBitePoint;
                    }

                    break;

                case TransmissionCalibratorStatus.FindClutchBitePoint:

                    if (Main.Transmission.IsShifting)
                    {
                        break;
                    }
                    if (data.Telemetry.Gear != gearTest)
                    {
                        Main.Transmission.Shift(data.Telemetry.Gear, gearTest, "normal");
                        break;
                    }

                    // Decrease clutch 0.25% at a time to find the bite point
                    clutch -= 0.25f/100.0f;

                    if (err > 50)
                    {
                        // We found the clutch bite point
                        var fs = File.AppendText("./gear-clutch");
                        fs.WriteLine(gearTest + "," + calRpm + "," + clutch);
                        fs.Close();
                        state = TransmissionCalibratorStatus.IterateCalibrationCycle;
                    }

                    break;

                case TransmissionCalibratorStatus.IterateCalibrationCycle:

                    clutch = 1;
                    gearTest ++;

                    calRpm = 700.0f;
                    // Find throttle point
                    state = TransmissionCalibratorStatus.FindThrottlePoint;
                    throttle = 0.001f;

                    rpmInRange = false;

                    break;
            }

            //abort when we give power
            if (Main.GetAxisIn(JoyControls.Throttle) > 0.1)
            {
                stationary = DateTime.Now;
                state = TransmissionCalibratorStatus.Idle;
            }

            Active = state != TransmissionCalibratorStatus.Idle;
        }
Beispiel #9
0
        public void TickTelemetry(IDataMiner data)
        {
            int idealGear = data.Telemetry.Gear;

            if (data.TransmissionSupportsRanges)
                RangeSize = 6;
            else
                RangeSize = 8;

            // TODO: Add generic telemetry object
            GameGear = data.Telemetry.Gear;
            if (IsShifting) return;
            if (TransmissionFrozen && !GetHomeMode) return;
            if (OverruleShifts) return;
            shiftRetry = 0;

            if (GetHomeMode)
            {
                if(idealGear < 1)
                {
                    idealGear = 1;
                }

                var lowRpm = Main.Drivetrain.StallRpm*1.5;
                var highRpm = Main.Drivetrain.StallRpm*3;

                if (data.Telemetry.EngineRpm < lowRpm && idealGear > 1)
                    idealGear--;
                if (data.Telemetry.EngineRpm > highRpm && idealGear < Main.Drivetrain.Gears)
                    idealGear++;

            }
            else
            {
                if (EnableSportShiftdown)
                    transmissionThrottle = Math.Max(Main.GetAxisIn(JoyControls.Brake)*8, transmissionThrottle);
                transmissionThrottle= Math.Min(1, Math.Max(0, transmissionThrottle));
                var lookupResult = configuration.Lookup(data.Telemetry.Speed*3.6, transmissionThrottle);
                idealGear = lookupResult.Gear;
                ThrottleScale = GetHomeMode ? 1 : lookupResult.ThrottleScale;

                if (Main.Data.Active.Application == "eurotrucks2")
                {
                    var ets2Miner = (Ets2DataMiner) (data);
                    var maxGears = (int) Math.Round(Main.Drivetrain.Gears*(1-ets2Miner.MyTelemetry.Damage.WearTransmission));

                    if (idealGear >= maxGears)
                        idealGear = maxGears;
                }

                if (data.Telemetry.Gear == 0 && ShiftCtrlNewGear != 0)
                {
                    Debug.WriteLine("Timeout");
                    ShiftCtrlNewGear = 0;
                    TransmissionFreezeUntill = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 250));
                    return;
                }
            }

            if (InReverse)
            {
                if (GameGear != -1 && Math.Abs(data.Telemetry.Speed) < 1)
                {
                    Debug.WriteLine("Shift from " + data.Telemetry.Gear + " to  " + idealGear);
                    Shift(data.Telemetry.Gear, -1, "up_1thr");
                }
                return;
            }

            // Kickdown?
            // What is basically does, is making this very-anxious gearbox tone down a bit in it's aggressive shift pattern.
            // With kickdown we specify 2 rules to make the gear "stick" longer with varying throttle positions.
            if (KickdownEnable)
            {
                if (KickdownCooldown)
                {
                    // We're on cooldown. Check if power/speed/rpm is able to reset this
            // The scheme is as follow:
                    // if (delta of [current speed] and [speed of last shift] ) > speedReset: then reset cooldown
                    // if ([generated power this gear] / [generated power new gear]) > 1+powerReset: then reset cooldown
                    // if (currentRpm < [rpm * stationaryValue]) : then reset cooldown

                    // This makes sure the gearbox shifts down if on very low revs and almost about to stall.

                    // Note: only for speeding up
                    if ((data.Telemetry.Speed - KickdownLockedSpeed) > KickdownSpeedReset)
                    {
                        Debug.WriteLine("[Kickdown] Reset on overspeed");
                        KickdownCooldown = false;
                    }

                    var maxPwr = Main.Drivetrain.CalculateMaxPower();

                    var engineRpmCurrentGear = Main.Drivetrain.CalculateRpmForSpeed(ShifterOldGear - 1, data.Telemetry.Speed);
                    var pwrCurrentGear = Main.Drivetrain.CalculatePower(engineRpmCurrentGear, data.Telemetry.Throttle);

                    var engineRpmNewGear = Main.Drivetrain.CalculateRpmForSpeed(idealGear - 1, data.Telemetry.Speed);
                    var pwrNewGear = Main.Drivetrain.CalculatePower(engineRpmNewGear, data.Telemetry.Throttle);
                    //Debug.WriteLine("N"+pwrCurrentGear.ToString("000") + " I:" + pwrNewGear.ToString("000"));
                    // This makes sure the gearbox shifts down if on low revs and the user is requesting power from the engine
                    if (pwrNewGear / pwrCurrentGear > 1 + KickdownPowerReset &&
                        pwrNewGear / maxPwr > KickdownPowerReset)
                    {
                        Debug.WriteLine("[Kickdown] Reset on power / " + pwrCurrentGear + " / " + pwrNewGear);
                        KickdownCooldown = false;
                    }

                    // This makes sure the gearbox shifts up in decent time when reaching end of gears
                    if (Main.Drivetrain.StallRpm*KickdownRpmReset > data.Telemetry.EngineRpm)
                    {
                        Debug.WriteLine("[Kickdown] Reset on stalling RPM");
                        KickdownCooldown = true;
                    }
                }
                else
                {
                }
            }

            if (idealGear != data.Telemetry.Gear)
            {
                if (KickdownEnable && KickdownCooldown && !GetHomeMode) return;
                KickdownLockedSpeed = Main.Data.Telemetry.Speed;
                var upShift = idealGear > data.Telemetry.Gear;
                var fullThrottle = data.Telemetry.Throttle > 0.6;

                var shiftStyle = (upShift ? "up" : "down") + "_" + (fullThrottle ? "1" : "0") + "thr";

                Debug.WriteLine("Shift from " + data.Telemetry.Gear + " to  " + idealGear);
                Shift(data.Telemetry.Gear, idealGear, shiftStyle);
            }
        }
Beispiel #10
0
 public void TickTelemetry(IDataMiner data)
 {
     try
     {
         WheelSpeed = Main.Drivetrain.CalculateSpeedForRpm(data.Telemetry.Gear - 1, data.Telemetry.EngineRpm);
         EngineSpeed = data.Telemetry.Speed;//the actual speed we are going
         if (double.IsInfinity(WheelSpeed)) WheelSpeed = 0;
         if (Antistall.Stalling) WheelSpeed = 0;
         SlipAngle = WheelSpeed / EngineSpeed;
         Slipping = (SlipAngle - AllowedSlip > 1.0);
         if (Main.Drivetrain.CalculateSpeedForRpm(data.Telemetry.Gear - 1, (float)Main.Drivetrain.StallRpm * 1.2f) >= data.Telemetry.Speed)
         {
             Slipping = false;
         }
     }catch
     {
     }
 }
Beispiel #11
0
 public ItemService(IDataMiner dm)
 {
     _dm = dm;
 }
Beispiel #12
0
 public void TickTelemetry(IDataMiner data)
 {
     Enabled = true;
     Active = true;
 }
Beispiel #13
0
        public void TickTelemetry(IDataMiner data)
        {
            return;
            try
            {
                if (busy) return;
                busy = true;
                if (sp == null)
                {
                    sp = new SerialPort("COM4", 115200);
                    sp.Open();
                    WriteInitLedTable();
                }
                sp.Write("rpm " + Math.Round(data.Telemetry.EngineRpm) + "\r\n");
                sp.Write("gear " + Math.Round(data.Telemetry.Gear%7*1.0f) + "\r\n");
                busy = false;
            }
            catch(Exception ex)
            {

            }
        }
Beispiel #14
0
 public void ManualSelectApp(IDataMiner app)
 {
     AutoMode = false;
     if (this.miners.Contains(app))
     {
         if (Active != null && Active.IsActive )
         {
             if (AppInactive!=null)
                 AppInactive(this, new EventArgs());
         }
         Active = app;
     }
 }
Beispiel #15
0
        public void TickTelemetry(IDataMiner data)
        {
            if (!Main.Data.Active.SupportsCar) return;
            bool wasCalibrating = Calibrating;
            Calibrating = !Main.Drivetrain.Calibrated;
            if(!wasCalibrating && Calibrating)
            {
                Debug.WriteLine("now calibrating");
                stage = DrivetrainCalibrationStage.StartIdleRpm;
            }

            if(stage!=DrivetrainCalibrationStage.None && !Calibrating)
                stage = DrivetrainCalibrationStage.None;
            ;
            switch(stage)
            {
                case DrivetrainCalibrationStage.None :
                    reqGears = false;
                    reqThrottle = false;
                    reqClutch = false;
                    break;

                case DrivetrainCalibrationStage.StartIdleRpm:

                    reqClutch = true;
                    reqThrottle = true;
                    reqGears = true;
                    Main.Transmission.Shift(data.Telemetry.Gear, 0, calibrateShiftStyle);
                    if (data.Telemetry.EngineRpm < 300)
                    {
                        throttle = 1;
                        clutch = 1;
                        gear = 0;
                    }
                    else if (data.Telemetry.EngineRpm>2000)
                    {
                        throttle = 0;
                        clutch = 1;
                        gear = 0;
                    }else
                    {
                        throttle = 0;
                        clutch = 1;
                        gear = 0;

                        if (Math.Abs(data.Telemetry.EngineRpm - previousEngineRpm) < 1){
                            stage = DrivetrainCalibrationStage.FinishIdleRpm;

                            MeasurementSettletime = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 2750));
                        }
                    }
                        previousEngineRpm = data.Telemetry.EngineRpm;
                    break;
                case DrivetrainCalibrationStage.FinishIdleRpm:
                    if (MeasurementSettled)
                    {
                        Debug.WriteLine("Idle RPM: " + data.Telemetry.EngineRpm);
                        if (data.Telemetry.EngineRpm < 300)
                        {
                            stage = DrivetrainCalibrationStage.StartIdleRpm;
                        }
                        else
                        {
                            Main.Drivetrain.StallRpm = data.Telemetry.EngineRpm;

                            stage = DrivetrainCalibrationStage.StartMaxRpm;
                            maxRpmTarget = data.Telemetry.EngineRpm + 1000;
                            previousThrottle = 0;
                        }
                    }
                    break;

                case DrivetrainCalibrationStage.StartMaxRpm:
                    reqClutch = true;
                    reqThrottle = true;
                    reqGears = true;

                    clutch = 1;
                    throttle = 1;
                    maxRpmMeasured = 0;

                    MeasurementSettletime = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0,1500));
                    stage = DrivetrainCalibrationStage.FinishMaxRpm;

                    break;
                case DrivetrainCalibrationStage.FinishMaxRpm:

                    throttle = 1;
                    maxRpmMeasured = Math.Max(maxRpmMeasured, data.Telemetry.EngineRpm);

                    if (MeasurementSettled)
                    {
                        if (Math.Abs(maxRpmMeasured-Main.Drivetrain.StallRpm) < 500)
                        {
                            Debug.WriteLine("Totally messed up MAX RPM.. resetting");
                            stage = DrivetrainCalibrationStage.StartIdleRpm;
                        }
                        else
                        {
                            Debug.WriteLine("Max RPM approx: " + maxRpmMeasured);

                            Main.Drivetrain.MaximumRpm = maxRpmMeasured-300;

                            stage = DrivetrainCalibrationStage.ShiftToFirst;
                            nextStage = DrivetrainCalibrationStage.StartGears;
                        }
                    }
                    break;

                case DrivetrainCalibrationStage.StartGears:
                    reqClutch = true;
                    reqThrottle = true;
                    reqGears = true;

                    throttle = 0;
                    clutch = 1;
                    gear++;
                    Main.Transmission.Shift(data.Telemetry.Gear, gear, calibrateShiftStyle);
                    MeasurementSettletime = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0,500));

                    stage = DrivetrainCalibrationStage.FinishGears;

                    break;
                case DrivetrainCalibrationStage.FinishGears:

                    if (MeasurementSettled && !Main.Transmission.IsShifting)
                    {
                        if(data.Telemetry.Gear != gear)
                        {
                            gear--;
                            // Car doesn't have this gear.
                            Debug.WriteLine("Gears: " + gear);

                            if (gear <= 0)
                            {
                                Debug.WriteLine("That's not right");
                                stage = DrivetrainCalibrationStage.StartGears;

                            }
                            else
                            {
                                Main.Drivetrain.Gears = gear;
                                Main.Drivetrain.GearRatios = new double[gear];

                                stage = DrivetrainCalibrationStage.ShiftToFirst;
                                nextStage = DrivetrainCalibrationStage.StartGearRatios;
                                MeasurementSettletime = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 500));
                                calibrationPreDone = false;
                            }
                            gear = 0;
                        }
                        else
                        {
                            stage=DrivetrainCalibrationStage.StartGears;
                        }
                    }
                    break;

                case DrivetrainCalibrationStage.ShiftToFirst:
                    if (!Main.Transmission.IsShifting && MeasurementSettled)
                    {
                        if (data.Telemetry.Gear != 1)
                        {
                            Main.Transmission.Shift(shiftToFirstRangeAttempt*Main.Transmission.RangeSize + 1, 1,
                                                    calibrateShiftStyle);
                            shiftToFirstRangeAttempt++;

                            MeasurementSettletime = DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, 100));
                            if (shiftToFirstRangeAttempt > 3) shiftToFirstRangeAttempt = 0;
                        }
                        else
                        {
                            stage = nextStage;
                            MeasurementSettletime = DateTime.MaxValue;
                        }
                    }

                    break;

                case DrivetrainCalibrationStage.EndGearRatios:

                    if (Main.Drivetrain.GearRatios.Length >= data.Telemetry.Gear)
                    {
                        if(data.Telemetry.Gear<=0)
                        {
                            stage = DrivetrainCalibrationStage.StartGearRatios;
                            break;
                        }
                        if (data.Telemetry.EngineRpm > Main.Drivetrain.StallRpm*1.15)
                        {
                            var gr = Main.Drivetrain.GearRatios[data.Telemetry.Gear - 1];
                            if (gr != 0)
                            {
                                stage = DrivetrainCalibrationStage.StartGearRatios;
                                break;
                            }
                            reqThrottle = true;
                            throttle = gearRatioSpeedCruise - data.Telemetry.Speed;
                            throttle /= 3;

                            var ratio = data.Telemetry.EngineRpm / (3.6 * data.Telemetry.Speed);
                            if (ratio > 1000 || ratio < 1)
                            {
                                stage = DrivetrainCalibrationStage.StartGearRatios;
                                break;
                            }

                            Debug.WriteLine("Gear " + data.Telemetry.Gear + " : " + ratio);

                            // start sampling
                            if (sample == 0) sample = ratio;
                            else sample = sample * 0.9 + ratio * 0.1;
                            samplesTaken ++;

                            if(samplesTaken==50)
                            {
                                Main.Drivetrain.GearRatios[data.Telemetry.Gear - 1] = sample;
                            }
                        }
                        else
                        {
                            stage = DrivetrainCalibrationStage.StartGearRatios;
                            break;
                        }
                    }
                    else
                    {
                        stage = DrivetrainCalibrationStage.StartGearRatios;
                    }
                    break;

                case DrivetrainCalibrationStage.StartGearRatios:

                    reqGears = false;
                    reqThrottle = false;
                    reqClutch = false;

                    // Activate get-home-mode; which shifts at 4x stall rpm
                    Main.Transmission.GetHomeMode = true;

                    if (data.Telemetry.EngineRpm > Main.Drivetrain.StallRpm*2)
                    {
                        // Driving at reasonable rpm's.

                        if (data.Telemetry.Gear > 0)
                        {
                            if (Main.Drivetrain.GearRatios.Length >= data.Telemetry.Gear &&
                                data.Telemetry.EngineRpm > Main.Drivetrain.StallRpm * 2)
                            {
                                var gr = Main.Drivetrain.GearRatios[data.Telemetry.Gear - 1];

                                if (gr == 0)
                                {
                                    samplesTaken = 0;
                                    gearRatioSpeedCruise = data.Telemetry.Speed;
                                    stage = DrivetrainCalibrationStage.EndGearRatios;
                                }
                            }
                        }

                        var GearsCalibrated = true;
                        for (int i = 0; i < Main.Drivetrain.Gears; i++)
                        {    if (Main.Drivetrain.GearRatios[i] < 1)
                            {
                                UncalibratedGear = i;

                                GearsCalibrated = false;
                            }
                        }

                        if (GearsCalibrated)
                        {
                            if (MeasurementSettled)
                            {
                                Main.Transmission.GetHomeMode = false;
                                Debug.WriteLine("Calibration done");
                                stage = DrivetrainCalibrationStage.None;

                                Main.Store(Main.Drivetrain.ExportParameters(), Main.Drivetrain.File);
                                Main.Load(Main.Drivetrain, Main.Drivetrain.File);
                            }

                            if (!calibrationPreDone)
                            {
                                calibrationPreDone = true;
                                MeasurementSettletime = DateTime.Now.Add(new TimeSpan(0, 0, 0, 3));
                            }
                        }

                    }

                    break;
            }
        }
Beispiel #16
0
 public void TickTelemetry(IDataMiner data)
 {
     //
     if (data.Application == "eurotrucks2")
     {
         //
         var ets2miner = (Ets2DataMiner) data;
         var ets2telemetry = ets2miner.MyTelemetry;
         var trailerAttached = ets2telemetry.Job.TrailerAttached;
         if (trailerAttached != TrailerAttached)
         {
             TrailerAttached = trailerAttached;
             Main.ReloadProfile(trailerAttached ? ets2telemetry.Job.Mass : 0);
         }
     }
 }
Beispiel #17
0
        public void TickTelemetry(IDataMiner data)
        {
            speed = data.Telemetry.Speed;

            if (true)
            {
                var ets2Tel = (Ets2DataMiner) data;
                var x = ets2Tel.MyTelemetry.Physics.CoordinateX;
                var z = ets2Tel.MyTelemetry.Physics.CoordinateZ;
                var yaw = 2*Math.PI*(ets2Tel.MyTelemetry.Physics.RotationX);
                var lah = 1.5f + ets2Tel.MyTelemetry.Physics.SpeedKmh/100.0f*7.5f;
                x += (float)Math.Sin(yaw)*-lah;
                z += (float)Math.Cos(yaw) * -lah;
                var me = new Ets2Point(x, 0, z, (float)yaw);
                lookPoint = new PointF(x, z);
                // Get map
                var map = Main.LoadedMap;
                var route = dlMap.Route;

                if (map == null || route == null)
                {
                    Active = false;
                    return;
                }

                bool firstTry = true;
                Ets2NavigationSegment activeSegment = default(Ets2NavigationSegment);
                var activeSegmentOption = default(Ets2NavigationSegment.Ets2NavigationSegmentOption);
                float dist = float.MaxValue;

            rescanSegment:
                // Find closest segment
                for (int segI = 0; segI < NearbySegments.Count; segI++)
                {
                    var seg = NearbySegments[segI];
                    if (seg == null)
                        continue;
                    if (!seg.Solutions.Any())
                    {
                        continue;
                    }

                    foreach (var sol in seg.Solutions)
                    {
                        if (sol.HiResPoints == null || !sol.HiResPoints.Any())
                            NearbySegments[segI].GenerateHiRes(sol);

                        var dst = sol.HiResPoints.Min(k => k.DistanceTo(me));
                        if (dist > dst)
                        {
                            dist = dst;
                            activeSegment = NearbySegments[segI];
                            activeSegmentOption = sol;
                        }
                    }

                }
                if (!NearbySegments.Any(k => k != null) || dist > 5)
                {
                    FindNewSegments(route, me);
                    if (firstTry)
                    {
                        firstTry = false;
                        goto rescanSegment;
                    }
                    else
                    {
                        //beep.Play();
                        //Active = false;
                        //return;
                    }
                }

                if (activeSegmentOption == null)
                    return;

                var lineDistanceError = 0.0;
                var angleDistancError = 0.0;

                Ets2Point bestPoint = default(Ets2Point);
                Ets2Point bestPointP1 = default(Ets2Point);
                double bestDistance = double.MaxValue;

                for (var k = 0; k < activeSegmentOption.HiResPoints.Count; k++)
                {
                    var distance = me.DistanceTo(activeSegmentOption.HiResPoints[k]);
                    if (bestDistance > Math.Abs(distance))
                    {
                        bestDistance = Math.Abs(distance);
                        if (k + 1 == activeSegmentOption.HiResPoints.Count)
                        {
                            bestPoint = activeSegmentOption.HiResPoints[k - 1];
                            bestPointP1 = activeSegmentOption.HiResPoints[k];
                        }
                        else
                        {
                            bestPoint = activeSegmentOption.HiResPoints[k];
                            var m = k;
                            do
                            {
                                m++;
                                if (m >= activeSegmentOption.HiResPoints.Count)
                                    break;
                                bestPointP1 = activeSegmentOption.HiResPoints[m];
                            } while (bestPoint.DistanceTo(bestPointP1) < 0.1f && m + 1 < activeSegmentOption.HiResPoints.Count);
                        }
                    }
                }
                var min = activeSegmentOption.HiResPoints.Min(k => k.DistanceTo(me));
                if (bestPoint == null)
                    return;

                var lx1 = bestPoint.X - Math.Sin(-bestPoint.Heading) * 5;
                var lz1 = bestPoint.Z - Math.Cos(-bestPoint.Heading) * 5;
                var lx2 = bestPoint.X + Math.Sin(-bestPoint.Heading) * 5;
                var lz2 = bestPoint.Z + Math.Cos(-bestPoint.Heading) * 5;

                lx2 = bestPoint.X;
                lx1 = bestPointP1.X;
                lz2 = bestPoint.Z;
                lz1 = bestPointP1.Z;

                var px1 = me.X - lx1;
                var pz1 = me.Z - lz1;
                var px2 = lz2 - lz1;
                var pz2 = -(lx2 - lx1);
                var qwer = Math.Sqrt(px2*px2 + pz2*pz2);
                Console.WriteLine(qwer);
                // Reference to top (otherwise 90deg offset) - CCW
                yawRoad = activeSegment.Type == Ets2NavigationSegmentType.Road ? -bestPoint.Heading + Math.PI/2 : bestPoint.Heading - Math.PI/2;

                hook = bestPoint;
                lineDistanceError = (px1*px2 + pz1*pz2)/Math.Sqrt(px2*px2 + pz2*pz2);
                angleDistancError = yaw - yawRoad;
                angleDistancError = angleDistancError%(Math.PI*2);
                 //lineDistanceError = -lineDistanceError;
                if (lineDistanceError > 7) lineDistanceError = 7;
                if (lineDistanceError < -7) lineDistanceError = -7;
                //if (Math.Abs(angleDistancError) < Math.PI/4) lineDistanceError = -lineDistanceError;
                Console.WriteLine(lineDistanceError.ToString("0.00m") + " | " + angleDistancError.ToString("0.000rad"));

                var gain = 2.5f + ets2Tel.Telemetry.Speed/2.5f;

                SteerAngle = 0.5f - lineDistanceError/gain;// - angleDistancError * 0.1f;
                //Debug.WriteLine(lineDistanceError + "px error / " + angleDistancError + " angle error / " + SteerAngle);
            }
        }
Beispiel #18
0
        public void TickTelemetry(IDataMiner data)
        {
            Enabled = true;
            switch (State)
            {
                case PowerMeterState.Idle:
                    if (Main.GetButtonIn(JoyControls.MeasurePower) && false)
                    {
                        integralRevver = 0;
                        State = PowerMeterState.Prearm;
                        this.Active = true;
                    }
                    else
                    {
                        this.Active = false;
                    }
                    break;

                    case PowerMeterState.Prearm:
                    preArmThr =  (1000 - data.Telemetry.EngineRpm)/1500;
                    if (Math.Abs(data.Telemetry.EngineRpm - 1000) < 100)
                    {
                        integralRevver += (1000 - data.Telemetry.EngineRpm)/750000.0f;
                    }
                    else
                    {
                        integralRevver = 0;
                    }
                    preArmThr += integralRevver;

                    if (preArmThr > 0.7f) preArmThr = 0.7f;
                    if (preArmThr < 0) preArmThr = 0;

                    if (Math.Abs(data.Telemetry.EngineRpm - 1000) < 5)
                    {
                        prearmSettler++;
                        if (prearmSettler > 200)
                        {
                            startRevup = DateTime.Now;
                            State = PowerMeterState.Revup;
                        }
                    }
                    else
                    {
                        prearmSettler = 0;
                    }
                    break;

                    case PowerMeterState.Revup:
                    if (data.Telemetry.EngineRpm >= 2000)
                    {
                        endRevup = DateTime.Now;
                        startRevdown = DateTime.Now;
                        State = PowerMeterState.Revdown;
                        revdownRpm = data.Telemetry.EngineRpm;
                    }
                    break;

                case PowerMeterState.Revdown:
                    if (data.Telemetry.EngineRpm <=1000)
                    {
                        endRevdown = DateTime.Now;
                        State = PowerMeterState.Cooldown;
                        var fallTime = endRevdown.Subtract(startRevdown).TotalMilliseconds/1000.0;
                        var fallRpm = revdownRpm - data.Telemetry.EngineRpm;
                        Console.WriteLine("Rev up: " + (endRevup.Subtract(startRevup).TotalMilliseconds) + "ms, rev down: " + (fallTime) + "ms (" + (fallRpm/fallTime)+"rpm/s");
                    }
                    break;

                case PowerMeterState.Cooldown:
                    Active = false;
                    if (data.Telemetry.EngineRpm < 700)
                    {
                        State = PowerMeterState.Idle;
                    }
                    break;

            }
        }
Beispiel #19
0
        public void TickTelemetry(IDataMiner data)
        {
            if (Adaptive && Main.Data.Active.Application == "eurotrucks2")
            {
                var ets2data = (Ets2DataMiner) Main.Data.Active;
                var ets2limit = ets2data.MyTelemetry.Job.SpeedLimit*3.6-4;
                if (ets2limit < 0)
                    ets2limit = 120;

                SpeedLimit = (int)ets2limit;
            }
            if (!Enabled)
            {
                brakeFactor = 0;
                limiterFactor = 1;
            }
            else
            {
                limiterFactor = 1 + (SpeedLimit - data.Telemetry.Speed*3.6)/SpeedSlope;

                if (limiterFactor < 0) limiterFactor = 0;
                if (limiterFactor > 1) limiterFactor = 1;

                if (data.Telemetry.Speed*3.6 - 2 >= SpeedLimit)
                {
                    var err = (data.Telemetry.Speed*3.6 - 3 - SpeedLimit)/25.0*0.15f;
                    brakeFactor = err;
                    limiterFactor = 0;
                }
                else
                {
                    brakeFactor = 0;
                }
            }
            if (data.Telemetry.EngineRpm > 21750)
            {
                Enabled = true;
                limiterFactor *= Math.Max(0, 1 - (data.Telemetry.EngineRpm - 1750)/350.0f);
            }
            var pwrLimiter = Main.Drivetrain.CalculateThrottleByPower(data.Telemetry.EngineRpm,1000);

            if (pwrLimiter > 1) pwrLimiter = 1;
            if (pwrLimiter < 0.2) pwrLimiter = 0.2;

            limiterFactor *= pwrLimiter;
        }
Beispiel #20
0
        public void TickTelemetry(IDataMiner telemetry)
        {
            bool wasStalling = Stalling;
            bool wasEngineStalled = EngineStalled;

            Rpm = telemetry.Telemetry.EngineRpm;
            EngineStalled = (telemetry.Telemetry.EngineRpm < 300);
            AntiStallRpm = Main.Drivetrain.StallRpm*1.25f;

            var gear = telemetry.Telemetry.Gear - 1;
            if (gear == -2) gear = 0;
            if (gear == 0) gear = 1;
            SpeedCutoff = Main.Drivetrain.CalculateSpeedForRpm(gear, (float)AntiStallRpm);

            if (telemetry.Telemetry.Gear == -1)
            {
                ReverseAndAccelerate = telemetry.Telemetry.Speed > 0.5;
                Stalling = telemetry.Telemetry.Speed+0.25 >= -SpeedCutoff;
            }
            else
            {
                ReverseAndAccelerate = telemetry.Telemetry.Speed < -0.5;
                Stalling = telemetry.Telemetry.Speed-0.25 <= SpeedCutoff;
            }
            Stalling |= ReverseAndAccelerate;

            Speed = telemetry.Telemetry.Speed;
            EngineRpm = telemetry.Telemetry.EngineRpm;

            if (EngineStalled && _throttle > 0)
            {
                Override = true;
            }
            else
            {
                Override = false;
            }
        }
Beispiel #21
0
        public void TickTelemetry(IDataMiner data)
        {
            var acc = (data.Telemetry.Speed - previousSpeed) /
                      (DateTime.Now.Subtract(previousTime).TotalMilliseconds / 1000);
            var pullSpeed = Main.Drivetrain.CalculateSpeedForRpm(data.Telemetry.Gear - 1, data.Telemetry.EngineRpm);

            LaunchControlActive = state != LaunchControlState.Inactive;

            switch (state)
            {
                case LaunchControlState.Inactive:
                    break;

                case LaunchControlState.Waiting:
                    _outThrottle = 0;
                    _outClutch = 1;
                    break;

                case LaunchControlState.Revving:
                    _outThrottle = RevvingProp - RevvingProp * data.Telemetry.EngineRpm / LaunchRpm;
                    _outClutch = 1;
                    revvedUp = Math.Abs(data.Telemetry.EngineRpm - LaunchRpm) < 300;
                    break;

                case LaunchControlState.Pulling:
                    _outThrottle = PullingThrottleProp - PullingThrottleProp * data.Telemetry.EngineRpm / LaunchRpm;
                    _outClutch = 1 - PullingClutchProp * previousAcc / PeakAcceleration;
                    if (_outClutch > 0.8) _outClutch = 0.8;

                    if (data.Telemetry.EngineRpm - 300 > LaunchRpm)
                        state = LaunchControlState.Slipping;
                    break;

                case LaunchControlState.Slipping:
                    // revving is less harder to do than pulling
                    // so we switch back to the revving settings, and when the wheelspin is over we go back.
                    _outThrottle = RevvingProp - RevvingProp * data.Telemetry.EngineRpm / LaunchRpm;
                    _outClutch = 1 - PullingClutchProp * previousAcc / PeakAcceleration;
                    if (_outClutch > 0.8) _outClutch = 0.8;

                    if (data.Telemetry.EngineRpm  < LaunchRpm)
                        state = LaunchControlState.Pulling;

                    break;
            }

            if (TemporaryLoadTc)
            {
                if (!tcLoaded && data.Telemetry.Gear == 1 && LaunchControlActive && Main.TractionControl.File.Contains("notc"))
                {
                    tcLoaded = true;
                    Main.Load(Main.TractionControl, "Settings/TractionControl/launch.ini");
                }

                if(tcLoaded && data.Telemetry.Gear != 1)
                {
                    tcLoaded = false;
                    Main.Load(Main.TractionControl, "Settings/TractionControl/notc.ini");
                }
            }

            if (LaunchControlActive && data.Telemetry.Speed > pullSpeed * 0.95)
            {
                Debug.WriteLine("Done pulling!");
                // We're done pulling
                state = LaunchControlState.Inactive;
            }

            if (_outThrottle > 1) _outThrottle = 1;
            if (_outThrottle < 0) _outThrottle = 0;

            if (_outClutch > 1) _outClutch = 1;
            if (_outClutch < 0) _outClutch = 0;

            previousSpeed = data.Telemetry.Speed;
            previousTime = DateTime.Now;
            previousAcc = acc*0.25 + previousAcc*0.75;

            //Debug.WriteLine(previousAcc);
        }
        public void TickTelemetry(IDataMiner data)
        {
            bool copyTargetThr = false;

            /** VARIABLE SPEED CONTROL **/
            var actualSpeed = data.Telemetry.Speed * 3.6;

            double thrP, thrI;
            if (data.Telemetry.Gear == -1)
            {
                SetSpeed = Main.GetAxisIn(JoyControls.VstLever) * 50;
                actualSpeed *= -1;

                thrP = 0.1;
                thrI = 0;

            }
            else
            {
                SetSpeed = Main.GetAxisIn(JoyControls.VstLever)*((fast) ? 200 : 100);

                thrP = 0.015 + 0.15 * actualSpeed / 120;
                thrI = 0.02 - 0.015 * actualSpeed / 120;
                if (Efficiency)
                {
                    thrP *= 0.5;
                    thrI = 0.00025;
                }
                if (Efficiency != wasEfficiency)
                {
                    copyTargetThr = true;
                    staticThrError = variableThrottle-2*thrP*lastSpeedError;
                }
                wasEfficiency = Efficiency;
            }
            var speedErrorThr = SetSpeed - actualSpeed;
            staticThrError += speedErrorThr*thrI;
            if (staticThrError > 0.8) staticThrError = 0.8;
            if (staticThrError < -0.8) staticThrError = -0.8;
            lastSpeedError = speedErrorThr;
            var oldThr = variableThrottle;
            if (copyTargetThr)
            {
                variableThrottle = thrP * speedErrorThr;
                variableThrottle *= UserThrottle;

                // Theoratical value required to copy last throttle
                staticThrError = (1 - variableThrottle)/UserThrottle;

                //Deduce at low speeds
                var deductor = actualSpeed/50;
                if (deductor > 1) deductor = 1;
                if (deductor < 0.01) deductor = 0.01;
                staticThrError *= deductor;

                // Add it.
                variableThrottle += staticThrError;
            }
            else
            {
                variableThrottle = thrP * speedErrorThr + staticThrError;
                variableThrottle *= UserThrottle;
            }
            if (variableThrottle > 1) variableThrottle = 1;
            if (variableThrottle < 0) variableThrottle = 0;

            var speedErrorBr = (actualSpeed - 3) - SetSpeed;
            if (speedErrorBr < 0) speedErrorBr = 0;
            if (actualSpeed < 50)
                speedErrorBr *= (50 - actualSpeed) / 15 + 1;
            variableBrake = 0.01 * speedErrorBr * speedErrorBr;
            if (variableBrake > 0.2) variableBrake = 0.2;
            if (variableBrake < 0) variableBrake = 0;

            if (variableBrake > 0.01)
                variableThrottle = 0;
            /** TRANSMISSION **/
            if (Main.Data.Active.Application == "eurotrucks2")
            {
                var ets2 = (Ets2DataMiner) Main.Data.Active;
                if (ets2.MyTelemetry.Job.TrailerAttached == false && !fast)
                    Efficiency = true;
                else
                {
                    if (Efficiency)
                    {
                        if ((SetSpeed - actualSpeed) > 5)
                        {
                            Efficiency = false;
                        }
                    }
                    else
                    {
                        if ((SetSpeed - actualSpeed) < 2)
                        {
                            Efficiency = true;
                        }
                    }
                }
            }
            //Efficiency = (SetSpeed - actualSpeed) < 5;
            if (DateTime.Now.Subtract(lastShifterTick).TotalMilliseconds > 40)
            {
                Active = ShiftingPhase == ShiftPhase.None ? false : true;
                lastShifterTick = DateTime.Now;
                switch (ShiftingPhase)
                {
                    case ShiftPhase.WaitButton:
                        if (Main.GetButtonIn(JoyControls.GearUp) == false &&
                            Main.GetButtonIn(JoyControls.GearDown) == false)
                        {
                            ShiftingPhase = ShiftPhase.None;
                        }
                        break;

                    case ShiftPhase.None:

                        // Reverse pressed?
                        if (Main.GetButtonIn(JoyControls.VstChange))
                        {
                            fast = !fast;
                            ShiftingPhase = ShiftPhase.WaitButton;
                        }
                        if (Main.GetButtonIn(JoyControls.GearDown))
                        {
                            Reverse = !Reverse;
                            ShiftingPhase = ShiftPhase.WaitButton;
                        }

                        if (Reverse)
                        {
                            if (data.Telemetry.Gear != -1)
                            {
                                Gear = -1;
                                ShiftingPhase = ShiftPhase.OffThrottle;
                            }
                        }
                        else
                        {
                            // Do nothing
                            if (data.Telemetry.Gear != Gear || Gear == 0)
                            {
                                if (Gear == 0)
                                    Gear++;
                                if (Gear == -1)
                                    Gear = 1;
                                ShiftingPhase = ShiftPhase.OffThrottle;
                            }
                            else
                            {
                                var curPower = Main.Drivetrain.CalculatePower(data.Telemetry.EngineRpm,
                                    data.Telemetry.Throttle);
                                if (curPower < 1) curPower = 1;
                                var curEfficiency = Main.Drivetrain.CalculateFuelConsumption(data.Telemetry.EngineRpm,
                                    data.Telemetry.Throttle)/curPower;
                                var reqPower = curPower*(variableThrottle - 0.5)*2;
                                if (reqPower < 25) reqPower = 25;
                                if (reqPower > 0.5*Main.Drivetrain.CalculateMaxPower())
                                    reqPower = 0.5*Main.Drivetrain.CalculateMaxPower();
                                reqpower = reqPower;
                                int maxgears = Main.Drivetrain.Gears;
                                var calcEfficiency = Efficiency ? double.MaxValue : 0;
                                var calcEfficiencyGear = -1;
                                var calcThrottle = variableThrottle;
                                var calcPower = curPower;

                                var allStalled = true;
                                for (int k = 0; k < maxgears; k++)
                                {
                                    if (maxgears >= 12 && ( k == 5)) continue;
                                    if (maxgears >= 10 && (k == 1 || k == 3)) continue;
                                    if (!Efficiency && k < 3) continue;

                                    // Always pick best efficient gear with power requirement met
                                    var rpm = Main.Drivetrain.CalculateRpmForSpeed(k, data.Telemetry.Speed);
                                    var orpm = Main.Drivetrain.CalculateRpmForSpeed(k, data.Telemetry.Speed);
                                    var estimatedPower = Main.Drivetrain.CalculatePower(rpm, variableThrottle);

                                    // RPM increase linear to throttle:
                                    rpm += estimatedPower/1200*190*variableThrottle;

                                    if (rpm < Main.Drivetrain.StallRpm && k > 0)
                                        continue;
                                    allStalled = false;
                                    if (orpm > Main.Drivetrain.MaximumRpm)
                                        continue;

                                    var thr = Main.Drivetrain.CalculateThrottleByPower(rpm, reqPower);
                                    if (thr > 1) thr = 1;
                                    if (thr < 0) thr = 0;
                                    var eff = Main.Drivetrain.CalculateFuelConsumption(rpm, thr)/reqPower;
                                    var pwr = Main.Drivetrain.CalculatePower(rpm, variableThrottle);

                                    if (Efficiency)
                                    {
                                        if (calcEfficiency > eff && eff*1.1 < curEfficiency)
                                        {
                                            calcEfficiency = eff;
                                            calcEfficiencyGear = k;
                                            calcThrottle = thr;
                                            calcPower = pwr;
                                        }
                                    }
                                    else
                                    {
                                        if (pwr > calcEfficiency)
                                        {
                                            calcEfficiency = pwr;
                                            calcEfficiencyGear = k;
                                            calcPower = pwr;
                                        }
                                    }
                                }

                                if (allStalled)
                                    if (maxgears >= 10)
                                    Gear = 3;
                                    else
                                    {
                                        Gear = 1;
                                    }
                                else if (calcEfficiencyGear >= 0 &&
                                    calcEfficiencyGear+1 != Gear)
                                {

                                    // Hysterisis
                                    if (Math.Abs(curPower - calcPower) > 25)
                                        Gear = calcEfficiencyGear+1;
                                }
                                if (Efficiency)
                                {
                                    //variableThrottle = Main.Drivetrain.CalculateThrottleByPower(
                                    //    data.Telemetry.EngineRpm,
                                    //    reqPower);
                                }
                                else
                                {
                                    //
                                }
                                if (Gear > 0 && Gear != data.Telemetry.Gear)
                                    ShiftingPhase = ShiftPhase.OffThrottle;
                            }
                        }
                        break;

                    case ShiftPhase.OffThrottle:
                        ShiftingPhase++;
                        break;

                    case ShiftPhase.OnClutch:
                        ShiftingPhase++;
                        break;

                    case ShiftPhase.EngageRange:
                        ShiftingPhase++;
                        break;

                    case ShiftPhase.EngageGear:
                        ShiftingPhase++;
                        break;

                    case ShiftPhase.Evaluate:
                        if (Gear == data.Telemetry.Gear)
                        {
                            LastSeenRange = DeductRangeFromGear(Gear);
                            ShiftingPhase++;
                        }
                        else
                        {
                            shiftingRetry++;
                            if (shiftingRetry > 50)
                            {
                                if (Gear > 0)
                                    Gear--;
                                else
                                    Gear = -1;
                                shiftingRetry = 0;
                                ShiftingPhase = ShiftPhase.EngageGear;
                            }
                            else                            if (shiftingRetry > 2)
                            {
                                LastSeenRange++;
                                LastSeenRange = LastSeenRange % 4;
                                ShiftingPhase = ShiftPhase.OnClutch;
                            }
                            else
                            {
                                ShiftingPhase = ShiftPhase.EngageGear;
                            }
                        }
                        break;

                    case ShiftPhase.OffClutch:
                        ShiftingPhase++;
                        break;

                    case ShiftPhase.OnThrottle:
                        shiftingRetry = 0;
                        ShiftingPhase = ShiftPhase.Cooldown;
                        break;

                        case ShiftPhase.Cooldown:
                        shiftingRetry++;
                        if (shiftingRetry > 4)
                        {
                            shiftingRetry = 0;
                            ShiftingPhase = ShiftPhase.None;
                        }
                        break;
                }
            }
        }