Eclipse SUMO - Simulation of Urban MObility
MSCFModel_CC.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// A series of automatic Cruise Controllers (CC, ACC, CACC)
19/****************************************************************************/
20#include <config.h>
21
22#include <algorithm>
26#include <microsim/MSVehicle.h>
28#include <microsim/MSNet.h>
29#include <microsim/MSEdge.h>
30#include <microsim/MSStop.h>
32#include <libsumo/Vehicle.h>
33#include <libsumo/TraCIDefs.h>
34#include "MSCFModel_CC.h"
35
36#ifndef sgn
37#define sgn(x) ((x > 0) - (x < 0))
38#endif
39
40
41// ===========================================================================
42// method definitions
43// ===========================================================================
45 myCcDecel(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_CCDECEL, 1.5)),
46 myCcAccel(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_CCACCEL, 1.5)),
47 myConstantSpacing(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_CONSTSPACING, 5.0)),
48 myKp(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_KP, 1.0)),
49 myLambda(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_LAMBDA, 0.1)),
50 myC1(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_C1, 0.5)),
51 myXi(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_XI, 1.0)),
52 myOmegaN(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_OMEGAN, 0.2)),
53 myTau(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_TAU, 0.5)),
54 myLanesCount((int)vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_LANES_COUNT, -1)),
55 myPloegH(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_PLOEG_H, 0.5)),
56 myPloegKp(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_PLOEG_KP, 0.2)),
57 myPloegKd(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_PLOEG_KD, 0.7)),
58 myFlatbedKa(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_KA, 2.4)),
59 myFlatbedKv(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_KV, 0.6)),
60 myFlatbedKp(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_KP, 12.0)),
61 myFlatbedH(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_H, 4.0)),
62 myFlatbedD(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_D, 5.0)) {
63
64 //if the lanes count has not been specified in the attributes of the model, lane changing cannot properly work
65 if (myLanesCount == -1) {
66 throw ProcessError("The number of lanes needs to be specified in the attributes of carFollowing-CC with the \"lanesCount\" attribute");
67 }
68
69 //instantiate the driver model. For now, use Krauss as default, then needs to be parameterized
71
72}
73
75
79 vars->ccKp = myKp;
80 vars->accLambda = myLambda;
82 vars->caccC1 = myC1;
83 vars->caccXi = myXi;
84 vars->caccOmegaN = myOmegaN;
85 vars->engineTau = myTau;
86 //we cannot invoke recomputeParameters() because we have no pointer to the MSVehicle class
87 vars->caccAlpha1 = 1 - vars->caccC1;
88 vars->caccAlpha2 = vars->caccC1;
89 vars->caccAlpha3 = -(2 * vars->caccXi - vars->caccC1 * (vars->caccXi + sqrt(vars->caccXi * vars->caccXi - 1))) * vars->caccOmegaN;
90 vars->caccAlpha4 = -(vars->caccXi + sqrt(vars->caccXi * vars->caccXi - 1)) * vars->caccOmegaN * vars->caccC1;
91 vars->caccAlpha5 = -vars->caccOmegaN * vars->caccOmegaN;
92
93 vars->ploegH = myPloegH;
94 vars->ploegKp = myPloegKp;
95 vars->ploegKd = myPloegKd;
96 vars->flatbedKa = myFlatbedKa;
97 vars->flatbedKv = myFlatbedKv;
98 vars->flatbedKp = myFlatbedKp;
99 vars->flatbedD = myFlatbedD;
100 vars->flatbedH = myFlatbedH;
101 //by default use a first order lag model for the engine
102 vars->engine = new FirstOrderLagModel();
108 return (VehicleVariables*)vars;
109}
110
111void
113 bool canChange;
115 // check for left lane change
116 std::pair<int, int> state = libsumo::Vehicle::getLaneChangeState(veh->getID(), +1);
117 int traciState = state.first;
118 if (traciState & LCA_LEFT && traciState & LCA_SPEEDGAIN) {
119 // we can gain by moving left. check that all vehicles can move left
120 if (!(state.first & LCA_BLOCKED)) {
121 // leader is not blocked. check all the members
122 canChange = true;
123 for (auto m = vars->members.begin(); m != vars->members.end(); m++) {
124 const std::pair<int, int> mState = libsumo::Vehicle::getLaneChangeState(m->second, +1);
125 if (mState.first & LCA_BLOCKED) {
126 canChange = false;
127 break;
128 }
129 }
130 if (canChange) {
131 libsumo::Vehicle::changeLane(veh->getID(), veh->getLaneIndex() + 1, 0);
132 for (auto m = vars->members.begin(); m != vars->members.end(); m++) {
133 libsumo::Vehicle::changeLane(m->second, veh->getLaneIndex() + 1, 0);
134 }
135 }
136
137 }
138 }
139 state = libsumo::Vehicle::getLaneChangeState(veh->getID(), -1);
140 traciState = state.first;
141 if (traciState & LCA_RIGHT && traciState & LCA_KEEPRIGHT) {
142 // we should move back right. check that all vehicles can move right
143 if (!(state.first & LCA_BLOCKED)) {
144 // leader is not blocked. check all the members
145 canChange = true;
146 for (auto m = vars->members.begin(); m != vars->members.end(); m++) {
147 const std::pair<int, int> mState = libsumo::Vehicle::getLaneChangeState(m->second, -1);
148 if (mState.first & LCA_BLOCKED) {
149 canChange = false;
150 break;
151 }
152 }
153 if (canChange) {
154 libsumo::Vehicle::changeLane(veh->getID(), veh->getLaneIndex() - 1, 1);
155 for (auto m = vars->members.begin(); m != vars->members.end(); m++) {
156 libsumo::Vehicle::changeLane(m->second, veh->getLaneIndex() - 1, 1);
157 }
158 }
159
160 }
161 }
162
163}
164
165double
166MSCFModel_CC::finalizeSpeed(MSVehicle* const veh, double vPos) const {
167 double vNext;
168 //acceleration computed by the controller
169 double controllerAcceleration;
170 //acceleration after engine actuation
171 double engineAcceleration;
172
174
175 //call processNextStop() to ensure vehicle removal in case of crash
176 veh->processNextStop(vPos);
177
178 //check whether the vehicle has collided and set the flag in case
179 if (!vars->crashed) {
180 for (const MSStop& s : veh->getStops()) {
181 if (s.pars.collision) {
182 vars->crashed = true;
183 }
184 }
185 }
186
187 if (vars->activeController != Plexe::DRIVER) {
189 }
190
191 if (vars->autoLaneChange) {
193 }
194
195 if (vars->activeController != Plexe::DRIVER) {
196 controllerAcceleration = SPEED2ACCEL(vPos - veh->getSpeed());
197 controllerAcceleration = std::min(vars->uMax, std::max(vars->uMin, controllerAcceleration));
198 //compute the actual acceleration applied by the engine
199 engineAcceleration = vars->engine->getRealAcceleration(veh->getSpeed(), veh->getAcceleration(), controllerAcceleration, MSNet::getInstance()->getCurrentTimeStep());
200 vNext = MAX2(double(0), veh->getSpeed() + ACCEL2SPEED(engineAcceleration));
201 vars->controllerAcceleration = controllerAcceleration;
202 } else {
203 vNext = myHumanDriver->finalizeSpeed(veh, vPos);
204 }
205
206 return vNext;
207}
208
209
210double
211MSCFModel_CC::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const pred, const CalcReason usage) const {
212
213 UNUSED_PARAMETER(pred);
215
216 if (vars->activeController != Plexe::DRIVER) {
217 return _v(veh, gap2pred, speed, predSpeed);
218 } else {
219 return myHumanDriver->followSpeed(veh, speed, gap2pred, predSpeed, predMaxDecel, pred, usage);
220 }
221}
222
223double
224MSCFModel_CC::insertionFollowSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const /*pred*/) const {
225 UNUSED_PARAMETER(veh);
226 UNUSED_PARAMETER(gap2pred);
227 UNUSED_PARAMETER(predSpeed);
228 UNUSED_PARAMETER(predMaxDecel);
229 //by returning speed + 1, we tell sumo that "speed" is always a safe speed
230 return speed + 1;
231}
232
233double
234MSCFModel_CC::stopSpeed(const MSVehicle* const veh, double speed, double gap2pred, double decel, const CalcReason usage) const {
235
237 if (vars->activeController != Plexe::DRIVER) {
238 double relSpeed;
239 getRadarMeasurements(veh, gap2pred, relSpeed);
240 if (gap2pred == -1) {
241 gap2pred = std::numeric_limits<double>().max();
242 }
243 return _v(veh, gap2pred, speed, speed + relSpeed);
244 } else {
245 return myHumanDriver->stopSpeed(veh, speed, gap2pred, decel, usage);
246 }
247}
248
249double MSCFModel_CC::freeSpeed(const MSVehicle* const veh, double speed, double seen, double maxSpeed, const bool onInsertion, const CalcReason usage) const {
251 if (vars->activeController != Plexe::DRIVER) {
252 double gap2pred, relSpeed;
253 getRadarMeasurements(veh, gap2pred, relSpeed);
254 if (gap2pred == -1) {
255 gap2pred = std::numeric_limits<double>().max();
256 }
257 return _v(veh, gap2pred, speed, speed + relSpeed);
258 } else {
259 return MSCFModel::freeSpeed(veh, speed, seen, maxSpeed, onInsertion, usage);
260 }
261}
262
263double
264MSCFModel_CC::interactionGap(const MSVehicle* const veh, double vL) const {
265
267 if (vars->activeController != Plexe::DRIVER) {
268 //maximum radar range is CC is enabled
269 return 250;
270 } else {
271 return myHumanDriver->interactionGap(veh, vL);
272 }
273
274}
275
276double
277MSCFModel_CC::maxNextSpeed(double speed, const MSVehicle* const veh) const {
279 if (vars->engineModel == CC_ENGINE_MODEL_FOLM) {
280 return speed + (double) ACCEL2SPEED(getMaxAccel());
281 } else {
282 return speed + (double) ACCEL2SPEED(20);
283 }
284}
285
286double
287MSCFModel_CC::minNextSpeed(double speed, const MSVehicle* const veh) const {
289 if (vars->engineModel == CC_ENGINE_MODEL_FOLM) {
290 return MSCFModel::minNextSpeed(speed, veh);
291 } else {
292 return MAX2((double)0, speed - (double) ACCEL2SPEED(20));
293 }
294}
295
296double
297MSCFModel_CC::_v(const MSVehicle* const veh, double gap2pred, double egoSpeed, double predSpeed) const {
298
300
301 //acceleration computed by the controller
302 double controllerAcceleration = vars->fixedAcceleration;
303 //speed computed by the model
304 double speed;
305 //acceleration computed by the Cruise Control
306 double ccAcceleration;
307 //acceleration computed by the Adaptive Cruise Control
308 double accAcceleration;
309 //acceleration computed by the Cooperative Adaptive Cruise Control
310 double caccAcceleration;
311 //variables needed by CACC
312 double predAcceleration, leaderAcceleration, leaderSpeed;
313 //dummy variables used for auto feeding
314 Position pos;
315 double time;
316 const double currentTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() + DELTA_T);
317
318 if (vars->crashed) {
319 return 0;
320 }
321 if (vars->activeController == Plexe::DRIVER || !vars->useFixedAcceleration) {
322 switch (vars->activeController) {
323 case Plexe::ACC:
324 ccAcceleration = _cc(veh, egoSpeed, vars->ccDesiredSpeed);
325 accAcceleration = _acc(veh, egoSpeed, predSpeed, gap2pred, vars->accHeadwayTime);
326 if (gap2pred > 250 || ccAcceleration < accAcceleration) {
327 controllerAcceleration = ccAcceleration;
328 } else {
329 controllerAcceleration = accAcceleration;
330 }
331 break;
332
333 case Plexe::CACC:
334 if (vars->autoFeed) {
337 }
338
339 if (vars->useControllerAcceleration) {
340 predAcceleration = vars->frontControllerAcceleration;
341 leaderAcceleration = vars->leaderControllerAcceleration;
342 } else {
343 predAcceleration = vars->frontAcceleration;
344 leaderAcceleration = vars->leaderAcceleration;
345 }
346 //overwrite pred speed using data obtained through wireless communication
347 predSpeed = vars->frontSpeed;
348 leaderSpeed = vars->leaderSpeed;
349 if (vars->usePrediction) {
350 predSpeed += (currentTime - vars->frontDataReadTime) * vars->frontAcceleration;
351 leaderSpeed += (currentTime - vars->leaderDataReadTime) * vars->leaderAcceleration;
352 }
353
354 if (vars->caccInitialized) {
355 controllerAcceleration = _cacc(veh, egoSpeed, predSpeed, predAcceleration, gap2pred, leaderSpeed, leaderAcceleration, vars->caccSpacing);
356 } else
357 //do not let CACC take decisions until at least one packet has been received
358 {
359 controllerAcceleration = 0;
360 }
361
362 break;
363
365
366 if (vars->autoFeed) {
370 }
371
372 if (vars->useControllerAcceleration) {
373 predAcceleration = vars->fakeData.frontControllerAcceleration;
374 leaderAcceleration = vars->fakeData.leaderControllerAcceleration;
375 } else {
376 predAcceleration = vars->fakeData.frontAcceleration;
377 leaderAcceleration = vars->fakeData.leaderAcceleration;
378 }
379 ccAcceleration = _cc(veh, egoSpeed, vars->ccDesiredSpeed);
380 caccAcceleration = _cacc(veh, egoSpeed, vars->fakeData.frontSpeed, predAcceleration, vars->fakeData.frontDistance, vars->fakeData.leaderSpeed, leaderAcceleration, vars->caccSpacing);
381 //faked CACC can be used to get closer to a platoon for joining
382 //using the minimum acceleration ensures that we do not exceed
383 //the CC desired speed
384 controllerAcceleration = std::min(ccAcceleration, caccAcceleration);
385
386 break;
387
388 case Plexe::PLOEG:
389
390 if (vars->autoFeed) {
392 }
393
394 if (vars->useControllerAcceleration) {
395 predAcceleration = vars->frontControllerAcceleration;
396 } else {
397 predAcceleration = vars->frontAcceleration;
398 }
399 //check if we received at least one packet
400 if (vars->frontInitialized)
401 //ploeg's controller computes \dot{u}_i, so we need to sum such value to the previously computed u_i
402 {
403 controllerAcceleration = vars->controllerAcceleration + _ploeg(veh, egoSpeed, predSpeed, predAcceleration, gap2pred);
404 } else {
405 controllerAcceleration = 0;
406 }
407
408 break;
409
410 case Plexe::CONSENSUS:
411 controllerAcceleration = _consensus(veh, egoSpeed, veh->getPosition(), currentTime);
412 break;
413
414 case Plexe::FLATBED:
415
416 if (vars->autoFeed) {
419 }
420
421 //overwrite pred speed using data obtained through wireless communication
422 predSpeed = vars->frontSpeed;
423 leaderSpeed = vars->leaderSpeed;
424 if (vars->usePrediction) {
425 predSpeed += (currentTime - vars->frontDataReadTime) * vars->frontAcceleration;
426 leaderSpeed += (currentTime - vars->leaderDataReadTime) * vars->leaderAcceleration;
427 }
428
429 if (vars->caccInitialized) {
430 controllerAcceleration = _flatbed(veh, veh->getAcceleration(), egoSpeed, predSpeed, gap2pred, leaderSpeed);
431 } else
432 //do not let CACC take decisions until at least one packet has been received
433 {
434 controllerAcceleration = 0;
435 }
436
437 break;
438
439 case Plexe::DRIVER:
440 std::cerr << "Switching to normal driver behavior still not implemented in MSCFModel_CC\n";
441 assert(false);
442 break;
443
444 default:
445 std::cerr << "Invalid controller selected in MSCFModel_CC\n";
446 assert(false);
447 break;
448
449 }
450
451 }
452
453 speed = MAX2(double(0), egoSpeed + ACCEL2SPEED(controllerAcceleration));
454
455 return speed;
456}
457
458double
459MSCFModel_CC::_cc(const MSVehicle* veh, double egoSpeed, double desSpeed) const {
460
462 //Eq. 5.5 of the Rajamani book, with Ki = 0 and bounds on max and min acceleration
463 return std::min(myCcAccel, std::max(-myCcDecel, -vars->ccKp * (egoSpeed - desSpeed)));
464
465}
466
467double
468MSCFModel_CC::_acc(const MSVehicle* veh, double egoSpeed, double predSpeed, double gap2pred, double headwayTime) const {
469
471 //Eq. 6.18 of the Rajamani book
472 return -1.0 / headwayTime * (egoSpeed - predSpeed + vars->accLambda * (-gap2pred + headwayTime * egoSpeed + 2));
473
474}
475
476double
477MSCFModel_CC::_cacc(const MSVehicle* veh, double egoSpeed, double predSpeed, double predAcceleration, double gap2pred, double leaderSpeed, double leaderAcceleration, double spacing) const {
479 //compute epsilon, i.e., the desired distance error
480 double epsilon = -gap2pred + spacing; //NOTICE: error (if any) should already be included in gap2pred
481 //compute epsilon_dot, i.e., the desired speed error
482 double epsilon_dot = egoSpeed - predSpeed;
483 //Eq. 7.39 of the Rajamani book
484 return vars->caccAlpha1 * predAcceleration + vars->caccAlpha2 * leaderAcceleration +
485 vars->caccAlpha3 * epsilon_dot + vars->caccAlpha4 * (egoSpeed - leaderSpeed) + vars->caccAlpha5 * epsilon;
486}
487
488
489double
490MSCFModel_CC::_ploeg(const MSVehicle* veh, double egoSpeed, double predSpeed, double predAcceleration, double gap2pred) const {
492 return (1 / vars->ploegH * (
494 vars->ploegKp * (gap2pred - (2 + vars->ploegH * egoSpeed)) +
495 vars->ploegKd * (predSpeed - egoSpeed - vars->ploegH * veh->getAcceleration()) +
496 predAcceleration
497 )) * TS ;
498}
499
500double
501MSCFModel_CC::d_i_j(const struct Plexe::VEHICLE_DATA* vehicles, const double h[MAX_N_CARS], int i, int j) const {
502
503 int k, min_i, max_i;
504 double d = 0;
505 //compute indexes of the summation
506 if (j < i) {
507 min_i = j;
508 max_i = i - 1;
509 } else {
510 min_i = i;
511 max_i = j - 1;
512 }
513 //compute distance
514 for (k = min_i; k <= max_i; k++) {
515 d += h[k] * vehicles[0].speed + vehicles[k].length + 15;
516 }
517
518 if (j < i) {
519 return d;
520 } else {
521 return -d;
522 }
523
524}
525
526double
527MSCFModel_CC::_consensus(const MSVehicle* veh, double egoSpeed, Position egoPosition, double time) const {
528 //TODO: this controller, by using real GPS coordinates, does only work
529 //when vehicles are traveling west-to-east on a straight line, basically
530 //on the X axis. This needs to be fixed to consider direction as well
532 int index = vars->position;
533 int nCars = vars->nCars;
534 struct Plexe::VEHICLE_DATA* vehicles = vars->vehicles;
535
536 //loop variable
537 int j;
538 //control input
539 double u_i = 0;
540 //actual distance term
541 double actualDistance = 0;
542 //desired distance term
543 double desiredDistance = 0;
544 //speed error term
545 double speedError = 0;
546 //degree of agent i
547 double d_i = 0;
548
549 //compensate my position: compute prediction of what will be my position at time of actuation
550 Position egoVelocity = veh->getVelocityVector();
551 egoPosition.set(egoPosition.x() + egoVelocity.x() * STEPS2TIME(DELTA_T),
552 egoPosition.y() + egoVelocity.y() * STEPS2TIME(DELTA_T));
553 vehicles[index].speed = egoSpeed;
554 vehicles[index].positionX = egoPosition.x();
555 vehicles[index].positionY = egoPosition.y();
556
557 //check that data from all vehicles have been received. the control
558 //law might actually need a subset of all the data, but d_i_j needs
559 //the lengths of all vehicles. uninitialized values might cause problems
560 if (vars->nInitialized != vars->nCars - 1) {
561 return 0;
562 }
563
564 //compute speed error.
565 speedError = -vars->b[index] * (egoSpeed - vehicles[0].speed);
566
567 //compute desired distance term
568 for (j = 0; j < nCars; j++) {
569 if (j == index) {
570 continue;
571 }
572 d_i += vars->L[index][j];
573 desiredDistance -= vars->K[index][j] * vars->L[index][j] * d_i_j(vehicles, vars->h, index, j);
574 }
575 desiredDistance = desiredDistance / d_i;
576
577 //compute actual distance term
578 for (j = 0; j < nCars; j++) {
579 if (j == index) {
580 continue;
581 }
582 //distance error for consensus with GPS equipped
583 Position otherPosition;
584 double dt = time - vehicles[j].time;
585 //predict the position of the other vehicle
586 otherPosition.setx(vehicles[j].positionX + dt * vehicles[j].speedX);
587 otherPosition.sety(vehicles[j].positionY + dt * vehicles[j].speedY);
588 double distance = egoPosition.distanceTo2D(otherPosition) * sgn(j - index);
589 actualDistance -= vars->K[index][j] * vars->L[index][j] * distance;
590 }
591
592 actualDistance = actualDistance / (d_i);
593
594 //original paper formula
595 u_i = (speedError + desiredDistance + actualDistance) / 1000;
596
597 return u_i;
598}
599
600double
601MSCFModel_CC::_flatbed(const MSVehicle* veh, double egoAcceleration, double egoSpeed, double predSpeed,
602 double gap2pred, double leaderSpeed) const {
604 return (
605 -vars->flatbedKa * egoAcceleration +
606 vars->flatbedKv * (predSpeed - egoSpeed) +
607 vars->flatbedKp * (gap2pred - vars->flatbedD - vars->flatbedH * (egoSpeed - leaderSpeed))
608 );
609}
610
611double
614 return vars->caccSpacing;
615}
616
617void
618MSCFModel_CC::getVehicleInformation(const MSVehicle* veh, double& speed, double& acceleration, double& controllerAcceleration, Position& position, double& time) const {
620 speed = veh->getSpeed();
622 controllerAcceleration = vars->controllerAcceleration;
623 position = veh->getPosition();
624 time = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
625}
626
627void MSCFModel_CC::setParameter(MSVehicle* veh, const std::string& key, const std::string& value) const {
628 // vehicle variables used to set the parameter
630
631 ParBuffer buf(value);
632
634 try {
635 if (key.compare(PAR_LEADER_SPEED_AND_ACCELERATION) == 0) {
636 double x, y, vx, vy;
637 buf >> vars->leaderSpeed >> vars->leaderAcceleration >> x >> y >> vars->leaderDataReadTime
638 >> vars->leaderControllerAcceleration >> vx >> vy >> vars->leaderAngle;
639 vars->leaderPosition = Position(x, y);
640 vars->leaderVelocity = Position(vx, vy);
641 vars->leaderInitialized = true;
642 if (vars->frontInitialized) {
643 vars->caccInitialized = true;
644 }
645 return;
646 }
647 if (key.compare(PAR_PRECEDING_SPEED_AND_ACCELERATION) == 0) {
648 double x, y, vx, vy;
649 buf >> vars->frontSpeed >> vars->frontAcceleration >> x >> y >> vars->frontDataReadTime
650 >> vars->frontControllerAcceleration >> vx >> vy >> vars->frontAngle;
651 vars->frontPosition = Position(x, y);
652 vars->frontVelocity = Position(vx, vy);
653 vars->frontInitialized = true;
654 if (vars->leaderInitialized) {
655 vars->caccInitialized = true;
656 }
657 return;
658 }
659 if (key.compare(CC_PAR_VEHICLE_DATA) == 0) {
660 struct Plexe::VEHICLE_DATA vehicle;
661 buf >> vehicle.index >> vehicle.speed >> vehicle.acceleration >>
662 vehicle.positionX >> vehicle.positionY >> vehicle.time >>
663 vehicle.length >> vehicle.u >> vehicle.speedX >>
664 vehicle.speedY >> vehicle.angle;
665 //if the index is larger than the number of cars, simply ignore the data
666 if (vehicle.index >= vars->nCars || vehicle.index == -1) {
667 return;
668 }
669 vars->vehicles[vehicle.index] = vehicle;
670 if (!vars->initialized[vehicle.index] && vehicle.index != vars->position) {
671 vars->nInitialized++;
672 }
673 vars->initialized[vehicle.index] = true;
674 return;
675 }
676 if (key.compare(PAR_LEADER_FAKE_DATA) == 0) {
677 buf >> vars->fakeData.leaderSpeed >> vars->fakeData.leaderAcceleration
679 if (buf.last_empty()) {
680 vars->useControllerAcceleration = false;
681 }
682 return;
683 }
684 if (key.compare(PAR_FRONT_FAKE_DATA) == 0) {
687 if (buf.last_empty()) {
688 vars->useControllerAcceleration = false;
689 }
690 return;
691 }
692 if (key.compare(CC_PAR_VEHICLE_POSITION) == 0) {
693 vars->position = StringUtils::toInt(value.c_str());
694 return;
695 }
696 if (key.compare(CC_PAR_PLATOON_SIZE) == 0) {
697 vars->nCars = StringUtils::toInt(value.c_str());
698 // given that we have a static matrix, check that we're not
699 // setting a number of cars larger than the size of that matrix
700 if (vars->nCars > MAX_N_CARS) {
701 vars->nCars = MAX_N_CARS;
702 std::stringstream warn;
703 warn << "MSCFModel_CC: setting a number of cars of " << vars->nCars << " out of a maximum of " << MAX_N_CARS <<
704 ". The CONSENSUS controller will not work properly if chosen. If you are using a different controller " <<
705 "you can ignore this warning";
706 WRITE_WARNING(warn.str());
707 }
708 return;
709 }
710 if (key.compare(PAR_ADD_MEMBER) == 0) {
711 std::string id;
712 int position;
713 buf >> id >> position;
714 vars->members[position] = id;
715 return;
716 }
717 if (key.compare(PAR_REMOVE_MEMBER) == 0) {
718 for (auto item = vars->members.begin(); item != vars->members.end(); item++)
719 if (item->second.compare(value) == 0) {
720 vars->members.erase(item);
721 break;
722 }
723 return;
724 }
725 if (key.compare(PAR_ENABLE_AUTO_LANE_CHANGE) == 0) {
726 vars->autoLaneChange = StringUtils::toInt(value.c_str()) == 1;
727 return;
728 }
729 if (key.compare(CC_PAR_CACC_XI) == 0) {
730 vars->caccXi = StringUtils::toDouble(value.c_str());
732 return;
733 }
734 if (key.compare(CC_PAR_CACC_OMEGA_N) == 0) {
735 vars->caccOmegaN = StringUtils::toDouble(value.c_str());
737 return;
738 }
739 if (key.compare(CC_PAR_CACC_C1) == 0) {
740 vars->caccC1 = StringUtils::toDouble(value.c_str());
742 return;
743 }
744 if (key.compare(CC_PAR_ENGINE_TAU) == 0) {
745 vars->engineTau = StringUtils::toDouble(value.c_str());
749 }
750 if (key.compare(CC_PAR_UMIN) == 0) {
751 vars->uMin = StringUtils::toDouble(value.c_str());
752 return;
753 }
754 if (key.compare(CC_PAR_UMAX) == 0) {
755 vars->uMax = StringUtils::toDouble(value.c_str());
756 return;
757 }
758 if (key.compare(CC_PAR_PLOEG_H) == 0) {
759 vars->ploegH = StringUtils::toDouble(value.c_str());
760 return;
761 }
762 if (key.compare(CC_PAR_PLOEG_KP) == 0) {
763 vars->ploegKp = StringUtils::toDouble(value.c_str());
764 return;
765 }
766 if (key.compare(CC_PAR_PLOEG_KD) == 0) {
767 vars->ploegKd = StringUtils::toDouble(value.c_str());
768 return;
769 }
770 if (key.compare(CC_PAR_FLATBED_KA) == 0) {
771 vars->flatbedKa = StringUtils::toDouble(value.c_str());
772 return;
773 }
774 if (key.compare(CC_PAR_FLATBED_KV) == 0) {
775 vars->flatbedKv = StringUtils::toDouble(value.c_str());
776 return;
777 }
778 if (key.compare(CC_PAR_FLATBED_KP) == 0) {
779 vars->flatbedKp = StringUtils::toDouble(value.c_str());
780 return;
781 }
782 if (key.compare(CC_PAR_FLATBED_H) == 0) {
783 vars->flatbedH = StringUtils::toDouble(value.c_str());
784 return;
785 }
786 if (key.compare(CC_PAR_FLATBED_D) == 0) {
787 vars->flatbedD = StringUtils::toDouble(value.c_str());
788 return;
789 }
790 if (key.compare(CC_PAR_VEHICLE_ENGINE_MODEL) == 0) {
791 if (vars->engine) {
792 delete vars->engine;
793 }
794 int engineModel = StringUtils::toInt(value.c_str());
795 switch (engineModel) {
797 vars->engine = new RealisticEngineModel();
799 veh->getInfluencer().setSpeedMode(0);
801 break;
802 }
804 default: {
805 vars->engine = new FirstOrderLagModel();
809 break;
810 }
811 }
814 return;
815 }
816 if (key.compare(CC_PAR_VEHICLE_MODEL) == 0) {
818 return;
819 }
820 if (key.compare(CC_PAR_VEHICLES_FILE) == 0) {
822 return;
823 }
824 if (key.compare(PAR_CACC_SPACING) == 0) {
825 vars->caccSpacing = StringUtils::toDouble(value.c_str());
826 return;
827 }
828 if (key.compare(PAR_FIXED_ACCELERATION) == 0) {
829 buf >> vars->useFixedAcceleration >> vars->fixedAcceleration;
830 return;
831 }
832 if (key.compare(PAR_CC_DESIRED_SPEED) == 0) {
833 vars->ccDesiredSpeed = StringUtils::toDouble(value.c_str());
834 return;
835 }
836 if (key.compare(PAR_ACTIVE_CONTROLLER) == 0) {
838 return;
839 }
840 if (key.compare(PAR_ACC_HEADWAY_TIME) == 0) {
841 vars->accHeadwayTime = StringUtils::toDouble(value.c_str());
842 return;
843 }
844 if (key.compare(PAR_USE_CONTROLLER_ACCELERATION) == 0) {
845 vars->useControllerAcceleration = StringUtils::toInt(value.c_str()) != 0;
846 return;
847 }
848 if (key.compare(PAR_USE_AUTO_FEEDING) == 0) {
849 int af;
850 std::string leaderId, frontId;
851 buf >> af;
852 vars->autoFeed = af == 1;
853 if (vars->autoFeed) {
854 vars->usePrediction = false;
855 buf >> leaderId;
856 if (buf.last_empty()) {
857 throw InvalidArgument("Trying to enable auto feeding without providing leader vehicle id");
858 }
859 vars->leaderVehicle = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(leaderId));
860 if (vars->leaderVehicle == 0) {
861 throw libsumo::TraCIException("Vehicle '" + leaderId + "' is not known");
862 }
863 buf >> frontId;
864 if (buf.last_empty()) {
865 throw InvalidArgument("Trying to enable auto feeding without providing front vehicle id");
866 }
867 vars->frontVehicle = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(frontId));
868 if (vars->frontVehicle == 0) {
869 throw libsumo::TraCIException("Vehicle '" + frontId + "' is not known");
870 }
871 vars->leaderInitialized = true;
872 vars->frontInitialized = true;
873 vars->caccInitialized = true;
874 }
875 return;
876 }
877 if (key.compare(PAR_USE_PREDICTION) == 0) {
878 vars->usePrediction = StringUtils::toInt(value.c_str()) == 1;
879 return;
880 }
881 } catch (NumberFormatException&) {
882 throw InvalidArgument("Invalid value '" + value + "' for parameter '" + key + "' for vehicle '" + veh->getID() + "'");
883 }
884
885}
886
887std::string MSCFModel_CC::getParameter(const MSVehicle* veh, const std::string& key) const {
888 // vehicle variables used to set the parameter
890 ParBuffer buf;
891
893 if (key.compare(PAR_SPEED_AND_ACCELERATION) == 0) {
894 Position velocity = veh->getVelocityVector();
895 buf << veh->getSpeed() << veh->getAcceleration() <<
896 vars->controllerAcceleration << veh->getPosition().x() <<
897 veh->getPosition().y() <<
898 STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) <<
899 velocity.x() << velocity.y() << veh->getAngle();
900 return buf.str();
901 }
902 if (key.compare(PAR_CRASHED) == 0) {
903 return vars->crashed ? "1" : "0";
904 }
905 if (key.compare(PAR_RADAR_DATA) == 0) {
906 double distance, relSpeed;
907 getRadarMeasurements(veh, distance, relSpeed);
908 buf << distance << relSpeed;
909 return buf.str();
910 }
911 if (key.compare(PAR_LANES_COUNT) == 0) {
912 buf << veh->getLane()->getEdge().getLanes().size();
913 return buf.str();
914 }
915 if (key.compare(PAR_DISTANCE_TO_END) == 0) {
916 //route of the vehicle
917 const MSRoute* route;
918 //edge the vehicle is currently traveling on
919 const MSEdge* currentEdge;
920 //last edge of the route of this vehicle
921 const MSEdge* lastEdge;
922 //current position of the vehicle on the edge its traveling in
923 double positionOnEdge;
924 //distance to trip end using
925 double distanceToEnd;
926
927 route = &veh->getRoute();
928 currentEdge = veh->getEdge();
929 lastEdge = route->getEdges().back();
930 positionOnEdge = veh->getPositionOnLane();
931 distanceToEnd = route->getDistanceBetween(positionOnEdge, lastEdge->getLanes()[0]->getLength(), currentEdge, lastEdge);
932
933 buf << distanceToEnd;
934 return buf.str();
935 }
936 if (key.compare(PAR_DISTANCE_FROM_BEGIN) == 0) {
937 //route of the vehicle
938 const MSRoute* route;
939 //edge the vehicle is currently traveling on
940 const MSEdge* currentEdge;
941 //last edge of the route of this vehicle
942 const MSEdge* firstEdge;
943 //current position of the vehicle on the edge its traveling in
944 double positionOnEdge;
945 //distance to trip end using
946 double distanceFromBegin;
947
948 route = &veh->getRoute();
949 currentEdge = veh->getEdge();
950 firstEdge = route->getEdges().front();
951 positionOnEdge = veh->getPositionOnLane();
952 distanceFromBegin = route->getDistanceBetween(0, positionOnEdge, firstEdge, currentEdge);
953
954 buf << distanceFromBegin;
955 return buf.str();
956 }
957 if (key.compare(PAR_CC_DESIRED_SPEED) == 0) {
958 buf << (double)vars->ccDesiredSpeed;
959 return buf.str();
960 }
961 if (key.compare(PAR_ACTIVE_CONTROLLER) == 0) {
962 buf << (int)vars->activeController;
963 return buf.str();
964 }
965 if (key.compare(PAR_ACC_HEADWAY_TIME) == 0) {
966 buf << (double)vars->accHeadwayTime;
967 return buf.str();
968 }
969 if (key.compare(PAR_ACC_ACCELERATION) == 0) {
970 buf << getACCAcceleration(veh);
971 return buf.str();
972 }
973 if (key.compare(PAR_CACC_SPACING) == 0) {
974 buf << vars->caccSpacing;
975 return buf.str();
976 }
977 if (key.find(CC_PAR_VEHICLE_DATA) == 0) {
978 ParBuffer inBuf(key);
979 int index;
980 inBuf >> index;
981 struct Plexe::VEHICLE_DATA vehicle;
982 if (index >= vars->nCars || index < 0) {
983 vehicle.index = -1;
984 } else {
985 vehicle = vars->vehicles[index];
986 }
987 buf << vehicle.index << vehicle.speed << vehicle.acceleration <<
988 vehicle.positionX << vehicle.positionY << vehicle.time <<
989 vehicle.length << vehicle.u << vehicle.speedX <<
990 vehicle.speedY << vehicle.angle;
991 return buf.str();
992 }
993 if (key.compare(PAR_ENGINE_DATA) == 0) {
994 int gear;
995 double rpm;
996 RealisticEngineModel* engine = dynamic_cast<RealisticEngineModel*>(vars->engine);
997 if (engine) {
998 engine->getEngineData(veh->getSpeed(), gear, rpm);
999 } else {
1000 gear = -1;
1001 rpm = 0;
1002 }
1003 buf << (gear + 1) << rpm;
1004 return buf.str();
1005 }
1006 return "";
1007}
1008
1011 vars->caccAlpha1 = 1 - vars->caccC1;
1012 vars->caccAlpha2 = vars->caccC1;
1013 vars->caccAlpha3 = -(2 * vars->caccXi - vars->caccC1 * (vars->caccXi + sqrt(vars->caccXi * vars->caccXi - 1))) * vars->caccOmegaN;
1014 vars->caccAlpha4 = -(vars->caccXi + sqrt(vars->caccXi * vars->caccXi - 1)) * vars->caccOmegaN * vars->caccC1;
1015 vars->caccAlpha5 = -vars->caccOmegaN * vars->caccOmegaN;
1016}
1017
1020 for (int i = 0; i < MAX_N_CARS; i++) {
1021 vars->initialized[i] = false;
1022 vars->nInitialized = 0;
1023 }
1024}
1025
1026void MSCFModel_CC::switchOnACC(const MSVehicle* veh, double ccDesiredSpeed) const {
1028 vars->ccDesiredSpeed = ccDesiredSpeed;
1030}
1031
1034 return vars->activeController;
1035}
1036
1037void MSCFModel_CC::getRadarMeasurements(const MSVehicle* veh, double& distance, double& relativeSpeed) const {
1038 std::pair<std::string, double> l = libsumo::Vehicle::getLeader(veh->getID(), 250);
1039 if (l.second < 0) {
1040 distance = -1;
1041 relativeSpeed = 0;
1042 } else {
1043 distance = l.second;
1045 relativeSpeed = leader->getSpeed() - veh->getSpeed();
1046 }
1047}
1048
1051 double distance, relSpeed;
1052 getRadarMeasurements(veh, distance, relSpeed);
1053 if (distance < 0) {
1054 return 0;
1055 } else {
1056 return _acc(veh, veh->getSpeed(), relSpeed + veh->getSpeed(), distance, vars->accHeadwayTime);
1057 }
1058}
1059
1061 return myLanesCount;
1062}
1063
1064MSCFModel*
1066 return new MSCFModel_CC(vtype);
1067}
#define ENGINE_PAR_XMLFILE
Definition: CC_Const.h:87
#define PAR_RADAR_DATA
Definition: CC_Const.h:149
#define PAR_FIXED_ACCELERATION
Definition: CC_Const.h:128
#define PAR_REMOVE_MEMBER
Definition: CC_Const.h:180
#define CC_PAR_CACC_OMEGA_N
Definition: CC_Const.h:96
#define CC_PAR_FLATBED_KP
Definition: CC_Const.h:109
#define PAR_CACC_SPACING
Definition: CC_Const.h:119
#define CC_PAR_PLOEG_KP
Definition: CC_Const.h:104
#define PAR_FRONT_FAKE_DATA
Definition: CC_Const.h:155
#define PAR_SPEED_AND_ACCELERATION
Definition: CC_Const.h:131
#define CC_ENGINE_MODEL_REALISTIC
Definition: CC_Const.h:80
#define MAX_N_CARS
Definition: CC_Const.h:77
#define CC_PAR_FLATBED_KV
Definition: CC_Const.h:108
#define PAR_USE_PREDICTION
Definition: CC_Const.h:176
#define PAR_DISTANCE_TO_END
Definition: CC_Const.h:158
#define CC_ENGINE_MODEL_FOLM
Definition: CC_Const.h:79
#define CC_PAR_VEHICLE_MODEL
Definition: CC_Const.h:115
#define CC_PAR_PLOEG_H
Definition: CC_Const.h:103
#define PAR_PRECEDING_SPEED_AND_ACCELERATION
Definition: CC_Const.h:164
#define PAR_ACTIVE_CONTROLLER
Definition: CC_Const.h:146
#define CC_PAR_CACC_XI
Definition: CC_Const.h:95
#define PAR_LEADER_SPEED_AND_ACCELERATION
Definition: CC_Const.h:134
#define CC_PAR_PLATOON_SIZE
Definition: CC_Const.h:92
#define CC_PAR_UMIN
Definition: CC_Const.h:100
#define CC_PAR_VEHICLE_POSITION
Definition: CC_Const.h:91
#define CC_PAR_FLATBED_KA
Definition: CC_Const.h:107
#define PAR_LANES_COUNT
Definition: CC_Const.h:140
#define CC_PAR_VEHICLE_ENGINE_MODEL
Definition: CC_Const.h:113
#define PAR_USE_AUTO_FEEDING
Definition: CC_Const.h:173
#define CC_PAR_FLATBED_D
Definition: CC_Const.h:111
#define PAR_CC_DESIRED_SPEED
Definition: CC_Const.h:143
#define CC_PAR_PLOEG_KD
Definition: CC_Const.h:105
#define CC_PAR_VEHICLES_FILE
Definition: CC_Const.h:116
#define CC_PAR_UMAX
Definition: CC_Const.h:101
#define CC_PAR_CACC_C1
Definition: CC_Const.h:97
#define FOLM_PAR_DT
Definition: CC_Const.h:84
#define PAR_LEADER_FAKE_DATA
Definition: CC_Const.h:154
#define FOLM_PAR_TAU
Definition: CC_Const.h:83
#define CC_PAR_FLATBED_H
Definition: CC_Const.h:110
#define PAR_ADD_MEMBER
Definition: CC_Const.h:179
#define PAR_ACC_HEADWAY_TIME
Definition: CC_Const.h:167
#define PAR_DISTANCE_FROM_BEGIN
Definition: CC_Const.h:161
#define ENGINE_PAR_VEHICLE
Definition: CC_Const.h:86
#define CC_PAR_ENGINE_TAU
Definition: CC_Const.h:98
#define ENGINE_PAR_DT
Definition: CC_Const.h:88
#define PAR_USE_CONTROLLER_ACCELERATION
Definition: CC_Const.h:137
#define PAR_ACC_ACCELERATION
Definition: CC_Const.h:122
#define PAR_ENGINE_DATA
Definition: CC_Const.h:170
#define CC_PAR_VEHICLE_DATA
Definition: CC_Const.h:90
#define PAR_ENABLE_AUTO_LANE_CHANGE
Definition: CC_Const.h:183
#define PAR_CRASHED
Definition: CC_Const.h:125
#define sgn(x)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:50
#define TS
Definition: SUMOTime.h:41
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:52
@ LCA_KEEPRIGHT
The action is due to the default of keeping right "Rechtsfahrgebot".
@ LCA_BLOCKED
blocked in all directions
@ LCA_LEFT
Wants go to the left.
@ LCA_SPEEDGAIN
The action is due to the wish to be faster (tactical lc)
@ LCA_RIGHT
Wants go to the right.
@ SUMO_ATTR_CF_CC_FLATBED_KP
@ SUMO_ATTR_CF_CC_LAMBDA
@ SUMO_ATTR_CF_CC_FLATBED_D
@ SUMO_ATTR_CF_CC_FLATBED_KA
@ SUMO_ATTR_CF_CC_PLOEG_KP
@ SUMO_ATTR_CF_CC_PLOEG_H
@ SUMO_ATTR_CF_CC_OMEGAN
@ SUMO_ATTR_CF_CC_C1
@ SUMO_ATTR_CF_CC_CCACCEL
@ SUMO_ATTR_CF_CC_PLOEG_KD
@ SUMO_ATTR_CF_CC_TAU
@ SUMO_ATTR_CF_CC_XI
@ SUMO_ATTR_CF_CC_CCDECEL
@ SUMO_ATTR_CF_CC_FLATBED_H
@ SUMO_ATTR_CF_CC_LANES_COUNT
@ SUMO_ATTR_CF_CC_CONSTSPACING
@ SUMO_ATTR_CF_CC_KP
@ SUMO_ATTR_CF_CC_FLATBED_KV
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MAX2(T a, T b)
Definition: StdDefs.h:77
int nInitialized
count of initialized vehicles
bool autoFeed
determines whether CACC should automatically fetch data about other vehicles
struct FAKE_CONTROLLER_DATA fakeData
fake controller data.
MSVehicle * frontVehicle
front sumo id, used for auto feeding
double accHeadwayTime
headway time for ACC
bool initialized[MAX_N_CARS]
tells whether data about a certain vehicle has been initialized
double frontSpeed
current front vehicle speed
double K[MAX_N_CARS][MAX_N_CARS]
K matrix.
struct Plexe::VEHICLE_DATA vehicles[MAX_N_CARS]
data about vehicles in the platoon
int position
my position within the platoon (0 = first car)
double frontAcceleration
current front vehicle acceleration (used by CACC)
bool frontInitialized
@did we receive at least one packet?
double leaderDataReadTime
when leader data has been readed from GPS
bool usePrediction
enable/disable data prediction (interpolation) for missing data
std::map< int, std::string > members
list of members belonging to my platoon
double leaderControllerAcceleration
platoon's leader controller acceleration (used by CACC)
double controllerAcceleration
acceleration as computed by the controller, to be sent to other vehicles
int L[MAX_N_CARS][MAX_N_CARS]
L matrix.
double caccXi
controller related parameters
double frontControllerAcceleration
front vehicle controller acceleration (used by CACC)
double b[MAX_N_CARS]
vector of damping ratios b
GenericEngineModel * engine
engine model employed by this car
int nCars
number of cars in the platoon
double leaderSpeed
platoon's leader speed (used by CACC)
double leaderAngle
platoon's leader angle in radians
enum Plexe::ACTIVE_CONTROLLER activeController
currently active controller
bool leaderInitialized
@did we receive at least one packet?
double caccSpacing
fixed spacing for CACC
Position frontVelocity
front vehicle velocity vector
double uMin
limits for u
double ccDesiredSpeed
CC desired speed.
double h[MAX_N_CARS]
vector of time headways h
Position frontPosition
current front vehicle position
double leaderAcceleration
platoon's leader acceleration (used by CACC)
bool autoLaneChange
automatic whole platoon lane change
Position leaderVelocity
platoon's leader velocity vector
double frontAngle
front vehicle angle in radians
double frontDataReadTime
when front vehicle data has been readed from GPS
int engineModel
numeric value indicating the employed model
MSVehicle * leaderVehicle
leader vehicle, used for auto feeding
Position leaderPosition
platoon's leader position
bool useControllerAcceleration
determines whether PATH's CACC should use the real vehicle acceleration or the controller computed on...
void setMaximumAcceleration(double maxAcc)
virtual double getRealAcceleration(double speed_mps, double accel_mps2, double reqAccel_mps2, SUMOTime timeStep=0)=0
void setMaximumDeceleration(double maxDec)
virtual void setParameter(const std::string parameter, const std::string &value)=0
void setChosenSpeedFactor(const double factor)
Returns the precomputed factor by which the driver wants to be faster than the speed limit.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const std::list< MSStop > & getStops() const
const MSRoute & getRoute() const
Returns the current route.
double _v(const MSVehicle *const veh, double gap2pred, double egoSpeed, double predSpeed) const
MSCFModel_CC(const MSVehicleType *vtype)
Constructor.
virtual std::string getParameter(const MSVehicle *veh, const std::string &key) const
set the information about a generic car. This method should be invoked by TraCI when a wireless messa...
virtual double insertionFollowSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const
Overload base MSCFModel::insertionFollowSpeed method to inject automated vehicles as soon as they are...
const double myPloegKd
Definition: MSCFModel_CC.h:389
const double myFlatbedH
Definition: MSCFModel_CC.h:395
const double myFlatbedKp
Definition: MSCFModel_CC.h:394
const double myPloegH
Ploeg's CACC parameters.
Definition: MSCFModel_CC.h:387
double getACCAcceleration(const MSVehicle *veh) const
returns the ACC computed acceleration when the faked CACC is controlling the car. This can be used to...
int getMyLanesCount() const
returns the number of lanes set in the configuration file
double _flatbed(const MSVehicle *veh, double egoAcceleration, double egoSpeed, double predSpeed, double gap2pred, double leaderSpeed) const
flatbed platoon towing model
void getVehicleInformation(const MSVehicle *veh, double &speed, double &acceleration, double &controllerAcceleration, Position &position, double &time) const
get the information about a vehicle. This can be used by TraCI in order to get speed and acceleration...
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
VehicleVariables * createVehicleVariables() const
Returns model specific values which are stored inside a vehicle and must be used with casting.
void getRadarMeasurements(const MSVehicle *veh, double &distance, double &relativeSpeed) const
return the data that is currently being measured by the radar
double _consensus(const MSVehicle *veh, double egoSpeed, Position egoPosition, double time) const
controller based on consensus strategy
const double myPloegKp
Definition: MSCFModel_CC.h:388
double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed (no dawdling)
double _ploeg(const MSVehicle *veh, double egoSpeed, double predSpeed, double predAcceleration, double gap2pred) const
controller for the Ploeg's CACC which computes the control input variation. Opposed to other controll...
const double myTau
engine time constant used for actuation lag
Definition: MSCFModel_CC.h:380
double d_i_j(const struct Plexe::VEHICLE_DATA *vehicles, const double h[MAX_N_CARS], int i, int j) const
computes the desired distance between vehicle i and vehicle j
const double myOmegaN
design constant for CACC
Definition: MSCFModel_CC.h:377
double stopSpeed(const MSVehicle *const veh, const double speed, double gap2pred, double decel, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
const double myC1
design constant for CACC
Definition: MSCFModel_CC.h:371
const int myLanesCount
number of lanes in the highway, in the absence of on-/off-ramps. This is used to move to the correct ...
Definition: MSCFModel_CC.h:384
virtual double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
double _cacc(const MSVehicle *veh, double egoSpeed, double predSpeed, double predAcceleration, double gap2pred, double leaderSpeed, double leaderAcceleration, double spacing) const
controller for the CACC which computes the acceleration to be applied. the value needs to be passed t...
virtual void setParameter(MSVehicle *veh, const std::string &key, const std::string &value) const
try to set the given parameter for this carFollowingModel
const double myConstantSpacing
the constant gap for CACC
Definition: MSCFModel_CC.h:362
double getCACCConstantSpacing(const MSVehicle *veh) const
returns CACC desired constant spacing
~MSCFModel_CC()
Destructor.
const double myFlatbedKv
Definition: MSCFModel_CC.h:393
void recomputeParameters(const MSVehicle *veh) const
Recomputes controller related parameters after setting them.
const double myXi
design constant for CACC
Definition: MSCFModel_CC.h:374
const double myFlatbedKa
flatbed CACC parameters
Definition: MSCFModel_CC.h:392
void switchOnACC(const MSVehicle *veh, double ccDesiredSpeed) const
switch on the ACC, so disabling the human driver car control
MSCFModel * myHumanDriver
the car following model which drives the car when automated cruising is disabled, i....
Definition: MSCFModel_CC.h:353
const double myLambda
design constant for ACC
Definition: MSCFModel_CC.h:368
void performAutoLaneChange(MSVehicle *const veh) const
const double myKp
design constant for CC
Definition: MSCFModel_CC.h:365
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
const double myCcAccel
The maximum acceleration that the CC can output.
Definition: MSCFModel_CC.h:359
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed without a leader.
const double myCcDecel
The maximum deceleration that the CC can output.
Definition: MSCFModel_CC.h:356
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
const double myFlatbedD
Definition: MSCFModel_CC.h:396
void resetConsensus(const MSVehicle *veh) const
Resets the consensus controller. In particular, sets the "initialized" vector all to false....
double interactionGap(const MSVehicle *const, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
enum Plexe::ACTIVE_CONTROLLER getActiveController(const MSVehicle *veh) const
return the currently active controller
double _cc(const MSVehicle *veh, double egoSpeed, double desSpeed) const
controller for the CC which computes the acceleration to be applied. the value needs to be passed to ...
double _acc(const MSVehicle *veh, double egoSpeed, double predSpeed, double gap2pred, double headwayTime) const
controller for the ACC which computes the acceleration to be applied. the value needs to be passed to...
Krauss car-following model, with acceleration decrease and faster start.
The car-following model abstraction.
Definition: MSCFModel.h:55
virtual double interactionGap(const MSVehicle *const veh, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
Definition: MSCFModel.cpp:255
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed without a leader.
Definition: MSCFModel.cpp:299
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
Definition: MSCFModel.cpp:276
virtual double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences. Called at most once per simulation...
Definition: MSCFModel.cpp:165
CalcReason
What the return value of stop/follow/free-Speed is used for.
Definition: MSCFModel.h:77
double myDecel
The vehicle's maximum deceleration [m/s^2].
Definition: MSCFModel.h:686
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Definition: MSCFModel.h:254
double myAccel
The vehicle's maximum acceleration [m/s^2].
Definition: MSCFModel.h:683
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0, const CalcReason usage=CalcReason::CURRENT) const =0
Computes the vehicle's follow speed (no dawdling)
double stopSpeed(const MSVehicle *const veh, const double speed, double gap, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
Definition: MSCFModel.h:168
A road/street connecting two junctions.
Definition: MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:561
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:713
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:321
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:379
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:124
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true, int routePosition=0) const
Compute the distance between 2 given edges on this route, including the length of internal lanes....
Definition: MSRoute.cpp:316
Definition: MSStop.h:44
void setSpeedMode(int speedMode)
Sets speed-constraining behaviors.
Definition: MSVehicle.cpp:770
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Definition: MSVehicle.h:510
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:1208
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:577
Influencer & getInfluencer()
Definition: MSVehicle.cpp:6773
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:486
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1593
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:377
double getAngle() const
Returns the vehicle's direction in radians.
Definition: MSVehicle.h:729
MSCFModel::VehicleVariables * getCarFollowVariables() const
Returns the vehicle's car following model variables.
Definition: MSVehicle.h:987
int getLaneIndex() const
Definition: MSVehicle.cpp:6233
Position getVelocityVector() const
Returns the vehicle's direction in radians.
Definition: MSVehicle.h:737
The car-following model and parameter.
Definition: MSVehicleType.h:63
const std::string & getID() const
Returns the id.
Definition: Named.h:74
std::string str() const
Definition: ParBuffer.h:148
bool last_empty()
Definition: ParBuffer.h:138
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
void setx(double x)
set position x
Definition: Position.h:70
void set(double x, double y)
set positions x and y
Definition: Position.h:85
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:252
double x() const
Returns the x-position.
Definition: Position.h:55
void sety(double y)
set position y
Definition: Position.h:75
double y() const
Returns the y-position.
Definition: Position.h:60
void getEngineData(double speed_mps, int &gear, double &rpm)
virtual double getSpeed() const =0
Returns the object's current speed.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
An error which allows to continue.
Definition: TraCIDefs.h:138
ACTIVE_CONTROLLER
Determines the currently active controller, i.e., ACC, CACC, or the driver. In future we might need t...
Definition: CC_Const.h:49
@ DRIVER
Definition: CC_Const.h:49
@ CONSENSUS
Definition: CC_Const.h:49
@ FAKED_CACC
Definition: CC_Const.h:49
@ CACC
Definition: CC_Const.h:49
@ PLOEG
Definition: CC_Const.h:49
@ ACC
Definition: CC_Const.h:49
@ FLATBED
Definition: CC_Const.h:49
double acceleration
Definition: CC_Const.h:66