51 #define DEBUG_COND (true)
66 #define TAXI_SERVICE "taxi"
67 #define TAXI_SERVICE_PREFIX "taxi:"
81 oc.
addDescription(
"device.taxi.dispatch-algorithm",
"Taxi Device",
"The dispatch algorithm [greedy|greedyClosest|greedyShared|routeExtension|traci]");
84 oc.
addDescription(
"device.taxi.dispatch-algorithm.output",
"Taxi Device",
"Write information from the dispatch algorithm to FILE");
87 oc.
addDescription(
"device.taxi.dispatch-algorithm.params",
"Taxi Device",
"Load dispatch algorithm parameters in format KEY1:VALUE1[,KEY2:VALUE]");
90 oc.
addDescription(
"device.taxi.dispatch-period",
"Taxi Device",
"The period between successive calls to the dispatcher");
93 oc.
addDescription(
"device.taxi.idle-algorithm",
"Taxi Device",
"The behavior of idle taxis [stop|randomCircling]");
96 oc.
addDescription(
"device.taxi.idle-algorithm.output",
"Taxi Device",
"Write information from the idling algorithm to FILE");
106 into.push_back(device);
120 if (personCapacity < 1 && containerCapacity < 1) {
132 std::string algo = oc.
getString(
"device.taxi.dispatch-algorithm");
135 if (algo ==
"greedy") {
137 }
else if (algo ==
"greedyClosest") {
139 }
else if (algo ==
"greedyShared") {
141 }
else if (algo ==
"routeExtension") {
143 }
else if (algo ==
"traci") {
146 throw ProcessError(
"Dispatch algorithm '" + algo +
"' is not known");
158 return lines.size() == 1 && (
165 const std::set<std::string>& lines,
168 const MSEdge* from,
double fromPos,
169 const MSEdge* to,
double toPos,
170 const std::string& group) {
175 throw ProcessError(
"Cannot add taxi reservation for " + std::string(person->
isPerson() ?
"person" :
"container")
176 +
" '" + person->
getID() +
"' because destination edge '" + to->
getID() +
"'"
177 +
" does not permit taxi access");
180 throw ProcessError(
"Cannot add taxi reservation for " + std::string(person->
isPerson() ?
"person" :
"container")
181 +
" '" + person->
getID() +
"' because origin edge '" + from->
getID() +
"'"
182 +
" does not permit taxi access");
187 myDispatcher->
addReservation(person, reservationTime, pickupTime, from, fromPos, to, toPos, group, *lines.begin(),
myMaxCapacity,
myMaxContainerCapacity);
192 const std::set<std::string>& lines,
193 const MSEdge* from,
double fromPos,
194 const MSEdge* to,
double toPos,
195 const std::string& group) {
204 std::vector<MSDevice_Taxi*> active;
206 if (taxi->getHolder().hasDeparted()) {
207 active.push_back(taxi);
233 std::string defaultServiceEnd =
toString(1e15);
235 if (algo ==
"stop") {
237 }
else if (algo ==
"randomCircling") {
266 return &
myFleet[0]->getHolder();
281 #ifdef DEBUG_DISPATCH
285 std::cout <<
" persons=" <<
toString(res->persons) <<
"\n";
290 std::vector<SUMOVehicleParameter::Stop> stops;
293 assert(veh !=
nullptr);
301 tmpEdges.push_back(rerouteOrigin);
306 std::map<const MSTransportable*, int> nOccur;
312 throw ProcessError(
"Invalid Re-dispatch for existing customer '" + person->
getID() +
"' with a new reservation");
317 if (nOccur.size() == 0) {
320 lastPos = veh->
getStops().back().pars.endPos;
321 #ifdef DEBUG_DISPATCH
323 std::cout <<
" re-dispatch with route-extension\n";
328 std::set<const MSTransportable*> onBoard;
331 onBoard.insert(onBoardP.begin(), onBoardP.end());
332 onBoard.insert(onBoardC.begin(), onBoardC.end());
333 std::set<const MSTransportable*> redundantPickup;
334 for (
auto item : nOccur) {
335 if (item.second == 1) {
337 if (onBoard.count(item.first) == 0) {
338 throw ProcessError(
"Re-dispatch did not mention pickup for existing customer '" + item.first->getID() +
"'");
340 }
else if (item.second == 2) {
341 if (onBoard.count(item.first) == 0) {
345 redundantPickup.insert(item.first);
348 throw ProcessError(
"Re-dispatch mentions existing customer '" + item.first->getID() +
"' " +
toString(item.second) +
" times");
352 if (!redundantPickup.empty()) {
353 for (
auto it = reservations.begin(); it != reservations.end();) {
354 bool isRedundant =
false;
356 if (redundantPickup.count(person) != 0) {
363 redundantPickup.erase(person);
365 it = reservations.erase(it);
376 tmpEdges.push_back(rerouteOrigin);
378 #ifdef DEBUG_DISPATCH
380 std::cout <<
" re-dispatch from scratch\n";
385 std::vector<std::string> missing;
387 if (nOccur.count(c) == 0) {
388 missing.push_back(c->getID());
398 bool isPickup =
false;
406 prepareStop(tmpEdges, stops, lastPos, res->from, res->fromPos,
"pickup " +
toString(res->persons) +
" (" + res->id +
")");
409 stops.back().triggered =
true;
411 stops.back().containerTriggered =
true;
413 stops.back().permitted.insert(transportable->
getID());
417 if (stops.back().duration == -1) {
422 prepareStop(tmpEdges, stops, lastPos, res->to, res->toPos,
"dropOff " +
toString(res->persons) +
" (" + res->id +
")");
426 #ifdef DEBUG_DISPATCH
428 std::cout <<
" tmpEdges=" <<
toString(tmpEdges) <<
"\n";
435 #ifdef DEBUG_DISPATCH
449 #ifdef DEBUG_DISPATCH
460 std::vector<SUMOVehicleParameter::Stop>& stops,
461 double& lastPos,
const MSEdge* stopEdge,
double stopPos,
462 const std::string& action) {
463 assert(!edges.empty());
464 if (stopPos < lastPos && stopPos + NUMERICAL_EPS >= lastPos) {
470 double distToStop = stopPos - lastPos;
475 if (stopEdge != edges.back()) {
476 distToStop += edges.back()->getLength();
477 if (distToStop < brakeGap) {
482 for (
int i = 1; i < (int)toFirstStop.size() - 1; i++) {
483 distToStop += toFirstStop[i]->getLength();
487 if (distToStop < brakeGap) {
490 edges.push_back(stopEdge);
494 if (stopEdge == edges.back() && !stops.empty()) {
495 if (stopPos >= lastPos && stopPos <= stops.back().endPos) {
497 stops.back().actType +=
"," + action;
503 stops.back().actType +=
"," + action;
507 if (stopEdge != edges.back() || stopPos < lastPos) {
508 edges.push_back(stopEdge);
518 stops.push_back(stop);
525 if (allowedLanes ==
nullptr) {
528 return allowedLanes->front();
545 double newPos,
double ) {
603 WRITE_WARNINGF(
"All customers left vehicle '%' at time=% but there are % remaining stops",
619 bool fulfilled =
true;
642 if (stop.pars.permitted.size() > 0) {
651 if (tripinfoOut !=
nullptr) {
662 if (key ==
"customers") {
664 }
else if (key ==
"occupiedDistance") {
666 }
else if (key ==
"occupiedTime") {
668 }
else if (key ==
"state") {
670 }
else if (key ==
"currentCustomers") {
672 }
else if (key ==
"pickUpDuration") {
674 }
else if (key ==
"dropOffDuration") {
689 if (key ==
"pickUpDuration" || key ==
"dropOffDuration") {
700 return (taxiLine == rideLine
#define TAXI_SERVICE_PREFIX
std::vector< const MSEdge * > ConstMSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
@ SVC_TAXI
vehicle is a taxi
const int STOP_PERMITTED_SET
@ DEPART_GIVEN
The time is given.
#define UNUSED_PARAMETER(x)
std::string joinToStringSorting(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
std::string joinNamedToStringSorting(const std::set< T * > &ns, const T_BETWEEN &between)
Base (microsim) event class.
The base class for microscopic and mesoscopic vehicles.
const std::list< MSStop > & getStops() const
virtual const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
A device which collects info on the vehicle trip (mainly on departure and arrival)
static void initDispatch()
initialize the dispatch algorithm
static Command * myDispatchCommand
The repeated call to the dispatcher.
void customerArrived(const MSTransportable *person)
called by MSDevice_Transportable upon unloading a person
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves arrival info.
static SUMOTime triggerDispatch(SUMOTime currentTime)
period command to trigger the dispatch algorithm
void dispatch(const Reservation &res)
service the given reservation
std::set< const MSTransportable * > myCustomers
the customer of the current reservation
SUMOTime myServiceEnd
the time at which the taxi service ends (end the vehicle may leave the simulation)
void generateOutput(OutputDevice *tripinfoOut) const
Called on writing tripinfo output.
void dispatchShared(std::vector< const Reservation * > reservations)
service the given reservations
MSIdling * myIdleAlgorithm
algorithm for controlling idle behavior
std::set< const Reservation * > myCurrentReservations
reservations currently being served
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
bool hasFuturePickup()
whether the taxi has another pickup scheduled
bool allowsBoarding(MSTransportable *t) const
whether the given person is allowed to board this taxi
static MSDispatch * myDispatcher
the dispatch algorithm
int myCustomersServed
number of customers that were served
static int myMaxContainerCapacity
bool isEmpty()
whether the taxi is empty
const std::string deviceName() const
return the name for this type of device
static std::vector< MSDevice_Taxi * > myFleet
static void removeReservation(MSTransportable *person, const std::set< std::string > &lines, const MSEdge *from, double fromPos, const MSEdge *to, double toPos, const std::string &group)
retract reservation
static SUMOTime myDispatchPeriod
the time between successive calls to the dispatcher
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves departure info on insertion.
static void cleanup()
resets counters
static bool isReservation(const std::set< std::string > &lines)
whether the given lines description is a taxi call
double myOccupiedDistance
distance driven with customers
MSDevice_Taxi(SUMOVehicle &holder, const std::string &id)
Constructor.
static void addReservation(MSTransportable *person, const std::set< std::string > &lines, SUMOTime reservationTime, SUMOTime pickupTime, const MSEdge *from, double fromPos, const MSEdge *to, double toPos, const std::string &group)
add new reservation
static bool hasServableReservations()
check whether there are still (servable) reservations in the system
void prepareStop(ConstMSEdgeVector &edges, std::vector< SUMOVehicleParameter::Stop > &stops, double &lastPos, const MSEdge *stopEdge, double stopPos, const std::string &action)
prepare stop for the given action
static SUMOVehicle * getTaxi()
returns a taxi if any exist or nullptr
void customerEntered(const MSTransportable *t)
called by MSDevice_Transportable upon loading a person
bool compatibleLine(const Reservation *res)
whether the given reservation is compatible with the taxi line
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_Taxi-options.
bool myIsStopped
whether the vehicle is currently stopped
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this device. Throw exception for unsupported key
SUMOTime myOccupiedTime
time spent driving with customers
~MSDevice_Taxi()
Destructor.
MSLane * getStopLane(const MSEdge *edge, const std::string &action)
determine stopping lane for taxi
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
static bool getBoolParam(const SUMOVehicle &v, const OptionsCont &oc, std::string paramName, bool deflt, bool required)
static double getFloatParam(const SUMOVehicle &v, const OptionsCont &oc, std::string paramName, double deflt, bool required)
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
static std::string getStringParam(const SUMOVehicle &v, const OptionsCont &oc, std::string paramName, std::string deflt, bool required)
A dispatch algorithm that services the reservations with the shortest traveltime-to-pickup first.
A dispatch algorithm that services customers in reservation order and always sends the closest availa...
A dispatch algorithm that services customers in reservation order and always sends the closest availa...
An algorithm that performs distpach for a taxi fleet.
virtual std::string removeReservation(MSTransportable *person, const MSEdge *from, double fromPos, const MSEdge *to, double toPos, std::string group)
remove person from reservation. If the whole reservation is removed, return it's id
virtual Reservation * addReservation(MSTransportable *person, SUMOTime reservationTime, SUMOTime pickupTime, const MSEdge *from, double fromPos, const MSEdge *to, double toPos, std::string group, const std::string &line, int maxCapacity, int maxContainerCapacity)
add a new reservation
bool hasServableReservations()
check whether there are still (servable) reservations in the system
virtual void fulfilledReservation(const Reservation *res)
erase reservation from storage
virtual void computeDispatch(SUMOTime now, const std::vector< MSDevice_Taxi * > &fleet)=0
computes dispatch and updates reservations
A road/street connecting two junctions.
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
double getLength() const
return the length of the edge
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
virtual void idle(MSDevice_Taxi *taxi)=0
computes Idling and updates reservations
Representation of a lane in the micro simulation.
double getLength() const
Returns the lane's length.
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
const ConstMSEdgeVector & getEdges() const
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
SUMOTime endBoarding
the maximum time at which persons may board this vehicle
bool isPerson() const
Whether it is a person.
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
int getPersonCapacity() const
Get this vehicle type's person capacity.
double getLength() const
Get vehicle's length [m].
int getContainerCapacity() const
Get this vehicle type's container capacity.
const std::string & getID() const
Returns the id.
A storage for options typed value containers)
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
An upper class for objects with additional parameters.
void setParametersStr(const std::string ¶msString, const std::string kvsep="=", const std::string sep="|")
set the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN"
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
Representation of a vehicle, person, or container.
virtual bool isStopped() const =0
Returns whether the object is at a stop.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
virtual bool replaceRouteEdges(ConstMSEdgeVector &edges, double cost, double savings, const std::string &info, bool onInit=false, bool check=false, bool removeStops=true, std::string *msgReturn=nullptr)=0
Replaces the current route by the given edges.
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual void reroute(SUMOTime t, const std::string &info, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false, const bool silent=false)=0
Performs a rerouting using the given router.
virtual const std::list< MSStop > & getStops() const =0
virtual bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, bool collision=false, ConstMSEdgeVector::const_iterator *searchStart=0)=0
Adds a stop.
virtual const std::vector< MSTransportable * > & getContainers() const =0
retrieve riding containers
virtual int getRNGIndex() const =0
virtual MSStop & getNextStop()=0
virtual int getPersonNumber() const =0
Returns the number of persons.
virtual const std::vector< MSTransportable * > & getPersons() const =0
retrieve riding persons
virtual int getContainerNumber() const =0
Returns the number of containers.
virtual double getBrakeGap(bool delayed=false) const =0
get distance for coming to a stop (used for rerouting checks)
virtual int getRoutePosition() const =0
return index of edge within route
virtual bool abortNextStop(int nextStopIndex=0)=0
deletes the next stop at the given index if it exists
Definition of vehicle stop (position and duration)
std::string lane
The lane to stop at.
double startPos
The stopping position start.
int index
at which position in the stops list
std::string actType
act Type (only used by Persons) (used by NETEDIT)
double endPos
The stopping position end.
bool parking
whether the vehicle is removed from the net while stopping
Structure representing possible vehicle parameter.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
std::string line
The vehicle's line (mainly for public transport)
A wrapper for a Command function.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.