Skip to content

Commit

Permalink
implemented new collision actions refs #1102
Browse files Browse the repository at this point in the history
git-svn-id: file:///home/behr_mi/git/sumo_synched/trunk@20593 afbd958f-9f77-42d5-a016-97a22340ccf4
  • Loading branch information
namdre committed Apr 29, 2016
1 parent 0de1fc1 commit 39284a2
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 48 deletions.
11 changes: 9 additions & 2 deletions sumo/src/microsim/MSFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,14 @@ MSFrame::fillOptions() {
oc.addDescription("ignore-junction-blocker", "Processing", "Ignore vehicles which block the junction after they have been standing for SECONDS (-1 means never ignore)");
#endif

oc.doRegister("ignore-route-errors", new Option_Bool(false));
oc.addDescription("ignore-route-errors", "Processing", "Do not check whether routes are connected");

oc.doRegister("ignore-accidents", new Option_Bool(false));
oc.addDescription("ignore-accidents", "Processing", "Do not check whether accidents occur");

oc.doRegister("ignore-route-errors", new Option_Bool(false));
oc.addDescription("ignore-route-errors", "Processing", "Do not check whether routes are connected");
oc.doRegister("collision.action", new Option_String("teleport"));
oc.addDescription("collision.action", "Processing", "How to deal with collisions: [none,warn,teleport,remove]");

oc.doRegister("max-num-vehicles", new Option_Integer(-1));
oc.addDescription("max-num-vehicles", "Processing", "Delay vehicle insertion to stay within the given maximum number");
Expand Down Expand Up @@ -479,6 +482,9 @@ MSFrame::checkOptions() {
if (oc.getBool("lanechange.allow-swap")) {
WRITE_WARNING("The option 'lanechange.allow-swap' is deprecated, and will not be supported in future versions of SUMO.");
}
if (oc.getBool("ignore-accidents")) {
WRITE_WARNING("The option 'ignore-accidents' is deprecated. Use 'collision.action none' instead.");
}
if (oc.getBool("duration-log.statistics") && oc.isDefault("verbose")) {
oc.set("verbose", "true");
}
Expand Down Expand Up @@ -517,6 +523,7 @@ MSFrame::setMSGlobals(OptionsCont& oc) {
}
MSGlobals::gWaitingTimeMemory = string2time(oc.getString("waiting-time-memory"));
MSAbstractLaneChangeModel::initGlobalOptions(oc);
MSLane::initCollisionOptions(oc);


DELTA_T = string2time(oc.getString("step-length"));
Expand Down
105 changes: 67 additions & 38 deletions sumo/src/microsim/MSLane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
// static member definitions
// ===========================================================================
MSLane::DictType MSLane::myDict;
MSLane::CollisionAction MSLane::myCollisionAction(MSLane::COLLISION_ACTION_TELEPORT);

// ===========================================================================
// internal class method definitions
Expand Down Expand Up @@ -904,30 +905,20 @@ MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
// << " all=" << toString(all) << "\n"
// << "\n";

if (myVehicles.size() == 0) {
if (myVehicles.size() == 0 || myCollisionAction == COLLISION_ACTION_NONE) {
return;
}
std::set<const MSVehicle*> toRemove;
std::set<const MSVehicle*> toTeleport;
if (MSGlobals::gLateralResolution <= 0 && MSGlobals::gLaneChangeDuration <= 0) {
// no sublanes
VehCont::iterator lastVeh = myVehicles.end() - 1;
for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh;) {
for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh; ++veh) {
VehCont::iterator pred = veh + 1;
if (detectCollisionBetween(timestep, stage, *veh, *pred)) {
handleCollision(timestep, *veh);
veh = myVehicles.erase(veh); // remove current vehicle
lastVeh = myVehicles.end() - 1;
if (veh == myVehicles.end()) {
break;
}
} else {
++veh;
}
detectCollisionBetween(timestep, stage, *veh, *pred, toRemove, toTeleport);
}
if (myPartialVehicles.size() > 0) {
if (detectCollisionBetween(timestep, stage, *lastVeh, myPartialVehicles.front())) {
handleCollision(timestep, *lastVeh);
myVehicles.erase(lastVeh); // remove current vehicle
}
detectCollisionBetween(timestep, stage, *lastVeh, myPartialVehicles.front(), toRemove, toTeleport);
}
} else {
// in the sublane-case it is insufficient to check the vehicles ordered
Expand All @@ -939,7 +930,6 @@ MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
// (lanechanger-style)

// XXX quick hack: check each in myVehicles against all others
std::set<MSVehicle*> toRemove;
for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
MSVehicle* follow = *veh;
for (AnyVehicleIterator veh2 = anyVehiclesBegin(); veh2 != anyVehiclesEnd(); ++veh2) {
Expand All @@ -950,8 +940,7 @@ MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
if (lead->getPositionOnLane(this) < follow->getPositionOnLane()) {
continue;
}
if (detectCollisionBetween(timestep, stage, follow, lead)) {
toRemove.insert(follow);
if (detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
break;
}
}
Expand All @@ -963,29 +952,34 @@ MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
follow->getPositionOnLane());
for (int i = 0; i < ahead.numSublanes(); ++i) {
const MSVehicle* lead = ahead[i];
if (lead != 0 && lead != follow && shadowLane->detectCollisionBetween(timestep, stage, follow, lead)) {
toRemove.insert(follow);
if (lead != 0 && lead != follow && shadowLane->detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
break;

}
}
}
}
for (std::set<MSVehicle*>::iterator veh = toRemove.begin(); veh != toRemove.end(); ++veh) {
removeVehicle(*veh, MSMoveReminder::NOTIFICATION_TELEPORT, false);
handleCollision(timestep, *veh);
}
for (std::set<const MSVehicle*>::iterator it = toRemove.begin(); it != toRemove.end(); ++it) {
MSVehicle* veh = const_cast<MSVehicle*>(*it);
MSLane* vehLane = veh->getLane();
vehLane->removeVehicle(veh, MSMoveReminder::NOTIFICATION_TELEPORT, false);
if (toTeleport.count(veh) > 0) {
MSVehicleTransfer::getInstance()->add(timestep, veh);
}
}
}


bool
MSLane::detectCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim) const {
MSLane::detectCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim,
std::set<const MSVehicle*>& toRemove, std::set<const MSVehicle*>& toTeleport) const {
assert(collider->isFrontOnLane(this));
if ((victim->hasInfluencer() && victim->getInfluencer()->isVTDAffected(timestep)) ||
(collider->hasInfluencer() && collider->getInfluencer()->isVTDAffected(timestep))) {
#ifndef NO_TRACI
if (myCollisionAction == COLLISION_ACTION_TELEPORT && ((victim->hasInfluencer() && victim->getInfluencer()->isVTDAffected(timestep)) ||
(collider->hasInfluencer() && collider->getInfluencer()->isVTDAffected(timestep)))) {
return false;
}
#endif
const SUMOReal gap = victim->getBackPositionOnLane(this) - collider->getPositionOnLane() - collider->getVehicleType().getMinGap();
if (gap < -NUMERICAL_EPS) {
//std::cout << SIMTIME
Expand Down Expand Up @@ -1014,8 +1008,34 @@ MSLane::detectCollisionBetween(SUMOTime timestep, const std::string& stage, cons
// synchroneous lane change maneuver
return false;
}
WRITE_WARNING("Teleporting vehicle '" + collider->getID()
+ "'; collision with vehicle '" + victim->getID()
std::string prefix;
switch (myCollisionAction) {
case COLLISION_ACTION_WARN:
prefix = "Vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
break;
case COLLISION_ACTION_TELEPORT:
prefix = "Teleporting vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
toRemove.insert(collider);
toTeleport.insert(collider);
break;
case COLLISION_ACTION_REMOVE:
prefix = "Removing collision participantes: vehicle '" + collider->getID() + "', vehicle '" + victim->getID();
#ifndef NO_TRACI
if (!(victim->hasInfluencer() && victim->getInfluencer()->isVTDAffected(timestep))) {
toRemove.insert(victim);
}
if (!(collider->hasInfluencer() && collider->getInfluencer()->isVTDAffected(timestep))) {
toRemove.insert(collider);
}
#else
toRemove.insert(victim);
toRemove.insert(collider);
#endif
break;
default:
break;
}
WRITE_WARNING(prefix
+ "', lane='" + getID()
+ "', gap=" + toString(gap)
+ (latGap == 0 ? "" : "', latGap=" + toString(latGap))
Expand All @@ -1028,14 +1048,6 @@ MSLane::detectCollisionBetween(SUMOTime timestep, const std::string& stage, cons
}


void
MSLane::handleCollision(SUMOTime timestep, MSVehicle* collider) {
myBruttoVehicleLengthSum -= collider->getVehicleType().getLengthWithGap();
myNettoVehicleLengthSum -= collider->getVehicleType().getLength();
MSVehicleTransfer::getInstance()->add(timestep, collider);
}


bool
MSLane::executeMovements(SUMOTime t, std::vector<MSLane*>& lanesWithVehiclesToIntegrate) {
// iteratate over vehicles in reverse so that move reminders will be called in the correct order
Expand Down Expand Up @@ -2373,5 +2385,22 @@ MSLane::getOppositeFollower(const MSVehicle* ego) const {
}
}


void
MSLane::initCollisionOptions(const OptionsCont& oc) {
const std::string action = oc.getString("collision.action");
if (action == "none") {
myCollisionAction = COLLISION_ACTION_NONE;
} else if (action == "warn") {
myCollisionAction = COLLISION_ACTION_WARN;
} else if (action == "teleport") {
myCollisionAction = COLLISION_ACTION_TELEPORT;
} else if (action == "remove") {
myCollisionAction = COLLISION_ACTION_REMOVE;
} else {
throw ProcessError("Invalid collision.action '" + action + "'.");
}
}

/****************************************************************************/

24 changes: 20 additions & 4 deletions sumo/src/microsim/MSLane.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ class MSLane : public Named, public Parameterised {


public:
/** @enum ChangeRequest
* @brief Requests set via TraCI
*/
enum CollisionAction {
COLLISION_ACTION_NONE,
COLLISION_ACTION_WARN,
COLLISION_ACTION_TELEPORT,
COLLISION_ACTION_REMOVE
};

/** @brief Constructor
*
* @param[in] id The lane's id
Expand Down Expand Up @@ -945,6 +955,12 @@ class MSLane : public Named, public Parameterised {
}
#endif

static void initCollisionOptions(const OptionsCont& oc);

static bool teleportOnCollision() {
return myCollisionAction == COLLISION_ACTION_TELEPORT;
}

protected:
/// moves myTmpVehicles int myVehicles after a lane change procedure
virtual void swapAfterLaneChange(SUMOTime t);
Expand All @@ -966,10 +982,8 @@ class MSLane : public Named, public Parameterised {


/// @brief detect whether there is a collision between the two vehicles
bool detectCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim) const;

/// @brief handle collision caused by the given vehicle
void handleCollision(SUMOTime timestep, MSVehicle* collider);
bool detectCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim,
std::set<const MSVehicle*>& toRemove, std::set<const MSVehicle*>& toTeleport) const;

/// @brief compute maximum braking distance on this lane
SUMOReal getMaximumBrakeDist() const;
Expand Down Expand Up @@ -1098,6 +1112,8 @@ class MSLane : public Named, public Parameterised {
/// @brief This lane's move reminder
std::vector< MSMoveReminder* > myMoveReminders;

/// @brief the action to take on collisions
static CollisionAction myCollisionAction;

/**
* @class vehicle_position_sorter
Expand Down
2 changes: 1 addition & 1 deletion sumo/src/microsim/MSNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ MSNet::closeSimulation(SUMOTime start) {
<< " Running: " << myVehicleControl->getRunningVehicleNo() << "\n"
<< " Waiting: " << myInserter->getWaitingVehicleNo() << "\n";

if (myVehicleControl->getTeleportCount() > 0) {
if (myVehicleControl->getTeleportCount() > 0 || myVehicleControl->getCollisionCount() > 0) {
// print optional teleport statistics
std::vector<std::string> reasons;
if (myVehicleControl->getCollisionCount() > 0) {
Expand Down
5 changes: 5 additions & 0 deletions sumo/src/microsim/MSVehicleControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,5 +386,10 @@ MSVehicleControl::getQuota(SUMOReal frac) const {
return base;
}

unsigned int
MSVehicleControl::getTeleportCount() const {
return (MSLane::teleportOnCollision() ? myCollisions : 0) + myTeleportsJam + myTeleportsYield + myTeleportsWrongLane;
}

/****************************************************************************/

4 changes: 1 addition & 3 deletions sumo/src/microsim/MSVehicleControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,7 @@ class MSVehicleControl {
}

/// @brief return the number of teleports (including collisions)
unsigned int getTeleportCount() const {
return myCollisions + myTeleportsJam + myTeleportsYield + myTeleportsWrongLane;
}
unsigned int getTeleportCount() const;

/// @brief return the number of emergency stops
unsigned int getEmergencyStops() const {
Expand Down

0 comments on commit 39284a2

Please sign in to comment.