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    MSFCDExport.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 // Realises dumping Floating Car Data (FCD) Data
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <utils/iodevices/OutputDevice.h>
28 #include <utils/options/OptionsCont.h>
29 #include <utils/geom/GeoConvHelper.h>
30 #include <utils/geom/GeomHelper.h>
31 #include <microsim/devices/MSDevice_FCD.h>
32 #include <microsim/devices/MSTransportableDevice_FCD.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>
39 #include <microsim/pedestrians/MSPerson.h>
40 #include <microsim/MSTransportableControl.h>
41 #include <microsim/MSContainer.h>
42 #include <microsim/MSVehicleControl.h>
43 #include "MSFCDExport.h"
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
49 void
write(OutputDevice & of,SUMOTime timestep,bool elevation)50 MSFCDExport::write(OutputDevice& of, SUMOTime timestep, bool elevation) {
51     const bool useGeo = OptionsCont::getOptions().getBool("fcd-output.geo");
52     const bool signals = OptionsCont::getOptions().getBool("fcd-output.signals");
53     const SUMOTime period = string2time(OptionsCont::getOptions().getString("device.fcd.period"));
54     if (period > 0 && timestep % period != 0) {
55         return;
56     }
57     of.openTag("timestep").writeAttr(SUMO_ATTR_TIME, time2string(timestep));
58     MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
59     const bool filter = MSDevice_FCD::getEdgeFilter().size() > 0;
60     for (MSVehicleControl::constVehIt it = vc.loadedVehBegin(); it != vc.loadedVehEnd(); ++it) {
61         const SUMOVehicle* veh = it->second;
62         const MSVehicle* microVeh = dynamic_cast<const MSVehicle*>(veh);
63         if ((veh->isOnRoad() || veh->isParking() || veh->isRemoteControlled())
64                 && veh->getDevice(typeid(MSDevice_FCD)) != nullptr
65                 // only filter on normal edges
66                 && (!filter || MSDevice_FCD::getEdgeFilter().count(veh->getEdge()) > 0)) {
67             Position pos = veh->getPosition();
68             if (useGeo) {
69                 of.setPrecision(gPrecisionGeo);
70                 GeoConvHelper::getFinal().cartesian2geo(pos);
71             }
72             of.openTag(SUMO_TAG_VEHICLE);
73             of.writeAttr(SUMO_ATTR_ID, veh->getID());
74             of.writeAttr(SUMO_ATTR_X, pos.x());
75             of.writeAttr(SUMO_ATTR_Y, pos.y());
76             if (elevation) {
77                 of.writeAttr(SUMO_ATTR_Z, pos.z());
78             }
79             of.writeAttr(SUMO_ATTR_ANGLE, GeomHelper::naviDegree(veh->getAngle()));
80             of.writeAttr(SUMO_ATTR_TYPE, veh->getVehicleType().getID());
81             of.writeAttr(SUMO_ATTR_SPEED, veh->getSpeed());
82             of.writeAttr(SUMO_ATTR_POSITION, veh->getPositionOnLane());
83             if (microVeh != nullptr) {
84                 of.writeAttr(SUMO_ATTR_LANE, microVeh->getLane()->getID());
85             }
86             of.writeAttr(SUMO_ATTR_SLOPE, veh->getSlope());
87             if (microVeh != nullptr && signals) {
88                 of.writeAttr("signals", toString(microVeh->getSignals()));
89             }
90             of.closeTag();
91             // write persons and containers
92             const MSEdge* edge = microVeh == nullptr ? veh->getEdge() : &veh->getLane()->getEdge();
93 
94             const std::vector<MSTransportable*>& persons = veh->getPersons();
95             for (std::vector<MSTransportable*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) {
96                 writeTransportable(of, edge, *it_p, SUMO_TAG_PERSON, useGeo, elevation);
97             }
98             const std::vector<MSTransportable*>& containers = veh->getContainers();
99             for (std::vector<MSTransportable*>::const_iterator it_c = containers.begin(); it_c != containers.end(); ++it_c) {
100                 writeTransportable(of, edge, *it_c, SUMO_TAG_CONTAINER, useGeo, elevation);
101             }
102         }
103     }
104     if (MSNet::getInstance()->getPersonControl().hasTransportables()) {
105         // write persons
106         MSEdgeControl& ec = MSNet::getInstance()->getEdgeControl();
107         const MSEdgeVector& edges = ec.getEdges();
108         for (MSEdgeVector::const_iterator e = edges.begin(); e != edges.end(); ++e) {
109             if (filter && MSDevice_FCD::getEdgeFilter().count(*e) == 0) {
110                 continue;
111             }
112             const std::vector<MSTransportable*>& persons = (*e)->getSortedPersons(timestep);
113             for (std::vector<MSTransportable*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) {
114                 writeTransportable(of, *e, *it_p, SUMO_TAG_PERSON, useGeo, elevation);
115             }
116         }
117     }
118     if (MSNet::getInstance()->getContainerControl().hasTransportables()) {
119         // write containers
120         MSEdgeControl& ec = MSNet::getInstance()->getEdgeControl();
121         const std::vector<MSEdge*>& edges = ec.getEdges();
122         for (std::vector<MSEdge*>::const_iterator e = edges.begin(); e != edges.end(); ++e) {
123             if (filter && MSDevice_FCD::getEdgeFilter().count(*e) == 0) {
124                 continue;
125             }
126             const std::vector<MSTransportable*>& containers = (*e)->getSortedContainers(timestep);
127             for (std::vector<MSTransportable*>::const_iterator it_c = containers.begin(); it_c != containers.end(); ++it_c) {
128                 writeTransportable(of, *e, *it_c, SUMO_TAG_CONTAINER, useGeo, elevation);
129             }
130         }
131     }
132     of.closeTag();
133 }
134 
135 
136 void
writeTransportable(OutputDevice & of,const MSEdge * e,MSTransportable * p,SumoXMLTag tag,bool useGeo,bool elevation)137 MSFCDExport::writeTransportable(OutputDevice& of, const MSEdge* e, MSTransportable* p, SumoXMLTag tag, bool useGeo, bool elevation) {
138     if (p->getDevice(typeid(MSTransportableDevice_FCD)) == nullptr) {
139         return;
140     }
141     Position pos = p->getPosition();
142     if (useGeo) {
143         of.setPrecision(gPrecisionGeo);
144         GeoConvHelper::getFinal().cartesian2geo(pos);
145     }
146     of.openTag(tag);
147     of.writeAttr(SUMO_ATTR_ID, p->getID());
148     of.writeAttr(SUMO_ATTR_X, pos.x());
149     of.writeAttr(SUMO_ATTR_Y, pos.y());
150     if (elevation) {
151         of.writeAttr(SUMO_ATTR_Z, pos.z());
152     }
153     of.writeAttr(SUMO_ATTR_ANGLE, GeomHelper::naviDegree(p->getAngle()));
154     of.writeAttr(SUMO_ATTR_SPEED, p->getSpeed());
155     of.writeAttr(SUMO_ATTR_POSITION, p->getEdgePos());
156     of.writeAttr(SUMO_ATTR_EDGE, e->getID());
157     of.writeAttr(SUMO_ATTR_SLOPE, e->getLanes()[0]->getShape().slopeDegreeAtOffset(p->getEdgePos()));
158     of.closeTag();
159 }
160 /****************************************************************************/
161