SUMO - Simulation of Urban MObility
TraCIServerAPI_Person.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-2018 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 // APIs for getting/setting person values via TraCI
16 /****************************************************************************/
17 
18 
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23 
28 #include <microsim/MSNet.h>
29 #include <microsim/MSEdge.h>
30 #include <libsumo/Person.h>
31 #include <libsumo/VehicleType.h>
32 #include "TraCIConstants.h"
33 #include "TraCIServer.h"
35 #include "TraCIServerAPI_Person.h"
36 
37 
38 // ===========================================================================
39 // method definitions
40 // ===========================================================================
41 bool
43  tcpip::Storage& outputStorage) {
44  const int variable = inputStorage.readUnsignedByte();
45  const std::string id = inputStorage.readString();
46  server.initWrapper(RESPONSE_GET_PERSON_VARIABLE, variable, id);
47  try {
48  if (!libsumo::Person::handleVariable(id, variable, &server) &&
50  switch (variable) {
51  case VAR_EDGES: {
52  int nextStageIndex = 0;
53  if (!server.readTypeCheckingInt(inputStorage, nextStageIndex)) {
54  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The message must contain the stage index.", outputStorage);
55  }
57  server.getWrapperStorage().writeStringList(libsumo::Person::getEdges(id, nextStageIndex));
58  break;
59  }
60  case VAR_STAGE: {
61  int nextStageIndex = 0;
62  if (!server.readTypeCheckingInt(inputStorage, nextStageIndex)) {
63  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The message must contain the stage index.", outputStorage);
64  }
66  server.getWrapperStorage().writeInt(libsumo::Person::getStage(id, nextStageIndex));
67  break;
68  }
69  case VAR_PARAMETER: {
70  std::string paramName = "";
71  if (!server.readTypeCheckingString(inputStorage, paramName)) {
72  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "Retrieval of a parameter requires its name.", outputStorage);
73  }
76  break;
77  }
78  default:
79  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "Get Person Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
80  }
81  }
82  } catch (libsumo::TraCIException& e) {
83  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, e.what(), outputStorage);
84  }
85  server.writeStatusCmd(CMD_GET_PERSON_VARIABLE, RTYPE_OK, "", outputStorage);
86  server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
87  return true;
88 }
89 
90 
91 bool
93  tcpip::Storage& outputStorage) {
94  std::string warning = ""; // additional description for response
95  // variable
96  int variable = inputStorage.readUnsignedByte();
97  if (variable != VAR_PARAMETER
98  && variable != ADD
99  && variable != APPEND_STAGE
100  && variable != REMOVE_STAGE
101  && variable != CMD_REROUTE_TRAVELTIME
102  && variable != MOVE_TO_XY
103  && variable != VAR_SPEED
104  && variable != VAR_TYPE
105  && variable != VAR_LENGTH
106  && variable != VAR_WIDTH
107  && variable != VAR_HEIGHT
108  && variable != VAR_MINGAP
109  && variable != VAR_COLOR
110  ) {
111  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Change Person State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
112  }
113 
114  try {
115  // TODO: remove declaration of c after completion
117  // id
118  std::string id = inputStorage.readString();
119  // TODO: remove declaration of p after completion
120  const bool shouldExist = variable != ADD;
121  MSTransportable* p = c.get(id);
122  if (p == nullptr && shouldExist) {
123  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Person '" + id + "' is not known", outputStorage);
124  }
125  // process
126  switch (variable) {
127  case VAR_SPEED: {
128  double speed = 0;
129  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
130  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Setting speed requires a double.", outputStorage);
131  }
132  // set the speed for all (walking) stages
133  libsumo::Person::setSpeed(id, speed);
134  // modify the vType so that stages added later are also affected
135  TraCIServerAPI_VehicleType::setVariable(CMD_SET_VEHICLE_VARIABLE, variable, p->getSingularType().getID(), server, inputStorage, outputStorage);
136  }
137  break;
138  case VAR_TYPE: {
139  std::string vTypeID;
140  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
141  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);
142  }
143  libsumo::Person::setType(id, vTypeID);
144  break;
145  }
146  case VAR_COLOR: {
148  if (!server.readTypeCheckingColor(inputStorage, col)) {
149  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The color must be given using the according type.", outputStorage);
150  }
151  libsumo::Person::setColor(id, col);
152  break;
153  }
154  case ADD: {
155  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
156  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a person requires a compound object.", outputStorage);
157  }
158  if (inputStorage.readInt() != 4) {
159  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a person needs four parameters.", outputStorage);
160  }
161  std::string vTypeID;
162  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
163  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "First parameter (type) requires a string.", outputStorage);
164  }
165  std::string edgeID;
166  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
167  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Second parameter (edge) requires a string.", outputStorage);
168  }
169  double depart;
170  if (!server.readTypeCheckingDouble(inputStorage, depart)) {
171  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (depart) requires a double.", outputStorage);
172  }
173  double pos;
174  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
175  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
176  }
177  libsumo::Person::add(id, edgeID, pos, depart, vTypeID);
178  }
179  break;
180  case APPEND_STAGE: {
181  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
182  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a person stage requires a compound object.", outputStorage);
183  }
184  int numParameters = inputStorage.readInt();
185  int stageType;
186  if (!server.readTypeCheckingInt(inputStorage, stageType)) {
187  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first parameter for adding a stage must be the stage type given as int.", outputStorage);
188  }
189  if (stageType == MSTransportable::DRIVING) {
190  // append driving stage
191  if (numParameters != 4) {
192  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a driving stage needs four parameters.", outputStorage);
193  }
194  std::string edgeID;
195  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
196  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Second parameter (edge) requires a string.", outputStorage);
197  }
198  std::string lines;
199  if (!server.readTypeCheckingString(inputStorage, lines)) {
200  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (lines) requires a string.", outputStorage);
201  }
202  std::string stopID;
203  if (!server.readTypeCheckingString(inputStorage, stopID)) {
204  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);
205  }
206  libsumo::Person::appendDrivingStage(id, edgeID, lines, stopID);
207  } else if (stageType == MSTransportable::WAITING) {
208  // append waiting stage
209  if (numParameters != 4) {
210  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a waiting stage needs four parameters.", outputStorage);
211  }
212  int duration;
213  if (!server.readTypeCheckingInt(inputStorage, duration)) {
214  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Second parameter (duration) requires an int.", outputStorage);
215  }
216  std::string description;
217  if (!server.readTypeCheckingString(inputStorage, description)) {
218  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (description) requires a string.", outputStorage);
219  }
220  std::string stopID;
221  if (!server.readTypeCheckingString(inputStorage, stopID)) {
222  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);
223  }
224  libsumo::Person::appendWaitingStage(id, STEPS2TIME(duration), description, stopID);
225  } else if (stageType == MSTransportable::MOVING_WITHOUT_VEHICLE) {
226  // append walking stage
227  if (numParameters != 6) {
228  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Adding a walking stage needs six parameters.", outputStorage);
229  }
230  std::vector<std::string> edgeIDs;
231  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
232  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Second parameter (edges) route must be defined as a list of edge ids.", outputStorage);
233  }
234  double arrivalPos;
235  if (!server.readTypeCheckingDouble(inputStorage, arrivalPos)) {
236  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Third parameter (arrivalPos) requires a double.", outputStorage);
237  }
238  int duration;
239  if (!server.readTypeCheckingInt(inputStorage, duration)) {
240  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (duration) requires an int.", outputStorage);
241  }
242  double speed;
243  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
244  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
245  }
246  std::string stopID;
247  if (!server.readTypeCheckingString(inputStorage, stopID)) {
248  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Fourth parameter (stopID) requires a string.", outputStorage);
249  }
250  libsumo::Person::appendWalkingStage(id, edgeIDs, arrivalPos, STEPS2TIME(duration), speed, stopID);
251  } else {
252  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Invalid stage type for person '" + id + "'", outputStorage);
253  }
254  }
255  break;
256  case REMOVE_STAGE: {
257  int nextStageIndex = 0;
258  if (!server.readTypeCheckingInt(inputStorage, nextStageIndex)) {
259  return server.writeErrorStatusCmd(CMD_GET_PERSON_VARIABLE, "The message must contain the stage index.", outputStorage);
260  }
261  libsumo::Person::removeStage(id, nextStageIndex);
262  }
263  break;
264  case CMD_REROUTE_TRAVELTIME: {
265  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
266  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Rerouting requires a compound object.", outputStorage);
267  }
268  if (inputStorage.readInt() != 0) {
269  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
270  }
272  }
273  break;
274  case MOVE_TO_XY: {
275  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
276  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "MoveToXY person requires a compound object.", outputStorage);
277  }
278  const int numArgs = inputStorage.readInt();
279  if (numArgs != 5) {
280  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "MoveToXY person should obtain: edgeID, x, y, angle and keepRouteFlag.", outputStorage);
281  }
282  // edge ID
283  std::string edgeID;
284  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
285  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The first parameter for moveToXY must be the edge ID given as a string.", outputStorage);
286  }
287  // x
288  double x = 0;
289  if (!server.readTypeCheckingDouble(inputStorage, x)) {
290  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The second parameter for moveToXY must be the x-position given as a double.", outputStorage);
291  }
292  // y
293  double y = 0;
294  if (!server.readTypeCheckingDouble(inputStorage, y)) {
295  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The third parameter for moveToXY must be the y-position given as a double.", outputStorage);
296  }
297  // angle
298  double angle = 0;
299  if (!server.readTypeCheckingDouble(inputStorage, angle)) {
300  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The fourth parameter for moveToXY must be the angle given as a double.", outputStorage);
301  }
302  int keepRouteFlag = 1;
303  if (!server.readTypeCheckingByte(inputStorage, keepRouteFlag)) {
304  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The fifth parameter for moveToXY must be the keepRouteFlag given as a byte.", outputStorage);
305  }
306  libsumo::Person::moveToXY(id, edgeID, x, y, angle, keepRouteFlag);
307  }
308  break;
309  case VAR_PARAMETER: {
310  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
311  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
312  }
313  //read itemNo
314  inputStorage.readInt();
315  std::string name;
316  if (!server.readTypeCheckingString(inputStorage, name)) {
317  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
318  }
319  std::string value;
320  if (!server.readTypeCheckingString(inputStorage, value)) {
321  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
322  }
323  libsumo::Person::setParameter(id, name, value);
324  }
325  break;
326  default:
327  try {
328  if (!TraCIServerAPI_VehicleType::setVariable(CMD_SET_PERSON_VARIABLE, variable, p->getSingularType().getID(), server, inputStorage, outputStorage)) {
329  return false;
330  }
331  } catch (ProcessError& e) {
332  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, e.what(), outputStorage);
333  }
334  break;
335  }
336  } catch (libsumo::TraCIException& e) {
337  return server.writeErrorStatusCmd(CMD_SET_PERSON_VARIABLE, e.what(), outputStorage);
338  }
339  server.writeStatusCmd(CMD_SET_PERSON_VARIABLE, RTYPE_OK, warning, outputStorage);
340  return true;
341 }
342 
343 
344 /****************************************************************************/
static void rerouteTraveltime(const std::string &personID)
Definition: Person.cpp:472
bool readTypeCheckingColor(tcpip::Storage &inputStorage, libsumo::TraCIColor &into)
Reads the value type and a color, verifying the type.
#define VAR_LENGTH
static std::vector< std::string > getEdges(const std::string &personID, int nextStageIndex=0)
Definition: Person.cpp:135
#define TYPE_COMPOUND
static void appendWalkingStage(const std::string &personID, const std::vector< std::string > &edgeIDs, double arrivalPos, double duration=-1, double speed=-1, const std::string &stopID="")
Definition: Person.cpp:427
static std::string getParameter(const std::string &routeID, const std::string &param)
Definition: Person.cpp:182
static void setType(const std::string &personID, const std::string &typeID)
Definition: Person.cpp:313
#define RTYPE_OK
#define VAR_HEIGHT
#define CMD_GET_PERSON_VARIABLE
#define VAR_TYPE
#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:165
#define APPEND_STAGE
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
static int getStage(const std::string &personID, int nextStageIndex=0)
Definition: Person.cpp:152
#define VAR_STAGE
virtual void writeUnsignedByte(int)
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
#define REMOVE_STAGE
virtual void writeInt(int)
static void setSpeed(const std::string &personID, double speed)
Definition: Person.cpp:307
#define TYPE_STRING
virtual int readUnsignedByte()
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
#define MOVE_TO_XY
static LIBSUMO_VEHICLE_TYPE_GETTER void add(const std::string &personID, const std::string &edgeID, double pos, double depart=DEPARTFLAG_NOW, const std::string typeID="DEFAULT_PEDTYPE")
Definition: Person.cpp:323
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xce: Change Person State)
virtual int readInt()
static std::string getTypeID(const std::string &personID)
Definition: Person.cpp:117
static void appendDrivingStage(const std::string &personID, const std::string &toEdge, const std::string &lines, const std::string &stopID="")
Definition: Person.cpp:389
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:776
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)
#define STEPS2TIME(x)
Definition: SUMOTime.h:58
#define CMD_SET_VEHICLE_VARIABLE
tcpip::Storage & getWrapperStorage()
virtual std::string readString()
#define VAR_EDGES
#define ADD
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:62
static void removeStage(const std::string &personID, int nextStageIndex)
Definition: Person.cpp:459
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xae: Get Person Variable)
#define VAR_SPEED
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
static void setParameter(const std::string &personID, const std::string &key, const std::string &value)
Definition: Person.cpp:666
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)
static bool handleVariable(const std::string &objID, const int variable, VariableWrapper *wrapper)
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:59
#define CMD_REROUTE_TRAVELTIME
#define RESPONSE_GET_PERSON_VARIABLE
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:94
static void appendWaitingStage(const std::string &personID, double duration, const std::string &description="waiting", const std::string &stopID="")
Definition: Person.cpp:410
static bool handleVariable(const std::string &objID, const int variable, VariableWrapper *wrapper)
Definition: Person.cpp:820
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
static void moveToXY(const std::string &personID, const std::string &edgeID, const double x, const double y, double angle, const int keepRouteFlag)
Definition: Person.cpp:549
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
void initWrapper(const int domainID, const int variable, const std::string &objID)
#define CMD_SET_PERSON_VARIABLE
#define VAR_PARAMETER
#define TYPE_INTEGER
#define VAR_MINGAP
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
#define VAR_WIDTH