Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2013-2024 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 MSDevice_ToC.h
15 : /// @author Leonhard Luecken
16 : /// @author Daniel Krajzewicz
17 : /// @author Jakob Erdmann
18 : /// @date 01.04.2018
19 : ///
20 : // The ToC Device controls the transition of control between automated and manual driving.
21 : //
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 :
26 : #include <random>
27 : #include <queue>
28 : #include "MSVehicleDevice.h"
29 : #include <utils/common/SUMOTime.h>
30 : #include <utils/common/WrappingCommand.h>
31 :
32 :
33 : // ===========================================================================
34 : // class declarations
35 : // ===========================================================================
36 : class SUMOVehicle;
37 : class MSVehicle;
38 : class Command_ToCTrigger;
39 : class Command_ToCProcess;
40 : class RGBColor;
41 :
42 : // ===========================================================================
43 : // class definitions
44 : // ===========================================================================
45 : /**
46 : * @class MSDevice_ToC
47 : *
48 : * @brief The ToC Device controls transition of control between automated and manual driving.
49 : *
50 : * @see MSDevice
51 : */
52 : class MSDevice_ToC : public MSVehicleDevice {
53 : private:
54 : // All currently existing ToC device instances
55 : static std::set<MSDevice_ToC*, ComparatorNumericalIdLess> myInstances;
56 : // All files, that receive ToC output (TODO: check if required)
57 : static std::set<std::string> createdOutputFiles;
58 :
59 : struct OpenGapParams {
60 : double newTimeHeadway;
61 : double newSpaceHeadway;
62 : double changeRate;
63 : double maxDecel;
64 : bool active;
65 43 : OpenGapParams(double timegap, double spacing, double changeRate, double maxDecel, bool active) :
66 43 : newTimeHeadway(timegap), newSpaceHeadway(spacing), changeRate(changeRate), maxDecel(maxDecel), active(active)
67 : {};
68 : };
69 :
70 : public:
71 : /** @brief Inserts MSDevice_ToC-options
72 : * @param[filled] oc The options container to add the options to
73 : */
74 : static void insertOptions(OptionsCont& oc);
75 :
76 :
77 : /** @brief Build devices for the given vehicle, if needed
78 : *
79 : * The options are read and evaluated whether a ToC-device shall be built
80 : * for the given vehicle.
81 : *
82 : * The built device is stored in the given vector.
83 : *
84 : * @param[in] v The vehicle for which a device may be built
85 : * @param[filled] into The vector to store the built device in
86 : */
87 : static void buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into);
88 :
89 : /** @brief returns all currently existing ToC devices
90 : */
91 : static const std::set<MSDevice_ToC*, ComparatorNumericalIdLess>& getInstances() {
92 : return myInstances;
93 : };
94 :
95 : /** @brief Closes root tags of output files
96 : */
97 : static void cleanup();
98 :
99 : private:
100 :
101 : /// @brief Enum describing the different regimes for the device, @see myState
102 : /// Possible transitions:
103 : /// AUTOMATED -> PREPARING_TOC
104 : /// PREPARING_TOC -> PERFORMING_MRM
105 : /// PREPARING_TOC -> MANUAL
106 : /// PERFORMING_MRM -> MANUAL
107 : /// MANUAL -> AUTOMATED
108 : enum ToCState {
109 : UNDEFINED = 0,
110 : MANUAL = 1,
111 : AUTOMATED = 2,
112 : PREPARING_TOC = 3, // this applies only to the transition AUTOMATED -> MANUAL !
113 : MRM = 4,
114 : RECOVERING = 5
115 : };
116 :
117 : /// @name Helpers for parameter parsing
118 : /// @{
119 : static double getDynamicMRMProbability(const SUMOVehicle& v);
120 : static OpenGapParams getOpenGapParams(const SUMOVehicle& v);
121 :
122 : static ToCState _2ToCState(const std::string&);
123 : static std::string _2string(ToCState state);
124 : /// @}
125 :
126 :
127 : public:
128 : /// @brief Destructor.
129 : ~MSDevice_ToC();
130 :
131 : /// @brief return the name for this type of device
132 44559 : const std::string deviceName() const override {
133 44559 : return "toc";
134 : }
135 :
136 : /// @brief Return value indicates whether the device still wants to be notified about the vehicle movement
137 : bool notifyMove(SUMOTrafficObject& veh,
138 : double oldPos,
139 : double newPos,
140 : double newSpeed) override;
141 :
142 : /// @brief try to retrieve the given parameter from this device. Throw exception for unsupported key
143 : std::string getParameter(const std::string& key) const override;
144 :
145 : /// @brief try to set the given parameter for this device. Throw exception for unsupported key
146 : void setParameter(const std::string& key, const std::string& value) override;
147 :
148 :
149 : /// @brief Trigger execution of an MRM
150 : SUMOTime triggerMRM(SUMOTime t);
151 :
152 : /// @brief Trigger execution of a ToC X-->AUTOMATED ("upwards")
153 : SUMOTime triggerUpwardToC(SUMOTime t);
154 :
155 : /// @brief Trigger execution of a ToC X-->MANUAL ("downwards")
156 : SUMOTime triggerDownwardToC(SUMOTime t);
157 :
158 : /// @brief Continue the ToC preparation for one time step
159 : SUMOTime ToCPreparationStep(SUMOTime t);
160 :
161 : /// @brief Continue the MRM for one time step
162 : SUMOTime MRMExecutionStep(SUMOTime t);
163 :
164 : /// @brief Continue the awareness recovery for one time step
165 : SUMOTime awarenessRecoveryStep(SUMOTime t);
166 :
167 : /// @brief Write output to file given by option device.toc.file
168 : void writeOutput();
169 :
170 : /// @brief Whether this device requested to write output
171 : bool generatesOutput() {
172 31446 : return myOutputFile != nullptr;
173 : }
174 :
175 : static SumoRNG* getResponseTimeRNG() {
176 : return &myResponseTimeRNG;
177 : }
178 : private:
179 : /** @brief Constructor
180 : *
181 : * @param[in] holder The vehicle that holds this device
182 : * @param[in] id The ID of the device
183 : * @param[in] file The file to write the device's output to
184 : * @param[in] manualType vType that models manual driving
185 : * @param[in] automatedType vType that models automated driving
186 : * @param[in] responseTime time lapse until vType switch after request was received
187 : * @param[in] recoveryRate rate at which the awareness increases after the takeover
188 : * @param[in] lcAbstinence awareness level below which no lane changes are taken out
189 : * @param[in] initialAwareness value to which the awareness is set after takeover
190 : * @param[in] mrmDecel constant deceleration rate assumed to be applied during an MRM
191 : * @param[in] mrmKeepRight whether the vehicle tries to change to the right during an MRM
192 : * @param[in] mrmSafeSpot stopping place to reach during an MRM
193 : * @param[in] useColorScheme whether the color of the vehicle should be changed according to its current ToC-state
194 : * @param[in] ogp parameters for the openGap mechanism applied during ToC preparation phase
195 : */
196 : MSDevice_ToC(SUMOVehicle& holder, const std::string& id, const std::string& outputFilename,
197 : const std::string& manualType, const std::string& automatedType, SUMOTime responseTime, double recoveryRate,
198 : double lcAbstinence, double initialAwareness, double mrmDecel,
199 : double dynamicToCThreshold, double dynamicMRMProbability, double maxPreparationAccel,
200 : bool mrmKeepRight, const std::string& mrmSafeSpot, SUMOTime mrmSafeSpotDuration, bool useColorScheme, OpenGapParams ogp);
201 :
202 : /** @brief Initialize vehicle colors for different states
203 : * @note For MANUAL and AUTOMATED, the color of the given types are used,
204 : * and for the other states hardcoded colors are given.
205 : */
206 : void initColorScheme();
207 :
208 : /// @brief Set the awareness to the given value
209 : void setAwareness(double value);
210 :
211 : /// @brief Set the ToC device's state
212 : void setState(ToCState state);
213 :
214 : // @brief Sets the device holder's color corresponding to the current state
215 : void setVehicleColor();
216 :
217 : /// @brief Request a ToC.
218 : /// If the device is in AUTOMATED or MRM state, a driver response time is sampled
219 : /// and the ToC is scheduled. If the response is larger than timeTillMRM,
220 : /// an MRM is scheduled as well.
221 : /// If the device is in MANUAL or UNDEFINED state, it switches to AUTOMATED.
222 : /// The request is ignored if the state is already PREPARING_TOC.
223 : /// @param timeTillMRM
224 : /// @param responseTime If the default is given (== -1), the response time is sampled randomly,
225 : /// @see sampleResponseTime()
226 : void requestToC(SUMOTime timeTillMRM, SUMOTime responseTime = -1000);
227 :
228 : /// @brief Request an MRM to be initiated immediately. No downward ToC will be scheduled.
229 : /// @note The initiated MRM process will run forever until a new ToC is requested.
230 : void requestMRM();
231 :
232 : /// @brief Switch the device holder's vehicle type
233 : void switchHolderType(const std::string& targetTypeID);
234 :
235 : /// @brief Break MRM Process or remove MRM-Trigger command from the event-queue.
236 : void descheduleMRM();
237 : /// @brief Remove scheduled ToC-Trigger command from the event-queue.
238 : void descheduleToC();
239 : /// @brief Remove ongoing ToC-Preparation process from the event-queue.
240 : void descheduleToCPreparation();
241 : /// @brief Remove ongoing awareness recovery process from the event-queue.
242 : void descheduleRecovery();
243 :
244 : /// @brief Resets the holder's LC mode to the last differing to LCModeMRM
245 : void resetDeliberateLCs();
246 : /// @brief Resets the holder's LC mode to the operational LC-mode of the ToC Device (@see LCModeMRM)
247 : void deactivateDeliberateLCs();
248 :
249 : /// @brief Whether the current operation mode is manual
250 : bool isManuallyDriven();
251 : /// @brief Whether the current operation mode is automated
252 : bool isAutomated();
253 :
254 : /// @brief Check if the vehicle should induce a ToC due to
255 : /// internal reasons. That is, if the route cannot be followed
256 : /// for more time than a given threshold, @see myDynamicToCThreshold
257 : bool checkDynamicToC();
258 :
259 : private:
260 : /// @name private state members of the ToC device
261 : /// @{
262 :
263 : /// @brief vehicle type ID for manual driving
264 : std::string myManualTypeID;
265 : /// @brief vehicle type ID for automated driving
266 : std::string myAutomatedTypeID;
267 :
268 :
269 : /// @brief Average response time needed by the driver to take back control
270 : SUMOTime myResponseTime;
271 : /// @brief Recovery rate for the driver's awareness after a ToC
272 : double myRecoveryRate;
273 : /// @brief Level of the awareness below which no lane-changes are performed
274 : double myLCAbstinence;
275 : /// @brief Average awareness the driver has initially after a ToC
276 : double myInitialAwareness;
277 :
278 : /// @brief Deceleration rate applied during MRM
279 : double myMRMDecel;
280 :
281 : /// @brief Current awareness-level of the driver in [0,1]
282 : double myCurrentAwareness;
283 :
284 : /// @brief Coloring scheme, @see initColorScheme()
285 : std::map<ToCState, RGBColor> myColorScheme;
286 :
287 : /// @brief Whether a coloring scheme shall by applied to indicate the different toc stages, @see initColorScheme()
288 : bool myUseColorScheme;
289 :
290 : /// @brief Current state of the device
291 : ToCState myState;
292 :
293 : /// @}
294 :
295 : /// @brief The holder vehicle casted to MSVehicle*
296 : MSVehicle* myHolderMS;
297 :
298 : /// @name Commands sent to the EventControl (used for cleanup)
299 : /// @note Must be removed in destructor.
300 : /// @{
301 : WrappingCommand<MSDevice_ToC>* myTriggerMRMCommand;
302 : WrappingCommand<MSDevice_ToC>* myTriggerToCCommand;
303 : WrappingCommand<MSDevice_ToC>* myRecoverAwarenessCommand;
304 : WrappingCommand<MSDevice_ToC>* myExecuteMRMCommand;
305 : WrappingCommand<MSDevice_ToC>* myPrepareToCCommand;
306 : /// @}
307 :
308 : /// @brief The file the devices output goes to
309 : OutputDevice* myOutputFile;
310 :
311 : /// @brief Storage for events to be written to the output
312 : std::queue<std::pair<SUMOTime, std::string> > myEvents;
313 :
314 : /// @brief Storage for events to be written to the output
315 : std::queue<std::pair<std::string, double> > myEventLanes;
316 :
317 : /// @brief Storage for events to be written to the output
318 : std::queue<std::pair<double, double>> myEventXY;
319 :
320 : /// @brief LC mode overridden during MRM, stored for restoration
321 : int myPreviousLCMode;
322 :
323 : /// @brief LC mode operational during an MRM
324 : static int LCModeMRM;
325 :
326 : /// @brief Parameters for the openGap mechanism applied during ToC preparation phase
327 : OpenGapParams myOpenGapParams;
328 :
329 : /// @brief Duration in s. for which the vehicle needs to be able to follow its route without a lane change
330 : /// to continue in automated mode (only has effect if dynamic ToCs are activated, @see myDynamicToCActive)
331 : double myDynamicToCThreshold;
332 : /// @brief Probability of an MRM to occur after a dynamically triggered ToC
333 : // (Note that these MRMs will not induce full stops in most cases)
334 : double myMRMProbability;
335 : /// @brief Switch for considering dynamic ToCs, @see myDynamicToCThreshold
336 : bool myDynamicToCActive;
337 : /// @brief Flag to indicate that a dynamically triggered ToC is in preparation
338 : bool myIssuedDynamicToC;
339 : /// @brief Lane, on which the ongoing dynamic ToC was issued. It can only be aborted if the lane was changed.
340 : int myDynamicToCLane;
341 :
342 : /// @brief Whether vehicle tries to change to the right during an MRM
343 : bool myMRMKeepRight;
344 :
345 : /// @brief stop vehicle tries to reach during MRM
346 : std::string myMRMSafeSpot;
347 :
348 : /// @brief duration at stop vehicle tries to reach during MRM
349 : SUMOTime myMRMSafeSpotDuration;
350 :
351 : /// @brief Maximal acceleration that may be applied during the ToC preparation phase
352 : /// TODO: Make effective
353 : double myMaxPreparationAccel;
354 :
355 : /// @brief Storage for original maximal acceleration of vehicle.
356 : double myOriginalMaxAccel;
357 :
358 : /// @brief Grid of the response time distribution.
359 : static std::vector<double> lookupResponseTimeMRMProbs;
360 : static std::vector<double> lookupResponseTimeLeadTimes;
361 : /// @brief Mean of the response time distribution. (Only depends on given lead time)
362 : static double responseTimeMean(double leadTime) {
363 4 : return MIN2(2 * sqrt(leadTime), 0.7 * leadTime);
364 : };
365 : /// @brief Variances of the response time distribution. Given the lead time and the MRM probability
366 : /// the variances in this table ensure that for the mean returned by responseTimeMean(leadTime)
367 : /// an MRM will occur with probability pMRM
368 : static std::vector<std::vector<double> > lookupResponseTimeVariances;
369 :
370 : /// @brief Random generator for ToC devices
371 : static SumoRNG myResponseTimeRNG;
372 :
373 : /// @brief Samples a random driver response time from a truncated Gaussian with
374 : /// parameters according to the lookup tables
375 : double sampleResponseTime(double leadTime) const;
376 :
377 : /// @brief Two-dimensional interpolation of variance from lookup table
378 : /// assumes pMRM >= 0, leadTime >= 0
379 : static double interpolateVariance(double leadTime, double pMRM);
380 :
381 : private:
382 : /// @brief Invalidated copy constructor.
383 : MSDevice_ToC(const MSDevice_ToC&);
384 :
385 : /// @brief Invalidated assignment operator.
386 : MSDevice_ToC& operator=(const MSDevice_ToC&);
387 :
388 :
389 : };
|