Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/libtraci/Simulation.cpp
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2017-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 Simulation.cpp
15
/// @author Laura Bieker-Walz
16
/// @author Robert Hilbrich
17
/// @date 15.09.2017
18
///
19
// C++ TraCI client API implementation
20
/****************************************************************************/
21
#include <config.h>
22
#include <cstdlib>
23
24
#include <foreign/tcpip/socket.h>
25
#define LIBTRACI 1
26
#include "Connection.h"
27
#include "Domain.h"
28
#include <libsumo/StorageHelper.h>
29
#include <libsumo/GUI.h>
30
#include <libsumo/Simulation.h>
31
32
33
namespace libtraci {
34
35
typedef Domain<libsumo::CMD_GET_SIM_VARIABLE, libsumo::CMD_SET_SIM_VARIABLE> Dom;
36
37
38
// ===========================================================================
39
// static member definitions
40
// ===========================================================================
41
std::pair<int, std::string>
42
Simulation::init(int port, int numRetries, const std::string& host, const std::string& label, FILE* const pipe) {
43
Connection::connect(host, port, numRetries, label, pipe);
44
switchConnection(label);
45
return getVersion();
46
}
47
48
49
std::pair<int, std::string>
50
Simulation::start(const std::vector<std::string>& cmd, int port, int numRetries, const std::string& label, const bool verbose,
51
const std::string& /* traceFile */, bool /* traceGetters */, void* /* _stdout */) {
52
if (port == -1) {
53
port = tcpip::Socket::getFreeSocketPort();
54
}
55
std::ostringstream oss;
56
for (const std::string& s : cmd) {
57
oss << s << " ";
58
}
59
oss << "--remote-port " << port << " 2>&1";
60
#ifndef WIN32
61
oss << " &";
62
#endif
63
if (verbose) {
64
std::cout << "Calling " << oss.str() << std::endl;
65
}
66
#ifdef WIN32
67
FILE* pipe = _popen(oss.str().c_str(), "r");
68
#else
69
FILE* pipe = popen(oss.str().c_str(), "r");
70
#endif
71
return init(port, numRetries, "localhost", label, pipe);
72
}
73
74
75
bool
76
Simulation::isLibsumo() {
77
return false;
78
}
79
80
81
bool
82
Simulation::hasGUI() {
83
try {
84
GUI::getIDList();
85
return true;
86
} catch (libsumo::TraCIException&) {
87
return false;
88
}
89
}
90
91
92
void
93
Simulation::switchConnection(const std::string& label) {
94
Connection::switchCon(label);
95
}
96
97
98
const std::string&
99
Simulation::getLabel() {
100
return Connection::getActive().getLabel();
101
}
102
103
104
void
105
Simulation::setOrder(int order) {
106
Connection::getActive().setOrder(order);
107
}
108
109
110
void
111
Simulation::load(const std::vector<std::string>& args) {
112
std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
113
tcpip::Storage content;
114
content.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
115
content.writeStringList(args);
116
Connection::getActive().doCommand(libsumo::CMD_LOAD, -1, "", &content);
117
}
118
119
120
bool
121
Simulation::isLoaded() {
122
return Connection::isActive();
123
}
124
125
126
void
127
Simulation::step(const double time) {
128
Connection::getActive().simulationStep(time);
129
}
130
131
132
void
133
Simulation::executeMove() {
134
std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
135
Connection::getActive().doCommand(libsumo::CMD_EXECUTEMOVE);
136
}
137
138
139
void
140
Simulation::close(const std::string& /* reason */) {
141
Connection::getActive().close();
142
}
143
144
145
std::pair<int, std::string>
146
Simulation::getVersion() {
147
std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
148
tcpip::Storage& inMsg = Connection::getActive().doCommand(libsumo::CMD_GETVERSION);
149
inMsg.readUnsignedByte(); // msg length
150
inMsg.readUnsignedByte(); // libsumo::CMD_GETVERSION again, see #7284
151
const int traciVersion = inMsg.readInt(); // to fix evaluation order
152
return std::make_pair(traciVersion, inMsg.readString());
153
}
154
155
156
std::string
157
Simulation::getOption(const std::string& option) {
158
return Dom::getString(libsumo::VAR_OPTION, option);
159
}
160
161
162
int
163
Simulation::getCurrentTime() {
164
return Dom::getInt(libsumo::VAR_TIME_STEP, "");
165
}
166
167
168
double
169
Simulation::getTime() {
170
return Dom::getDouble(libsumo::VAR_TIME, "");
171
}
172
173
174
double
175
Simulation::getEndTime() {
176
return Dom::getDouble(libsumo::VAR_END, "");
177
}
178
179
180
int
181
Simulation::getLoadedNumber() {
182
return Dom::getInt(libsumo::VAR_LOADED_VEHICLES_NUMBER, "");
183
}
184
185
186
std::vector<std::string>
187
Simulation::getLoadedIDList() {
188
return Dom::getStringVector(libsumo::VAR_LOADED_VEHICLES_IDS, "");
189
}
190
191
192
int
193
Simulation::getDepartedNumber() {
194
return Dom::getInt(libsumo::VAR_DEPARTED_VEHICLES_NUMBER, "");
195
}
196
197
198
std::vector<std::string>
199
Simulation::getDepartedIDList() {
200
return Dom::getStringVector(libsumo::VAR_DEPARTED_VEHICLES_IDS, "");
201
}
202
203
204
int
205
Simulation::getArrivedNumber() {
206
return Dom::getInt(libsumo::VAR_ARRIVED_VEHICLES_NUMBER, "");
207
}
208
209
210
std::vector<std::string>
211
Simulation::getArrivedIDList() {
212
return Dom::getStringVector(libsumo::VAR_ARRIVED_VEHICLES_IDS, "");
213
}
214
215
216
int
217
Simulation::getParkingStartingVehiclesNumber() {
218
return Dom::getInt(libsumo::VAR_PARKING_STARTING_VEHICLES_NUMBER, "");
219
}
220
221
222
std::vector<std::string>
223
Simulation::getParkingStartingVehiclesIDList() {
224
return Dom::getStringVector(libsumo::VAR_PARKING_STARTING_VEHICLES_IDS, "");
225
}
226
227
228
int
229
Simulation::getParkingEndingVehiclesNumber() {
230
return Dom::getInt(libsumo::VAR_PARKING_ENDING_VEHICLES_NUMBER, "");
231
}
232
233
234
std::vector<std::string>
235
Simulation::getParkingEndingVehiclesIDList() {
236
return Dom::getStringVector(libsumo::VAR_PARKING_ENDING_VEHICLES_IDS, "");
237
}
238
239
240
int
241
Simulation::getStopStartingVehiclesNumber() {
242
return Dom::getInt(libsumo::VAR_STOP_STARTING_VEHICLES_NUMBER, "");
243
}
244
245
246
std::vector<std::string>
247
Simulation::getStopStartingVehiclesIDList() {
248
return Dom::getStringVector(libsumo::VAR_STOP_STARTING_VEHICLES_IDS, "");
249
}
250
251
252
int
253
Simulation::getStopEndingVehiclesNumber() {
254
return Dom::getInt(libsumo::VAR_STOP_ENDING_VEHICLES_NUMBER, "");
255
}
256
257
258
std::vector<std::string>
259
Simulation::getStopEndingVehiclesIDList() {
260
return Dom::getStringVector(libsumo::VAR_STOP_ENDING_VEHICLES_IDS, "");
261
}
262
263
264
int
265
Simulation::getCollidingVehiclesNumber() {
266
return Dom::getInt(libsumo::VAR_COLLIDING_VEHICLES_NUMBER, "");
267
}
268
269
270
std::vector<std::string>
271
Simulation::getCollidingVehiclesIDList() {
272
return Dom::getStringVector(libsumo::VAR_COLLIDING_VEHICLES_IDS, "");
273
}
274
275
276
int
277
Simulation::getEmergencyStoppingVehiclesNumber() {
278
return Dom::getInt(libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER, "");
279
}
280
281
282
std::vector<std::string>
283
Simulation::getEmergencyStoppingVehiclesIDList() {
284
return Dom::getStringVector(libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_IDS, "");
285
}
286
287
288
int
289
Simulation::getStartingTeleportNumber() {
290
return Dom::getInt(libsumo::VAR_TELEPORT_STARTING_VEHICLES_NUMBER, "");
291
}
292
293
294
std::vector<std::string>
295
Simulation::getStartingTeleportIDList() {
296
return Dom::getStringVector(libsumo::VAR_TELEPORT_STARTING_VEHICLES_IDS, "");
297
}
298
299
300
int
301
Simulation::getEndingTeleportNumber() {
302
return Dom::getInt(libsumo::VAR_TELEPORT_ENDING_VEHICLES_NUMBER, "");
303
}
304
305
306
std::vector<std::string>
307
Simulation::getEndingTeleportIDList() {
308
return Dom::getStringVector(libsumo::VAR_TELEPORT_ENDING_VEHICLES_IDS, "");
309
}
310
311
312
int
313
Simulation::getDepartedPersonNumber() {
314
return Dom::getInt(libsumo::VAR_DEPARTED_PERSONS_NUMBER, "");
315
}
316
317
318
std::vector<std::string>
319
Simulation::getDepartedPersonIDList() {
320
return Dom::getStringVector(libsumo::VAR_DEPARTED_PERSONS_IDS, "");
321
}
322
323
324
int
325
Simulation::getArrivedPersonNumber() {
326
return Dom::getInt(libsumo::VAR_ARRIVED_PERSONS_NUMBER, "");
327
}
328
329
330
std::vector<std::string>
331
Simulation::getArrivedPersonIDList() {
332
return Dom::getStringVector(libsumo::VAR_ARRIVED_PERSONS_IDS, "");
333
}
334
335
336
std::vector<std::string>
337
Simulation::getBusStopIDList() {
338
return Dom::getStringVector(libsumo::VAR_BUS_STOP_ID_LIST, "");
339
}
340
341
int
342
Simulation::getBusStopWaiting(const std::string& stopID) {
343
return Dom::getInt(libsumo::VAR_BUS_STOP_WAITING, stopID);
344
}
345
346
std::vector<std::string>
347
Simulation::getBusStopWaitingIDList(const std::string& stopID) {
348
return Dom::getStringVector(libsumo::VAR_BUS_STOP_WAITING_IDS, stopID);
349
}
350
351
352
std::vector<std::string>
353
Simulation::getPendingVehicles() {
354
return Dom::getStringVector(libsumo::VAR_PENDING_VEHICLES, "");
355
}
356
357
358
std::vector<libsumo::TraCICollision>
359
Simulation::getCollisions() {
360
std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
361
tcpip::Storage& ret = Dom::get(libsumo::VAR_COLLISIONS, "");
362
std::vector<libsumo::TraCICollision> result;
363
ret.readInt();
364
StoHelp::readCollisionVector(ret, result);
365
return result;
366
}
367
368
369
double
370
Simulation::getScale() {
371
return Dom::getDouble(libsumo::VAR_SCALE, "");
372
}
373
374
375
double
376
Simulation::getDeltaT() {
377
return Dom::getDouble(libsumo::VAR_DELTA_T, "");
378
}
379
380
381
libsumo::TraCIPositionVector
382
Simulation::getNetBoundary() {
383
return Dom::getPolygon(libsumo::VAR_NET_BOUNDING_BOX, "");
384
}
385
386
387
int
388
Simulation::getMinExpectedNumber() {
389
return Dom::getInt(libsumo::VAR_MIN_EXPECTED_VEHICLES, "");
390
}
391
392
393
libsumo::TraCIPosition
394
Simulation::convert2D(const std::string& edgeID, double pos, int laneIndex, bool toGeo) {
395
tcpip::Storage content;
396
StoHelp::writeCompound(content, 2);
397
content.writeUnsignedByte(libsumo::POSITION_ROADMAP);
398
content.writeString(edgeID);
399
content.writeDouble(pos);
400
content.writeUnsignedByte(laneIndex);
401
content.writeUnsignedByte(libsumo::TYPE_UBYTE);
402
content.writeUnsignedByte(toGeo ? libsumo::POSITION_LON_LAT : libsumo::POSITION_2D);
403
return Dom::getPos(libsumo::POSITION_CONVERSION, "", &content, toGeo);
404
}
405
406
407
libsumo::TraCIPosition
408
Simulation::convert3D(const std::string& edgeID, double pos, int laneIndex, bool toGeo) {
409
tcpip::Storage content;
410
StoHelp::writeCompound(content, 2);
411
content.writeUnsignedByte(libsumo::POSITION_ROADMAP);
412
content.writeString(edgeID);
413
content.writeDouble(pos);
414
content.writeUnsignedByte(laneIndex);
415
content.writeUnsignedByte(libsumo::TYPE_UBYTE);
416
content.writeUnsignedByte(toGeo ? libsumo::POSITION_LON_LAT_ALT : libsumo::POSITION_3D);
417
return Dom::getPos3D(libsumo::POSITION_CONVERSION, "", &content, toGeo);
418
}
419
420
421
libsumo::TraCIRoadPosition
422
Simulation::convertRoad(double x, double y, bool isGeo, const std::string& vClass) {
423
tcpip::Storage content;
424
StoHelp::writeCompound(content, 3);
425
content.writeUnsignedByte(isGeo ? libsumo::POSITION_LON_LAT : libsumo::POSITION_2D);
426
content.writeDouble(x);
427
content.writeDouble(y);
428
content.writeUnsignedByte(libsumo::TYPE_UBYTE);
429
content.writeUnsignedByte(libsumo::POSITION_ROADMAP);
430
StoHelp::writeTypedString(content, vClass);
431
std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
432
tcpip::Storage& ret = Dom::get(libsumo::POSITION_CONVERSION, "", &content, libsumo::POSITION_ROADMAP);
433
libsumo::TraCIRoadPosition result;
434
result.edgeID = ret.readString();
435
result.pos = ret.readDouble();
436
result.laneIndex = ret.readByte();
437
return result;
438
}
439
440
441
libsumo::TraCIPosition
442
Simulation::convertGeo(double x, double y, bool fromGeo) {
443
tcpip::Storage content;
444
StoHelp::writeCompound(content, 2);
445
content.writeUnsignedByte(fromGeo ? libsumo::POSITION_LON_LAT : libsumo::POSITION_2D);
446
content.writeDouble(x);
447
content.writeDouble(y);
448
content.writeUnsignedByte(libsumo::TYPE_UBYTE);
449
content.writeUnsignedByte(fromGeo ? libsumo::POSITION_2D : libsumo::POSITION_LON_LAT);
450
return Dom::getPos(libsumo::POSITION_CONVERSION, "", &content, !fromGeo);
451
}
452
453
454
double
455
Simulation::getDistance2D(double x1, double y1, double x2, double y2, bool isGeo, bool isDriving) {
456
tcpip::Storage content;
457
StoHelp::writeCompound(content, 3);
458
content.writeUnsignedByte(isGeo ? libsumo::POSITION_LON_LAT : libsumo::POSITION_2D);
459
content.writeDouble(x1);
460
content.writeDouble(y1);
461
content.writeUnsignedByte(isGeo ? libsumo::POSITION_LON_LAT : libsumo::POSITION_2D);
462
content.writeDouble(x2);
463
content.writeDouble(y2);
464
content.writeUnsignedByte(isDriving ? libsumo::REQUEST_DRIVINGDIST : libsumo::REQUEST_AIRDIST);
465
return Dom::getDouble(libsumo::DISTANCE_REQUEST, "", &content);
466
}
467
468
469
double
470
Simulation::getDistanceRoad(const std::string& edgeID1, double pos1, const std::string& edgeID2, double pos2, bool isDriving) {
471
tcpip::Storage content;
472
StoHelp::writeCompound(content, 3);
473
content.writeUnsignedByte(libsumo::POSITION_ROADMAP);
474
content.writeString(edgeID1);
475
content.writeDouble(pos1);
476
content.writeUnsignedByte(0);
477
content.writeUnsignedByte(libsumo::POSITION_ROADMAP);
478
content.writeString(edgeID2);
479
content.writeDouble(pos2);
480
content.writeUnsignedByte(0);
481
content.writeUnsignedByte(isDriving ? libsumo::REQUEST_DRIVINGDIST : libsumo::REQUEST_AIRDIST);
482
return Dom::getDouble(libsumo::DISTANCE_REQUEST, "", &content);
483
}
484
485
486
libsumo::TraCIStage
487
Simulation::findRoute(const std::string& fromEdge, const std::string& toEdge, const std::string& vType, const double depart, const int routingMode) {
488
tcpip::Storage content;
489
StoHelp::writeCompound(content, 5);
490
StoHelp::writeTypedString(content, fromEdge);
491
StoHelp::writeTypedString(content, toEdge);
492
StoHelp::writeTypedString(content, vType);
493
StoHelp::writeTypedDouble(content, depart);
494
StoHelp::writeTypedInt(content, routingMode);
495
return Dom::getTraCIStage(libsumo::FIND_ROUTE, "", &content);
496
}
497
498
499
std::vector<libsumo::TraCIStage>
500
Simulation::findIntermodalRoute(const std::string& fromEdge, const std::string& toEdge,
501
const std::string& modes, double depart, const int routingMode, double speed, double walkFactor,
502
double departPos, double arrivalPos, const double departPosLat,
503
const std::string& pType, const std::string& vType, const std::string& destStop) {
504
tcpip::Storage content;
505
StoHelp::writeCompound(content, 13);
506
StoHelp::writeTypedString(content, fromEdge);
507
StoHelp::writeTypedString(content, toEdge);
508
StoHelp::writeTypedString(content, modes);
509
StoHelp::writeTypedDouble(content, depart);
510
StoHelp::writeTypedInt(content, routingMode);
511
StoHelp::writeTypedDouble(content, speed);
512
StoHelp::writeTypedDouble(content, walkFactor);
513
StoHelp::writeTypedDouble(content, departPos);
514
StoHelp::writeTypedDouble(content, arrivalPos);
515
StoHelp::writeTypedDouble(content, departPosLat);
516
StoHelp::writeTypedString(content, pType);
517
StoHelp::writeTypedString(content, vType);
518
StoHelp::writeTypedString(content, destStop);
519
std::unique_lock<std::mutex> lock{ libtraci::Connection::getActive().getMutex() };
520
tcpip::Storage& result = Dom::get(libsumo::FIND_INTERMODAL_ROUTE, "", &content);
521
int numStages = result.readInt();
522
std::vector<libsumo::TraCIStage> ret;
523
while (numStages-- > 0) {
524
libsumo::TraCIStage s;
525
StoHelp::readCompound(result, 13);
526
s.type = StoHelp::readTypedInt(result);
527
s.vType = StoHelp::readTypedString(result);
528
s.line = StoHelp::readTypedString(result);
529
s.destStop = StoHelp::readTypedString(result);
530
s.edges = StoHelp::readTypedStringList(result);
531
s.travelTime = StoHelp::readTypedDouble(result);
532
s.cost = StoHelp::readTypedDouble(result);
533
s.length = StoHelp::readTypedDouble(result);
534
s.intended = StoHelp::readTypedString(result);
535
s.depart = StoHelp::readTypedDouble(result);
536
s.departPos = StoHelp::readTypedDouble(result);
537
s.arrivalPos = StoHelp::readTypedDouble(result);
538
s.description = StoHelp::readTypedString(result);
539
ret.emplace_back(s);
540
}
541
return ret;
542
}
543
544
LIBTRACI_PARAMETER_IMPLEMENTATION(Simulation, SIM)
545
546
void
547
Simulation::setScale(double value) {
548
Dom::setDouble(libsumo::VAR_SCALE, "", value);
549
}
550
551
void
552
Simulation::clearPending(const std::string& routeID) {
553
Dom::setString(libsumo::CMD_CLEAR_PENDING_VEHICLES, "", routeID);
554
}
555
556
557
void
558
Simulation::saveState(const std::string& fileName) {
559
Dom::setString(libsumo::CMD_SAVE_SIMSTATE, "", fileName);
560
}
561
562
double
563
Simulation::loadState(const std::string& fileName) {
564
Dom::setString(libsumo::CMD_LOAD_SIMSTATE, "", fileName);
565
return 0.;
566
}
567
568
void
569
Simulation::writeMessage(const std::string& msg) {
570
Dom::setString(libsumo::CMD_MESSAGE, "", msg);
571
}
572
573
574
void
575
Simulation::subscribe(const std::vector<int>& varIDs, double begin, double end, const libsumo::TraCIResults& parameters) {
576
libtraci::Connection::getActive().subscribe(libsumo::CMD_SUBSCRIBE_SIM_VARIABLE, "", begin, end, -1, -1, varIDs, parameters);
577
}
578
579
580
const libsumo::TraCIResults
581
Simulation::getSubscriptionResults() {
582
return libtraci::Connection::getActive().getAllSubscriptionResults(libsumo::RESPONSE_SUBSCRIBE_SIM_VARIABLE)[""];
583
}
584
585
586
LIBTRACI_SUBSCRIPTION_IMPLEMENTATION(Simulation, SIM)
587
588
}
589
590
591
/****************************************************************************/
592
593