From dfe1caae5b27fc07e8d9f59a2abc61e621e7e6fc Mon Sep 17 00:00:00 2001
From: Luc-Sol
Date: Fri, 20 Mar 2026 12:04:30 +0100
Subject: [PATCH] GC Now resets all its classes itself and cleanup of
triptracker
- EnergyModel no longer stores/reset/restores states of J_EAs and ActivityTrackers, these are now called through the GCs store/reset/restore state functions.
- Removed the v_ from variable names in the TripTracker/CookingTracker.
- Added some descriptions to the methods of the TripTracker
- Removed old code/comments from TripTracker
- Fixed indentation in the TripTracker
---
_alp/Agents/EnergyModel/Code/Functions.java | 47 +--
.../Agents/GridConnection/Code/Functions.java | 32 +-
_alp/Agents/GridConnection/Code/Functions.xml | 5 +
_alp/Classes/Class.J_ActivityTracker.java | 10 +-
.../Class.J_ActivityTrackerCooking.java | 72 ++---
.../Classes/Class.J_ActivityTrackerTrips.java | 276 +++++++++---------
6 files changed, 206 insertions(+), 236 deletions(-)
diff --git a/_alp/Agents/EnergyModel/Code/Functions.java b/_alp/Agents/EnergyModel/Code/Functions.java
index 8b4701d..12d879b 100644
--- a/_alp/Agents/EnergyModel/Code/Functions.java
+++ b/_alp/Agents/EnergyModel/Code/Functions.java
@@ -237,11 +237,6 @@
p_timeVariables.updateTimeVariables(v_timeStepsElapsed, p_timeParameters);
//// Store and reset model states
-for (J_EA EA : c_energyAssets) {
- EA.storeStatesAndReset();
-}
-
-
for (GridConnection GC : c_gridConnections) {
if (GC.v_rapidRunData != null) {
@@ -255,21 +250,12 @@
GC.v_rapidRunData.connectionMetaData = GC.v_liveConnectionMetaData.getClone();
GC.v_rapidRunData.initializeAccumulators(GC.v_liveData.activeEnergyCarriers, GC.v_liveData.activeConsumptionEnergyCarriers, GC.v_liveData.activeProductionEnergyCarriers, GC.v_liveAssetsMetaData.activeAssetFlows); //f_initializeAccumulators();
- GC.f_resetStates();
+ // f_resetStates resets the accumulators in rapidrundata, so must be after copying the previous run data
+ GC.f_resetStates(p_timeVariables);
- GC.c_tripTrackers.forEach(tt->{
- tt.storeStatesAndReset();
- tt.setStartIndex(p_timeVariables, GC.f_getChargePoint());
- //tt.prepareNextActivity(p_runStartTime_h*60, GC.f_getChargePoint());
- });
- if (GC instanceof GCHouse) {
- if (((GCHouse)GC).p_cookingTracker != null) {
- ((GCHouse)GC).p_cookingTracker.storeStatesAndReset();
- }
- }
}
for (GridConnection GC : c_subGridConnections) {
- GC.f_resetStates();
+ GC.f_resetStates(p_timeVariables);
}
for (GridNode GN : pop_gridNodes) {
@@ -285,19 +271,11 @@
if (b_storePreviousRapidRunData) {
EC.v_previousRunData = EC.v_rapidRunData;
}
- /*EC.v_rapidRunData.assetsMetaData = EC.v_liveAssetsMetaData.getClone();
- EC.v_rapidRunData.connectionMetaData = EC.v_liveConnectionMetaData.getClone();
- if(EC.v_rapidRunData.getStoreTotalAssetFlows() == false){
- EC.v_rapidRunData.setStoreTotalAssetFlows(true);
- EC.v_rapidRunData.initializeAccumulators(p_runEndTime_h - p_runStartTime_h, p_timeStep_h, EC.v_liveData.activeEnergyCarriers, EC.v_liveData.activeConsumptionEnergyCarriers, EC.v_liveData.activeProductionEnergyCarriers, EC.v_liveAssetsMetaData.activeAssetFlows);
- }*/
}
EC.v_rapidRunData = new J_RapidRunData(p_timeParameters, true);
EC.v_rapidRunData.assetsMetaData = EC.v_liveAssetsMetaData.getClone();
EC.v_rapidRunData.connectionMetaData = EC.v_liveConnectionMetaData.getClone();
- //if(EC.v_rapidRunData.getStoreTotalAssetFlows() == false){
EC.v_rapidRunData.setStoreTotalAssetFlows(true);
- //}
EC.v_rapidRunData.initializeAccumulators(EC.v_liveData.activeEnergyCarriers, EC.v_liveData.activeConsumptionEnergyCarriers, EC.v_liveData.activeProductionEnergyCarriers, EC.v_liveAssetsMetaData.activeAssetFlows);
EC.f_resetStates();
@@ -379,27 +357,8 @@
v_timeStepsElapsed = v_timeStepsElapsed_live;
p_timeVariables.updateTimeVariables(v_timeStepsElapsed, p_timeParameters);
-
-for (J_EA EA : c_energyAssets) {
- EA.restoreStates();
-}
-
-/*for (GridNode GN : pop_gridNodes) {
- //Has no reset states
-}*/
-
for (GridConnection GC : c_gridConnections) {
GC.f_resetStatesAfterRapidRun();
- GC.c_tripTrackers.forEach(tt->{
- tt.restoreStates();
- //tt.prepareNextActivity((t_h-p_runStartTime_h)*60, GC.f_getChargePoint());
- });
- //GC.c_tripTrackers.forEach(tt->tt.prepareNextActivity((t_h-p_runStartTime_h)*60));
- if (GC instanceof GCHouse) {
- if (((GCHouse)GC).p_cookingTracker != null) {
- ((GCHouse)GC).p_cookingTracker.restoreStates();
- }
- }
}
v_isRapidRun = false;
diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java
index 20dfc03..bd39480 100644
--- a/_alp/Agents/GridConnection/Code/Functions.java
+++ b/_alp/Agents/GridConnection/Code/Functions.java
@@ -123,34 +123,43 @@
/*ALCODEEND*/}
-double f_resetStates()
+double f_resetStates(J_TimeVariables timeVariables)
{/*ALCODESTART::1668983912731*/
fm_currentProductionFlows_kW.clear();
fm_currentConsumptionFlows_kW.clear();
fm_currentBalanceFlows_kW.clear();
fm_heatFromEnergyCarrier_kW.clear();
fm_consumptionForHeating_kW.clear();
-//fm_currentAssetFlows_kW.clear(); // Why not this one??
+//fm_currentAssetFlows_kW.clear(); // Why not this one?? (I'd have to check, but all these fm's are reset at calculateEnergyBalance, so they possibly could all be removed, ~Luc 20/03/26)
v_previousPowerElectricity_kW = 0;
v_previousPowerHeat_kW = 0;
-//v_electricityPriceLowPassed_eurpkWh = 0;
-//v_currentElectricityPriceConsumption_eurpkWh = 0;
v_rapidRunData.resetAccumulators(v_liveData.activeEnergyCarriers, v_liveData.activeConsumptionEnergyCarriers, v_liveData.activeProductionEnergyCarriers); //f_initializeAccumulators();
//Reset specific variables/collections in specific GC types (GCProduction, GConversion, etc.)
f_resetSpecificGCStates();
-//Store states and reset EMS
+// Reset other classes
if(p_energyManagement != null){
p_energyManagement.storeStatesAndReset();
}
-//Store states and reset charge point
if(p_chargePoint != null){
p_chargePoint.storeStatesAndReset();
}
+
+c_energyAssets.forEach(ea -> ea.storeStatesAndReset());
+
+c_tripTrackers.forEach(tt -> {
+ tt.storeStatesAndReset();
+ tt.setStartIndex(timeVariables, f_getChargePoint());
+ }
+);
+
+if (p_cookingTracker != null) {
+ p_cookingTracker.storeStatesAndReset();
+}
/*ALCODEEND*/}
double f_setOperatingSwitches()
@@ -321,7 +330,7 @@ else if(j_ea instanceof J_EAFlex j_eaFlex){
double f_resetSpecificGCStates()
{/*ALCODESTART::1717060111619*/
-
+// to be overwritten by child GCs!
/*ALCODEEND*/}
double f_resetStatesAfterRapidRun()
@@ -329,17 +338,22 @@ else if(j_ea instanceof J_EAFlex j_eaFlex){
//Reset specificGC states after rapid run
f_resetSpecificGCStatesAfterRapidRun();
-//Restore states in EMS
+//Restore other classes
if(p_energyManagement != null){
p_energyManagement.restoreStates();
}
-//Restore states in charge point
if(p_chargePoint != null){
p_chargePoint.restoreStates();
}
+c_energyAssets.forEach(ea -> ea.restoreStates());
+c_tripTrackers.forEach(tt-> tt.restoreStates());
+
+if (p_cookingTracker != null) {
+ p_cookingTracker.restoreStates();
+}
/*ALCODEEND*/}
double f_resetSpecificGCStatesAfterRapidRun()
diff --git a/_alp/Agents/GridConnection/Code/Functions.xml b/_alp/Agents/GridConnection/Code/Functions.xml
index 4c6b2d3..d0c4b7f 100644
--- a/_alp/Agents/GridConnection/Code/Functions.xml
+++ b/_alp/Agents/GridConnection/Code/Functions.xml
@@ -118,6 +118,10 @@
false
true
true
+
+
+
+
@@ -238,6 +242,7 @@
false
true
true
+
VOID
diff --git a/_alp/Classes/Class.J_ActivityTracker.java b/_alp/Classes/Class.J_ActivityTracker.java
index 9afbc06..6e24db7 100644
--- a/_alp/Classes/Class.J_ActivityTracker.java
+++ b/_alp/Classes/Class.J_ActivityTracker.java
@@ -24,8 +24,8 @@ public abstract class J_ActivityTracker implements I_StoreStatesAndReset {
protected ArrayList endtimes_min = new ArrayList<>();
//private ArrayList eventMagnitude = new ArrayList<>();
public int nbActivities = 0;
- public int v_eventIndex = 0;
- protected int v_eventIndexStored =0;
+ public int eventIndex = 0;
+ protected int eventIndexStored =0;
/**
* Default constructor
@@ -37,12 +37,12 @@ public J_ActivityTracker(EnergyModel main, int rowIndex, double time_min) {
}
public void storeStatesAndReset() {
- v_eventIndexStored = v_eventIndex;
- v_eventIndex = 0;
+ eventIndexStored = eventIndex;
+ eventIndex = 0;
}
public void restoreStates() {
- v_eventIndex = v_eventIndexStored;
+ eventIndex = eventIndexStored;
}
diff --git a/_alp/Classes/Class.J_ActivityTrackerCooking.java b/_alp/Classes/Class.J_ActivityTrackerCooking.java
index 5def17b..d91c686 100644
--- a/_alp/Classes/Class.J_ActivityTrackerCooking.java
+++ b/_alp/Classes/Class.J_ActivityTrackerCooking.java
@@ -54,12 +54,12 @@ public J_ActivityTrackerCooking(TextFile inputCookingActivities, int rowIndex, d
powerFractions_fr.add(ratio);
}
- while ( starttimes_min.get(v_eventIndex) - time_min < 0) {
- starttimes_min.set( v_eventIndex, starttimes_min.get(v_eventIndex) + 1440 ); // Source data is always just one day, repeating every day.
- endtimes_min.set( v_eventIndex, endtimes_min.get(v_eventIndex) + 1440 ); // Source data is always just one day, repeating every day.
- v_eventIndex++;
- if ( v_eventIndex > starttimes_min.size() - 1 ) {
- v_eventIndex = 0;
+ while ( starttimes_min.get(eventIndex) - time_min < 0) {
+ starttimes_min.set( eventIndex, starttimes_min.get(eventIndex) + 1440 ); // Source data is always just one day, repeating every day.
+ endtimes_min.set( eventIndex, endtimes_min.get(eventIndex) + 1440 ); // Source data is always just one day, repeating every day.
+ eventIndex++;
+ if ( eventIndex > starttimes_min.size() - 1 ) {
+ eventIndex = 0;
}
}
@@ -73,62 +73,62 @@ public J_ActivityTrackerCooking(TextFile inputCookingActivities, int rowIndex, d
public void manageActivities(J_TimeVariables timeVariables) {
double time_min = timeVariables.getAnyLogicTime_h() * 60;
//traceln("Cooking tracker current time: " + time_min);
- //traceln("Event index: " + v_eventIndex);
+ //traceln("Event index: " + eventIndex);
//traceln("startTimes: " + starttimes_min);
//traceln("endTimes: " + endtimes_min);
//traceln("powerFractions_fr: " + powerFractions_fr);
if (cooking) {
- if (time_min >= endtimes_min.get(v_eventIndex) ) { // end cooking session. Also check if a new one starts in this timestep!
+ if (time_min >= endtimes_min.get(eventIndex) ) { // end cooking session. Also check if a new one starts in this timestep!
//main.v_activeCookingSessions.decrementAndGet();
//traceln("End of cooking session, currently active cooking sessions %s", main.v_activeCookingSessions);
// factor to compensate for the fact that you might not be cooking for the entire timestep.
- double fr = (time_min - this.endtimes_min.get(this.v_eventIndex)) / this.timeStep_min;
- this.powerFraction_fr = fr * this.powerFractions_fr.get(this.v_eventIndex);
+ double fr = (time_min - this.endtimes_min.get(this.eventIndex)) / this.timeStep_min;
+ this.powerFraction_fr = fr * this.powerFractions_fr.get(this.eventIndex);
- starttimes_min.set( v_eventIndex, starttimes_min.get(v_eventIndex) + 1440 );
- endtimes_min.set( v_eventIndex, endtimes_min.get(v_eventIndex) + 1440 );
- v_eventIndex++;
- if ( v_eventIndex >= starttimes_min.size() ) {
- v_eventIndex = 0;
+ starttimes_min.set( eventIndex, starttimes_min.get(eventIndex) + 1440 );
+ endtimes_min.set( eventIndex, endtimes_min.get(eventIndex) + 1440 );
+ eventIndex++;
+ if ( eventIndex >= starttimes_min.size() ) {
+ eventIndex = 0;
}
cooking=false;
- if (time_min >= starttimes_min.get(v_eventIndex)) {
+ if (time_min >= starttimes_min.get(eventIndex)) {
// factor to compensate for the fact that you might not be cooking for the entire timestep.
- fr = (time_min - this.starttimes_min.get(this.v_eventIndex)) / this.timeStep_min;
- this.powerFraction_fr = fr * this.powerFractions_fr.get(this.v_eventIndex);
+ fr = (time_min - this.starttimes_min.get(this.eventIndex)) / this.timeStep_min;
+ this.powerFraction_fr = fr * this.powerFractions_fr.get(this.eventIndex);
//main.v_activeCookingSessions.incrementAndGet();
cooking=true;
- traceln("Starting next cooking session in same timestep as previous session ended!! Rowindex %s, eventIndex %s\", rowIndex, v_eventIndex");
+ traceln("Starting next cooking session in same timestep as previous session ended!! Rowindex %s, eventIndex %s\", rowIndex, eventIndex");
}
}
else {
- this.powerFraction_fr = this.starttimes_min.get(this.v_eventIndex);
+ this.powerFraction_fr = this.starttimes_min.get(this.eventIndex);
}
- } else if (time_min >= starttimes_min.get(v_eventIndex) ) { // start cooking session. Also check if it ends within this timestep!
- /*if (endtimes_min.get(v_eventIndex) - starttimes_min.get(v_eventIndex) > 100) {
- traceln("Cooking event longer than 100 minutes!! Rowindex %s, eventIndex %s.", rowIndex, v_eventIndex);
+ } else if (time_min >= starttimes_min.get(eventIndex) ) { // start cooking session. Also check if it ends within this timestep!
+ /*if (endtimes_min.get(eventIndex) - starttimes_min.get(eventIndex) > 100) {
+ traceln("Cooking event longer than 100 minutes!! Rowindex %s, eventIndex %s.", rowIndex, eventIndex);
}*/
// factor to compensate for the fact that you might not be cooking for the entire timestep.
- double fr = (time_min - this.starttimes_min.get(this.v_eventIndex)) / this.timeStep_min;
- this.powerFraction_fr = fr * this.powerFractions_fr.get(this.v_eventIndex);
+ double fr = (time_min - this.starttimes_min.get(this.eventIndex)) / this.timeStep_min;
+ this.powerFraction_fr = fr * this.powerFractions_fr.get(this.eventIndex);
//main.v_activeCookingSessions.incrementAndGet();
cooking=true;
- if (time_min >= endtimes_min.get(v_eventIndex) ) { // end cooking session in the same timestep? Still need to fix energy use for this case!!
+ if (time_min >= endtimes_min.get(eventIndex) ) { // end cooking session in the same timestep? Still need to fix energy use for this case!!
//main.v_activeCookingSessions.decrementAndGet();
//traceln("End of cooking session, currently active cooking sessions %s", main.v_activeCookingSessions);
- fr = (this.endtimes_min.get(this.v_eventIndex) - this.starttimes_min.get(this.v_eventIndex)) / this.timeStep_min;
- this.powerFraction_fr = fr * this.powerFractions_fr.get(this.v_eventIndex);
+ fr = (this.endtimes_min.get(this.eventIndex) - this.starttimes_min.get(this.eventIndex)) / this.timeStep_min;
+ this.powerFraction_fr = fr * this.powerFractions_fr.get(this.eventIndex);
- starttimes_min.set( v_eventIndex, starttimes_min.get(v_eventIndex) + 1440 );
- endtimes_min.set( v_eventIndex, endtimes_min.get(v_eventIndex) + 1440 );
- v_eventIndex++;
- if ( v_eventIndex >= starttimes_min.size() ) {
- v_eventIndex = 0;
+ starttimes_min.set( eventIndex, starttimes_min.get(eventIndex) + 1440 );
+ endtimes_min.set( eventIndex, endtimes_min.get(eventIndex) + 1440 );
+ eventIndex++;
+ if ( eventIndex >= starttimes_min.size() ) {
+ eventIndex = 0;
}
cooking=false;
}
@@ -142,17 +142,17 @@ public void manageActivities(J_TimeVariables timeVariables) {
@Override
public void storeStatesAndReset() {
- v_eventIndexStored = v_eventIndex;
+ eventIndexStored = eventIndex;
storedStarttimes_min = new ArrayList<>(starttimes_min);
storedEndtimes_min = new ArrayList<>(endtimes_min);
starttimes_min = new ArrayList<>(initalStarttimes_min);
endtimes_min = new ArrayList<>(initalEndtimes_min);
- v_eventIndex = 0;
+ eventIndex = 0;
}
@Override
public void restoreStates() {
- v_eventIndex = v_eventIndexStored;
+ eventIndex = eventIndexStored;
starttimes_min = new ArrayList<>(storedStarttimes_min);
endtimes_min = new ArrayList<>(storedEndtimes_min);
}
diff --git a/_alp/Classes/Class.J_ActivityTrackerTrips.java b/_alp/Classes/Class.J_ActivityTrackerTrips.java
index 13d2d68..359ba8f 100644
--- a/_alp/Classes/Class.J_ActivityTrackerTrips.java
+++ b/_alp/Classes/Class.J_ActivityTrackerTrips.java
@@ -12,16 +12,13 @@ public class J_ActivityTrackerTrips extends J_ActivityTracker {
public ArrayList distances_km = new ArrayList<>();
private int rowIndex;
public I_Vehicle vehicle;
- public double v_idleTimeToNextTrip_min;
- public double v_idleTimeToNextTripStored_min;
- public double v_tripDist_km;
- //public double v_energyNeedForNextTrip_kWh;
- //public double v_energyNeedForNextTripStored_kWh;
- public double v_nextEventStartTime_min;
+ public double idleTimeToNextTrip_min;
+ public double idleTimeToNextTripStored_min;
+ public double tripDistance_km;
+ public double nextEventStartTime_min;
public double distanceScaling_fr = 1.0;
public double currentTripTimesteps_n;
private double nextEventStartTime_h;
- //public String tripPatternIdentifier;
/**
* Default constructor
@@ -36,7 +33,6 @@ public J_ActivityTrackerTrips(J_TimeParameters timeParameters, TextFile tripsCsv
tripsCsv.close();
tripsCsv.canReadMore();
-
tripsCsv.readLine(); // Skips first line
while (roundToInt(tripsCsv.readDouble())!=rowIndex && tripsCsv.canReadMore()) { // Skip until rowIndex found
@@ -54,19 +50,19 @@ public J_ActivityTrackerTrips(J_TimeParameters timeParameters, TextFile tripsCsv
distances_km.add(tripsCsv.readDouble());
}
- // 'forward' to next current activity
+ // 'forward' to next activity
setStartIndex(timeVariables, chargePointRegistration);
}
private double getTimeSinceWeekStart(double time_min) {
- double timeSinceWeekStart_min = (time_min + (timeParameters.getDayOfWeek1jan()-1) * 24 * 60) % (7*24*60); // Trip start/end-times are all defined as minutes since monday 00:00h
+ double timeSinceWeekStart_min = (time_min + (timeParameters.getDayOfWeek1jan()-1) * 24 * 60) % (7*24*60);
return timeSinceWeekStart_min;
}
private void setNextTrip() {
- v_eventIndex++;
- if ( v_eventIndex > starttimes_min.size() - 1 ) {
- v_eventIndex = 0;
+ eventIndex++;
+ if ( eventIndex > starttimes_min.size() - 1 ) {
+ eventIndex = 0;
}
}
@@ -87,10 +83,8 @@ public void setAnnualDistance_km(double desiredAnnualDistance_km) { // Scale tri
double currentAnnualDistance_km = getAnnualDistance_km();
double scalingFactor_f = desiredAnnualDistance_km / currentAnnualDistance_km;
- //distances_km = (ArrayList)distances_km.stream().map(a -> scalingFactor_f*a).toList();
ListIterator iterator = distances_km.listIterator();
for (int i = 0; i= starttimes_min.get(v_eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < starttimes_min.get(v_eventIndex)) { // is a trip starting this timestep?
- //currentTripDuration = roundToInt(endtimes_min.get(v_eventIndex) - starttimes_min.get(v_eventIndex) / (energyModel.p_timeStep_h * 60));
- currentTripTimesteps_n = max(1,roundToInt(((endtimes_min.get(v_eventIndex) - starttimes_min.get(v_eventIndex)) / (timeParameters.getTimeStep_h() * 60))));
-
- vehicle.startTrip(timeVariables);
- if(vehicle instanceof J_EAEV EV) {
- chargePointRegistration.deregisterChargingRequest(EV);
- }
- //if (time_min == roundToInt(endtimes_min.get(v_eventIndex) / (60*energyModel.p_timeStep_h)) * (energyModel.p_timeStep_h*60) ) { // is the trip also ending this timestep?
- if (timeSinceWeekStart_min >= endtimes_min.get(v_eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < endtimes_min.get(v_eventIndex)) { // is the trip also ending this timestep?
- vehicle.endTrip(v_tripDist_km);
- setNextTrip();//v_eventIndex++;
- prepareNextActivity(time_min, chargePointRegistration);
- }
- }
- } else {
- if (vehicle instanceof J_EAFuelVehicle fuelVehicle) {
- fuelVehicle.progressTrip(v_tripDist_km / currentTripTimesteps_n);
- }
- //if (time_min == roundToInt(endtimes_min.get(v_eventIndex)/ (60*energyModel.p_timeStep_h)) * 60*energyModel.p_timeStep_h ) { // is a trip ending this timestep?
- if (timeSinceWeekStart_min >= endtimes_min.get(v_eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < endtimes_min.get(v_eventIndex)) { // is a trip ending this timestep?
- vehicle.endTrip(v_tripDist_km);
- setNextTrip();//v_eventIndex++;
- prepareNextActivity(time_min, chargePointRegistration);
- //if (time_min == roundToInt(starttimes_min.get(v_eventIndex) / (60*energyModel.p_timeStep_h)) * (energyModel.p_timeStep_h*60) ) { // is the next trip also starting this timestep?
- if (timeSinceWeekStart_min >= starttimes_min.get(v_eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < starttimes_min.get(v_eventIndex) ) { // is the next trip also starting this timestep?
- currentTripTimesteps_n = max(1,roundToInt(((endtimes_min.get(v_eventIndex) - starttimes_min.get(v_eventIndex)) / (timeParameters.getTimeStep_h() * 60))));
- vehicle.startTrip(timeVariables);
- if(vehicle instanceof J_EAEV EV) {
- chargePointRegistration.deregisterChargingRequest(EV);
- }
- }
- }
- }
- }
+ double time_min = timeVariables.getT_h() * 60;
+ double timeSinceWeekStart_min = getTimeSinceWeekStart(time_min); // Trip start/end-times are all defined as minutes since monday 00:00h, trips are looped indefinitely
+ if (vehicle.getAvailability()) { // at start of timestep! check for multiple 'events' in timestep!
+ if ( timeSinceWeekStart_min >= starttimes_min.get(eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < starttimes_min.get(eventIndex)) { // is a trip starting this timestep?
+ currentTripTimesteps_n = max(1,roundToInt(((endtimes_min.get(eventIndex) - starttimes_min.get(eventIndex)) / (timeParameters.getTimeStep_h() * 60))));
+
+ vehicle.startTrip(timeVariables);
+ if(vehicle instanceof J_EAEV EV) {
+ chargePointRegistration.deregisterChargingRequest(EV);
+ }
+ if (timeSinceWeekStart_min >= endtimes_min.get(eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < endtimes_min.get(eventIndex)) { // is the trip also ending this timestep?
+ vehicle.endTrip(tripDistance_km);
+ setNextTrip();
+ prepareNextActivity(time_min, chargePointRegistration);
+ }
+ }
+ } else {
+ if (vehicle instanceof J_EAFuelVehicle fuelVehicle) {
+ fuelVehicle.progressTrip(tripDistance_km / currentTripTimesteps_n);
+ }
+ if (timeSinceWeekStart_min >= endtimes_min.get(eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < endtimes_min.get(eventIndex)) { // is a trip ending this timestep?
+ vehicle.endTrip(tripDistance_km);
+ setNextTrip();
+ prepareNextActivity(time_min, chargePointRegistration);
+ if (timeSinceWeekStart_min >= starttimes_min.get(eventIndex) && (timeSinceWeekStart_min-timeParameters.getTimeStep_h() * 60) < starttimes_min.get(eventIndex) ) { // is the next trip also starting this timestep?
+ currentTripTimesteps_n = max(1,roundToInt(((endtimes_min.get(eventIndex) - starttimes_min.get(eventIndex)) / (timeParameters.getTimeStep_h() * 60))));
+ vehicle.startTrip(timeVariables);
+ if(vehicle instanceof J_EAEV EV) {
+ chargePointRegistration.deregisterChargingRequest(EV);
+ }
+ }
+ }
+ }
+ }
- public void setStartIndex(J_TimeVariables timeVariables, I_ChargePointRegistration chargePointRegistration) {
- // 'forward' to current activity if tripTracker is instantiated not at the start of the simulation or year
- double time_min = timeVariables.getT_h() * 60.0;
-
- double timeSinceWeekStart_min = getTimeSinceWeekStart(time_min);
- boolean looped = false;
- while ( starttimes_min.get(v_eventIndex) < (timeSinceWeekStart_min ) ) { // If this occurs 'during' a trip, that trip is ignored, it is not executed.
- setNextTrip(); // Skip to the next trip.
-
- if (v_eventIndex == starttimes_min.size()-1 ) {
- if (looped) { // break while loop!
- setNextTrip(); // Reverts to first trip of week
- break;
- } else {
- looped = true;
- }
- }
-
- }
- prepareNextActivity(time_min, chargePointRegistration);
- }
-
- public void prepareNextActivity(double time_min, I_ChargePointRegistration chargePointRegistration) {
- /*if ( v_eventIndex >= starttimes_min.size() ) { // This should only happen at the end of the year, not every week.
- v_eventIndex = 0;
- }*/
- double timeSinceWeekStart_min = getTimeSinceWeekStart(time_min);
- v_nextEventStartTime_min = starttimes_min.get(v_eventIndex); // minutes from start of week
-
- if (v_eventIndex == 0 && timeSinceWeekStart_min > v_nextEventStartTime_min) { // Next week's trip!
- nextEventStartTime_h = (v_nextEventStartTime_min + time_min - timeSinceWeekStart_min)/60 + 168;
- } else {
- nextEventStartTime_h = (v_nextEventStartTime_min + time_min - timeSinceWeekStart_min)/60;
- }
- //traceln("Prepare next activity, trip startTime: %s hours. Time since week start: %s", nextEventStartTime_h, (timeSinceWeekStart_min)/60);
- v_idleTimeToNextTrip_min = (v_nextEventStartTime_min - timeSinceWeekStart_min) % (24*7*60); // Modulo 24*7*60 needed because otherwise negative values can occur when trip starts 'next week'.
- v_tripDist_km = distanceScaling_fr * distances_km.get( v_eventIndex ); // Update upcoming trip distance
-
- if (vehicle instanceof J_EAEV ev) {
-
- double energyNeedForNextTrip_kWh = ev.getEnergyConsumption_kWhpkm() * v_tripDist_km;
- if (v_idleTimeToNextTrip_min > 0 && (energyNeedForNextTrip_kWh-ev.getCurrentSOC_kWh())> v_idleTimeToNextTrip_min/60 * ev.capacityElectric_kW) {
- traceln("TripTracker reports: charging need for next trip is not feasible! Time till next trip: %s hours, chargeNeed_kWh: %s", roundToDecimal(v_idleTimeToNextTrip_min/60,2), roundToDecimal(energyNeedForNextTrip_kWh-ev.getCurrentSOC_kWh(),2));
- }
- //v_energyNeedForNextTrip_kWh = min(v_energyNeedForNextTrip_kWh+10,ev.getStorageCapacity_kWh()); // added 10kWh margin 'just in case'. This is actually realistic; people will charge their cars a bit more than strictly needed for the next trip, if possible.
- // Check if more charging is needed for next trip!
- double nextTripDist_km = 0;
- double nextTripStartTime_min = 0;
-
- if ( v_eventIndex == starttimes_min.size() - 1 ) {
- nextTripDist_km = 0;//distances_km.get( 0 );
- nextTripStartTime_min = endtimes_min.get(v_eventIndex);
- } else {
- nextTripDist_km = distanceScaling_fr*distances_km.get( v_eventIndex+1 );
- nextTripStartTime_min = starttimes_min.get( v_eventIndex+1 );
- }
- double additionalChargingNeededForNextTrip_kWh = max(0,nextTripDist_km * ev.getEnergyConsumption_kWhpkm() - (nextTripStartTime_min - endtimes_min.get(v_eventIndex))/60*ev.getVehicleChargingCapacity_kW());
- /*if (additionalChargingNeededForNextTrip_kWh>0) {
- traceln("*******Additional charging required to prepare for trip after next trip!*********");
- }*/
- energyNeedForNextTrip_kWh += additionalChargingNeededForNextTrip_kWh;
- energyNeedForNextTrip_kWh = min(energyNeedForNextTrip_kWh+10,ev.getStorageCapacity_kWh());
- //traceln("TripTracker, energyNeedForNextTrip: %s", v_energyNeedForNextTrip_kWh);
- ev.setEnergyNeedForNextTrip_kWh(energyNeedForNextTrip_kWh);
- /*if ( (v_energyNeedForNextTrip_kWh - EV.getCurrentStateOfCharge() * EV.getStorageCapacity_kWh()) / (v_idleTimeToNextTrip_min/60) > EV.capacityElectric_kW ) {
- traceln("Infeasible trip pattern for EV, not enough time to charge for next trip! Required charging power is: " + (v_energyNeedForNextTrip_kWh - EV.getCurrentStateOfCharge() * EV.getStorageCapacity_kWh()) / (v_idleTimeToNextTrip_min/60) + " kW");
- traceln("RowIndex: " + rowIndex + " tripDistance: " + v_tripDist_km + " km, time to next trip: " + v_idleTimeToNextTrip_min + " minutes");
+ /*
+ * This method 'Forwards' to the activity at time in timeVariables
+ * It also immediately calls prepareNextActivity
+ */
+ public void setStartIndex(J_TimeVariables timeVariables, I_ChargePointRegistration chargePointRegistration) {
+ double time_min = timeVariables.getT_h() * 60.0;
+ double timeSinceWeekStart_min = getTimeSinceWeekStart(time_min);
+ boolean looped = false;
+ while ( starttimes_min.get(eventIndex) < (timeSinceWeekStart_min ) ) { // If this occurs 'during' a trip, that trip is ignored, it is not executed.
+ setNextTrip(); // Skip to the next trip.
+
+ if (eventIndex == starttimes_min.size()-1 ) {
+ if (looped) {
+ setNextTrip(); // Increments eventIndex, reverts to first trip of week when 'overflowing'
+ break;
+ } else {
+ looped = true;
+ }
+ }
+
+ }
+ prepareNextActivity(time_min, chargePointRegistration);
+ }
+
+ /*
+ * This method is called after the previous trip ended.
+ * It calculates the time to and distance of the coming trip.
+ * If the vehicle is an EV it also calculates the charging need, including possible future trips.
+ * The function passes this information to the EV and registers the charging request at the chargepoint.
+ */
+ public void prepareNextActivity(double time_min, I_ChargePointRegistration chargePointRegistration) {
+ // Trip start/end-times are all defined as minutes since monday 00:00h
+ double timeSinceWeekStart_min = getTimeSinceWeekStart(time_min);
+ nextEventStartTime_min = starttimes_min.get(eventIndex);
+
+ if (eventIndex == 0 && timeSinceWeekStart_min > nextEventStartTime_min) { // Next week's trip!
+ nextEventStartTime_h = (nextEventStartTime_min + time_min - timeSinceWeekStart_min)/60 + 168;
+ } else {
+ nextEventStartTime_h = (nextEventStartTime_min + time_min - timeSinceWeekStart_min)/60;
+ }
+ // traceln("Prepare next activity, trip startTime: %s hours. Time since week start: %s", nextEventStartTime_h, (timeSinceWeekStart_min)/60);
+ idleTimeToNextTrip_min = (nextEventStartTime_min - timeSinceWeekStart_min) % (24*7*60); // Modulo 24*7*60 needed because otherwise negative values can occur when trip starts 'next week'.
+ tripDistance_km = distanceScaling_fr * distances_km.get( eventIndex ); // Update upcoming trip distance
+
+ if (vehicle instanceof J_EAEV ev) {
+
+ double energyNeedForNextTrip_kWh = ev.getEnergyConsumption_kWhpkm() * tripDistance_km;
+ if (idleTimeToNextTrip_min > 0 && (energyNeedForNextTrip_kWh-ev.getCurrentSOC_kWh())> idleTimeToNextTrip_min/60 * ev.capacityElectric_kW) {
+ traceln("TripTracker reports: charging need for next trip is not feasible! Time till next trip: %s hours, chargeNeed_kWh: %s", roundToDecimal(idleTimeToNextTrip_min/60,2), roundToDecimal(energyNeedForNextTrip_kWh-ev.getCurrentSOC_kWh(),2));
+ }
+ //v_energyNeedForNextTrip_kWh = min(v_energyNeedForNextTrip_kWh+10,ev.getStorageCapacity_kWh()); // added 10kWh margin 'just in case'. This is actually realistic; people will charge their cars a bit more than strictly needed for the next trip, if possible.
+ // Check if more charging is needed for next trip!
+ double nextTripDist_km = 0;
+ double nextTripStartTime_min = 0;
+
+ if ( eventIndex == starttimes_min.size() - 1 ) {
+ nextTripDist_km = 0;//distances_km.get( 0 );
+ nextTripStartTime_min = endtimes_min.get(eventIndex);
+ } else {
+ nextTripDist_km = distanceScaling_fr*distances_km.get( eventIndex+1 );
+ nextTripStartTime_min = starttimes_min.get( eventIndex+1 );
+ }
+ double additionalChargingNeededForNextTrip_kWh = max(0,nextTripDist_km * ev.getEnergyConsumption_kWhpkm() - (nextTripStartTime_min - endtimes_min.get(eventIndex))/60*ev.getVehicleChargingCapacity_kW());
+
+ energyNeedForNextTrip_kWh += additionalChargingNeededForNextTrip_kWh;
+ energyNeedForNextTrip_kWh = min(energyNeedForNextTrip_kWh+10,ev.getStorageCapacity_kWh());
+ //traceln("TripTracker, energyNeedForNextTrip: %s", v_energyNeedForNextTrip_kWh);
+ ev.setEnergyNeedForNextTrip_kWh(energyNeedForNextTrip_kWh);
+ /*if ( (v_energyNeedForNextTrip_kWh - EV.getCurrentStateOfCharge() * EV.getStorageCapacity_kWh()) / (idleTimeToNextTrip_min/60) > EV.capacityElectric_kW ) {
+ traceln("Infeasible trip pattern for EV, not enough time to charge for next trip! Required charging power is: " + (v_energyNeedForNextTrip_kWh - EV.getCurrentStateOfCharge() * EV.getStorageCapacity_kWh()) / (idleTimeToNextTrip_min/60) + " kW");
+ traceln("RowIndex: " + rowIndex + " tripDistance: " + tripDistance_km + " km, time to next trip: " + idleTimeToNextTrip_min + " minutes");
} */
-
- //Register EV at the chargepoint
- chargePointRegistration.registerChargingRequest(ev);
- }
- }
+
+ //Register EV at the chargepoint
+ chargePointRegistration.registerChargingRequest(ev);
+ }
+ }
public double getNextEventStartTime_h() {
return nextEventStartTime_h;
@@ -231,25 +231,17 @@ public double getDistanceScaling_fr( ) {
@Override
public void storeStatesAndReset() {
- v_eventIndexStored = v_eventIndex;
- //v_energyNeedForNextTripStored_kWh = v_energyNeedForNextTrip_kWh;
- v_idleTimeToNextTripStored_min = v_idleTimeToNextTrip_min;
- //v_eventIndex = 0; Taken care of by setStartIndex() call!
- //v_energyNeedForNextTrip_kWh = 0;
- v_idleTimeToNextTrip_min = 0;
+ eventIndexStored = eventIndex;
+ idleTimeToNextTripStored_min = idleTimeToNextTrip_min;
+ idleTimeToNextTrip_min = 0;
+ // Don't forget to call setStartIndex !
}
@Override
public void restoreStates() {
- v_eventIndex = v_eventIndexStored;
- v_nextEventStartTime_min = starttimes_min.get(v_eventIndex);
- v_idleTimeToNextTrip_min = v_idleTimeToNextTripStored_min;
- v_tripDist_km = distanceScaling_fr * distances_km.get( v_eventIndex ); // Update upcoming trip distance
-
- /*
- v_energyNeedForNextTrip_kWh = v_energyNeedForNextTripStored_kWh;
- if(vehicle instanceof J_EAEV ev) {
- ev.setEnergyNeedForNextTrip_kWh(v_energyNeedForNextTrip_kWh);
- }*/
+ eventIndex = eventIndexStored;
+ nextEventStartTime_min = starttimes_min.get(eventIndex);
+ idleTimeToNextTrip_min = idleTimeToNextTripStored_min;
+ tripDistance_km = distanceScaling_fr * distances_km.get( eventIndex ); // Update upcoming trip distance
}
}