From 5645ea6e7ee7a19f577f9f0d7dffdc2bdc55e174 Mon Sep 17 00:00:00 2001 From: MrGeorgen Date: Fri, 16 Apr 2021 22:58:04 +0200 Subject: [PATCH] driving cars --- src/main/java/de/mrgeorgen/v2g/car.java | 88 +++++++++++++++---- src/main/java/de/mrgeorgen/v2g/carGrid.java | 10 +-- src/main/java/de/mrgeorgen/v2g/powerGrid.java | 43 +++++---- 3 files changed, 102 insertions(+), 39 deletions(-) diff --git a/src/main/java/de/mrgeorgen/v2g/car.java b/src/main/java/de/mrgeorgen/v2g/car.java index fe2c38d..7942f0f 100644 --- a/src/main/java/de/mrgeorgen/v2g/car.java +++ b/src/main/java/de/mrgeorgen/v2g/car.java @@ -1,31 +1,87 @@ package de.mrgeorgen.v2g; +import java.util.Random; public class car { - private final int id; + private static int idCounter; public final carTemplate carModel; public int battery; private int chargeLock; + private final int drivesToWorkHour; + private final int drivesFromWorkHour; + private final carGrid homeCarGrid; + public carGrid workCarGrid; + private final int driveToWorkPower; + private final int hoursToWork; + private boolean stuck; + private final String carName; + private final int speed; + private final int workDistance; - public car(carTemplate carModel) { // id can be the same for different models + public car(carGrid homeCarGrid, carTemplate carModel) { + this.homeCarGrid = homeCarGrid; this.carModel = carModel; - setChargeLock(0.6); - id = powerGrid.idCounter++; + chargeLock = (int)(carModel.fullBattery * 0.6); + carName = carModel.model + " id. " + idCounter++; battery = carModel.fullBattery / 2; + Random random = new Random(); + drivesToWorkHour = 5 + random.nextInt(4); + drivesFromWorkHour = 14 + random.nextInt(8); + speed = 30 + random.nextInt(100); + workDistance = random.nextInt(100); + hoursToWork = workDistance / speed; + driveToWorkPower = carModel.fullBattery * workDistance / carModel.range / (hoursToWork != 0 ? hoursToWork : 1); } - public int charge(int maxCharge) { - int chargeAmmount = Math.abs(maxCharge) < carModel.chargeSpeed ? maxCharge : maxCharge > 0 ? carModel.chargeSpeed : -1 * carModel.chargeSpeed; - if(battery + chargeAmmount <= chargeLock && chargeAmmount < 0) chargeAmmount = (battery - chargeLock) * -1; // do not charge if the car gets under the charge lock - if(battery + chargeAmmount > carModel.fullBattery) chargeAmmount = carModel.fullBattery - battery; // prevent the battery from overcharging - if(battery + chargeAmmount < 0) chargeAmmount = battery * -1; // prevent the battery from dischargingunder 0% - if(powerGrid.logLevel >= 3 && chargeAmmount != 0) System.out.println(carModel.model + " id. " + id + " is " + (chargeAmmount < 0 ? "dis" : "") + "charging with " + (double)Math.abs(chargeAmmount) / 1000 + " kW. battery: " + (double)battery / 1000 + "/" + (double)carModel.fullBattery / 1000 + " kWh (" + Math.round(getBatteryRelativ() * 100) + "%)"); - battery += chargeAmmount; - if(chargeAmmount < 0) powerGrid.savedEnergie += Math.abs(chargeAmmount); - return chargeAmmount; + public int charge(int maxPower) { + int chargePower = Math.abs(maxPower) < carModel.chargeSpeed ? maxPower : carModel.chargeSpeed * Integer.signum(maxPower); + if(battery + chargePower < chargeLock && chargePower < 0) { + // do not charge if the car gets under the charge lock + if(battery >= chargeLock) chargePower = -(battery - chargeLock); + else chargePower = 0; + } + if(battery + chargePower > carModel.fullBattery) chargePower = carModel.fullBattery - battery; // prevent the battery from overcharging + if(battery + chargePower < 0) chargePower = -battery; // prevent the battery from discharging under 0% + if(powerGrid.logLevel >= 3 && chargePower != 0) System.out.println(carName + " is " + (chargePower < 0 ? "dis" : "") + "charging with " + (double)Math.abs(chargePower) / 1000 + " kW. battery: " + (double)battery / 1000 + "/" + (double)carModel.fullBattery / 1000 + " kWh (" + Math.round(getBatteryRelativ() * 100) + "%)"); + battery += chargePower; + return chargePower; } - private void setChargeLock(double chargeLock) { - chargeLock = (int)(carModel.fullBattery * chargeLock); - } public double getBatteryRelativ() { return (double)battery / carModel.fullBattery; } + public void tickDrive(int hourOfDay) { + if(stuck) return; + int driveStartHour; + carGrid carStartFrom; + carGrid carDrivesTo; + String destination; + if(duringDrive(hourOfDay, drivesToWorkHour)) { + driveStartHour = drivesToWorkHour; + carStartFrom = homeCarGrid; + carDrivesTo = workCarGrid; + destination = "work"; + } + else if(duringDrive(hourOfDay, drivesFromWorkHour)) { + driveStartHour = drivesFromWorkHour; + carStartFrom = workCarGrid; + carDrivesTo = homeCarGrid; + destination = "home"; + } + else return; + if(hourOfDay == driveStartHour) { + carStartFrom.dockedCars.remove(this); + if(hoursToWork != 0) return; + } + battery -= driveToWorkPower; + if(battery < 0) { + stuck = true; + if(powerGrid.logLevel >= 1) System.out.println(carName + " is stuck because of an empty battery during drive to " + destination); + return; + } + if(hourOfDay == driveStartHour + hoursToWork) { + carDrivesTo.dockedCars.add(this); + if(powerGrid.logLevel >= 3) System.out.println(carName + " drove " + workDistance + " km to " + destination + " with " + speed + " km/h"); + } + } + private boolean duringDrive(int hourOfDay, int startHour) { + return hourOfDay >= startHour && hourOfDay <= startHour + hoursToWork; + } } diff --git a/src/main/java/de/mrgeorgen/v2g/carGrid.java b/src/main/java/de/mrgeorgen/v2g/carGrid.java index 7bb7f6d..bbf93d2 100644 --- a/src/main/java/de/mrgeorgen/v2g/carGrid.java +++ b/src/main/java/de/mrgeorgen/v2g/carGrid.java @@ -5,8 +5,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.Random; -import de.mrgeorgen.v2g.car; -import de.mrgeorgen.v2g.carGrid; public class carGrid { private final int id; public ArrayList dockedCars = new ArrayList(); @@ -24,11 +22,11 @@ public class carGrid { for(carTemplate carModel : models) { final int numberOfCars = random.nextInt(10); for(int i = 0; i < numberOfCars; ++i) { - dockedCars.add(new car(carModel)); + dockedCars.add(new car(this, carModel)); } } } - public int chargeCars(int maxCharge) { + public int chargeCars(int maxPower) { Collections.sort(dockedCars, new Comparator() { public int compare(car car1, car car2) { Double car1RelativBattery = car1.getBatteryRelativ(); @@ -36,10 +34,10 @@ public class carGrid { return car1RelativBattery.compareTo(car2RelativBattery); } }); - if(maxCharge < 0) Collections.reverse(dockedCars); + if(maxPower < 0) Collections.reverse(dockedCars); int charged = 0; for(car car : dockedCars) { - charged += car.charge(maxCharge - charged); + charged += car.charge(maxPower - charged); } if(powerGrid.logLevel >= 2 && charged != 0) System.out.println("carGrid " + id + " " + (charged < 0 ? "dis" : "") + "charged " + dockedCars.size() + " cars with " + (double)Math.abs(charged) / 1000 + " kW"); return charged; diff --git a/src/main/java/de/mrgeorgen/v2g/powerGrid.java b/src/main/java/de/mrgeorgen/v2g/powerGrid.java index b3f7b51..b40e2fb 100644 --- a/src/main/java/de/mrgeorgen/v2g/powerGrid.java +++ b/src/main/java/de/mrgeorgen/v2g/powerGrid.java @@ -1,18 +1,16 @@ package de.mrgeorgen.v2g; -import java.util.Random; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.lang.Math; +import java.util.Random; public class powerGrid { - public static int savedEnergie; - public static int idCounter; - public static int logLevel = 1; + public static int logLevel; public static void main(String args[]) { - if(args.length != 1) { - System.out.println("Invalid Syntax. Use the number of days the simulation shell run as the first argument"); + if(args.length != 2) { + System.out.println("Invalid Syntax. Use the number of days the simulation shell run as the first argument and the logLevel as the second. level 1 for only errors. level 2 for information about the carGrid and level 3 for car informations"); return; } + logLevel = Integer.parseInt(args[1]); Random random = new Random(); ArrayList allCars = new ArrayList(); ArrayList carGrids = new ArrayList(); @@ -22,16 +20,22 @@ public class powerGrid { carGrids.add(carGrid); allCars.addAll(carGrid.dockedCars); } + // done after initlising the car because when the car constructor is called not all carGrids are created yet + for(car car : allCars) { + car.workCarGrid = carGrids.get(random.nextInt(carGrids.size())); + } final int hourSimulationRuns = Integer.parseInt(args[0]) * 24; + int savedEnergie = 0; for(int houresPassed = 0; houresPassed < hourSimulationRuns; ++houresPassed) { final int hourOfDay = houresPassed % 24; if(logLevel >= 2) System.out.println("Day " + houresPassed / 24 + " Hour " + hourOfDay); - int averageEnergie; - if(hourOfDay < 6 || hourOfDay > 22) averageEnergie = allCars.size() * 3000; // energie available at night - else if(hourOfDay < 7) averageEnergie = allCars.size() * -1000; // energie for light in the morning - else if(hourOfDay < 19) averageEnergie = allCars.size() * -500; // at the day energie is still needed but not as much because the lights are not on - else /* hourOfDay > 19 && hourOfDay < 23 */ averageEnergie = allCars.size() * -1000; // the lights are on again - int energieAvailable = (int)(averageEnergie * (0.5 + 1.5 * random.nextDouble())); + int averagePower; + if(hourOfDay < 6 || hourOfDay > 22) averagePower = allCars.size() * 4000; // energie available at night + else if(hourOfDay < 7) averagePower = allCars.size() * -1000; // energie for light in the morning + else if(hourOfDay < 19) averagePower = allCars.size() * -500; // at the day energie is still needed but not as much because the lights are not on + else /* hourOfDay > 19 && hourOfDay < 23 */ averagePower = allCars.size() * -1000; // the lights are on again + int powerAvailable = (int)(averagePower * (0.5 + 1.5 * random.nextDouble())); + final int energieBeforeCharging = powerAvailable; Collections.sort(carGrids, new Comparator() { public int compare(carGrid carGrid1, carGrid carGrid2) { Double carGrid1RelativChargeState = carGrid1.relativeChargeState(); @@ -39,13 +43,18 @@ public class powerGrid { return carGrid1RelativChargeState.compareTo(carGrid2RelativBattery); } }); - if(energieAvailable < 0) Collections.reverse(carGrids); + if(powerAvailable < 0) Collections.reverse(carGrids); for(carGrid carGrid : carGrids) { - energieAvailable -= carGrid.chargeCars(energieAvailable); + powerAvailable -= carGrid.chargeCars(powerAvailable); } + final int chargePower = energieBeforeCharging - powerAvailable; + if(chargePower < 0) savedEnergie += Math.abs(chargePower); if(logLevel >= 1) { - if(energieAvailable > 0) System.out.println(energieAvailable + " W could not be used by the cars"); - else if(energieAvailable < 0) System.out.println(Math.abs(energieAvailable) + " W could not be taken from the cars"); + if(powerAvailable > 0) System.out.println(powerAvailable + " W could not be used by the cars"); + else if(powerAvailable < 0) System.out.println(Math.abs(powerAvailable) + " W could not be taken from the cars"); + } + for(car car : allCars) { + car.tickDrive(hourOfDay); } } System.out.println("vehicle to grid saved " + (double)savedEnergie / 1000 + " kWh with " + allCars.size() + " cars and " + carGrids.size() + " carGrids");