LCOV - code coverage report
Current view: top level - src/microsim/devices - MSDevice.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 89.7 % 39 35
Test Date: 2025-11-14 15:59:05 Functions: 60.0 % 5 3

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2007-2025 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.h
      15              : /// @author  Michael Behrisch
      16              : /// @author  Daniel Krajzewicz
      17              : /// @author  Jakob Erdmann
      18              : /// @date    Tue, 04 Dec 2007
      19              : ///
      20              : // Abstract in-vehicle device
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : 
      25              : #include <string>
      26              : #include <vector>
      27              : #include <map>
      28              : #include <set>
      29              : #include <random>
      30              : #include <microsim/MSMoveReminder.h>
      31              : #include <microsim/MSNet.h>
      32              : #include <microsim/MSVehicleType.h>
      33              : #include <microsim/MSVehicleControl.h>
      34              : #include <utils/common/Named.h>
      35              : #include <utils/common/StringUtils.h>
      36              : #include <utils/common/UtilExceptions.h>
      37              : #include <utils/options/OptionsCont.h>
      38              : 
      39              : 
      40              : // ===========================================================================
      41              : // class declarations
      42              : // ===========================================================================
      43              : class OutputDevice;
      44              : class SUMOVehicle;
      45              : class MSTransportable;
      46              : class SUMOSAXAttributes;
      47              : class MSVehicleDevice;
      48              : class MSTransportableDevice;
      49              : 
      50              : 
      51              : // ===========================================================================
      52              : // class definitions
      53              : // ===========================================================================
      54              : /**
      55              :  * @class MSDevice
      56              :  * @brief Abstract in-vehicle / in-person device
      57              :  *
      58              :  * The MSDevice-interface brings the following interfaces to a vehicle /person that
      59              :  *  may be overwritten by real devices:
      60              :  * @arg Building and retrieval of a device id
      61              :  */
      62              : class MSDevice : public Named {
      63              : public:
      64              :     /** @brief Inserts options for building devices
      65              :      * @param[filled] oc The options container to add the options to
      66              :      */
      67              :     static void insertOptions(OptionsCont& oc);
      68              : 
      69              :     /** @brief check device-specific options
      70              :      * @param[filled] oc The options container with the user-defined options
      71              :      */
      72              :     static bool checkOptions(OptionsCont& oc);
      73              : 
      74              : 
      75              :     /** @brief Build devices for the given vehicle, if needed
      76              :     *
      77              :     * @param[in] v The vehicle for which a device may be built
      78              :     * @param[filled] into The vector to store the built device in
      79              :     */
      80              :     static void buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into);
      81              : 
      82              :     /** @brief Build devices for the given person, if needed
      83              :     *
      84              :     * @param[in] p The person for which a device may be built
      85              :     * @param[filled] into The vector to store the built device in
      86              :     */
      87              :     static void buildTransportableDevices(MSTransportable& p, std::vector<MSTransportableDevice*>& into);
      88              : 
      89              :     /// @brief extracts the deviceName from the id (which includes holder id) and is subject to special cases
      90              :     static std::string getDeviceName(const std::string& id);
      91              : 
      92              :     static SumoRNG* getEquipmentRNG() {
      93              :         return &myEquipmentRNG;
      94              :     }
      95              : 
      96              :     /// @brief return the name for this type of device
      97              :     virtual const std::string deviceName() const = 0;
      98              : 
      99              :     /// @brief perform cleanup for all devices
     100              :     static void cleanupAll();
     101              : 
     102              :     static const std::string LOADSTATE_DEVICENAMES;
     103              : 
     104              : public:
     105              :     /** @brief Constructor
     106              :      *
     107              :      * @param[in] id The ID of the device
     108              :      */
     109         2557 :     MSDevice(const std::string& id) : Named(id) {
     110              :     }
     111              : 
     112              : 
     113              :     /// @brief Destructor
     114      6120964 :     virtual ~MSDevice() { }
     115              : 
     116              : 
     117              :     /** @brief Called on vehicle deletion to extend tripinfo and other outputs
     118              :      *
     119              :      * The device may write some statistics into the tripinfo output and may
     120              :      *  choose to finalize its own outputs. It is assumed that the
     121              :      *  information written to tripinfoOut is a valid xml-snipplet, which
     122              :      *  will be embedded within the vehicle's tripinfo information.
     123              :      *
     124              :      * The device should use the openTag / closeTag methods of the OutputDevice
     125              :      *  for correct indentation.
     126              :      *
     127              :      * @exception IOError not yet implemented
     128              :      */
     129       978751 :     virtual void generateOutput(OutputDevice* /*tripinfoOut*/) const {
     130       978751 :     }
     131              : 
     132              :     /** @brief Saves the state of the device
     133              :      *
     134              :      * The default implementation writes a warning and does nothing.
     135              :      * @param[in] out The OutputDevice to write the information into
     136              :      */
     137              :     virtual void saveState(OutputDevice& out) const;
     138              : 
     139              :     /** @brief Loads the state of the device from the given description
     140              :      *
     141              :      * The default implementation does nothing.
     142              :      * @param[in] attrs XML attributes describing the current state
     143              :      */
     144              :     virtual void loadState(const SUMOSAXAttributes& attrs);
     145              : 
     146              :     /// @brief try to retrieve the given parameter from this device. Throw exception for unsupported key
     147            0 :     virtual std::string getParameter(const std::string& key) const {
     148            0 :         throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
     149              :     }
     150              : 
     151              :     /// @brief try to set the given parameter for this device. Throw exception for unsupported key
     152            0 :     virtual void setParameter(const std::string& key, const std::string& value) {
     153              :         UNUSED_PARAMETER(value);
     154            0 :         throw InvalidArgument("Setting parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
     155              :     }
     156              : 
     157              : protected:
     158              :     /// @name Helper methods for device assignment
     159              :     /// @{
     160              : 
     161              :     /** @brief Adds common command options that allow to assign devices to vehicles
     162              :      *
     163              :      * @param[in] deviceName The name of the device type
     164              :      * @param[in] optionsTopic The options topic into which the options shall be added
     165              :      * @param[filled] oc The options container to add the options to
     166              :      */
     167              :     static void insertDefaultAssignmentOptions(const std::string& deviceName, const std::string& optionsTopic, OptionsCont& oc, const bool isPerson = false);
     168              : 
     169              : 
     170              :     /** @brief Determines whether a vehicle should get a certain device
     171              :      *
     172              :      * @param[in] oc The options container to get the information about assignment from
     173              :      * @param[in] deviceName The name of the device type
     174              :      * @param[in] v The vehicle to determine whether it shall be equipped or not
     175              :      */
     176              :     template<class DEVICEHOLDER>
     177              :     static bool equippedByDefaultAssignmentOptions(const OptionsCont& oc, const std::string& deviceName, DEVICEHOLDER& v, bool outputOptionSet, const bool isPerson = false);
     178              :     /// @}
     179              : 
     180              : 
     181              : private:
     182              :     /// @brief vehicles which explicitly carry a device, sorted by device, first
     183              :     static std::map<std::string, std::set<std::string> > myExplicitIDs;
     184              : 
     185              :     /// @brief A random number generator used to choose from vtype/route distributions and computing the speed factors
     186              :     static SumoRNG myEquipmentRNG;
     187              : 
     188              : 
     189              : private:
     190              :     /// @brief Invalidated copy constructor.
     191              :     MSDevice(const MSDevice&);
     192              : 
     193              :     /// @brief Invalidated assignment operator.
     194              :     MSDevice& operator=(const MSDevice&);
     195              : 
     196              : };
     197              : 
     198              : 
     199              : template<class DEVICEHOLDER> bool
     200    109154808 : MSDevice::equippedByDefaultAssignmentOptions(const OptionsCont& oc, const std::string& deviceName, DEVICEHOLDER& v, bool outputOptionSet, const bool isPerson) {
     201    215971385 :     const std::string prefix = (isPerson ? "person-device." : "device.") + deviceName;
     202              :     // assignment by number
     203    326951073 :     bool numberGiven = ((oc.exists(prefix + ".deterministic") && oc.getBool(prefix + ".deterministic"))
     204    435862504 :                         || (oc.exists(prefix + ".probability") && oc.getFloat(prefix + ".probability") >= 0.));
     205    109154808 :     double probability = numberGiven ? oc.getFloat(prefix + ".probability") : 0;
     206              :     // assignment by name
     207              :     bool haveByName = false;
     208              :     bool nameGiven = false;
     209    217796265 :     if (oc.exists(prefix + ".explicit") && oc.isSet(prefix + ".explicit")) {
     210              :         nameGiven = true;
     211        13546 :         if (myExplicitIDs.find(deviceName) == myExplicitIDs.end()) {
     212          476 :             myExplicitIDs[deviceName] = std::set<std::string>();
     213          476 :             const std::vector<std::string> idList = OptionsCont::getOptions().getStringVector(prefix + ".explicit");
     214          476 :             myExplicitIDs[deviceName].insert(idList.begin(), idList.end());
     215          476 :         }
     216        27092 :         haveByName = myExplicitIDs[deviceName].count(v.getID()) > 0;
     217              :     }
     218              :     // assignment by abstract parameters
     219              :     bool haveByParameter = false;
     220              :     bool parameterGiven = false;
     221    109154814 :     const std::string key = "has." + deviceName + ".device";
     222    109154808 :     if (v.getParameter().hasParameter(key)) {
     223              :         parameterGiven = true;
     224         7916 :         haveByParameter = StringUtils::toBool(v.getParameter().getParameter(key, "false"));
     225    109150850 :     } else if (v.getVehicleType().getParameter().hasParameter(key)) {
     226              :         parameterGiven = true;
     227        39638 :         haveByParameter = StringUtils::toBool(v.getVehicleType().getParameter().getParameter(key, "false"));
     228    218262056 :     } else if (v.getVehicleType().getParameter().hasParameter(prefix + ".probability")) {
     229              :         // override global options
     230              :         numberGiven = true;
     231         5260 :         probability = StringUtils::toDouble(v.getVehicleType().getParameter().getParameter(prefix + ".probability", "0"));
     232              :     }
     233              :     //std::cout << " deviceName=" << deviceName << " holder=" << v.getID()
     234              :     //    << " nameGiven=" << nameGiven << " haveByName=" << haveByName
     235              :     //    << " parameterGiven=" << parameterGiven << " haveByParameter=" << haveByParameter
     236              :     //    << " numberGiven=" << numberGiven << " haveByNumber=" << haveByNumber
     237              :     //    << " outputOptionSet=" << outputOptionSet << "\n";
     238    109154802 :     if (haveByName) {
     239              :         return true;
     240    109154000 :     } else if (parameterGiven) {
     241              :         return haveByParameter;
     242    109130226 :     } else if (numberGiven) {
     243       544836 :         if (oc.exists(prefix + ".deterministic") && oc.getBool(prefix + ".deterministic")) {
     244           12 :             return MSNet::getInstance()->getVehicleControl().getQuota(probability) == 1;
     245       272406 :         } else if (probability > 0) {
     246       271604 :             if (v.getParameter().hasParameter(LOADSTATE_DEVICENAMES)) {
     247              :                 // replicate probabilistic assignment
     248         2118 :                 const std::vector<std::string> lsdn = StringTokenizer(v.getParameter().getParameter(LOADSTATE_DEVICENAMES)).getVector();
     249         1056 :                 return std::find(lsdn.begin(), lsdn.end(), deviceName) != lsdn.end();
     250         1056 :             } else {
     251       270548 :                 return RandHelper::rand(&myEquipmentRNG) < probability;
     252              :             }
     253              :         } else {
     254              :             return false;
     255              :         }
     256              :     } else {
     257    108857808 :         return !nameGiven && outputOptionSet;
     258              :     }
     259              : }
        

Generated by: LCOV version 2.0-1