1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2004-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 MSInductLoop.h 11 /// @author Christian Roessel 12 /// @author Daniel Krajzewicz 13 /// @author Sascha Krieg 14 /// @author Michael Behrisch 15 /// @author Jakob Erdmann 16 /// @date 2004-11-23 17 /// @version $Id$ 18 /// 19 // An unextended detector measuring at a fixed position on a fixed lane. 20 /****************************************************************************/ 21 #ifndef MSInductLoop_h 22 #define MSInductLoop_h 23 24 25 // =========================================================================== 26 // included modules 27 // =========================================================================== 28 #include <config.h> 29 30 #include <string> 31 #include <deque> 32 #include <map> 33 #include <functional> 34 #include <microsim/MSMoveReminder.h> 35 #include <microsim/output/MSDetectorFileOutput.h> 36 37 38 // =========================================================================== 39 // class declarations 40 // =========================================================================== 41 class MSLane; 42 class MSVehicle; 43 class OutputDevice; 44 45 46 // =========================================================================== 47 // class definitions 48 // =========================================================================== 49 /** 50 * @class MSInductLoop 51 * @brief An unextended detector measuring at a fixed position on a fixed lane. 52 * 53 * Only vehicles that passed the entire detector are counted. We 54 * ignore vehicles that are emitted onto the detector and vehicles 55 * that change their lane while they are on the detector, because we 56 * cannot determine a meaningful enter/leave-times. 57 * 58 * This detector uses the MSMoveReminder mechanism, i.e. the vehicles 59 * call the detector if they pass it. 60 * 61 * @see MSMoveReminder 62 * @see MSDetectorFileOutput 63 */ 64 class MSInductLoop 65 : public MSMoveReminder, public MSDetectorFileOutput { 66 public: 67 /** 68 * @brief Constructor. 69 * 70 * Adds reminder to MSLane. 71 * 72 * @param[in] id Unique id 73 * @param[in] lane Lane where detector works on 74 * @param[in] position Position of the detector within the lane 75 * @param[in] vTypes which vehicle types are considered 76 */ 77 MSInductLoop(const std::string& id, MSLane* const lane, 78 double positionInMeters, 79 const std::string& vTypes); 80 81 82 /// @brief Destructor 83 ~MSInductLoop(); 84 85 86 /** @brief Resets all generated values to allow computation of next interval 87 */ 88 virtual void reset(); 89 90 91 /** @brief Returns the position of the detector on the lane 92 * @return The detector's position in meters 93 */ getPosition()94 double getPosition() const { 95 return myPosition; 96 } 97 98 99 /// @name Methods inherited from MSMoveReminder 100 /// @{ 101 /** @brief Checks whether the reminder is activated by a vehicle entering the lane 102 * 103 * Lane change means in this case that the vehicle changes to the lane 104 * the reminder is placed at. 105 * 106 * @param[in] veh The entering vehicle. 107 * @param[in] reason how the vehicle enters the lane 108 * @return True if vehicle enters the induction loop 109 * @see Notification 110 */ 111 bool notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* enteredLane = 0); 112 113 /** @brief Checks whether the vehicle shall be counted and/or shall still touch this MSMoveReminder 114 * 115 * As soon a vehicle enters the detector, its entry time is computed and stored 116 * in myVehiclesOnDet via enterDetectorByMove. If it passes the detector, the 117 * according leaving time is computed and stored, too, using leaveDetectorByMove. 118 * 119 * @param[in] veh Vehicle that asks this remider. 120 * @param[in] oldPos Position before move. 121 * @param[in] newPos Position after move with newSpeed. 122 * @param[in] newSpeed Moving speed. 123 * @return True if vehicle hasn't passed the detector completely. 124 * @see MSMoveReminder 125 * @see MSMoveReminder::notifyMove 126 * @see enterDetectorByMove 127 * @see leaveDetectorByMove 128 */ 129 bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double newSpeed); 130 131 132 /** @brief Dismisses the vehicle if it is on the detector due to a lane change 133 * 134 * If the vehicle is on the detector, it will be dismissed by incrementing 135 * myDismissedVehicleNumber and removing this vehicle's entering time from 136 * myVehiclesOnDet. 137 * 138 * @param[in] veh The leaving vehicle. 139 * @param[in] lastPos Position on the lane when leaving. 140 * @param[in] isArrival whether the vehicle arrived at its destination 141 * @param[in] isLaneChange whether the vehicle changed from the lane 142 * @see leaveDetectorByLaneChange 143 * @see MSMoveReminder 144 * @see MSMoveReminder::notifyLeave 145 */ 146 bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 147 148 149 //@} 150 151 152 153 /// @name Methods returning current values 154 /// @{ 155 156 /** @brief Returns the speed of the vehicle on the detector 157 * 158 * If no vehicle is on the detector, -1 is returned, otherwise 159 * this vehicle's current speed. 160 * 161 * @return The speed [m/s] of the vehicle if one is on the detector, -1 otherwise 162 */ 163 double getCurrentSpeed() const; 164 165 166 /** @brief Returns the length of the vehicle on the detector 167 * 168 * If no vehicle is on the detector, -1 is returned, otherwise 169 * this vehicle's length. 170 * 171 * @return The length [m] of the vehicle if one is on the detector, -1 otherwise 172 */ 173 double getCurrentLength() const; 174 175 176 /** @brief Returns the current occupancy 177 * 178 * If a vehicle is on the detector, 1 is returned. If a vehicle has passed the detector 179 * in this timestep, its occupancy value is returned. If no vehicle has passed, 180 * 0 is returned. 181 * 182 * @return This detector's current occupancy 183 * @todo recheck (especially if more than one vehicle has passed) 184 */ 185 double getCurrentOccupancy() const; 186 187 188 /** @brief Returns the number of vehicles that have passed the detector 189 * 190 * If a vehicle is on the detector, 1 is returned. If a vehicle has passed the detector 191 * in this timestep, 1 is returned. If no vehicle has passed, 192 * 0 is returned. 193 * 194 * @return The number of vehicles that have passed the detector 195 * @todo recheck (especially if more than one vehicle has passed) 196 */ 197 int getCurrentPassedNumber() const; 198 199 200 /** @brief Returns the ids of vehicles that have passed the detector 201 * 202 * @return The ids of vehicles that have passed the detector 203 * @todo recheck (especially if more than one vehicle has passed) 204 */ 205 std::vector<std::string> getCurrentVehicleIDs() const; 206 207 208 /** @brief Returns the time since the last vehicle left the detector 209 * 210 * @return Timesteps from last leaving (detection) of the detector 211 */ 212 double getTimeSinceLastDetection() const; 213 //@} 214 215 216 217 /// @name Methods inherited from MSDetectorFileOutput. 218 /// @{ 219 220 /** @brief Writes collected values into the given stream 221 * 222 * @param[in] dev The output device to write the data into 223 * @param[in] startTime First time step the data were gathered 224 * @param[in] stopTime Last time step the data were gathered 225 * @see MSDetectorFileOutput::writeXMLOutput 226 * @exception IOError If an error on writing occurs (!!! not yet implemented) 227 */ 228 void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime); 229 230 231 /** @brief Opens the XML-output using "detector" as root element 232 * 233 * @param[in] dev The output device to write the root into 234 * @see MSDetectorFileOutput::writeXMLDetectorProlog 235 * @exception IOError If an error on writing occurs (!!! not yet implemented) 236 */ 237 void writeXMLDetectorProlog(OutputDevice& dev) const; 238 /// @} 239 240 241 242 /** @brief Struct to store the data of the counted vehicle internally. 243 * 244 * These data is fed into a container. 245 * 246 * @see myVehicleDataCont 247 */ 248 struct VehicleData { 249 /** @brief Constructor 250 * 251 * Used if the vehicle has passed the induct loop completely 252 * 253 * @param[in] vehLength The length of the vehicle 254 * @param[in] entryTimestep The time at which the vehicle entered the detector 255 * @param[in] leaveTimestep The time at which the vehicle left the detector 256 */ VehicleDataVehicleData257 VehicleData(const std::string& id, double vehLength, double entryTimestep, double leaveTimestep, 258 const std::string& typeID) 259 : idM(id), lengthM(vehLength), entryTimeM(entryTimestep), leaveTimeM(leaveTimestep), 260 speedM(vehLength / MAX2(leaveTimestep - entryTimestep, NUMERICAL_EPS)), typeIDM(typeID) {} 261 262 /// @brief The id of the vehicle 263 std::string idM; 264 /// @brief Length of the vehicle 265 double lengthM; 266 /// @brief Entry-time of the vehicle in [s] 267 double entryTimeM; 268 /// @brief Leave-time of the vehicle in [s] 269 double leaveTimeM; 270 /// @brief Speed of the vehicle in [m/s] 271 double speedM; 272 /// @brief Type of the vehicle in 273 std::string typeIDM; 274 }; 275 276 277 /** @brief Returns vehicle data for vehicles that have been on the detector starting at the given time 278 * 279 * @param[in] t The time from which vehicles shall be counted 280 * @param[in] leaveTime Whether entryTime or leaveTime shall be compared against t 281 * (the latter gives a more complete picture but may include vehicles in multiple steps even if they did not stay on the detector) 282 * @return The list of vehicles 283 */ 284 virtual std::vector<VehicleData> collectVehiclesOnDet(SUMOTime t, bool leaveTime = false) const; 285 286 /// @brief allows for special color in the gui version setSpecialColor(const RGBColor *)287 virtual void setSpecialColor(const RGBColor* /*color*/) {}; 288 289 protected: 290 /// @name Methods that add and remove vehicles from internal container 291 /// @{ 292 293 /** @brief Introduces a vehicle to the detector's map myVehiclesOnDet. 294 * @param veh The entering vehicle. 295 * @param entryTimestep Timestep (not necessary integer) of entrance. 296 */ 297 virtual void enterDetectorByMove(SUMOTrafficObject& veh, double entryTimestep); 298 299 300 /** @brief Processes a vehicle that leaves the detector 301 * 302 * Removes a vehicle from the detector's map myVehiclesOnDet and 303 * adds the vehicle data to the internal myVehicleDataCont. 304 * 305 * @param veh The leaving vehicle. 306 * @param leaveTimestep Timestep (not necessary integer) of leaving. 307 */ 308 virtual void leaveDetectorByMove(SUMOTrafficObject& veh, double leaveTimestep); 309 310 311 /** @brief Removes a vehicle from the detector's map myVehiclesOnDet. 312 * @param veh The leaving vehicle. 313 * @param lastPos The last position of the leaving vehicle. 314 */ 315 virtual void leaveDetectorByLaneChange(SUMOTrafficObject& veh, double lastPos); 316 /// @} 317 318 319 protected: 320 /// @name Function for summing up values 321 ///@{ 322 323 /// @brief Adds up VehicleData::speedM speedSum(double sumSoFar,const MSInductLoop::VehicleData & data)324 static inline double speedSum(double sumSoFar, const MSInductLoop::VehicleData& data) { 325 return sumSoFar + data.speedM; 326 } 327 328 /// @brief Adds up VehicleData::lengthM lengthSum(double sumSoFar,const MSInductLoop::VehicleData & data)329 static inline double lengthSum(double sumSoFar, const MSInductLoop::VehicleData& data) { 330 return sumSoFar + data.lengthM; 331 } 332 ///@} 333 334 335 protected: 336 /// @brief Detector's position on lane [m] 337 const double myPosition; 338 339 /// @brief Leave-time of the last vehicle detected [s] 340 double myLastLeaveTime; 341 342 /// @brief Occupancy by the last vehicle detected. 343 double myLastOccupancy; 344 345 /// @brief The number of entered vehicles 346 int myEnteredVehicleNumber; 347 348 349 /// @brief Type of myVehicleDataCont. 350 typedef std::deque< VehicleData > VehicleDataCont; 351 352 /// @brief Data of vehicles that have completely passed the detector 353 VehicleDataCont myVehicleDataCont; 354 355 /// @brief Data of vehicles that have completely passed the detector in the last time interval 356 VehicleDataCont myLastVehicleDataCont; 357 358 359 /// @brief Type of myVehiclesOnDet 360 361 typedef std::map< SUMOTrafficObject*, double > VehicleMap; 362 363 /// @brief Data for vehicles that have entered the detector (vehicle -> enter time) 364 VehicleMap myVehiclesOnDet; 365 366 private: 367 /// @brief Invalidated copy constructor. 368 MSInductLoop(const MSInductLoop&); 369 370 /// @brief Invalidated assignment operator. 371 MSInductLoop& operator=(const MSInductLoop&); 372 373 374 }; 375 376 377 #endif 378 379 /****************************************************************************/ 380 381