Пример #1
0
        protected override ContentRepairSuggestion GetObsoletableAspect(CarObject car, DataWrapper data)
        {
            // doesn’t work with KERS
            if (!data.GetIniFile("ers.ini").IsEmptyOrDamaged() || !data.GetIniFile("ctrl_ers_0.ini").IsEmptyOrDamaged())
            {
                return(null);
            }

            if ((car.SpecsBhp?.IndexOf("*", StringComparison.Ordinal) ?? 0) != -1 ||
                (car.SpecsBhp?.IndexOf("whp", StringComparison.OrdinalIgnoreCase) ?? 0) != -1 ||
                (car.SpecsTorque?.IndexOf("*", StringComparison.Ordinal) ?? 0) != -1 ||
                !FlexibleParser.TryParseDouble(car.SpecsTorque, out var maxUiTorque))
            {
                return(null);
            }

            Lut torque;

            try {
                torque = TorquePhysicUtils.LoadCarTorque(data);
            } catch (Exception e) {
                Logging.Warning(e);
                return(null);
            }

            var loss = 1d - torque.MaxY / maxUiTorque;

            if (loss > 0.01)
            {
                return(null);
            }

            var actual = loss.Abs() < 0.002 ? "same" : loss > 0 ? $"{loss * 100:F1}% smaller" : $"{-loss * 100:F1}% bigger";

            return(new CommonErrorSuggestion("Suspiciously low transmission power loss",
                                             $"Usually, in UI torque & power are taken from crankshaft, but data should contain torque at wheels, which is about 10–20% smaller. " +
                                             $"Here, although, it’s {actual}. It might be a mistake.\n\nIf you want to specify power at the wheels in UI, add “*”.",
                                             (p, c) => FixAsync(car, p, c))
            {
                AffectsData = false,
                ShowProgressDialog = false,
                FixCaption = "Fix UI"
            }.AlternateFix("Add “*”", (progress, token) => {
                if (FlexibleParser.TryParseDouble(car.SpecsBhp, out var uiBhp))
                {
                    car.SpecsBhp = SelectedAcObjectViewModel.SpecsFormat(AppStrings.CarSpecs_PowerAtWheels_FormatTooltip,
                                                                         uiBhp.ToString(@"F0", CultureInfo.InvariantCulture));
                }

                if (FlexibleParser.TryParseDouble(car.SpecsTorque, out var uiTorque))
                {
                    car.SpecsTorque = SelectedAcObjectViewModel.SpecsFormat(AppStrings.CarSpecs_Torque_FormatTooltip,
                                                                            uiTorque.ToString(@"F0", CultureInfo.InvariantCulture)) + "*";
                }

                return Task.FromResult(true);
            }, false));
        }
Пример #2
0
        protected override Task <bool> FixAsync(CarObject car, IProgress <AsyncProgressEntry> progress = null,
                                                CancellationToken cancellation = default(CancellationToken))
        {
            progress?.Report(AsyncProgressEntry.FromStringIndetermitate("Fixing car…"));

            var data = car.AcdData;

            if (data == null || data.IsEmpty)
            {
                return(Task.FromResult(false));
            }

            Lut torque, power;

            try {
                torque = TorquePhysicUtils.LoadCarTorque(data);
                power  = TorquePhysicUtils.TorqueToPower(torque);
            } catch (Exception e) {
                Logging.Error(e);
                return(Task.FromResult(false));
            }

            var multipler = ActionExtension.InvokeInMainThread(() => {
                var dlg = new CarTransmissionLossSelector(car, torque.MaxY, power.MaxY);
                dlg.ShowDialog();
                return(dlg.IsResultOk ? dlg.Multipler : (double?)null);
            });

            if (!multipler.HasValue)
            {
                return(Task.FromResult(false));
            }

            torque.TransformSelf(x => x.Y * multipler.Value);
            power.TransformSelf(x => x.Y * multipler.Value);

            if (car.SpecsTorqueCurve != null)
            {
                var torqueUi = new Lut(car.SpecsTorqueCurve.Points);
                torqueUi.TransformSelf(x => x.Y * multipler.Value);
                car.SpecsTorqueCurve = new GraphData(torqueUi);
            }

            if (car.SpecsPowerCurve != null)
            {
                var powerUi = new Lut(car.SpecsPowerCurve.Points);
                powerUi.TransformSelf(x => x.Y * multipler.Value);
                car.SpecsPowerCurve = new GraphData(powerUi);
            }

            car.SpecsTorque = SelectedAcObjectViewModel.SpecsFormat(AppStrings.CarSpecs_Torque_FormatTooltip,
                                                                    torque.MaxY.ToString(@"F0", CultureInfo.InvariantCulture)) + (multipler.Value == 1d ? "*" : "");
            car.SpecsBhp = SelectedAcObjectViewModel.SpecsFormat(multipler.Value == 1d ? AppStrings.CarSpecs_PowerAtWheels_FormatTooltip
                    : AppStrings.CarSpecs_Power_FormatTooltip, power.MaxY.ToString(@"F0", CultureInfo.InvariantCulture));
            return(Task.FromResult(true));
        }
Пример #3
0
        protected override ContentRepairSuggestion GetObsoletableAspect(CarObject car, DataWrapper data)
        {
            if ((car.SpecsWeight?.IndexOf("*", StringComparison.Ordinal) ?? 0) != -1)
            {
                return(null);
            }

            var uiWeight = car.GetWidthValue() ?? 0d;

            if (uiWeight <= 1d)
            {
                return(null);
            }

            var withDriver = data.GetIniFile(@"car.ini")["BASIC"].GetFloat("TOTALMASS", -1f);

            if (withDriver <= 0f)
            {
                return(null);
            }

            var weight       = withDriver - CommonAcConsts.DriverWeight;
            var driverWeight = withDriver - uiWeight;

            if (driverWeight > CommonAcConsts.DriverWeight - OptionAllowedPadding)
            {
                return(null);
            }

            var valueStr = Math.Abs(driverWeight) < 0.1 ? "nothing" : driverWeight < 1 ? $"{driverWeight} kg" : $"only {driverWeight} kg";

            return(new CommonErrorSuggestion("Invalid weight",
                                             $"In car.ini, TOTALMASS should include driver weight (+{CommonAcConsts.DriverWeight} kg) as well, " +
                                             $"but according to these TOTALMASS and mass in UI file, driver weights {valueStr}. Could be a mistake.\n\nIf you want to specify weight with driver in UI, add “*”.",
                                             (p, c) => FixAsync(car, p, c))
            {
                AffectsData = true,
                FixCaption = "Fix data"
            }.AlternateFix("Fix UI", (progress, token) => {
                car.SpecsWeight = SelectedAcObjectViewModel.SpecsFormat(AppStrings.CarSpecs_Weight_FormatTooltip,
                                                                        weight.ToString(@"F0", CultureInfo.InvariantCulture));
                return Task.FromResult(true);
            }, false).AlternateFix("Add “*”", (progress, token) => {
                car.SpecsWeight = SelectedAcObjectViewModel.SpecsFormat(AppStrings.CarSpecs_Weight_FormatTooltip,
                                                                        withDriver.ToString(@"F0", CultureInfo.InvariantCulture)) + "*";
                return Task.FromResult(true);
            }, false));
        }