Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2005-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 MSCalibrator.h 15 : /// @author Daniel Krajzewicz 16 : /// @author Jakob Erdmann 17 : /// @author Michael Behrisch 18 : /// @date Tue, May 2005 19 : /// 20 : // Calibrates the flow on an edge by removing an inserting vehicles 21 : /****************************************************************************/ 22 : #pragma once 23 : #include <config.h> 24 : 25 : #include <string> 26 : #include <vector> 27 : #include <utils/common/Command.h> 28 : #include <microsim/MSRouteHandler.h> 29 : #include <microsim/output/MSMeanData_Net.h> 30 : #include <microsim/output/MSDetectorFileOutput.h> 31 : 32 : 33 : // =========================================================================== 34 : // class declarations 35 : // =========================================================================== 36 : class OutputDevice; 37 : class MSRouteProbe; 38 : 39 : 40 : // =========================================================================== 41 : // class definitions 42 : // =========================================================================== 43 : /** 44 : * @class MSCalibrator 45 : * @brief Calibrates the flow on a segment to a specified one 46 : */ 47 : class MSCalibrator : public MSRouteHandler, public Command, public MSDetectorFileOutput { 48 : public: 49 : /** constructor */ 50 : MSCalibrator(const std::string& id, 51 : const MSEdge* const edge, 52 : MSLane* lane, 53 : const double pos, 54 : const std::string& aXMLFilename, 55 : const std::string& outputFilename, 56 : const SUMOTime freq, const double length, 57 : const MSRouteProbe* probe, 58 : const double invalidJamThreshold, 59 : const std::string& vTypes, 60 : bool addLaneMeanData = true); 61 : 62 : /** destructor */ 63 : virtual ~MSCalibrator(); 64 : 65 : /** @brief Write the generated output to the given device 66 : * @param[in] dev The output device to write the data into 67 : * @param[in] startTime First time step the data were gathered 68 : * @param[in] stopTime Last time step the data were gathered 69 : * @exception IOError If an error on writing occurs 70 : */ 71 : void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime); 72 : 73 : 74 : /** @brief Open the XML-output 75 : * 76 : * The implementing function should open an xml element using 77 : * OutputDevice::writeXMLHeader. 78 : * 79 : * @param[in] dev The output device to write the root into 80 : * @exception IOError If an error on writing occurs 81 : */ 82 : void writeXMLDetectorProlog(OutputDevice& dev) const; 83 : 84 : /** the implementation of the MSTrigger / Command interface. 85 : Calibrating takes place here. */ 86 : virtual SUMOTime execute(SUMOTime currentTime); 87 : 88 : /// @brief cleanup remaining data structures 89 : static void cleanup(); 90 : 91 : /// @brief return all calibrator instances 92 : static const std::map<std::string, MSCalibrator*>& getInstances() { 93 : return myInstances; 94 : } 95 : 96 : struct AspiredState { 97 650 : AspiredState() : begin(-1), end(-1), q(-1.), v(-1.), vehicleParameter(0) {} 98 : SUMOTime begin; 99 : SUMOTime end; 100 : double q; 101 : double v; 102 : SUMOVehicleParameter* vehicleParameter; 103 : }; 104 : 105 : AspiredState getCurrentStateInterval() const; 106 : 107 : const MSEdge* getEdge() const { 108 12 : return myEdge; 109 : } 110 : 111 : const MSLane* getLane() const { 112 621 : return myLane; 113 : } 114 : 115 : const MSRouteProbe* getRouteProbe() const { 116 12 : return myProbe; 117 : } 118 : 119 523202 : inline virtual int passed() const { 120 : // calibrator measures at start of segment 121 : // vehicles drive to the end of an edge by default so they count as passed 122 : // but vaporized vehicles do not count 123 : // if the calibrator is located on a short edge, the vehicles are 124 : // vaporized on the next edge so we cannot rely on myEdgeMeanData.nVehVaporized 125 523202 : return myEdgeMeanData.nVehEntered + myEdgeMeanData.nVehDeparted - myClearedInJam - myRemoved; 126 : } 127 : 128 : int getInserted() const { 129 12 : return myEdgeMeanData.nVehDeparted; 130 : } 131 : 132 : int getRemoved() const { 133 12 : return myClearedInJam + myRemoved; 134 : } 135 : 136 : void setFlow(SUMOTime begin, SUMOTime end, double vehsPerHour, double speed, SUMOVehicleParameter vehicleParameter); 137 : 138 : protected: 139 : class CalibratorCommand : public Command { 140 : public: 141 335 : CalibratorCommand(MSCalibrator* cali) : 142 335 : myCalibrator(cali) {} 143 : 144 577751 : SUMOTime execute(SUMOTime currentTime) { 145 577751 : return myCalibrator->execute(currentTime); 146 : } 147 : 148 : /** @brief Reschedule or deschedule the command when quick-loading state 149 : * 150 : * The implementations should return -1 if the command shall not be re-scheduled, 151 : * or a value >= 0 that describe the new time at which the command 152 : * shall be executed again. 153 : * 154 : * @param[in] currentTime The current simulation time 155 : * @param[in] execTime The time at which the command would have been executed 156 : * @param[in] newTime The simulation time at which the simulation is restarted 157 : * @return The time at which the command shall be executed again 158 : */ 159 : SUMOTime shiftTime(SUMOTime currentTime, SUMOTime execTime, SUMOTime newTime); 160 : 161 : private: 162 : MSCalibrator* myCalibrator; 163 : }; 164 : 165 : 166 : /// @name inherited from GenericSAXHandler 167 : //@{ 168 : 169 : /** @brief Called on the opening of a tag; 170 : * 171 : * @param[in] element ID of the currently opened element 172 : * @param[in] attrs Attributes within the currently opened element 173 : * @exception ProcessError If something fails 174 : * @see GenericSAXHandler::myStartElement 175 : */ 176 : virtual void myStartElement(int element, 177 : const SUMOSAXAttributes& attrs); 178 : 179 : /** @brief Called on the closing of a tag; 180 : * 181 : * @param[in] element ID of the currently closed element 182 : * @exception ProcessError If something fails 183 : * @see GenericSAXHandler::myEndElement 184 : */ 185 : virtual void myEndElement(int element); 186 : //@} 187 : 188 : 189 : 190 : class VehicleRemover : public MSMoveReminder { 191 : public: 192 543 : VehicleRemover(MSLane* lane, MSCalibrator* parent) : 193 543 : MSMoveReminder(parent->getID(), lane, true), myParent(parent) {} 194 : 195 : /// @name inherited from MSMoveReminder 196 : //@{ 197 : /** @brief Checks whether the reminder is activated by a vehicle entering the lane 198 : * 199 : * Lane change means in this case that the vehicle changes to the lane 200 : * the reminder is placed at. 201 : * 202 : * @param[in] veh The entering vehicle. 203 : * @param[in] reason how the vehicle enters the lane 204 : * @return True if vehicle enters the reminder. 205 : * @see Notification 206 : */ 207 : //@} 208 : virtual bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 209 : 210 : void disable() { 211 543 : myParent = 0; 212 : } 213 : 214 : private: 215 : MSCalibrator* myParent; 216 : }; 217 : friend class VehicleRemover; 218 : friend class GUICalibrator; 219 : 220 : // @return whether the current state is active (GUI) 221 : bool isActive() const { 222 162949 : return myAmActive; 223 : } 224 : 225 : protected: 226 : 227 : void intervalEnd(); 228 : 229 : bool isCurrentStateActive(SUMOTime time); 230 : 231 : bool tryEmit(MSLane* lane, MSVehicle* vehicle); 232 : 233 : void init(); 234 : 235 : /// @brief number of vehicles expected to pass this interval 236 : int totalWished() const; 237 : 238 : /// @brief flow in the current interval in veh/h 239 : double currentFlow() const; 240 : 241 : /// @brief measured speed in the current interval 242 : double currentSpeed() const; 243 : 244 : /* @brief returns whether the lane is jammed although it should not be 245 : * @param[in] lane The lane to check or all for negative values 246 : */ 247 : bool invalidJam(int laneIndex) const; 248 : 249 0 : inline int inserted() const { 250 0 : return myInserted; 251 : } 252 0 : inline int removed() const { 253 0 : return myRemoved; 254 : } 255 0 : inline int clearedInJam() const { 256 0 : return myClearedInJam; 257 : } 258 : 259 : /* @brief returns the number of vehicles (of the current type) that still 260 : * fit on the given lane 261 : * @param[in] lane The lane to check (return the maximum of all lanes for negative values) 262 : */ 263 : int remainingVehicleCapacity(int laneIndex) const; 264 : 265 : /// @brief reset collected vehicle data 266 : virtual void reset(); 267 : 268 : /// @brief aggregate lane values 269 : virtual void updateMeanData(); 270 : 271 : /** @brief try to schedule the given vehicle for removal. return true if it 272 : * isn't already scheduled */ 273 : bool scheduleRemoval(SUMOTrafficObject* veh) { 274 : return myToRemove.insert(veh->getID()).second; 275 : } 276 : 277 : 278 : /** @brief remove any vehicles which are scheduled for removal. 279 : * return true if removals took place */ 280 : bool removePending(); 281 : 282 : /// @brief determine id of new vehicle from calibrator state 283 : std::string getNewVehicleID(); 284 : 285 : protected: 286 : /// @brief the edge on which this calibrator lies 287 : MSEdge* const myEdge; 288 : /// @brief the lane on which this calibrator lies (0 if the whole edge is covered at once) 289 : MSLane* const myLane; 290 : /// @brief the position on the edge where this calibrator lies 291 : const double myPos; 292 : /// @brief the route probe to retrieve routes from 293 : const MSRouteProbe* const myProbe; 294 : /// @brief dummy parent to retrieve vType filter 295 : MSMeanData_Net myMeanDataParent; 296 : /// @brief data collector for the calibrator 297 : std::vector<MSMeanData_Net::MSLaneMeanDataValues*> myLaneMeanData; 298 : /// @brief accumlated data for the whole edge 299 : MSMeanData_Net::MSLaneMeanDataValues myEdgeMeanData; 300 : 301 : /// @brief List of adaptation intervals 302 : std::vector<AspiredState> myIntervals; 303 : /// @brief Iterator pointing to the current interval 304 : std::vector<AspiredState>::const_iterator myCurrentStateInterval; 305 : 306 : std::vector<VehicleRemover*> myVehicleRemovers; 307 : 308 : /** @brief set of vehicle ids to remove 309 : * @note: we avoid keeping vehicle points because someone else might 310 : * invalidate it before look at it again (i.e. another calibrator) 311 : */ 312 : std::set<std::string> myToRemove; 313 : 314 : /// @brief The device for xml statistics 315 : OutputDevice* myOutput; 316 : 317 : /// @brief The frequeny with which to check for calibration 318 : SUMOTime myFrequency; 319 : /// @brief The number of vehicles that were removed in the current interval 320 : int myRemoved; 321 : /// @brief The number of vehicles that were inserted in the current interval 322 : int myInserted; 323 : /// @brief The number of vehicles that were removed when clearin a jam 324 : int myClearedInJam; 325 : /// @brief The information whether the speed adaption has been reset 326 : bool mySpeedIsDefault; 327 : /// @brief The information whether speed was adapted in the current interval 328 : bool myDidSpeedAdaption; 329 : /// @brief The information whether init was called 330 : bool myDidInit; 331 : /// @brief The default (maximum) speed on the segment 332 : double myDefaultSpeed; 333 : /// @brief The default (maximum) speed on the segment 334 : bool myHaveWarnedAboutClearingJam; 335 : 336 : /// @brief whether the calibrator was active when last checking 337 : bool myAmActive; 338 : 339 : /// @brief relative speed threshold for detecting and clearing invalid jam 340 : double myInvalidJamThreshold; 341 : 342 : /// @brief whether the calibrator has registered an invalid jam in the last execution step 343 : bool myHaveInvalidJam; 344 : 345 : /* @brief objects which need to live longer than the MSCalibrator 346 : * instance which created them */ 347 : static std::vector<MSMoveReminder*> myLeftoverReminders; 348 : static std::vector<SUMOVehicleParameter*> myLeftoverVehicleParameters; 349 : static std::map<std::string, MSCalibrator*> myInstances; 350 : 351 : };