SUMO - Simulation of Urban MObility
TraCIServerAPI_Person.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // APIs for getting/setting person values via TraCI
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #ifndef NO_TRACI
32 
37 #include <microsim/MSNet.h>
38 #include <microsim/MSEdge.h>
39 #include "TraCIConstants.h"
40 #include "TraCIServer.h"
41 #include "TraCIServerAPI_Person.h"
43 
44 
45 // ===========================================================================
46 // method definitions
47 // ===========================================================================
48 bool
50  tcpip::Storage& outputStorage) {
51  // variable
52  int variable = inputStorage.readUnsignedByte();
53  std::string id = inputStorage.readString();
54  // check variable
55  if (variable != ID_LIST && variable != ID_COUNT
56  && variable != VAR_POSITION && variable != VAR_POSITION3D && variable != VAR_ANGLE && variable != VAR_SPEED
57  && variable != VAR_ROAD_ID && variable != VAR_LANEPOSITION
58  && variable != VAR_WIDTH && variable != VAR_LENGTH && variable != VAR_MINGAP
59  && variable != VAR_TYPE && variable != VAR_SHAPECLASS && variable != VAR_COLOR
60  && variable != VAR_WAITING_TIME && variable != VAR_PARAMETER
61  && variable != VAR_NEXT_EDGE
62  && variable != VAR_EDGES
63  && variable != VAR_STAGE
64  && variable != VAR_STAGES_REMAINING
65  && variable != VAR_VEHICLE
66  ) {
67  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "Get Person Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
68  }
69  // begin response building
70  tcpip::Storage tempMsg;
71  // response-code, variableID, objectID
73  tempMsg.writeUnsignedByte(variable);
74  tempMsg.writeString(id);
76  if (variable == ID_LIST || variable == ID_COUNT) {
77  if (variable == ID_LIST) {
78  std::vector<std::string> ids;
79  for (MSTransportableControl::constVehIt i = c.loadedBegin(); i != c.loadedEnd(); ++i) {
80  if (i->second->getCurrentStageType() != MSTransportable::WAITING_FOR_DEPART) {
81  ids.push_back(i->first);
82  }
83  }
85  tempMsg.writeStringList(ids);
86  } else {
88  tempMsg.writeInt((int) c.size());
89  }
90  } else {
91  MSTransportable* p = c.get(id);
92  if (p == 0) {
93  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "Person '" + id + "' is not known", outputStorage);
94  }
95  switch (variable) {
96  case VAR_POSITION: {
98  tempMsg.writeDouble(p->getPosition().x());
99  tempMsg.writeDouble(p->getPosition().y());
100  }
101  break;
102  case VAR_POSITION3D:
104  tempMsg.writeDouble(p->getPosition().x());
105  tempMsg.writeDouble(p->getPosition().y());
106  tempMsg.writeDouble(p->getPosition().z());
107  break;
108  case VAR_ANGLE:
111  break;
112  case VAR_SPEED:
114  tempMsg.writeDouble(p->getSpeed());
115  break;
116  case VAR_ROAD_ID:
118  tempMsg.writeString(p->getEdge()->getID());
119  break;
120  case VAR_LANEPOSITION:
122  tempMsg.writeDouble(p->getEdgePos());
123  break;
124  case VAR_COLOR:
125  tempMsg.writeUnsignedByte(TYPE_COLOR);
126  tempMsg.writeUnsignedByte(p->getParameter().color.red());
127  tempMsg.writeUnsignedByte(p->getParameter().color.green());
128  tempMsg.writeUnsignedByte(p->getParameter().color.blue());
129  tempMsg.writeUnsignedByte(p->getParameter().color.alpha());
130  break;
131  case VAR_WAITING_TIME:
133  tempMsg.writeDouble(p->getWaitingSeconds());
134  break;
135  case VAR_TYPE:
137  tempMsg.writeString(p->getVehicleType().getID());
138  break;
139  case VAR_NEXT_EDGE:
141  tempMsg.writeString(dynamic_cast<MSPerson*>(p)->getNextEdge());
142  break;
143  case VAR_EDGES: {
144  int nextStageIndex = 0;
145  if (!server.readTypeCheckingInt(inputStorage, nextStageIndex)) {
146  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The message must contain the stage index.", outputStorage);
147  }
148  if (nextStageIndex >= p->getNumRemainingStages()) {
149  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The stage index must be lower than the number of remaining stages.", outputStorage);
150  }
151  if (nextStageIndex < (p->getNumRemainingStages() - p->getNumStages())) {
152  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The negative stage index must refer to a valid previous stage.", outputStorage);
153  }
154  ConstMSEdgeVector edges = p->getEdges(nextStageIndex);
156  tempMsg.writeInt((int)edges.size());
157  for (ConstMSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
158  tempMsg.writeString((*i)->getID());
159  }
160  break;
161  }
162  case VAR_STAGE: {
163  int nextStageIndex = 0;
164  if (!server.readTypeCheckingInt(inputStorage, nextStageIndex)) {
165  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The message must contain the stage index.", outputStorage);
166  }
167  if (nextStageIndex >= p->getNumRemainingStages()) {
168  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The stage index must be lower than the number of remaining stages.", outputStorage);
169  }
170  if (nextStageIndex < (p->getNumRemainingStages() - p->getNumStages())) {
171  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The negative stage index must refer to a valid previous stage.", outputStorage);
172  }
174  tempMsg.writeInt(p->getStageType(nextStageIndex));
175  break;
176  }
179  tempMsg.writeInt(p->getNumRemainingStages());
180  break;
181  case VAR_VEHICLE: {
182  const SUMOVehicle* veh = p->getVehicle();
184  tempMsg.writeString(veh == 0 ? "" : veh->getID());
185  break;
186  }
187  case VAR_PARAMETER: {
188  std::string paramName = "";
189  if (!server.readTypeCheckingString(inputStorage, paramName)) {
190  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "Retrieval of a parameter requires its name.", outputStorage);
191  }
193  tempMsg.writeString(p->getParameter().getParameter(paramName, ""));
194  }
195  default:
197  break;
198  }
199  }
200  server.writeStatusCmd(CMD_GET_PERSON_VARIABLE, RTYPE_OK, "", outputStorage);
201  server.writeResponseWithLength(outputStorage, tempMsg);
202  return true;
203 }
204 
205 
206 bool
208  tcpip::Storage& outputStorage) {
209  std::string warning = ""; // additional description for response
210  // variable
211  int variable = inputStorage.readUnsignedByte();
212  if (variable != VAR_PARAMETER
213  && variable != ADD
214  && variable != APPEND_STAGE
215  && variable != REMOVE_STAGE
216  && variable != CMD_REROUTE_TRAVELTIME
217  && variable != VAR_SPEED
218  && variable != VAR_TYPE
219  && variable != VAR_LENGTH
220  && variable != VAR_WIDTH
221  && variable != VAR_HEIGHT
222  && variable != VAR_MINGAP
223  && variable != VAR_COLOR
224  ) {
225  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Change Person State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
226  }
227  // id
229  std::string id = inputStorage.readString();
230  const bool shouldExist = variable != ADD;
231  MSTransportable* p = c.get(id);
232  if (p == 0 && shouldExist) {
233  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Person '" + id + "' is not known", outputStorage);
234  }
235  // process
236  switch (variable) {
237  case VAR_SPEED: {
238  double speed = 0;
239  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
240  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Setting speed requires a double.", outputStorage);
241  }
242  // set the speed for all (walking) stages
243  p->setSpeed(speed);
244  // modify the vType so that stages added later are also affected
245  TraCIServerAPI_VehicleType::setVariable(CMD_SET_VEHICLE_VARIABLE, variable, p->getSingularType().getID(), server, inputStorage, outputStorage);
246  }
247  break;
248  case VAR_TYPE: {
249  std::string vTypeID;
250  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
251  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);
252  }
253  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
254  if (vehicleType == 0) {
255  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle type '" + vTypeID + "' is not known.", outputStorage);
256  }
257  p->replaceVehicleType(vehicleType);
258  break;
259  }
260  case ADD: {
261  if (p != 0) {
262  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The person " + id + " to add already exists.", outputStorage);
263  }
264  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
265  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a person requires a compound object.", outputStorage);
266  }
267  if (inputStorage.readInt() != 4) {
268  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a person needs four parameters.", outputStorage);
269  }
270  SUMOVehicleParameter vehicleParams;
271  vehicleParams.id = id;
272 
273  std::string vTypeID;
274  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
275  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "First parameter (type) requires a string.", outputStorage);
276  }
277  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
278  if (!vehicleType) {
279  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid type '" + vTypeID + "' for person '" + id + "'", outputStorage);
280  }
281 
282  std::string edgeID;
283  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
284  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Second parameter (edge) requires a string.", outputStorage);
285  }
286  const MSEdge* edge = MSEdge::dictionary(edgeID);
287  if (!edge) {
288  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid edge '" + edgeID + "' for person: '" + id + "'", outputStorage);
289  }
290  int depart;
291  if (!server.readTypeCheckingInt(inputStorage, depart)) {
292  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (depart) requires an integer.", outputStorage);
293  }
294  if (depart < 0) {
295  const int proc = -depart;
296  if (proc >= static_cast<int>(DEPART_DEF_MAX)) {
297  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid departure time.", outputStorage);
298  }
299  vehicleParams.departProcedure = (DepartDefinition)proc;
300  vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
301  } else if (depart < MSNet::getInstance()->getCurrentTimeStep()) {
302  vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
303  WRITE_WARNING("Departure time for person '" + id + "' is in the past; using current time instead.");
304  } else {
305  vehicleParams.depart = depart;
306  }
307 
308  double pos;
309  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
310  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
311  }
312  vehicleParams.departPosProcedure = DEPART_POS_GIVEN;
313  if (fabs(pos) > edge->getLength()) {
314  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid departure position.", outputStorage);
315  }
316  if (pos < 0) {
317  pos += edge->getLength();
318  }
319  vehicleParams.departPos = pos;
320 
321  SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
323  plan->push_back(new MSTransportable::Stage_Waiting(*edge, 0, depart, pos, "awaiting departure", true));
324 
325  try {
326  MSTransportable* person = MSNet::getInstance()->getPersonControl().buildPerson(params, vehicleType, plan);
328  } catch (ProcessError& e) {
329  delete params;
330  delete plan;
331  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, e.what(), outputStorage);
332  }
333  }
334  break;
335  case APPEND_STAGE: {
336  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
337  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a person stage requires a compound object.", outputStorage);
338  }
339  int numParameters = inputStorage.readInt();
340  int stageType;
341  if (!server.readTypeCheckingInt(inputStorage, stageType)) {
342  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first parameter for adding a stage must be the stage type given as int.", outputStorage);
343  }
344  // append driving stage
345  if (stageType == MSTransportable::DRIVING) {
346  if (numParameters != 4) {
347  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a driving stage needs four parameters.", outputStorage);
348  }
349  std::string edgeID;
350  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
351  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Second parameter (edge) requires a string.", outputStorage);
352  }
353  const MSEdge* edge = MSEdge::dictionary(edgeID);
354  if (!edge) {
355  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid edge '" + edgeID + "' for person: '" + id + "'", outputStorage);
356  }
357  std::string lines;
358  if (!server.readTypeCheckingString(inputStorage, lines)) {
359  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (lines) requires a string.", outputStorage);
360  }
361  if (lines.size() == 0) {
362  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Empty lines parameter for person: '" + id + "'", outputStorage);
363  }
364  std::string stopID;
365  MSStoppingPlace* bs = 0;
366  if (!server.readTypeCheckingString(inputStorage, stopID)) {
367  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);
368  }
369  if (stopID != "") {
370  bs = MSNet::getInstance()->getBusStop(stopID);
371  if (bs == 0) {
372  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid stopping place id '" + stopID + "' for person: '" + id + "'", outputStorage);
373  }
374  }
375  p->appendStage(new MSPerson::MSPersonStage_Driving(*edge, bs, -NUMERICAL_EPS, StringTokenizer(lines).getVector()));
376 
377  // append waiting stage
378  } else if (stageType == MSTransportable::WAITING) {
379  if (numParameters != 4) {
380  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a waiting stage needs four parameters.", outputStorage);
381  }
382  int duration;
383  if (!server.readTypeCheckingInt(inputStorage, duration)) {
384  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Second parameter (duration) requires an int.", outputStorage);
385  }
386  if (duration < 0) {
387  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Duration for person: '" + id + "' must not be negative", outputStorage);
388  }
389  std::string description;
390  if (!server.readTypeCheckingString(inputStorage, description)) {
391  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (description) requires a string.", outputStorage);
392  }
393  std::string stopID;
394  MSStoppingPlace* bs = 0;
395  if (!server.readTypeCheckingString(inputStorage, stopID)) {
396  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);
397  }
398  if (stopID != "") {
399  bs = MSNet::getInstance()->getBusStop(stopID);
400  if (bs == 0) {
401  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid stopping place id '" + stopID + "' for person: '" + id + "'", outputStorage);
402  }
403  }
404  p->appendStage(new MSTransportable::Stage_Waiting(*p->getArrivalEdge(), duration, 0, p->getArrivalPos(), description, false));
405 
406  // append walking stage
407  } else if (stageType == MSTransportable::MOVING_WITHOUT_VEHICLE) {
408  if (numParameters != 6) {
409  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a walking stage needs six parameters.", outputStorage);
410  }
411  std::vector<std::string> edgeIDs;
412  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
413  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Second parameter (edges) route must be defined as a list of edge ids.", outputStorage);
414  }
415  ConstMSEdgeVector edges;
416  try {
417  MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
418  } catch (ProcessError& e) {
419  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, e.what(), outputStorage);
420  }
421  if (edges.empty()) {
422  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Empty edge list for walking stage of person '" + id + "'.", outputStorage);
423  }
424  double arrivalPos;
425  if (!server.readTypeCheckingDouble(inputStorage, arrivalPos)) {
426  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (arrivalPos) requires a double.", outputStorage);
427  }
428  if (fabs(arrivalPos) > edges.back()->getLength()) {
429  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid arrivalPos for walking stage of person '" + id + "'.", outputStorage);
430  }
431  if (arrivalPos < 0) {
432  arrivalPos += edges.back()->getLength();
433  }
434  int duration;
435  if (!server.readTypeCheckingInt(inputStorage, duration)) {
436  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (duration) requires an int.", outputStorage);
437  }
438  double speed;
439  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
440  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
441  }
442  if (speed < 0) {
443  speed = p->getVehicleType().getMaxSpeed();
444  }
445  std::string stopID;
446  MSStoppingPlace* bs = 0;
447  if (!server.readTypeCheckingString(inputStorage, stopID)) {
448  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);
449  }
450  if (stopID != "") {
451  bs = MSNet::getInstance()->getBusStop(stopID);
452  if (bs == 0) {
453  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid stopping place id '" + stopID + "' for person: '" + id + "'", outputStorage);
454  }
455  }
456  p->appendStage(new MSPerson::MSPersonStage_Walking(edges, bs, duration, speed, p->getArrivalPos(), arrivalPos, 0));
457 
458 
459  } else {
460  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid stage type for person '" + id + "'", outputStorage);
461  }
462  }
463  break;
464  case REMOVE_STAGE: {
465  int nextStageIndex = 0;
466  if (!server.readTypeCheckingInt(inputStorage, nextStageIndex)) {
467  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The message must contain the stage index.", outputStorage);
468  }
469  if (nextStageIndex >= p->getNumRemainingStages()) {
470  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The stage index must be lower than the number of remaining stages.", outputStorage);
471  }
472  if (nextStageIndex < 0) {
473  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The stage index may not be negative.", outputStorage);
474  }
475  p->removeStage(nextStageIndex);
476  }
477  break;
478  case CMD_REROUTE_TRAVELTIME: {
479  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
480  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Rerouting requires a compound object.", outputStorage);
481  }
482  if (inputStorage.readInt() != 0) {
483  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
484  }
486  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Person '" + id + "' is not currenlty walking.", outputStorage);
487  }
488 
489  const MSEdge* from = p->getEdge();
490  double departPos = p->getEdgePos();
491  const MSEdge* to = p->getArrivalEdge();
492  double arrivalPos = p->getArrivalPos();
493  double speed = p->getVehicleType().getMaxSpeed();
494  ConstMSEdgeVector newEdges;
495  MSNet::getInstance()->getPedestrianRouter().compute(from, to, departPos, arrivalPos, speed, 0, 0, newEdges);
496  if (newEdges.empty()) {
497  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Could not find new route for person '" + id + "'.", outputStorage);
498  }
499  ConstMSEdgeVector oldEdges = p->getEdges(0);
500  assert(!oldEdges.empty());
501  if (oldEdges.front()->getFunction() != EDGEFUNC_NORMAL) {
502  oldEdges.erase(oldEdges.begin());
503  }
504  if (newEdges == oldEdges) {
505  break;
506  }
507  if (newEdges.front() != from) {
508  // @note: maybe this should be done automatically by the router
509  newEdges.insert(newEdges.begin(), from);
510  }
511  //std::cout << " from=" << from->getID() << " to=" << to->getID() << " newEdges=" << toString(newEdges) << "\n";
512  MSPerson::MSPersonStage_Walking* newStage = new MSPerson::MSPersonStage_Walking(newEdges, 0, -1, speed, departPos, arrivalPos, 0);
513  if (p->getNumRemainingStages() == 1) {
514  // Do not remove the last stage (a waiting stage would be added otherwise)
515  p->appendStage(newStage);
516  //std::cout << "case a: remaining=" << p->getNumRemainingStages() << "\n";
517  p->removeStage(0);
518  } else {
519  p->removeStage(0);
520  p->appendStage(newStage);
521  //std::cout << "case b: remaining=" << p->getNumRemainingStages() << "\n";
522  }
523  }
524  break;
525  case VAR_PARAMETER: {
526  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
527  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
528  }
529  //readt itemNo
530  inputStorage.readInt();
531  std::string name;
532  if (!server.readTypeCheckingString(inputStorage, name)) {
533  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
534  }
535  std::string value;
536  if (!server.readTypeCheckingString(inputStorage, value)) {
537  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
538  }
539  ((SUMOVehicleParameter&) p->getParameter()).addParameter(name, value);
540  }
541  break;
542  default:
543  try {
544  if (!TraCIServerAPI_VehicleType::setVariable(CMD_SET_PERSON_VARIABLE, variable, p->getSingularType().getID(), server, inputStorage, outputStorage)) {
545  return false;
546  }
547  } catch (ProcessError& e) {
548  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, e.what(), outputStorage);
549  }
550  break;
551  }
552  server.writeStatusCmd(CMD_SET_PERSON_VARIABLE, RTYPE_OK, warning, outputStorage);
553  return true;
554 }
555 
556 
557 bool
558 TraCIServerAPI_Person::getPosition(const std::string& id, Position& p) {
559  MSPerson* person = dynamic_cast<MSPerson*>(MSNet::getInstance()->getPersonControl().get(id));
560  if (person == 0) {
561  return false;
562  }
563  p = person->getPosition();
564  return true;
565 }
566 
567 
568 #endif
569 
570 
571 /****************************************************************************/
572 
#define VAR_ROAD_ID
double getLength() const
return the length of the edge
Definition: MSEdge.h:570
double z() const
Returns the z-position.
Definition: Position.h:73
RGBColor color
The vehicle&#39;s color, TraCI may change this.
virtual double getAngle() const
return the current angle of the transportable
virtual double getEdgePos() const
Return the position on the edge.
#define VAR_LENGTH
std::map< std::string, MSTransportable * >::const_iterator constVehIt
Definition of the internal transportables map iterator.
#define TYPE_COMPOUND
#define POSITION_2D
A lane area vehicles can halt at.
#define VAR_POSITION
virtual double getWaitingSeconds() const
the time this transportable spent waiting in seconds
void setSpeed(double speed)
sets the walking speed (ignored in other stages)
const SUMOVehicleParameter & getParameter() const
double x() const
Returns the x-position.
Definition: Position.h:63
The position is given.
#define RTYPE_OK
#define VAR_HEIGHT
#define VAR_WAITING_TIME
#define CMD_GET_PERSON_VARIABLE
SUMOVehicle * getVehicle() const
The vehicle associated with this transportable.
#define VAR_TYPE
#define VAR_VEHICLE
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
MSPedestrianRouterDijkstra & getPedestrianRouter(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:993
#define VAR_COLOR
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:169
double getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
#define APPEND_STAGE
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_COLOR
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
virtual MSTransportable * buildPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan) const
Builds a new person.
#define POSITION_3D
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:745
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
#define VAR_STAGE
virtual void writeUnsignedByte(int)
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:252
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
Tag for the last element in the enum for safe int casting.
static bool getVariable(const int variable, const std::string &v, tcpip::Storage &tempMsg)
Processes a value request for the given type.
#define VAR_NEXT_EDGE
#define REMOVE_STAGE
virtual void writeInt(int)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
#define VAR_POSITION3D
The car-following model and parameter.
Definition: MSVehicleType.h:73
#define TYPE_STRING
virtual int readUnsignedByte()
virtual double getSpeed() const
the current speed of the transportable
static bool getPosition(const std::string &id, Position &p)
Returns the named persons&#39;s position.
int size() const
Returns the number of known transportables.
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:83
void removeStage(int next)
removes the nth next stage
#define VAR_ANGLE
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:81
std::vector< MSTransportable::Stage * > MSTransportablePlan
the structure holding the plan of a transportable
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:187
const MSVehicleType & getVehicleType() const
#define VAR_SHAPECLASS
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:864
const MSEdge * getEdge() const
Returns the current edge.
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xce: Change Person State)
Representation of a vehicle.
Definition: SUMOVehicle.h:67
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
virtual int readInt()
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:767
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
#define VAR_LANEPOSITION
StageType getCurrentStageType() const
the current stage type of the transportable
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:305
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:90
double y() const
Returns the y-position.
Definition: Position.h:68
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
virtual void writeStringList(const std::vector< std::string > &s)
SUMOTime depart
The vehicle&#39;s departure time.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
#define CMD_SET_VEHICLE_VARIABLE
virtual std::string readString()
#define VAR_EDGES
#define ADD
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:74
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xae: Get Person Variable)
bool compute(const E *from, const E *to, double departPos, double arrivalPos, double speed, SUMOTime msTime, const N *onlyNode, std::vector< const E * > &into, bool allEdges=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
#define VAR_SPEED
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, std::mt19937 *rng=0)
Returns the named vehicle type or a sample from the named distribution.
constVehIt loadedEnd() const
Returns the end of the internal transportables map.
void appendStage(Stage *stage, int next=-1)
Appends the given stage to the current plan.
double departPos
(optional) The position the vehicle shall depart from
static bool setVariable(const int cmd, const int variable, const std::string &id, TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value for the given type.
virtual void writeString(const std::string &s)
Structure representing possible vehicle parameter.
#define TYPE_DOUBLE
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:66
#define CMD_REROUTE_TRAVELTIME
StageType getStageType(int next) const
the stage type for the nth next stage
bool add(MSTransportable *transportable)
Adds a single transportable, returns false if an id clash occured.
#define RESPONSE_GET_PERSON_VARIABLE
ConstMSEdgeVector getEdges(int next) const
Return the edges of the nth next stage.
const std::string & getID() const
Returns the name of the vehicle type.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
virtual Position getPosition() const
Return the Network coordinate of the transportable.
virtual void writeDouble(double)
double getArrivalPos() const
returns the final arrival pos
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:76
int getNumStages() const
Return the total number stages in this persons plan.
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
constVehIt loadedBegin() const
Returns the begin of the internal transportables map.
#define NUMERICAL_EPS
Definition: config.h:152
#define CMD_SET_PERSON_VARIABLE
#define VAR_PARAMETER
#define ID_COUNT
#define TYPE_INTEGER
#define VAR_MINGAP
#define ID_LIST
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:69
#define VAR_STAGES_REMAINING
const MSEdge * getArrivalEdge() const
returns the final arrival edge
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:802
DepartDefinition
Possible ways to depart.
std::string id
The vehicle&#39;s id.
#define VAR_WIDTH