Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/traci-server/TraCIServerAPI_Simulation.cpp
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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_Simulation.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @author Laura Bieker
19
/// @date Sept 2002
20
///
21
// APIs for getting/setting simulation values via TraCI
22
/****************************************************************************/
23
#include <config.h>
24
25
#include <utils/common/StdDefs.h>
26
#include <utils/geom/GeoConvHelper.h>
27
#include <microsim/MSNet.h>
28
#include <microsim/MSEdgeControl.h>
29
#include <microsim/MSInsertionControl.h>
30
#include <microsim/MSEdge.h>
31
#include <microsim/MSLane.h>
32
#include <microsim/MSVehicle.h>
33
#include <microsim/MSVehicleControl.h>
34
#include <microsim/MSStateHandler.h>
35
#include <microsim/MSStoppingPlace.h>
36
#include <libsumo/Helper.h>
37
#include <libsumo/Simulation.h>
38
#include <libsumo/TraCIConstants.h>
39
#include <libsumo/StorageHelper.h>
40
#include "TraCIServerAPI_Simulation.h"
41
42
43
// ===========================================================================
44
// method definitions
45
// ===========================================================================
46
bool
47
TraCIServerAPI_Simulation::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
48
tcpip::Storage& outputStorage) {
49
const int variable = inputStorage.readUnsignedByte();
50
const std::string id = inputStorage.readString();
51
server.initWrapper(libsumo::RESPONSE_GET_SIM_VARIABLE, variable, id);
52
try {
53
// unlike the other domains we cannot check here first whether libsumo::Simulation can handle it because the implementations for the state variables differ
54
switch (variable) {
55
case libsumo::VAR_LOADED_VEHICLES_NUMBER:
56
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);
57
break;
58
case libsumo::VAR_LOADED_VEHICLES_IDS:
59
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);
60
break;
61
case libsumo::VAR_DEPARTED_VEHICLES_NUMBER:
62
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);
63
break;
64
case libsumo::VAR_DEPARTED_VEHICLES_IDS:
65
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);
66
break;
67
case libsumo::VAR_TELEPORT_STARTING_VEHICLES_NUMBER:
68
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);
69
break;
70
case libsumo::VAR_TELEPORT_STARTING_VEHICLES_IDS:
71
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);
72
break;
73
case libsumo::VAR_TELEPORT_ENDING_VEHICLES_NUMBER:
74
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);
75
break;
76
case libsumo::VAR_TELEPORT_ENDING_VEHICLES_IDS:
77
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);
78
break;
79
case libsumo::VAR_ARRIVED_VEHICLES_NUMBER:
80
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);
81
break;
82
case libsumo::VAR_ARRIVED_VEHICLES_IDS:
83
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);
84
break;
85
case libsumo::VAR_DEPARTED_PERSONS_NUMBER:
86
writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);
87
break;
88
case libsumo::VAR_DEPARTED_PERSONS_IDS:
89
writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);
90
break;
91
case libsumo::VAR_ARRIVED_PERSONS_NUMBER:
92
writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);
93
break;
94
case libsumo::VAR_ARRIVED_PERSONS_IDS:
95
writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);
96
break;
97
case libsumo::VAR_PARKING_STARTING_VEHICLES_NUMBER:
98
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);
99
break;
100
case libsumo::VAR_PARKING_STARTING_VEHICLES_IDS:
101
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);
102
break;
103
case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_NUMBER:
104
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);
105
break;
106
case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_IDS:
107
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);
108
break;
109
case libsumo::VAR_PARKING_ENDING_VEHICLES_NUMBER:
110
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);
111
break;
112
case libsumo::VAR_PARKING_ENDING_VEHICLES_IDS:
113
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);
114
break;
115
case libsumo::VAR_STOP_STARTING_VEHICLES_NUMBER:
116
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);
117
break;
118
case libsumo::VAR_STOP_STARTING_VEHICLES_IDS:
119
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);
120
break;
121
case libsumo::VAR_STOP_ENDING_VEHICLES_NUMBER:
122
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);
123
break;
124
case libsumo::VAR_STOP_ENDING_VEHICLES_IDS:
125
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);
126
break;
127
case libsumo::VAR_COLLIDING_VEHICLES_NUMBER:
128
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);
129
break;
130
case libsumo::VAR_COLLIDING_VEHICLES_IDS:
131
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);
132
break;
133
case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER:
134
writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);
135
break;
136
case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_IDS:
137
writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);
138
break;
139
case libsumo::VAR_COLLISIONS: {
140
std::vector<libsumo::TraCICollision> collisions = libsumo::Simulation::getCollisions();
141
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);
142
const int cnt = 1 + (int)collisions.size() * 4;
143
server.getWrapperStorage().writeInt(cnt);
144
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_INTEGER);
145
server.getWrapperStorage().writeInt((int)collisions.size());
146
for (const auto& c : collisions) {
147
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
148
server.getWrapperStorage().writeString(c.collider);
149
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
150
server.getWrapperStorage().writeString(c.victim);
151
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
152
server.getWrapperStorage().writeString(c.colliderType);
153
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
154
server.getWrapperStorage().writeString(c.victimType);
155
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
156
server.getWrapperStorage().writeDouble(c.colliderSpeed);
157
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
158
server.getWrapperStorage().writeDouble(c.victimSpeed);
159
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
160
server.getWrapperStorage().writeString(c.type);
161
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
162
server.getWrapperStorage().writeString(c.lane);
163
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
164
server.getWrapperStorage().writeDouble(c.pos);
165
}
166
break;
167
}
168
case libsumo::VAR_NET_BOUNDING_BOX: {
169
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_POLYGON);
170
libsumo::TraCIPositionVector tb = libsumo::Simulation::getNetBoundary();
171
server.getWrapperStorage().writeByte(2);
172
server.getWrapperStorage().writeDouble(tb.value[0].x);
173
server.getWrapperStorage().writeDouble(tb.value[0].y);
174
server.getWrapperStorage().writeDouble(tb.value[1].x);
175
server.getWrapperStorage().writeDouble(tb.value[1].y);
176
break;
177
}
178
case libsumo::POSITION_CONVERSION: {
179
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
180
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Position conversion requires a compound object.", outputStorage);
181
}
182
const int compoundSize = inputStorage.readInt();
183
if (compoundSize < 2 || compoundSize > 3) {
184
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Position conversion requires a source position and a position type as parameter.", outputStorage);
185
}
186
if (!commandPositionConversion(server, inputStorage, compoundSize, server.getWrapperStorage(), libsumo::CMD_GET_SIM_VARIABLE)) {
187
return false;
188
}
189
break;
190
}
191
case libsumo::DISTANCE_REQUEST:
192
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
193
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
194
}
195
if (inputStorage.readInt() != 3) {
196
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of distance requires two positions and a distance type as parameter.", outputStorage);
197
}
198
if (!commandDistanceRequest(server, inputStorage, server.getWrapperStorage(), libsumo::CMD_GET_SIM_VARIABLE)) {
199
return false;
200
}
201
break;
202
case libsumo::FIND_ROUTE: {
203
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
204
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a compound object.", outputStorage);
205
}
206
if (inputStorage.readInt() != 5) {
207
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires five parameter.", outputStorage);
208
}
209
std::string from, to, vtype;
210
double depart;
211
if (!server.readTypeCheckingString(inputStorage, from)) {
212
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as first parameter.", outputStorage);
213
}
214
if (!server.readTypeCheckingString(inputStorage, to)) {
215
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as second parameter.", outputStorage);
216
}
217
if (!server.readTypeCheckingString(inputStorage, vtype)) {
218
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as third parameter.", outputStorage);
219
}
220
if (!server.readTypeCheckingDouble(inputStorage, depart)) {
221
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as fourth parameter.", outputStorage);
222
}
223
const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");
224
libsumo::StorageHelper::writeStage(server.getWrapperStorage(), libsumo::Simulation::findRoute(from, to, vtype, depart, routingMode));
225
break;
226
}
227
case libsumo::FIND_INTERMODAL_ROUTE: {
228
if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
229
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of an intermodal route requires a compound object.", outputStorage);
230
}
231
if (inputStorage.readInt() != 13) {
232
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of an intermodal route requires thirteen parameters.", outputStorage);
233
}
234
std::string from, to, modes, ptype, vtype, destStop;
235
double depart, speed, walkFactor, departPos, arrivalPos, departPosLat;
236
if (!server.readTypeCheckingString(inputStorage, from)) {
237
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as first parameter.", outputStorage);
238
}
239
if (!server.readTypeCheckingString(inputStorage, to)) {
240
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as second parameter.", outputStorage);
241
}
242
if (!server.readTypeCheckingString(inputStorage, modes)) {
243
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as third parameter.", outputStorage);
244
}
245
if (!server.readTypeCheckingDouble(inputStorage, depart)) {
246
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as fourth parameter.", outputStorage);
247
}
248
const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");
249
if (!server.readTypeCheckingDouble(inputStorage, speed)) {
250
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as sixth parameter.", outputStorage);
251
}
252
if (!server.readTypeCheckingDouble(inputStorage, walkFactor)) {
253
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as seventh parameter.", outputStorage);
254
}
255
if (!server.readTypeCheckingDouble(inputStorage, departPos)) {
256
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as eigth parameter.", outputStorage);
257
}
258
if (!server.readTypeCheckingDouble(inputStorage, arrivalPos)) {
259
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as nineth parameter.", outputStorage);
260
}
261
if (!server.readTypeCheckingDouble(inputStorage, departPosLat)) {
262
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as tenth parameter.", outputStorage);
263
}
264
if (!server.readTypeCheckingString(inputStorage, ptype)) {
265
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as eleventh parameter.", outputStorage);
266
}
267
if (!server.readTypeCheckingString(inputStorage, vtype)) {
268
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as twelvth parameter.", outputStorage);
269
}
270
if (!server.readTypeCheckingString(inputStorage, destStop)) {
271
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as thirteenth parameter.", outputStorage);
272
}
273
const std::vector<libsumo::TraCIStage>& result = libsumo::Simulation::findIntermodalRoute(from, to, modes, depart, routingMode, speed, walkFactor, departPos, arrivalPos, departPosLat, ptype, vtype, destStop);
274
server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);
275
server.getWrapperStorage().writeInt((int)result.size());
276
for (const libsumo::TraCIStage& s : result) {
277
libsumo::StorageHelper::writeStage(server.getWrapperStorage(), s);
278
}
279
break;
280
}
281
default:
282
if (!libsumo::Simulation::handleVariable(id, variable, &server, &inputStorage)) {
283
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Get Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
284
}
285
}
286
} catch (libsumo::TraCIException& e) {
287
return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, e.what(), outputStorage);
288
}
289
server.writeStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, libsumo::RTYPE_OK, "", outputStorage);
290
server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
291
return true;
292
}
293
294
295
bool
296
TraCIServerAPI_Simulation::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
297
tcpip::Storage& outputStorage) {
298
std::string warning = ""; // additional description for response
299
// variable
300
int variable = inputStorage.readUnsignedByte();
301
if (variable != libsumo::CMD_CLEAR_PENDING_VEHICLES
302
&& variable != libsumo::CMD_SAVE_SIMSTATE
303
&& variable != libsumo::CMD_LOAD_SIMSTATE
304
&& variable != libsumo::VAR_PARAMETER
305
&& variable != libsumo::VAR_SCALE
306
&& variable != libsumo::CMD_MESSAGE
307
) {
308
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Set Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
309
}
310
// id
311
std::string id = inputStorage.readString();
312
// process
313
try {
314
switch (variable) {
315
case libsumo::VAR_SCALE: {
316
double value;
317
if (!server.readTypeCheckingDouble(inputStorage, value)) {
318
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A double is needed for setting traffic scale.", outputStorage);
319
}
320
if (value < 0.0) {
321
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Traffic scale may not be negative.", outputStorage);
322
}
323
libsumo::Simulation::setScale(value);
324
}
325
break;
326
case libsumo::CMD_CLEAR_PENDING_VEHICLES: {
327
//clear any pending vehicle insertions
328
std::string route;
329
if (!server.readTypeCheckingString(inputStorage, route)) {
330
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for clearing pending vehicles.", outputStorage);
331
}
332
libsumo::Simulation::clearPending(route);
333
}
334
break;
335
case libsumo::CMD_SAVE_SIMSTATE: {
336
//save current simulation state
337
std::string file;
338
if (!server.readTypeCheckingString(inputStorage, file)) {
339
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for saving simulation state.", outputStorage);
340
}
341
libsumo::Simulation::saveState(file);
342
}
343
break;
344
case libsumo::CMD_LOAD_SIMSTATE: {
345
//quick-load simulation state
346
std::string file;
347
if (!server.readTypeCheckingString(inputStorage, file)) {
348
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for loading simulation state.", outputStorage);
349
}
350
double time = libsumo::Simulation::loadState(file);
351
TraCIServer::getInstance()->stateLoaded(TIME2STEPS(time));
352
}
353
break;
354
case libsumo::VAR_PARAMETER: {
355
StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");
356
const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");
357
const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");
358
libsumo::Simulation::setParameter(id, name, value);
359
break;
360
}
361
case libsumo::CMD_MESSAGE: {
362
std::string msg;
363
if (!server.readTypeCheckingString(inputStorage, msg)) {
364
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for adding a log message.", outputStorage);
365
}
366
libsumo::Simulation::writeMessage(msg);
367
}
368
break;
369
default:
370
break;
371
}
372
} catch (libsumo::TraCIException& e) {
373
return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, e.what(), outputStorage);
374
}
375
server.writeStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
376
return true;
377
}
378
379
380
void
381
TraCIServerAPI_Simulation::writeVehicleStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {
382
const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;
383
outputStorage.writeUnsignedByte(libsumo::TYPE_INTEGER);
384
outputStorage.writeInt((int) ids.size());
385
}
386
387
388
void
389
TraCIServerAPI_Simulation::writeVehicleStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {
390
const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;
391
outputStorage.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
392
outputStorage.writeStringList(ids);
393
}
394
395
396
void
397
TraCIServerAPI_Simulation::writeTransportableStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {
398
const std::vector<std::string>& ids = server.getTransportableStateChanges().find(state)->second;
399
outputStorage.writeUnsignedByte(libsumo::TYPE_INTEGER);
400
outputStorage.writeInt((int)ids.size());
401
}
402
403
404
void
405
TraCIServerAPI_Simulation::writeTransportableStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {
406
const std::vector<std::string>& ids = server.getTransportableStateChanges().find(state)->second;
407
outputStorage.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
408
outputStorage.writeStringList(ids);
409
}
410
411
412
bool
413
TraCIServerAPI_Simulation::commandPositionConversion(TraCIServer& server, tcpip::Storage& inputStorage,
414
const int compoundSize, tcpip::Storage& outputStorage,
415
const int commandId) {
416
std::pair<MSLane*, double> roadPos;
417
Position cartesianPos;
418
Position geoPos;
419
double z = 0;
420
421
// actual position type that will be converted
422
int srcPosType = inputStorage.readUnsignedByte();
423
424
switch (srcPosType) {
425
case libsumo::POSITION_2D:
426
case libsumo::POSITION_3D:
427
case libsumo::POSITION_LON_LAT:
428
case libsumo::POSITION_LON_LAT_ALT: {
429
const double x = inputStorage.readDouble();
430
const double y = inputStorage.readDouble();
431
if (srcPosType != libsumo::POSITION_2D && srcPosType != libsumo::POSITION_LON_LAT) {
432
z = inputStorage.readDouble();
433
}
434
geoPos.set(x, y);
435
cartesianPos.set(x, y);
436
if (srcPosType == libsumo::POSITION_LON_LAT || srcPosType == libsumo::POSITION_LON_LAT_ALT) {
437
GeoConvHelper::getFinal().x2cartesian_const(cartesianPos);
438
} else {
439
GeoConvHelper::getFinal().cartesian2geo(geoPos);
440
}
441
}
442
break;
443
case libsumo::POSITION_ROADMAP: {
444
const std::string roadID = inputStorage.readString();
445
const double pos = inputStorage.readDouble();
446
const int laneIdx = inputStorage.readUnsignedByte();
447
try {
448
// convert edge,offset,laneIdx to cartesian position
449
cartesianPos = geoPos = libsumo::Helper::getLaneChecking(roadID, laneIdx, pos)->geometryPositionAtOffset(pos);
450
z = cartesianPos.z();
451
GeoConvHelper::getFinal().cartesian2geo(geoPos);
452
} catch (libsumo::TraCIException& e) {
453
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, e.what());
454
return false;
455
}
456
}
457
break;
458
default:
459
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Source position type not supported");
460
return false;
461
}
462
463
int destPosType = 0;
464
if (!server.readTypeCheckingUnsignedByte(inputStorage, destPosType)) {
465
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Destination position type must be of type ubyte.");
466
return false;
467
}
468
469
SUMOVehicleClass vClass = SVC_IGNORING;
470
if (compoundSize == 3) {
471
inputStorage.readUnsignedByte();
472
const std::string& vClassString = inputStorage.readString();
473
if (!SumoVehicleClassStrings.hasString(vClassString)) {
474
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Unknown vehicle class '" + vClassString + "'.");
475
return false;
476
}
477
vClass = SumoVehicleClassStrings.get(vClassString);
478
}
479
480
switch (destPosType) {
481
case libsumo::POSITION_ROADMAP: {
482
// convert cartesion position to edge,offset,lane_index
483
roadPos = libsumo::Helper::convertCartesianToRoadMap(cartesianPos, vClass);
484
if (roadPos.first == nullptr) {
485
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "No matching lane found.");
486
return false;
487
}
488
// write result that is added to response msg
489
outputStorage.writeUnsignedByte(libsumo::POSITION_ROADMAP);
490
outputStorage.writeString(roadPos.first->getEdge().getID());
491
outputStorage.writeDouble(roadPos.second);
492
outputStorage.writeUnsignedByte(roadPos.first->getIndex());
493
}
494
break;
495
case libsumo::POSITION_2D:
496
case libsumo::POSITION_3D:
497
case libsumo::POSITION_LON_LAT:
498
case libsumo::POSITION_LON_LAT_ALT:
499
outputStorage.writeUnsignedByte(destPosType);
500
if (destPosType == libsumo::POSITION_LON_LAT || destPosType == libsumo::POSITION_LON_LAT_ALT) {
501
outputStorage.writeDouble(geoPos.x());
502
outputStorage.writeDouble(geoPos.y());
503
} else {
504
outputStorage.writeDouble(cartesianPos.x());
505
outputStorage.writeDouble(cartesianPos.y());
506
}
507
if (destPosType != libsumo::POSITION_2D && destPosType != libsumo::POSITION_LON_LAT) {
508
outputStorage.writeDouble(z);
509
}
510
break;
511
default:
512
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Destination position type not supported");
513
return false;
514
}
515
return true;
516
}
517
518
519
bool
520
TraCIServerAPI_Simulation::commandDistanceRequest(TraCIServer& server, tcpip::Storage& inputStorage,
521
tcpip::Storage& outputStorage, int commandId) {
522
Position pos1;
523
Position pos2;
524
std::pair<const MSLane*, double> roadPos1;
525
std::pair<const MSLane*, double> roadPos2;
526
527
// read position 1
528
int posType = inputStorage.readUnsignedByte();
529
switch (posType) {
530
case libsumo::POSITION_ROADMAP:
531
try {
532
std::string roadID = inputStorage.readString();
533
roadPos1.second = inputStorage.readDouble();
534
roadPos1.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos1.second);
535
pos1 = roadPos1.first->geometryPositionAtOffset(roadPos1.second);
536
} catch (libsumo::TraCIException& e) {
537
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, e.what());
538
return false;
539
}
540
break;
541
case libsumo::POSITION_2D:
542
case libsumo::POSITION_3D: {
543
double p1x = inputStorage.readDouble();
544
double p1y = inputStorage.readDouble();
545
pos1.set(p1x, p1y);
546
}
547
if (posType == libsumo::POSITION_3D) {
548
inputStorage.readDouble();// z value is ignored
549
}
550
roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
551
break;
552
case libsumo::POSITION_LON_LAT:
553
case libsumo::POSITION_LON_LAT_ALT: {
554
double p1x = inputStorage.readDouble();
555
double p1y = inputStorage.readDouble();
556
pos1.set(p1x, p1y);
557
GeoConvHelper::getFinal().x2cartesian_const(pos1);
558
}
559
if (posType == libsumo::POSITION_LON_LAT_ALT) {
560
inputStorage.readDouble();// altitude value is ignored
561
}
562
roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
563
break;
564
default:
565
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Unknown position format used for distance request");
566
return false;
567
}
568
569
// read position 2
570
posType = inputStorage.readUnsignedByte();
571
switch (posType) {
572
case libsumo::POSITION_ROADMAP:
573
try {
574
std::string roadID = inputStorage.readString();
575
roadPos2.second = inputStorage.readDouble();
576
roadPos2.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos2.second);
577
pos2 = roadPos2.first->geometryPositionAtOffset(roadPos2.second);
578
} catch (libsumo::TraCIException& e) {
579
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, e.what());
580
return false;
581
}
582
break;
583
case libsumo::POSITION_2D:
584
case libsumo::POSITION_3D: {
585
double p2x = inputStorage.readDouble();
586
double p2y = inputStorage.readDouble();
587
pos2.set(p2x, p2y);
588
}
589
if (posType == libsumo::POSITION_3D) {
590
inputStorage.readDouble();// z value is ignored
591
}
592
roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
593
break;
594
case libsumo::POSITION_LON_LAT:
595
case libsumo::POSITION_LON_LAT_ALT: {
596
double p2x = inputStorage.readDouble();
597
double p2y = inputStorage.readDouble();
598
pos2.set(p2x, p2y);
599
GeoConvHelper::getFinal().x2cartesian_const(pos2);
600
}
601
if (posType == libsumo::POSITION_LON_LAT_ALT) {
602
inputStorage.readDouble();// altitude value is ignored
603
}
604
roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
605
break;
606
default:
607
server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Unknown position format used for distance request");
608
return false;
609
}
610
611
// read distance type
612
const int distType = inputStorage.readUnsignedByte();
613
614
double distance = 0.0;
615
if (distType == libsumo::REQUEST_DRIVINGDIST) {
616
distance = libsumo::Helper::getDrivingDistance(roadPos1, roadPos2);
617
} else {
618
// compute air distance (default)
619
distance = pos1.distanceTo(pos2);
620
}
621
// write response command
622
outputStorage.writeUnsignedByte(libsumo::TYPE_DOUBLE);
623
outputStorage.writeDouble(distance);
624
return true;
625
}
626
627
628
/****************************************************************************/
629
630