Skip to content

Commit

Permalink
fix #14806
Browse files Browse the repository at this point in the history
  • Loading branch information
namdre committed May 1, 2024
1 parent a22a254 commit aed8058
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 16 deletions.
24 changes: 23 additions & 1 deletion src/microsim/MSInsertionControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ MSInsertionControl::addFlow(SUMOVehicleParameter* const pars, int index) {
flow.pars->repetitionsDone--;
}
myFlows.emplace_back(flow);
myFlowIDs.insert(pars->id);
myFlowIDs.insert(std::make_pair(pars->id, flow.index));
return true;
}

Expand Down Expand Up @@ -242,6 +242,7 @@ MSInsertionControl::determineCandidates(SUMOTime time) {
newPars->id = pars->id + "." + toString(i->index);
newPars->depart = pars->repetitionProbability > 0 ? time : pars->depart + pars->repetitionTotalOffset + computeRandomDepartOffset();
pars->incrementFlow(scale, &myFlowRNG);
myFlowIDs[pars->id] = i->index;
//std::cout << SIMTIME << " flow=" << pars->id << " done=" << pars->repetitionsDone << " totalOffset=" << STEPS2TIME(pars->repetitionTotalOffset) << "\n";
// try to build the vehicle
if (vehControl.getVehicle(newPars->id) == nullptr) {
Expand Down Expand Up @@ -434,5 +435,26 @@ MSInsertionControl::computeRandomDepartOffset() const {
return 0;
}

const SUMOVehicleParameter*
MSInsertionControl::getFlowPars(const std::string& id) const {
if (hasFlow(id)) {
for (const Flow& f : myFlows) {
if (f.pars->id == id) {
return f.pars;
}
}
}
return nullptr;
}

SUMOVehicle*
MSInsertionControl::getLastFlowVehicle(const std::string& id) const {
const auto it = myFlowIDs.find(id);
if (it != myFlowIDs.end()) {
const std::string vehID = id + "." + toString(it->second);
return MSNet::getInstance()->getVehicleControl().getVehicle(vehID);
}
return nullptr;
}

/****************************************************************************/
10 changes: 8 additions & 2 deletions src/microsim/MSInsertionControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ class MSInsertionControl {
return myFlowIDs.count(id) != 0;
}

/// @brief return parameters for the given flow
const SUMOVehicleParameter* getFlowPars(const std::string& id) const;

/// @brief return the last vehicle for the given flow
SUMOVehicle* getLastFlowVehicle(const std::string& id) const;

/// @brief updates the flow scale value to keep track of TraCI-induced change
void updateScale(const std::string vtypeid);

Expand Down Expand Up @@ -241,8 +247,8 @@ class MSInsertionControl {
/// @brief Container for periodical vehicle parameters
std::vector<Flow> myFlows;

/// @brief Cache for periodical vehicle ids for quicker checking
std::set<std::string> myFlowIDs;
/// @brief Cache for periodical vehicle ids and their most recent index for quicker checking
std::map<std::string, int> myFlowIDs;

/// @brief The maximum waiting time; vehicles waiting longer are deleted (-1: no deletion)
SUMOTime myMaxDepartDelay;
Expand Down
44 changes: 31 additions & 13 deletions src/microsim/MSRouteHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ MSRouteHandler::MSRouteHandler(const std::string& file, bool addVehiclesDirectly
myCurrentRouteDistribution(nullptr),
myAmLoadingState(false),
myScaleSuffix(OptionsCont::getOptions().getString("scale-suffix")),
myReplayRerouting(OptionsCont::getOptions().getBool("replay-rerouting")) {
myReplayRerouting(OptionsCont::getOptions().getBool("replay-rerouting")),
myStartTriggeredInFlow(false)
{
myActiveRoute.reserve(100);
}

Expand Down Expand Up @@ -871,25 +873,24 @@ MSRouteHandler::closeTransportableFlow() {
}
} else {
SUMOTime depart = myVehicleParameter->depart;
const bool triggered = myVehicleParameter->departProcedure == DepartDefinition::TRIGGERED;
if (myVehicleParameter->repetitionOffset < 0) {
// poisson: randomize first depart
myVehicleParameter->incrementFlow(1, &myParsingRNG);
}
for (; i < myVehicleParameter->repetitionNumber && (triggered || depart + myVehicleParameter->repetitionTotalOffset <= myVehicleParameter->repetitionEnd); i++) {
for (; i < myVehicleParameter->repetitionNumber && (myVehicleParameter->repetitionNumber != std::numeric_limits<int>::max()
|| depart + myVehicleParameter->repetitionTotalOffset <= myVehicleParameter->repetitionEnd); i++) {
// type existence has been checked on opening
MSVehicleType* const type = MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid, &myParsingRNG);
addFlowTransportable(depart + myVehicleParameter->repetitionTotalOffset, type, baseID, i);
if (myVehicleParameter->departProcedure != DepartDefinition::TRIGGERED) {
myVehicleParameter->incrementFlow(1, &myParsingRNG);
}
myVehicleParameter->incrementFlow(1, &myParsingRNG);
}
}
resetActivePlanAndVehicleParameter();
} catch (ProcessError&) {
deleteActivePlanAndVehicleParameter();
throw;
}
myStartTriggeredInFlow = false;
}


Expand Down Expand Up @@ -1095,22 +1096,39 @@ MSRouteHandler::addRideOrTransport(const SUMOSAXAttributes& attrs, const SumoXML
double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, aid.c_str(), ok,
s == nullptr ? std::numeric_limits<double>::infinity() : s->getEndLanePosition());

SUMOVehicle* startVeh = nullptr;
const SUMOVehicleParameter* startVeh = nullptr;
const MSEdge* startVehFrom = nullptr;
if (myActiveTransportablePlan->empty() && myVehicleParameter->departProcedure == DepartDefinition::TRIGGERED) {
if (st.size() != 1) {
throw ProcessError("Triggered departure for " + agent + " '" + aid + "' requires a unique lines value.");
}
// agent starts
MSVehicleControl& vehControl = MSNet::getInstance()->getVehicleControl();
const std::string vehID = st.front();
startVeh = vehControl.getVehicle(vehID);
SUMOVehicle* sVeh = vehControl.getVehicle(vehID);
if (sVeh == nullptr) {
if (MSNet::getInstance()->hasFlow(vehID)) {
startVeh = MSNet::getInstance()->getInsertionControl().getFlowPars(vehID);
if (startVeh != nullptr) {
ConstMSRoutePtr const route = MSRoute::dictionary(startVeh->routeid);
startVehFrom = route->getEdges().front();
// flows are inserted at the end of the time step so we
// do delay the pedestrian event by one time step
myVehicleParameter->depart = startVeh->depart + DELTA_T;
myStartTriggeredInFlow = true;
}
}
} else {
startVeh = &sVeh->getParameter();
startVehFrom = sVeh->getRoute().getEdges().front();
myVehicleParameter->depart = startVeh->depart;
}
if (startVeh == nullptr) {
throw ProcessError("Unknown vehicle '" + vehID + "' in triggered departure for " + agent + " '" + aid + "'.");
}
if (startVeh->getParameter().departProcedure == DepartDefinition::TRIGGERED) {
if (startVeh->departProcedure == DepartDefinition::TRIGGERED) {
throw ProcessError("Cannot use triggered vehicle '" + vehID + "' in triggered departure for " + agent + " '" + aid + "'.");
}
myVehicleParameter->depart = startVeh->getParameter().depart;
}

if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
Expand All @@ -1129,12 +1147,12 @@ MSRouteHandler::addRideOrTransport(const SUMOSAXAttributes& attrs, const SumoXML
"' (edge '" + fromID + "' != edge '" + myActiveTransportablePlan->back()->getDestination()->getID() + "').");
}
}
if (startVeh != nullptr && startVeh->getRoute().getEdges().front() != from) {
if (startVeh != nullptr && startVehFrom != from) {
throw ProcessError("Disconnected plan for triggered " + agent + " '" + aid +
"' (edge '" + fromID + "' != edge '" + startVeh->getRoute().getEdges().front()->getID() + "').");
"' (edge '" + fromID + "' != edge '" + startVehFrom->getID() + "').");
}
} else if (startVeh != nullptr) {
from = startVeh->getRoute().getEdges().front();
from = startVehFrom;
}
if (myActiveTransportablePlan->empty()) {
if (from == nullptr) {
Expand Down
3 changes: 3 additions & 0 deletions src/microsim/MSRouteHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ class MSRouteHandler : public SUMORouteHandler, public MapMatcher<MSEdge, MSLane
/// @brief whether loaded rerouting events shall be replayed
bool myReplayRerouting;

/// @brief whether we are loading a personFlow that is starting triggered in a vehicle flow
bool myStartTriggeredInFlow;

/// @brief A random number generator used to choose from vtype/route distributions and computing the speed factors
static SumoRNG myParsingRNG;

Expand Down
4 changes: 4 additions & 0 deletions src/microsim/transportables/MSStageDriving.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,14 @@ MSStageDriving::proceed(MSNet* net, MSTransportable* transportable, SUMOTime now
// we are the first real stage (stage 0 is WAITING_FOR_DEPART)
const std::string vehID = *myLines.begin();
SUMOVehicle* startVeh = net->getVehicleControl().getVehicle(vehID);
if (startVeh == nullptr && net->hasFlow(vehID)) {
startVeh = net->getInsertionControl().getLastFlowVehicle(vehID);
}
if (startVeh == nullptr) {
throw ProcessError("Vehicle '" + vehID + "' not found for triggered departure of " +
(isPerson ? "person" : "container") + " '" + transportable->getID() + "'.");
}
myDeparted = now;
setVehicle(startVeh);
if (myOriginStop != nullptr) {
myOriginStop->removeTransportable(transportable);
Expand Down

0 comments on commit aed8058

Please sign in to comment.