# Module Structure The flowchart of the `FleetPy` can be shown from the following figure. ![Main simulation flow of FleetyPy](./figures/1_flowchart.jpg) The simulation modules will be selected in the input parameters, which determine the codes to execute during the `step` method of the simulation flow. The simulation creates disaggregated records for vehicles, users, and the infrastructure (if applicable). The remaining part will introduce the following modules in details: - Simulation module - Network module - Demand (Traveler) module - Vehicle module - Fleet operator module: includes different operation strategies - Miscellaneous contents ## Simulation Module There are two general structural flowcharts of simulation flow * event-based, i.e. requests accept/reject immediately after request (sequentially) * time-based, i.e. requests accept/reject in a batch ![Difference Simulation Flows for ImmediateDecisionSimulation and BatchOfferSimulation.](./figures/1_immediate_vs_batch.jpg) New simulation flows can be derived from FleetSimulationBase by for example overwriting the `step(...)`, which defines the simulation flow in each time step. ### BatchOfferSimulation Customers request trips from a single ride-pooling operator continuously in time. Offers are only created after the optimisation step of the operator and fetched from the `time_trigger` function. The `step(...)` function consists of the following steps: 1. update fleets and network 2. get new travelers, and add to undecided request 3. make request (without immediate response) to operators 4. periodically for waiting requests: run decision process -> possibly leave system (cancellation) 5. call time trigger -> offer to all undecided assigned requests 6. sequential processes for each undecided request: user-decision 7. trigger charging ops file: `src/BatchOfferSimulation.py` ### ImmediateDecisionsSimulation In this simulation each request immediatly decides for or against an offer. The `step(...)` function consists of the following steps: 1. update fleets and network 2. get new travelers, and add to undecided request 3. sequential processes for each undecided request: request -> offer -> user-decision 4. periodically for waiting requests: run decision process -> possibly leave system (cancellation) 5. periodically operator: call ride pooling optimization, repositioning, charging management 6. trigger charging infra file: `src/ImmediateDecisionsSimulation.py` ### BrokerDecisionSimulation This fleet simulation class is used in the publication: > Competition and Cooperation of Autonomous Ridepooling Services: Game-Based Simulation of a Broker Concept; Engelhardt, Malcolm, Dandl, Bogenberger (2022) DOI: https://doi.org/10.3389/ffutr.2022.915219 > In this case, offers from two different fleetcontrols are collected and a broker decides which of these offers will be forwarded to the customer and the customer always chooses this offer. The `BrokerDescisionFleetCtrl` has to be used for operators to create all needed offer attributes for the broker decision. file: `src/BrokerSimulation.py` ## Network Module Network modules can be found in the folder `src/routing`. The tasks of network modules can be divided into two: 1. Represent the road network, which is accessible to the vehicles, to provide a representation of the traffic state. 2. Provide efficient routing methods to calculate paths and travel times between different locations in the network. Different network representations (modules) inherit from the base class defined in `src/routing/NetworkBase.py`. The following figure compares the computational efficiency using different methods. ![Impact of different network modules on computational time of routing queries.](./figures/1_network_module_comptime.png) The following network modules are currently available. The selected network modules are controlled by the parameter `network_type`. ### NetworkBasic This routing class does all routing computations based on Dijkstra's algorithm implemented in Python. file: `src/routing/NetworkBasic.py` ### NetworkBasicWithStore This routing class does all routing computations based on Dijkstra's algorithm. Compared to `NetworkBasic`, this class stores already computed travel information in a dictionary and returns the values from this dictionary if queried again. file: `src/routing/NetworkBasicWithStore.py` ### NetworkPartialPreprocessed This network uses [NumPy](https://numpy.org/) travel time tables that are processed beforehand and stored in the data folder. Instead of preprocessing the whole network, only the travel time of the shortest routes between first x nodes are preprocessed. Note that nodes should be sorted first based on their expected usage as routing targets. see: * `src/preprocessing/networks/create_partially_preprocessed_travel_time_tables.py` for creating the NumPy tables This network stores additionally computed traveltimes in a dictionary and reuses this data. As fallback, Dijkstra's algorithm implemented in Python is used. file: `src/routing/NetworkPartialPreprocessed.py` ### NetworkTTMatrix Routing based on a preprocessed travel time (TT)-Matrix. For changing travel-times, tt-scaling factors can be read from a file. see: `src/preprocessing/networks/create_travel_time_tables.py` for creating the NumPy tables. file: `src/routing/NetworkTTMatrix.py` ### Variants implemented in C++ To install the coupling to C++, you need to run `src/routing/cpp_router/setup.py` #### NetworkBasicCpp This routing class does all routing computations based on Dijkstra's algorithm. Compared to `NetworkBasic`, this module has the same methods but is implemented in C++ and included via Cython. file: `src/routing/NetworkBasicCpp.py` #### NetworkBasicWithStoreCpp This routing class does all routing computations based on Dijkstra's algorithm. Compared to `NetworkBasicWithStore`, this module has the same methods but is implemented in C++ and included via Cython. file: `src/routing/NetworkBasicWithStoreCpp.py` #### NetworkPartialPreprocessedCpp This network uses [NumPy](https://numpy.org/) travel time tables that are processed beforehand and stored in the data folder. Compared to `NetworkPartialPreprocessed`, this module has the same methods but is implemented in C++ and included via Cython. file: `src/routing/NetworkPartialPreprocessedCpp.py` ## Traveler Module Traveler modules define how customers/requests behave when performing trips in the simulation environment. These classes are used to store characteristics of a customer (e.g. behavioral parameters), collect information of a conducted trip during the simulation and writes the information to the user-output file. All interface methods used during the simulation can be found by exploring the base class `RequestBase`. If a new traveler has to be implemented, the class should inherit from `RequestBase`. In the following some already implemented customer classes are described. The selected traveler modules are controlled by the parameter `rq_type`. file: `src\demand\TravelerModels.py` ![Impact of different customer models on user statistics.](./figures/4_customer_models.png) ### BasicRequest This request only performs a mode choice based on if it recieved an offer or not. if an offer is recieved, it accepts the offer. if multiple offers are recieved an error is thrown. file: `src\demand\TravelerModels.py` ### IndividualConstraintRequest This request class makes decisions based on hard constraints; individual constraints can be read from demand file columns. If an operator offer satisfies these, it will be accepted. Moreover, it can be used to communicate earliest and latest pick-up time to the operators. file: `src\demand\TravelerModels.py` ### PriceSensitiveIndividualConstraintRequest This request class can be used to communicate earliest and latest pick-up time to the operators. Moreover, the requests have a maximum price they are willing to pay. file: `src\demand\TravelerModels.py` ### WaitingTimeSensitiveLinearDeclineRequest This request is sensitive to waiting_times: * all offers are accepted if waiting time is below G_AR_MAX_WT * all offers are decline if waiting time is higher than G_AR_MAX_WT_2 * linear decrease of probability of acceptance between G_AR_MAX_WT and G_AR_MAX_WT_2 file: `src\demand\TravelerModels.py` ### PreferredOperatorRequest this request is used for the broker scenarios as base case of (quasi) independent operators. The customer chooses: * self.preferred op, if an offer is recieved from this op * declines else This is used to meassure if the unpreferred op was able to create an offer. Requires simulation class PreferredOperatorSimulation. file: `src\demand\TravelerModels.py` ### BrokerDecisionRequest This request class is used for the broker decision simulation where a broker instead of the customer decides on which offer to take. The broker marks offers, that it has been chosen by the flag G_OFFER_BROKER_FLAG which is unique. This request class will only accept these marked offers. Requires simulation class BrokerDecisionSimulation ! file: `src\demand\TravelerModels.py` ### UserDecisionRequest This request class is used for the easyride user decision simulation. The user chooses the offer with the lowest overall travel time. file: `src\demand\TravelerModels.py` ### MasterRandomChoiceRequest This request class randomly chooses between options. file: `src\demand\TravelerModels.py` ### SlaveRequest This request class does not have any choice functionality. (i.e. is used when mode choice is performed outside of FleetPy) file: `src\demand\TravelerModels.py` ### ParcelRequestBase This is a base class for parcels that are represented as travelers. file: `src\demand\TravelerModels.py` ### BasicParcelRequest This parcel request can be used only for a single operator. It always accepts an offer coming from this operator. file: `src\demand\TravelerModels.py` ### SlaveParcelRequest This parcel request class does not have any choice functionality. For coupled frameworks only! file: `src\demand\TravelerModels.py` ## Vehicle Module tbc ## Fleet Control Modules Fleet control modules define how operators of MoD services control their fleets. Interface methods to the simulation class are defined in the base class `FleetControlBase` in the file `src\fleetctrl\FleetControlBase.py`. If a new Fleet control class is to be implemented, the new class has to inherit from this base class. The fleet control module defines how the service is adopted for example with respect to time-triggers or new requests and usually implements how new vehicle routes are assigned to fleet vehicles e.g. by applying an assignment algorithm (VRP) or rebalance the fleet according to expected future demand. Depending on the setting, different sub-modules can be selected that implement specific aspects of the control tasks. These sub-modules include: * Assignment-algorithm * Rebalancing-algorithm * Charging-tasks * Long-term reservation tasks * Dynamic pricing * Dynamic fleet sizing In the following the implemented upper level fleet control modules are described, followed by the different sub-modules. The selected fleet control module is controlled by the parameter `op_module`. ![Impact of different fleet control modules.](./figures/5_fleet_control_impacts.png) ### PoolingInsertionHeuristicOnly This class applies an Insertion Heuristic, in which new requests are inserted in the currently assigned vehicle plans and the insertion with the best control objective value is selected. IMPORTANT NOTE: Both the new and the previously assigned plan are stored and await an instant response of the request. Therefore, this fleet control module is only consistent for the ImmediateOfferSimulation class. file: `src\fleetctrl\PoolingIRSOnly.py` ### RidePoolingBatchOptimizationFleetControlBase This is a further base class for ride-pooling fleet controls that perform batch optimization algorithm. THIS CLASS IS FOR INHERITANCE ONLY. this class can be used for common ride-pooling studies using a batch assignmant algorithm for optimisation triggered in the _time_trigger_request_batch() method customers are introduced by the user_request() function, for each customer requesting a trip, either the method user_confirms_booking() or user_cancels_request has to be called! DEPENDING ON THE MODELLED CUSTOMER-FLEETOPERATOR-INTERACTION-FOLLOWING METHODS HAVE TO BE EXTENDED. * user_request() * user_confirms_booking() * user_cancels_request() * time_trigger() file: `src\fleetctrl\RidePoolingBatchOptimizationFleetControlBase.py` ### PoolingIRSAssignmentBatchOptimization Pooling class that combines an immediate response and batch optimization: * requests enter system continuously * offer has to be created immediately by an insertion heuristic * request replies immediately -> there can never be 2 requests at the same time waiting for an offer! * re-optimization of solution after certain time interval file: `src\fleetctrl\PoolingIRSAssignmentBatchOptimization.py` ### RidePoolingBatchAssignmentFleetcontrol This class assigns and returns offers to customer only in batches. Ride pooling optimisation is called after every optimisation_time_step and offers are created in the time_trigger function. file: `src\fleetctrl\RidePoolingBatchAssignmentFleetcontrol.py` ### BrokerDecisionCtrl this fleetcontrol is used for simulations with a central broker which assigns users to operators in the publication Competition and Cooperation of Autonomous Ridepooling Services: Game-Based Simulation of a Broker Concept; Engelhardt, Malcolm, Dandl, Bogenberger (2022) DOI: https://doi.org/10.3389/ffutr.2022.915219 therefore, in this fleetcontrol the attribute "add fleet vmt" (the addtional driving distance to serve a customer calculated after the insertion heuristic) is added to the offer parameters which is used by the broker as a decision variable. file: `src\fleetctrl\BrokerAndExchangeFleetControl.py` ### RPPFleetControlFullInsertion this class is used in the paper Integrating Parcel Deliveries into a Ride-Pooling Service - An Agent-Based Simulation Study; Fehn, Engelhardt, Dandl, Bogenberger, Busch (2022) DOI: https://doi.org/10.1016/j.tra.2022.103580 Parcel deliveries are integrated in a ride-pooling service. No explicit time constraints are assumed for parcel pick-ups and drop-offs. Parcels are picked up and dropped off, when vehicles pass by origin or destination during passenger transport the "closeness" of vehicle routes to parcels is defined by the parameter G_OP_PA_ASSTH (between 0 and 1, with 1 reflecting that parcel o and d is directly on the vehicle route). G_OP_PA_OBASS (bool) describes the integration. if False, an insertion of parcels into vehicle routes is only allowed, when no passenger is on board. This class represents the CDPA strategy in the paper. origin and destination of parcels are directly inserted, when vehicle pass by. the fleet control requires an immediate descision process in the simulation class file: `src\fleetctrl\RPPFleetControl.py` ### RPPFleetControlSingleStopInsertion this class is used in the paper Integrating Parcel Deliveries into a Ride-Pooling Service - An Agent-Based Simulation Study; Fehn, Engelhardt, Dandl, Bogenberger, Busch (2022) DOI: https://doi.org/10.1016/j.tra.2022.103580 Parcel deliveries are integrated in a ride-pooling service. No explicit time constraints are assumed for parcel pick-ups and drop-offs. Parcels are picked up and dropped off, when vehicles pass by origin or destination during passenger transport the "closeness" of vehicle routes to parcels is defined by the parameter G_OP_PA_ASSTH (between 0 and 1, with 1 reflecting that parcel o and d is directly on the vehicle route). G_OP_PA_OBASS (bool) describes the integration. if False, an insertion of parcels into vehicle routes is only allowed, when no passenger is on board. This class represents the SDPA strategy in the paper. origin and destination of parcels are added to vehicle schedules independently from each other. if a vehicle passes by origin, it is inserted into the route to pick up the parcel. The destination is only inserted if the corresponding vehicle passes also the destination some time later during the simulation. In case not all parcels could be delivered (but are already pick up), remaining parcels are delivered at the time specified by G_OP_PA_REDEL. This class reflects the SDPA strategy in the paper. The fleet control requires an immediate descision process in the simulation class. file: `src\fleetctrl\RPPFleetControl.py` ### RPPFleetControlSingleStopInsertionGuided this class is used in the paper Integrating Parcel Deliveries into a Ride-Pooling Service - An Agent-Based Simulation Study; Fehn, Engelhardt, Dandl, Bogenberger, Busch (2022) DOI: https://doi.org/10.1016/j.tra.2022.103580 Parcel deliveries are integrated in a ride-pooling service. No explicit time constraints are assumed for parcel pick-ups and drop-offs. Parcels are picked up and dropped off, when vehicles pass by origin or destination during passenger transport the "closeness" of vehicle routes to parcels is defined by the parameter G_OP_PA_ASSTH (between 0 and 1, with 1 reflecting that parcel o and d is directly on the vehicle route). G_OP_PA_OBASS (bool) describes the integration. if False, an insertion of parcels into vehicle routes is only allowed, when no passenger is on board. This class represents the SDPA strategy in the paper. origin and destination of parcels are added to vehicle schedules independently from each other. If a vehicle passes by origin, it is inserted into the route to pick up the parcel. The destination is only inserted if the corresponding vehicle passes also the destination some time later during the simulation. In comparison to the class `RPPFleetControlSingleStopInsertion`, the descision to deliver a parcel that is onboard of a vehicle is coupled to assignment process of passengers. Thereby, when assigning passengers it is also checked if a route with also delivering the parcels would fit the "closeness" criteria. In case not all parcels could be delivered (but are already pick up), remaining parcels are delivered at the time specified by G_OP_PA_REDEL. This class reflects the CDPA strategy in the paper. The fleet control requires an immediate descision process in the simulation class. file: `src\fleetctrl\RPPFleetControl.py` ## Fleet Control - Pooling This sub-module defines which algorithm is used to assign and re-optimize vehicle schedules for the ride-pooling use case. By default `AlonsoMoraAssignment` is used. The ride-pooling batch optimizer is controlled by the parameter `op_rp_batch_optimizer`. If new batch assignment algorithms are about to be implemented, the class should inherit from the base class `BatchAssignmentAlgorithmBase` in `src\fleetctrl\pooling\batch\BatchAssignmentAlgorithmBase.py` which provides all the interface methods that are needed. ### AlonsoMoraAssignment This algorithm is a variant of the publication On-demand high-capacity ride-sharing via dynamic trip-vehicle assignment; Alonso-Mora, Javier; Samaranayake, Samitha; Wallar, Alex; Frazzoli, Emilio; Rus, Daniela (2017) the differences are described in Speed-up Heuristic for an On-Demand Ride-Pooling Algorithm; Engelhardt, Roman; Dandl, Florian; Bogenberger, Klaus (2020) https://arxiv.org/pdf/2007.14877 file: `src\fleetctrl\pooling\batch\AlonsoMora\AlonsoMoraAssignment.py` ### BatchInsertionHeuristicAssignment this class uses a simple insertion heuristic to assign requests in batch that havent been assigned before. file: `src\fleetctrl\pooling\batch\InsertionHeuristic\BatchInsertionHeuristic.py` ## Fleet Control - Repositioning This sub-modules is used to select algorithms that distributes idle vehicles to match future expected demand. The selected repositioning strategy is controlled by the parameter `op_repo_method`. If new algorithms are to be implemented, the class should inherit from the base class `RepositioningBase` in `src\fleetctrl\repositioning\RepositioningBase.py` which provides all the interface methods that are required. ### PavoneHailingRepositioningFC This class implements an adaption of the real-time rebalancing policy formulated in section 4.3 of Zhang, R.; Pavone, M. (2016): Control of robotic mobility-on-demand systems. A queueing-theoretical perspective. In: The International Journal of Robotics Research 35 (1-3), S. 186–203. DOI: 10.1177/0278364915581863. The adaption is that the supply side is forecast using arrival forecast and excess vehicles cannot be negative. file: `src\fleetctrl\repositioning\PavoneHailingFC.py` ### PavoneHailingV2RepositioningFC This class implements an adaption of the real-time rebalancing policy formulated in section 4.3 of Zhang, R.; Pavone, M. (2016): Control of robotic mobility-on-demand systems. A queueing-theoretical perspective. In: The International Journal of Robotics Research 35 (1-3), S. 186–203. DOI: 10.1177/0278364915581863. The adaption is that the supply side is forecast using arrival forecast. Moreover, the computation of excess vehicles is more complex to allow negative values, but consistent solution during global vehicle shortage. file: `src\fleetctrl\repositioning\PavoneHailingFC.py` ### DensityRepositioning This class implements Density Based Repositioning Algorithm described in Density Based Distribution Model for Repositioning Strategies of Ride Hailing Services; Syed, Arslan Ali; Dandl, Florian; Kaltenhäuser, Bernd; Bogenberger, Klaus (2021); DOI: 10.3389/ffutr.2021.681451 file: `src\fleetctrl\repositioning\FrontiersDensityBasedRepositioning.py` ### AlonsoMoraRepositioning This class implements the reactive repositioning strategy proposed in On-demand high-capacity ride-sharing via dynamic trip-vehicle assignment Javier Alonso-Mora, Samitha Samaranayake, Alex Wallar, Emilio Frazzoli, and Daniela Rus (2016) Vehicles are sent to locations where customers have been rejected since the last repo time-trigger. Therefore, this algorithm does not require demand forecast. file: `src\fleetctrl\repositioning\AlonsoMoraRepositioning.py` ## Fleet Control - Reservation This modules deals with request pre-booking a trip a long time in advance. As these requests are hard to handle in the online assignment algorithm (a lot of insertion possibilities into current vehicles schedules), those requests are handeled in an additional sub-module. The selected reservation strategy is controlled by the parameter `op_reservation_module`. By default the module `RollingHorizonReservation` is used. If new algorithms are to be implemented, the class should inherit from the base class `ReservationBase` in `src\fleetctrl\reservation\ReservationBase.py` which provides all the interface methods that are required. ### RollingHorizonReservation This reservation class treats reservation requests with a naive rolling horizon approach: innitially reservation requests are assigned to vehicles by an insertion heuristic; this assignment is kept until the simulation time approches the earliest pickup time within the rolling horizon; then requests are revealed to the global optimisation and removed from the reservation class. file: `src\fleetctrl\reservation\RollingHorizon.py` ## Fleet Control - Charging This sub-modules deals with algorithms and strategies to sent vehicles to charging stations. The selected charging strategy is controlled by the parameter `op_charging_method`. If new algorithms are to be implemented, the class should inherit from the base class `ChargingBase` in `src\fleetctrl\charging\ChargingBase.py` which provides all the interface methods that are required. ### ChargingThresholdPublicInfrastructure This strategy looks through all fleet vehicles an triggers charging tasks in case the soc within a planned route of a vehicle drops below a threshold (G_OP_APS_SOC) the closest charging station possible from this position is considered for charging in case multiple charging operators are present, the offer closest to postion is selected (also with depots). This strategy is also used in the publication Simulating Charging Processes of Mobility-On-Demand Services at Public Infrastructure: Can Operators Complement Each Other? Zhang, Yunfei; Engelhardt, Roman; Syed, Arslan-Ali; Dandl, Florian; Hardt, Cornelius; Bogenberger, Klaus (2022) DOI: 10.1109/ITSC55140.2022.9922449 file: `src\fleetctrl\charging\Threshold.py` ## Fleet Control - Pricing This sub-module implements strategies that dynamically set fares for trips. The selected pricing strategy is controlled by the parameter `op_dyn_pricing_method`. If new algorithms are to be implemented, the class should inherit from the base class `DynamicPrizingBase` in `src\fleetctrl\pricing\DynamicPricingBase.py` which provides all the interface methods that are required. ### TimeBaseDP This strategy sets fares at specific times during the simulation based on an input file. file: `src\fleetctrl\pricing\TimeBasedDP.py` ### UtilizationBasedDP This is a utilization dependent pricing scheme, which adjusts the general fare factor. After certain simulation intervals, the current fleet utilization is measured. If the utilization over-(under-)shoots a certain threshold, fares are in-(de-)creased. file: `src\fleetctrl\pricing\UtilizationBasedDP.py` ## Fleet Control - Fleet Sizing This sub-module is used to dynamically active or deactive vehicles. Deactivated vehicles are sent back to the depot and are not available for customer assignments. This can be used model driver shift for example. The selected fleet sizing strategy is controlled by the parameter `op_dyn_fs_method`. If new algorithms are to be implemented, the class should inherit from the base class `DynamicFleetSizingBase` in `src\fleetctrl\fleetsizing\DynamicFleetSizingBase.py` which provides all the interface methods that are required. ### TimeBasedFS This strategy activates or deactivates fleet vehicles a specific times during the simulation. Information about the timedependent fleetsize has to be given with the file "op_act_fs_file". Based on the active fleetsize curve, this strategy activates and deactivates vehicles to fit this curve inactive vehicles in depots are selected to charge if a charging station is present * vehicles are sent to the nearest depots (idle vehicles have priority; other vehicles have to finish their task first (locks their plan)) * the presence of a charging station has no influence on the depot to be picked! file: `src\fleetctrl\fleetsizing\TimeBasedFS.py` ### UtilizationBasedFS this strategy dynamically adopts the active fleet size based on the current fleet utilization * a target utilization has to be given. fleet size is adopted to fit this utilization ("op_dyfs_target_utilization") * an interval around this utilization has to be given which specifies the reaction time of the algorithm ("op_dyfs_target_utilization_interval") * if the current utilization exceeds target_utilization + target_utilization intervall vehicles are added until the utilization afterwards corresponds to target_utilization - target_utilization_interval * for vehicles to be deactivated the current utilization has to deceed target_utilization - target_utilization_interval for a time interval specified by "op_dyfs_underutilization_interval" * if the active fleet size falls below a minimum, specified by "op_dyfs_minimum_active_fleetsize" no more vehicles are deactivated inactive vehicles in depots are selected to charge if a charging station is present * vehicles are sent to the nearest depots (idle vehicles have priority; other vehicles have to finish their task first (locks their plan)) * the presence of a charging station has no influence on the depot to be picked! file: `src\fleetctrl\fleetsizing\UtilizationBasedFS.py` ## Miscellaneous Contents They are stored under `src/misc`. `FleetPy\src\misc\globals.py` stores all global variables that are useful in the simulation.