matsim-libs icon indicating copy to clipboard operation
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

Open CLIVTI opened this issue 3 years ago • 3 comments

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();

	



}

CLIVTI avatar Oct 25 '21 14:10 CLIVTI

Maybe try to set the following parameter in the qsim config group to "false" instead of "true":

param name="usingFastCapacityUpdate" value="true"

ikaddoura avatar Jan 15 '24 16:01 ikaddoura

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.

mrieser avatar Jan 16 '24 21:01 mrieser

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

CLIVTI avatar Jan 17 '24 09:01 CLIVTI