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