Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSDevice_FCD.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2013-2026 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/****************************************************************************/
20// A device which stands as an implementation FCD and which outputs movereminder calls
21/****************************************************************************/
22#include <config.h>
23
24#include <bitset>
31#include <microsim/MSNet.h>
32#include <microsim/MSLane.h>
33#include <microsim/MSEdge.h>
34#include <microsim/MSVehicle.h>
35#include "MSDevice_FCD.h"
36
37
38// ===========================================================================
39// static members
40// ===========================================================================
46std::vector<std::string> MSDevice_FCD::myParamsToWrite;
48std::set<const MSEdge*> MSDevice_FCD::myEdgeFilter;
49std::vector<PositionVector> MSDevice_FCD::myShape4Filters;
55
56
57// ===========================================================================
58// method definitions
59// ===========================================================================
60// ---------------------------------------------------------------------------
61// static initialisation methods
62// ---------------------------------------------------------------------------
63void
65 oc.addOptionSubTopic("FCD Device");
66 insertDefaultAssignmentOptions("fcd", "FCD Device", oc);
67
68 oc.doRegister("device.fcd.begin", new Option_String("-1"));
69 oc.addDescription("device.fcd.begin", "FCD Device", TL("Recording begin time for FCD-data"));
70
71 oc.doRegister("device.fcd.period", new Option_String("0"));
72 oc.addDescription("device.fcd.period", "FCD Device", TL("Recording period for FCD-data"));
73
74 oc.doRegister("device.fcd.radius", new Option_Float(0));
75 oc.addDescription("device.fcd.radius", "FCD Device", TL("Record objects in a radius around equipped vehicles"));
76}
77
78
79void
80MSDevice_FCD::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
82 if (equippedByDefaultAssignmentOptions(oc, "fcd", v, oc.isSet("fcd-output"))) {
83 MSDevice_FCD* device = new MSDevice_FCD(v, "fcd_" + v.getID());
84 into.push_back(device);
85 }
86}
87
88
89// ---------------------------------------------------------------------------
90// MSDevice_FCD-methods
91// ---------------------------------------------------------------------------
92MSDevice_FCD::MSDevice_FCD(SUMOVehicle& holder, const std::string& id) :
93 MSVehicleDevice(holder, id) {
94}
95
96
99
100
103 SumoXMLAttrMask mask;
104 mask.set(SUMO_ATTR_X);
105 mask.set(SUMO_ATTR_Y);
106 if (MSNet::getInstance()->hasElevation()) {
107 mask.set(SUMO_ATTR_Z);
108 }
109 mask.set(SUMO_ATTR_ANGLE);
110 mask.set(SUMO_ATTR_TYPE);
111 mask.set(SUMO_ATTR_SPEED);
112 mask.set(SUMO_ATTR_POSITION);
113 mask.set(SUMO_ATTR_LANE); // for micro vehicles only
114 mask.set(SUMO_ATTR_EDGE); // for persons and meso vehicles
115 mask.set(SUMO_ATTR_SLOPE);
116 if (!MSGlobals::gUseMesoSim && OptionsCont::getOptions().getFloat("fcd-output.max-leader-distance") > 0.) {
117 mask.set(SUMO_ATTR_LEADER_ID);
118 mask.set(SUMO_ATTR_LEADER_SPEED);
119 mask.set(SUMO_ATTR_LEADER_GAP);
120 }
121 return mask;
122}
123
124
125bool
127 // lazily build the shape filter in the case where route file is loaded as an additional file
130 }
131 const MSVehicle* msVeh = dynamic_cast<const MSVehicle*>(veh);
132 for (auto shape : myShape4Filters) {
133 if (shape.around(veh->getPosition()) || ((msVeh != nullptr) && shape.around(msVeh->getBackPosition()))) {
134 return true;
135 }
136 }
137 return false;
138}
139
140
141void
144 if (oc.isSet("fcd-output.filter-shapes")) {
145 const ShapeContainer& loadedShapes = MSNet::getInstance()->getShapeContainer();
146 if (loadedShapes.getPolygons().size() > 0) {
147 for (std::string attrName : oc.getStringVector("fcd-output.filter-shapes")) {
148 if (loadedShapes.getPolygons().get(attrName) == 0) {
149 WRITE_ERRORF(TL("Specified shape '%' for filtering fcd-output could not be found."), attrName);
150 } else {
151 // store the PositionVector, not reference, as traci can manipulate / detete the polygons
152 myShape4Filters.push_back(loadedShapes.getPolygons().get(attrName)->getShape());
153 }
154 }
156 }
157 } else {
159 }
160}
161
162
163void
166 return;
167 }
170 myPeriod = string2time(oc.getString("device.fcd.period"));
171 myBegin = string2time(oc.getString("device.fcd.begin"));
172 myUseGeo = oc.getBool("fcd-output.geo");
173 myUseUTM = oc.getBool("fcd-output.utm");
174 myMaxLeaderDistance = oc.getFloat("fcd-output.max-leader-distance");
175 myParamsToWrite = oc.getStringVector("fcd-output.params");
176 myRadius = oc.getFloat("device.fcd.radius");
177 mySkipEmpty = oc.getBool("fcd-output.skip-empty");
178 if (oc.isSet("fcd-output.filter-edges.input-file")) {
179 const std::string file = oc.getString("fcd-output.filter-edges.input-file");
180 std::ifstream strm(file.c_str());
181 if (!strm.good()) {
182 throw ProcessError(TLF("Could not load names of edges for filtering fcd-output from '%'.", file));
183 }
184 while (strm.good()) {
185 std::string name;
186 strm >> name;
187 // maybe we're loading an edge-selection
188 if (StringUtils::startsWith(name, "edge:")) {
189 name = name.substr(5);
190 }
191 myEdgeFilter.insert(MSEdge::dictionary(name));
192 }
193 }
194 SumoXMLAttrMask emissions;
195 emissions.set(SUMO_ATTR_ECLASS);
196 emissions.set(SUMO_ATTR_CO2);
197 emissions.set(SUMO_ATTR_CO);
198 emissions.set(SUMO_ATTR_HC);
199 emissions.set(SUMO_ATTR_NOX);
200 emissions.set(SUMO_ATTR_PMX);
201 emissions.set(SUMO_ATTR_FUEL);
202 emissions.set(SUMO_ATTR_ELECTRICITY);
203 emissions.set(SUMO_ATTR_NOISE);
204 SumoXMLAttrMask misc;
205 misc.set(SUMO_ATTR_SIGNALS);
206 misc.set(SUMO_ATTR_ACCELERATION);
208 misc.set(SUMO_ATTR_SPEED_VEC);
209 misc.set(SUMO_ATTR_ACCEL_VEC);
210 misc.set(SUMO_ATTR_DISTANCE);
211 misc.set(SUMO_ATTR_ODOMETER);
212 misc.set(SUMO_ATTR_POSITION_LAT);
213 misc.set(SUMO_ATTR_SPEED_LAT);
214 misc.set(SUMO_ATTR_SPEEDREL);
215 misc.set(SUMO_ATTR_LEADER_ID);
216 misc.set(SUMO_ATTR_LEADER_SPEED);
217 misc.set(SUMO_ATTR_ARRIVALDELAY);
218 misc.set(SUMO_ATTR_DELAY);
219 misc.set(SUMO_ATTR_SEGMENT);
220 misc.set(SUMO_ATTR_QUEUE);
221 misc.set(SUMO_ATTR_ENTRYTIME);
222 misc.set(SUMO_ATTR_EVENTTIME);
223 misc.set(SUMO_ATTR_BLOCKTIME);
224 const std::map<std::string, SumoXMLAttrMask> special = {{"location", getDefaultMask()}, {"emissions", emissions}, {"misc", misc}};
225 if (oc.isSet("fcd-output.attributes")) {
226 myWrittenAttributes = OutputDevice::parseWrittenAttributes(oc.getStringVector("fcd-output.attributes"), "fcd output", special);
227 } else {
229 }
230 // need to store this because some attributes are reset later
231 const bool all = myWrittenAttributes.all();
233 if (!MSNet::getInstance()->hasElevation()) {
235 }
236 if (oc.getBool("fcd-output.signals")) {
238 }
239 if (oc.getBool("fcd-output.acceleration")) {
241 }
243 if (oc.getBool("fcd-output.distance")) {
245 }
246 if (oc.getBool("fcd-output.speed-relative")) {
248 }
249
250 if (oc.isSet("fcd-output.filter-shapes")) {
251 // build the shape filter if it is desired
254 }
256}
257
258
259void
261 myEdgeFilter.clear();
262 myShape4Filters.clear();
265 myShapeFilterDesired = false;
266 myWrittenAttributes.reset();
267}
268
269
270/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define SUMOTime_MAX
Definition SUMOTime.h:34
std::bitset< 96 > SumoXMLAttrMask
@ SUMO_ATTR_LANE
@ SUMO_ATTR_NOISE
MSMeanData_Harmonoise.
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_PMX
@ SUMO_ATTR_Y
@ SUMO_ATTR_Z
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_X
@ SUMO_ATTR_SPEEDREL
@ SUMO_ATTR_HC
@ SUMO_ATTR_POSITION_LAT
@ SUMO_ATTR_FUEL
@ SUMO_ATTR_ODOMETER
@ SUMO_ATTR_ACCEL_VEC
@ SUMO_ATTR_ELECTRICITY
@ SUMO_ATTR_SIGNALS
@ SUMO_ATTR_LEADER_GAP
@ SUMO_ATTR_QUEUE
@ SUMO_ATTR_CO
@ SUMO_ATTR_ACCELERATION_LAT
@ SUMO_ATTR_ARRIVALDELAY
@ SUMO_ATTR_BLOCKTIME
@ SUMO_ATTR_SLOPE
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_LEADER_SPEED
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_SPEED_VEC
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_EVENTTIME
@ SUMO_ATTR_SEGMENT
@ SUMO_ATTR_CO2
@ SUMO_ATTR_ID
@ SUMO_ATTR_SPEED_LAT
@ SUMO_ATTR_ENTRYTIME
@ SUMO_ATTR_ECLASS
@ SUMO_ATTR_DELAY
@ SUMO_ATTR_LEADER_ID
@ SUMO_ATTR_NOX
@ SUMO_ATTR_POSITION
A device which collects info on the vehicle trip (mainly on departure and arrival)
static void cleanup()
resets the edge filter
static SumoXMLAttrMask getDefaultMask()
MSDevice_FCD(SUMOVehicle &holder, const std::string &id)
Constructor.
static SUMOTime myBegin
begin time
~MSDevice_FCD()
Destructor.
static bool myShapeFilterInitialized
static std::vector< PositionVector > myShape4Filters
polygon spatial filter for FCD output
static SumoXMLAttrMask myWrittenAttributes
bit mask for checking attributes to be written
static std::set< const MSEdge * > myEdgeFilter
edge filter for FCD output
static std::vector< std::string > myParamsToWrite
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_FCD-options.
static double myRadius
static bool myUseUTM
static bool mySkipEmpty
whether time steps without vehicles will generate output
static bool myEdgeFilterInitialized
static bool myShapeFilterDesired
static void initOnce()
initialize edge filter and attribute mask (once)
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
static double myMaxLeaderDistance
static SUMOTime myPeriod
static void buildShapeFilter()
static bool shapeFilter(const SUMOTrafficObject *veh)
checks if in polygon
static bool myUseGeo
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
Definition MSDevice.cpp:157
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
Definition MSDevice.h:200
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition MSEdge.cpp:1081
static bool gUseMesoSim
Definition MSGlobals.h:106
static bool gSublane
whether sublane simulation is enabled (sublane model or continuous lanechanging)
Definition MSGlobals.h:165
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:199
ShapeContainer & getShapeContainer()
Returns the shapes container.
Definition MSNet.h:525
Abstract in-vehicle device.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
const Position getBackPosition() const
const std::string & getID() const
Returns the id.
Definition Named.h:73
T get(const std::string &id) const
Retrieves an item.
int size() const
Returns the number of stored items within the container.
A storage for options typed value containers)
Definition OptionsCont.h:89
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
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)
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
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.
static const SumoXMLAttrMask parseWrittenAttributes(const std::vector< std::string > &attrList, const std::string &desc, const std::map< std::string, SumoXMLAttrMask > &special=std::map< std::string, SumoXMLAttrMask >())
Parses a list of strings for attribute names and sets the relevant bits in the returned mask.
void setExpectedAttributes(const SumoXMLAttrMask &expected, const int depth=2)
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
const PositionVector & getShape() const
Returns the shape of the polygon.
Representation of a vehicle, person, or container.
virtual Position getPosition(const double offset=0) const =0
Return current position (x/y, cartesian)
Representation of a vehicle.
Definition SUMOVehicle.h:63
Storage for geometrical objects.
const Polygons & getPolygons() const
Returns all polygons.
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.