Eclipse SUMO - Simulation of Urban MObility
MSFCDExport.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2012-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
21 // Realises dumping Floating Car Data (FCD) Data
22 /****************************************************************************/
23 #include <config.h>
24 
28 #include <utils/geom/GeomHelper.h>
30 #include <libsumo/Helper.h>
33 #include <microsim/MSEdgeControl.h>
34 #include <microsim/MSEdge.h>
35 #include <microsim/MSLane.h>
36 #include <microsim/MSGlobals.h>
37 #include <microsim/MSNet.h>
38 #include <microsim/MSVehicle.h>
43 #include "MSFCDExport.h"
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
49 void
50 MSFCDExport::write(OutputDevice& of, SUMOTime timestep, bool elevation) {
52  const SUMOTime period = string2time(oc.getString("device.fcd.period"));
53  const SUMOTime begin = string2time(oc.getString("device.fcd.begin"));
54  if ((period > 0 && (timestep - begin) % period != 0) || timestep < begin) {
55  return;
56  }
58  const bool maskSet = oc.isSet("fcd-output.attributes");
59  const bool useGeo = oc.getBool("fcd-output.geo");
60  const bool signals = oc.getBool("fcd-output.signals") || (maskSet && of.useAttribute(SUMO_ATTR_SIGNALS, mask));
61  const bool writeAccel = oc.getBool("fcd-output.acceleration") || (maskSet && of.useAttribute(SUMO_ATTR_ACCELERATION, mask));
62  const bool writeDistance = oc.getBool("fcd-output.distance") || (maskSet && of.useAttribute(SUMO_ATTR_DISTANCE, mask));
63  const double maxLeaderDistance = oc.getFloat("fcd-output.max-leader-distance");
64  std::vector<std::string> params = oc.getStringVector("fcd-output.params");
65  MSNet* net = MSNet::getInstance();
67  const double radius = oc.getFloat("device.fcd.radius");
68  const bool filter = MSDevice_FCD::getEdgeFilter().size() > 0;
69  const bool shapeFilter = MSDevice_FCD::hasShapeFilter();
70  std::set<const Named*> inRadius;
71  if (radius > 0) {
72  // collect all vehicles in radius around equipped vehicles
73  for (MSVehicleControl::constVehIt it = vc.loadedVehBegin(); it != vc.loadedVehEnd(); ++it) {
74  const SUMOVehicle* veh = it->second;
75  if (isVisible(veh) && hasOwnOutput(veh, filter, shapeFilter)) {
76  PositionVector shape;
77  shape.push_back(veh->getPosition());
80  }
81  }
82  }
83 
84  of.openTag("timestep").writeAttr(SUMO_ATTR_TIME, time2string(timestep));
85  for (MSVehicleControl::constVehIt it = vc.loadedVehBegin(); it != vc.loadedVehEnd(); ++it) {
86  const SUMOVehicle* veh = it->second;
87  const MSVehicle* microVeh = dynamic_cast<const MSVehicle*>(veh);
88  const MSBaseVehicle* baseVeh = dynamic_cast<const MSBaseVehicle*>(veh);
89  if (isVisible(veh)) {
90  const bool hasOutput = hasOwnOutput(veh, filter, shapeFilter, (radius > 0 && inRadius.count(veh) > 0));
91  if (hasOutput) {
92  Position pos = veh->getPosition();
93  if (useGeo) {
96  }
98  of.writeAttr(SUMO_ATTR_ID, veh->getID());
99  of.writeOptionalAttr(SUMO_ATTR_X, pos.x(), mask);
100  of.writeOptionalAttr(SUMO_ATTR_Y, pos.y(), mask);
102  if (elevation) {
103  of.writeOptionalAttr(SUMO_ATTR_Z, pos.z(), mask);
104  }
107  of.writeOptionalAttr(SUMO_ATTR_SPEED, veh->getSpeed(), mask);
109  if (microVeh != nullptr) {
110  of.writeOptionalAttr(SUMO_ATTR_LANE, microVeh->getLane()->getID(), mask);
111  } else {
112  of.writeOptionalAttr(SUMO_ATTR_EDGE, veh->getEdge()->getID(), mask);
113  }
114  of.writeOptionalAttr(SUMO_ATTR_SLOPE, veh->getSlope(), mask);
115  if (microVeh != nullptr) {
116  if (signals) {
117  of.writeOptionalAttr(SUMO_ATTR_SIGNALS, toString(microVeh->getSignals()), mask);
118  }
119  if (writeAccel) {
121  if (MSGlobals::gSublane) {
123  }
124  }
125  }
126  if (writeDistance) {
127  double lanePos = veh->getPositionOnLane();
128  if (microVeh != nullptr && microVeh->getLane()->isInternal()) {
129  lanePos = microVeh->getRoute().getDistanceBetween(0., lanePos, microVeh->getEdge()->getLanes()[0], microVeh->getLane(),
130  microVeh->getRoutePosition());
131  }
132  of.writeOptionalAttr(SUMO_ATTR_DISTANCE, veh->getEdge()->getDistanceAt(lanePos), mask);
133  }
136  if (microVeh != nullptr) {
138  }
139  if (maxLeaderDistance >= 0 && microVeh != nullptr) {
140  std::pair<const MSVehicle* const, double> leader = microVeh->getLeader(maxLeaderDistance);
141  if (leader.first != nullptr) {
142  of.writeOptionalAttr(SUMO_ATTR_LEADER_ID, toString(leader.first->getID()), mask);
143  of.writeOptionalAttr(SUMO_ATTR_LEADER_SPEED, toString(leader.first->getSpeed()), mask);
144  of.writeOptionalAttr(SUMO_ATTR_LEADER_GAP, toString(leader.second + microVeh->getVehicleType().getMinGap()), mask);
145  } else {
149  }
150  }
151  for (const std::string& key : params) {
152  std::string error;
153  const std::string value = baseVeh->getPrefixedParameter(key, error);
154  if (value != "") {
156  }
157  }
158  if (of.useAttribute(SUMO_ATTR_ARRIVALDELAY, mask)) {
159  double arrivalDelay = baseVeh->getStopArrivalDelay();
160  if (arrivalDelay == INVALID_DOUBLE) {
161  // no upcoming stop also means that there is no delay
162  arrivalDelay = 0;
163  }
164  of.writeOptionalAttr(SUMO_ATTR_ARRIVALDELAY, arrivalDelay, mask);
165  }
166  of.closeTag();
167  }
168  // write persons and containers
169  const MSEdge* edge = microVeh == nullptr ? veh->getEdge() : &veh->getLane()->getEdge();
170 
171  const std::vector<MSTransportable*>& persons = veh->getPersons();
172  for (MSTransportable* person : persons) {
173  writeTransportable(of, edge, person, veh, filter, shapeFilter, inRadius.count(person) > 0, SUMO_TAG_PERSON, useGeo, elevation, mask);
174  }
175  const std::vector<MSTransportable*>& containers = veh->getContainers();
176  for (MSTransportable* container : containers) {
177  writeTransportable(of, edge, container, veh, filter, shapeFilter, inRadius.count(container) > 0, SUMO_TAG_CONTAINER, useGeo, elevation, mask);
178  }
179  }
180  }
181  if (net->hasPersons() && net->getPersonControl().hasTransportables()) {
182  // write persons
183  MSEdgeControl& ec = net->getEdgeControl();
184  const MSEdgeVector& edges = ec.getEdges();
185  for (MSEdgeVector::const_iterator e = edges.begin(); e != edges.end(); ++e) {
186  if (filter && MSDevice_FCD::getEdgeFilter().count(*e) == 0) {
187  continue;
188  }
189  const std::vector<MSTransportable*>& persons = (*e)->getSortedPersons(timestep);
190  for (MSTransportable* person : persons) {
191  writeTransportable(of, *e, person, nullptr, filter, shapeFilter, inRadius.count(person) > 0, SUMO_TAG_PERSON, useGeo, elevation, mask);
192  }
193  }
194  }
195  if (net->hasContainers() && net->getContainerControl().hasTransportables()) {
196  // write containers
197  MSEdgeControl& ec = net->getEdgeControl();
198  const std::vector<MSEdge*>& edges = ec.getEdges();
199  for (std::vector<MSEdge*>::const_iterator e = edges.begin(); e != edges.end(); ++e) {
200  if (filter && MSDevice_FCD::getEdgeFilter().count(*e) == 0) {
201  continue;
202  }
203  const std::vector<MSTransportable*>& containers = (*e)->getSortedContainers(timestep);
204  for (MSTransportable* container : containers) {
205  writeTransportable(of, *e, container, nullptr, filter, shapeFilter, inRadius.count(container) > 0, SUMO_TAG_CONTAINER, useGeo, elevation, mask);
206  }
207  }
208  }
209  of.closeTag();
210 }
211 
212 bool
214  return veh->isOnRoad() || veh->isParking() || veh->isRemoteControlled();
215 }
216 
217 bool
218 MSFCDExport::hasOwnOutput(const SUMOVehicle* veh, bool filter, bool shapeFilter, bool isInRadius) {
219  return ((!filter || MSDevice_FCD::getEdgeFilter().count(veh->getEdge()) > 0)
220  && (!shapeFilter || MSDevice_FCD::shapeFilter(veh))
221  && ((veh->getDevice(typeid(MSDevice_FCD)) != nullptr) || isInRadius));
222 }
223 
224 bool
225 MSFCDExport::hasOwnOutput(const MSTransportable* p, bool filter, bool shapeFilter, bool isInRadius) {
226  return ((!filter || MSDevice_FCD::getEdgeFilter().count(p->getEdge()) > 0)
227  && (!shapeFilter || MSDevice_FCD::shapeFilter(p))
228  && ((p->getDevice(typeid(MSTransportableDevice_FCD)) != nullptr) || isInRadius));
229 }
230 
231 void
233  bool filter, bool shapeFilter, bool inRadius,
234  SumoXMLTag tag, bool useGeo, bool elevation, SumoXMLAttrMask mask) {
235  if (!hasOwnOutput(p, filter, shapeFilter, inRadius)) {
236  return;
237  }
238  Position pos = p->getPosition();
239  if (useGeo) {
242  }
243  of.openTag(tag);
244  of.writeAttr(SUMO_ATTR_ID, p->getID());
245  of.writeOptionalAttr(SUMO_ATTR_X, pos.x(), mask);
246  of.writeOptionalAttr(SUMO_ATTR_Y, pos.y(), mask);
247  if (elevation) {
248  of.writeOptionalAttr(SUMO_ATTR_Z, pos.z(), mask);
249  }
253  of.writeOptionalAttr(SUMO_ATTR_EDGE, e->getID(), mask);
254  of.writeOptionalAttr(SUMO_ATTR_SLOPE, e->getLanes()[0]->getShape().slopeDegreeAtOffset(p->getEdgePos()), mask);
255  of.writeOptionalAttr(SUMO_ATTR_VEHICLE, v == nullptr ? "" : v->getID(), mask);
256  of.closeTag();
257 }
258 
259 
260 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_VEHICLE
description of a vehicle
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_PERSON
std::bitset< 96 > SumoXMLAttrMask
@ SUMO_ATTR_LANE
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_Y
@ SUMO_ATTR_Z
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_X
@ SUMO_ATTR_POSITION_LAT
@ SUMO_ATTR_ODOMETER
@ SUMO_ATTR_SIGNALS
@ SUMO_ATTR_LEADER_GAP
@ SUMO_ATTR_ACCELERATION_LAT
@ SUMO_ATTR_ARRIVALDELAY
@ SUMO_ATTR_SLOPE
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_LEADER_SPEED
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_VEHICLE
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_SPEED_LAT
@ SUMO_ATTR_LEADER_ID
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_TIME
trigger: the time of the step
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:26
int gPrecisionGeo
Definition: StdDefs.cpp:27
const double INVALID_DOUBLE
invalid double
Definition: StdDefs.h:64
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:191
double getAccelerationLat() const
return the lateral speed of the current lane change maneuver
double getSpeedLat() const
return the lateral speed of the current lane change maneuver
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:55
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
std::string getPrefixedParameter(const std::string &key, std::string &error) const
retrieve parameters of devices, models and the vehicle itself
virtual double getStopArrivalDelay() const
Returns the estimated public transport stop arrival delay in seconds.
int getRoutePosition() const
return index of edge within route
const MSRoute & getRoute() const
Returns the current route.
A device which collects info on the vehicle trip (mainly on departure and arrival)
Definition: MSDevice_FCD.h:47
static const std::set< const MSEdge * > & getEdgeFilter()
Definition: MSDevice_FCD.h:83
static bool hasShapeFilter()
is there a filter based on shapes?
Definition: MSDevice_FCD.h:102
static SumoXMLAttrMask getWrittenAttributes()
Definition: MSDevice_FCD.h:87
static bool shapeFilter(const SUMOTrafficObject *veh)
checks if in polygon
Stores edges and lanes, performs moving of vehicle.
Definition: MSEdgeControl.h:78
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
Definition: MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
double getDistanceAt(double pos) const
Returns the kilometrage/mileage at the given offset along the edge.
Definition: MSEdge.cpp:1569
static bool isVisible(const SUMOVehicle *veh)
static bool hasOwnOutput(const SUMOVehicle *veh, bool filter, bool shapeFilter, bool isInRadius=false)
static void write(OutputDevice &of, SUMOTime timestep, bool elevation)
Writes the position and the angle of each vehicle into the given device.
Definition: MSFCDExport.cpp:50
static void writeTransportable(OutputDevice &of, const MSEdge *e, MSTransportable *p, const SUMOVehicle *v, bool filter, bool shapeFilter, bool inRadius, SumoXMLTag tag, bool useGeo, bool elevation, SumoXMLAttrMask mask)
write transportable
static bool gSublane
whether sublane simulation is enabled (sublane model or continuous lanechanging)
Definition: MSGlobals.h:160
bool isInternal() const
Definition: MSLane.cpp:2506
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
The simulated network and simulation perfomer.
Definition: MSNet.h:89
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:182
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:1182
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:378
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:421
bool hasContainers() const
Returns whether containers are simulated.
Definition: MSNet.h:411
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:395
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:1173
double getDistanceBetween(double fromPos, double toPos, const MSLane *fromLane, const MSLane *toLane, int routePosition=0) const
Compute the distance between 2 given edges on this route, optionally including the length of internal...
Definition: MSRoute.cpp:311
bool hasTransportables() const
checks whether any transportable waits to finish her plan
A device which collects info on the vehicle trip (mainly on departure and arrival)
virtual double getEdgePos() const
Return the position on the edge.
virtual double getAngle() const
return the current angle of the transportable
virtual double getSpeed() const
the current speed of the transportable
Position getPosition(const double) const
Return current position (x/y, cartesian)
const MSEdge * getEdge() const
Returns the current edge.
MSDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists or nullptr if not.
The class responsible for building and deletion of vehicles.
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:5726
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Definition: MSVehicle.h:517
int getSignals() const
Returns the signals.
Definition: MSVehicle.h:1185
std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:6474
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:584
double getMinGap() const
Get the free space in front of vehicles of this class.
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:91
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeOptionalAttr(const SumoXMLAttr attr, const T &val, long long int attributeMask)
writes a named attribute unless filtered
Definition: OutputDevice.h:271
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void setPrecision(int precision=gPrecision)
Sets the precision or resets it to default.
bool useAttribute(const SumoXMLAttr attr, SumoXMLAttrMask attributeMask) const
Definition: OutputDevice.h:259
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double x() const
Returns the x-position.
Definition: Position.h:55
double z() const
Returns the z-position.
Definition: Position.h:65
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
virtual MSDevice * getDevice(const std::type_info &type) const =0
Returns a device of the given type if it exists or nullptr if not.
virtual double getSlope() const =0
Returns the slope of the road at object's position in degrees.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual Position getPosition(const double offset=0) const =0
Return current position (x/y, cartesian)
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
virtual double getLateralPositionOnLane() const =0
Get the vehicle's lateral position on the lane.
virtual const std::vector< MSTransportable * > & getContainers() const =0
retrieve riding containers
virtual double getOdometer() const =0
Returns the distance that was already driven by this vehicle.
virtual const std::vector< MSTransportable * > & getPersons() const =0
retrieve riding persons
virtual bool isOnRoad() const =0
Returns the information whether the vehicle is on a road (is simulated)
virtual bool isParking() const =0
Returns the information whether the vehicle is parked.
virtual bool isRemoteControlled() const =0
Returns the information whether the vehicle is fully controlled via TraCI.
virtual double getAngle() const =0
Get the vehicle's angle.
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
static void collectObjectsInRange(int domain, const PositionVector &shape, double range, std::set< const Named * > &into)
Definition: Helper.cpp:814
TRACI_CONST int CMD_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_GET_PERSON_VARIABLE