Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 : /****************************************************************************/
14 : /// @file MELoop.h
15 : /// @author Daniel Krajzewicz
16 : /// @date Tue, May 2005
17 : ///
18 : // The main mesocopic simulation loop
19 : /****************************************************************************/
20 : #pragma once
21 : #include <config.h>
22 :
23 : #include <vector>
24 : #include <queue>
25 : #include <map>
26 : #include <utils/common/SUMOTime.h>
27 : #include <microsim/MSMoveReminder.h>
28 :
29 :
30 : // ===========================================================================
31 : // class declarations
32 : // ===========================================================================
33 : class MESegment;
34 : class MEVehicle;
35 : class MSEdge;
36 : class MSLink;
37 : class MSVehicleControl;
38 : class OptionsCont;
39 :
40 : // ===========================================================================
41 : // class definitions
42 : // ===========================================================================
43 : /**
44 : * @class MELoop
45 : * @brief The main mesocopic simulation loop
46 : */
47 : class MELoop {
48 : public:
49 : /// SUMO constructor
50 : MELoop(const SUMOTime recheckInterval);
51 :
52 : ~MELoop();
53 :
54 : /** @brief Perform simulation up to the given time
55 : *
56 : * Checks all vehicles with an event time less or equal than the given time.
57 : *
58 : * @param[in] tMax the end time for the sim step
59 : */
60 : void simulate(SUMOTime tMax);
61 :
62 : /** @brief Adds the given car to the leading vehicles
63 : *
64 : * @param[in] veh the car which became a leading one
65 : * @param[in] link the link on which the car shall register its approach
66 : */
67 : void addLeaderCar(MEVehicle* veh, MSLink* link);
68 :
69 : /** @brief Removes the given car from the leading vehicles
70 : *
71 : * @param[in] v the car which was a leading one
72 : */
73 : void removeLeaderCar(MEVehicle* v);
74 :
75 : /** @brief remove the given car and clean up the relevant data structures */
76 : void vaporizeCar(MEVehicle* v, MSMoveReminder::Notification reason);
77 :
78 : /// @brief whether the given edge is entering a roundabout
79 : static bool isEnteringRoundabout(const MSEdge& e);
80 :
81 : /** @brief Compute number of segments per edge (best value stay close to the configured segment length) */
82 : static int numSegmentsFor(const double length, const double slength);
83 :
84 : /** @brief Build the segments for a given edge
85 : *
86 : * @param[in] e the edge to build for
87 : */
88 : void buildSegmentsFor(const MSEdge& e, const OptionsCont& oc);
89 :
90 : /** @brief Get the segment for a given edge at a given position
91 : *
92 : * @param[in] e the edge to get the segment for
93 : * @param[in] pos the position to get the segment for
94 : * @return The relevant segment
95 : */
96 : MESegment* getSegmentForEdge(const MSEdge& e, double pos = 0);
97 :
98 : /** @brief change to the next segment
99 : * this handles combinations of the following cases:
100 : * (ending / continuing route) and (leaving segment / finishing teleport)
101 : */
102 : SUMOTime changeSegment(MEVehicle* veh, SUMOTime leaveTime, MESegment* const toSegment,
103 : MSMoveReminder::Notification reason, const bool ignoreLink = false) const;
104 :
105 : /** @brief Remove all vehicles before quick-loading state */
106 : void clearState();
107 :
108 : private:
109 : /** @brief Check whether the vehicle may move
110 : *
111 : * This method is called when the vehicle reaches its event time and checks
112 : * whether it may proceed to the next segment.
113 : *
114 : * @param[in] veh The vehicle to check
115 : */
116 : void checkCar(MEVehicle* veh);
117 :
118 : /** @brief Retrieve next segment
119 : *
120 : * If the segment is not the last on the current edge, its successor is returned.
121 : * Otherwise, the first segment of the edge at which the vehicle continues
122 : * his journey is returned.
123 : *
124 : * @param[in] s The segment the vehicle is currently at
125 : * @param[in] v The vehicle to get the next segment for
126 : * @return The vehicle's next segment
127 : * @todo Recheck the "quick and dirty" stuff (@see MESegment::saveState, @see MESegment::loadState)
128 : */
129 : MESegment* nextSegment(MESegment* s, MEVehicle* v);
130 :
131 :
132 : /** @brief teleports a vehicle or continues a teleport
133 : * @param[in] veh The vehicle to teleport
134 : * @param[in] toSegment The first segment where the vehicle may reenter the network
135 : */
136 : void teleportVehicle(MEVehicle* veh, MESegment* const toSegment, bool disconnected);
137 :
138 : private:
139 :
140 : struct LeaderEvent {
141 : LeaderEvent(MEVehicle* v);
142 :
143 : SUMOTime time;
144 : // eventIndex ensures stable sorting of vehicles with the same event time
145 : long long int eventIndex;
146 : // nid allows safely comparing events for deleted vehicles (myInvalidatedLeaderCars)
147 : long long int nid;
148 : MEVehicle* veh;
149 :
150 : bool operator<(const LeaderEvent& b) const {
151 205469915 : if (time == b.time) {
152 1911467 : return eventIndex > b.eventIndex;
153 : }
154 203558448 : return time > b.time;
155 : }
156 :
157 : bool operator==(const LeaderEvent& b) const {
158 108131 : return time == b.time && nid == b.nid;
159 : }
160 :
161 : static long long int myEventCounter;
162 : };
163 :
164 : /// @brief leader cars in the segments sorted by exit time
165 : typedef std::priority_queue<LeaderEvent> LeaderEventQeue;
166 : LeaderEventQeue myLeaderCars;
167 : LeaderEventQeue myInvalidatedLeaderCars;
168 :
169 : /// @brief mapping from internal edge ids to their initial segments
170 : std::vector<MESegment*> myEdges2FirstSegments;
171 :
172 : /// @brief the interval at which to recheck at full segments (<=0 means asap)
173 : const SUMOTime myFullRecheckInterval;
174 :
175 : /// @brief the interval at which to recheck at blocked junctions (<=0 means asap)
176 : const SUMOTime myLinkRecheckInterval;
177 :
178 : private:
179 : /// @brief Invalidated copy constructor.
180 : MELoop(const MELoop&);
181 :
182 : /// @brief Invalidated assignment operator.
183 : MELoop& operator=(const MELoop&);
184 : };
|