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-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // A series of automatic Cruise Controllers (CC, ACC, CACC)
16 /****************************************************************************/
17 
18 
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include "MSCFModel_CC.h"
23 #include <microsim/MSVehicle.h>
25 #include <microsim/MSNet.h>
26 #include <microsim/MSEdge.h>
28 #include <utils/common/SUMOTime.h>
31 #include <libsumo/Vehicle.h>
32 #include <libsumo/TraCIDefs.h>
33 #include <algorithm>
34 
35 #ifndef sgn
36 #define sgn(x) ((x > 0) - (x < 0))
37 #endif
38 
39 // ===========================================================================
40 // method definitions
41 // ===========================================================================
43  myCcDecel(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_CCDECEL, 1.5)),
44  myCcAccel(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_CCACCEL, 1.5)),
45  myConstantSpacing(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_CONSTSPACING, 5.0)),
46  myKp(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_KP, 1.0)),
47  myLambda(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_LAMBDA, 0.1)),
48  myC1(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_C1, 0.5)),
49  myXi(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_XI, 1.0)),
50  myOmegaN(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_OMEGAN, 0.2)),
51  myTau(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_TAU, 0.5)),
52  myLanesCount((int)vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_LANES_COUNT, -1)),
53  myPloegH(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_PLOEG_H, 0.5)),
54  myPloegKp(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_PLOEG_KP, 0.2)),
55  myPloegKd(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_PLOEG_KD, 0.7)),
56  myFlatbedKa(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_KA, 2.4)),
57  myFlatbedKv(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_KV, 0.6)),
58  myFlatbedKp(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_KP, 12.0)),
59  myFlatbedH(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_H, 4.0)),
60  myFlatbedD(vtype->getParameter().getCFParam(SUMO_ATTR_CF_CC_FLATBED_D, 5.0)) {
61 
62  //if the lanes count has not been specified in the attributes of the model, lane changing cannot properly work
63  if (myLanesCount == -1) {
64  std::cerr << "The number of lanes needs to be specified in the attributes of carFollowing-CC with the \"lanesCount\" attribute\n";
65  WRITE_ERROR("The number of lanes needs to be specified in the attributes of carFollowing-CC with the \"lanesCount\" attribute");
66  assert(false);
67  }
68 
69  //instantiate the driver model. For now, use Krauss as default, then needs to be parameterized
70  myHumanDriver = new MSCFModel_Krauss(vtype);
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();
103  vars->engine->setParameter(FOLM_PAR_TAU, vars->engineTau);
108  return (VehicleVariables*)vars;
109 }
110 
111 void
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 
165 double
166 MSCFModel_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  std::list<MSVehicle::Stop> stops = veh->getMyStops();
181  for (auto s : stops)
182  if (s.collision) {
183  vars->crashed = true;
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 
210 double
211 MSCFModel_CC::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const pred) 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);
220  }
221 }
222 
223 double
224 MSCFModel_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 
233 double
234 MSCFModel_CC::stopSpeed(const MSVehicle* const veh, double speed, double gap2pred) const {
235 
237  if (vars->activeController != Plexe::DRIVER) {
238  double gap2pred, 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);
246  }
247 }
248 
249 double MSCFModel_CC::freeSpeed(const MSVehicle* const veh, double speed, double seen, double maxSpeed, const bool onInsertion) 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);
260  }
261 }
262 
263 double
264 MSCFModel_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 
276 double
277 MSCFModel_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 
286 double
287 MSCFModel_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 
296 double
297 MSCFModel_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 
364  case Plexe::FAKED_CACC:
365 
366  if (vars->autoFeed) {
369  vars->fakeData.frontDistance = pos.distanceTo2D(veh->getPosition());
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 
458 double
459 MSCFModel_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 
467 double
468 MSCFModel_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 
476 double
477 MSCFModel_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 
489 double
490 MSCFModel_CC::_ploeg(const MSVehicle* veh, double egoSpeed, double predSpeed, double predAcceleration, double gap2pred) const {
492  return (1 / vars->ploegH * (
493  -vars->controllerAcceleration +
494  vars->ploegKp * (gap2pred - (2 + vars->ploegH * egoSpeed)) +
495  vars->ploegKd * (predSpeed - egoSpeed - vars->ploegH * veh->getAcceleration()) +
496  predAcceleration
497  )) * TS ;
498 }
499 
500 double
501 MSCFModel_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 
526 double
527 MSCFModel_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 
600 double
601 MSCFModel_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 
611 double
614  return vars->caccSpacing;
615 }
616 
617 void
618 MSCFModel_CC::getVehicleInformation(const MSVehicle* veh, double& speed, double& acceleration, double& controllerAcceleration, Position& position, double& time) const {
620  speed = veh->getSpeed();
621  acceleration = veh->getAcceleration();
622  controllerAcceleration = vars->controllerAcceleration;
623  position = veh->getPosition();
624  time = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
625 }
626 
627 void MSCFModel_CC::setParameter(MSVehicle* veh, const std::string& key, const std::string& value) const {
628  // vehicle variables used to set the parameter
629  CC_VehicleVariables* vars;
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) {
685  buf >> vars->fakeData.frontSpeed >> vars->fakeData.frontAcceleration >> vars->fakeData.frontDistance
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());
731  recomputeParameters(veh);
732  return;
733  }
734  if (key.compare(CC_PAR_CACC_OMEGA_N) == 0) {
735  vars->caccOmegaN = StringUtils::toDouble(value.c_str());
736  recomputeParameters(veh);
737  return;
738  }
739  if (key.compare(CC_PAR_CACC_C1) == 0) {
740  vars->caccC1 = StringUtils::toDouble(value.c_str());
741  recomputeParameters(veh);
742  return;
743  }
744  if (key.compare(CC_PAR_ENGINE_TAU) == 0) {
745  vars->engineTau = StringUtils::toDouble(value.c_str());
746  vars->engine->setParameter(FOLM_PAR_TAU, vars->engineTau);
747  recomputeParameters(veh);
748  vars->engine->setParameter(FOLM_PAR_TAU, vars->engineTau);
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();
807  vars->engine->setParameter(FOLM_PAR_TAU, vars->engineTau);
809  break;
810  }
811  }
814  return;
815  }
816  if (key.compare(CC_PAR_VEHICLE_MODEL) == 0) {
817  vars->engine->setParameter(ENGINE_PAR_VEHICLE, value);
818  return;
819  }
820  if (key.compare(CC_PAR_VEHICLES_FILE) == 0) {
821  vars->engine->setParameter(ENGINE_PAR_XMLFILE, value);
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) {
837  vars->activeController = (enum Plexe::ACTIVE_CONTROLLER) StringUtils::toInt(value.c_str());
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 
887 std::string MSCFModel_CC::getParameter(const MSVehicle* veh, const std::string& key) const {
888  // vehicle variables used to set the parameter
889  CC_VehicleVariables* vars;
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 
1018 void MSCFModel_CC::resetConsensus(const MSVehicle* veh) const {
1020  for (int i = 0; i < MAX_N_CARS; i++) {
1021  vars->initialized[i] = false;
1022  vars->nInitialized = 0;
1023  }
1024 }
1025 
1026 void MSCFModel_CC::switchOnACC(const MSVehicle* veh, double ccDesiredSpeed) const {
1028  vars->ccDesiredSpeed = ccDesiredSpeed;
1029  vars->activeController = Plexe::ACC;
1030 }
1031 
1034  return vars->activeController;
1035 }
1036 
1037 void 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 
1064 MSCFModel*
1066  return new MSCFModel_CC(vtype);
1067 }
bool last_empty()
Definition: ParBuffer.h:135
bool initialized[MAX_N_CARS]
tells whether data about a certain vehicle has been initialized
#define ENGINE_PAR_VEHICLE
Definition: CC_Const.h:83
#define CC_PAR_CACC_OMEGA_N
Definition: CC_Const.h:93
#define PAR_ACC_HEADWAY_TIME
Definition: CC_Const.h:164
#define PAR_CC_DESIRED_SPEED
Definition: CC_Const.h:140
const double myFlatbedH
Definition: MSCFModel_CC.h:396
#define sgn(x)
#define FOLM_PAR_DT
Definition: CC_Const.h:81
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:268
#define CC_ENGINE_MODEL_REALISTIC
Definition: CC_Const.h:77
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:670
int engineModel
numeric value indicating the employed model
const double myXi
design constant for CACC
Definition: MSCFModel_CC.h:375
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
MSCFModel::VehicleVariables * getCarFollowVariables() const
Returns the vehicle&#39;s car following model variables.
Definition: MSVehicle.h:911
#define PAR_DISTANCE_FROM_BEGIN
Definition: CC_Const.h:158
bool frontInitialized
we receive at least one packet?
~MSCFModel_CC()
Destructor.
double getAngle() const
Returns the vehicle&#39;s direction in radians.
Definition: MSVehicle.h:681
The action is due to the default of keeping right "Rechtsfahrgebot".
virtual double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:121
#define CC_PAR_FLATBED_KP
Definition: CC_Const.h:106
#define CC_PAR_PLOEG_KP
Definition: CC_Const.h:101
#define PAR_PRECEDING_SPEED_AND_ACCELERATION
Definition: CC_Const.h:161
#define PAR_ACTIVE_CONTROLLER
Definition: CC_Const.h:143
struct FAKE_CONTROLLER_DATA fakeData
fake controller data.
Position getVelocityVector() const
Returns the vehicle&#39;s direction in radians.
Definition: MSVehicle.h:689
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:53
#define PAR_USE_PREDICTION
Definition: CC_Const.h:173
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
#define PAR_LANES_COUNT
Definition: CC_Const.h:137
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:561
#define CC_PAR_FLATBED_H
Definition: CC_Const.h:107
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:245
double ccDesiredSpeed
CC desired speed.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:244
std::list< Stop > getMyStops()
Definition: MSVehicle.cpp:5812
#define CC_PAR_CACC_C1
Definition: CC_Const.h:94
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
#define PAR_USE_AUTO_FEEDING
Definition: CC_Const.h:170
double y() const
Returns the y-position.
Definition: Position.h:62
The car-following model abstraction.
Definition: MSCFModel.h:57
double b[MAX_N_CARS]
vector of damping ratios b
double frontSpeed
current front vehicle speed
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:397
GenericEngineModel * engine
engine model employed by this car
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
virtual void setParameter(MSVehicle *veh, const std::string &key, const std::string &value) const
try to set the given parameter for this carFollowingModel
#define CC_PAR_PLATOON_SIZE
Definition: CC_Const.h:89
Wants go to the right.
double x() const
Returns the x-position.
Definition: Position.h:57
const double myFlatbedD
Definition: MSCFModel_CC.h:397
#define CC_PAR_FLATBED_KA
Definition: CC_Const.h:104
double leaderAngle
platoon&#39;s leader angle in radians
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:165
double myAccel
The vehicle&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:616
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
T MAX2(T a, T b)
Definition: StdDefs.h:80
MSVehicle * leaderVehicle
leader vehicle, used for auto feeding
Position leaderVelocity
platoon&#39;s leader velocity vector
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
const MSRoute & getRoute() const
Returns the current route.
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:1280
virtual void setParameter(const std::string parameter, const std::string &value)=0
double getACCAcceleration(const MSVehicle *veh) const
returns the ACC computed acceleration when the faked CACC is controlling the car. This can be used to...
#define CC_PAR_VEHICLE_MODEL
Definition: CC_Const.h:112
double leaderAcceleration
platoon&#39;s leader acceleration (used by CACC)
#define TS
Definition: SUMOTime.h:44
void set(double x, double y)
set positions x and y
Definition: Position.h:87
double uMin
limits for u
double frontAngle
front vehicle angle in radians
#define CC_PAR_CACC_XI
Definition: CC_Const.h:92
double accHeadwayTime
headway time for ACC
Wants go to the left.
The action is due to the wish to be faster (tactical lc)
MSCFModel * myHumanDriver
the car following model which drives the car when automated cruising is disabled, i...
Definition: MSCFModel_CC.h:354
const double myC1
design constant for CACC
Definition: MSCFModel_CC.h:372
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:55
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:32
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
#define CC_PAR_UMIN
Definition: CC_Const.h:97
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
The car-following model and parameter.
Definition: MSVehicleType.h:66
double _consensus(const MSVehicle *veh, double egoSpeed, Position egoPosition, double time) const
controller based on consensus strategy
double caccSpacing
fixed spacing for CACC
int getLaneIndex() const
Definition: MSVehicle.cpp:5233
static std::pair< int, int > getLaneChangeState(const std::string &vehicleID, int direction)
Definition: Vehicle.cpp:599
double _v(const MSVehicle *const veh, double gap2pred, double egoSpeed, double predSpeed) const
double getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:210
double interactionGap(const MSVehicle *const, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
#define CC_PAR_ENGINE_TAU
Definition: CC_Const.h:95
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 ...
A road/street connecting two junctions.
Definition: MSEdge.h:76
int nInitialized
count of initialized vehicles
#define PAR_FRONT_FAKE_DATA
Definition: CC_Const.h:152
const double myOmegaN
design constant for CACC
Definition: MSCFModel_CC.h:378
void recomputeParameters(const MSVehicle *veh) const
Recomputes controller related parameters after setting them.
void setSpeedMode(int speedMode)
Sets speed-constraining behaviors.
Definition: MSVehicle.cpp:758
void switchOnACC(const MSVehicle *veh, double ccDesiredSpeed) const
switch on the ACC, so disabling the human driver car control
#define CC_PAR_PLOEG_KD
Definition: CC_Const.h:102
double K[MAX_N_CARS][MAX_N_CARS]
K matrix.
#define CC_PAR_FLATBED_D
Definition: CC_Const.h:108
blocked in all directions
double frontAcceleration
current front vehicle acceleration (used by CACC)
#define PAR_FIXED_ACCELERATION
Definition: CC_Const.h:125
Position frontPosition
current front vehicle position
bool useControllerAcceleration
determines whether PATH&#39;s CACC should use the real vehicle acceleration or the controller computed on...
int nCars
number of cars in the platoon
Representation of a vehicle.
Definition: SUMOVehicle.h:61
#define PAR_RADAR_DATA
Definition: CC_Const.h:146
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...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
#define CC_PAR_VEHICLE_ENGINE_MODEL
Definition: CC_Const.h:110
void setx(double x)
set position x
Definition: Position.h:72
MSCFModel_CC(const MSVehicleType *vtype)
Constructor.
#define CC_PAR_VEHICLES_FILE
Definition: CC_Const.h:113
#define PAR_LEADER_FAKE_DATA
Definition: CC_Const.h:151
#define PAR_USE_CONTROLLER_ACCELERATION
Definition: CC_Const.h:134
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:337
Position leaderPosition
platoon&#39;s leader position
const double myLambda
design constant for ACC
Definition: MSCFModel_CC.h:369
VehicleVariables * createVehicleVariables() const
Returns model specific values which are stored inside a vehicle and must be used with casting...
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...
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
double controllerAcceleration
acceleration as computed by the controller, to be sent to other vehicles
std::map< int, std::string > members
list of members belonging to my platoon
double getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:533
double _ploeg(const MSVehicle *veh, double egoSpeed, double predSpeed, double predAcceleration, double gap2pred) const
controller for the Ploeg&#39;s CACC which computes the control input variation. Opposed to other controll...
#define STEPS2TIME(x)
Definition: SUMOTime.h:57
#define ENGINE_PAR_XMLFILE
Definition: CC_Const.h:84
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:284
double leaderSpeed
platoon&#39;s leader speed (used by CACC)
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:224
enum Plexe::ACTIVE_CONTROLLER activeController
currently active controller
int getMyLanesCount() const
returns the number of lanes set in the configuration file
#define PAR_ENGINE_DATA
Definition: CC_Const.h:167
double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const
Computes the vehicle&#39;s safe speed (no dawdling)
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...
static void changeLane(const std::string &vehicleID, int laneIndex, double duration)
Definition: Vehicle.cpp:953
double frontDataReadTime
when front vehicle data has been readed from GPS
Position frontVelocity
front vehicle velocity vector
double leaderControllerAcceleration
platoon&#39;s leader controller acceleration (used by CACC)
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter...
void setChosenSpeedFactor(const double factor)
Returns the precomputed factor by which the driver wants to be faster than the speed limit...
const double myFlatbedKp
Definition: MSCFModel_CC.h:395
double _flatbed(const MSVehicle *veh, double egoAcceleration, double egoSpeed, double predSpeed, double gap2pred, double leaderSpeed) const
flatbed platoon towing model
#define PAR_LEADER_SPEED_AND_ACCELERATION
Definition: CC_Const.h:131
void performAutoLaneChange(MSVehicle *const veh) const
void setMaximumDeceleration(double maxAcceleration_mpsps)
virtual double getRealAcceleration(double speed_mps, double accel_mps2, double reqAccel_mps2, SUMOTime timeStep=0)=0
double frontControllerAcceleration
front vehicle controller acceleration (used by CACC)
double myDecel
The vehicle&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:619
double acceleration
Definition: CC_Const.h:63
#define CC_PAR_VEHICLE_DATA
Definition: CC_Const.h:87
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
#define PAR_CACC_SPACING
Definition: CC_Const.h:116
MSVehicle * frontVehicle
front sumo id, used for auto feeding
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:385
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 myCcDecel
The maximum deceleration that the CC can output.
Definition: MSCFModel_CC.h:357
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:5817
#define ENGINE_PAR_DT
Definition: CC_Const.h:85
const double myPloegKd
Definition: MSCFModel_CC.h:390
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1819
const double myFlatbedKa
flatbed CACC parameters
Definition: MSCFModel_CC.h:393
double caccXi
controller related parameters
#define CC_PAR_FLATBED_KV
Definition: CC_Const.h:105
void setMaximumAcceleration(double maxAcceleration_mpsps)
const double myConstantSpacing
the constant gap for CACC
Definition: MSCFModel_CC.h:363
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...
#define PAR_SPEED_AND_ACCELERATION
Definition: CC_Const.h:128
int position
my position within the platoon (0 = first car)
#define PAR_REMOVE_MEMBER
Definition: CC_Const.h:177
double getAcceleration() const
Returns the vehicle&#39;s acceleration in m/s (this is computed as the last step&#39;s mean acceleration in c...
Definition: MSVehicle.h:494
void sety(double y)
set position y
Definition: Position.h:77
const double myFlatbedKv
Definition: MSCFModel_CC.h:394
static std::pair< std::string, double > getLeader(const std::string &vehicleID, double dist=0.)
Definition: Vehicle.cpp:279
double h[MAX_N_CARS]
vector of time headways h
#define FOLM_PAR_TAU
Definition: CC_Const.h:80
enum Plexe::ACTIVE_CONTROLLER getActiveController(const MSVehicle *veh) const
return the currently active controller
struct Plexe::VEHICLE_DATA vehicles[MAX_N_CARS]
data about vehicles in the platoon
double getCACCConstantSpacing(const MSVehicle *veh) const
returns CACC desired constant spacing
bool autoLaneChange
automatic whole platoon lane change
#define PAR_ENABLE_AUTO_LANE_CHANGE
Definition: CC_Const.h:180
std::string str() const
Definition: ParBuffer.h:145
const double myPloegKp
Definition: MSCFModel_CC.h:389
bool leaderInitialized
we receive at least one packet?
const double myTau
engine time constant used for actuation lag
Definition: MSCFModel_CC.h:381
int L[MAX_N_CARS][MAX_N_CARS]
L matrix.
const double myPloegH
Ploeg&#39;s CACC parameters.
Definition: MSCFModel_CC.h:388
ACTIVE_CONTROLLER
Determines the currently active controller, i.e., ACC, CACC, or the driver. In future we might need t...
Definition: CC_Const.h:45
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...
void getEngineData(double speed_mps, int &gear, double &rpm)
void resetConsensus(const MSVehicle *veh) const
Resets the consensus controller. In particular, sets the "initialized" vector all to false...
const double myCcAccel
The maximum acceleration that the CC can output.
Definition: MSCFModel_CC.h:360
#define PAR_DISTANCE_TO_END
Definition: CC_Const.h:155
#define CC_ENGINE_MODEL_FOLM
Definition: CC_Const.h:76
#define PAR_ACC_ACCELERATION
Definition: CC_Const.h:119
#define CC_PAR_VEHICLE_POSITION
Definition: CC_Const.h:88
const double myKp
design constant for CC
Definition: MSCFModel_CC.h:366
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
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:477
#define MAX_N_CARS
Definition: CC_Const.h:74
#define CC_PAR_PLOEG_H
Definition: CC_Const.h:100
Krauss car-following model, with acceleration decrease and faster start.
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const =0
Computes the vehicle&#39;s follow speed (no dawdling)
double stopSpeed(const MSVehicle *const veh, const double speed, double gap2pred) const
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
const std::string & getID() const
Returns the name of the vehicle.
virtual double getSpeed() const =0
Returns the vehicle&#39;s current speed.
#define CC_PAR_UMAX
Definition: CC_Const.h:98
#define PAR_CRASHED
Definition: CC_Const.h:122
bool autoFeed
determines whether CACC should automatically fetch data about other vehicles
#define PAR_ADD_MEMBER
Definition: CC_Const.h:176
double leaderDataReadTime
when leader data has been readed from GPS
void getRadarMeasurements(const MSVehicle *veh, double &distance, double &relativeSpeed) const
return the data that is currently being measured by the radar
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
bool usePrediction
enable/disable data prediction (interpolation) for missing data
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:277