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