#include <config.h>
#include <string>
#include "MSLane.h"
#include "MSMoveReminder.h"
StringBijection<MSMoveReminder::Notification>::Entry MSMoveReminder::NotificationValues[] = {
{"departed", NOTIFICATION_DEPARTED},
{"junction", NOTIFICATION_JUNCTION},
{"segment", NOTIFICATION_SEGMENT},
{"laneChange", NOTIFICATION_LANE_CHANGE},
{"loadState", NOTIFICATION_LOAD_STATE},
{"teleport", NOTIFICATION_TELEPORT},
{"teleportContinuation", NOTIFICATION_TELEPORT_CONTINUATION},
{"parking", NOTIFICATION_PARKING},
{"reroute", NOTIFICATION_REROUTE},
{"parkingReroute", NOTIFICATION_PARKING_REROUTE},
{"arrived", NOTIFICATION_ARRIVED},
{"teleportArrived", NOTIFICATION_TELEPORT_ARRIVED},
{"vaporizedCalibrator", NOTIFICATION_VAPORIZED_CALIBRATOR},
{"vaporizedCollision", NOTIFICATION_VAPORIZED_COLLISION},
{"vaporizedTraCI", NOTIFICATION_VAPORIZED_TRACI},
{"vaporizedGUI", NOTIFICATION_VAPORIZED_GUI},
{"vaporizer", NOTIFICATION_VAPORIZED_VAPORIZER},
{"vaporizedBreakdown", NOTIFICATION_VAPORIZED_BREAKDOWN},
{"none", NOTIFICATION_NONE}
};
StringBijection<MSMoveReminder::Notification> MSMoveReminder::Notifications(
MSMoveReminder::NotificationValues, MSMoveReminder::NOTIFICATION_NONE, false);
MSMoveReminder::MSMoveReminder(const std::string& description, MSLane* const lane, const bool doAdd) :
myLane(lane),
myDescription(description)
#ifdef HAVE_FOX
, myNotificationMutex(true)
#endif
{
if (myLane != nullptr && doAdd) {
myLane->addMoveReminder(this);
}
}
void
MSMoveReminder::updateDetector(SUMOTrafficObject& veh, double entryPos, double leavePos,
SUMOTime entryTime, SUMOTime currentTime, SUMOTime leaveTime,
bool cleanUp) {
if (entryTime > currentTime) {
return;
}
auto j = myLastVehicleUpdateValues.find(veh.getNumericalID());
if (j != myLastVehicleUpdateValues.end()) {
const SUMOTime previousUpdateTime = j->second.first;
if (previousUpdateTime <= currentTime) {
entryTime = previousUpdateTime;
entryPos = j->second.second;
}
}
assert(entryTime <= currentTime);
if ((entryTime < leaveTime) && (entryPos <= leavePos)) {
const double timeOnLane = STEPS2TIME(currentTime - entryTime);
const double speed = (leavePos - entryPos) / STEPS2TIME(leaveTime - entryTime);
myLastVehicleUpdateValues[veh.getNumericalID()] = std::pair<SUMOTime, double>(currentTime, entryPos + speed * timeOnLane);
assert(timeOnLane >= 0);
notifyMoveInternal(veh, timeOnLane, timeOnLane, speed, speed, speed * timeOnLane, speed * timeOnLane, 0.);
} else {
myLastVehicleUpdateValues[veh.getNumericalID()] = std::pair<SUMOTime, double>(leaveTime, leavePos);
}
if (cleanUp) {
removeFromVehicleUpdateValues(veh);
}
}
void
MSMoveReminder::saveReminderState(OutputDevice& out, const SUMOTrafficObject& veh) {
auto j = myLastVehicleUpdateValues.find(veh.getNumericalID());
if (j != myLastVehicleUpdateValues.end()) {
out.openTag(SUMO_TAG_REMINDER);
out.writeAttr(SUMO_ATTR_ID, getDescription());
out.writeAttr(SUMO_ATTR_TIME, (*j).second.first);
out.writeAttr(SUMO_ATTR_POSITION, (*j).second.second);
out.closeTag();
}
}
void
MSMoveReminder::loadReminderState(long long int numID, SUMOTime time, double pos) {
myLastVehicleUpdateValues[numID] = std::make_pair(time, pos);
}
void
MSMoveReminder::removeFromVehicleUpdateValues(SUMOTrafficObject& veh) {
myLastVehicleUpdateValues.erase(veh.getNumericalID());
}