Skip to content

Commit

Permalink
Merge branch 'master' into kmt_UpdateCarriersAnalysis
Browse files Browse the repository at this point in the history
  • Loading branch information
kt86 authored Feb 20, 2024
2 parents a203a2c + 91288bf commit e16182d
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 85 deletions.
2 changes: 1 addition & 1 deletion contribs/hybridsim/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<name>hybridsim</name>

<properties>
<protobuf.version>3.25.2</protobuf.version>
<protobuf.version>3.25.3</protobuf.version>
<grpc.version>1.61.1</grpc.version>
</properties>

Expand Down
2 changes: 1 addition & 1 deletion contribs/protobuf/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<name>protobuf</name>

<properties>
<protobuf.version>3.25.2</protobuf.version>
<protobuf.version>3.25.3</protobuf.version>
</properties>

<dependencies>
Expand Down
2 changes: 2 additions & 0 deletions contribs/vsp/src/main/java/playground/vsp/ev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and if there is a charger on the home link, it does not search for a suitable ac
The final SoC at the end of the iteration is maintained and transferred as the initial SoC to the next iteration.

For this to work, vehicles that represent an EV need to be attached to a vehicle type that is tagged as EV by providing a specific attribute (see `MATSimVehicleWrappingEVSpecificationProvider.class`).
By default, _all_ of these (electric) vehicles are planned by to potentially get charged according to the above described logic.
However, one can prevent this on the vehicle level by `UrbanEVUtils.setChargingDuringActivities(vehicle, false)` when defining the input.

## A few notes to the current state of this package (and it's issues and TODOs)

Expand Down
34 changes: 3 additions & 31 deletions contribs/vsp/src/main/java/playground/vsp/ev/UrbanEVModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

package playground.vsp.ev;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.matsim.contrib.ev.EvModule;
import org.matsim.contrib.ev.charging.ChargingModule;
import org.matsim.contrib.ev.discharging.DischargingModule;
Expand All @@ -31,9 +33,6 @@
import org.matsim.core.config.groups.ScoringConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.mobsim.qsim.AbstractQSimModule;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.matsim.core.mobsim.qsim.components.QSimComponentsConfigGroup;

