MATSIM
SimpleAdaptiveSignal.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: kai
3  * SimpleAdaptiveSignalEngine.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2012 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 
21 package tutorial.programming.simpleAdaptiveSignalEngine;
22 
23 import java.io.IOException;
24 import java.io.Writer;
25 import java.util.ArrayList;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Queue;
29 
30 import javax.inject.Inject;
31 
32 import org.apache.log4j.Logger;
33 import org.matsim.api.core.v01.Id;
34 import org.matsim.api.core.v01.Scenario;
44 import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent;
45 import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent;
51 import org.matsim.core.utils.io.IOUtils;
52 
64 class SimpleAdaptiveSignal implements MobsimBeforeSimStepListener, MobsimInitializedListener, BasicEventHandler {
65 
66  @Inject Scenario scenario;
67 
68  private Queue<Double> vehicleExitTimesOnLink5 = new LinkedList<>() ;
69  private long cnt4 = 0 ;
70  private long cnt5 = 0 ;
71  private OutputDirectoryHierarchy controlerIO;
72  private Writer out ;
73 
74  private SignalizeableItem signalLink4;
75  private SignalizeableItem signalLink5;
76 
77  class Result {
78  int iteration ;
79  double shareUp ;
80  double shareDown ;
81  } ;
82 
83  private List<Result> results = new ArrayList<>() ;
84 
85  @Inject
86  public SimpleAdaptiveSignal(OutputDirectoryHierarchy controlerIO) {
87  this.controlerIO = controlerIO ;
88  }
89 
90  @Override
91  public void notifyMobsimInitialized(MobsimInitializedEvent e) {
92  Netsim mobsim = (Netsim) e.getQueueSimulation() ;
93  signalLink4 = (SignalizeableItem) mobsim.getNetsimNetwork().getNetsimLink(Id.createLinkId("4")) ;
94  signalLink5 = (SignalizeableItem) mobsim.getNetsimNetwork().getNetsimLink(Id.createLinkId("5")) ;
95  signalLink4.setSignalized(true);
96  signalLink5.setSignalized(true);
97  }
98 
99  @Override
100  public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent e) {
101  double now = e.getSimulationTime();
102 
103  // switch the signal on link 5 to green when vehicles want to leave link 5 now
104  final Double dpTime = this.vehicleExitTimesOnLink5.peek();
105  if ( dpTime !=null && dpTime < now ) {
106  signalLink4.setSignalStateAllTurningMoves(SignalGroupState.RED) ;
107  signalLink5.setSignalStateAllTurningMoves(SignalGroupState.GREEN) ;
108  } else {
109  signalLink4.setSignalStateAllTurningMoves(SignalGroupState.GREEN) ;
110  signalLink5.setSignalStateAllTurningMoves(SignalGroupState.RED) ;
111  }
112 
113 // /* alternative approach: switch between the signals every other second
114 // * independent of link counts and vehicle behavior */
115 // if ( now<20.*60 && (long)now%2==0 ) {
116 // link4.setSignalStateAllTurningMoves(SignalGroupState.RED) ;
117 // link5.setSignalStateAllTurningMoves(SignalGroupState.GREEN);
118 // } else {
119 // link4.setSignalStateAllTurningMoves(SignalGroupState.GREEN) ;
120 // link5.setSignalStateAllTurningMoves(SignalGroupState.RED);
121 // }
122  }
123 
124  @Override
125  public void handleEvent(Event event) {
126  switch (event.getEventType()){
127  /* store the desired link exit time when a vehicle is entering a link
128  * and count the vehicles */
129  case VehicleEntersTrafficEvent.EVENT_TYPE:
130  // for the first link every vehicle needs one second without delay
131  storeDesiredExitTimeAndCountVehiclesOnLink(((HasLinkId) event).getLinkId(), event.getTime() + 1.);
132  break;
133  case LinkEnterEvent.EVENT_TYPE:
134  // calculate earliest link exit time
135  Link link5 = scenario.getNetwork().getLinks().get(Id.createLinkId(5));
136  double freespeedTt = link5.getLength() / link5.getFreespeed();
137  // this is the earliest time where matsim sets the agent to the next link
138  double matsimFreespeedTT = Math.floor(freespeedTt + 1);
139  storeDesiredExitTimeAndCountVehiclesOnLink(((HasLinkId) event).getLinkId(), event.getTime() + matsimFreespeedTT);
140  break;
141 
142  // remove the desired exit time from the collection when the vehicle leaves the link
143  case LinkLeaveEvent.EVENT_TYPE:
144  case VehicleLeavesTrafficEvent.EVENT_TYPE:
145  if ( ((HasLinkId) event).getLinkId().equals(Id.create("5", Link.class)) ) {
146  this.vehicleExitTimesOnLink5.remove() ;
147  }
148  break;
149  default:
150  break;
151  }
152  }
153 
154  private void storeDesiredExitTimeAndCountVehiclesOnLink(Id<Link> linkId, double desiredExitTime) {
155  if ( linkId.equals(Id.createLinkId("5")) ) {
156  // remember the desired exit time (1 second after entering traffic)
157  this.vehicleExitTimesOnLink5.add( desiredExitTime ) ;
158  // every vehicle that enters the link increases the counter:
159  cnt5++ ;
160  } else if ( linkId.equals(Id.createLinkId("4")) ) {
161  /* in this example we do not want to know the exit time of vehicles on link 4
162  * but we still count the vehicles on it */
163  cnt4++ ;
164  }
165  }
166 
167  @Override
168  public void reset(int iteration) {
169  double sum = cnt4 + cnt5 ;
170  Logger.getLogger(this.getClass()).warn("iteration: " + iteration + " cnt4: " + (cnt4/sum) + " cnt5: " + (cnt5/sum) ) ;
171 
172  Result result = new Result() ;
173  result.iteration = iteration ;
174  result.shareUp = cnt5/sum ;
175  result.shareDown = cnt4/sum ;
176  results.add(result) ;
177 
178  cnt4 = 0 ;
179  cnt5 = 0 ;
180 
181  if ( out==null ) {
182  out = IOUtils.getBufferedWriter(controlerIO.getOutputFilename("split.txt")) ;
183  }
184 
185  try {
186  out.write( result.iteration + "\t" + result.shareUp + "\t" + result.shareDown + "\n" ) ;
187  out.flush() ;
188  } catch (IOException e) {
189  e.printStackTrace();
190  }
191  }
192 
193  static public void main( String[] args ) {
194  RunSimpleAdaptiveSignalExample.main( args ) ;
195  }
196 }
void notifyMobsimBeforeSimStep(final MobsimBeforeSimStepEvent e)