Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/maven/com.google.protobuf-proto…
Browse files Browse the repository at this point in the history
…buf-java-4.28.3
  • Loading branch information
jfbischoff authored Nov 5, 2024
2 parents c670924 + 3bae08b commit e57c07e
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import org.matsim.core.config.groups.QSimConfigGroup.LinkDynamics;
import org.matsim.core.config.groups.QSimConfigGroup.TrafficDynamics;
import org.matsim.core.gbl.Gbl;
import org.matsim.core.gbl.MatsimRandom;
import org.matsim.core.mobsim.framework.MobsimDriverAgent;
import org.matsim.core.mobsim.qsim.interfaces.MobsimVehicle;
import org.matsim.core.mobsim.qsim.interfaces.SignalGroupState;
Expand All @@ -63,8 +62,8 @@
* Separating out the "lane" functionality from the "link" functionality.
* <p></p>
* Design thoughts:<ul>
* <li> In fast capacity update, the flows are not accumulated in every time step,
* rather updated only if an agent wants to enter the link or an agent is added to buffer.
* <li> In fast capacity update, the flows are not accumulated in every time step,
* rather updated only if an agent wants to enter the link or an agent is added to buffer.
* Improvement of 15-20% in the computational performance is observed. amit feb'16
* (I seem to recall that in the end that statement was not consistently correct. kai, feb'18)</li>
* <li>Currently (feb'18), the design is such that (possibly time-dep) flowCap and nEffectiveLanes are "pushed" into the
Expand All @@ -90,7 +89,7 @@ public final void addFromWait(final QVehicle veh) {

addToBuffer(veh);
}

/**
* Stores the accumulated fractional parts of the flow capacity. See also
* flowCapFraction.
Expand Down Expand Up @@ -189,7 +188,7 @@ private void addValue(double value1, double now) {
private double effectiveNumberOfLanesUsedInQsim = Double.POSITIVE_INFINITY ;

private double accumulatedInflowCap = 1. ;

private final FlowEfficiencyCalculator flowEfficiencyCalculator;

private QueueWithBuffer(AbstractQLink.QLinkInternalInterface qlink, final VehicleQ<QVehicle> vehicleQueue, Id<Lane> laneId,
Expand All @@ -198,7 +197,7 @@ private QueueWithBuffer(AbstractQLink.QLinkInternalInterface qlink, final Vehicl
// the general idea is to give this object no longer access to "everything". Objects get back pointers (here qlink), but they
// do not present the back pointer to the outside. In consequence, this object can go up to qlink, but not any further. kai, mar'16
// Now I am even trying to get rid of the full qLink back pointer (since it allows, e.g., going back to Link). kai, feb'18

// log.setLevel(Level.DEBUG);

this.flowEfficiencyCalculator = flowEfficiencyCalculator;
Expand Down Expand Up @@ -328,7 +327,7 @@ private void updateFastFlowAccumulation(){
double now = context.getSimTimer().getTimeOfDay() ;

double remainingFlowCapThisTimeStep = subtractConsumptionOfVehiclesThatAreAlreadyInTheBuffer();

if( this.flowcap_accumulate.getTimeStep() < now
&& this.flowcap_accumulate.getValue() < remainingFlowCapThisTimeStep){

Expand All @@ -344,7 +343,7 @@ private void updateFastFlowAccumulation(){

private void updateSlowFlowAccumulation(){
double remainingFlowCapThisTimeStep = subtractConsumptionOfVehiclesThatAreAlreadyInTheBuffer();

if (this.thisTimeStepGreen
&& this.flowcap_accumulate.getValue() < remainingFlowCapThisTimeStep){
double newFlowCap = Math.min(flowcap_accumulate.getValue() + flowCapacityPerTimeStep,
Expand Down Expand Up @@ -372,15 +371,15 @@ public final void initBeforeSimStep() {
private void calculateFlowCapacity() {
// the following is not looking at time because it simply assumes that the lookups are "now". kai, feb'18
// I am currently not sure if this statement is correct. kai, feb'18

// we need the flow capacity per sim-tick and multiplied with flowCapFactor
flowCapacityPerTimeStep = unscaledFlowCapacity_s * context.qsimConfig.getTimeStepSize() * context.qsimConfig.getFlowCapFactor() ;
inverseFlowCapacityPerTimeStep = 1.0 / flowCapacityPerTimeStep;

// start with the base assumption, might be adjusted below depending on the traffic dynamics
this.effectiveNumberOfLanesUsedInQsim = this.effectiveNumberOfLanes;
this.maxInflowUsedInQsim = this.flowCapacityPerTimeStep;

switch (context.qsimConfig.getTrafficDynamics()) {
case queue:
case withHoles:
Expand All @@ -391,10 +390,10 @@ private void calculateFlowCapacity() {
// equal: rho * (vmax + vhole) = vhole * rhojam
// rho(qmax) = vhole * rhojam / (vmax + vhole)
// qmax = vmax * rho(qmax) = rhojam / (1/vhole + 1/vmax) ;

// yyyyyy this should possibly be getFreespeed(now). But if that's the case, then maxFlowFromFdiag would
// also have to be re-computed with each freespeed change. kai, feb'18

final double maxFlowFromFdiag = (this.effectiveNumberOfLanes/context.effectiveCellSize) / ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLinkInternalInterface.getFreespeed() ) ;
final double minimumNumberOfLanesFromFdiag = this.flowCapacityPerTimeStep * context.effectiveCellSize * ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLinkInternalInterface.getFreespeed() );

Expand Down Expand Up @@ -455,19 +454,19 @@ private void calculateFlowCapacity() {
}
}
break;

default: throw new RuntimeException("The traffic dynamics "+context.qsimConfig.getTrafficDynamics()+" is not implemented yet.");
}
// log.debug( "linkId=" + this.qLink.getLink().getId() + "; flowCapPerTimeStep=" + flowCapacityPerTimeStep +
// "; invFlowCapPerTimeStep=" + inverseFlowCapacityPerTimeStep + "; maxFlowFromFdiag=" + maxFlowFromFdiag ) ;

}

private void calculateStorageCapacity() {
// The following is not adjusted for time-dependence!! kai, apr'16
// No, I think that it simply assumes that the lookups are "now". kai, feb'18
// double now = context.getSimTimer().getTimeOfDay() ;

// first guess at storageCapacity:
storageCapacity = this.length * this.effectiveNumberOfLanesUsedInQsim / context.effectiveCellSize * context.qsimConfig.getStorageCapFactor() ;
// storageCapacity = this.length * this.qLink.getLink().getNumberOfLanes(now) / context.effectiveCellSize * context.qsimConfig.getStorageCapFactor() ;
Expand All @@ -489,7 +488,7 @@ private void calculateStorageCapacity() {
if (Double.isNaN(freespeedTravelTime)) {
throw new IllegalStateException("Double.NaN is not a valid freespeed travel time for a link. Please check the attributes length and freespeed!");
}

//this assumes that vehicles have the flowEfficiencyFactor of 1.0; the actual flow can be different
double tempStorageCapacity = freespeedTravelTime * unscaledFlowCapacity_s * context.qsimConfig.getFlowCapFactor();
// yy note: freespeedTravelTime may be Inf. In this case, storageCapacity will also be set to Inf. This can still be
Expand All @@ -505,7 +504,7 @@ private void calculateStorageCapacity() {
QueueWithBuffer.spaceCapWarningCount++;
}
storageCapacity = tempStorageCapacity;

// write out the modified qsim behavior as link attribute
qLinkInternalInterface.getLink().getAttributes().putAttribute("storageCapacityUsedInQsim", storageCapacity );
}
Expand All @@ -514,7 +513,7 @@ private void calculateStorageCapacity() {
* () uncongested branch is q(rho) = rho * v_max
* () congested branch is q(rho) = (rho - rho_jam) * v_holes
* () rho_maxflow is where these two meet, resulting in rho_maxflow = v_holes * rho_jam / ( v_holes + v_max )
* () max flow is q(rho_maxflow), resulting in v_max * v_holes * rho_jam / ( v_holes + v_max )
* () max flow is q(rho_maxflow), resulting in v_max * v_holes * rho_jam / ( v_holes + v_max )
* () Since everything else is given, rho_jam needs to be large enough so that q(rho_maxflow) can reach capacity, resulting in
* rho_jam >= capacity * (v_holes + v_max) / (v_max * v_holes) ;
* () In consequence, storage capacity needs to be larger than curved_length * rho_jam .
Expand Down Expand Up @@ -554,7 +553,7 @@ private void calculateStorageCapacity() {
}

private double getBufferStorageCapacity() {
return flowCapacityPerTimeStep;//this assumes that vehicles have the flowEfficiencyFactor of 1.0
return flowCapacityPerTimeStep;//this assumes that vehicles have the flowEfficiencyFactor of 1.0
}

@Override
Expand Down Expand Up @@ -664,7 +663,6 @@ private void removeVehicleFromQueue(final QVehicle veh2Remove) {
case withHoles:
case kinematicWaves:
QueueWithBuffer.Hole hole = new QueueWithBuffer.Hole() ;
double ttimeOfHoles = length*3600./HOLE_SPEED_KM_H/1000. ;

// double offset = this.storageCapacity/this.flowCapacityPerTimeStep ;
/* NOTE: Start with completely full link, i.e. N_storageCap cells filled. Now make light at end of link green, discharge with
Expand All @@ -680,7 +678,12 @@ private void removeVehicleFromQueue(final QVehicle veh2Remove) {
// double nLanes = 2. * flowCapacityPerTimeStep ; // pseudo-lanes
// double ttimeOfHoles = 0.1 * this.storageCapacity/this.flowCapacityPerTimeStep/nLanes ;

hole.setEarliestLinkExitTime( now + 1.0*ttimeOfHoles + 0.0*MatsimRandom.getRandom().nextDouble()*ttimeOfHoles ) ;
// The calculation of the earliest exit time looked like the formula below. It looks like someone tried to include some randomness,
// but the random part was multiplied with zero, therefore I removed it. Janek oct' 24
// now + 1.0*ttimeOfHoles + 0.0*MatsimRandom.getRandom().nextDouble()*ttimeOfHoles
var holeTravelTime = length * 3.6 / HOLE_SPEED_KM_H;
var earliestExitTime = now + holeTravelTime;
hole.setEarliestLinkExitTime(earliestExitTime) ;
hole.setSizeInEquivalents(veh2Remove.getSizeInEquivalents());
holes.add( hole ) ;
break;
Expand Down Expand Up @@ -747,9 +750,9 @@ public void recalcTimeVariantAttributes() {
// not speed, since that is looked up anyways.
// yy might also make flow and storage self-detecting changes (not really that
// much more expensive). kai, feb'18

// log.debug("just entered recalcTimeVariantAttributes; now=" + this.context.getSimTimer().getTimeOfDay() ) ;

calculateFlowCapacity();
calculateStorageCapacity();
flowcap_accumulate.setValue(flowCapacityPerTimeStep);
Expand Down Expand Up @@ -916,7 +919,7 @@ public final double getLastMovementTimeOfFirstVehicle() {
public final void addTransitSlightlyUpstreamOfStop( final QVehicle veh) {
this.vehQueue.addFirst(veh) ;
}

@Override
public final void setSignalized( final boolean isSignalized) {
qSignalizedItem = new DefaultSignalizeableItem( qLinkInternalInterface.getToNode().getOutLinks().keySet());
Expand Down Expand Up @@ -1020,7 +1023,7 @@ void setVisInfo(Coord upstreamCoord, Coord downstreamCoord) {
this.downstreamCoord = downstreamCoord;
}
}

private int noOfSeepModeBringFwd = 0;

private QVehicle peekFromVehQueue(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
import com.google.inject.Key;
import com.google.inject.Singleton;
import com.google.inject.name.Names;

import jakarta.inject.Inject;
import jakarta.inject.Provider;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.config.groups.TravelTimeCalculatorConfigGroup;
Expand All @@ -35,8 +36,7 @@
import org.matsim.core.router.util.TravelTime;
import org.matsim.core.utils.collections.CollectionUtils;

import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Set;


/**
Expand All @@ -55,28 +55,42 @@ public void install() {

if (getConfig().travelTimeCalculator().isCalculateLinkToLinkTravelTimes()) {
throw new RuntimeException("separate modes together with link2link routing currently not implemented. doesn't look difficult, "
+ "but I cannot say if it would be picked up correctly by downstream modules. kai, nov'16") ;
+ "but I cannot say if it would be picked up correctly by downstream modules. kai, nov'16");
}

Set<String> analyzedModes = getConfig().travelTimeCalculator().getAnalyzedModes();

// go through all modes:
// for (final String mode : CollectionUtils.stringToSet(getConfig().travelTimeCalculator().getAnalyzedModesAsString() )) {
for (final String mode : getConfig().routing().getNetworkModes() ) {
for (final String mode : getConfig().routing().getNetworkModes()) {

// generate and bind the observer:
bind(TravelTimeCalculator.class).annotatedWith(Names.named(mode)).toProvider(new SingleModeTravelTimeCalculatorProvider(mode)).in(Singleton.class);
if (analyzedModes.contains(mode)) {
// generate and bind the observer:
bind(TravelTimeCalculator.class).annotatedWith(Names.named(mode)).toProvider(new SingleModeTravelTimeCalculatorProvider(mode)).in(Singleton.class);

// bind the observer to travel time provider (for router):
addTravelTimeBinding(mode).toProvider(new Provider<TravelTime>() {
@Inject Injector injector;
@Override public TravelTime get() {
return injector.getInstance( Key.get( TravelTimeCalculator.class, Names.named( mode ) ) ).getLinkTravelTimes();
}
// bind the observer to travel time provider (for router):
addTravelTimeBinding(mode).toProvider(new Provider<TravelTime>() {
@Inject
Injector injector;

// the following is not there yet (leads to NPE). Presumably, the collection into the underlying multi-binder is
// done later, and until then it is only available per annotation (as above)? kai, nov'19
@Override
public TravelTime get() {
return injector.getInstance(Key.get(TravelTimeCalculator.class, Names.named(mode))).getLinkTravelTimes();
}

// the following is not there yet (leads to NPE). Presumably, the collection into the underlying multi-binder is
// done later, and until then it is only available per annotation (as above)? kai, nov'19
// @Inject Map<String,TravelTime> travelTimes ;
// @Override public TravelTime get() { return travelTimes.get( mode ) ; }
}).in( Singleton.class );
// (This used to be without "Singleton". I think that with Singleton it makes more sense, but don't know ramifications. kai, nov'19)
}).in(Singleton.class);
// (This used to be without "Singleton". I think that with Singleton it makes more sense, but don't know ramifications. kai, nov'19)
} else {

// For modes that are not analyzed, no travel time calculator is bound
// however, travel time is still provided
addTravelTimeBinding(mode).to(FreeSpeedTravelTime.class).in(Singleton.class);

}

}
} else {
Expand All @@ -88,7 +102,7 @@ public void install() {
// bind the TravelTime objects. In this case, this just passes on the same information from TravelTimeCalculator to each individual mode:
if (getConfig().travelTimeCalculator().isCalculateLinkTravelTimes()) {
// for (String mode : CollectionUtils.stringToSet(getConfig().travelTimeCalculator().getAnalyzedModesAsString() )) {
for ( String mode : getConfig().routing().getNetworkModes() ) {
for (String mode : getConfig().routing().getNetworkModes()) {
addTravelTimeBinding(mode).toProvider(ObservedLinkTravelTimes.class);
}
}
Expand All @@ -101,9 +115,12 @@ public void install() {

private static class SingleModeTravelTimeCalculatorProvider implements Provider<TravelTimeCalculator> {

@Inject TravelTimeCalculatorConfigGroup config;
@Inject EventsManager eventsManager;
@Inject Network network;
@Inject
TravelTimeCalculatorConfigGroup config;
@Inject
EventsManager eventsManager;
@Inject
Network network;

private String mode;

Expand All @@ -117,17 +134,17 @@ public TravelTimeCalculator get() {
// config.isCalculateLinkTravelTimes(), config.isCalculateLinkToLinkTravelTimes(), true, CollectionUtils.stringToSet(mode));
// eventsManager.addHandler(calculator);
// return TravelTimeCalculator.configure(calculator, config, network);
TravelTimeCalculator.Builder builder = new TravelTimeCalculator.Builder( network );
builder.setTimeslice( config.getTraveltimeBinSize() );
builder.setMaxTime( config.getMaxTime() );
builder.setCalculateLinkTravelTimes( config.isCalculateLinkTravelTimes() );
builder.setCalculateLinkToLinkTravelTimes( config.isCalculateLinkToLinkTravelTimes() );
builder.setFilterModes( true ); // no point asking the config since we are in "separateModes" anyways.
builder.setAnalyzedModes( CollectionUtils.stringToSet( mode ) );
builder.configure( config );
TravelTimeCalculator.Builder builder = new TravelTimeCalculator.Builder(network);
builder.setTimeslice(config.getTraveltimeBinSize());
builder.setMaxTime(config.getMaxTime());
builder.setCalculateLinkTravelTimes(config.isCalculateLinkTravelTimes());
builder.setCalculateLinkToLinkTravelTimes(config.isCalculateLinkToLinkTravelTimes());
builder.setFilterModes(true); // no point asking the config since we are in "separateModes" anyways.
builder.setAnalyzedModes(CollectionUtils.stringToSet(mode));
builder.configure(config);
TravelTimeCalculator calculator = builder.build();
eventsManager.addHandler( calculator );
return calculator ;
eventsManager.addHandler(calculator);
return calculator;
}
}

Expand Down
Loading

0 comments on commit e57c07e

Please sign in to comment.