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