public class UrbanEVModule extends AbstractModule {
Expand All @@ -47,13 +46,6 @@ public class UrbanEVModule extends AbstractModule {
QSimComponentsConfigGroup qsimComponentsConfig = ConfigUtils.addOrGetModule( config, QSimComponentsConfigGroup.class );
qsimComponentsConfig.addActiveComponent( EvModule.EV_COMPONENT );

// UrbanEVConfigGroup urbanEVConfig = ConfigUtils.addOrGetModule( config, UrbanEVConfigGroup.class );

// if (urbanEVConfig == null)
// throw new IllegalArgumentException(
// "no config group of type " + UrbanEVConfigGroup.GROUP_NAME + " was specified in the config");
// was this meaningful? I.e. do we want the code to fail if there is no such config group? kai, apr'23

//standard EV stuff
install(new ChargingInfrastructureModule());
install(new ChargingModule());
Expand All @@ -62,7 +54,6 @@ public class UrbanEVModule extends AbstractModule {
install(new ElectricFleetModule());

//bind custom EVFleet stuff
// bind(ElectricFleetUpdater.class).in(Singleton.class);
addControlerListenerBinding().to(ElectricFleetUpdater.class).in( Singleton.class );
// (this takes the matsim modal vehicles for each leg and gives them to the ElectricFleetSpecification. Don't know why it has to be in
// this ad-hoc way. kai, apr'23)
Expand All @@ -74,21 +65,14 @@ protected void configureQSim() {
// bind(UrbanVehicleChargingHandler.class);
addMobsimScopeEventHandlerBinding().to(UrbanVehicleChargingHandler.class);
// (I think that this takes the plugin/plugout activities, and actually initiates the charging. kai, apr'23)
// yes it does, just like the regular VehicleChargingHandler in the ev contrib. schlenther, feb'24.
}
});

//bind urban ev planning stuff
addMobsimListenerBinding().to(UrbanEVTripsPlanner.class);
// (I think that this inserts the charging activities just before the mobsim starts (i.e. it is not in the plans). kai, apr'23)

//TODO find a better solution for this yyyy yes. We do not want automagic. kai, apr'23 done. kai, apr'23
// Collection<String> whileChargingActTypes = urbanEVConfig.getWhileChargingActivityTypes().isEmpty() ?
// config.planCalcScore().getActivityTypes() :
// urbanEVConfig.getWhileChargingActivityTypes();

// bind(ActivityWhileChargingFinder.class).toInstance(new ActivityWhileChargingFinder(whileChargingActTypes,
// urbanEVConfig.getMinWhileChargingActivityDuration_s()));

bind( ActivityWhileChargingFinder.class ).in( Singleton.class );

//bind custom analysis:
Expand All @@ -98,16 +82,4 @@ protected void configureQSim() {
addControlerListenerBinding().to(ActsWhileChargingAnalyzer.class);
}

// private Set<String> getOpenBerlinActivityTypes() {
// Set<String> activityTypes = new HashSet<>();
// for (long ii = 600; ii <= 97200; ii += 600) {
// activityTypes.add("home_" + ii + ".0");
// activityTypes.add("work_" + ii + ".0");
// activityTypes.add("leisure_" + ii + ".0");
// activityTypes.add("shopping_" + ii + ".0");
// activityTypes.add("other_" + ii + ".0");
// }
// return activityTypes;
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,12 @@

package playground.vsp.ev;

import static java.util.stream.Collectors.*;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import com.sun.istack.Nullable;
import jakarta.inject.Provider;

import one.util.streamex.StreamEx;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.logging.log4j.LogManager;
Expand All @@ -43,18 +35,16 @@
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.population.Activity;
import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.Plan;
import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.api.core.v01.population.PopulationFactory;
import org.matsim.api.core.v01.population.*;
import org.matsim.contrib.common.util.StraightLineKnnFinder;
import org.matsim.contrib.ev.charging.ChargingLogic;
import org.matsim.contrib.ev.charging.ChargingPower;
import org.matsim.contrib.ev.discharging.AuxEnergyConsumption;
import org.matsim.contrib.ev.discharging.DriveEnergyConsumption;
import org.matsim.contrib.ev.fleet.*;
import org.matsim.contrib.ev.fleet.ElectricFleetSpecification;
import org.matsim.contrib.ev.fleet.ElectricFleetUtils;
import org.matsim.contrib.ev.fleet.ElectricVehicle;
import org.matsim.contrib.ev.fleet.ElectricVehicleSpecification;
import org.matsim.contrib.ev.infrastructure.ChargerSpecification;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureSpecification;
import org.matsim.core.config.Config;
Expand All @@ -69,11 +59,7 @@
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.NetworkRoute;
import org.matsim.core.router.LinkWrapperFacility;
import org.matsim.core.router.SingleModeNetworksCache;
import org.matsim.core.router.StageActivityTypeIdentifier;
import org.matsim.core.router.TripRouter;
import org.matsim.core.router.TripStructureUtils;
import org.matsim.core.router.*;
import org.matsim.core.router.util.TravelTime;
import org.matsim.core.utils.misc.OptionalTime;
import org.matsim.core.utils.timing.TimeInterpretation;
Expand All @@ -82,15 +68,15 @@
import org.matsim.utils.objectattributes.attributable.AttributesImpl;
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleUtils;
import org.matsim.vehicles.Vehicles;
import org.matsim.withinday.utils.EditPlans;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import com.sun.istack.Nullable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

import one.util.streamex.StreamEx;
import static java.util.stream.Collectors.*;

class UrbanEVTripsPlanner implements MobsimInitializedListener {

Expand All @@ -100,9 +86,6 @@ class UrbanEVTripsPlanner implements MobsimInitializedListener {
@Inject
Scenario scenario;

@Inject
Vehicles vehicles;

@Inject
private SingleModeNetworksCache singleModeNetworksCache;

Expand Down Expand Up @@ -151,9 +134,10 @@ public void notifyMobsimInitialized(MobsimInitializedEvent e) {
if (!(e.getQueueSimulation() instanceof QSim)) {
throw new IllegalStateException(UrbanEVTripsPlanner.class + " only works with a mobsim of type " + QSim.class);
}
UrbanEVConfigGroup configGroup = (UrbanEVConfigGroup)config.getModules().get(UrbanEVConfigGroup.GROUP_NAME);
//collect all selected plans that contain ev legs and map them to the set of ev used
Map<Plan, Set<Id<Vehicle>>> selectedEVPlans = StreamEx.of(scenario.getPopulation().getPersons().values())
.mapToEntry(p -> p.getSelectedPlan(), p -> getUsedEV(p.getSelectedPlan()))
.mapToEntry(p -> p.getSelectedPlan(), p -> getUsedEVToPreplan(p.getSelectedPlan()))
.filterValues(evSet -> !evSet.isEmpty())
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));

Expand All @@ -169,16 +153,17 @@ public void notifyMobsimInitialized(MobsimInitializedEvent e) {
* @param plan
* @return
*/
private Set<Id<Vehicle>> getUsedEV(Plan plan) {
private Set<Id<Vehicle>> getUsedEVToPreplan(Plan plan) {
return TripStructureUtils.getLegs(plan)
.stream()
.map(leg -> VehicleUtils.getVehicleId(plan.getPerson(), leg.getMode()))
.filter(vehicleId -> isEV(vehicleId))
.filter(vehicleId -> isEVAndToBeChargedWhileActivities(vehicleId))
.collect(toSet());
}

private boolean isEV(Id<Vehicle> vehicleId) {
return this.electricFleetSpecification.getVehicleSpecifications().containsKey(Id.create(vehicleId, Vehicle.class));
private boolean isEVAndToBeChargedWhileActivities(Id<Vehicle> vehicleId) {
ElectricVehicleSpecification ev = this.electricFleetSpecification.getVehicleSpecifications().getOrDefault(Id.create(vehicleId, Vehicle.class), null);
return (ev != null && UrbanEVUtils.isChargingDuringActivities(ev));
}

private void processPlans(Map<Plan, Set<Id<Vehicle>>> selectedEVPlans) {
Expand Down
67 changes: 67 additions & 0 deletions contribs/vsp/src/main/java/playground/vsp/ev/UrbanEVUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* *********************************************************************** *
* project: org.matsim.*
* Controler.java
* *
* *********************************************************************** *
* *
* copyright : (C) 2007 by the members listed in the COPYING, *
* LICENSE and WARRANTY file. *
* email : info at matsim dot org *
* *
* *********************************************************************** *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */

package playground.vsp.ev;

import org.matsim.contrib.ev.fleet.ElectricVehicleSpecification;
import org.matsim.vehicles.Vehicle;

public final class UrbanEVUtils {

public static final String PLAN_CHARGING_DURING_ACTS_ATTRIBUTE_NAME = "planChargingDuringActivities";

/**
* Checks whether {@code electricVehicleSpecification} should be charged during the drivers' activities. <br>
* If this is the case, [@code {@link UrbanEVTripsPlanner} will pre-plan charging according to the driver's selected plan. <br>
* <p>
* Checks for the corresponding attribute with key={@code PLAN_CHARGING_DURING_ACTS_ATTRIBUTE_NAME} in the MATSim input vehicle.
* <b>If the attribute was not provided, true is returned!</b>
* This means that by default, <i>all</i> electricVehicleSpecifications are planned to get charged during activities and not during trips
* (planning for the latter is done by {@code org.matsim.contrib.ev.routing.EVNetworkRoutingModule}.
* </p>
* @param electricVehicleSpecification
* @return
*/
public static boolean isChargingDuringActivities(ElectricVehicleSpecification electricVehicleSpecification) {
Object attribute = electricVehicleSpecification.getMatsimVehicle().getAttributes().getAttribute(PLAN_CHARGING_DURING_ACTS_ATTRIBUTE_NAME);
return attribute == null ? true : (Boolean) attribute;
}

/**
* see description for {@code setChargingDuringActivities(Vehicle vehicle, boolean value)}
* @param electricVehicleSpecification
* @param value
*/
public static void setChargingDuringActivities(ElectricVehicleSpecification electricVehicleSpecification, boolean value) {
setChargingDuringActivities(electricVehicleSpecification.getMatsimVehicle(), value);
}

/**
* defines whether the vehicle shall be included for planning recharging during the driver's activities (with {@code UrbanEVTripsPlanner}, or not. <br>
* In the latter case, recharging may be planned to take place during a trip, if the vehicle is taken for a trip with a mode that is
* routed by {@code org.matsim.contrib.ev.routing.EVNetworkRoutingModule}.
* @param vehicle
* @param value
*/
public static void setChargingDuringActivities(Vehicle vehicle, boolean value) {
vehicle.getAttributes().putAttribute(PLAN_CHARGING_DURING_ACTS_ATTRIBUTE_NAME, value);
}

}
Loading

0 comments on commit e16182d

Please sign in to comment.