private static DataRow GenerateEcologDopplerRow(DataRow newRow, DataRow beforeRow, DataRow tripRow, DataRow correctedGpsRow, InsertDatum datum) { newRow.SetField(EcologDao.ColumnTripId, tripRow.Field <int>(TripsDao.ColumnTripId)); newRow.SetField(EcologDao.ColumnDriverId, tripRow.Field <int>(TripsDao.ColumnDriverId)); newRow.SetField(EcologDao.ColumnCarId, tripRow.Field <int>(TripsDao.ColumnCarId)); newRow.SetField(EcologDao.ColumnSensorId, tripRow.Field <int>(TripsDao.ColumnSensorId)); newRow.SetField(EcologDao.ColumnJst, correctedGpsRow.Field <DateTime>(CorrectedGpsDao.ColumnJst)); newRow.SetField(EcologDao.ColumnLatitude, correctedGpsRow.Field <double>(CorrectedGpsDao.ColumnLatitude)); newRow.SetField(EcologDao.ColumnLongitude, correctedGpsRow.Field <double>(CorrectedGpsDao.ColumnLongitude)); double speed = correctedGpsRow.Field <Single>(CorrectedGpsDao.ColumnSpeed); double speedMeterPerSec = speed / 3.6; //Console.WriteLine("SPEED: " + speed); newRow.SetField(EcologDao.ColumnSpeed, speed); newRow.SetField(EcologDao.ColumnHeading, correctedGpsRow.Field <Single>(CorrectedGpsDao.ColumnHeading)); double distanceDiff = correctedGpsRow.Field <Single>(CorrectedGpsDao.ColumnDistanceDifference); //Console.WriteLine("DISTANCE_DIFF: " + distanceDiff); newRow.SetField(EcologDao.ColumnDistanceDifference, distanceDiff); var meshAndAltitude = AltitudeCalculator.GetInstance().CalcAltitude( correctedGpsRow.Field <double>(CorrectedGpsDao.ColumnLatitude), correctedGpsRow.Field <double>(CorrectedGpsDao.ColumnLongitude)); newRow.SetField(EcologDao.ColumnTerraubAltitude, meshAndAltitude.Item2); newRow.SetField(EcologDao.ColumnMeshId, meshAndAltitude.Item1); double terrainAltitudeDiff = meshAndAltitude.Item2 - beforeRow.Field <Single>(EcologDao.ColumnTerraubAltitude); //Console.WriteLine("ALTITUDE_DIFF: " + terrainAltitudeDiff); newRow.SetField(EcologDao.ColumnTerrainAltitudeDiffarencce, terrainAltitudeDiff); // TODO 加速度を追加する場合はここへ newRow.SetField(EcologDao.ColumnLongitudinalAcc, DBNull.Value); newRow.SetField(EcologDao.ColumnLateralAcc, DBNull.Value); newRow.SetField(EcologDao.ColumnVerticalAcc, DBNull.Value); double airResistancePower = 0; if (speed > 1 && distanceDiff > 0) { airResistancePower = AirResistanceCalculator.CalcPower( Rho, datum.EstimatedCarModel.CdValue, datum.EstimatedCarModel.FrontalProjectedArea, (speed + WindSpeed) / 3.6, speedMeterPerSec); } //Console.WriteLine("AIR: " + airResistancePower); newRow.SetField( EcologDao.ColumnEnergyByAirResistance, airResistancePower); double rollingResistancePower = 0; if (speed > 1 && distanceDiff > 0) { rollingResistancePower = RollingResistanceCalculator.CalcPower( Myu, datum.EstimatedCarModel.Weight, Math.Atan(terrainAltitudeDiff / distanceDiff), speedMeterPerSec); } //Console.WriteLine("ROLLING: " + rollingResistancePower); newRow.SetField( EcologDao.ColumnEnergyByRollingResistance, rollingResistancePower); double climbingResistancePower = 0; if (speed > 1 && distanceDiff > 0) { climbingResistancePower = ClimbingResistanceCalculator.CalcPower( datum.EstimatedCarModel.Weight, Math.Atan(terrainAltitudeDiff / distanceDiff), speedMeterPerSec); } //Console.WriteLine("CLIMBING: " + climbingResistancePower); newRow.SetField( EcologDao.ColumnEnergyByClimbingResistance, climbingResistancePower); double accResistancePower = 0; if (speed > 1 && distanceDiff > 0) { accResistancePower = AccResistanceCalculator.CalcPower( beforeRow.Field <Single>(EcologDao.ColumnSpeed) / 3.6, beforeRow.Field <DateTime>(EcologDao.ColumnJst), speedMeterPerSec, correctedGpsRow.Field <DateTime>(CorrectedGpsDao.ColumnJst), datum.EstimatedCarModel.Weight); } //Console.WriteLine("ACC: " + accResistancePower); newRow.SetField( EcologDao.ColumnEnergyByAccResistance, accResistancePower); double drivingResistancePower = airResistancePower + rollingResistancePower + climbingResistancePower + accResistancePower; double torque = 0; if (drivingResistancePower > 0 && speed > 0) { torque = drivingResistancePower * 1000 * 3600 / speedMeterPerSec * datum.EstimatedCarModel.TireRadius / datum.EstimatedCarModel.ReductionRatio; } int efficiency = EfficiencyCalculator.GetInstance().GetEfficiency(datum.EstimatedCarModel, speedMeterPerSec, torque); //Console.WriteLine("EFFICIENCY: " + efficiency); newRow.SetField(EcologDao.ColumnEfficiency, efficiency); double convertLoss = ConvertLossCaluculator.CalcEnergy( drivingResistancePower, datum.EstimatedCarModel, speedMeterPerSec, efficiency); newRow.SetField(EcologDao.ColumnConvertLoss, convertLoss); //Console.WriteLine("CONVERTLOSS: " + convertLoss); double regeneEnergy = RegeneEnergyCalculator.CalcEnergy(drivingResistancePower, speedMeterPerSec, datum.EstimatedCarModel, efficiency); newRow.SetField(EcologDao.ColumnRegeneEnergy, regeneEnergy); double regeneLoss = RegeneLossCalculator.CalcEnergy(drivingResistancePower, regeneEnergy, datum.EstimatedCarModel, speedMeterPerSec, efficiency); newRow.SetField(EcologDao.ColumnRegeneLoss, regeneLoss); double lostEnergy = LostEnergyCalculator.CalcEnergy(convertLoss, regeneLoss, airResistancePower, rollingResistancePower); newRow.SetField(EcologDao.ColumnLostEnergy, lostEnergy); newRow.SetField(EcologDao.ColumnConsumedElectricEnergy, ConsumedEnergyCaluculator.CalcEnergy(drivingResistancePower, datum.EstimatedCarModel, speedMeterPerSec, efficiency)); newRow.SetField(EcologDao.ColumnLostEnergyByWellToWheel, DBNull.Value); newRow.SetField(EcologDao.ColumnConsumedFuel, DBNull.Value); newRow.SetField(EcologDao.ColumnConsumedFuelByWellToWheel, DBNull.Value); newRow.SetField(EcologDao.ColumnEnergyByEquipment, EquipmentEnergyCalculator.CalcEquipmentEnergy(correctedGpsRow.Field <DateTime>(CorrectedGpsDao.ColumnJst))); newRow.SetField(EcologDao.ColumnEnergyByCooling, DBNull.Value); newRow.SetField(EcologDao.ColumnEnergyByHeating, DBNull.Value); newRow.SetField(EcologDao.ColumnTripDirection, tripRow.Field <string>(TripsDao.ColumnTripDirection)); newRow.SetField(EcologDao.ColumnLinkId, correctedGpsRow.Field <string>(CorrectedGPSDopplerDao.ColumnLinkId)); newRow.SetField(EcologDao.ColumnRoadTheta, correctedGpsRow.Field <Single>(CorrectedGPSDopplerDao.ColumnRoadTheta)); return(newRow); }
public static ECOLOGTuple calculateEcologTuple(GPSTuple previusGPS, GPSTuple currentGPSTuple, DataTable roadLinks, Car car) { // ECOLOGTupleの空のインスタンスを作成 ECOLOGTuple retTuple = new ECOLOGTuple(); // GPSTupleから現在地、GPS時刻、速度を取得。 // 端末時刻は時刻同期がちゃんと取れてる必要があるので、GPS時刻を使うのが無難な気がする。 retTuple.Jst = currentGPSTuple.GpsTime; retTuple.Latitude = currentGPSTuple.Latitude; retTuple.Longitude = currentGPSTuple.Longitude; retTuple.Speed = currentGPSTuple.Speed; // 10mメッシュ標高データから取得する。 // シングルトンクラスのGetInstance()はインスタンスそのものを返すのでnewいらない。 AltitudeCalculator altitudeCalculator = AltitudeCalculator.GetInstance(); Tuple <int, double> meshIdAltitudeTuple = altitudeCalculator.CalcAltitude(currentGPSTuple.Latitude, currentGPSTuple.Longitude); retTuple.TerrainAltitude = meshIdAltitudeTuple.Item2; double previusAltitude = altitudeCalculator.CalcAltitude(previusGPS.Latitude, previusGPS.Longitude).Item2; double altitudeDiff = retTuple.TerrainAltitude - previusAltitude; // distance double distanceDiff = DistanceCalculator.CalcDistance(previusGPS.Latitude, previusGPS.Longitude, currentGPSTuple.Latitude, currentGPSTuple.Longitude); // calculate resistancePower double airResistancePower = 0; double rollingResistancePower = 0; double climbingResistancePower = 0; double accResitancePower = 0; if (currentGPSTuple.Speed > 1 && distanceDiff > 0) { airResistancePower = AirResistanceCalculator.CalcPower(Rho, car.CdValue, car.FrontalProjectedArea, (currentGPSTuple.Speed + WindSpeed) / 3.6, currentGPSTuple.Speed / 3.6); rollingResistancePower = RollingResistanceCalculator.CalcPower(Myu, car.Weight, Math.Atan(altitudeDiff / distanceDiff), // TODO: 前のタプルとの標高差と距離が角度求めるには必要。 currentGPSTuple.Speed / 3.6); climbingResistancePower = ClimbingResistanceCalculator.CalcPower(car.Weight, Math.Atan(altitudeDiff / distanceDiff), // TODO: rollingResistancePowerと同様 currentGPSTuple.Speed / 3.6); accResitancePower = AccResistanceCalculator.CalcPower(previusGPS.Speed / 3.6, previusGPS.GpsTime, currentGPSTuple.Speed / 3.6, currentGPSTuple.GpsTime, car.Weight); } double drivingResistancePower = airResistancePower + rollingResistancePower + climbingResistancePower + accResitancePower; // torque double torque = 0; if (drivingResistancePower > 0 && currentGPSTuple.Speed > 0) { torque = drivingResistancePower * 1000 * 3600 / (currentGPSTuple.Speed / 3.6) * car.TireRadius / car.ReductionRatio; } // Efficiency int efficiency = EfficiencyCalculator.GetInstance().GetEfficiency(car, currentGPSTuple.Speed / 3.6, torque); // 各種損失はSensorLogInserterReの計算メソッドを用いて算出する double convertLoss = ConvertLossCaluculator.CalcEnergy(drivingResistancePower, car, currentGPSTuple.Speed / 3.6, efficiency); double regeneEnergy = RegeneEnergyCalculator.CalcEnergy(drivingResistancePower, currentGPSTuple.Speed / 3.6, car, efficiency); double regeneLoss = RegeneLossCalculator.CalcEnergy(drivingResistancePower, regeneEnergy, car, currentGPSTuple.Speed / 3.6, efficiency); double lostEnergy = LostEnergyCalculator.CalcEnergy(convertLoss, regeneLoss, airResistancePower, rollingResistancePower); // link and semantic_link // 近傍リンクをSQLで指定、すべてのリンクに対して、GPS点とリンクの距離を求める // 最近傍リンクまでの距離が閾値を超えない場合には、それをGPS点が通過するリンクとする return(retTuple); }