matsim-libs
matsim-libs copied to clipboard
Qsim: Vehicle getting stuck when vehicle is expected to leave a link and flowCapacity of that link is changed to 0 at the same time step
Hi, i tried a simple scenario, say a series of networkChangeEvents are set to a given link (say Id is "link_1"): at time t=0: flowCapacity=0, t=T: flowCapacity >0, t=T+x: flowCapacity=0. t=T+x+y: flowCapacity>0.
If a vehicle enters this link and, according to qsim's link model, is expected to leave this link at t=T+x (note that at the exact time step t=T+x, the flowCapacity is set to 0) , this vehicle gets stuck. In the output/event file, this vehicle will have a linkEnterEvent at "link_1", but then this vehicle will not be able to leave this link at t=T+x+y and hense no linkLeaveEvent (since at t=T+x+y the flowCapacity is set to >0 again and therefore vehicles should be able to leave the link). The next event of this vehicle is "vehicle abort" event at the last time step of qsim simulation.
More mysteriously, I found that this case only happens when there is no more vehicle using this link. Say now you have two vehicles entering this link "link_1", first one according to qsim's link model, is expected to leave this link at t=T+x; 2nd one following the 1st one and according to qsim's link model, is expected to leave this link at t=T+x+k (doesnt matter if T+x+k > or <T+x+y). Then running this and in the event file, both vehicles can leave this link, meaning no "vehicle abort" events at the last time step of qsim simulation
I present a simple example using Matsim 13.0 below. In the example, link with Id "stop_1" has the following capacity change event: t=0, flowCapacity=0, t=6:05:30, flowCapacity>0 t=6:05:33, flowCapacity=0 t=6:06:00, flowCapacity>0. The person id="person_problem" will enter link "stop_1" at 6:05:30 and according to the freespeed, is expected to leave the link at 6:05:33, and gets stuck (vehicle abort). The expected result should be that person id="person_problem" will have a linkLeaveEvent at "stop_1" at 6:06:00. If you add one more person, (use "population_test_more_agent.xml" instead), both vehicles can leave the link "stop_1" at 6:06:00.
Notes: I set unrealistically high link length, link freespeed and capacity just to make sure the vehicle is (almost) at freespeed at all time, so i know the expected time of each link leave event .
The config file i use: config_4_links.zip
The simple network file: network_4_links.zip
The population files, "population_test.xml" gives the example with vehicle getting abort; "population_test_more_agent.xml" gives the example with no vehicles getting abort: population.zip
The main classs is shown below (just copy paste into the IDE):
public static void main(String[] args) {
String inputPathScenario = "your Path";
// set up transit config group
final String DictionaryFile = inputPathScenario+"output_test_moreAgent"; // output_test or output_test_moreAgent
final String NetworkFile = inputPathScenario + "network_4_links.xml";
final String PlanFile = inputPathScenario + "population_test_more_agent.xml"; // population_test or population_test_more_agent
final String ConfigFile = inputPathScenario + "config_4_links.xml";
Config config = ConfigUtils.loadConfig( ConfigFile ) ;
config.controler().setLastIteration(0);
config.controler().setOutputDirectory(DictionaryFile);
config.network().setTimeVariantNetwork(true);
config.network().setInputFile(NetworkFile);
config.plans().setInputFile(PlanFile);
config.transit().setUseTransit(false) ;
config.qsim().setTrafficDynamics(TrafficDynamics.queue); //TrafficDynamics.kinematicWaves; TrafficDynamics.queue
config.qsim().setEndTime(10*3600);
config.qsim().setUsingFastCapacityUpdate(false);
Scenario scenario = ScenarioUtils.loadScenario(config );
Id<Link> linkId = Id.createLinkId("stop_1");
Link linkToClose = scenario.getNetwork().getLinks().get(linkId ) ;
NetworkChangeEvent networkChangeEventStart = new NetworkChangeEvent(0) ;
networkChangeEventStart.setFlowCapacityChange(new ChangeValue( ChangeType.ABSOLUTE_IN_SI_UNITS, 0 ));
networkChangeEventStart.addLink(linkToClose);
NetworkUtils.addNetworkChangeEvent(scenario.getNetwork(),networkChangeEventStart);
NetworkChangeEvent networkChangeEventOpen = new NetworkChangeEvent(6*3600+5*60+30-1) ; //6:05:30 let the link open
networkChangeEventOpen.setFlowCapacityChange(new ChangeValue( ChangeType.ABSOLUTE_IN_SI_UNITS, 7200 ));
networkChangeEventOpen.addLink(linkToClose);
NetworkUtils.addNetworkChangeEvent(scenario.getNetwork(),networkChangeEventOpen);
NetworkChangeEvent networkChangeEventClose = new NetworkChangeEvent(6*3600+5*60+30+3) ; //6:05:33 close the link again
networkChangeEventClose.setFlowCapacityChange(new ChangeValue( ChangeType.ABSOLUTE_IN_SI_UNITS, 0 ));
networkChangeEventClose.addLink(linkToClose);
NetworkUtils.addNetworkChangeEvent(scenario.getNetwork(),networkChangeEventClose);
NetworkChangeEvent networkChangeEventReopen = new NetworkChangeEvent(6*3600+5*60+60) ; //6:05:60 open the link again
networkChangeEventReopen.setFlowCapacityChange(new ChangeValue( ChangeType.ABSOLUTE_IN_SI_UNITS, 7200 ));
networkChangeEventReopen.addLink(linkToClose);
NetworkUtils.addNetworkChangeEvent(scenario.getNetwork(),networkChangeEventReopen);
Controler controler = new Controler(scenario);
controler.run();
}
Maybe try to set the following parameter in the qsim config group to "false" instead of "true":
param name="usingFastCapacityUpdate" value="true"
I would have to check the code, but that flowCapacity = 0
sounds suspicious. We do various calculations based on the flowCapacity, and if it is zero, who knows if there is not somewhere a division by zero or so, resulting in infinite values. As I said, it's just a suspicion, I would have to check the code to see what happens. Maybe you can try to set the flowCapacity to 0.001 instead and see what happens then.
Also, for other persons coming here and reading this for network change events: please also do not set freespeed to 0. When a vehicle enters the link, its expected link-exit-time is calculated and the vehicle is put into the queue. Given a speed of 0, the link-exit-time becomes infinite, and having first-in-first-out queues in MATSim, a vehicle with infinite exit-time essentially blocks every other vehicle behind it, no matter what speed they would be allowed to drive, as (by default) there is no overtaking in MATSim.
I would have to check the code, but that
flowCapacity = 0
sounds suspicious. We do various calculations based on the flowCapacity, and if it is zero, who knows if there is not somewhere a division by zero or so, resulting in infinite values. As I said, it's just a suspicion, I would have to check the code to see what happens. Maybe you can try to set the flowCapacity to 0.001 instead and see what happens then.Also, for other persons coming here and reading this for network change events: please also do not set freespeed to 0. When a vehicle enters the link, its expected link-exit-time is calculated and the vehicle is put into the queue. Given a speed of 0, the link-exit-time becomes infinite, and having first-in-first-out queues in MATSim, a vehicle with infinite exit-time essentially blocks every other vehicle behind it, no matter what speed they would be allowed to drive, as (by default) there is no overtaking in MATSim.
Thanks a lot for looking into this issue!!! thanks for the suggestion, we have also realised that it is not good to set flowCapacity = 0
. The initial idea is to activate/deactivate the link at the given time window. We have instead now used org.matsim.contrib.signals which suits better for that purpose. While using our user-defined signal controller, there is no issue similar as above appearing.
best Chengxi