Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parking maintenance #3049

Merged
merged 3 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@

public class GeneralParkingModule implements StartupListener, BeforeMobsimListener {

private Controler controler;
private final Controler controler;
private ParkingScore parkingScoreManager;
public final ParkingScore getParkingScoreManager() {
return parkingScoreManager;
}
// public final ParkingScore getParkingScoreManager() {
// return parkingScoreManager;
// }

public final void setParkingScoreManager(ParkingScore parkingScoreManager) {
this.parkingScoreManager = parkingScoreManager;
}

private ParkingInfrastructure parkingInfrastructureManager;
private ParkingChoiceSimulation parkingSimulation;
private ParkingChoiceSimulation parkingChoiceSimulation;

public GeneralParkingModule(Controler controler){
this.controler = controler ;
Expand All @@ -32,40 +32,40 @@ public GeneralParkingModule(Controler controler){

@Override
public void notifyStartup(StartupEvent event) {
parkingSimulation = new ParkingChoiceSimulation(controler.getScenario(), parkingInfrastructureManager);
controler.getEvents().addHandler(parkingSimulation);
parkingChoiceSimulation = new ParkingChoiceSimulation(controler.getScenario(), parkingInfrastructureManager);
controler.getEvents().addHandler( parkingChoiceSimulation );
// controler.addControlerListener(parkingSimulation);
// was not doing anything there. kai, jul'15
}

public final ParkingInfrastructure getParkingInfrastructure() {
return parkingInfrastructureManager;
}
// public final ParkingInfrastructure getParkingInfrastructure() {
// return parkingInfrastructureManager;
// }

public final void setParkingInfrastructurManager(ParkingInfrastructure parkingInfrastructureManager) {
this.parkingInfrastructureManager = parkingInfrastructureManager;
}

@Deprecated
// lower level objects may keep back pointers to higher level objects if they have to, but we prefer that they do not provide them
// as a service. kai, apr'15
public final Controler getControler() {
return controler;
}
// @Deprecated
// // lower level objects may keep back pointers to higher level objects if they have to, but we prefer that they do not provide them
// // as a service. kai, apr'15
// public final Controler getControler() {
// return controler;
// }

@Override
public void notifyBeforeMobsim(BeforeMobsimEvent event) {
parkingScoreManager.prepareForNewIteration();
parkingInfrastructureManager.reset();
parkingSimulation.prepareForNewIteration();
parkingChoiceSimulation.prepareForNewIteration();
}

protected final ParkingInfrastructure getParkingInfrastructureManager() {
return parkingInfrastructureManager;
}
protected final ParkingChoiceSimulation getParkingSimulation() {
return parkingSimulation;
}
// protected final ParkingInfrastructure getParkingInfrastructureManager() {
// return parkingInfrastructureManager;
// }
//
// protected final ParkingChoiceSimulation getParkingSimulation() {
// return parkingSimulation;
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public final class ParkingChoiceSimulation



private ParkingInfrastructure parkingInfrastructureManager;
private Scenario scenario;
private final ParkingInfrastructure parkingInfrastructureManager;
private final Scenario scenario;
private IntegerValueHashMap<Id<Person>> currentPlanElementIndex;
private HashMap<Id<Person>, ParkingOperationRequestAttributes> parkingOperationRequestAttributes;
private DoubleValueHashMap<Id<Person>> firstDepartureTimeOfDay;
Expand All @@ -59,45 +59,38 @@ public ParkingChoiceSimulation(Scenario scenario, ParkingInfrastructure parkingI
this.parkingInfrastructureManager = parkingInfrastructureManager;
}

@Override
public void reset(int iteration) {
}

@Override
public void handleEvent(ActivityEndEvent event) {
currentPlanElementIndex.increment(event.getPersonId());
}

@Override
public void handleEvent(PersonDepartureEvent event) {

if (event.getLegMode().equalsIgnoreCase(TransportMode.car) && !event.getPersonId().toString().contains("pt") && isNotTransitAgent(event.getPersonId())) {
// (exclude some cases (in a brittle way, i.e. based on IDs))

if (!firstDepartureTimeOfDay.containsKey(event.getPersonId())) {
firstDepartureTimeOfDay.put(event.getPersonId(), event.getTime());
// (I think that this is to remember the wrap-around activity.
// kai, jul'15)
// (I think that this is to remember the wrap-around activity. kai, jul'15)
}

if (isFirstCarDepartureOfDay(event.getPersonId())) {
// (special case, think about it later)

ParkingOperationRequestAttributes parkingAttributes = new ParkingOperationRequestAttributes();
parkingAttributes.personId = event.getPersonId();
// this is a trick to get the correct departure time
parkingAttributes.arrivalTime = 0;
parkingAttributes.parkingDurationInSeconds = GeneralLib.getIntervalDuration(0, event.getTime());
parkingInfrastructureManager.personCarDepartureEvent(parkingAttributes);
} else {
ParkingOperationRequestAttributes parkingAttributes = parkingOperationRequestAttributes
.get(event.getPersonId());
parkingAttributes.parkingDurationInSeconds = GeneralLib
.getIntervalDuration(parkingAttributes.arrivalTime, event.getTime());
ParkingOperationRequestAttributes parkingAttributes = parkingOperationRequestAttributes.get(event.getPersonId());
parkingAttributes.parkingDurationInSeconds = GeneralLib.getIntervalDuration(parkingAttributes.arrivalTime, event.getTime());
if (parkingAttributes.parkingDurationInSeconds == 24 * 3600) {
// (yyyy no idea what this is and why. kai, jul'15)

parkingAttributes.parkingDurationInSeconds = 1; // not zero,
// because
// this
// might
// lead to
// NaN
parkingAttributes.parkingDurationInSeconds = 1; // not zero, because this might lead to NaN
}

PC2Parking parking = parkingInfrastructureManager.personCarDepartureEvent(parkingAttributes);
Expand All @@ -111,26 +104,34 @@ public void handleEvent(PersonDepartureEvent event) {
public void handleEvent(PersonArrivalEvent event) {
Id<Person> personId = event.getPersonId();
if (event.getLegMode().equalsIgnoreCase(TransportMode.car) && !event.getPersonId().toString().contains("pt") && isNotTransitAgent(event.getPersonId())) {
ParkingOperationRequestAttributes parkingAttributes = new ParkingOperationRequestAttributes();
Link link = scenario.getNetwork().getLinks().get(event.getLinkId());
Activity nextActivity = getNextActivity(personId);
// (exclude some cases (in a brittle way, i.e. based on IDs))

parkingAttributes.destCoordinate = link.getCoord();
parkingAttributes.arrivalTime = event.getTime();
parkingAttributes.personId = personId;
parkingAttributes.facilityId = nextActivity.getFacilityId();
parkingAttributes.actType = nextActivity.getType();
// I think that this just packages some information together into the parkingAttributes:
ParkingOperationRequestAttributes parkingAttributes = new ParkingOperationRequestAttributes();
{
Link link = scenario.getNetwork().getLinks().get( event.getLinkId() );
Activity nextActivity = getNextActivity( personId );

parkingAttributes.destCoordinate = link.getCoord();
parkingAttributes.arrivalTime = event.getTime();
parkingAttributes.personId = personId;
parkingAttributes.facilityId = nextActivity.getFacilityId();
parkingAttributes.actType = nextActivity.getType();
}

if (isLastCarLegOfDay(personId)) {
parkingAttributes.parkingDurationInSeconds = GeneralLib.getIntervalDuration(event.getTime(),
firstDepartureTimeOfDay.get(personId));
// (special case, think about it later)

parkingAttributes.parkingDurationInSeconds = GeneralLib.getIntervalDuration(event.getTime(), firstDepartureTimeOfDay.get(personId));
} else {
Activity activityBeforeNextCarLeg = getActivityBeforeNextCarLeg(personId);

double endTime= activityBeforeNextCarLeg.getEndTime().seconds();
double parkingDuration=0;

if (endTime==Double.NEGATIVE_INFINITY || endTime==Double.POSITIVE_INFINITY){
// (I think that this _can_ happen, especially in context of within-day replanning, if departure time is unknown. (*))

// try to estimate parking duration

Person person = scenario.getPopulation().getPersons().get(personId);
Expand All @@ -148,20 +149,22 @@ public void handleEvent(PersonArrivalEvent event) {
}
}

parkingAttributes.parkingDurationInSeconds = GeneralLib.getIntervalDuration(event.getTime(),
endTime);
parkingAttributes.parkingDurationInSeconds = GeneralLib.getIntervalDuration(event.getTime(), endTime);
// (This is the _estimated_ parking duration, since we are at arrival. This is needed to define the "best" parking
// location ... cf. short-term/long-term parking at airports. Could rename the attributed into "expected...", but we
// have seen at other places in the code that such attributes may change their interpretation based on context so will
// not do this here.)
}

parkingAttributes.legIndex = currentPlanElementIndex.get(personId);

PC2Parking parking = parkingInfrastructureManager.parkVehicle(parkingAttributes);
// to me this looks like first the agent arrives at his/her
// activity. And then the negative parking score is added after the
// fact, however without consuming time. I.e. there is no physics.
// kai, jul'15
// to me this looks like first the agent arrives at his/her activity. And then the negative parking score is added after the
// fact, however without consuming time. I.e. there is no physics. kai, jul'15

if (isLastCarLegOfDay(personId)) {
parkingInfrastructureManager.scoreParkingOperation(parkingAttributes, parking);
// (The last arrival of the day is scored here, since there is no corresponding departure event.)
}

parkingOperationRequestAttributes.put(personId, parkingAttributes);
Expand All @@ -184,10 +187,8 @@ public void prepareForNewIteration() {
if (PopulationUtils.hasCarLeg(person.getSelectedPlan()) && isNotTransitAgent(person.getId())) {
ParkingOperationRequestAttributes parkingAttributes = new ParkingOperationRequestAttributes();

Activity firstActivityOfDayBeforeDepartingWithCar = PopulationUtils
.getFirstActivityOfDayBeforeDepartingWithCar(person.getSelectedPlan());
Activity firstActivityAfterLastCarLegOfDay = PopulationUtils
.getFirstActivityAfterLastCarLegOfDay(person.getSelectedPlan());
Activity firstActivityOfDayBeforeDepartingWithCar = PopulationUtils.getFirstActivityOfDayBeforeDepartingWithCar(person.getSelectedPlan());
Activity firstActivityAfterLastCarLegOfDay = PopulationUtils.getFirstActivityAfterLastCarLegOfDay(person.getSelectedPlan());

parkingAttributes.destCoordinate = firstActivityAfterLastCarLegOfDay.getCoord();
// parkingAttributes.arrivalTime=firstActivityAfterLastCarLegOfDay.getStartTime();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,13 @@ public synchronized PC2Parking parkVehicle(ParkingOperationRequestAttributes par
}

// put parking that was found into a sorted queue:
PriorityQueue<SortableMapObject<PC2Parking>> queue = new PriorityQueue<SortableMapObject<PC2Parking>>();
PriorityQueue<SortableMapObject<PC2Parking>> queue = new PriorityQueue<>();
for (PC2Parking parking : collection) {
double score = parkingScoreManager.calcScore(parkingOperationRequestAttributes.destCoordinate,
parkingOperationRequestAttributes.arrivalTime,
parkingOperationRequestAttributes.parkingDurationInSeconds, parking,
parkingOperationRequestAttributes.personId, parkingOperationRequestAttributes.legIndex, false);
queue.add(new SortableMapObject<PC2Parking>(parking, -1.0 * score)); // score made positive, so that priority queue works properly
queue.add( new SortableMapObject<>( parking, -1.0 * score ) ); // score made positive, so that priority queue works properly
}

// TODO: should I make MNL only on top 5 here?
Expand Down Expand Up @@ -298,8 +298,7 @@ public synchronized PC2Parking parkVehicle(ParkingOperationRequestAttributes par
// this puts the personId (!!!! yyyyyy) at the parking location:
parkedVehicles.put(parkingOperationRequestAttributes.personId, selectedParking.getId());

// this tells the parking lot to decrease the number of
// available spaces:
// this tells the parking lot to decrease the number of available spaces:
parkVehicle(selectedParking);

// PC2Parking closestParking =
Expand Down Expand Up @@ -364,10 +363,8 @@ public synchronized PC2Parking parkVehicle(ParkingOperationRequestAttributes par
e.printStackTrace();
}

// yyyyyy the parking arrival event returns person id, not vehicle id.
// Do we change to vehicle id, or add the vehicle
// id to the event? In the code, the person id is used for the walk
// distance. kai, jul'15
// yyyyyy the parking arrival event returns person id, not vehicle id. Do we change to vehicle id, or add the vehicle id to
// the event? In the code, the person id is used for the walk distance. kai, jul'15

return selectedParking;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package org.matsim.contrib.parking.parkingchoice.example;
package org.matsim.contrib.parking.parkingchoice.run;

import org.matsim.api.core.v01.population.Person;
import org.matsim.contrib.parking.parkingchoice.PC2.scoring.AbstractParkingBetas;
Expand All @@ -26,7 +26,7 @@
* @author jbischoff
* example class for setting parking betas: we simply return 1 for Beta values. Typically those values should be person- and/or income depending
*/
public class ParkingBetaExample extends AbstractParkingBetas {
class ParkingBetaExample extends AbstractParkingBetas {


@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package org.matsim.contrib.parking.parkingchoice.example;
package org.matsim.contrib.parking.parkingchoice.run;

import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.population.Person;
Expand All @@ -27,7 +27,7 @@
* @author jbischoff
*
*/
public class ParkingCostCalculatorExample implements ParkingCostModel {
class ParkingCostCalculatorExample implements ParkingCostModel {

private double hourlyParkingCharge;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
import org.matsim.contrib.parking.parkingchoice.PC2.scoring.ParkingScoreManager;
import org.matsim.contrib.parking.parkingchoice.PC2.simulation.ParkingInfrastructure;
import org.matsim.contrib.parking.parkingchoice.PC2.simulation.ParkingInfrastructureManager;
import org.matsim.contrib.parking.parkingchoice.example.ParkingBetaExample;
import org.matsim.contrib.parking.parkingchoice.example.ParkingCostCalculatorExample;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.controler.Controler;
Expand All @@ -47,7 +45,7 @@
*
*
*/
public class RunParkingChoiceExample {
class RunParkingChoiceExample {

public static void main(String[] args) {
Config config = ConfigUtils.loadConfig("parkingchoice/config.xml");
Expand All @@ -64,21 +62,24 @@ public static void run(Config config) {

// we need some settings to walk from parking to destination:
ParkingScore parkingScoreManager = new ParkingScoreManager(new WalkTravelTime(controler.getConfig().routing()), scenario);
parkingScoreManager.setParkingScoreScalingFactor(1);
parkingScoreManager.setParkingBetas(new ParkingBetaExample());

{
parkingScoreManager.setParkingScoreScalingFactor( 1 );
parkingScoreManager.setParkingBetas( new ParkingBetaExample() );
}
// ---

ParkingInfrastructure parkingInfrastructureManager = new ParkingInfrastructureManager(parkingScoreManager, controler.getEvents());
{
LinkedList<PublicParking> publicParkings = new LinkedList<PublicParking>();
LinkedList<PublicParking> publicParkings = new LinkedList<>();

//parking 1: we place this near the workplace
publicParkings.add(new PublicParking(Id.create("workPark", PC2Parking.class), 98, new Coord((double) 10000, (double) 0),
publicParkings.add(new PublicParking(Id.create("workPark", PC2Parking.class), 98, new Coord( 10000, 0 ),
new ParkingCostCalculatorExample(1), "park"));

//parking 2: we place this at home
final double x = -25000;
publicParkings.add(new PublicParking(Id.create("homePark", PC2Parking.class), 98, new Coord(x, (double) 0),
publicParkings.add(new PublicParking(Id.create("homePark", PC2Parking.class), 98, new Coord( -25000, 0 ),
new ParkingCostCalculatorExample(0), "park"));

parkingInfrastructureManager.setPublicParkings(publicParkings);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package org.matsim.contrib.parking.run;
package org.matsim.contrib.parking.parkingchoice.run;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.contrib.parking.parkingchoice.run.RunParkingChoiceExample;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.testcases.MatsimTestUtils;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* *
* *********************************************************************** */

package org.matsim.contrib.parking.run;
package org.matsim.contrib.parking.parkingchoice.run;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand Down
Loading