1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2012-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    MSQueueExport.cpp
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Mario Krumnow
14 /// @author  Michael Behrisch
15 /// @date    2012-04-26
16 /// @version $Id$
17 ///
18 // Export the queueing length in front of a junction (very experimental!)
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <microsim/MSEdgeControl.h>
28 #include <microsim/MSEdge.h>
29 #include <microsim/MSLane.h>
30 #include <microsim/MSGlobals.h>
31 #include <utils/iodevices/OutputDevice.h>
32 #include "MSQueueExport.h"
33 #include <microsim/MSNet.h>
34 #include <microsim/MSVehicle.h>
35 
36 
37 // ===========================================================================
38 // method definitions
39 // ===========================================================================
40 void
write(OutputDevice & of,SUMOTime timestep)41 MSQueueExport::write(OutputDevice& of, SUMOTime timestep) {
42     of.openTag("data").writeAttr("timestep", time2string(timestep));
43     writeEdge(of);
44     of.closeTag();
45 }
46 
47 
48 void
writeEdge(OutputDevice & of)49 MSQueueExport::writeEdge(OutputDevice& of) {
50     of.openTag("lanes");
51     MSEdgeControl& ec = MSNet::getInstance()->getEdgeControl();
52     const MSEdgeVector& edges = ec.getEdges();
53     for (MSEdgeVector::const_iterator e = edges.begin(); e != edges.end(); ++e) {
54         MSEdge& edge = **e;
55         const std::vector<MSLane*>& lanes = edge.getLanes();
56         for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
57             writeLane(of, **lane);
58         }
59     }
60     of.closeTag();
61 }
62 
63 
64 void
writeLane(OutputDevice & of,const MSLane & lane)65 MSQueueExport::writeLane(OutputDevice& of, const MSLane& lane) {
66     // maximum of all vehicle waiting times
67     double queueing_time = 0.0;
68     // back of last stopped vehicle (XXX does not check for continuous queue)
69     double queueing_length = 0.0;
70     // back of last slow vehicle (XXX does not check for continuous queue)
71     double queueing_length2 = 0.0;
72     const double threshold_velocity = 5 / 3.6; // slow
73 
74     if (!lane.empty()) {
75         for (MSLane::VehCont::const_iterator it_veh = lane.myVehicles.begin(); it_veh != lane.myVehicles.end(); ++it_veh) {
76             const MSVehicle& veh = **it_veh;
77             if (!veh.isOnRoad()) {
78                 continue;
79             }
80 
81             if (veh.getWaitingSeconds() > 0) {
82                 queueing_time = MAX2(veh.getWaitingSeconds(), queueing_time);
83                 const double veh_back_to_lane_end = (lane.getLength() - veh.getPositionOnLane()) + veh.getVehicleType().getLength();
84                 queueing_length = MAX2(veh_back_to_lane_end, queueing_length);
85             }
86 
87             //Experimental
88             if (veh.getSpeed() < (threshold_velocity) && (veh.getPositionOnLane() > (veh.getLane()->getLength()) * 0.25)) {
89                 const double veh_back_to_lane_end = (lane.getLength() - veh.getPositionOnLane()) + veh.getVehicleType().getLength();
90                 queueing_length2 = MAX2(veh_back_to_lane_end, queueing_length2);
91             }
92         }
93     }
94 
95     //Output
96     if (queueing_length > 1 || queueing_length2 > 1) {
97         of.openTag("lane").writeAttr("id", lane.getID()).writeAttr("queueing_time", queueing_time).writeAttr("queueing_length", queueing_length);
98         of.writeAttr("queueing_length_experimental", queueing_length2).closeTag();
99     }
100 }
101 
102 
103 /****************************************************************************/
104