Line data Source code
1 : #pragma once
2 :
3 : #include <functional>
4 : #include <list>
5 : #include <map>
6 : #include <memory>
7 : #include <rapidxml.hpp>
8 : #include <rapidxml_print.hpp>
9 : #include <string>
10 : #include <unordered_map>
11 : #include <vector>
12 :
13 : #include "data/SUMO/Additionals/Location.hpp"
14 : #include "data/SUMO/SUMO.hpp"
15 :
16 : namespace SUMO {
17 : class Network {
18 : public:
19 : Additionals::Location location;
20 :
21 : struct Junction;
22 : struct Connection;
23 :
24 : struct Edge {
25 : typedef SUMO::ID ID;
26 : typedef int Priority;
27 :
28 : static const Priority PRIORITY_UNSPECIFIED = -1000;
29 :
30 : enum Function {
31 : NORMAL,
32 : INTERNAL,
33 : CONNECTOR,
34 : CROSSING,
35 : WALKINGAREA
36 : };
37 :
38 : struct Lane {
39 : public:
40 : typedef SUMO::ID ID;
41 : typedef size_t Index;
42 :
43 : const Network &net;
44 : const Edge &edge;
45 :
46 : ID id;
47 : Index index;
48 : Speed speed;
49 : Length length;
50 : Shape shape;
51 :
52 : std::vector<std::reference_wrapper<const Connection>> getOutgoing() const;
53 :
54 : Vector2 getIncomingDirection() const;
55 : Vector2 getOutgoingDirection() const;
56 :
57 : Shape getShape() const;
58 :
59 : bool operator==(const Lane &other) const;
60 : bool operator<(const Lane &other) const;
61 : };
62 :
63 : const Network &net;
64 :
65 : const ID id;
66 : std::optional<SUMO::ID> fromID = std::nullopt;
67 : std::optional<SUMO::ID> toID = std::nullopt;
68 : std::optional<std::reference_wrapper<const Junction>> from = std::nullopt;
69 : std::optional<std::reference_wrapper<const Junction>> to = std::nullopt;
70 : Priority priority = Edge::PRIORITY_UNSPECIFIED;
71 : Function function = NORMAL;
72 : Shape shape = {};
73 :
74 : std::vector<Lane> lanes = {};
75 :
76 : Length length() const;
77 : Speed speed() const;
78 :
79 : Shape getShape() const;
80 :
81 : std::vector<std::reference_wrapper<const Edge>> getOutgoing() const;
82 : std::vector<std::reference_wrapper<const Connection>> getOutgoingConnections() const;
83 :
84 : bool operator==(const Edge &other) const;
85 : bool operator<(const Edge &other) const;
86 : };
87 :
88 : struct Junction {
89 : typedef SUMO::ID ID;
90 :
91 : enum Type {
92 : PRIORITY,
93 : TRAFFIC_LIGHT,
94 : RIGHT_BEFORE_LEFT,
95 : LEFT_BEFORE_RIGHT,
96 : UNREGULATED,
97 : TRAFFIC_LIGHT_UNREGULATED,
98 : PRIORITY_STOP,
99 : ALLWAY_STOP,
100 : RAIL_SIGNAL,
101 : ZIPPER,
102 : RAIL_CROSSING,
103 : TRAFFIC_LIGHT_RIGHT_ON_RED,
104 : DEAD_END,
105 :
106 : INTERNAL,
107 :
108 : UNKNOWN,
109 : DISTRICT
110 : };
111 :
112 : struct Request {
113 : const Network &net;
114 : const Junction::ID junctionID;
115 :
116 : Index index;
117 : std::vector<bool> response;
118 : std::vector<bool> foes;
119 : bool cont;
120 :
121 : const Junction &junction() const;
122 :
123 : std::vector<std::reference_wrapper<const Connection>> getResponse() const;
124 : };
125 :
126 : const ID id;
127 : const Coord pos;
128 : Type type = UNKNOWN;
129 : Shape shape = {};
130 :
131 : std::vector<std::reference_wrapper<const Edge::Lane>> incLanes = {};
132 : std::vector<std::reference_wrapper<const Edge::Lane>> intLanes = {};
133 :
134 : std::map<Index, Request> requests = {};
135 :
136 : /**
137 : * @brief Get connections by order.
138 : *
139 : * The order of connections is as specified in
140 : * https://sumo.dlr.de/docs/Networks/SUMO_Road_Networks.html#requests
141 : *
142 : * @return std::vector<const Connection *>
143 : */
144 : std::vector<std::reference_wrapper<const Connection>> getConnections() const;
145 :
146 : std::vector<std::reference_wrapper<const Edge::Lane>> outLanes() const;
147 :
148 : bool operator==(const Junction &other) const;
149 : };
150 :
151 : struct TrafficLightLogic {
152 : typedef SUMO::ID ID;
153 : enum Type {
154 : STATIC,
155 : ACTUATED,
156 : DELAY_BASED
157 : };
158 : typedef std::string ProgramID;
159 :
160 : const ID id;
161 : const Type type;
162 : const ProgramID programId;
163 : const Time offset;
164 :
165 7304 : struct Phase {
166 : // https://sumo.dlr.de/docs/Simulation/Traffic_Lights.html#signal_state_definitions
167 : enum State {
168 : RED,
169 : YELLOW_STOP,
170 : GREEN_NOPRIORITY,
171 : GREEN_PRIORITY,
172 : GREEN_RIGHT,
173 : YELLOW_START,
174 : OFF_YIELD,
175 : OFF
176 : };
177 :
178 : const Time duration;
179 :
180 : const std::vector<State> state;
181 : };
182 :
183 : // The key is the time at which the phase starts.
184 : std::map<Time, Phase> phases = {};
185 :
186 : Time getGreenTime(size_t linkIndex) const;
187 : Time getCycleTime() const;
188 : size_t getNumberStops(size_t linkIndex) const;
189 :
190 : const Phase &getPhase(Time time) const;
191 : };
192 :
193 : typedef std::unordered_map<TrafficLightLogic::ID, TrafficLightLogic> TrafficLights;
194 :
195 : /**
196 : * @brief Connection
197 : *
198 : * The meaning of indices in SUMO is explained in this link:
199 : * https://sumo.dlr.de/docs/Networks/SUMO_Road_Networks.html#indices_of_a_connection
200 : *
201 : * From what I understand, in a connection the linkIndex reports to the TL
202 : * index that controls the connection.
203 : *
204 : * The junction index is used to determine connections with conflicts. This
205 : * junction index is deduced from the order of ...
206 : */
207 : struct Connection {
208 : const Edge &from, &to;
209 : const Index fromLaneIndex, toLaneIndex;
210 :
211 : enum Direction {
212 : INVALID,
213 : STRAIGHT,
214 : TURN, /// @brief Turnaround (as in a deadend)
215 : LEFT,
216 : RIGHT,
217 : PARTIALLY_LEFT,
218 : PARTIALLY_RIGHT
219 : };
220 : Direction dir;
221 :
222 : enum State {
223 : DEAD_END, // Not very used in SUMO files
224 : EQUAL,
225 : MINOR_LINK,
226 : MAJOR_LINK,
227 : CONTROLLER_OFF,
228 : YELLOW_FLASHING,
229 : YELLOW_MINOR_LINK, // Not very used in SUMO files
230 : YELLOW_MAJOR_LINK, // Not very used in SUMO files
231 : RED, // Not very used in SUMO files
232 : GREEN_MINOR, // Not very used in SUMO files
233 : GREEN_MAJOR // Not very used in SUMO files
234 : };
235 : const State state;
236 :
237 : std::optional<std::reference_wrapper<const Edge::Lane>> via = std::nullopt;
238 :
239 : std::optional<std::reference_wrapper<const TrafficLightLogic>> tl = std::nullopt;
240 : std::optional<size_t> linkIndex = std::nullopt;
241 :
242 : const Edge::Lane &fromLane() const;
243 : const Edge::Lane &toLane() const;
244 :
245 : const Junction &getJunction() const;
246 :
247 : size_t getJunctionIndex() const;
248 :
249 : Time getGreenTime() const;
250 : Time getCycleTime() const;
251 : size_t getNumberStops() const;
252 :
253 : const Junction::Request &getRequest() const;
254 :
255 : bool operator==(const Connection &other) const;
256 :
257 : const TrafficLightLogic::Phase::State &getTrafficLightState(Time t) const;
258 : };
259 :
260 : private:
261 : // clang-format off
262 : typedef std::unordered_map<
263 : SUMO::Network::Edge::ID, std::unordered_map<
264 : SUMO::Index, std::unordered_map<
265 : SUMO::Network::Edge::ID, std::unordered_map<
266 : SUMO::Index,
267 : SUMO::Network::Connection
268 : >
269 : >
270 : >
271 : > Connections;
272 : // clang-format on
273 :
274 : std::unordered_map<Junction::ID, Junction> junctions;
275 : std::unordered_map<Edge::ID, Edge> edges;
276 :
277 : // clang-format off
278 : std::unordered_map<
279 : Junction::ID, std::unordered_map<
280 : Junction::ID,
281 : std::list<std::reference_wrapper<Edge>>
282 : >
283 : > edgesByJunctions;
284 : // clang-format on
285 :
286 : std::unordered_map<Edge::Lane::ID, std::pair<std::string, Edge::Lane::Index>> lanes;
287 : TrafficLights trafficLights;
288 : Connections connections;
289 :
290 : Junction &loadJunction(const rapidxml::xml_node<> *it);
291 : Edge &loadEdge(const rapidxml::xml_node<> *it);
292 : TrafficLightLogic &loadTrafficLightLogic(const rapidxml::xml_node<> *it);
293 : Connection &loadConnection(const rapidxml::xml_node<> *it);
294 :
295 : public:
296 : static std::shared_ptr<SUMO::Network> loadFromFile(const std::string &path);
297 :
298 : std::vector<Junction> getJunctions() const;
299 : const Junction &getJunction(const Junction::ID &id) const;
300 :
301 : std::vector<Edge> getEdges() const;
302 : const Edge &getEdge(const Edge::ID &id) const;
303 :
304 : std::vector<std::reference_wrapper<const Connection>> getConnections(const Edge &e1, const Edge &e2) const;
305 : std::unordered_map<SUMO::Network::Edge::ID, std::unordered_map<SUMO::Network::Edge::ID, std::list<std::reference_wrapper<const SUMO::Network::Connection>>>> getConnections() const;
306 : const TrafficLights &getTrafficLights() const;
307 :
308 : void saveStatsToFile(const std::string &path) const;
309 : };
310 :
311 : typedef std::vector<SUMO::Network::Edge::ID> Route;
312 : } // namespace SUMO
313 :
314 : namespace utils::stringify {
315 : template<>
316 : class stringify<SUMO::Network::Edge::Function> {
317 : public:
318 : static SUMO::Network::Edge::Function fromString(const std::string &s);
319 :
320 : static std::string toString(const SUMO::Network::Edge::Function &t);
321 : };
322 :
323 : template<>
324 : class stringify<SUMO::Network::Junction::Type> {
325 : public:
326 : static SUMO::Network::Junction::Type fromString(const std::string &s);
327 :
328 : static std::string toString(const SUMO::Network::Junction::Type &t);
329 : };
330 :
331 : template<>
332 : class stringify<SUMO::Network::TrafficLightLogic::Type> {
333 : public:
334 : static SUMO::Network::TrafficLightLogic::Type fromString(const std::string &s);
335 :
336 : static std::string toString(const SUMO::Network::TrafficLightLogic::Type &t);
337 : };
338 :
339 : template<>
340 : class stringify<SUMO::Network::TrafficLightLogic::Phase::State> {
341 : public:
342 : static SUMO::Network::TrafficLightLogic::Phase::State fromString(const std::string &s);
343 :
344 : static std::string toString(const SUMO::Network::TrafficLightLogic::Phase::State &t);
345 : };
346 :
347 : template<>
348 : class stringify<std::vector<SUMO::Network::TrafficLightLogic::Phase::State>> {
349 : public:
350 : static std::vector<SUMO::Network::TrafficLightLogic::Phase::State> fromString(const std::string &s);
351 :
352 : static std::string toString(const std::vector<SUMO::Network::TrafficLightLogic::Phase::State> &t);
353 : };
354 :
355 : template<>
356 : class stringify<SUMO::Network::Connection::Direction> {
357 : public:
358 : static SUMO::Network::Connection::Direction fromString(const std::string &s);
359 :
360 : static std::string toString(const SUMO::Network::Connection::Direction &t);
361 : };
362 :
363 : template<>
364 : class stringify<SUMO::Network::Connection::State> {
365 : public:
366 : static SUMO::Network::Connection::State fromString(const std::string &s);
367 :
368 : static std::string toString(const SUMO::Network::Connection::State &t);
369 : };
370 : } // namespace utils::stringify
|