61 MSLane*
const lane,
const double length,
const bool doAdd,
63 MSMoveReminder(
"meandata_" + (parent == nullptr ?
"" : parent->getID() +
"|") + (lane == nullptr ?
"NULL" : lane->getID()), lane, doAdd),
67 travelledDistance(0) { }
76#ifdef DEBUG_NOTIFY_ENTER
77 std::cout <<
"\n" <<
SIMTIME <<
" MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.
getID() <<
"' enters lane '" << enteredLane->
getID() <<
"'" << std::endl;
82 return myParent ==
nullptr || myParent->vehicleApplies(veh);
92 double leaveSpeed = newSpeed, leaveSpeedFront = newSpeed;
95 double timeOnLane =
TS;
96 double frontOnLane = oldPos > myLaneLength ? 0. :
TS;
100 double timeBeforeEnter = 0.;
101 double timeBeforeEnterBack = 0.;
102 double timeBeforeLeaveFront = newPos <= myLaneLength ?
TS : 0.;
103 double timeBeforeLeave =
TS;
106 if (oldPos < 0 && newPos >= 0) {
109 timeOnLane =
TS - timeBeforeEnter;
110 frontOnLane = timeOnLane;
118 if (oldBackPos < 0. && newBackPos > 0.) {
120 }
else if (newBackPos <= 0) {
121 timeBeforeEnterBack =
TS;
123 timeBeforeEnterBack = 0.;
127 if (newBackPos > myLaneLength
128 && oldBackPos <= myLaneLength) {
132 const double timeAfterLeave =
TS - timeBeforeLeave;
133 timeOnLane -= timeAfterLeave;
136 if (fabs(timeOnLane) < NUMERICAL_EPS) {
143 if (newPos > myLaneLength && oldPos <= myLaneLength) {
147 const double timeAfterLeave =
TS - timeBeforeLeaveFront;
148 frontOnLane -= timeAfterLeave;
150 if (fabs(frontOnLane) < NUMERICAL_EPS) {
156 assert(frontOnLane <=
TS);
157 assert(timeOnLane <=
TS);
159 if (timeOnLane < 0) {
163 if (timeOnLane == 0) {
167#ifdef DEBUG_NOTIFY_MOVE
168 std::stringstream ss;
170 <<
"lane length: " << myLaneLength
171 <<
"\noldPos: " << oldPos
172 <<
"\nnewPos: " << newPos
173 <<
"\noldPosBack: " << oldBackPos
174 <<
"\nnewPosBack: " << newBackPos
175 <<
"\ntimeBeforeEnter: " << timeBeforeEnter
176 <<
"\ntimeBeforeEnterBack: " << timeBeforeEnterBack
177 <<
"\ntimeBeforeLeaveFront: " << timeBeforeLeaveFront
178 <<
"\ntimeBeforeLeave: " << timeBeforeLeave;
179 if (!(timeBeforeLeave >=
MAX2(timeBeforeEnterBack, timeBeforeLeaveFront))
180 || !(timeBeforeEnter <=
MIN2(timeBeforeEnterBack, timeBeforeLeaveFront))) {
183 std::cout << ss.str() << std::endl;
188 assert(timeBeforeEnter <=
MIN2(timeBeforeEnterBack, timeBeforeLeaveFront));
189 assert(timeBeforeLeave >=
MAX2(timeBeforeEnterBack, timeBeforeLeaveFront));
193 double lengthOnLaneAtStepStart =
MAX2(0.,
MIN4(myLaneLength, vehLength, vehLength - (oldPos - myLaneLength), oldPos));
195 double lengthOnLaneAtStepEnd =
MAX2(0.,
MIN4(myLaneLength, vehLength, vehLength - (newPos - myLaneLength), newPos));
196 double integratedLengthOnLane = 0.;
197 if (timeBeforeEnterBack < timeBeforeLeaveFront) {
202 integratedLengthOnLane += (timeBeforeEnterBack - timeBeforeEnter) * (lengthOnLaneAtBackEnter + lengthOnLaneAtStepStart) * 0.5;
205 integratedLengthOnLane += (timeBeforeLeaveFront - timeBeforeEnterBack) * vehLength;
207 integratedLengthOnLane += (timeBeforeLeave - timeBeforeLeaveFront) * (vehLength + lengthOnLaneAtStepEnd) * 0.5;
208 }
else if (timeBeforeEnterBack >= timeBeforeLeaveFront) {
211 double lengthOnLaneAtLeaveFront;
212 if (timeBeforeLeaveFront == timeBeforeEnter) {
214 lengthOnLaneAtLeaveFront = lengthOnLaneAtStepStart;
215 }
else if (timeBeforeLeaveFront == timeBeforeLeave) {
217 lengthOnLaneAtLeaveFront = lengthOnLaneAtStepEnd;
219 lengthOnLaneAtLeaveFront = myLaneLength;
221#ifdef DEBUG_NOTIFY_MOVE
222 std::cout <<
"lengthOnLaneAtLeaveFront=" << lengthOnLaneAtLeaveFront << std::endl;
225 integratedLengthOnLane += (timeBeforeLeaveFront - timeBeforeEnter) * (lengthOnLaneAtLeaveFront + lengthOnLaneAtStepStart) * 0.5;
227 integratedLengthOnLane += (timeBeforeEnterBack - timeBeforeLeaveFront) * lengthOnLaneAtLeaveFront;
229 integratedLengthOnLane += (timeBeforeLeave - timeBeforeEnterBack) * (lengthOnLaneAtLeaveFront + lengthOnLaneAtStepEnd) * 0.5;
232 double meanLengthOnLane = integratedLengthOnLane /
TS;
233#ifdef DEBUG_NOTIFY_MOVE
234 std::cout <<
"Calculated mean length on lane '" << myLane->getID() <<
"' in last step as " << meanLengthOnLane
235 <<
"\nlengthOnLaneAtStepStart=" << lengthOnLaneAtStepStart <<
", lengthOnLaneAtStepEnd=" << lengthOnLaneAtStepEnd <<
", integratedLengthOnLane=" << integratedLengthOnLane
244 :
MAX2(0.,
MIN2(newPos, myLaneLength) -
MAX2(oldPos, 0.));
254 notifyMoveInternal(veh, frontOnLane, timeOnLane, (enterSpeed + leaveSpeedFront) / 2., (enterSpeed + leaveSpeed) / 2., travelledDistanceFrontOnLane, travelledDistanceVehicleOnLane, meanLengthOnLane);
270 return sampleSeconds == 0;
281 return sampleSeconds;
302 if (!myCurrentData.empty()) {
303 myCurrentData.pop_front();
306 myCurrentData.push_back(std::make_shared<TrackerEntry>(myParent->createValues(myLane, myLaneLength,
false)));
313 myCurrentData.front()->myValues->
addTo(val);
319 myTrackedData[&veh]->myValues->notifyMoveInternal(veh, frontOnLane, timeOnLane, meanSpeedFrontOnLane, meanSpeedVehicleOnLane, travelledDistanceFrontOnLane, travelledDistanceVehicleOnLane, meanLengthOnLane);
326 myTrackedData[&veh]->myNumVehicleLeft++;
328 return myTrackedData[&veh]->myValues->notifyLeave(veh, lastPos, reason);
334#ifdef DEBUG_NOTIFY_ENTER
335 std::cout <<
"\n" <<
SIMTIME <<
" MSMeanData::MeanDataValueTracker: veh '" << veh.
getID() <<
"' enters lane '" << enteredLane->
getID() <<
"'" << std::endl;
342 if (myParent->vehicleApplies(veh) && myTrackedData.find(&veh) == myTrackedData.end()) {
343 myTrackedData[&veh] = myCurrentData.back();
344 myTrackedData[&veh]->myNumVehicleEntered++;
345 if (!myTrackedData[&veh]->myValues->notifyEnter(veh, reason)) {
346 myTrackedData[&veh]->myNumVehicleLeft++;
347 myTrackedData.erase(&veh);
358 return myCurrentData.front()->myValues->isEmpty();
367 const double speedLimit,
368 const double defaultTravelTime,
370 myCurrentData.front()->myValues->write(dev, attributeMask, period, numLanes, speedLimit,
372 myCurrentData.front()->myNumVehicleEntered);
379 for (
const auto& it : myCurrentData) {
380 if (it->myNumVehicleEntered == it->myNumVehicleLeft) {
392 return myCurrentData.front()->myValues->getSamples();
401 const bool useLanes,
const std::string& excludeEmpty,
const bool withInternal,
402 const bool trackVehicles,
403 const int detectPersons,
404 const double maxTravelTime,
405 const double minSamples,
406 const std::string& vTypes,
407 const std::string& writeAttributes,
408 const std::vector<MSEdge*>& edges,
425 if (excludeEmpty ==
"default" || excludeEmpty ==
"defaults") {
427 }
else if (excludeEmpty ==
"modified") {
452 myMeasures.push_back(std::vector<MeanDataValues*>());
454 const std::vector<MSLane*>& lanes = edge->getLanes();
458 for (
MSLane*
const lane : lanes) {
459 data =
createValues(lane, lanes[0]->getLength(),
false);
462 while (s !=
nullptr) {
474 data =
createValues(
nullptr, lanes[0]->getLength(),
false);
479 while (s !=
nullptr) {
492 for (
MSLane*
const lane : lanes) {
495 lane->addMoveReminder(
myMeasures.back().back());
506 if (e->isTazConnector()) {
515 for (std::vector<std::vector<MeanDataValues*> >::const_iterator i =
myMeasures.begin(); i !=
myMeasures.end(); ++i) {
516 for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
527 MSEdgeVector::iterator edge =
myEdges.begin();
528 for (std::vector<std::vector<MeanDataValues*> >::const_iterator i =
myMeasures.begin(); i !=
myMeasures.end(); ++i, ++edge) {
531 while (s !=
nullptr) {
540 for (std::vector<std::vector<MeanDataValues*> >::const_iterator i =
myMeasures.begin(); i !=
myMeasures.end(); ++i) {
541 for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
550 return edge->
getID();
557 throw ProcessError(
TL(
"aggregated meanData output not yet implemented for trackVehicles"));
560 double edgeLengthSum = 0;
565 edgeLengthSum += edge->getLength();
566 laneNumber += edge->getNumDrivingLanes();
567 speedSum += edge->getSpeedLimit();
568 totalTT += edge->getLength() / edge->getSpeedLimit();
571 for (
const std::vector<MeanDataValues*>& edgeValues :
myMeasures) {
573 meanData->addTo(*sumData);
580 for (
int i = 0; i < (int)
myEdges.size(); i++) {
582 std::vector<MeanDataValues*>& edgeValues =
myMeasures[i];
584 while (s !=
nullptr) {
587 meanData->addTo(*sumData);
610 throw ProcessError(
TL(
"aggregated meanData output not yet implemented for trackVehicles"));
614 double edgeLengthSum = 0;
618 std::set<const MSEdge*> connected;
619 for (
const MSEdge* edge : taz->getSuccessors()) {
620 connected.insert(edge);
622 for (
const MSEdge* edge : taz->getPredecessors()) {
623 connected.insert(edge);
625 for (
const MSEdge* edge : connected) {
626 edgeLengthSum += edge->getLength();
627 laneNumber += edge->getNumDrivingLanes();
628 speedSum += edge->getSpeedLimit();
629 totalTT += edge->getLength() / edge->getSpeedLimit();
632 for (
int i = 0; i < (int)
myEdges.size(); i++) {
634 if (connected.count(edge) != 0) {
635 std::vector<MeanDataValues*>& edgeValues =
myMeasures[i];
638 while (s !=
nullptr) {
641 meanData->addTo(*sumData);
647 meanData->
addTo(*sumData);
662 for (
const std::vector<MeanDataValues*>& edgeValues :
myMeasures) {
673 const std::vector<MeanDataValues*>& edgeValues,
679 while (s !=
nullptr) {
704 if (!laneData->isEmpty() || (
myPrintModified && laneData->getLane()->isSpeedModified())) {
714 const MSLane*
const lane = laneData->getLane();
721 laneData->reset(
true);
736 meanData.
reset(
true);
742 laneData->addTo(*sumData);
750 if (writeCheck || !sumData->
isEmpty()) {
784 for (std::vector<std::vector<MeanDataValues*> >::const_iterator i =
myMeasures.begin(); i !=
myMeasures.end(); ++i) {
785 for (std::vector<MeanDataValues*>::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
796 const bool partialInterval = startTime <
myInitTime;
800 if (partialInterval) {
803 while (numReady-- > 0) {
815 MSEdgeVector::const_iterator edge =
myEdges.begin();
816 for (
const std::vector<MeanDataValues*>& measures :
myMeasures) {
817 writeEdge(dev, measures, *edge, startTime, stopTime);
841const std::vector<MSMeanData::MeanDataValues*>*
852const std::vector<MSMoveReminder*>
854 std::vector<MSMoveReminder*> result;
856 result.insert(result.end(), vec.begin(), vec.end());
#define WRITE_ERRORF(...)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_EDGE
begin/end of the description of an edge
std::bitset< 96 > SumoXMLAttrMask
AggregateType
Numbers representing special SUMO-XML-attribute values Information on edgeData/laneData output should...
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_SAMPLEDSECONDS
MSMeanData_Net.
T MIN4(T a, T b, T c, T d)
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
A single mesoscopic segment (cell)
void addDetector(MSMoveReminder *data, int queueIndex=-1)
Adds a data collector for a detector to this segment.
void prepareDetectorForWriting(MSMoveReminder &data, int queueIndex=-1)
Removes a data collector for a detector from this segment.
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
static double speedAfterTime(const double t, const double oldSpeed, const double dist)
Calculates the speed after a time t \in [0,TS] given the initial speed and the distance traveled in a...
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
Base of value-generating classes (detectors)
bool detectsPersons() const
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
int getNumDrivingLanes() const
return the number of lanes that permit non-weak modes if the edge allows non weak modes and the numbe...
double getSpeedLimit() const
Returns the speed limit of the edge @caution The speed limit of the first lane is retured; should pro...
double getLength() const
return the length of the edge
static MELoop * gMesoNet
mesoscopic simulation infrastructure
static bool gSemiImplicitEulerUpdate
static int gNumSimThreads
how many threads to use for simulation
Representation of a lane in the micro simulation.
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
double getLength() const
Returns the lane's length.
bool isSpeedModified() const
Data structure for mean (aggregated) edge/lane values for tracked vehicles.
double getSamples() const
Returns the number of collected sample seconds.
MeanDataValueTracker(MSLane *const lane, const double length, const MSMeanData *const parent)
Constructor.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder's lane.
void addTo(MSMeanData::MeanDataValues &val) const
Add the values of this to the given one and store them there.
void notifyMoveInternal(const SUMOTrafficObject &veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane)
Internal notification about the vehicle moves.
void write(OutputDevice &dev, const SumoXMLAttrMask &attributeMask, const SUMOTime period, const int numLanes, const double speedLimit, const double defaultTravelTime, const int numVehicles=-1) const
Writes output values into the given stream.
std::list< std::shared_ptr< TrackerEntry > > myCurrentData
The currently active meandata "intervals".
virtual ~MeanDataValueTracker()
Destructor.
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Computes current values and adds them to their sums.
bool isEmpty() const
Returns whether any data was collected.
void reset(bool afterWrite)
Resets values so they may be used for the next interval.
Data structure for mean (aggregated) edge/lane values.
virtual void addTo(MeanDataValues &val) const =0
Add the values of this to the given one and store them there.
virtual bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle leaves the reminder's lane.
MeanDataValues(MSLane *const lane, const double length, const bool doAdd, const MSMeanData *const parent)
Constructor.
virtual void write(OutputDevice &dev, const SumoXMLAttrMask &attributeMask, const SUMOTime period, const int numLanes, const double speedLimit, const double defaultTravelTime, const int numVehicles=-1) const =0
Writes output values into the given stream.
virtual void update()
Called if a per timestep update is needed. Default does nothing.
virtual bool isEmpty() const
Returns whether any data was collected.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks whether the reminder still has to be notified about the vehicle moves.
virtual ~MeanDataValues()
Destructor.
virtual void reset(bool afterWrite=false)=0
Resets values so they may be used for the next interval.
virtual bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called if the vehicle enters the reminder's lane.
virtual double getSamples() const
Returns the number of collected sample seconds.
Data collector for edges/lanes.
virtual MSMeanData::MeanDataValues * createValues(MSLane *const lane, const double length, const bool doAdd) const =0
Create an instance of MeanDataValues.
void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes collected values into the given stream.
virtual void writePrefix(OutputDevice &dev, const MeanDataValues &values, const SumoXMLTag tag, const std::string id) const
Writes the surrounding element into the given stream.
const bool myDumpInternal
Whether internal lanes/edges shall be written.
bool myPrintDefaults
Whether empty lanes/edges shall be written with default values.
const AggregateType myAggregate
whether the data for all edges shall be aggregated
const SUMOTime myDumpBegin
The first and the last time step to write information (-1 indicates always)
virtual void detectorUpdate(const SUMOTime step)
Updates the detector.
virtual ~MSMeanData()
Destructor.
MSMeanData(const std::string &id, const SUMOTime dumpBegin, const SUMOTime dumpEnd, const bool useLanes, const std::string &excludeEmpty, const bool withInternal, const bool trackVehicles, const int detectPersons, const double minSamples, const double maxTravelTime, const std::string &vTypes, const std::string &writeAttributes, const std::vector< MSEdge * > &edges, AggregateType aggregate)
Constructor.
void writeAggregated(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes aggregated data of all edge values into the given stream.
void init()
Adds the value collectors to all relevant edges.
const double myMinSamples
the minimum sample seconds
void resetOnly(SUMOTime stopTime)
Resets network value in order to allow processing of the next interval.
void writeAggregatedTAZ(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes aggregated data for each TAZ into the given stream.
std::map< const MSEdge *, int > myEdgeIndex
The index in myEdges / myMeasures.
const SumoXMLAttrMask myWrittenAttributes
bit mask for checking attributes to be written
const bool myAmEdgeBased
Information whether the output shall be edge-based (not lane-based)
SUMOTime myInitTime
time at which init was called();
const double myMaxTravelTime
the maximum travel time to write
bool myDumpEmpty
Whether empty lanes/edges shall be written.
std::list< std::pair< SUMOTime, SUMOTime > > myPendingIntervals
The intervals for which output still has to be generated (only in the tracking case)
const std::vector< MeanDataValues * > * getEdgeValues(const MSEdge *edge) const
void writeEdge(OutputDevice &dev, const std::vector< MeanDataValues * > &edgeValues, const MSEdge *const edge, SUMOTime startTime, SUMOTime stopTime)
Writes edge values into the given stream.
virtual std::string getEdgeID(const MSEdge *const edge)
Return the relevant edge id.
virtual void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using "netstats" as root element.
MSEdgeVector myEdges
The corresponding first edges.
const std::vector< MSMoveReminder * > getReminders() const
retrieve all MeanDataValues
virtual void openInterval(OutputDevice &dev, const SUMOTime startTime, const SUMOTime stopTime)
Writes the interval opener.
bool myPrintModified
Whether only empty lanes/edges which have been modified shall be written.
std::vector< std::vector< MeanDataValues * > > myMeasures
Value collectors; sorted by edge, then by lane.
const bool myTrackVehicles
Whether vehicles are tracked.
Something on a lane to be noticed about vehicle movement.
void setDescription(const std::string &description)
Notification
Definition of a vehicle state.
@ NOTIFICATION_SEGMENT
The vehicle changes the segment (meso only)
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
virtual bool skipFinalReset() const
gui may prevent final meanData reset to keep live data visible
MSEdgeControl & getEdgeControl()
Returns the edge control.
double getLength() const
Get vehicle's length [m].
std::string myID
The name of the object.
void addTo(const StoringVisitor &cont) const
Adds this object to the given container.
const std::string & getID() const
Returns the id.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
OutputDevice & writeOptionalAttr(const SumoXMLAttr attr, const T &val, const SumoXMLAttrMask &attributeMask, const bool isNull=false)
writes a named attribute unless filtered
Representation of a vehicle, person, or container.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual double getPreviousSpeed() const =0
Returns the object's previous speed.
virtual bool hasArrived() const =0
Returns whether this object has arrived.
A scoped lock which only triggers on condition.
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
#define UNUSED_PARAMETER(x)