Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/traci-server/TraCIServerAPI_Vehicle.cpp
193870 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2009-2026 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file TraCIServerAPI_Vehicle.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Laura Bieker
17
/// @author Christoph Sommer
18
/// @author Michael Behrisch
19
/// @author Bjoern Hendriks
20
/// @author Mario Krumnow
21
/// @author Jakob Erdmann
22
/// @author Leonhard Luecken
23
/// @author Robert Hilbrich
24
/// @author Lara Codeca
25
/// @author Mirko Barthauer
26
/// @date 07.05.2009
27
///
28
// APIs for getting/setting vehicle values via TraCI
29
/****************************************************************************/
30
#include <config.h>
31
32
#include <microsim/MSNet.h>
33
#include <microsim/MSInsertionControl.h>
34
#include <microsim/MSVehicle.h>
35
#include <microsim/MSVehicleControl.h>
36
#include <microsim/MSLane.h>
37
#include <microsim/MSEdge.h>
38
#include <microsim/MSGlobals.h>
39
#include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
40
#include <utils/geom/PositionVector.h>
41
#include <utils/router/DijkstraRouter.h>
42
#include <utils/router/DijkstraRouter.h>
43
#include <utils/emissions/PollutantsInterface.h>
44
#include <utils/emissions/HelpersHarmonoise.h>
45
#include <utils/vehicle/SUMOVehicleParameter.h>
46
#include <libsumo/StorageHelper.h>
47
#include <libsumo/TraCIConstants.h>
48
#include <libsumo/Vehicle.h>
49
#include <libsumo/VehicleType.h>
50
#include "TraCIServerAPI_Simulation.h"
51
#include "TraCIServerAPI_Vehicle.h"
52
#include "TraCIServerAPI_VehicleType.h"
53
54
55
// ===========================================================================
56
// method definitions
57
// ===========================================================================
58
bool
59
TraCIServerAPI_Vehicle::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
60
tcpip::Storage& outputStorage) {
61
std::string warning = ""; // additional description for response
62
// variable
63
int variable = inputStorage.readUnsignedByte();
64
if (variable != libsumo::CMD_STOP && variable != libsumo::CMD_CHANGELANE
65
&& variable != libsumo::CMD_REROUTE_TO_PARKING
66
&& variable != libsumo::CMD_CHANGESUBLANE && variable != libsumo::CMD_OPENGAP
67
&& variable != libsumo::CMD_REPLACE_STOP
68
&& variable != libsumo::CMD_INSERT_STOP
69
&& variable != libsumo::VAR_STOP_PARAMETER
70
&& variable != libsumo::CMD_SLOWDOWN && variable != libsumo::CMD_CHANGETARGET && variable != libsumo::CMD_RESUME
71
&& variable != libsumo::VAR_TYPE && variable != libsumo::VAR_ROUTE_ID && variable != libsumo::VAR_ROUTE
72
&& variable != libsumo::VAR_LANEPOSITION_LAT
73
&& variable != libsumo::VAR_UPDATE_BESTLANES
74
&& variable != libsumo::VAR_EDGE_TRAVELTIME && variable != libsumo::VAR_EDGE_EFFORT
75
&& variable != libsumo::CMD_REROUTE_TRAVELTIME && variable != libsumo::CMD_REROUTE_EFFORT
76
&& variable != libsumo::VAR_SIGNALS && variable != libsumo::VAR_MOVE_TO
77
&& variable != libsumo::VAR_LENGTH && variable != libsumo::VAR_MAXSPEED && variable != libsumo::VAR_VEHICLECLASS
78
&& variable != libsumo::VAR_SPEED_FACTOR && variable != libsumo::VAR_EMISSIONCLASS
79
&& variable != libsumo::VAR_WIDTH && variable != libsumo::VAR_MINGAP && variable != libsumo::VAR_SHAPECLASS
80
&& variable != libsumo::VAR_ACCEL && variable != libsumo::VAR_DECEL && variable != libsumo::VAR_IMPERFECTION
81
&& variable != libsumo::VAR_APPARENT_DECEL && variable != libsumo::VAR_EMERGENCY_DECEL
82
&& variable != libsumo::VAR_ACTIONSTEPLENGTH
83
&& variable != libsumo::VAR_TAU && variable != libsumo::VAR_LANECHANGE_MODE
84
&& variable != libsumo::VAR_SPEED && variable != libsumo::VAR_ACCELERATION && variable != libsumo::VAR_PREV_SPEED && variable != libsumo::VAR_SPEEDSETMODE && variable != libsumo::VAR_COLOR
85
&& variable != libsumo::ADD && variable != libsumo::ADD_FULL && variable != libsumo::REMOVE
86
&& variable != libsumo::VAR_HEIGHT
87
&& variable != libsumo::VAR_MASS
88
&& variable != libsumo::VAR_ROUTING_MODE
89
&& variable != libsumo::VAR_LATALIGNMENT
90
&& variable != libsumo::VAR_MAXSPEED_LAT
91
&& variable != libsumo::VAR_MINGAP_LAT
92
&& variable != libsumo::VAR_LINE
93
&& variable != libsumo::VAR_VIA
94
&& variable != libsumo::VAR_IMPATIENCE
95
&& variable != libsumo::VAR_BOARDING_DURATION
96
&& variable != libsumo::VAR_HIGHLIGHT
97
&& variable != libsumo::CMD_TAXI_DISPATCH
98
&& variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/
99
) {
100
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
101
}
102
// id
103
std::string id = inputStorage.readString();
104
#ifdef DEBUG_MOVEXY
105
std::cout << SIMTIME << " processSet veh=" << id << "\n";
106
#endif
107
const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;
108
SUMOVehicle* sumoVehicle = MSNet::getInstance()->getVehicleControl().getVehicle(id);
109
if (sumoVehicle == nullptr) {
110
if (shouldExist) {
111
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
112
}
113
}
114
MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
115
if (v == nullptr && shouldExist) {
116
return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);
117
}
118
try {
119
switch (variable) {
120
case libsumo::CMD_STOP: {
121
const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Stop needs a compound object description.");
122
if (compoundSize < 4 || compoundSize > 7) {
123
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);
124
}
125
// read road map position
126
const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop parameter must be the edge id given as a string.");
127
const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop parameter must be the end position along the edge given as a double.");
128
const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop parameter must be the lane index given as a byte.");
129
const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop parameter must be the stopping duration given as a double.");
130
int stopFlags = 0;
131
if (compoundSize >= 5) {
132
stopFlags = StoHelp::readTypedByte(inputStorage, "The fifth stop parameter must be a byte indicating its parking/triggered status.");
133
}
134
double startPos = libsumo::INVALID_DOUBLE_VALUE;
135
if (compoundSize >= 6) {
136
startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop parameter must be the start position along the edge given as a double.");
137
}
138
double until = libsumo::INVALID_DOUBLE_VALUE;
139
if (compoundSize >= 7) {
140
until = StoHelp::readTypedDouble(inputStorage, "The seventh stop parameter must be the minimum departure time given as a double.");
141
}
142
libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);
143
}
144
break;
145
case libsumo::CMD_REPLACE_STOP:
146
if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {
147
return false;
148
}
149
break;
150
case libsumo::CMD_INSERT_STOP:
151
if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {
152
return false;
153
}
154
break;
155
case libsumo::VAR_STOP_PARAMETER: {
156
const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Setting stop parameter needs a compound object description.");
157
if (compoundSize != 3 && compoundSize != 4) {
158
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting a stop parameter needs a compound object description of 3 or 4 items.", outputStorage);
159
}
160
const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The first setStopParameter parameter must be the nextStopIndex given as an integer.");
161
const std::string param = StoHelp::readTypedString(inputStorage, "The second setStopParameter parameter must be the param given as a string.");
162
const std::string value = StoHelp::readTypedString(inputStorage, "The third setStopParameter parameter must be the value given as a string.");
163
int customParam = 0;
164
if (compoundSize == 4) {
165
customParam = StoHelp::readTypedByte(inputStorage, "The fourth setStopParameter parameter must be the customParam flag given as a byte.");
166
}
167
libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);
168
}
169
break;
170
case libsumo::CMD_REROUTE_TO_PARKING: {
171
StoHelp::readCompound(inputStorage, 1, "Reroute to stop needs a compound object description of 1 item.");
172
libsumo::Vehicle::rerouteParkingArea(id, StoHelp::readTypedString(inputStorage, "The first reroute to stop parameter must be the parking area id given as a string."));
173
}
174
break;
175
case libsumo::CMD_RESUME: {
176
StoHelp::readCompound(inputStorage, 0, "Resuming requires an empty compound object.");
177
libsumo::Vehicle::resume(id);
178
}
179
break;
180
case libsumo::CMD_CHANGELANE: {
181
const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Lane change needs a compound object description.");
182
if (compoundSize != 3 && compoundSize != 2) {
183
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);
184
}
185
const int laneIndex = StoHelp::readTypedByte(inputStorage, "The first lane change parameter must be the lane index given as a byte.");
186
const double duration = StoHelp::readTypedDouble(inputStorage, "The second lane change parameter must be the duration given as a double.");
187
// relative lane change
188
int relative = 0;
189
if (compoundSize == 3) {
190
relative = StoHelp::readTypedByte(inputStorage, "The third lane change parameter must be a Byte for defining whether a relative lane change should be applied.");
191
}
192
193
if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {
194
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
195
}
196
197
if (relative < 1) {
198
libsumo::Vehicle::changeLane(id, laneIndex, duration);
199
} else {
200
libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);
201
}
202
}
203
break;
204
case libsumo::CMD_CHANGESUBLANE: {
205
libsumo::Vehicle::changeSublane(id, StoHelp::readTypedDouble(inputStorage, "Sublane-changing requires a double."));
206
}
207
break;
208
case libsumo::CMD_SLOWDOWN: {
209
StoHelp::readCompound(inputStorage, 2, "Slow down needs a compound object description of two items.");
210
const double newSpeed = StoHelp::readTypedDouble(inputStorage, "The first slow down parameter must be the speed given as a double.");
211
if (newSpeed < 0.) {
212
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
213
}
214
const double duration = StoHelp::readTypedDouble(inputStorage, "The second slow down parameter must be the duration given as a double.");
215
if (duration < 0. || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
216
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
217
}
218
libsumo::Vehicle::slowDown(id, newSpeed, duration);
219
}
220
break;
221
case libsumo::CMD_CHANGETARGET: {
222
libsumo::Vehicle::changeTarget(id, StoHelp::readTypedString(inputStorage, "Change target requires a string containing the id of the new destination edge as parameter."));
223
}
224
break;
225
case libsumo::CMD_OPENGAP: {
226
const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Create gap needs a compound object description.");
227
if (compoundSize != 5 && compoundSize != 6) {
228
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);
229
}
230
const double newTimeHeadway = StoHelp::readTypedDouble(inputStorage, "The first create gap parameter must be the new desired time headway (tau) given as a double.");
231
double newSpaceHeadway = StoHelp::readTypedDouble(inputStorage, "The second create gap parameter must be the new desired space headway given as a double.");
232
const double duration = StoHelp::readTypedDouble(inputStorage, "The third create gap parameter must be the duration given as a double.");
233
const double changeRate = StoHelp::readTypedDouble(inputStorage, "The fourth create gap parameter must be the change rate given as a double.");
234
const double maxDecel = StoHelp::readTypedDouble(inputStorage, "The fifth create gap parameter must be the maximal braking rate given as a double.");
235
236
if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {
237
libsumo::Vehicle::deactivateGapControl(id);
238
} else {
239
if (newTimeHeadway <= 0) {
240
if (newTimeHeadway != -1) {
241
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired time headway (tau) must be positive for create gap", outputStorage);
242
} // else if == -1: keep vehicles current headway, see libsumo::Vehicle::openGap
243
}
244
if (newSpaceHeadway < 0) {
245
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired space headway must be non-negative for create gap", outputStorage);
246
}
247
if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
248
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);
249
}
250
if (changeRate <= 0) {
251
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);
252
}
253
if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {
254
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the maximal braking rate must be positive for the openGap command", outputStorage);
255
} // else if <= 0: don't limit cf model's suggested brake rate, see libsumo::Vehicle::openGap
256
std::string refVehID = "";
257
if (compoundSize == 6) {
258
refVehID = StoHelp::readTypedString(inputStorage, "The sixth create gap parameter must be a reference vehicle's ID given as a string.");
259
}
260
libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);
261
}
262
}
263
break;
264
case libsumo::VAR_TYPE: {
265
libsumo::Vehicle::setType(id, StoHelp::readTypedString(inputStorage, "The vehicle type id must be given as a string."));
266
}
267
break;
268
case libsumo::VAR_ROUTE_ID: {
269
libsumo::Vehicle::setRouteID(id, StoHelp::readTypedString(inputStorage, "The route id must be given as a string."));
270
}
271
break;
272
case libsumo::VAR_ROUTE: {
273
libsumo::Vehicle::setRoute(id, StoHelp::readTypedStringList(inputStorage, "A route must be defined as a list of edge ids."));
274
}
275
break;
276
case libsumo::VAR_EDGE_TRAVELTIME: {
277
const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");
278
std::string edgeID;
279
double begTime = 0.;
280
double endTime = std::numeric_limits<double>::max();
281
double value = libsumo::INVALID_DOUBLE_VALUE;
282
if (parameterCount == 4) {
283
begTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the begin time as first parameter.");
284
endTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the end time as second parameter.");
285
edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 4 parameters requires the referenced edge as third parameter.");
286
value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.");
287
} else if (parameterCount == 2) {
288
edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 2 parameters requires the referenced edge as first parameter.");
289
value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 2 parameters requires the travel time as double as second parameter.");
290
} else if (parameterCount == 1) {
291
edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 1 parameter requires the referenced edge as first parameter.");
292
} else {
293
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
294
}
295
libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);
296
}
297
break;
298
case libsumo::VAR_EDGE_EFFORT: {
299
const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");
300
std::string edgeID;
301
double begTime = 0.;
302
double endTime = std::numeric_limits<double>::max();
303
double value = libsumo::INVALID_DOUBLE_VALUE;
304
if (parameterCount == 4) {
305
begTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the begin time as first parameter.");
306
endTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the end time as second parameter.");
307
edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 4 parameters requires the referenced edge as third parameter.");
308
value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the effort as double as fourth parameter.");
309
} else if (parameterCount == 2) {
310
edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 2 parameters requires the referenced edge as first parameter.");
311
value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 2 parameters requires the effort as double as second parameter.");
312
} else if (parameterCount == 1) {
313
edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 1 parameter requires the referenced edge as first parameter.");
314
} else {
315
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
316
}
317
libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);
318
}
319
break;
320
case libsumo::CMD_REROUTE_TRAVELTIME: {
321
StoHelp::readCompound(inputStorage, 0, "Rerouting by travel time requires an empty compound object.");
322
libsumo::Vehicle::rerouteTraveltime(id, false);
323
}
324
break;
325
case libsumo::CMD_REROUTE_EFFORT: {
326
StoHelp::readCompound(inputStorage, 0, "Rerouting by effort requires an empty compound object.");
327
libsumo::Vehicle::rerouteEffort(id);
328
}
329
break;
330
case libsumo::VAR_SIGNALS:
331
libsumo::Vehicle::setSignals(id, StoHelp::readTypedInt(inputStorage, "Setting signals requires an integer."));
332
break;
333
case libsumo::VAR_MOVE_TO: {
334
const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting position requires a compound object.");
335
if (parameterCount < 2 || parameterCount > 3) {
336
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position and optionally the reason.", outputStorage);
337
}
338
const std::string laneID = StoHelp::readTypedString(inputStorage, "The first parameter for setting a position must be the lane ID given as a string.");
339
const double position = StoHelp::readTypedDouble(inputStorage, "The second parameter for setting a position must be the position given as a double.");
340
int reason = libsumo::MOVE_AUTOMATIC;
341
if (parameterCount == 3) {
342
reason = StoHelp::readTypedInt(inputStorage, "The third parameter for setting a position must be the reason given as an int.");
343
}
344
// process
345
libsumo::Vehicle::moveTo(id, laneID, position, reason);
346
}
347
break;
348
case libsumo::VAR_IMPATIENCE: {
349
libsumo::Vehicle::setImpatience(id, StoHelp::readTypedDouble(inputStorage, "Setting impatience requires a double."));
350
}
351
break;
352
case libsumo::VAR_SPEED: {
353
libsumo::Vehicle::setSpeed(id, StoHelp::readTypedDouble(inputStorage, "Setting speed requires a double."));
354
}
355
break;
356
case libsumo::VAR_ACCELERATION: {
357
StoHelp::readCompound(inputStorage, 2, "Setting acceleration requires 2 parameters.");
358
const double accel = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the acceleration as first parameter given as a double.");
359
const double duration = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the duration as second parameter given as a double.");
360
if (duration < 0) {
361
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);
362
}
363
libsumo::Vehicle::setAcceleration(id, accel, duration);
364
}
365
break;
366
case libsumo::VAR_PREV_SPEED: {
367
double prevSpeed = 0;
368
double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;
369
int inputtype = inputStorage.readUnsignedByte();
370
if (inputtype == libsumo::TYPE_COMPOUND) {
371
// Setting previous speed with 2 parameters, uses a compound object description
372
const int parameterCount = inputStorage.readInt();
373
if (parameterCount == 2) {
374
prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous speed as first parameter given as a double.");
375
prevAcceleration = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous acceleration as second parameter given as a double.");
376
} else if (parameterCount == 1) {
377
prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 1 parameter requires the previous speed as first parameter given as a double.");
378
} else {
379
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);
380
}
381
} else if (inputtype == libsumo::TYPE_DOUBLE) {
382
// Setting previous speed with 1 parameter (double), no compound object description
383
prevSpeed = inputStorage.readDouble();
384
} else {
385
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 parameter given as a double or 2 parameters as compound object description.", outputStorage);
386
}
387
if (prevSpeed < 0) {
388
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);
389
}
390
libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);
391
}
392
break;
393
case libsumo::VAR_SPEEDSETMODE:
394
libsumo::Vehicle::setSpeedMode(id, StoHelp::readTypedInt(inputStorage, "Setting speed mode requires an integer."));
395
break;
396
case libsumo::VAR_LANECHANGE_MODE:
397
libsumo::Vehicle::setLaneChangeMode(id, StoHelp::readTypedInt(inputStorage, "Setting lane change mode requires an integer."));
398
break;
399
case libsumo::VAR_ROUTING_MODE:
400
libsumo::Vehicle::setRoutingMode(id, StoHelp::readTypedInt(inputStorage, "Setting routing mode requires an integer."));
401
break;
402
case libsumo::VAR_COLOR: {
403
libsumo::Vehicle::setColor(id, StoHelp::readTypedColor(inputStorage, "The color must be given using the according type."));
404
break;
405
}
406
case libsumo::ADD: {
407
StoHelp::readCompound(inputStorage, 6, "Adding a vehicle needs six parameters.");
408
const std::string vTypeID = StoHelp::readTypedString(inputStorage, "First parameter (type) requires a string.");
409
const std::string routeID = StoHelp::readTypedString(inputStorage, "Second parameter (route) requires a string.");
410
const int departCode = StoHelp::readTypedInt(inputStorage, "Third parameter (depart) requires an integer.");
411
std::string depart = toString(STEPS2TIME(departCode));
412
if (-departCode == static_cast<int>(DepartDefinition::TRIGGERED)) {
413
depart = "triggered";
414
} else if (-departCode == static_cast<int>(DepartDefinition::CONTAINER_TRIGGERED)) {
415
depart = "containerTriggered";
416
} else if (-departCode == static_cast<int>(DepartDefinition::NOW)) {
417
depart = "now";
418
} else if (-departCode == static_cast<int>(DepartDefinition::SPLIT)) {
419
depart = "split";
420
} else if (-departCode == static_cast<int>(DepartDefinition::BEGIN)) {
421
depart = "begin";
422
}
423
424
const double departPosCode = StoHelp::readTypedDouble(inputStorage, "Fourth parameter (position) requires a double.");
425
std::string departPos = toString(departPosCode);
426
if (-departPosCode == (int)DepartPosDefinition::RANDOM) {
427
departPos = "random";
428
} else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {
429
departPos = "random_free";
430
} else if (-departPosCode == (int)DepartPosDefinition::FREE) {
431
departPos = "free";
432
} else if (-departPosCode == (int)DepartPosDefinition::BASE) {
433
departPos = "base";
434
} else if (-departPosCode == (int)DepartPosDefinition::LAST) {
435
departPos = "last";
436
} else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {
437
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
438
}
439
440
const double departSpeedCode = StoHelp::readTypedDouble(inputStorage, "Fifth parameter (speed) requires a double.");
441
std::string departSpeed = toString(departSpeedCode);
442
if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {
443
departSpeed = "random";
444
} else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {
445
departSpeed = "max";
446
} else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {
447
departSpeed = "desired";
448
} else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {
449
departSpeed = "speedLimit";
450
} else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {
451
departSpeed = "last";
452
} else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {
453
departSpeed = "avg";
454
}
455
456
const int departLaneCode = StoHelp::readTypedByte(inputStorage, "Sixth parameter (lane) requires a byte.");
457
std::string departLane = toString(departLaneCode);
458
if (-departLaneCode == (int)DepartLaneDefinition::RANDOM) {
459
departLane = "random";
460
} else if (-departLaneCode == (int)DepartLaneDefinition::FREE) {
461
departLane = "free";
462
} else if (-departLaneCode == (int)DepartLaneDefinition::ALLOWED_FREE) {
463
departLane = "allowed";
464
} else if (-departLaneCode == (int)DepartLaneDefinition::BEST_FREE) {
465
departLane = "best";
466
} else if (-departLaneCode == (int)DepartLaneDefinition::FIRST_ALLOWED) {
467
departLane = "first";
468
}
469
libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);
470
}
471
break;
472
case libsumo::ADD_FULL: {
473
StoHelp::readCompound(inputStorage, 14, "Adding a fully specified vehicle needs fourteen parameters.");
474
const std::string routeID = StoHelp::readTypedString(inputStorage, "First parameter (route) requires a string.");
475
const std::string vTypeID = StoHelp::readTypedString(inputStorage, "Second parameter (type) requires a string.");
476
const std::string depart = StoHelp::readTypedString(inputStorage, "Third parameter (depart) requires an string.");
477
const std::string departLane = StoHelp::readTypedString(inputStorage, "Fourth parameter (depart lane) requires a string.");
478
const std::string departPos = StoHelp::readTypedString(inputStorage, "Fifth parameter (depart position) requires a string.");
479
const std::string departSpeed = StoHelp::readTypedString(inputStorage, "Sixth parameter (depart speed) requires a string.");
480
const std::string arrivalLane = StoHelp::readTypedString(inputStorage, "Seventh parameter (arrival lane) requires a string.");
481
const std::string arrivalPos = StoHelp::readTypedString(inputStorage, "Eighth parameter (arrival position) requires a string.");
482
const std::string arrivalSpeed = StoHelp::readTypedString(inputStorage, "Ninth parameter (arrival speed) requires a string.");
483
const std::string fromTaz = StoHelp::readTypedString(inputStorage, "Tenth parameter (from taz) requires a string.");
484
const std::string toTaz = StoHelp::readTypedString(inputStorage, "Eleventh parameter (to taz) requires a string.");
485
const std::string line = StoHelp::readTypedString(inputStorage, "Twelth parameter (line) requires a string.");
486
const int personCapacity = StoHelp::readTypedInt(inputStorage, "13th parameter (person capacity) requires an int.");
487
const int personNumber = StoHelp::readTypedInt(inputStorage, "14th parameter (person number) requires an int.");
488
libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
489
fromTaz, toTaz, line, personCapacity, personNumber);
490
}
491
break;
492
case libsumo::REMOVE: {
493
libsumo::Vehicle::remove(id, (char)StoHelp::readTypedByte(inputStorage, "Removing a vehicle requires a byte."));
494
}
495
break;
496
case libsumo::MOVE_TO_XY: {
497
const int parameterCount = StoHelp::readCompound(inputStorage, -1, "MoveToXY vehicle requires a compound object.");
498
if (parameterCount < 5 || parameterCount > 7) {
499
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle should obtain: edgeID, lane, x, y, angle and optionally keepRouteFlag and matchThreshold.", outputStorage);
500
}
501
const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first parameter for moveToXY must be the edge ID given as a string.");
502
const int laneIndex = StoHelp::readTypedInt(inputStorage, "The second parameter for moveToXY must be lane given as an int.");
503
const double x = StoHelp::readTypedDouble(inputStorage, "The third parameter for moveToXY must be the x-position given as a double.");
504
const double y = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for moveToXY must be the y-position given as a double.");
505
const double angle = StoHelp::readTypedDouble(inputStorage, "The fifth parameter for moveToXY must be the angle given as a double.");
506
int keepRouteFlag = 1;
507
if (parameterCount >= 6) {
508
keepRouteFlag = StoHelp::readTypedByte(inputStorage, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.");
509
}
510
double matchThreshold = 100.;
511
if (parameterCount == 7) {
512
matchThreshold = StoHelp::readTypedDouble(inputStorage, "The seventh parameter for moveToXY must be the matchThreshold given as a double.");
513
}
514
libsumo::Vehicle::moveToXY(id, edgeID, laneIndex, x, y, angle, keepRouteFlag, matchThreshold);
515
}
516
break;
517
case libsumo::VAR_SPEED_FACTOR: {
518
libsumo::Vehicle::setSpeedFactor(id, StoHelp::readTypedDouble(inputStorage, "Setting speed factor requires a double."));
519
}
520
break;
521
case libsumo::VAR_LINE: {
522
libsumo::Vehicle::setLine(id, StoHelp::readTypedString(inputStorage, "The line must be given as a string."));
523
}
524
break;
525
case libsumo::VAR_VIA: {
526
libsumo::Vehicle::setVia(id, StoHelp::readTypedStringList(inputStorage, "Vias must be defined as a list of edge ids."));
527
}
528
break;
529
case libsumo::VAR_PARAMETER: {
530
StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");
531
const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");
532
const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");
533
libsumo::Vehicle::setParameter(id, name, value);
534
}
535
break;
536
case libsumo::VAR_HIGHLIGHT: {
537
const int parameterCount = StoHelp::readCompound(inputStorage, -1, "A compound object is needed for highlighting an object.");
538
if (parameterCount > 5) {
539
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);
540
}
541
542
libsumo::TraCIColor col = libsumo::TraCIColor(255, 0, 0);
543
if (parameterCount > 0) {
544
col = StoHelp::readTypedColor(inputStorage, "The first parameter for highlighting must be the highlight color.");
545
}
546
double size = -1;
547
if (parameterCount > 1) {
548
size = StoHelp::readTypedDouble(inputStorage, "The second parameter for highlighting must be the highlight size.");
549
}
550
int alphaMax = -1;
551
if (parameterCount > 2) {
552
alphaMax = StoHelp::readTypedUnsignedByte(inputStorage, "The third parameter for highlighting must be maximal alpha.");
553
}
554
double duration = -1;
555
if (parameterCount > 3) {
556
duration = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for highlighting must be the highlight duration.");
557
}
558
int type = 0;
559
if (parameterCount > 4) {
560
type = StoHelp::readTypedUnsignedByte(inputStorage, "The fifth parameter for highlighting must be the highlight type id as ubyte.");
561
}
562
libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);
563
}
564
break;
565
case libsumo::CMD_TAXI_DISPATCH: {
566
libsumo::Vehicle::dispatchTaxi(id, StoHelp::readTypedStringList(inputStorage, "A dispatch command must be defined as a list of reservation ids."));
567
}
568
break;
569
case libsumo::VAR_ACTIONSTEPLENGTH: {
570
const double value = StoHelp::readTypedDouble(inputStorage, "Setting action step length requires a double.");
571
if (fabs(value) == std::numeric_limits<double>::infinity()) {
572
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);
573
}
574
bool resetActionOffset = value >= 0.0;
575
libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);
576
}
577
break;
578
case libsumo::VAR_LANEPOSITION_LAT: {
579
libsumo::Vehicle::setLateralLanePosition(id, StoHelp::readTypedDouble(inputStorage, "Setting lateral lane position requires a double."));
580
}
581
break;
582
case libsumo::VAR_UPDATE_BESTLANES: {
583
libsumo::Vehicle::updateBestLanes(id);
584
}
585
break;
586
case libsumo::VAR_MINGAP: {
587
const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum gap requires a double.");
588
if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
589
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum gap.", outputStorage);
590
}
591
libsumo::Vehicle::setMinGap(id, value);
592
}
593
break;
594
case libsumo::VAR_MINGAP_LAT: {
595
const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum lateral gap requires a double.");
596
if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
597
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);
598
}
599
libsumo::Vehicle::setMinGapLat(id, value);
600
}
601
break;
602
default: {
603
try {
604
if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {
605
return false;
606
}
607
} catch (ProcessError& e) {
608
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
609
} catch (libsumo::TraCIException& e) {
610
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
611
}
612
}
613
break;
614
}
615
} catch (libsumo::TraCIException& e) {
616
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
617
}
618
server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
619
return true;
620
}
621
622
623
bool
624
TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {
625
const std::string m1 = replace ? "Replacing" : "Inserting";
626
const std::string m2 = replace ? "replacement" : "insertion";
627
const int parameterCount = StoHelp::readCompound(inputStorage, -1, m1 + " stop needs a compound object description.");
628
if (parameterCount != 8 && parameterCount != 9) {
629
return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description of eight or nine items.", outputStorage);
630
}
631
// read road map position
632
const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop " + m2 + " parameter must be the edge id given as a string.");
633
const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop " + m2 + " parameter must be the end position along the edge given as a double.");
634
const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop " + m2 + " parameter must be the lane index given as a byte.");
635
const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.");
636
const int stopFlags = StoHelp::readTypedInt(inputStorage, "The fifth stop " + m2 + " parameter must be an int indicating its parking/triggered status.");
637
const double startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop " + m2 + " parameter must be the start position along the edge given as a double.");
638
const double until = StoHelp::readTypedDouble(inputStorage, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.");
639
const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The eighth stop " + m2 + " parameter must be the replacement index given as an int.");
640
int teleport = 0;
641
if (parameterCount == 9) {
642
teleport = StoHelp::readTypedByte(inputStorage, "The ninth stop " + m2 + " parameter must be the teleport flag given as a byte.");
643
}
644
if (replace) {
645
libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
646
} else {
647
libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
648
}
649
return true;
650
}
651
652
653
/****************************************************************************/
654
655