/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file NLDetectorBuilder.h14/// @author Daniel Krajzewicz15/// @author Clemens Honomichl16/// @author Christian Roessel17/// @author Michael Behrisch18/// @date Mon, 15 Apr 200219///20// Builds detectors for microsim21/****************************************************************************/22#pragma once23#include <config.h>2425#include <string>26#include <microsim/output/MSCrossSection.h>27#include <microsim/traffic_lights/MSTLLogicControl.h>28#include <microsim/output/MSE2Collector.h>29// #include <microsim/output/MSMultiLaneE2Collector.h>3031// ===========================================================================32// class declarations33// ===========================================================================34class MSDetectorFileOutput;35class MSLane;36class MSEdge;3738class MEInductLoop;39class MESegment;404142// ===========================================================================43// class definitions44// ===========================================================================45/**46* @class NLDetectorBuilder47* @brief Builds detectors for microsim48*49* The building methods may be overridden, to build guisim-instances of the triggers,50* for example.51*/52class NLDetectorBuilder {53public:54/** @brief Constructor55*56* @param[in] net The network to which's detector control built detector shall be added57*/58NLDetectorBuilder(MSNet& net);596061/// @brief Destructor62virtual ~NLDetectorBuilder();636465/// @name Value parsing and detector building methods66/// @{6768/** @brief Builds an e1 detector and adds it to the net69*70* Checks the given values, first. If one of the values is invalid71* (lane is not known, sampling frequency<=0, position is larger72* than lane's length, the id is already in use), an InvalidArgument is thrown.73*74* Otherwise the e1 detector is built by calling "createInductLoop".75*76* Internally, there is also a distinction whether a mesosim e1 detector77* shall be built.78*79* @param[in] id The id the detector shall have80* @param[in] lane The name of the lane the detector is placed at81* @param[in] pos The definition of the position on the lane the detector shall be placed at82* @param[in] length The optional length of the detector83* @param[in] splInterval The aggregation time span the detector shall use84* @param[in] device The output device the detector shall write into85* @param[in] friendlyPos Whether the position information shall be used "friendly" (see user docs)86* @param[in] vTypes which vehicle types are considered87* @exception InvalidArgument If one of the values is invalid88* @return The created detector89*/90Parameterised* buildInductLoop(const std::string& id,91const std::string& lane, double pos, double length, SUMOTime splInterval,92const std::string& device, bool friendlyPos,93const std::string name, const std::string& vTypes, const std::string& nextEdges, int detectPersons);949596/** @brief Builds an instantenous induction and adds it to the net97*98* Checks the given values, first. If one of the values is invalid99* (lane is not known, sampling frequency<=0, position is larger100* than lane's length, the id is already in use), an InvalidArgument is thrown.101*102* Otherwise the e1 detector is built by calling "createInductLoop".103*104* @param[in] id The id the detector shall have105* @param[in] lane The name of the lane the detector is placed at106* @param[in] pos The definition of the position on the lane the detector shall be placed at107* @param[in] device The output device the detector shall write into108* @param[in] friendlyPos Whether the position information shall be used "friendly" (see user docs)109* @exception InvalidArgument If one of the values is invalid110* @return The created detector111*/112Parameterised* buildInstantInductLoop(const std::string& id,113const std::string& lane, double pos,114const std::string& device, bool friendlyPos,115const std::string name, const std::string& vTypes,116const std::string& nextEdges,117int detectPersons);118119120/** @brief Builds a new E2 detector and adds it to the net's detector control. Also performs some121* consistency checks for the detector positioning and applies "friendly positioning"122*123* @param[in] tlls Traffic light logic associated to the detector124* @param[in] toLane Lane associated to the detector (only for tlls != 0)125* @param[in] friendlyPos Whether automatic adjustments of the detector position shall be applied in case of erroneous specification126* @see For the other parameters see the MSE2Collector constructors127*128* @todo Add parameter showDetector to indicate whether the detector should be visible in the GUI129*130*/131Parameterised* buildE2Detector(const std::string& id, MSLane* lane, double pos, double endPos, double length,132const std::string& device, SUMOTime frequency,133SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,134const std::string name, const std::string& vTypes,135const std::string& nextEdges,136int detectPersons, bool friendlyPos, bool showDetector,137MSTLLogicControl::TLSLogicVariants* tlls = 0, MSLane* toLane = 0);138139Parameterised* buildE2Detector(const std::string& id, std::vector<MSLane*> lanes, double pos, double endPos,140const std::string& device, SUMOTime frequency,141SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,142const std::string name, const std::string& vTypes,143const std::string& nextEdges,144int detectPersons, bool friendlyPos, bool showDetector,145MSTLLogicControl::TLSLogicVariants* tlls = 0, MSLane* toLane = 0);146147148/** @brief Stores temporary the initial information about an e3 detector to build149*150* If the given sample interval is < 0, an InvalidArgument is thrown. Otherwise,151* the values are stored in a new instance of E3DetectorDefinition within152* "myE3Definition".153*154* @param[in] id The id the detector shall have155* @param[in] device The output device the detector shall write into156* @param[in] splInterval The aggregation time span the detector shall use157* @param[in] haltingTimeThreshold Detector parameter: the time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed158* @param[in] haltingSpeedThreshold Detector parameter: the speed a vehicle's speed must be below to be assigned as jammed159* @exception InvalidArgument If one of the values is invalid160*/161Parameterised* beginE3Detector(const std::string& id, const std::string& device, SUMOTime splInterval,162double haltingSpeedThreshold, SUMOTime haltingTimeThreshold,163const std::string name, const std::string& vTypes,164const std::string& nextEdges,165int detectPersons, bool openEntry, bool expectArrival);166167168/** @brief Builds an entry point of an e3 detector169*170* If the lane is not known or the position information is not within the lane,171* an InvalidArgument is thrown. Otherwise a MSCrossSection is built172* using the obtained values and added to the list of entries of the e3 definition173* stored in "myE3Definition".174*175* @param[in] lane The id of the lane the entry shall be placed at176* @param[in] pos The position on the lane the entry shall be placed at177* @param[in] friendlyPos Whether the position information shall be used "friendly" (see user docs)178* @exception InvalidArgument If one of the values is invalid179*/180void addE3Entry(const std::string& lane, double pos, bool friendlyPos);181182183/** @brief Builds an exit point of an e3 detector184*185* If the lane is not known or the position information is not within the lane,186* an InvalidArgument is thrown. Otherwise a MSCrossSection is built187* using the obtained values and added to the list of exits of the e3 definition188* stored in "myE3Definition".189*190* @param[in] lane The id of the lane the exit shall be placed at191* @param[in] pos The position on the lane the exit shall be placed at192* @param[in] friendlyPos Whether the position information shall be used "friendly" (see user docs)193* @exception InvalidArgument If one of the values is invalid194*/195void addE3Exit(const std::string& lane, double pos, bool friendlyPos);196197198/** @brief Builds of an e3 detector using collected values199*200* The parameter collected are used to build an e3 detector using201* "createE3Detector". The resulting detector is added to the net.202*203* @param[in] lane The id of the lane the exit shall be placed at204* @param[in] pos The position on the lane the exit shall be placed at205* @exception InvalidArgument If one of the values is invalid206*/207void endE3Detector();208209210/** @brief Returns the id of the currently built e3 detector211*212* This is used for error-message generation only. If no id is known,213* "<unknown>" is returned.214*215* @return The id of the currently processed e3 detector216*/217std::string getCurrentE3ID() const;218219220/** @brief Builds a vTypeProbe and adds it to the net221*222* Checks the given values, first. If one of the values is invalid223* (sampling frequency<=0), an InvalidArgument is thrown.224*225* Otherwise the vTypeProbe is built (directly).226*227* @param[in] id The id the detector shall have228* @param[in] vtype The name of the vehicle type the detector shall observe229* @param[in] frequency The reporting frequency230* @param[in] device The output device the detector shall write into231* @exception InvalidArgument If one of the values is invalid232*/233void buildVTypeProbe(const std::string& id,234const std::string& vtype, SUMOTime frequency,235const std::string& device);236237238/** @brief Builds a routeProbe and adds it to the net239*240* Checks the given values, first. If one of the values is invalid241* (sampling frequency<=0), an InvalidArgument is thrown.242*243* Otherwise the routeProbe is built (directly).244*245* @param[in] id The id the detector shall have246* @param[in] edge The name of the edge the detector shall observe247* @param[in] frequency The reporting frequency248* @param[in] begin The start of the first reporting interval249* @param[in] device The output device the detector shall write into250* @exception InvalidArgument If one of the values is invalid251*/252void buildRouteProbe(const std::string& id, const std::string& edge,253SUMOTime frequency, SUMOTime begin,254const std::string& device,255const std::string& vTypes);256/// @}257258259260/// @name Detector creating methods261///262/// Virtual, so they may be overwritten, for generating gui-versions of the detectors, for example.263/// @{264265/** @brief Creates an instance of an e1 detector using the given values266*267* Simply calls the MSInductLoop constructor268*269* @param[in] id The id the detector shall have270* @param[in] lane The lane the detector is placed at271* @param[in] pos The position on the lane the detector is placed at272* @param[in] length The optional length of the detector273* @param[in] vTypes which vehicle types are considered274* @param[in] show Whether to show the detector in the gui if available275*/276virtual MSDetectorFileOutput* createInductLoop(const std::string& id,277MSLane* lane, double pos,278double length,279const std::string name, const std::string& vTypes,280const std::string& nextEdges,281int detectPersons,282bool show);283284285/** @brief Creates an instance of an e1 detector using the given values286*287* Simply calls the MSInductLoop constructor288*289* @param[in] id The id the detector shall have290* @param[in] lane The lane the detector is placed at291* @param[in] pos The position on the lane the detector is placed at292* @param[in] od The output device the loop shall use293*/294virtual MSDetectorFileOutput* createInstantInductLoop(const std::string& id,295MSLane* lane, double pos, const std::string& od,296const std::string name, const std::string& vTypes,297const std::string& nextEdges,298int detectPersons);299300301/** @brief Creates a MSE2Collector instance, overridden by GUIE2Collector::createE2Detector()302*303* Simply calls the MSE2Collector constructor304*305* @see MSE2Collector Constructor documentation306*/307virtual MSE2Collector* createE2Detector(const std::string& id,308DetectorUsage usage, MSLane* lane, double pos, double endPos, double length,309SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,310const std::string name, const std::string& vTypes,311const std::string& nextEdges,312int detectPersons, bool showDetector);313314virtual MSE2Collector* createE2Detector(const std::string& id,315DetectorUsage usage, std::vector<MSLane*> lanes, double pos, double endPos,316SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,317const std::string name, const std::string& vTypes,318const std::string& nextEdges,319int detectPersons, bool showDetector);320321/** @brief Creates an instance of an e3 detector using the given values322*323* Simply calls the MSE3Collector constructor.324*325* @param[in] id The id the detector shall have326* @param[in] entries The list of this detector's entries327* @param[in] exits The list of this detector's exits328* @param[in] haltingSpeedThreshold Detector parameter: the speed a vehicle's speed must be below to be assigned as jammed329* @param[in] haltingTimeThreshold Detector parameter: the time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed330*/331virtual MSDetectorFileOutput* createE3Detector(const std::string& id,332const CrossSectionVector& entries, const CrossSectionVector& exits,333double haltingSpeedThreshold, SUMOTime haltingTimeThreshold,334const std::string name, const std::string& vTypes,335const std::string& nextEdges,336int detectPersons, bool openEntry, bool expectArrival);337338339/** @brief Creates edge based mean data collector using the given specification340*341* @param[in] id The id the detector shall have342* @param[in] frequency The aggregation interval the detector shall use343* @param[in] begin dump begin time344* @param[in] end dump end time345* @param[in] type The type of values to be generated346* @param[in] useLanes Information whether lane-based or edge-based dump shall be generated347* @param[in] withEmpty Information whether empty lanes/edges shall be written348* @param[in] withInternal Information whether internal lanes/edges shall be written349* @param[in] trackVehicles Information whether information shall be collected per vehicle350* @param[in] detectPersons Whether pedestrians shall be detected instead of vehicles351* @param[in] maxTravelTime the maximum travel time to output352* @param[in] minSamples the minimum number of sample seconds before the values are valid353* @param[in] haltSpeed the maximum speed to consider a vehicle waiting354* @param[in] vTypes the set of vehicle types to consider355* @exception InvalidArgument If one of the values is invalid356*/357void createEdgeLaneMeanData(const std::string& id, SUMOTime frequency,358SUMOTime begin, SUMOTime end, const std::string& type,359const bool useLanes, const bool withEmpty, const bool printDefaults,360const bool withInternal, const bool trackVehicles, const int detectPersons,361const double maxTravelTime, const double minSamples,362const double haltSpeed, const std::string& vTypes,363const std::string& writeAttributes,364std::vector<MSEdge*> edges,365AggregateType aggregate,366const std::string& device);367/// @}368369370protected:371/**372* @class E3DetectorDefinition373* @brief Holds the incoming definitions of an e3 detector unless the detector is build.374*/375class E3DetectorDefinition : public Parameterised {376public:377/** @brief Constructor378* @param[in] id The id the detector shall have379* @param[in] device The output device the detector shall write into380* @param[in] haltingSpeedThreshold Detector parameter: the speed a vehicle's speed must be below to be assigned as jammed381* @param[in] haltingTimeThreshold Detector parameter: the time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed382* @param[in] splInterval The aggregation time span the detector shall use383*/384E3DetectorDefinition(const std::string& id,385const std::string& device, double haltingSpeedThreshold,386SUMOTime haltingTimeThreshold, SUMOTime splInterval,387const std::string name, const std::string& vTypes,388const std::string& nextEdges,389int detectPersons, bool openEntry, bool expectArrival);390391/// @brief Destructor392virtual ~E3DetectorDefinition();393394/// @brief The id of the detector395const std::string myID;396/// @brief The device the detector shall use397const std::string myDevice;398/// @brief The speed a vehicle's speed must be below to be assigned as jammed399double myHaltingSpeedThreshold;400/// @brief The time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed401SUMOTime myHaltingTimeThreshold;402/// @brief List of detector's entries403CrossSectionVector myEntries;404/// @brief List of detector's exits405CrossSectionVector myExits;406/// @brief The aggregation interval407SUMOTime mySampleInterval;408/// @brief name409std::string myName;410/// @brief The types to filter411const std::string myVehicleTypes;412/// @brief The route edges to filter by413const std::string myNextEdges;414/// @brief person detection mode415int myDetectPersons;416/// @brief Whether the detector is declared as having incomplete entry detectors417bool myOpenEntry;418/// @brief Whether the detector expects vehicles to arrive inside (and doesn't issue a warning in this case)419bool myExpectArrival;420//@}421422private:423/// @brief Invalidated copy constructor.424E3DetectorDefinition(const E3DetectorDefinition&);425426/// @brief Invalidated assignment operator.427E3DetectorDefinition& operator=(const E3DetectorDefinition&);428429};430431432protected:433/** @brief Computes the position to use434*435* At first, it is checked whether the given position is negative. If so, the436* position is added to the lane's length to obtain the position counted437* backwards.438*439* If the resulting position is beyond or in front (<0) of the lane, it is either440* set to the according lane's boundary (.1 or length-.1) if friendlyPos441* is set, or, if friendlyPos is not set, an InvalidArgument is thrown.442*443* @param[in] pos Definition of the position on the lane444* @param[in] lane The lane the position must be valid for445* @param[in] friendlyPos Whether false positions shall be made acceptable446* @param[in] detid The id of the currently built detector (for error message generation)447* @exception InvalidArgument If the defined position is invalid448*/449double getPositionChecking(double pos, MSLane* lane, bool friendlyPos,450SumoXMLTag tag,451const std::string& detid);452453454/// @name Value checking/adapting methods455/// @{456457/** @brief Returns the named edge458* @param[in] edgeID The id of the lane459* @param[in] type The type of the detector (for error message generation)460* @param[in] detid The id of the currently built detector (for error message generation)461* @exception InvalidArgument If the named edge is not known462*/463MSEdge* getEdgeChecking(const std::string& edgeID, SumoXMLTag type,464const std::string& detid);465466public:467/** @brief Returns the named lane468* @param[in] laneID The id of the lane469* @param[in] type The type of the detector (for error message generation)470* @param[in] detid The id of the currently built detector (for error message generation)471* @exception InvalidArgument If the named lane is not known472*/473MSLane* getLaneChecking(const std::string& laneID, SumoXMLTag type,474const std::string& detid);475476protected:477/** @brief Checks whether the given frequency (sample interval) is valid478* @param[in] splInterval The sample interval479* @param[in] type The type of the detector (for error message generation)480* @param[in] id The id of the detector (for error message generation)481* @exception InvalidArgument If the given sample interval is invalid (<=0)482* @todo Why is splInterval an int???483*/484void checkSampleInterval(SUMOTime splInterval, SumoXMLTag type, const std::string& id);485/// @}486487488protected:489/// @brief The net to fill490MSNet& myNet;491492493private:494/// @brief definition of the currently parsed e3 detector495E3DetectorDefinition* myE3Definition;496497498private:499/// @brief Invalidated copy constructor.500NLDetectorBuilder(const NLDetectorBuilder&);501502/// @brief Invalidated assignment operator.503NLDetectorBuilder& operator=(const NLDetectorBuilder&);504505};506507508