MATSIM
QueueAgentSnapshotInfoBuilder.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * QueueAgentSnapshotInfoBuilder
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2011 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 package org.matsim.core.mobsim.qsim.qnetsimengine;
21 
22 import org.apache.logging.log4j.LogManager;
23 import org.apache.logging.log4j.Logger;
24 import org.matsim.api.core.v01.Scenario;
27 
28 import jakarta.inject.Inject;
29 import java.util.Collection;
30 
31 
41 class QueueAgentSnapshotInfoBuilder extends AbstractAgentSnapshotInfoBuilder {
42 
43  private static Logger log = LogManager.getLogger(QueueAgentSnapshotInfoBuilder.class);
44 
45  @Inject
46  QueueAgentSnapshotInfoBuilder(Scenario scenario, SnapshotLinkWidthCalculator linkWidthCalculator) {
47  super(scenario, linkWidthCalculator);
48  }
49 
50  @Override
51  double calculateVehicleSpacing(double curvedLength, double overallStorageCapacity,
52  Collection<? extends VisVehicle> vehs) {
53  // the length of a vehicle in visualization
54 
55  double sum = 0. ;
56  for ( VisVehicle veh : vehs ) {
57  sum += veh.getSizeInEquivalents() ;
58  }
59 
60  return Math.min(
61  curvedLength / overallStorageCapacity , // number of ``cells''
62  curvedLength / sum // the link may be more than ``full'' because of forward squeezing of stuck vehicles
63  );
64  }
65 
66  @Override
67  double calculateOdometerDistanceFromFromNode(
68  double time, double curvedLength, double freespeed, double spacing, double prevVehiclesDistance, double remainingTravelTime
69  ) {
70 
71  // avoid divide by 0 and place vehicles at root of link when link has zero length
72  if (curvedLength == 0) {
73  return 0;
74  }
75 
76  // we calculate where the vehicle would be with free speed.
77  /*
78  * In the old code version we had the problem that vehicles did not change position while changing the link,
79  * i.e. they had a positionEvent at time 10 at the junction coordinate (0,0) where the previous link ends,
80  * and the following link starts, then at time 11 they left the old link, entered the new link and had a new
81  * positionEvent at the very same coordinate (0,0) because this is the from coord of the second link.
82  *
83  * The current version tries to simplify this logic by calculating the vehicle's position by simply using
84  * v = s/t -> s = v*t. Because t is the remaining time s is the distance to the toNode. We have to therefore
85  * subtract s from the overall curvedLength to receive the distance from fromNode:
86  * curvedLength - s -> curvedLength - v*t -> curvedLength - freespeed * remainingTravelTime
87  *
88  * This will produce a constant motion since the qsim will generate only a single position for the timestep in
89  * which the vehicle has its link enter, link leave event when crossing two links. The last position on the old
90  * link will be the position of the toNode. The first position generated on the new link is going to be the
91  * timestep after the link enter event for that link occurred. janek june'21
92  */
93  var result = curvedLength - freespeed * remainingTravelTime;
94 
95  // if someone passes negative parameters place the vehicle at the beginning of the link
96  if (result < 0.0) { result = 0.0; }
97 
98  // This is a bit weird if prevVehiclesDistance is NAN, this is the first vehicle. I guess this is a little uncommon
99  // in Java, but this is how I found things.
100  // Place a virtual vehicle at the end of the link + spacing so this vehicle can queue at the link's end
101  if (Double.isNaN(prevVehiclesDistance)) {
102  prevVehiclesDistance = curvedLength + spacing;
103  }
104  // if the freeflow position is further along the link as the prev vehicle, this vehicle has to queue behind the
105  // previous.
106  if (result >= prevVehiclesDistance - spacing) {
107  result = prevVehiclesDistance - spacing;
108  }
109 
110  return result;
111  }
112 }