2_module_structure - TUM-VT/FleetPy GitHub Wiki

Module Structure

The flowchart of the FleetPy can be shown from the following figure.

Main simulation flow of FleetyPy

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.

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.

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 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 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.

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.

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.