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 7021053 : TraCIServerAPI_Simulation::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
48 : tcpip::Storage& outputStorage) {
49 7021053 : const int variable = inputStorage.readUnsignedByte();
50 7021053 : const std::string id = inputStorage.readString();
51 7021053 : 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 7021053 : switch (variable) {
55 18 : case libsumo::VAR_LOADED_VEHICLES_NUMBER:
56 18 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);
57 : break;
58 98 : case libsumo::VAR_LOADED_VEHICLES_IDS:
59 98 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);
60 : break;
61 47749 : case libsumo::VAR_DEPARTED_VEHICLES_NUMBER:
62 47749 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);
63 : break;
64 46770 : case libsumo::VAR_DEPARTED_VEHICLES_IDS:
65 46770 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);
66 : break;
67 18 : case libsumo::VAR_TELEPORT_STARTING_VEHICLES_NUMBER:
68 18 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);
69 : break;
70 18 : case libsumo::VAR_TELEPORT_STARTING_VEHICLES_IDS:
71 18 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);
72 : break;
73 18 : case libsumo::VAR_TELEPORT_ENDING_VEHICLES_NUMBER:
74 18 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);
75 : break;
76 18 : case libsumo::VAR_TELEPORT_ENDING_VEHICLES_IDS:
77 18 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);
78 : break;
79 1374 : case libsumo::VAR_ARRIVED_VEHICLES_NUMBER:
80 1374 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);
81 : break;
82 12183 : case libsumo::VAR_ARRIVED_VEHICLES_IDS:
83 12183 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);
84 : break;
85 12 : case libsumo::VAR_DEPARTED_PERSONS_NUMBER:
86 12 : writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);
87 : break;
88 12 : case libsumo::VAR_DEPARTED_PERSONS_IDS:
89 12 : writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);
90 : break;
91 12 : case libsumo::VAR_ARRIVED_PERSONS_NUMBER:
92 12 : writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);
93 : break;
94 12 : case libsumo::VAR_ARRIVED_PERSONS_IDS:
95 12 : writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);
96 : break;
97 23 : case libsumo::VAR_PARKING_STARTING_VEHICLES_NUMBER:
98 23 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);
99 : break;
100 23 : case libsumo::VAR_PARKING_STARTING_VEHICLES_IDS:
101 23 : 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 23 : case libsumo::VAR_PARKING_ENDING_VEHICLES_NUMBER:
110 23 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);
111 : break;
112 23 : case libsumo::VAR_PARKING_ENDING_VEHICLES_IDS:
113 23 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);
114 : break;
115 23 : case libsumo::VAR_STOP_STARTING_VEHICLES_NUMBER:
116 23 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);
117 : break;
118 23 : case libsumo::VAR_STOP_STARTING_VEHICLES_IDS:
119 23 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);
120 : break;
121 23 : case libsumo::VAR_STOP_ENDING_VEHICLES_NUMBER:
122 23 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);
123 : break;
124 23 : case libsumo::VAR_STOP_ENDING_VEHICLES_IDS:
125 23 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);
126 : break;
127 64 : case libsumo::VAR_COLLIDING_VEHICLES_NUMBER:
128 64 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);
129 : break;
130 16 : case libsumo::VAR_COLLIDING_VEHICLES_IDS:
131 16 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);
132 : break;
133 64 : case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER:
134 64 : writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);
135 : break;
136 16 : case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_IDS:
137 16 : writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);
138 : break;
139 272 : case libsumo::VAR_COLLISIONS: {
140 272 : std::vector<libsumo::TraCICollision> collisions = libsumo::Simulation::getCollisions();
141 272 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);
142 272 : const int cnt = 1 + (int)collisions.size() * 4;
143 272 : server.getWrapperStorage().writeInt(cnt);
144 272 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_INTEGER);
145 272 : server.getWrapperStorage().writeInt((int)collisions.size());
146 292 : for (const auto& c : collisions) {
147 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
148 20 : server.getWrapperStorage().writeString(c.collider);
149 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
150 20 : server.getWrapperStorage().writeString(c.victim);
151 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
152 20 : server.getWrapperStorage().writeString(c.colliderType);
153 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
154 20 : server.getWrapperStorage().writeString(c.victimType);
155 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
156 20 : server.getWrapperStorage().writeDouble(c.colliderSpeed);
157 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
158 20 : server.getWrapperStorage().writeDouble(c.victimSpeed);
159 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
160 20 : server.getWrapperStorage().writeString(c.type);
161 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
162 20 : server.getWrapperStorage().writeString(c.lane);
163 20 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
164 20 : server.getWrapperStorage().writeDouble(c.pos);
165 : }
166 : break;
167 272 : }
168 4 : case libsumo::VAR_NET_BOUNDING_BOX: {
169 4 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_POLYGON);
170 4 : libsumo::TraCIPositionVector tb = libsumo::Simulation::getNetBoundary();
171 4 : server.getWrapperStorage().writeByte(2);
172 4 : server.getWrapperStorage().writeDouble(tb.value[0].x);
173 4 : server.getWrapperStorage().writeDouble(tb.value[0].y);
174 4 : server.getWrapperStorage().writeDouble(tb.value[1].x);
175 4 : server.getWrapperStorage().writeDouble(tb.value[1].y);
176 : break;
177 : }
178 333 : case libsumo::POSITION_CONVERSION: {
179 333 : 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 333 : const int compoundSize = inputStorage.readInt();
183 333 : 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 333 : if (!commandPositionConversion(server, inputStorage, compoundSize, server.getWrapperStorage(), libsumo::CMD_GET_SIM_VARIABLE)) {
187 : return false;
188 : }
189 : break;
190 : }
191 337 : case libsumo::DISTANCE_REQUEST:
192 337 : 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 337 : 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 337 : if (!commandDistanceRequest(server, inputStorage, server.getWrapperStorage(), libsumo::CMD_GET_SIM_VARIABLE)) {
199 : return false;
200 : }
201 : break;
202 11835 : case libsumo::FIND_ROUTE: {
203 11835 : 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 11835 : 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 11835 : 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 11835 : 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 11835 : 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 11835 : 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 11835 : 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 11835 : libsumo::StorageHelper::writeStage(server.getWrapperStorage(), libsumo::Simulation::findRoute(from, to, vtype, depart, routingMode));
228 : break;
229 : }
230 304 : case libsumo::FIND_INTERMODAL_ROUTE: {
231 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : 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 304 : if (!server.readTypeCheckingString(inputStorage, destStop)) {
277 8 : return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as thirteenth parameter.", outputStorage);
278 : }
279 304 : const std::vector<libsumo::TraCIStage>& result = libsumo::Simulation::findIntermodalRoute(from, to, modes, depart, routingMode, speed, walkFactor, departPos, arrivalPos, departPosLat, ptype, vtype, destStop);
280 296 : server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);
281 296 : server.getWrapperStorage().writeInt((int)result.size());
282 896 : for (const libsumo::TraCIStage& s : result) {
283 600 : libsumo::StorageHelper::writeStage(server.getWrapperStorage(), s);
284 : }
285 : break;
286 296 : }
287 6899298 : default:
288 6899298 : if (!libsumo::Simulation::handleVariable(id, variable, &server, &inputStorage)) {
289 2 : return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Get Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
290 : }
291 : }
292 32 : } catch (libsumo::TraCIException& e) {
293 32 : return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, e.what(), outputStorage);
294 32 : }
295 7021015 : server.writeStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, libsumo::RTYPE_OK, "", outputStorage);
296 7021015 : server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
297 : return true;
298 : }
299 :
300 :
301 : bool
302 239 : TraCIServerAPI_Simulation::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
303 : tcpip::Storage& outputStorage) {
304 239 : std::string warning = ""; // additional description for response
305 : // variable
306 239 : int variable = inputStorage.readUnsignedByte();
307 239 : if (variable != libsumo::CMD_CLEAR_PENDING_VEHICLES
308 : && variable != libsumo::CMD_SAVE_SIMSTATE
309 239 : && variable != libsumo::CMD_LOAD_SIMSTATE
310 239 : && variable != libsumo::VAR_PARAMETER
311 9 : && variable != libsumo::VAR_SCALE
312 9 : && 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 239 : std::string id = inputStorage.readString();
318 : // process
319 : try {
320 239 : switch (variable) {
321 4 : case libsumo::VAR_SCALE: {
322 : double value;
323 4 : 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 4 : if (value < 0.0) {
327 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Traffic scale may not be negative.", outputStorage);
328 : }
329 4 : libsumo::Simulation::setScale(value);
330 : }
331 4 : break;
332 : case libsumo::CMD_CLEAR_PENDING_VEHICLES: {
333 : //clear any pending vehicle insertions
334 : std::string route;
335 5 : 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 5 : libsumo::Simulation::clearPending(route);
339 : }
340 : break;
341 : case libsumo::CMD_SAVE_SIMSTATE: {
342 : //save current simulation state
343 : std::string file;
344 53 : 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 53 : libsumo::Simulation::saveState(file);
348 : }
349 : break;
350 : case libsumo::CMD_LOAD_SIMSTATE: {
351 : //quick-load simulation state
352 : std::string file;
353 164 : if (!server.readTypeCheckingString(inputStorage, file)) {
354 8 : return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for loading simulation state.", outputStorage);
355 : }
356 164 : double time = libsumo::Simulation::loadState(file);
357 156 : TraCIServer::getInstance()->stateLoaded(TIME2STEPS(time));
358 : }
359 : break;
360 : case libsumo::VAR_PARAMETER: {
361 8 : StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");
362 8 : const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");
363 12 : const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");
364 8 : libsumo::Simulation::setParameter(id, name, value);
365 : break;
366 : }
367 : case libsumo::CMD_MESSAGE: {
368 : std::string msg;
369 5 : 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 5 : libsumo::Simulation::writeMessage(msg);
373 : }
374 : break;
375 : default:
376 : break;
377 : }
378 12 : } catch (libsumo::TraCIException& e) {
379 12 : return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, e.what(), outputStorage);
380 12 : }
381 227 : server.writeStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
382 : return true;
383 : }
384 :
385 :
386 : void
387 49404 : TraCIServerAPI_Simulation::writeVehicleStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {
388 : const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;
389 49404 : outputStorage.writeUnsignedByte(libsumo::TYPE_INTEGER);
390 49404 : outputStorage.writeInt((int) ids.size());
391 49404 : }
392 :
393 :
394 : void
395 59218 : TraCIServerAPI_Simulation::writeVehicleStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {
396 59218 : const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;
397 59218 : outputStorage.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
398 59218 : outputStorage.writeStringList(ids);
399 59218 : }
400 :
401 :
402 : void
403 24 : TraCIServerAPI_Simulation::writeTransportableStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {
404 : const std::vector<std::string>& ids = server.getTransportableStateChanges().find(state)->second;
405 24 : outputStorage.writeUnsignedByte(libsumo::TYPE_INTEGER);
406 24 : outputStorage.writeInt((int)ids.size());
407 24 : }
408 :
409 :
410 : void
411 24 : TraCIServerAPI_Simulation::writeTransportableStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {
412 24 : const std::vector<std::string>& ids = server.getTransportableStateChanges().find(state)->second;
413 24 : outputStorage.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
414 24 : outputStorage.writeStringList(ids);
415 24 : }
416 :
417 :
418 : bool
419 333 : 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 333 : int srcPosType = inputStorage.readUnsignedByte();
429 :
430 333 : switch (srcPosType) {
431 135 : case libsumo::POSITION_2D:
432 : case libsumo::POSITION_3D:
433 : case libsumo::POSITION_LON_LAT:
434 : case libsumo::POSITION_LON_LAT_ALT: {
435 135 : const double x = inputStorage.readDouble();
436 135 : const double y = inputStorage.readDouble();
437 135 : 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 135 : if (srcPosType == libsumo::POSITION_LON_LAT || srcPosType == libsumo::POSITION_LON_LAT_ALT) {
443 17 : GeoConvHelper::getFinal().x2cartesian_const(cartesianPos);
444 : } else {
445 118 : GeoConvHelper::getFinal().cartesian2geo(geoPos);
446 : }
447 : }
448 : break;
449 198 : case libsumo::POSITION_ROADMAP: {
450 198 : const std::string roadID = inputStorage.readString();
451 198 : const double pos = inputStorage.readDouble();
452 198 : const int laneIdx = inputStorage.readUnsignedByte();
453 : try {
454 : // convert edge,offset,laneIdx to cartesian position
455 391 : cartesianPos = geoPos = libsumo::Helper::getLaneChecking(roadID, laneIdx, pos)->geometryPositionAtOffset(pos);
456 : z = cartesianPos.z();
457 193 : 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 328 : int destPosType = 0;
470 328 : 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 328 : if (compoundSize == 3) {
477 102 : inputStorage.readUnsignedByte();
478 102 : const std::string& vClassString = inputStorage.readString();
479 102 : if (!SumoVehicleClassStrings.hasString(vClassString)) {
480 0 : server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Unknown vehicle class '" + vClassString + "'.");
481 : return false;
482 : }
483 102 : vClass = SumoVehicleClassStrings.get(vClassString);
484 : }
485 :
486 328 : switch (destPosType) {
487 113 : case libsumo::POSITION_ROADMAP: {
488 : // convert cartesion position to edge,offset,lane_index
489 113 : roadPos = libsumo::Helper::convertCartesianToRoadMap(cartesianPos, vClass);
490 113 : 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 113 : outputStorage.writeUnsignedByte(libsumo::POSITION_ROADMAP);
496 113 : outputStorage.writeString(roadPos.first->getEdge().getID());
497 113 : outputStorage.writeDouble(roadPos.second);
498 113 : outputStorage.writeUnsignedByte(roadPos.first->getIndex());
499 : }
500 : break;
501 215 : case libsumo::POSITION_2D:
502 : case libsumo::POSITION_3D:
503 : case libsumo::POSITION_LON_LAT:
504 : case libsumo::POSITION_LON_LAT_ALT:
505 215 : outputStorage.writeUnsignedByte(destPosType);
506 215 : if (destPosType == libsumo::POSITION_LON_LAT || destPosType == libsumo::POSITION_LON_LAT_ALT) {
507 27 : outputStorage.writeDouble(geoPos.x());
508 27 : outputStorage.writeDouble(geoPos.y());
509 : } else {
510 188 : outputStorage.writeDouble(cartesianPos.x());
511 188 : outputStorage.writeDouble(cartesianPos.y());
512 : }
513 215 : if (destPosType != libsumo::POSITION_2D && destPosType != libsumo::POSITION_LON_LAT) {
514 13 : 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 337 : TraCIServerAPI_Simulation::commandDistanceRequest(TraCIServer& server, tcpip::Storage& inputStorage,
527 : tcpip::Storage& outputStorage, int commandId) {
528 : Position pos1;
529 : Position pos2;
530 337 : std::pair<const MSLane*, double> roadPos1;
531 337 : std::pair<const MSLane*, double> roadPos2;
532 :
533 : // read position 1
534 337 : int posType = inputStorage.readUnsignedByte();
535 337 : switch (posType) {
536 183 : case libsumo::POSITION_ROADMAP:
537 : try {
538 183 : std::string roadID = inputStorage.readString();
539 183 : roadPos1.second = inputStorage.readDouble();
540 183 : roadPos1.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos1.second);
541 183 : 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 183 : break;
547 150 : case libsumo::POSITION_2D:
548 : case libsumo::POSITION_3D: {
549 150 : double p1x = inputStorage.readDouble();
550 150 : double p1y = inputStorage.readDouble();
551 : pos1.set(p1x, p1y);
552 : }
553 150 : if (posType == libsumo::POSITION_3D) {
554 4 : inputStorage.readDouble();// z value is ignored
555 : }
556 150 : roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
557 150 : break;
558 4 : case libsumo::POSITION_LON_LAT:
559 : case libsumo::POSITION_LON_LAT_ALT: {
560 4 : double p1x = inputStorage.readDouble();
561 4 : double p1y = inputStorage.readDouble();
562 : pos1.set(p1x, p1y);
563 4 : GeoConvHelper::getFinal().x2cartesian_const(pos1);
564 : }
565 4 : if (posType == libsumo::POSITION_LON_LAT_ALT) {
566 0 : inputStorage.readDouble();// altitude value is ignored
567 : }
568 4 : roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
569 4 : 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 337 : posType = inputStorage.readUnsignedByte();
577 337 : switch (posType) {
578 183 : case libsumo::POSITION_ROADMAP:
579 : try {
580 183 : std::string roadID = inputStorage.readString();
581 183 : roadPos2.second = inputStorage.readDouble();
582 183 : roadPos2.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos2.second);
583 183 : 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 183 : break;
589 150 : case libsumo::POSITION_2D:
590 : case libsumo::POSITION_3D: {
591 150 : double p2x = inputStorage.readDouble();
592 150 : double p2y = inputStorage.readDouble();
593 : pos2.set(p2x, p2y);
594 : }
595 150 : if (posType == libsumo::POSITION_3D) {
596 4 : inputStorage.readDouble();// z value is ignored
597 : }
598 150 : roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
599 150 : break;
600 4 : case libsumo::POSITION_LON_LAT:
601 : case libsumo::POSITION_LON_LAT_ALT: {
602 4 : double p2x = inputStorage.readDouble();
603 4 : double p2y = inputStorage.readDouble();
604 : pos2.set(p2x, p2y);
605 4 : GeoConvHelper::getFinal().x2cartesian_const(pos2);
606 : }
607 4 : if (posType == libsumo::POSITION_LON_LAT_ALT) {
608 0 : inputStorage.readDouble();// altitude value is ignored
609 : }
610 4 : roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
611 4 : 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 337 : const int distType = inputStorage.readUnsignedByte();
619 :
620 : double distance = 0.0;
621 337 : if (distType == libsumo::REQUEST_DRIVINGDIST) {
622 183 : distance = libsumo::Helper::getDrivingDistance(roadPos1, roadPos2);
623 : } else {
624 : // compute air distance (default)
625 154 : distance = pos1.distanceTo(pos2);
626 : }
627 : // write response command
628 337 : outputStorage.writeUnsignedByte(libsumo::TYPE_DOUBLE);
629 337 : outputStorage.writeDouble(distance);
630 : return true;
631 : }
632 :
633 :
634 : /****************************************************************************/
|