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