示例#1
0
        public static double[] ApplyUKF(double[] Data)
        {
            double[] NewData = new double[Data.Length];

            UKF Filter = new UKF();

            for (int i = 0; i < Data.Length; i++)
            {
                Filter.Update(new[] { Data[i] });
                NewData[i] = Filter.getState()[0];
            }

            return(NewData);
        }
示例#2
0
        public void Calculate()
        {
            // Find max and min RPM index
            int    MaxRPMIdx = -1;
            int    MinRPMIdx = -1;
            double MaxRPM    = -1;
            double MinRPM    = -1;

            Calculator.Weight2 = Weight;

            for (int i = 0; i < DataEntries.Length; i++)
            {
                if (DataEntries[i][RPM] > MaxRPM)
                {
                    MaxRPMIdx = i;
                    MaxRPM    = DataEntries[i][RPM];
                }
            }

            for (int i = MaxRPMIdx - 1; i >= 0; i--)
            {
                if (DataEntries[i][RPM] < DataEntries[i + 1][RPM])
                {
                    MinRPMIdx = i;
                    MinRPM    = DataEntries[i][RPM];
                    continue;
                }

                break;
            }

            if (MaxRPMIdx == -1 || MinRPMIdx == -1 || (MaxRPM - MinRPMIdx) <= 1)
            {
                throw new Exception("Invalid data");
            }

            // Trim data
            DataEntries = DataEntries.Skip(MinRPMIdx).Take(MaxRPMIdx - MinRPMIdx).ToArray();

            // Normalize time
            double StartTime = DataEntries[0][DeviceTime];

            for (int i = 0; i < DataEntries.Length; i++)
            {
                DataEntries[i][DeviceTime] = DataEntries[i][DeviceTime] - StartTime;
            }

            // Smooth out speed

            /*double[] Speeds = DataEntries.Select(E => GetSpeed(E)).ToArray();
             * Speeds = Utils.ApplyUKF(Speeds);
             * for (int i = 0; i < DataEntries.Length; i++)
             *      SetSpeed(DataEntries[i], Speeds[i]);*/

            // Calculate all data
            const int CalcOffset = 1;
            double    Dt         = 0;

            DataEntries[0].Calculated = new CalculatedEntry();

            UKF Filter = new UKF(DataEntries.Length);

            double MaxPower  = 0;
            double MaxTorque = 0;

            for (int i = CalcOffset; i < DataEntries.Length - CalcOffset; i++)
            {
                int PrevIdx = i - CalcOffset;
                int NextIdx = i + CalcOffset;

                double PrevTime = DataEntries[PrevIdx][DeviceTime];
                double CurTime  = DataEntries[i][DeviceTime];
                double NextTime = DataEntries[NextIdx][DeviceTime];

                Dt = Utils.Distance(PrevTime, NextTime);

                double PrevSpeed = GetSpeed(PrevIdx);
                double CurSpeed  = GetSpeed(i);
                double NextSpeed = GetSpeed(NextIdx);

                double PowerRaw = Calculator.Calculate(NextSpeed, PrevSpeed, NextTime, PrevTime);
                Filter.Update(new double[] { PowerRaw });

                //double Power = Filter.getState()[0];
                double Power = PowerRaw;

                double Torque = Calculator.CalcTorque(Power * 1.2, DataEntries[i][RPM]);

                if (Power > MaxPower)
                {
                    MaxPower = Power;
                }

                if (Torque > MaxTorque)
                {
                    MaxTorque = Torque;
                }

                DataEntries[i].Calculated = new CalculatedEntry(Power, PowerRaw, Torque);
            }

            Console.WriteLine("{0} whp; {1} Nm", MaxPower, MaxTorque);

            // Fill last index
            int LastIdx = DataEntries.Length - 1;

            if (DataEntries[LastIdx].Calculated == null)
            {
                int Prev = FindPrevious(LastIdx, null);
                DataEntries[LastIdx].Calculated = new CalculatedEntry(DataEntries[Prev].Calculated);
            }

            // Interpolate calculated data
            for (int i = 0; i < DataEntries.Length; i++)
            {
                if (DataEntries[i].Calculated == null)
                {
                    LogEntry Prev = DataEntries[FindPrevious(i, null)];
                    LogEntry Next = DataEntries[FindNext(i, null)];

                    DataEntries[i].Calculated = new CalculatedEntry(this, Prev, Next, DataEntries[i][DeviceTime]);
                }
            }

            // Smooth out power raw
            double[] PowerRaws = DataEntries.Select(E => E.Calculated.PowerRaw).ToArray();
            Utils.NoiseReduction(ref PowerRaws, 1);             // 4
            for (int i = 0; i < PowerRaws.Length; i++)
            {
                DataEntries[i].Calculated.Power = PowerRaws[i];
            }
        }