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