public IEnumerable<WeightedLocation> GetWeightedLocations(LogLine logLine) { var baseRpmIndex = RpmIndex(logLine.Rpm.Value); var baseKpaIndex = KpaIndex(logLine.Map.Value); var locations = new List<WeightedLocation>(); for (int kpaI = SafeIndex(baseKpaIndex - 2); kpaI <= SafeIndex(baseKpaIndex + 2); kpaI++) { for (int rpmI = SafeIndex(baseRpmIndex - 2); rpmI <= SafeIndex(baseRpmIndex + 2); rpmI++) { var location = new WeightedLocation { KpaIndex = kpaI, RpmIndex = rpmI, ProximityIndex = CalcProximityIndex(kpaI, rpmI, logLine) }; if (location.ProximityIndex > 0.05) { locations.Add(location); } } } if (locations.Count == 1) { locations[0].ProximityIndex = 1; } return locations; }
public void TestIndexing() { var coords = new MapCoordinates(); var logline = new LogLine(){Rpm = new Rpm(){Value = 1888}, Map = new Map(){Value = 45}}; Assert.AreEqual(2.7777, coords.ExactRpmIndex(logline)); Assert.AreEqual(2.6, coords.ExactKpaIndex(logline)); }
public void TestImportance(float rpm, float kpa) { var service = new MapCoordinates(); var line = new LogLine() { Map = new Map { Value = kpa }, Rpm = new Rpm { Value = rpm } }; var location = service.GetWeightedLocations(line); Assert.GreaterOrEqual(location.Count(), 1); Assert.Greater(location.Sum(l => l.ProximityIndex), 0.85); Assert.Less(location.Sum(l => l.ProximityIndex), 1.18); }
private LogLine GetLogLine(byte[] line) { var logLine = new LogLine() { Map = new Map() { Bytes = line[Index["Map"]]}, AccEnr = new AccEnr() { Bytes = line[Index["AccEnr"]] }, AfrCorrection = new AfrCorrection() { Bytes = line[Index["AfrCorrection"]] }, AfrWideband = new AfrWideband() { Bytes = line[Index["AfrWideband"]] }, Coolant = new Coolant() { Bytes = line[Index["Coolant"]] }, Iat = new Iat() { Bytes = line[Index["Iat"]] }, Tps = new Tps() { Bytes = line[Index["Tps"]] }, Rpm = new Rpm() { Bytes = BitConverter.ToUInt16(line, Index["Rpm"]) }, }; return logLine; }
public LogLine[] ReadLog(byte[] fileContent) { var howManyLines = (fileContent.Length - Header.Length) / LineLength; var result = new LogLine[howManyLines]; var copyArray = new byte[40]; for (var lineNo = 0; lineNo < howManyLines; lineNo += 1) { var skip = Header.Length + lineNo * LineLength; //if slow, change to array.Copy() Array.Copy(fileContent, skip, copyArray, 0, 40); //var lineBytes = fileContent.Skip(skip).Take(LineLength).ToArray(); var line = GetLogLine(copyArray); result[lineNo] = line; } return result; }
public IEnumerable<LogLine>[,] BuildMap(LogLine[] log) { var map = new List<LogLine>[16,16]; for (int i = 0; i < log.Length - 1; i++) { var logLine = log[i]; //cool engine if (logLine.Coolant.Value < 70) continue; // acceleration enrichment if (logLine.AccEnr.Value > 5) { continue; } //fuel cut if (logLine.Map.Value < 20 && logLine.Tps.Value < 2 && logLine.Rpm.Value > 1650) continue; //engine stop if (logLine.Rpm.Value < 3) continue; //fuel cut if(Math.Abs(logLine.AfrCorrection.Value) < 0.1 && logLine.AfrWideband.Value > 22) continue; if (i + AfrCorrDelay < log.Length) { logLine.AfrCorrection.Bytes = log[i + AfrCorrDelay].AfrCorrection.Bytes; } var rpmIndex = _coord.RpmIndex(logLine.Rpm.Value); var lambdaDelay = LambdaDelay[rpmIndex]; //var lambdaDelay = 0; //lambda delay (cca 100ms) if (i + lambdaDelay < log.Length) { //Console.WriteLine("Lambda diff: {0}", logLine.AfrWideband.Value - log[i + LambdaDelay].AfrWideband.Value); logLine.AfrWideband.Bytes = log[i + lambdaDelay].AfrWideband.Bytes; } var weightedLocations = _coord.GetWeightedLocations(logLine); var topOne = weightedLocations.OrderByDescending(w => w.ProximityIndex).FirstOrDefault(); //if (topOne != null) //{ // topOne.ProximityIndex = 1; //} foreach (var weightedLocation in weightedLocations) { if (map[weightedLocation.RpmIndex, weightedLocation.KpaIndex] == null) { map[weightedLocation.RpmIndex, weightedLocation.KpaIndex] = new List<LogLine>(); } logLine.ProximityIndex = weightedLocation.ProximityIndex; map[weightedLocation.RpmIndex, weightedLocation.KpaIndex].Add(logLine); } } return map; }
public float ExactKpaIndex(LogLine logLine) { return (logLine.Map.Value - _realKpaOffset) / (KpaMax - KpaMin) * 16 - 1; }
public float ExactRpmIndex(LogLine logLine) { return ((logLine.Rpm.Value + _realRpmOffset) / RpmMax) * 16 - 1; }
public float CalcProximityIndex(int kpaI, int rpmI, LogLine logLine) { var exactRpmIndex = ExactRpmIndex(logLine); var exactKpaIndex = ExactKpaIndex(logLine); var kpaDiff = Math.Abs(kpaI - exactKpaIndex + 0.5); var rpmDiff = Math.Abs(rpmI - exactRpmIndex + 0.5); var distance = Math.Sqrt(Math.Pow(kpaDiff, 2) + Math.Pow(rpmDiff, 2)); //var index = (float)Math.Log(1 / distance, 10); //return Math.Min(1, Math.Max(0, index)); if (distance < 1) { return (float) (1 - distance); } return 0; }
public float[,] CalculateAfrDelay(LogLine[] log) { var map = new List<int>[16, 16]; var fuelCut = false; for (int i = 0; i < log.Length; i++) { var logLine = log[i]; int delay; var kpaIndex = _coord.KpaIndex(logLine.Map.Value); var rpmIndex = _coord.RpmIndex(logLine.Rpm.Value); if (map[rpmIndex, kpaIndex] == null) { map[rpmIndex, kpaIndex] = new List<int>(); } // fuel cut start if (!fuelCut && logLine.Map.Value < 26 && logLine.Tps.Value < 1 && logLine.Rpm.Value > 1650) { fuelCut = true; //fuel cut start if (log[i + 1].Map.Value > 26 && log[i + 1].Tps.Value > 1 && log[i + 1].Rpm.Value > 1650) { for (int j = i; j < i + 30; j++) { if (log[j].AfrWideband.Value > 18) { map[rpmIndex, kpaIndex].Add(i - j); break; } } //check how long it took } } // fuel cut end else if (fuelCut && logLine.Map.Value > 26 && logLine.Tps.Value > 1 && logLine.Rpm.Value > 1650) { fuelCut = false; //fuel cut start if (log[i + 1].Map.Value > 26 && log[i + 1].Tps.Value > 1 && log[i + 1].Rpm.Value > 1650) { for (int j = i; j < i + 30; j++) { if (log[j].AfrWideband.Value < 16) { map[rpmIndex, kpaIndex].Add(i-j); break; } } //check how long it took } } else { fuelCut = false; continue; } } return Averange(map); }