-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: update vdf to latest internal version (#193)
* feat: update vdf to latest internal version * update * Update README.md Make things clearer for the adjustment of capacity factors in the config. --------- Co-authored-by: Milos Balac <[email protected]>
- Loading branch information
Showing
23 changed files
with
1,308 additions
and
125 deletions.
There are no files selected for viewing
96 changes: 96 additions & 0 deletions
96
examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFEngineSimulation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package org.eqasim.examples.corsica_vdf; | ||
|
||
import java.net.URL; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import org.eqasim.core.components.traffic.EqasimTrafficQSimModule; | ||
import org.eqasim.core.components.transit.EqasimTransitQSimModule; | ||
import org.eqasim.core.simulation.analysis.EqasimAnalysisModule; | ||
import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; | ||
import org.eqasim.ile_de_france.IDFConfigurator; | ||
import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; | ||
import org.eqasim.vdf.VDFConfigGroup; | ||
import org.eqasim.vdf.VDFModule; | ||
import org.eqasim.vdf.VDFQSimModule; | ||
import org.eqasim.vdf.engine.VDFEngineConfigGroup; | ||
import org.eqasim.vdf.engine.VDFEngineModule; | ||
import org.matsim.api.core.v01.Scenario; | ||
import org.matsim.core.config.CommandLine; | ||
import org.matsim.core.config.CommandLine.ConfigurationException; | ||
import org.matsim.core.config.Config; | ||
import org.matsim.core.config.ConfigUtils; | ||
import org.matsim.core.controler.Controler; | ||
import org.matsim.core.scenario.ScenarioUtils; | ||
|
||
import com.google.common.io.Resources; | ||
|
||
/** | ||
* This is an example run script that runs the Corsica test scenario with a | ||
* volume-delay function to simulate travel times. | ||
*/ | ||
public class RunCorsicaVDFEngineSimulation { | ||
static public void main(String[] args) throws ConfigurationException { | ||
CommandLine cmd = new CommandLine.Builder(args) // | ||
.allowPrefixes("mode-parameter", "cost-parameter") // | ||
.build(); | ||
|
||
IDFConfigurator configurator = new IDFConfigurator(); | ||
configurator.getQSimModules().removeIf(m -> m instanceof EqasimTrafficQSimModule); | ||
|
||
URL configUrl = Resources.getResource("corsica/corsica_config.xml"); | ||
Config config = ConfigUtils.loadConfig(configUrl, configurator.getConfigGroups()); | ||
|
||
config.controler().setLastIteration(2); | ||
|
||
// VDF: Add config group | ||
config.addModule(new VDFConfigGroup()); | ||
|
||
// VDF: Disable queue logic | ||
config.qsim().setFlowCapFactor(1e9); | ||
config.qsim().setStorageCapFactor(1e9); | ||
|
||
// VDF: Set capacity factor instead (~0.1 for a 10% simulation in theory... any better advice?) | ||
VDFConfigGroup.getOrCreate(config).setCapacityFactor(0.1); | ||
|
||
// VDF: Optional | ||
VDFConfigGroup.getOrCreate(config).setWriteInterval(1); | ||
VDFConfigGroup.getOrCreate(config).setWriteFlowInterval(1); | ||
|
||
// VDF Engine: Add config group | ||
config.addModule(new VDFEngineConfigGroup()); | ||
|
||
// VDF Engine: Decide whether to genertae link events or not | ||
VDFEngineConfigGroup.getOrCreate(config).setGenerateNetworkEvents(false); | ||
|
||
// VDF Engine: Remove car from main modes | ||
Set<String> mainModes = new HashSet<>(config.qsim().getMainModes()); | ||
mainModes.remove("car"); | ||
config.qsim().setMainModes(mainModes); | ||
|
||
Scenario scenario = ScenarioUtils.createScenario(config); | ||
configurator.configureScenario(scenario); | ||
ScenarioUtils.loadScenario(scenario); | ||
|
||
Controler controller = new Controler(scenario); | ||
configurator.configureController(controller); | ||
controller.addOverridingModule(new EqasimAnalysisModule()); | ||
controller.addOverridingModule(new EqasimModeChoiceModule()); | ||
controller.addOverridingModule(new IDFModeChoiceModule(cmd)); | ||
|
||
// VDF: Add modules | ||
controller.addOverridingModule(new VDFModule()); | ||
controller.addOverridingQSimModule(new VDFQSimModule()); | ||
|
||
// VDF Engine: Add modules | ||
controller.addOverridingModule(new VDFEngineModule()); | ||
|
||
// VDF Engine: Active engine | ||
controller.configureQSimComponents(cfg -> { | ||
EqasimTransitQSimModule.configure(cfg, controller.getConfig()); | ||
cfg.addNamedComponent(VDFEngineModule.COMPONENT_NAME); // here | ||
}); | ||
|
||
controller.run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# VDF Module | ||
|
||
The following describes how volume-delay-functions (VDF) can be used in eqasim. There are several shortcomings with the queue-based simulation of MATSim, especially when thinking, for instance, of spillback from a city network onto highways and similar phenomena. This could be covered by lanes in MATSim, but this functionality does not seem to be widely used and data acquisition seems tricky. | ||
|
||
Therefore, we propose to simply treat each link in the network as a line that needs to be traversed by all vehicles with a specific duration. This duration, as in the classic BPR function, is directly dependent on the flow on that link. Our idea is now to track the flow on each link from the previous iteration(s) and then impose the calculated travel time. The same travel time is used in the routing and decision-making, so that agents will avoid using links with high flow relative to its capacity, because traversal times are high. | ||
|
||
## VDF Module | ||
|
||
The main components of this extension are the `VDF(QSim)Module` and the `VDFConfigGroup`. The interval on which flows are evaluated can be configured, but is set to one hour by default. The volume-delay-function used is the classic BPR function that calculates a traversal time based on the free-flow traversal time and the ratio between detected flow and link capacity. | ||
|
||
For the VDF functionality to work: | ||
- Set the storage capacity of all links to infinity (`1e9`), we effectively disable the queue logic using the `storageCapacityFactor` in the QSim configuration | ||
- Set the flow capacity of all links to infinity (`1e9`), we effectively disable the queue logic using the `flowCapacityFactor` in the QSim configuration | ||
- Remove `car` from the `mainModes` in the QSim configuration | ||
- Add `VDFModule` and `VDFQSimModule` | ||
|
||
On the technical side, the logic is that the VDF component tracks link enter/leave events and thus established the flows on the links. Based on those flows, the traversal times are calculated and bound via `TravelTime`. This travel time is then used by the standard network routing modules for the relevant modes. | ||
|
||
Note that it would be unstable to always use the flows of the previous iteration. Therefore, we interpolate over multiple iterations. There are various ways of doing so, by default we use a horizon-based approach in which we track the flows on all links over `N` (default 10) iterations and then calculate the mean (MA, moving average approach). Another approach is to always blend between the flows of the previous iteration and the current one (AR, auto-regressive approach). It can be selected in the config group. | ||
|
||
Furthermore, averaging over multiple iterations means that we need to recover this state if we want to restart a simulation later on at a specific iteration. The config group provides a `inputFile` parameter that does exactly this, based on the VDF output of a previous simulation. | ||
|
||
The binary output can be controlled by setting `writeInterval` in the config group. If set to a very large value, only the last iteration will be saved. Optionally, a file containing the flows on all links will be generated by setting `writeFlowInterval`. | ||
|
||
**Attention**: The VDF (default BPR) is defined for a full-size simulation, and so are the capacities in the network. To obtain proper travel times, the observed flows, hence, need to be scaled up if a down-scaled demand is used. This is done through the `capacityFactor` parameter in the config group. It works analogously to QSim's flow capacity factor. A factor of *0.1* performs the calculations as if the capacities were only *10%* of their nominal values. | ||
|
||
## VDF Engine | ||
|
||
The next step after imposing travel times in the QSim is to simplify simulation altogether. For this, there is the `VDFEngineModule`. It replaces the simulation of selected modes (like car) completely in the QSim. In particular, it removes the queue simulation as we don't need this in a VDF simulation. The agents are simply removed from the simulation at departure and added back at the destination after the trip has been finished. | ||
|
||
There are two options to work with the generated flows: | ||
- Either, the engine manually generates link enter/leave events that are later tracked by the VDF module. | ||
- Or, we send all link traversals as a batch to the flow trackers (much more performant), but we lose the ability to analyze link enter/leave events otherwise. | ||
|
||
By default, the `VDFEngineConfigGroup` is configured to generate events and replace the `car` mode. | ||
|
||
## Example | ||
|
||
An example for the configuration of both cases can be found in the `examples` package for `corsica_vdf`. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.