/// <summary> /// 引数の文字列式を、CANDataの数値に置き換えた文字列を返す /// </summary> /// <param name="Formula">計算式</param> /// <param name="Data">CANデータ</param> public string DecodeFormula(string Formula, FormMain.CanData data) { //計算式 System.Text.StringBuilder exp = new System.Text.StringBuilder(Formula); string str; byte nibble = (byte)(0x0F); //式中のLoData1~LoData8の文字列を、数値に置き換える for (int i = 0; i < 8; i++) { //Lower 4bitは、Higher 4bitを0でマスクするだけ str = (nibble & data.data[i]).ToString(); exp = exp.Replace("LoData" + (i + 1).ToString(), str); } //式中のHiData1~HiData8の文字列を、数値に置き換える for (int i = 0; i < 8; i++) { //Higher 4bitは、4bit右シフトするだけ str = (data.data[i] >> 4).ToString(); exp = exp.Replace("HiData" + (i + 1).ToString(), str); } //式中のData1~Data8の文字列を、数値に置き換える //Data1~Data8の置き換えを、LoDataやHiDataの前に実行すると、LoData1の中のData1のみ置換されてうまく動かない事に注意 for (int i = 0; i < 8; i++) { str = data.data[i].ToString(); exp = exp.Replace("Data" + (i + 1).ToString(), str); } return(exp.ToString()); }
/// <summary> /// 引数の文字列式を、固定計算式のインデックスに変換する /// ユーザー定義のデータとCanDataはインデックスが1異なる事に注意 /// </summary> /// <param name="Formula">計算式</param> /// <param name="Data">CANデータ</param> public double FixedFormula(string Formula, FormMain.CanData data) { // nibble計算用 byte nibble = (byte)(0x0F); // 車速 double frSpeed; double rrSpeed; // Formulaに対応した計算を以下列挙する switch (Formula) { // CANID 10C // BMW Engine RPM // (LoData4*255+Data3)*5 case "#BMW_RPM": return(((nibble & data.data[3]) * 256d + data.data[2]) * 5d); // CANID 10C // BMW Throttel Valve Position // Data6/255*100 case "#BMW_ThrottelValvePosition": return(data.data[5] / 255d * 100d); // CANID 10C // BMW Throttel Position // Data8/255*100 case "#BMW_ThrottelPosition": return(data.data[7] / 255d * 100d); // CANID 110 // BMW Ignition Timing // LoData4*256+Data3 // ToDo need to confirm later //case "#BMW_IgnitionTiming": // return ((nibble & data.data[3])*256d + data.data[2]) / 5d; // CANID 110 // BMW Throttel Grip Position // Data6/255*100 case "#BMW_ThrottelGripPosition": return(data.data[5] / 255d * 100d); // CANID 120 // BMW FrBrake1 // Data3 case "#BMW_FrBrake1": return(data.data[2] / 4d); // CANID 120 // BMW FrBrake2 // Data5 case "#BMW_FrBrake2": return(data.data[4] / 4d); // CANID 120 // BMW RrBrake1 // Data4 case "#BMW_RrBrake1": return(data.data[3] / 2d); // CANID 120 // BMW RrBrake2 // Data6 case "#BMW_RrBrake2": return(data.data[5] / 2d); // CANID 29C // BMW FrStroke // (LoData7*256+Data6)/5 case "#BMW_FrStroke": return(((nibble & data.data[6]) * 256d + data.data[5]) / 5d); // CANID 29C // BMW RrStroke // (Data8*16+HiData7)/3 case "#BMW_RrStroke": return((data.data[7] * 16d + (data.data[6] >> 4)) / 3d); // CANID 10C // BMW LeanAngle // (Data5*90/128-90) case "#BMW_LeanAngle": return(((double)data.data[4] * 90d / 127d) - 90d); // CANID 293 // BMW RrSpeed // (LoData2*256+Data1)/8 case "#BMW_RrSpeed": return(((nibble & data.data[1]) * 256d + data.data[0]) / 8d); // CANID 293 // BMW FrSpeed2 // (Data3*16+HiData2)/8 case "#BMW_FrSpeed2": return((data.data[2] * 16d + (data.data[1] >> 4)) / 8d); // CANID 293 // BMW FrSpeed1 // (LoData5*256+Data4)/8 case "#BMW_FrSpeed1": return(((nibble & data.data[4]) * 256 + data.data[3]) / 8d); // CANID 293 // BMW_DistFrSpeed1 // 積分計算が後処理で必要になるので、ダミーで0を返すだけとする。 case "#BMW_DistFrSpeed1": return(0); // CANID 293 // BMW SlipRate // rrSpeed/frSpeed*100-100 case "#BMW_SlipRate": rrSpeed = (((nibble & data.data[1]) * 256d) + data.data[0]) / 8d; frSpeed = (((nibble & data.data[4]) * 256d) + data.data[3]) / 8d; // 0割防止 if (frSpeed == 0) { return(0); } return(rrSpeed / frSpeed * 100d - 100d); // CANID 2BC // BMW BMW_Gear // HiData6 // 1 4 7 8 11 13 が 1-6速に該当 case "#BMW_Gear": switch (data.data[5] >> 4) { case 1: return(1); case 4: return(2); case 7: return(3); case 8: return(4); case 11: return(5); case 13: return(6); default: return(0); } // CANID 174 // BMW_YawRate // Data2*125/128+Data1/256-125 case "#BMW_YawRate": return(data.data[1] * 125d / 127d + data.data[0] / 255d - 125d); // CANID 174 // BMW_YAxisG // (Data6+Data5/256-128)/32 case "#BMW_YAxisG": return((data.data[5] + (data.data[4] / 255d) - 128d) / 32d); // CANID 178 // BMW_RollRate // Data2*125/128+Data1/256-125 case "#BMW_RollRate": return(data.data[1] * 125d / 127d + data.data[0] / 255d - 125d); // CANID 178 // BMW_XAxisG // (Data6+Data5/256-128)/32 case "#BMW_XAxisG": return((data.data[5] + (data.data[4] / 255d) - 128d) / 32d); // CANID 17C // BMW_ZAxisG // (Data6+Data5/256-128)/32 case "#BMW_ZAxisG": return((data.data[5] + (data.data[4] / 255d) - 128d) / 32d); // CANID 3FA // BMW_AirTemp // Data1*0.75-50 case "#BMW_AirTemp": return(data.data[0] * 0.75 - 48d); // CANID 3FA // BMW_OilTemp // Data2-25 case "#BMW_OilTemp": return(data.data[1] - 25d); // CANID 2BC // BMW_WaterTemp // Data3*0.76-25 case "#BMW_WaterTemp": return(data.data[2] * 0.76 - 25d); // CANID 2B0 // BMW_DistanceCounterFr // LoData5*253+Data4 case "#BMW_DistCountFr": return((nibble & data.data[4]) * 253d + data.data[3]); // CANID 2B0 // BMW_AccumulatedDistCountFr // 積算計算が後処理で必要になるので、ダミーで0を返すだけとする。 case "#BMW_AccumulatedDistCountFr": return(0); // CANID 2B0 // BMW_DistanceCounterRr // Data3 case "#BMW_DistCountRr": return(data.data[2]); // CANID 2B0 // BMW_DistanceCounterRr // 積算計算が後処理で必要になるので、ダミーで0を返すだけとする。 case "#BMW_AccumulatedDistCountRr": return(0); // CANID 2BC // BMW_FuelCounter // Data4+Data5*256 case "#BMW_FuelCount": return(data.data[4] * 256 + data.data[3]); // CANID 2BC // BMW_FuelCounter // 積算計算が後処理で必要になるので、ダミーで0を返すだけとする。 case "#BMW_AccumulatedFuelCount": return(0); // CANID 2D0 // BMW_FuelLevel // Data2*256+Data1 case "#BMW_FuelLevel": return((data.data[1] * 256d + data.data[0]) / 562d * 100d); // CANID 3F8 // BMW_OdMeter // Data4*65536+Data3*256+Data2 case "#BMW_OdMeter": return(data.data[3] * 65536d + data.data[2] * 256d + data.data[1]); // CANID 2BC // BMW_FuelConsumption // 後処理で必要になるので、ダミーで0を返すだけとする。 case "#BMW_FuelConsumption": return(0); // CANID 2BC // BMW_Range // 後処理で必要になるので、ダミーで0を返すだけとする。 case "#BMW_Range": return(0); // CANID 7FF // GPS Latitude // (Data8*16777216+Data7*65536+Data6*256+Data5-90000000)/1000000 case "#GPS_Latitude": return((data.data[7] * 16777216d + data.data[6] * 65536d + data.data[5] * 256d + data.data[4] - 90000000d) / 1000000d); // CANID 7FF // GPS Longitude // (Data4*16777216+Data3*65536+Data2*256+Data1-180000000)/1000000 case "#GPS_Longitude": return((data.data[3] * 16777216d + data.data[2] * 65536d + data.data[1] * 256d + data.data[0] - 180000000d) / 1000000d); // CANID 7FE // GPS Speed // (Data8*16777216+Data7*65536+Data6*256+Data5)/1000000*3600/1000 // unit of GPS speed is m/sec so *3600/1000 to convert to km/h case "#GPS_Speed": return((data.data[7] * 16777216d + data.data[6] * 65536d + data.data[5] * 256d + data.data[4]) / 1000000d * 3600 / 1000); // CANID 7FE // GPS Altitude // (Data4*16777216+Data3*65536+Data2*256+Data1-1000000000)/1000000 case "#GPS_Altitude": return((data.data[3] * 16777216d + data.data[2] * 65536d + data.data[1] * 256d + data.data[0] - 1000000000d) / 1000000d); // CANID 7FE // GPS Distance // 積分計算が後処理で必要になるので、ダミーで0を返すだけとする。 case "#GPS_Distance": return(0); // CANID any // Data1 case "#Data1": return(data.data[0]); case "#HiData1": return(data.data[0] >> 4); case "#LoData1": return(nibble & data.data[0]); case "#Data2": return(data.data[1]); case "#HiData2": return(data.data[1] >> 4); case "#LoData2": return(nibble & data.data[1]); case "#Data3": return(data.data[2]); case "#HiData3": return(data.data[2] >> 4); case "#LoData3": return(nibble & data.data[2]); case "#Data4": return(data.data[3]); case "#HiData4": return(data.data[3] >> 4); case "#LoData4": return(nibble & data.data[3]); case "#Data5": return(data.data[4]); case "#HiData5": return(data.data[4] >> 4); case "#LoData5": return(nibble & data.data[4]); case "#Data6": return(data.data[5]); case "#HiData6": return(data.data[5] >> 4); case "#LoData6": return(nibble & data.data[5]); case "#Data7": return(data.data[6]); case "#HiData7": return(data.data[6] >> 4); case "#LoData7": return(nibble & data.data[6]); case "#Data8": return(data.data[7]); case "#HiData8": return(data.data[7] >> 4); case "#LoData8": return(nibble & data.data[7]); // 計算定義が間違っていてここまで来た場合は0を返す default: return(0); } }
private void BtnPreAna_Click(object sender, EventArgs e) { if (OpenFileDAT.ShowDialog() != DialogResult.OK) { return; } string FileName = OpenFileDAT.FileName; //ファイルサイズを調べる FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read); long fileSize = fs.Length; //CANDataは1データ16バイトなので、用意する配列は ( ファイルサイズ / 16 - 1) long arySize = fileSize / 16; //CANDataが壊れていると、16で割り切れないかもしれないのでチェックしておき、あまりが出たら読み込む個数を1減らす long checkSize = fileSize % 16; if (checkSize != 0) { arySize--; } //バイナリーリーダー生成 BinaryReader reader = new BinaryReader(fs); //CANデータを1フレーム分読み込む FormMain.CanData tempCanData = new FormMain.CanData(); List <ushort> ListCANID = new List <ushort>(); for (int i = 0; i < arySize; i++) { tempCanData.timeSec = reader.ReadUInt32(); tempCanData.timeMSec = reader.ReadUInt16(); tempCanData.id = reader.ReadUInt16(); tempCanData.data = new byte[8]; for (int j = 0; j < 8; j++) { tempCanData.data[j] = reader.ReadByte(); } //ここで1フレーム分読み込み終了 //CANIDがListに既存でなければ追加する if (ListCANID.IndexOf(tempCanData.id) == -1) { ListCANID.Add(tempCanData.id); } } ListCANID.Sort(); // fileクローズ reader.Close(); // 収集したCANIDの選択ダイアログを表示 FormAnalysys f = new FormAnalysys { ListCANID = ListCANID }; f.ShowDialog(this); f.Dispose(); // このタイミングでDecodeRuleに、FormAnalysysで追加したルールが追加されているので、DecodeRuleを再ロードする LoadDecodeRuleToListView(); }