37#define DEBUG_COND (true)
51 oc.
addDescription(
"device.glosa.range",
"GLOSA Device",
TL(
"The communication range to the traffic light"));
54 oc.
addDescription(
"device.glosa.max-speedfactor",
"GLOSA Device",
TL(
"The maximum speed factor when approaching a green light"));
57 oc.
addDescription(
"device.glosa.min-speed",
"GLOSA Device",
TL(
"Minimum speed when coasting towards a red light"));
60 oc.
addDescription(
"device.glosa.add-switchtime",
"GLOSA Device",
TL(
"Additional time the vehicle shall need to reach the intersection after the signal turns green"));
63 oc.
addDescription(
"device.glosa.use-queue",
"GLOSA Device",
TL(
"Use queue in front of the tls for GLOSA calculation"));
66 oc.
addDescription(
"device.glosa.override-safety",
"GLOSA Device",
TL(
"Override safety features - ignore the current light state, always follow GLOSA's predicted state"));
69 oc.
addDescription(
"device.glosa.ignore-cfmodel",
"GLOSA Device",
TL(
"Vehicles follow a perfect speed calculation - ignore speed calculations from the CF model if not safety critical"));
85 into.push_back(device);
98 double addSwitchTime,
bool useQueue,
bool overrideSafety,
bool ignoreCFModel) :
123 double newPos,
double ) {
126 const double vMax =
myVeh.getLane()->getVehicleMaxSpeed(&
myVeh);
131 bool currentPhaseGreen =
false;
132 bool currentPhaseStop =
false;
134 double nextSwitch = 0;
135 nextSwitch = timeToSwitch;
136 double QueueLength = 0;
137 double greenTime = 0;
138 double additionalJunctionTime = 0;
141 double factor = 0.21;
149 int switchOffset = 0;
152 currentPhaseGreen =
true;
154 currentPhaseStop =
true;
157#if defined DEBUG_GLOSA || defined DEBUG_QUEUE
159 std::cout <<
SIMTIME <<
" veh=" <<
myVeh.getID() <<
" d=" <<
myDistance <<
" ttJ=" << timeToJunction <<
" ttS=" << timeToSwitch <<
"\n";
167 std::cout <<
SIMTIME <<
" veh=" <<
myVeh.getID() <<
" Queuelength=" << QueueLength <<
"\n";
170 if (currentPhaseGreen) {
173 additionalJunctionTime = (QueueLength * factor + addition) - greenTime;
174 if ((additionalJunctionTime > 0) && (additionalJunctionTime < nextSwitch)) {
176 timeToJunction += additionalJunctionTime;
179 additionalJunctionTime = 0;
183 std::cout <<
SIMTIME <<
" veh=" <<
myVeh.getID() <<
" Additonaljunctiontime=" << additionalJunctionTime <<
" Greentime=" << greenTime <<
" TimetoJunction(GreenQueue)=" << timeToJunction <<
"\n";
188 if (currentPhaseStop) {
189 nextSwitch += QueueLength * factor + addition;
192 std::cout <<
SIMTIME <<
" veh=" <<
myVeh.getID() <<
" Nextswitch(RedQueue)=" << nextSwitch <<
"\n";
199 for (
int countwhile = 1; countwhile < 11; countwhile++) {
200 if (currentPhaseGreen) {
203 nextSwitch -= QueueLength * factor + addition;
211 std::cout <<
SIMTIME <<
" veh=" <<
myVeh.getID() <<
" traffic light will be/is green" <<
"\n";
213 <<
" timeToJunction=" << timeToJunction
214 <<
" nextSwitch=" << nextSwitch
219 if (timeToJunction > nextSwitch) {
229 <<
" vMax2=" << vMax2
230 <<
" timetoJunction2=" << timetoJunction2
231 <<
" yellowSlack=" << yellowSlack <<
"\n";
235 if (timetoJunction2 <= (nextSwitch + yellowSlack)) {
253 }
else if (currentPhaseStop) {
257 std::cout <<
SIMTIME <<
" veh=" <<
myVeh.getID() <<
" traffic light will be/is red" <<
"\n";
259 <<
" timeToJunction=" << timeToJunction
260 <<
" nextSwitch=" << nextSwitch
266 nextSwitch += QueueLength * factor + addition;
269 std::cout <<
SIMTIME <<
" veh=" <<
myVeh.getID() <<
" nextSwitch(redadditon): " << nextSwitch <<
"\n";
276 nextSwitch -= QueueLength * factor + addition;
277 timeToJunction -= additionalJunctionTime;
286 if (nextSwitch > 80.) {
287 nextSwitch += (double)switchOffset;
289 nextSwitch -= (double)switchOffset;
290 }
else if (nextSwitch > 60.) {
291 nextSwitch += (double)switchOffset;
293 nextSwitch -= (double)switchOffset;
294 }
else if (nextSwitch > 40.) {
295 nextSwitch += (double)switchOffset;
297 nextSwitch -= (double)switchOffset;
298 }
else if (nextSwitch > 20.) {
299 nextSwitch += (double)switchOffset;
301 nextSwitch -= (double)switchOffset;
316 myVeh.updateBestLanes();
318 const std::vector<MSLane*>& bestLaneConts =
myVeh.getBestLanesContinuation(lane);
324 if ((*linkIt)->isTLSControlled()) {
330 lane = (*linkIt)->getViaLaneOrLane();
343 double tlsRange = 1e10;
344 const std::string val =
myNextTLSLink->getTLLogic()->getParameter(
"device.glosa.range",
"1e10");
348 WRITE_WARNINGF(
TL(
"Invalid value '%' for parameter 'device.glosa.range' of traffic light '%'"),
365 assert(tlsLink !=
nullptr);
367 assert(tl !=
nullptr);
369 const int n = (int)phases.size();
373 for (
int i = 1; i <
n; i++) {
374 const auto& phase = phases[(cur + i) %
n];
375 const char ls = phase->getState()[tlsLink->
getTLIndex()];
377 || (tlsLink->
haveGreen() && ls !=
'g' && ls !=
'G')) {
381 result += phase->duration;
390 assert(tlsLink !=
nullptr);
392 assert(tl !=
nullptr);
394 const int n = (int)phases.size();
395 const int cur = countOld;
398 for (
int i = 0; i <
n; i++) {
399 const auto& phase = phases[(cur + i) %
n];
400 const char ls = phase->getState()[tlsLink->
getTLIndex()];
401 if (currentPhaseGreen && (ls ==
'g' || ls ==
'G')) {
402 countOld = (cur + i) %
n;
405 if (currentPhaseStop && (ls !=
'g' && ls !=
'G')) {
406 countOld = (cur + i) %
n;
409 result += phase->duration;
411 currentPhaseGreen = !currentPhaseGreen;
412 currentPhaseStop = !currentPhaseStop;
418 assert(tlsLink !=
nullptr);
420 assert(tl !=
nullptr);
422 const int n = (int)phases.size();
428 for (
int i = 1; i <
n; i++) {
429 const auto& phase = phases[(cur - i) %
n];
430 const char ls = phase->getState()[tlsLink->
getTLIndex()];
431 if (ls !=
'g' && ls !=
'G') {
434 result += phase->duration;
444 const double v =
myVeh.getSpeed();
445 const double a =
myVeh.getCarFollowModel().getMaxAccel();
448 const double remaining_time = remaining_dist / vMax;
449 return accel_time + remaining_time;
481 const double v = speed;
482 const double t = time;
483 const double a =
myVeh.getCarFollowModel().getMaxAccel();
485 return v * t + a * t * t / 2;
493 const double a =
myVeh.getCarFollowModel().getMaxAccel();
494 const double p_half = v / a;
495 const double t = -p_half + sqrt(p_half * p_half + 2 * d / a);
513 const double t = timeToSwitch;
514 const double a =
myVeh.getCarFollowModel().getMaxAccel();
516 const double w = vMax;
517 const double s = distance;
518 const double v =
myVeh.getSpeed();
528 const double rootConst = a * a * t * t - 2.0 * a * w * t + 2 * a * s;
530 if (rootConst >= 0) {
531 vConst = sqrt(rootConst) - a * t + w;
533 double d =
myVeh.getCarFollowModel().getMaxDecel();
539 const double sign0 = -1;
540 const double root_argument = a * d * ((2.0 * d * (s - (w * t))) - ((v - w) * (v - w)) + (a * ((d * (t * t)) + (2.0 * (s - (t * v))))));
541 if (root_argument < 0) {
543 WRITE_WARNINGF(
"GLOSA error 1 root_argument=% s=% t=% v=%", root_argument, s, t, v);
550 const double x = (((a * (v - (d * t))) + (d * w) - sign0 * sqrt(root_argument)) / (d + a));
551 double y = (v - x) / d;
555 if (s < (w * w - x * x) / 2.0 / a) {
558 std::vector<std::pair<SUMOTime, double> > speedTimeLine;
561 myVeh.getInfluencer().setSpeedTimeLine(speedTimeLine);
568 if (!(x >= u && x <= w && y < t)) {
570 WRITE_WARNINGF(
"GLOSA error 2 x=% y=% s=% t=% v=%", x, y, s, t, v);
575 std::cout <<
"veh=" <<
myVeh.getID() <<
" cant go slow enough" <<
"\n";
586 std::cout <<
"veh=" <<
myVeh.getID() <<
" cant go fast enough" <<
"\n";
592 const double targetSpeed = x;
593 const double duration =
MAX2(y,
TS);
597 std::cout <<
" targetSpeed=" << targetSpeed <<
" duration=" << duration <<
"\n";
601 std::vector<std::pair<SUMOTime, double> > speedTimeLine;
604 myVeh.getInfluencer().setSpeedTimeLine(speedTimeLine);
606 myVeh.setChosenSpeedFactor(targetSpeed /
myVeh.getLane()->getSpeedLimit());
624 if (key ==
"minSpeed") {
639 if (key ==
"minSpeed") {
#define WRITE_WARNINGF(...)
const std::string invalid_return< std::string >::value
@ SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
void generateOutput(OutputDevice *tripinfoOut) const
Called on writing tripinfo output.
const MSLink * myNextTLSLink
the upcoming traffic light
MSVehicle & myVeh
myHolder cast to needed type
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
static double timeGreen(const MSLink *tlsLink)
bool mySpeedAdviceActive
If speedFactor is currently beeing changed by the GLOSA device.
bool myOverrideSafety
if true ignore the current light state, always follow GLOSA's predicted state
bool myUseQueue
if true the queue in front of the TLS is used for calculation
double myAddSwitchTime
Additional time the vehicle shall need to reach the intersection after the signal turns green.
double myMaxSpeedFactor
maximum speed factor when trying to reach green light
double myRange
maximum communication range
void adaptSpeed(double distance, double timeToJunction, double timeToSwitch, bool &solved)
adapt speed to reach junction at green
double myMinSpeed
minimum approach speed towards red light
~MSDevice_GLOSA()
Destructor.
double time_to_junction_at_continuous_accel(double d, double v)
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_GLOSA-options.
static double getTimeToSwitch(const MSLink *tlsLink, int &countOld)
compute time to next (relevant) switch
double myDistance
the distance to the upcoming traffic light
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
updates next tls link
double distance_at_continuous_accel(double speed, double time)
double earliest_arrival(double speed, double distance)
return minimum number of seconds to reach the junction
double myOriginalSpeedFactor
original speed factor
static void cleanup()
resets counters
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this device. Throw exception for unsupported key
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
updates distance and computes speed advice
static double getTimeToNextSwitch(const MSLink *tlsLink, bool ¤tPhaseGreen, bool ¤tPhaseStop, int &countOld)
compute time to next (relevant) switch the vehicle can reach
const std::string deviceName() const
return the name for this type of device
MSDevice_GLOSA(SUMOVehicle &holder, const std::string &id, double minSpeed, double range, double maxSpeedFactor, double addSwitchTime, bool useQueue, bool overrideSafety, bool ignoreCFModel)
Constructor.
bool myIgnoreCFModel
if true ignore non-critical speed calculations from the CF model, follow GLOSA's perfect speed calcul...
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.
bool isInternal() const
return whether this edge is an internal edge
Representation of a lane in the micro simulation.
static std::vector< MSLink * >::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
double getLength() const
Returns the lane's length.
bool isLinkEnd(std::vector< MSLink * >::const_iterator &i) const
MSEdge & getEdge() const
Returns the lane's edge.
int getTLIndex() const
Returns the TLS index.
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
bool haveRed() const
Returns whether this link is blocked by a red (or redyellow) traffic light.
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
The parent class for traffic light logics.
virtual int getCurrentPhaseIndex() const =0
Returns the current index within the program.
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
SUMOTime getSpentDuration(SUMOTime simStep=-1) const
Returns the duration spent in the current phase.
MSVehicleDevice(SUMOVehicle &holder, const std::string &id)
Constructor.
Representation of a vehicle in the micro simulation.
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 *o)
Adds an option under the given name.
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.
Representation of a vehicle, person, or container.
bool getBoolParam(const std::string ¶mName, const bool required=false, const bool deflt=false) const
Retrieve a boolean parameter for the traffic object.
double getFloatParam(const std::string ¶mName, const bool required=false, const double deflt=INVALID_DOUBLE, bool checkDist=true) const
Retrieve a floating point parameter for the traffic object.
Representation of a vehicle.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
*brief user defined string literal for JSON values *sa std::size_t n