1# -*- coding: utf-8 -*- 2# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3# Copyright (C) 2011-2019 German Aerospace Center (DLR) and others. 4# This program and the accompanying materials 5# are made available under the terms of the Eclipse Public License v2.0 6# which accompanies this distribution, and is available at 7# http://www.eclipse.org/legal/epl-v20.html 8# SPDX-License-Identifier: EPL-2.0 9 10# @file _vehicle.py 11# @author Michael Behrisch 12# @author Lena Kalleske 13# @author Mario Krumnow 14# @author Lena Kalleske 15# @author Jakob Erdmann 16# @author Laura Bieker 17# @author Daniel Krajzewicz 18# @author Leonhard Luecken 19# @date 2011-03-09 20# @version $Id$ 21 22from __future__ import absolute_import 23import struct 24import warnings 25from .domain import Domain 26from .storage import Storage 27from . import constants as tc 28from .exceptions import TraCIException 29 30 31def _readBestLanes(result): 32 result.read("!iB") 33 nbLanes = result.read("!i")[0] # Length 34 lanes = [] 35 for i in range(nbLanes): 36 result.read("!B") 37 laneID = result.readString() 38 length, occupation, offset = result.read("!BdBdBb")[1::2] 39 allowsContinuation = bool(result.read("!BB")[1]) 40 nextLanesNo = result.read("!Bi")[1] 41 nextLanes = [] 42 for j in range(nextLanesNo): 43 nextLanes.append(result.readString()) 44 lanes.append((laneID, length, occupation, offset, allowsContinuation, tuple(nextLanes))) 45 return tuple(lanes) 46 47 48def _readLeader(result): 49 result.read("!iB") 50 vehicleID = result.readString() 51 result.read("!B") 52 dist = result.readDouble() 53 if vehicleID: 54 return vehicleID, dist 55 return None 56 57 58def _readNeighbors(result): 59 """ result has structure: 60 byte(TYPE_COMPOUND) | length(neighList) | Per list entry: string(vehID) | double(dist) 61 """ 62 N = result.readInt() # length of the vehicle list 63 neighs = [] 64 for i in range(N): 65 vehID = result.readString() 66 dist = result.readDouble() 67 neighs.append((vehID, dist)) 68 return neighs 69 70 71def _readNextTLS(result): 72 result.read("!iB") # numCompounds, TYPE_INT 73 numTLS = result.read("!i")[0] 74 nextTLS = [] 75 for i in range(numTLS): 76 result.read("!B") 77 tlsID = result.readString() 78 tlsIndex, dist, state = result.read("!BiBdBB")[1::2] 79 nextTLS.append((tlsID, tlsIndex, dist, chr(state))) 80 return tuple(nextTLS) 81 82 83def _readNextStops(result): 84 result.read("!iB") # numCompounds, TYPE_INT 85 numStops = result.read("!i")[0] 86 nextStop = [] 87 for i in range(numStops): 88 result.read("!B") 89 lane = result.readString() 90 result.read("!B") 91 endPos = result.readDouble() 92 result.read("!B") 93 stoppingPlaceID = result.readString() 94 result.read("!B") 95 stopFlags = result.readInt() 96 result.read("!B") 97 duration = result.readDouble() 98 result.read("!B") 99 until = result.readDouble() 100 nextStop.append((lane, endPos, stoppingPlaceID, stopFlags, duration, until)) 101 return tuple(nextStop) 102 103 104_RETURN_VALUE_FUNC = {tc.VAR_SPEED: Storage.readDouble, 105 tc.VAR_SPEED_WITHOUT_TRACI: Storage.readDouble, 106 tc.VAR_ACCELERATION: Storage.readDouble, 107 tc.VAR_POSITION: lambda result: result.read("!dd"), 108 tc.VAR_POSITION3D: lambda result: result.read("!ddd"), 109 tc.VAR_ANGLE: Storage.readDouble, 110 tc.VAR_ROAD_ID: Storage.readString, 111 tc.VAR_LANE_ID: Storage.readString, 112 tc.VAR_LANE_INDEX: Storage.readInt, 113 tc.VAR_TYPE: Storage.readString, 114 tc.VAR_ROUTE_ID: Storage.readString, 115 tc.VAR_ROUTE_INDEX: Storage.readInt, 116 tc.VAR_COLOR: lambda result: result.read("!BBBB"), 117 tc.VAR_LANEPOSITION: Storage.readDouble, 118 tc.VAR_CO2EMISSION: Storage.readDouble, 119 tc.VAR_COEMISSION: Storage.readDouble, 120 tc.VAR_HCEMISSION: Storage.readDouble, 121 tc.VAR_PMXEMISSION: Storage.readDouble, 122 tc.VAR_NOXEMISSION: Storage.readDouble, 123 tc.VAR_FUELCONSUMPTION: Storage.readDouble, 124 tc.VAR_NOISEEMISSION: Storage.readDouble, 125 tc.VAR_ELECTRICITYCONSUMPTION: Storage.readDouble, 126 tc.VAR_PERSON_NUMBER: Storage.readInt, 127 tc.LAST_STEP_PERSON_ID_LIST: Storage.readStringList, 128 tc.VAR_EDGE_TRAVELTIME: Storage.readDouble, 129 tc.VAR_EDGE_EFFORT: Storage.readDouble, 130 tc.VAR_ROUTE_VALID: lambda result: bool(result.read("!i")[0]), 131 tc.VAR_EDGES: Storage.readStringList, 132 tc.VAR_SIGNALS: Storage.readInt, 133 tc.VAR_LENGTH: Storage.readDouble, 134 tc.VAR_MAXSPEED: Storage.readDouble, 135 tc.VAR_ALLOWED_SPEED: Storage.readDouble, 136 tc.VAR_VEHICLECLASS: Storage.readString, 137 tc.VAR_SPEED_FACTOR: Storage.readDouble, 138 tc.VAR_SPEED_DEVIATION: Storage.readDouble, 139 tc.VAR_EMISSIONCLASS: Storage.readString, 140 tc.VAR_WAITING_TIME: Storage.readDouble, 141 tc.VAR_ACCUMULATED_WAITING_TIME: Storage.readDouble, 142 tc.VAR_LANECHANGE_MODE: Storage.readInt, 143 tc.VAR_SPEEDSETMODE: Storage.readInt, 144 tc.VAR_SLOPE: Storage.readDouble, 145 tc.VAR_WIDTH: Storage.readDouble, 146 tc.VAR_HEIGHT: Storage.readDouble, 147 tc.VAR_LINE: Storage.readString, 148 tc.VAR_VIA: Storage.readStringList, 149 tc.VAR_MINGAP: Storage.readDouble, 150 tc.VAR_SHAPECLASS: Storage.readString, 151 tc.VAR_ACCEL: Storage.readDouble, 152 tc.VAR_DECEL: Storage.readDouble, 153 tc.VAR_EMERGENCY_DECEL: Storage.readDouble, 154 tc.VAR_APPARENT_DECEL: Storage.readDouble, 155 tc.VAR_ACTIONSTEPLENGTH: Storage.readDouble, 156 tc.VAR_LASTACTIONTIME: Storage.readDouble, 157 tc.VAR_IMPERFECTION: Storage.readDouble, 158 tc.VAR_TAU: Storage.readDouble, 159 tc.VAR_BEST_LANES: _readBestLanes, 160 tc.VAR_LEADER: _readLeader, 161 tc.VAR_NEIGHBORS: _readNeighbors, 162 tc.VAR_NEXT_TLS: _readNextTLS, 163 tc.VAR_NEXT_STOPS: _readNextStops, 164 tc.VAR_LANEPOSITION_LAT: Storage.readDouble, 165 tc.VAR_MAXSPEED_LAT: Storage.readDouble, 166 tc.VAR_MINGAP_LAT: Storage.readDouble, 167 tc.VAR_LATALIGNMENT: Storage.readString, 168 tc.DISTANCE_REQUEST: Storage.readDouble, 169 tc.VAR_ROUTING_MODE: Storage.readInt, 170 tc.VAR_STOPSTATE: Storage.readInt, 171 tc.VAR_DISTANCE: Storage.readDouble} 172 173 174class VehicleDomain(Domain): 175 # imported for backwards compatibility 176 STOP_DEFAULT = tc.STOP_DEFAULT 177 STOP_PARKING = tc.STOP_PARKING 178 STOP_TRIGGERED = tc.STOP_TRIGGERED 179 STOP_CONTAINER_TRIGGERED = tc.STOP_CONTAINER_TRIGGERED 180 STOP_BUS_STOP = tc.STOP_BUS_STOP 181 STOP_CONTAINER_STOP = tc.STOP_CONTAINER_STOP 182 STOP_CHARGING_STATION = tc.STOP_CHARGING_STATION 183 STOP_PARKING_AREA = tc.STOP_PARKING_AREA 184 DEPART_TRIGGERED = tc.DEPARTFLAG_TRIGGERED 185 DEPART_CONTAINER_TRIGGERED = tc.DEPARTFLAG_CONTAINER_TRIGGERED 186 DEPART_NOW = tc.DEPARTFLAG_NOW 187 DEPART_SPEED_RANDOM = tc.DEPARTFLAG_SPEED_RANDOM 188 DEPART_SPEED_MAX = tc.DEPARTFLAG_SPEED_MAX 189 DEPART_LANE_RANDOM = tc.DEPARTFLAG_LANE_RANDOM 190 DEPART_LANE_FREE = tc.DEPARTFLAG_LANE_FREE 191 DEPART_LANE_ALLOWED_FREE = tc.DEPARTFLAG_LANE_ALLOWED_FREE 192 DEPART_LANE_BEST_FREE = tc.DEPARTFLAG_LANE_BEST_FREE 193 DEPART_LANE_FIRST_ALLOWED = tc.DEPARTFLAG_LANE_FIRST_ALLOWED 194 195 def __init__(self): 196 Domain.__init__(self, "vehicle", tc.CMD_GET_VEHICLE_VARIABLE, tc.CMD_SET_VEHICLE_VARIABLE, 197 tc.CMD_SUBSCRIBE_VEHICLE_VARIABLE, tc.RESPONSE_SUBSCRIBE_VEHICLE_VARIABLE, 198 tc.CMD_SUBSCRIBE_VEHICLE_CONTEXT, tc.RESPONSE_SUBSCRIBE_VEHICLE_CONTEXT, 199 _RETURN_VALUE_FUNC) 200 201 def getSpeed(self, vehID): 202 """getSpeed(string) -> double 203 204 Returns the speed in m/s of the named vehicle within the last step. 205 """ 206 return self._getUniversal(tc.VAR_SPEED, vehID) 207 208 def getAcceleration(self, vehID): 209 """getAcceleration(string) -> double 210 211 Returns the acceleration in m/s^2 of the named vehicle within the last step. 212 """ 213 return self._getUniversal(tc.VAR_ACCELERATION, vehID) 214 215 def getSpeedWithoutTraCI(self, vehID): 216 """getSpeedWithoutTraCI(string) -> double 217 Returns the speed that the vehicle would drive if not speed-influencing 218 command such as setSpeed or slowDown was given. 219 """ 220 return self._getUniversal(tc.VAR_SPEED_WITHOUT_TRACI, vehID) 221 222 def getPosition(self, vehID): 223 """getPosition(string) -> (double, double) 224 225 Returns the position of the named vehicle within the last step [m,m]. 226 """ 227 return self._getUniversal(tc.VAR_POSITION, vehID) 228 229 def getPosition3D(self, vehID): 230 """getPosition3D(string) -> (double, double, double) 231 232 Returns the position of the named vehicle within the last step [m,m,m]. 233 """ 234 return self._getUniversal(tc.VAR_POSITION3D, vehID) 235 236 def getAngle(self, vehID): 237 """getAngle(string) -> double 238 239 Returns the angle in degrees of the named vehicle within the last step. 240 """ 241 return self._getUniversal(tc.VAR_ANGLE, vehID) 242 243 def getRoadID(self, vehID): 244 """getRoadID(string) -> string 245 246 Returns the id of the edge the named vehicle was at within the last step. 247 """ 248 return self._getUniversal(tc.VAR_ROAD_ID, vehID) 249 250 def getLaneID(self, vehID): 251 """getLaneID(string) -> string 252 253 Returns the id of the lane the named vehicle was at within the last step. 254 """ 255 return self._getUniversal(tc.VAR_LANE_ID, vehID) 256 257 def getLaneIndex(self, vehID): 258 """getLaneIndex(string) -> integer 259 260 Returns the index of the lane the named vehicle was at within the last step. 261 """ 262 return self._getUniversal(tc.VAR_LANE_INDEX, vehID) 263 264 def getTypeID(self, vehID): 265 """getTypeID(string) -> string 266 267 Returns the id of the type of the named vehicle. 268 """ 269 return self._getUniversal(tc.VAR_TYPE, vehID) 270 271 def getRouteID(self, vehID): 272 """getRouteID(string) -> string 273 274 Returns the id of the route of the named vehicle. 275 """ 276 return self._getUniversal(tc.VAR_ROUTE_ID, vehID) 277 278 def getRouteIndex(self, vehID): 279 """getRouteIndex(string) -> int 280 281 Returns the index of the current edge within the vehicles route or -1 if the 282 vehicle has not yet departed 283 """ 284 return self._getUniversal(tc.VAR_ROUTE_INDEX, vehID) 285 286 def getRoute(self, vehID): 287 """getRoute(string) -> list(string) 288 289 Returns the ids of the edges the vehicle's route is made of. 290 """ 291 return self._getUniversal(tc.VAR_EDGES, vehID) 292 293 def getLanePosition(self, vehID): 294 """getLanePosition(string) -> double 295 296 The position of the vehicle along the lane measured in m. 297 """ 298 return self._getUniversal(tc.VAR_LANEPOSITION, vehID) 299 300 def getColor(self, vehID): 301 """getColor(string) -> (integer, integer, integer, integer) 302 303 Returns the vehicle's rgba color. 304 """ 305 return self._getUniversal(tc.VAR_COLOR, vehID) 306 307 def getCO2Emission(self, vehID): 308 """getCO2Emission(string) -> double 309 310 Returns the CO2 emission in mg for the last time step. 311 """ 312 return self._getUniversal(tc.VAR_CO2EMISSION, vehID) 313 314 def getCOEmission(self, vehID): 315 """getCOEmission(string) -> double 316 317 Returns the CO emission in mg for the last time step. 318 """ 319 return self._getUniversal(tc.VAR_COEMISSION, vehID) 320 321 def getHCEmission(self, vehID): 322 """getHCEmission(string) -> double 323 324 Returns the HC emission in mg for the last time step. 325 """ 326 return self._getUniversal(tc.VAR_HCEMISSION, vehID) 327 328 def getPMxEmission(self, vehID): 329 """getPMxEmission(string) -> double 330 331 Returns the particular matter emission in mg for the last time step. 332 """ 333 return self._getUniversal(tc.VAR_PMXEMISSION, vehID) 334 335 def getNOxEmission(self, vehID): 336 """getNOxEmission(string) -> double 337 338 Returns the NOx emission in mg for the last time step. 339 """ 340 return self._getUniversal(tc.VAR_NOXEMISSION, vehID) 341 342 def getFuelConsumption(self, vehID): 343 """getFuelConsumption(string) -> double 344 345 Returns the fuel consumption in ml for the last time step. 346 """ 347 return self._getUniversal(tc.VAR_FUELCONSUMPTION, vehID) 348 349 def getNoiseEmission(self, vehID): 350 """getNoiseEmission(string) -> double 351 352 Returns the noise emission in db for the last time step. 353 """ 354 return self._getUniversal(tc.VAR_NOISEEMISSION, vehID) 355 356 def getElectricityConsumption(self, vehID): 357 """getElectricityConsumption(string) -> double 358 359 Returns the electricity consumption in Wh for the last time step. 360 """ 361 return self._getUniversal(tc.VAR_ELECTRICITYCONSUMPTION, vehID) 362 363 def getPersonNumber(self, vehID): 364 """getPersonNumber(string) -> integer 365 Returns the total number of persons which includes those defined 366 using attribute 'personNumber' as well as <person>-objects which are riding in 367 this vehicle. 368 """ 369 return self._getUniversal(tc.VAR_PERSON_NUMBER, vehID) 370 371 def getPersonIDList(self, vehID): 372 """getPersonIDList(string) -> integer 373 Returns the list of persons which includes those defined using attribute 'personNumber' 374 as well as <person>-objects which are riding in this vehicle. 375 """ 376 return self._getUniversal(tc.LAST_STEP_PERSON_ID_LIST, vehID) 377 378 def getAdaptedTraveltime(self, vehID, time, edgeID): 379 """getAdaptedTraveltime(string, double, string) -> double 380 381 . 382 """ 383 self._connection._beginMessage(tc.CMD_GET_VEHICLE_VARIABLE, 384 tc.VAR_EDGE_TRAVELTIME, vehID, 1 + 4 + 1 + 8 + 1 + 4 + len(edgeID)) 385 self._connection._string += struct.pack( 386 "!BiBd", tc.TYPE_COMPOUND, 2, tc.TYPE_DOUBLE, time) 387 self._connection._packString(edgeID) 388 return self._connection._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_EDGE_TRAVELTIME, vehID).readDouble() 389 390 def getEffort(self, vehID, time, edgeID): 391 """getEffort(string, double, string) -> double 392 393 . 394 """ 395 self._connection._beginMessage(tc.CMD_GET_VEHICLE_VARIABLE, 396 tc.VAR_EDGE_EFFORT, vehID, 1 + 4 + 1 + 8 + 1 + 4 + len(edgeID)) 397 self._connection._string += struct.pack( 398 "!BiBd", tc.TYPE_COMPOUND, 2, tc.TYPE_DOUBLE, time) 399 self._connection._packString(edgeID) 400 return self._connection._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_EDGE_EFFORT, vehID).readDouble() 401 402 def isRouteValid(self, vehID): 403 """isRouteValid(string) -> bool 404 Returns whether the current vehicle route is connected for the vehicle 405 class of the given vehicle. 406 """ 407 return self._getUniversal(tc.VAR_ROUTE_VALID, vehID) 408 409 def getSignals(self, vehID): 410 """getSignals(string) -> integer 411 412 Returns an integer encoding the state of a vehicle's signals. 413 """ 414 return self._getUniversal(tc.VAR_SIGNALS, vehID) 415 416 def getLength(self, vehID): 417 """getLength(string) -> double 418 419 Returns the length in m of the given vehicle. 420 """ 421 return self._getUniversal(tc.VAR_LENGTH, vehID) 422 423 def getMaxSpeed(self, vehID): 424 """getMaxSpeed(string) -> double 425 426 Returns the maximum speed in m/s of this vehicle. 427 """ 428 return self._getUniversal(tc.VAR_MAXSPEED, vehID) 429 430 def getLateralLanePosition(self, vehID): 431 """getLateralLanePosition(string) -> double 432 433 Returns The lateral position of the vehicle on its current lane measured in m. 434 """ 435 return self._getUniversal(tc.VAR_LANEPOSITION_LAT, vehID) 436 437 def getMaxSpeedLat(self, vehID): 438 """getMaxSpeedLat(string) -> double 439 440 Returns the maximum lateral speed in m/s of this vehicle. 441 """ 442 return self._getUniversal(tc.VAR_MAXSPEED_LAT, vehID) 443 444 def getLateralAlignment(self, vehID): 445 """getLateralAlignment(string) -> string 446 447 Returns The preferred lateral alignment of the vehicle 448 """ 449 return self._getUniversal(tc.VAR_LATALIGNMENT, vehID) 450 451 def getMinGapLat(self, vehID): 452 """getMinGapLat(string) -> double 453 454 Returns The desired lateral gap of this vehicle at 50km/h in m 455 """ 456 return self._getUniversal(tc.VAR_MINGAP_LAT, vehID) 457 458 def getAllowedSpeed(self, vehID): 459 """getAllowedSpeed(string) -> double 460 461 Returns the maximum allowed speed on the current lane regarding speed factor in m/s for this vehicle. 462 """ 463 return self._getUniversal(tc.VAR_ALLOWED_SPEED, vehID) 464 465 def getVehicleClass(self, vehID): 466 """getVehicleClass(string) -> string 467 468 Returns the vehicle class of this vehicle. 469 """ 470 return self._getUniversal(tc.VAR_VEHICLECLASS, vehID) 471 472 def getSpeedFactor(self, vehID): 473 """getSpeedFactor(string) -> double 474 475 Returns the chosen speed factor for this vehicle. 476 """ 477 return self._getUniversal(tc.VAR_SPEED_FACTOR, vehID) 478 479 def getSpeedDeviation(self, vehID): 480 """getSpeedDeviation(string) -> double 481 482 Returns the standard deviation for the speed factor of the vehicle type. 483 """ 484 return self._getUniversal(tc.VAR_SPEED_DEVIATION, vehID) 485 486 def getEmissionClass(self, vehID): 487 """getEmissionClass(string) -> string 488 489 Returns the emission class of this vehicle. 490 """ 491 return self._getUniversal(tc.VAR_EMISSIONCLASS, vehID) 492 493 def getWaitingTime(self, vehID): 494 """getWaitingTime() -> double 495 The waiting time of a vehicle is defined as the time (in seconds) spent with a 496 speed below 0.1m/s since the last time it was faster than 0.1m/s. 497 (basically, the waiting time of a vehicle is reset to 0 every time it moves). 498 A vehicle that is stopping intentionally with a <stop> does not accumulate waiting time. 499 """ 500 return self._getUniversal(tc.VAR_WAITING_TIME, vehID) 501 502 def getAccumulatedWaitingTime(self, vehID): 503 """getAccumulatedWaitingTime() -> double 504 The accumulated waiting time of a vehicle collects the vehicle's waiting time 505 over a certain time interval (interval length is set per option '--waiting-time-memory') 506 """ 507 return self._getUniversal(tc.VAR_ACCUMULATED_WAITING_TIME, vehID) 508 509 def getLaneChangeMode(self, vehID): 510 """getLaneChangeMode(string) -> integer 511 512 Gets the vehicle's lane change mode as a bitset. 513 """ 514 return self._getUniversal(tc.VAR_LANECHANGE_MODE, vehID) 515 516 def getSpeedMode(self, vehID): 517 """getSpeedMode -> int 518 The speed mode of a vehicle 519 """ 520 return self._getUniversal(tc.VAR_SPEEDSETMODE, vehID) 521 522 def getSlope(self, vehID): 523 """getSlope -> double 524 The slope at the current position of the vehicle in degrees 525 """ 526 return self._getUniversal(tc.VAR_SLOPE, vehID) 527 528 def getWidth(self, vehID): 529 """getWidth(string) -> double 530 531 Returns the width in m of this vehicle. 532 """ 533 return self._getUniversal(tc.VAR_WIDTH, vehID) 534 535 def getHeight(self, vehID): 536 """getHeight(string) -> double 537 538 Returns the height in m of this vehicle. 539 """ 540 return self._getUniversal(tc.VAR_HEIGHT, vehID) 541 542 def getLine(self, vehID): 543 """getLine(string) -> string 544 545 Returns the line information of this vehicle. 546 """ 547 return self._getUniversal(tc.VAR_LINE, vehID) 548 549 def getVia(self, vehID): 550 """getVia(string) -> list(string) 551 552 Returns the ids of via edges for this vehicle 553 """ 554 return self._getUniversal(tc.VAR_VIA, vehID) 555 556 def getMinGap(self, vehID): 557 """getMinGap(string) -> double 558 559 Returns the offset (gap to front vehicle if halting) of this vehicle. 560 """ 561 return self._getUniversal(tc.VAR_MINGAP, vehID) 562 563 def getShapeClass(self, vehID): 564 """getShapeClass(string) -> string 565 566 Returns the shape class of this vehicle. 567 """ 568 return self._getUniversal(tc.VAR_SHAPECLASS, vehID) 569 570 def getAccel(self, vehID): 571 """getAccel(string) -> double 572 573 Returns the maximum acceleration possibility in m/s^2 of this vehicle. 574 """ 575 return self._getUniversal(tc.VAR_ACCEL, vehID) 576 577 def getDecel(self, vehID): 578 """getDecel(string) -> double 579 580 Returns the preferred maximal deceleration possibility in m/s^2 of this vehicle. 581 """ 582 return self._getUniversal(tc.VAR_DECEL, vehID) 583 584 def getEmergencyDecel(self, vehID): 585 """getEmergencyDecel(string) -> double 586 587 Returns the maximal physically possible deceleration in m/s^2 of this vehicle. 588 """ 589 return self._getUniversal(tc.VAR_EMERGENCY_DECEL, vehID) 590 591 def getApparentDecel(self, vehID): 592 """getApparentDecel(string) -> double 593 594 Returns the apparent deceleration in m/s^2 of this vehicle. 595 """ 596 return self._getUniversal(tc.VAR_APPARENT_DECEL, vehID) 597 598 def getActionStepLength(self, vehID): 599 """getActionStepLength(string) -> double 600 601 Returns the action step length for this vehicle. 602 """ 603 return self._getUniversal(tc.VAR_ACTIONSTEPLENGTH, vehID) 604 605 def getLastActionTime(self, vehID): 606 """getLastActionTime(string) -> double 607 608 Returns the time of last action point for this vehicle. 609 """ 610 return self._getUniversal(tc.VAR_LASTACTIONTIME, vehID) 611 612 def getImperfection(self, vehID): 613 """getImperfection(string) -> double 614 615 . 616 """ 617 return self._getUniversal(tc.VAR_IMPERFECTION, vehID) 618 619 def getTau(self, vehID): 620 """getTau(string) -> double 621 622 Returns the driver's reaction time in s for this vehicle. 623 """ 624 return self._getUniversal(tc.VAR_TAU, vehID) 625 626 def getBestLanes(self, vehID): 627 """getBestLanes(string) -> 628 629 Information about the wish to use subsequent edges' lanes. 630 """ 631 return self._getUniversal(tc.VAR_BEST_LANES, vehID) 632 633 def getLeader(self, vehID, dist=0.): 634 """getLeader(string, double) -> (string, double) 635 636 Return the leading vehicle id together with the distance. The distance 637 is measured from the front + minGap to the back of the leader, so it does not include the 638 minGap of the vehicle. 639 The dist parameter defines the maximum lookahead, 0 calculates a lookahead from the brake gap. 640 Note that the returned leader may be farther away than the given dist. 641 """ 642 self._connection._beginMessage( 643 tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_LEADER, vehID, 1 + 8) 644 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, dist) 645 return _readLeader(self._connection._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_LEADER, vehID)) 646 647 def getRightFollowers(self, vehID, blockingOnly=False): 648 """ bool -> list(pair(string, double)) 649 Convenience method, see getNeighbors() 650 """ 651 if blockingOnly: 652 mode = 5 653 else: 654 mode = 1 655 return self.getNeighbors(vehID, mode) 656 657 def getRightLeaders(self, vehID, blockingOnly=False): 658 """ bool -> list(pair(string, double)) 659 Convenience method, see getNeighbors() 660 """ 661 if blockingOnly: 662 mode = 7 663 else: 664 mode = 3 665 return self.getNeighbors(vehID, mode) 666 667 def getLeftFollowers(self, vehID, blockingOnly=False): 668 """ bool -> list(pair(string, double)) 669 Convenience method, see getNeighbors() 670 """ 671 if blockingOnly: 672 mode = 4 673 else: 674 mode = 0 675 return self.getNeighbors(vehID, mode) 676 677 def getLeftLeaders(self, vehID, blockingOnly=False): 678 """ bool -> list(pair(string, double)) 679 Convenience method, see getNeighbors() 680 """ 681 if blockingOnly: 682 mode = 6 683 else: 684 mode = 2 685 return self.getNeighbors(vehID, mode) 686 687 def getNeighbors(self, vehID, mode): 688 """ byte -> list(pair(string, double)) 689 690 The parameter mode is a bitset (UBYTE), specifying the following: 691 bit 1: query lateral direction (left:0, right:1) 692 bit 2: query longitudinal direction (followers:0, leaders:1) 693 bit 3: blocking (return all:0, return only blockers:1) 694 695 The returned list contains pairs (ID, dist) for all lane change relevant neighboring leaders, resp. followers, 696 along with their longitudinal distance to the ego vehicle (egoFront - egoMinGap to leaderBack, resp. 697 followerFront - followerMinGap to egoBack. The value can be negative for overlapping neighs). 698 For the non-sublane case, the lists will contain at most one entry. 699 700 Note: The exact set of blockers in case blocking==1 is not determined for the sublane model, 701 but either all neighboring vehicles are returned (in case LCA_BLOCKED) or 702 none is returned (in case !LCA_BLOCKED). 703 """ 704 self._connection._beginMessage(tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_NEIGHBORS, vehID, 2) 705 self._connection._string += struct.pack("!BB", tc.TYPE_UBYTE, mode) 706 return _readNeighbors(self._connection._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.VAR_NEIGHBORS, vehID)) 707 708 def getNextTLS(self, vehID): 709 """getNextTLS(string) -> 710 711 Return list of upcoming traffic lights [(tlsID, tlsIndex, distance, state), ...] 712 """ 713 return self._getUniversal(tc.VAR_NEXT_TLS, vehID) 714 715 def getNextStops(self, vehID): 716 """getNextStop(string) -> [(string, double, string, int, int, int)], ... 717 718 Return list of upcoming stops [(lane, endPos, stoppingPlaceID, stopFlags, duration, until), ...] 719 where integer stopFlag is defined as: 720 1 * stopped + 721 2 * parking + 722 4 * personTriggered + 723 8 * containerTriggered + 724 16 * isBusStop + 725 32 * isContainerStop + 726 64 * chargingStation + 727 128 * parkingarea 728 with each of these flags defined as 0 or 1. 729 """ 730 return self._getUniversal(tc.VAR_NEXT_STOPS, vehID) 731 732 def subscribeLeader(self, vehID, dist=0., begin=0, end=2**31 - 1): 733 """subscribeLeader(string, double) -> None 734 735 Subscribe for the leading vehicle id together with the distance. 736 The dist parameter defines the maximum lookahead, 0 calculates a lookahead from the brake gap. 737 """ 738 self._connection._subscribe(tc.CMD_SUBSCRIBE_VEHICLE_VARIABLE, begin, end, vehID, 739 (tc.VAR_LEADER,), {tc.VAR_LEADER: struct.pack("!Bd", tc.TYPE_DOUBLE, dist)}) 740 741 def getDrivingDistance(self, vehID, edgeID, pos, laneIndex=0): 742 """getDrivingDistance(string, string, double, integer) -> double 743 744 Return the distance to the given edge and position along the vehicles route. 745 """ 746 self._connection._beginMessage(tc.CMD_GET_VEHICLE_VARIABLE, tc.DISTANCE_REQUEST, 747 vehID, 1 + 4 + 1 + 4 + len(edgeID) + 8 + 1 + 1) 748 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 2) 749 self._connection._packString(edgeID, tc.POSITION_ROADMAP) 750 self._connection._string += struct.pack("!dBB", 751 pos, laneIndex, tc.REQUEST_DRIVINGDIST) 752 return self._connection._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.DISTANCE_REQUEST, vehID).readDouble() 753 754 def getDrivingDistance2D(self, vehID, x, y): 755 """getDrivingDistance2D(string, double, double) -> integer 756 757 Return the distance to the given network position along the vehicles route. 758 """ 759 self._connection._beginMessage( 760 tc.CMD_GET_VEHICLE_VARIABLE, tc.DISTANCE_REQUEST, vehID, 1 + 4 + 1 + 8 + 8 + 1) 761 self._connection._string += struct.pack("!BiBddB", tc.TYPE_COMPOUND, 2, 762 tc.POSITION_2D, x, y, tc.REQUEST_DRIVINGDIST) 763 return self._connection._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.DISTANCE_REQUEST, vehID).readDouble() 764 765 def getDistance(self, vehID): 766 """getDistance(string) -> double 767 768 Returns the distance to the starting point like an odometer 769 """ 770 return self._getUniversal(tc.VAR_DISTANCE, vehID) 771 772 def getStopState(self, vehID): 773 """getStopState(string) -> integer 774 775 Returns information in regard to stopping: 776 The returned integer is defined as 1 * stopped + 2 * parking 777 + 4 * personTriggered + 8 * containerTriggered + 16 * isBusStop 778 + 32 * isContainerStop 779 with each of these flags defined as 0 or 1 780 """ 781 return self._getUniversal(tc.VAR_STOPSTATE, vehID) 782 783 def isStopped(self, vehID): 784 """isStopped(string) -> bool 785 Return whether the vehicle is stopped 786 """ 787 return (self.getStopState(vehID) & 1) == 1 788 789 def isStoppedParking(self, vehID): 790 """isStoppedParking(string) -> bool 791 Return whether the vehicle is parking (implies stopped) 792 """ 793 return (self.getStopState(vehID) & 2) == 2 794 795 def isStoppedTriggered(self, vehID): 796 """isStoppedTriggered(string) -> bool 797 Return whether the vehicle is stopped and waiting for a person or container 798 """ 799 return (self.getStopState(vehID) & 12) > 0 800 801 def isAtBusStop(self, vehID): 802 """isAtBusStop(string) -> bool 803 Return whether the vehicle is stopped at a bus stop 804 """ 805 return (self.getStopState(vehID) & 16) == 16 806 807 def isAtContainerStop(self, vehID): 808 """isAtContainerStop(string) -> bool 809 Return whether the vehicle is stopped at a container stop 810 """ 811 return (self.getStopState(vehID) & 32) == 32 812 813 def getLaneChangeState(self, vehID, direction): 814 """getLaneChangeState(string, int) -> (int, int) 815 Return the lane change state for the vehicle 816 """ 817 self._connection._beginMessage( 818 tc.CMD_GET_VEHICLE_VARIABLE, tc.CMD_CHANGELANE, vehID, 1 + 4) 819 self._connection._string += struct.pack("!Bi", tc.TYPE_INTEGER, direction) 820 result = self._connection._checkResult(tc.CMD_GET_VEHICLE_VARIABLE, tc.CMD_CHANGELANE, vehID) 821 return result.read("!iBiBi")[2::2] # ignore num compounds and type int 822 823 def getLaneChangeStatePretty(self, vehID, direction): 824 """getLaneChangeState(string, int) -> ([string, ...], [string, ...]) 825 Return the lane change state for the vehicle as a list of string constants 826 """ 827 constants = { 828 0: 'stay', 829 1: 'left', 830 2: 'right', 831 3: 'strategic', 832 4: 'cooperative', 833 5: 'speedGain', 834 6: 'keepRight', 835 7: 'TraCI', 836 8: 'urgent', 837 9: 'blocked by left leader', 838 10: 'blocked by left follower', 839 11: 'blocked by right leader', 840 12: 'bloecked by right follower', 841 13: 'overlapping', 842 14: 'insufficient space', 843 15: 'sublane', 844 } 845 846 def prettifyBitstring(intval): 847 return [v for k, v in constants.items() if (intval & 2**k)] 848 849 state, stateTraCI = self.getLaneChangeState(vehID, direction) 850 return prettifyBitstring(state), prettifyBitstring(stateTraCI) 851 852 def couldChangeLane(self, vehID, direction, state=None): 853 """couldChangeLane(string, int) -> bool 854 Return whether the vehicle could change lanes in the specified direction 855 """ 856 if state is None: 857 state, stateTraCI = self.getLaneChangeState(vehID, direction) 858 if self.wantsAndCouldChangeLane(vehID, direction, stateTraCI): 859 # vehicle changed in the last step. state is no longer applicable 860 return False 861 return state != tc.LCA_UNKNOWN and (state & tc.LCA_BLOCKED == 0) 862 863 def wantsAndCouldChangeLane(self, vehID, direction, state=None): 864 """wantsAndCouldChangeLane(string, int) -> bool 865 Return whether the vehicle wants to and could change lanes in the specified direction 866 """ 867 if state is None: 868 state, stateTraCI = self.getLaneChangeState(vehID, direction) 869 if self.wantsAndCouldChangeLane(vehID, direction, stateTraCI): 870 # vehicle changed in the last step. state is no longer applicable 871 return False 872 if state & tc.LCA_BLOCKED == 0: 873 if direction == -1: 874 return state & tc.LCA_RIGHT != 0 875 if direction == 1: 876 return state & tc.LCA_LEFT != 0 877 return False 878 879 def getRoutingMode(self, vehID): 880 """returns the current routing mode: 881 tc.ROUTING_MODE_DEFAULT : use weight storages and fall-back to edge speeds (default) 882 tc.ROUTING_MODE_AGGREGATED : use global smoothed travel times from device.rerouting 883 """ 884 return self._getUniversal(tc.VAR_ROUTING_MODE, vehID) 885 886 def setMaxSpeed(self, vehID, speed): 887 """setMaxSpeed(string, double) -> None 888 889 Sets the maximum speed in m/s for this vehicle. 890 """ 891 self._connection._sendDoubleCmd( 892 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_MAXSPEED, vehID, speed) 893 894 def setMaxSpeedLat(self, vehID, speed): 895 """setMaxSpeedLat(string, double) -> None 896 897 Sets the maximum lateral speed in m/s for this vehicle. 898 """ 899 self._connection._sendDoubleCmd( 900 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_MAXSPEED_LAT, vehID, speed) 901 902 def rerouteParkingArea(self, vehID, parkingAreaID): 903 """rerouteParkingArea(string, string) 904 905 Changes the next parking area in parkingAreaID, updates the vehicle route, 906 and preserve consistency in case of passengers/containers on board. 907 """ 908 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_REROUTE_TO_PARKING, vehID, 909 1 + 4 + # compound 910 1 + 4 + len(parkingAreaID)) 911 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 1) 912 self._connection._packString(parkingAreaID) 913 self._connection._sendExact() 914 915 def setStop(self, vehID, edgeID, pos=1., laneIndex=0, duration=tc.INVALID_DOUBLE_VALUE, 916 flags=tc.STOP_DEFAULT, startPos=tc.INVALID_DOUBLE_VALUE, until=tc.INVALID_DOUBLE_VALUE): 917 """setStop(string, string, double, integer, double, integer, double, double) -> None 918 919 Adds or modifies a stop with the given parameters. The duration and the until attribute are 920 in seconds. 921 """ 922 if type(duration) is int and duration >= 1000 and duration % 1000 == 0: 923 warnings.warn("API change now handles duration as floating point seconds", stacklevel=2) 924 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_STOP, 925 vehID, (1 + 4 + 1 + 4 + len(edgeID) + 1 + 8 + 1 + 1 + 926 1 + 8 + 1 + 1 + 1 + 8 + 1 + 8)) 927 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 7) 928 self._connection._packString(edgeID) 929 self._connection._string += struct.pack("!BdBBBdBB", tc.TYPE_DOUBLE, pos, 930 tc.TYPE_BYTE, laneIndex, tc.TYPE_DOUBLE, duration, tc.TYPE_BYTE, flags) 931 self._connection._string += struct.pack("!BdBd", 932 tc.TYPE_DOUBLE, startPos, tc.TYPE_DOUBLE, until) 933 self._connection._sendExact() 934 935 def setBusStop(self, vehID, stopID, duration=tc.INVALID_DOUBLE_VALUE, 936 until=tc.INVALID_DOUBLE_VALUE, flags=tc.STOP_DEFAULT): 937 """setBusStop(string, string, double, double, integer) -> None 938 939 Adds or modifies a bus stop with the given parameters. The duration and the until attribute are 940 in seconds. 941 """ 942 self.setStop(vehID, stopID, duration=duration, 943 until=until, flags=flags | tc.STOP_BUS_STOP) 944 945 def setContainerStop(self, vehID, stopID, duration=tc.INVALID_DOUBLE_VALUE, 946 until=tc.INVALID_DOUBLE_VALUE, flags=tc.STOP_DEFAULT): 947 """setContainerStop(string, string, double, double, integer) -> None 948 949 Adds or modifies a container stop with the given parameters. The duration and the until attribute are 950 in seconds. 951 """ 952 self.setStop(vehID, stopID, duration=duration, until=until, 953 flags=flags | tc.STOP_CONTAINER_STOP) 954 955 def setChargingStationStop(self, vehID, stopID, duration=tc.INVALID_DOUBLE_VALUE, 956 until=tc.INVALID_DOUBLE_VALUE, flags=tc.STOP_DEFAULT): 957 """setChargingStationStop(string, string, double, double, integer) -> None 958 959 Adds or modifies a stop at a chargingStation with the given parameters. The duration and the until attribute are 960 in seconds. 961 """ 962 self.setStop(vehID, stopID, duration=duration, until=until, 963 flags=flags | tc.STOP_CHARGING_STATION) 964 965 def setParkingAreaStop(self, vehID, stopID, duration=tc.INVALID_DOUBLE_VALUE, 966 until=tc.INVALID_DOUBLE_VALUE, flags=tc.STOP_PARKING): 967 """setParkingAreaStop(string, string, double, double, integer) -> None 968 969 Adds or modifies a stop at a parkingArea with the given parameters. The duration and the until attribute are 970 in seconds. 971 """ 972 self.setStop(vehID, stopID, duration=duration, until=until, 973 flags=flags | tc.STOP_PARKING_AREA) 974 975 def resume(self, vehID): 976 """resume(string) -> None 977 978 Resumes the vehicle from the current stop (throws an error if the vehicle is not stopped). 979 """ 980 self._connection._beginMessage( 981 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_RESUME, vehID, 1 + 4) 982 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 0) 983 self._connection._sendExact() 984 985 def changeLane(self, vehID, laneIndex, duration): 986 """changeLane(string, int, double) -> None 987 988 Forces a lane change to the lane with the given index; if successful, 989 the lane will be chosen for the given amount of time (in s). 990 """ 991 if type(duration) is int and duration >= 1000: 992 warnings.warn("API change now handles duration as floating point seconds", stacklevel=2) 993 self._connection._beginMessage( 994 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_CHANGELANE, vehID, 1 + 4 + 1 + 1 + 1 + 8) 995 self._connection._string += struct.pack( 996 "!BiBBBd", tc.TYPE_COMPOUND, 2, tc.TYPE_BYTE, laneIndex, tc.TYPE_DOUBLE, duration) 997 self._connection._sendExact() 998 999 def changeLaneRelative(self, vehID, indexOffset, duration): 1000 """changeLaneRelative(string, int, double) -> None 1001 1002 Forces a relative lane change; if successful, 1003 the lane will be chosen for the given amount of time (in s). 1004 The indexOffset specifies the target lane relative to the vehicles current lane 1005 """ 1006 if type(duration) is int and duration >= 1000: 1007 warnings.warn("API change now handles duration as floating point seconds", stacklevel=2) 1008 self._connection._beginMessage( 1009 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_CHANGELANE, vehID, 1 + 4 + 1 + 1 + 1 + 8 + 1 + 1) 1010 self._connection._string += struct.pack( 1011 "!BiBBBdBB", tc.TYPE_COMPOUND, 3, tc.TYPE_BYTE, indexOffset, tc.TYPE_DOUBLE, duration, tc.TYPE_BYTE, 1) 1012 self._connection._sendExact() 1013 1014 def changeSublane(self, vehID, latDist): 1015 """changeLane(string, double) -> None 1016 Forces a lateral change by the given amount (negative values indicate changing to the right, positive 1017 to the left). This will override any other lane change motivations but conform to 1018 safety-constraints as configured by laneChangeMode. 1019 """ 1020 self._connection._sendDoubleCmd( 1021 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_CHANGESUBLANE, vehID, latDist) 1022 1023 def slowDown(self, vehID, speed, duration): 1024 """slowDown(string, double, double) -> None 1025 1026 Changes the speed smoothly to the given value over the given amount 1027 of time in seconds (can also be used to increase speed). 1028 """ 1029 if type(duration) is int and duration >= 1000: 1030 warnings.warn("API change now handles duration as floating point seconds", stacklevel=2) 1031 self._connection._beginMessage( 1032 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_SLOWDOWN, vehID, 1 + 4 + 1 + 8 + 1 + 8) 1033 self._connection._string += struct.pack( 1034 "!BiBdBd", tc.TYPE_COMPOUND, 2, tc.TYPE_DOUBLE, speed, tc.TYPE_DOUBLE, duration) 1035 self._connection._sendExact() 1036 1037 def openGap(self, vehID, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel=-1, referenceVehID=None): 1038 """openGap(string, double, double, double, double, double, string) -> None 1039 1040 Changes the vehicle's desired time headway (cf-parameter tau) smoothly to the given new value 1041 using the given change rate. Similarly, the given space headway is applied gradually 1042 to achieve a minimal spatial gap. 1043 The vehicle is commanded to keep the increased headway for 1044 the given duration once its target value is attained. The maximal value for the 1045 deceleration can be given to prevent harsh braking due to the change of tau. If maxDecel=-1, 1046 the limit determined by the CF model is used. 1047 A vehicle ID for a reference vehicle can optionally be given, otherwise, the gap is created with 1048 respect to the current leader on the ego vehicle's current lane. 1049 Note that this does only affect the following behavior regarding the current leader and does 1050 not influence the gap acceptance during lane change, etc. 1051 """ 1052 if type(duration) is int and duration >= 1000: 1053 warnings.warn("API change now handles duration as floating point seconds", stacklevel=2) 1054 nParams = 5 1055 # compoundType, nParams, float params (2 newHeadways, duration, changeRate, maxDecel) 1056 msgLength = 1 + 4 + (1 + 8) * nParams 1057 if referenceVehID is not None: 1058 nParams = 6 1059 msgLength += 1 + 4 + len(referenceVehID) # TYPE_STRING, len, referenceVehID 1060 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_OPENGAP, vehID, msgLength) 1061 self._connection._string += struct.pack("!BiBdBdBdBdBd", tc.TYPE_COMPOUND, nParams, 1062 tc.TYPE_DOUBLE, newTimeHeadway, tc.TYPE_DOUBLE, newSpaceHeadway, 1063 tc.TYPE_DOUBLE, duration, tc.TYPE_DOUBLE, changeRate, 1064 tc.TYPE_DOUBLE, maxDecel) 1065 if nParams == 6: 1066 self._connection._packString(referenceVehID) 1067 self._connection._sendExact() 1068 1069 def deactivateGapControl(self, vehID): 1070 """deactivateGapControl(string) -> None 1071 1072 Deactivate the vehicle's gap control 1073 """ 1074 self.openGap(vehID, -1, -1, -1, -1) 1075 1076 def requestToC(self, vehID, leadTime): 1077 """ requestToC(string, double) -> None 1078 1079 Interface for triggering a transition of control for a vehicle equipped with a ToC device. 1080 """ 1081 self.setParameter(vehID, "device.toc.requestToC", str(leadTime)) 1082 1083 def changeTarget(self, vehID, edgeID): 1084 """changeTarget(string, string) -> None 1085 1086 The vehicle's destination edge is set to the given edge id. The route is rebuilt. 1087 """ 1088 self._connection._sendStringCmd( 1089 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_CHANGETARGET, vehID, edgeID) 1090 1091 def setType(self, vehID, typeID): 1092 """setType(string, string) -> None 1093 1094 Sets the id of the type for the named vehicle. 1095 """ 1096 self._connection._sendStringCmd( 1097 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_TYPE, vehID, typeID) 1098 1099 def setRouteID(self, vehID, routeID): 1100 """setRouteID(string, string) -> None 1101 1102 Changes the vehicles route to the route with the given id. 1103 """ 1104 self._connection._sendStringCmd( 1105 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_ROUTE_ID, vehID, routeID) 1106 1107 def setRoute(self, vehID, edgeList): 1108 """ 1109 setRoute(string, list) -> None 1110 1111 changes the vehicle route to given edges list. 1112 The first edge in the list has to be the one that the vehicle is at at the moment. 1113 1114 example usage: 1115 setRoute('1', ['1', '2', '4', '6', '7']) 1116 1117 this changes route for vehicle id 1 to edges 1-2-4-6-7 1118 """ 1119 if isinstance(edgeList, str): 1120 edgeList = [edgeList] 1121 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_ROUTE, vehID, 1122 1 + 4 + sum(map(len, edgeList)) + 4 * len(edgeList)) 1123 self._connection._packStringList(edgeList) 1124 self._connection._sendExact() 1125 1126 def updateBestLanes(self, vehID): 1127 """ updateBestLanes(string) -> None 1128 Triggers an update of the vehicle's bestLanes (structure determining the lane preferences used by LC models) 1129 It may be called after modifying the vClass for instance. 1130 """ 1131 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_UPDATE_BESTLANES, vehID) 1132 1133 def setAdaptedTraveltime(self, vehID, edgeID, time=None, begTime=None, endTime=None): 1134 """setAdaptedTraveltime(string, string, double, double, double) -> None 1135 Inserts the information about the travel time of edge "edgeID" valid 1136 from begin time to end time into the vehicle's internal edge weights 1137 container. 1138 If the time is not specified, any previously set values for that edge 1139 are removed. 1140 If begTime or endTime are not specified the value is set for the whole 1141 simulation duration. 1142 """ 1143 if type(edgeID) != str and type(begTime) == str: 1144 # legacy handling 1145 warnings.warn( 1146 "Parameter order has changed for setAdaptedTraveltime(). Attempting legacy ordering. " + 1147 "Please update your code.", stacklevel=2) 1148 return self.setAdaptedTraveltime(vehID, begTime, endTime, edgeID, time) 1149 if time is None: 1150 # reset 1151 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EDGE_TRAVELTIME, 1152 vehID, 1 + 4 + 1 + 4 + len(edgeID)) 1153 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 1) 1154 self._connection._packString(edgeID) 1155 self._connection._sendExact() 1156 elif begTime is None: 1157 # set value for the whole simulation 1158 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EDGE_TRAVELTIME, 1159 vehID, 1 + 4 + 1 + 4 + len(edgeID) + 1 + 8) 1160 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 2) 1161 self._connection._packString(edgeID) 1162 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, time) 1163 self._connection._sendExact() 1164 else: 1165 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EDGE_TRAVELTIME, 1166 vehID, 1 + 4 + 1 + 8 + 1 + 8 + 1 + 4 + len(edgeID) + 1 + 8) 1167 self._connection._string += struct.pack("!BiBdBd", tc.TYPE_COMPOUND, 4, tc.TYPE_DOUBLE, begTime, 1168 tc.TYPE_DOUBLE, endTime) 1169 self._connection._packString(edgeID) 1170 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, time) 1171 self._connection._sendExact() 1172 1173 def setEffort(self, vehID, edgeID, effort=None, begTime=None, endTime=None): 1174 """setEffort(string, string, double, double, double) -> None 1175 Inserts the information about the effort of edge "edgeID" valid from 1176 begin time to end time into the vehicle's internal edge weights 1177 container. 1178 If the time is not specified, any previously set values for that edge 1179 are removed. 1180 If begTime or endTime are not specified the value is set for the whole 1181 simulation duration. 1182 """ 1183 if type(edgeID) != str and type(begTime) == str: 1184 # legacy handling 1185 warnings.warn( 1186 "Parameter order has changed for setEffort(). Attempting legacy ordering. Please update your code.", 1187 stacklevel=2) 1188 return self.setEffort(vehID, begTime, endTime, edgeID, effort) 1189 if effort is None: 1190 # reset 1191 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EDGE_EFFORT, 1192 vehID, 1 + 4 + 1 + 4 + len(edgeID)) 1193 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 1) 1194 self._connection._packString(edgeID) 1195 self._connection._sendExact() 1196 elif begTime is None: 1197 # set value for the whole simulation 1198 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EDGE_EFFORT, 1199 vehID, 1 + 4 + 1 + 4 + len(edgeID) + 1 + 8) 1200 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 2) 1201 self._connection._packString(edgeID) 1202 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, effort) 1203 self._connection._sendExact() 1204 else: 1205 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EDGE_EFFORT, 1206 vehID, 1 + 4 + 1 + 8 + 1 + 8 + 1 + 4 + len(edgeID) + 1 + 8) 1207 self._connection._string += struct.pack("!BiBdBd", tc.TYPE_COMPOUND, 4, tc.TYPE_DOUBLE, begTime, 1208 tc.TYPE_DOUBLE, endTime) 1209 self._connection._packString(edgeID) 1210 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, effort) 1211 self._connection._sendExact() 1212 1213 LAST_TRAVEL_TIME_UPDATE = -1 1214 1215 def setRoutingMode(self, vehID, routingMode): 1216 """sets the current routing mode: 1217 tc.ROUTING_MODE_DEFAULT : use weight storages and fall-back to edge speeds (default) 1218 tc.ROUTING_MODE_AGGREGATED : use global smoothed travel times from device.rerouting 1219 """ 1220 self._connection._sendIntCmd( 1221 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_ROUTING_MODE, vehID, routingMode) 1222 1223 def rerouteTraveltime(self, vehID, currentTravelTimes=True): 1224 """rerouteTraveltime(string, bool) -> None Reroutes a vehicle. If 1225 currentTravelTimes is True (default) then the current traveltime of the 1226 edges is loaded and used for rerouting. If currentTravelTimes is False 1227 custom travel times are used. The various functions and options for 1228 customizing travel times are described at https://sumo.dlr.de/wiki/Simulation/Routing 1229 1230 When rerouteTraveltime has been called once with option 1231 currentTravelTimes=True, all edge weights are set to the current travel 1232 times at the time of that call (even for subsequent simulation steps). 1233 """ 1234 if currentTravelTimes: 1235 time = self._connection.simulation.getTime() 1236 if time != self.LAST_TRAVEL_TIME_UPDATE: 1237 self.LAST_TRAVEL_TIME_UPDATE = time 1238 for edge in self._connection.edge.getIDList(): 1239 self._connection.edge.adaptTraveltime( 1240 edge, self._connection.edge.getTraveltime(edge)) 1241 self._connection._beginMessage( 1242 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_REROUTE_TRAVELTIME, vehID, 1 + 4) 1243 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 0) 1244 self._connection._sendExact() 1245 1246 def rerouteEffort(self, vehID): 1247 self._connection._beginMessage( 1248 tc.CMD_SET_VEHICLE_VARIABLE, tc.CMD_REROUTE_EFFORT, vehID, 1 + 4) 1249 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 0) 1250 self._connection._sendExact() 1251 1252 def setSignals(self, vehID, signals): 1253 """setSignals(string, integer) -> None 1254 1255 Sets an integer encoding the state of the vehicle's signals. 1256 """ 1257 self._connection._sendIntCmd( 1258 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_SIGNALS, vehID, signals) 1259 1260 def moveTo(self, vehID, laneID, pos): 1261 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, 1262 tc.VAR_MOVE_TO, vehID, 1 + 4 + 1 + 4 + len(laneID) + 1 + 8) 1263 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 2) 1264 self._connection._packString(laneID) 1265 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, pos) 1266 self._connection._sendExact() 1267 1268 def setSpeed(self, vehID, speed): 1269 """setSpeed(string, double) -> None 1270 1271 Sets the speed in m/s for the named vehicle within the last step. 1272 Calling with speed=-1 hands the vehicle control back to SUMO. 1273 """ 1274 self._connection._sendDoubleCmd( 1275 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_SPEED, vehID, speed) 1276 1277 def setColor(self, vehID, color): 1278 """setColor(string, (integer, integer, integer, integer)) 1279 1280 Sets the color for the vehicle with the given ID, i.e. (255,0,0) for the color red. 1281 The fourth component (alpha) is optional. 1282 """ 1283 self._connection._beginMessage( 1284 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_COLOR, vehID, 1 + 1 + 1 + 1 + 1) 1285 self._connection._string += struct.pack("!BBBBB", tc.TYPE_COLOR, int(color[0]), int(color[1]), int(color[2]), 1286 int(color[3]) if len(color) > 3 else 255) 1287 self._connection._sendExact() 1288 1289 def setLength(self, vehID, length): 1290 """setLength(string, double) -> None 1291 1292 Sets the length in m for the given vehicle. 1293 """ 1294 self._connection._sendDoubleCmd( 1295 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_LENGTH, vehID, length) 1296 1297 def setVehicleClass(self, vehID, clazz): 1298 """setVehicleClass(string, string) -> None 1299 1300 Sets the vehicle class for this vehicle. 1301 """ 1302 self._connection._sendStringCmd( 1303 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_VEHICLECLASS, vehID, clazz) 1304 1305 def setSpeedFactor(self, vehID, factor): 1306 """setSpeedFactor(string, double) -> None 1307 1308 . 1309 """ 1310 self._connection._sendDoubleCmd( 1311 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_SPEED_FACTOR, vehID, factor) 1312 1313 def setEmissionClass(self, vehID, clazz): 1314 """setEmissionClass(string, string) -> None 1315 1316 Sets the emission class for this vehicle. 1317 """ 1318 self._connection._sendStringCmd( 1319 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EMISSIONCLASS, vehID, clazz) 1320 1321 def setWidth(self, vehID, width): 1322 """setWidth(string, double) -> None 1323 1324 Sets the width in m for this vehicle. 1325 """ 1326 self._connection._sendDoubleCmd( 1327 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_WIDTH, vehID, width) 1328 1329 def setHeight(self, vehID, height): 1330 """setHeight(string, double) -> None 1331 1332 Sets the height in m for this vehicle. 1333 """ 1334 self._connection._sendDoubleCmd( 1335 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_HEIGHT, vehID, height) 1336 1337 def setLine(self, vehID, line): 1338 """setHeight(string, string) -> None 1339 1340 Sets the line information for this vehicle. 1341 """ 1342 self._connection._sendStringCmd( 1343 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_LINE, vehID, line) 1344 1345 def setVia(self, vehID, edgeList): 1346 """ 1347 setVia(string, list) -> None 1348 1349 changes the via edges to the given edges list (to be used during 1350 subsequent rerouting calls). 1351 1352 Note: a single edgeId as argument is allowed as shorthand for a list of length 1 1353 """ 1354 if isinstance(edgeList, str): 1355 edgeList = [edgeList] 1356 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_VIA, vehID, 1357 1 + 4 + sum(map(len, edgeList)) + 4 * len(edgeList)) 1358 self._connection._packStringList(edgeList) 1359 self._connection._sendExact() 1360 1361 def setMinGap(self, vehID, minGap): 1362 """setMinGap(string, double) -> None 1363 1364 Sets the offset (gap to front vehicle if halting) for this vehicle. 1365 """ 1366 self._connection._sendDoubleCmd( 1367 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_MINGAP, vehID, minGap) 1368 1369 def setMinGapLat(self, vehID, minGapLat): 1370 """setMinGapLat(string, double) -> None 1371 1372 Sets the minimum lateral gap of the vehicle at 50km/h in m 1373 """ 1374 self._connection._sendDoubleCmd( 1375 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_MINGAP_LAT, vehID, minGapLat) 1376 1377 def setLateralAlignment(self, vehID, align): 1378 """setLateralAlignment(string, string) -> None 1379 1380 Sets the preferred lateral alignment for this vehicle. 1381 """ 1382 self._connection._sendStringCmd( 1383 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_LATALIGNMENT, vehID, align) 1384 1385 def setShapeClass(self, vehID, clazz): 1386 """setShapeClass(string, string) -> None 1387 1388 Sets the shape class for this vehicle. 1389 """ 1390 self._connection._sendStringCmd( 1391 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_SHAPECLASS, vehID, clazz) 1392 1393 def setAccel(self, vehID, accel): 1394 """setAccel(string, double) -> None 1395 1396 Sets the maximum acceleration in m/s^2 for this vehicle. 1397 """ 1398 self._connection._sendDoubleCmd( 1399 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_ACCEL, vehID, accel) 1400 1401 def setDecel(self, vehID, decel): 1402 """setDecel(string, double) -> None 1403 1404 Sets the preferred maximal deceleration in m/s^2 for this vehicle. 1405 """ 1406 self._connection._sendDoubleCmd( 1407 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_DECEL, vehID, decel) 1408 1409 def setEmergencyDecel(self, vehID, decel): 1410 """setEmergencyDecel(string, double) -> None 1411 1412 Sets the maximal physically possible deceleration in m/s^2 for this vehicle. 1413 """ 1414 self._connection._sendDoubleCmd( 1415 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_EMERGENCY_DECEL, vehID, decel) 1416 1417 def setApparentDecel(self, vehID, decel): 1418 """setApparentDecel(string, double) -> None 1419 1420 Sets the apparent deceleration in m/s^2 for this vehicle. 1421 """ 1422 self._connection._sendDoubleCmd( 1423 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_APPARENT_DECEL, vehID, decel) 1424 1425 def setActionStepLength(self, vehID, actionStepLength, resetActionOffset=True): 1426 """setActionStepLength(string, double, bool) -> None 1427 1428 Sets the action step length for this vehicle. If resetActionOffset == True (default), the 1429 next action point is scheduled immediately. if If resetActionOffset == False, the interval 1430 between the last and the next action point is updated to match the given value, or if the latter 1431 is smaller than the time since the last action point, the next action follows immediately. 1432 """ 1433 if actionStepLength < 0: 1434 raise TraCIException("Invalid value for actionStepLength. Given value must be non-negative.") 1435 # Use negative value to indicate resetActionOffset == False 1436 if not resetActionOffset: 1437 actionStepLength *= -1 1438 self._connection._sendDoubleCmd( 1439 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_ACTIONSTEPLENGTH, vehID, actionStepLength) 1440 1441 def highlight(self, vehID, color=(255, 0, 0, 255), size=-1, alphaMax=-1, duration=-1, type=0): 1442 """ highlight(string, color, float, ubyte) -> void 1443 Adds a circle of the given color tracking the vehicle. 1444 If a positive size [in m] is given the size of the highlight is chosen accordingly, 1445 otherwise the length of the vehicle is used as reference. 1446 If alphaMax and duration are positive, the circle fades in and out within the given duration, 1447 otherwise it permanently follows the vehicle. 1448 """ 1449 if (type > 255): 1450 raise TraCIException("poi.highlight(): maximal value for type is 255") 1451 if (alphaMax > 255): 1452 raise TraCIException("vehicle.highlight(): maximal value for alphaMax is 255") 1453 if (alphaMax <= 0 and duration > 0): 1454 raise TraCIException("vehicle.highlight(): duration>0 requires alphaMax>0") 1455 if (alphaMax > 0 and duration <= 0): 1456 raise TraCIException("vehicle.highlight(): alphaMax>0 requires duration>0") 1457 1458 if (type > 0): 1459 compoundLength = 5 1460 elif (alphaMax > 0): 1461 compoundLength = 4 1462 elif (size > 0): 1463 compoundLength = 2 1464 elif color: 1465 compoundLength = 1 1466 else: 1467 compoundLength = 0 1468 1469 msg_length = 1 + 1 1470 if compoundLength >= 1: 1471 msg_length += 1 + 4 1472 if compoundLength >= 2: 1473 msg_length += 1 + 8 1474 if compoundLength >= 3: 1475 msg_length += 1 + 8 + 1 + 1 1476 if compoundLength >= 5: 1477 msg_length += 1 + 1 1478 if not color: 1479 # Send red as highlight standard 1480 color = (255, 0, 0, 255) 1481 1482 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_HIGHLIGHT, vehID, msg_length) 1483 self._connection._string += struct.pack("!BB", tc.TYPE_COMPOUND, compoundLength) 1484 if (compoundLength >= 1): 1485 self._connection._string += struct.pack("!BBBBB", tc.TYPE_COLOR, int(color[0]), int(color[1]), 1486 int(color[2]), int(color[3]) if len(color) > 3 else 255) 1487 if (compoundLength >= 2): 1488 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, size) 1489 if (compoundLength >= 3): 1490 self._connection._string += struct.pack("!BB", tc.TYPE_UBYTE, alphaMax) 1491 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, duration) 1492 if (compoundLength >= 5): 1493 self._connection._string += struct.pack("!BB", tc.TYPE_UBYTE, type) 1494 self._connection._sendExact() 1495 1496 def setImperfection(self, vehID, imperfection): 1497 """setImperfection(string, double) -> None 1498 1499 Sets the driver imperfection sigma. 1500 """ 1501 self._connection._sendDoubleCmd( 1502 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_IMPERFECTION, vehID, imperfection) 1503 1504 def setTau(self, vehID, tau): 1505 """setTau(string, double) -> None 1506 1507 Sets the driver's tau-parameter (reaction time or anticipation time depending on the car-following model) in s 1508 for this vehicle. 1509 """ 1510 self._connection._sendDoubleCmd( 1511 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_TAU, vehID, tau) 1512 1513 def setLaneChangeMode(self, vehID, lcm): 1514 """setLaneChangeMode(string, integer) -> None 1515 1516 Sets the vehicle's lane change mode as a bitset. 1517 """ 1518 self._connection._sendIntCmd( 1519 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_LANECHANGE_MODE, vehID, lcm) 1520 1521 def setSpeedMode(self, vehID, sm): 1522 """setSpeedMode(string, integer) -> None 1523 1524 Sets the vehicle's speed mode as a bitset. 1525 """ 1526 self._connection._sendIntCmd( 1527 tc.CMD_SET_VEHICLE_VARIABLE, tc.VAR_SPEEDSETMODE, vehID, sm) 1528 1529 def addLegacy(self, vehID, routeID, depart=tc.DEPARTFLAG_NOW, pos=0, speed=0, 1530 lane=tc.DEPARTFLAG_LANE_FIRST_ALLOWED, typeID="DEFAULT_VEHTYPE"): 1531 """ 1532 Add a new vehicle (old style) 1533 """ 1534 if depart == tc.DEPARTFLAG_NOW: 1535 depart = "now" 1536 elif depart == tc.DEPARTFLAG_TRIGGERED: 1537 depart = "triggered" 1538 else: 1539 depart = str(depart) 1540 if pos < 0: 1541 print("Invalid departure position.") 1542 return 1543 if lane == tc.DEPARTFLAG_LANE_FIRST_ALLOWED: 1544 lane = "first" 1545 elif lane == tc.DEPARTFLAG_LANE_FREE: 1546 lane = "free" 1547 else: 1548 lane = str(lane) 1549 self.addFull(vehID, routeID, typeID, depart, lane, str(pos), str(speed)) 1550 1551 def add(self, vehID, routeID, typeID="DEFAULT_VEHTYPE", depart=None, 1552 departLane="first", departPos="base", departSpeed="0", 1553 arrivalLane="current", arrivalPos="max", arrivalSpeed="current", 1554 fromTaz="", toTaz="", line="", personCapacity=0, personNumber=0): 1555 """ 1556 Add a new vehicle (new style with all possible parameters) 1557 """ 1558 messageString = struct.pack("!Bi", tc.TYPE_COMPOUND, 14) 1559 if depart is None: 1560 depart = str(self._connection.simulation.getTime()) 1561 for val in (routeID, typeID, depart, departLane, departPos, departSpeed, 1562 arrivalLane, arrivalPos, arrivalSpeed, fromTaz, toTaz, line): 1563 val = str(val) 1564 messageString += struct.pack("!Bi", tc.TYPE_STRING, len(val)) + val.encode("latin1") 1565 messageString += struct.pack("!Bi", tc.TYPE_INTEGER, personCapacity) 1566 messageString += struct.pack("!Bi", tc.TYPE_INTEGER, personNumber) 1567 1568 self._connection._beginMessage( 1569 tc.CMD_SET_VEHICLE_VARIABLE, tc.ADD_FULL, vehID, len(messageString)) 1570 self._connection._string += messageString 1571 self._connection._sendExact() 1572 1573 addFull = add 1574 1575 def remove(self, vehID, reason=tc.REMOVE_VAPORIZED): 1576 '''Remove vehicle with the given ID for the give reason. 1577 Reasons are defined in module constants and start with REMOVE_''' 1578 self._connection._sendByteCmd( 1579 tc.CMD_SET_VEHICLE_VARIABLE, tc.REMOVE, vehID, reason) 1580 1581 def moveToXY(self, vehID, edgeID, lane, x, y, angle=tc.INVALID_DOUBLE_VALUE, keepRoute=1): 1582 '''Place vehicle at the given x,y coordinates and force it's angle to 1583 the given value (for drawing). 1584 If the angle is set to INVALID_DOUBLE_VALUE, the vehicle assumes the 1585 natural angle of the edge on which it is driving. 1586 If keepRoute is set to 1, the closest position 1587 within the existing route is taken. If keepRoute is set to 0, the vehicle may move to 1588 any edge in the network but it's route then only consists of that edge. 1589 If keepRoute is set to 2 the vehicle has all the freedom of keepRoute=0 1590 but in addition to that may even move outside the road network. 1591 edgeID and lane are optional placement hints to resolve ambiguities''' 1592 self._connection._beginMessage(tc.CMD_SET_VEHICLE_VARIABLE, tc.MOVE_TO_XY, 1593 vehID, 1 + 4 + 1 + 4 + len(edgeID) + 1 + 4 + 1 + 8 + 1 + 8 + 1 + 8 + 1 + 1) 1594 self._connection._string += struct.pack("!Bi", tc.TYPE_COMPOUND, 6) 1595 self._connection._packString(edgeID) 1596 self._connection._string += struct.pack("!Bi", tc.TYPE_INTEGER, lane) 1597 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, x) 1598 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, y) 1599 self._connection._string += struct.pack("!Bd", tc.TYPE_DOUBLE, angle) 1600 self._connection._string += struct.pack("!BB", tc.TYPE_BYTE, keepRoute) 1601 self._connection._sendExact() 1602 1603 def subscribe(self, objectID, varIDs=(tc.VAR_ROAD_ID, tc.VAR_LANEPOSITION), begin=0, end=2**31 - 1): 1604 """subscribe(string, list(integer), int, int) -> None 1605 1606 Subscribe to one or more object values for the given interval. 1607 """ 1608 Domain.subscribe(self, objectID, varIDs, begin, end) 1609 1610 def subscribeContext(self, objectID, domain, dist, varIDs=( 1611 tc.VAR_ROAD_ID, tc.VAR_LANEPOSITION), begin=0, end=2**31 - 1): 1612 """subscribe(string, int, double, list(integer), int, int) -> None 1613 1614 Subscribe to one or more object values of the given domain around the 1615 given objectID in a given radius 1616 """ 1617 Domain.subscribeContext( 1618 self, objectID, domain, dist, varIDs, begin, end) 1619 1620 def addSubscriptionFilterLanes(self, lanes, noOpposite=False, downstreamDist=None, upstreamDist=None): 1621 """addSubscriptionFilterLanes(list(integer), bool, double, double) -> None 1622 1623 Adds a lane-filter to the last modified vehicle context subscription (call it just after subscribing). 1624 lanes is a list of relative lane indices (-1 -> right neighboring lane of the ego, 0 -> ego lane, etc.) 1625 noOpposite specifies whether vehicles on opposite direction lanes shall be returned 1626 downstreamDist and upstreamDist specify the range of the search for surrounding vehicles along the road net. 1627 """ 1628 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_LANES, lanes) 1629 if noOpposite: 1630 self.addSubscriptionFilterNoOpposite() 1631 if downstreamDist is not None: 1632 self.addSubscriptionFilterDownstreamDistance(downstreamDist) 1633 if upstreamDist is not None: 1634 self.addSubscriptionFilterUpstreamDistance(upstreamDist) 1635 1636 def addSubscriptionFilterNoOpposite(self): 1637 """addSubscriptionFilterNoOpposite() -> None 1638 1639 Omits vehicles on other edges than the ego's for the last modified vehicle context subscription 1640 (call it just after subscribing). 1641 """ 1642 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_NOOPPOSITE) 1643 1644 def addSubscriptionFilterDownstreamDistance(self, dist): 1645 """addSubscriptionFilterDownstreamDist(float) -> None 1646 1647 Sets the downstream distance along the network for vehicles to be returned by the last modified 1648 vehicle context subscription (call it just after subscribing). 1649 """ 1650 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_DOWNSTREAM_DIST, dist) 1651 1652 def addSubscriptionFilterUpstreamDistance(self, dist): 1653 """addSubscriptionFilterUpstreamDist(float) -> None 1654 1655 Sets the upstream distance along the network for vehicles to be returned by the last modified 1656 vehicle context subscription (call it just after subscribing). 1657 """ 1658 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_UPSTREAM_DIST, dist) 1659 1660 def addSubscriptionFilterCFManeuver(self, downstreamDist=None, upstreamDist=None): 1661 """addSubscriptionFilterCFManeuver() -> None 1662 1663 Restricts vehicles returned by the last modified vehicle context subscription to leader and follower of the ego. 1664 downstreamDist and upstreamDist specify the range of the search for leader and follower along the road net. 1665 """ 1666 self.addSubscriptionFilterLeadFollow([0]) 1667 if downstreamDist is not None: 1668 self.addSubscriptionFilterDownstreamDistance(downstreamDist) 1669 if upstreamDist is not None: 1670 self.addSubscriptionFilterUpstreamDistance(upstreamDist) 1671 1672 def addSubscriptionFilterLCManeuver(self, direction, noOpposite=False, downstreamDist=None, upstreamDist=None): 1673 """addSubscriptionFilterLCManeuver(int) -> None 1674 1675 Restricts vehicles returned by the last modified vehicle context subscription to neighbor and ego-lane leader 1676 and follower of the ego. 1677 direction - lane change direction (in {-1=right, 1=left}) 1678 noOpposite specifies whether vehicles on opposite direction lanes shall be returned 1679 downstreamDist and upstreamDist specify the range of the search for leader and follower along the road net. 1680 Combine with: distance filters; vClass/vType filter. 1681 """ 1682 if direction is None: 1683 # Using default: both directions 1684 lanes = [-1, 0, 1] 1685 elif not (direction == -1 or direction == 1): 1686 warnings.warn("Ignoring lane change subscription filter " + 1687 "with non-neighboring lane offset direction=%s." % direction) 1688 return 1689 else: 1690 lanes = [0, direction] 1691 self.addSubscriptionFilterLeadFollow(lanes) 1692 if noOpposite: 1693 self.addSubscriptionFilterNoOpposite() 1694 if downstreamDist is not None: 1695 self.addSubscriptionFilterDownstreamDistance(downstreamDist) 1696 if upstreamDist is not None: 1697 self.addSubscriptionFilterUpstreamDistance(upstreamDist) 1698 1699 def addSubscriptionFilterLeadFollow(self, lanes): 1700 """addSubscriptionFilterLCManeuver() -> None 1701 1702 Restricts vehicles returned by the last modified vehicle context subscription to neighbor and ego-lane leader 1703 and follower of the ego. 1704 Combine with: lanes-filter to restrict to one direction; distance filters; vClass/vType filter. 1705 """ 1706 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_LEAD_FOLLOW) 1707 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_LANES, lanes) 1708 1709 def addSubscriptionFilterTurn(self, downstreamDist=None, upstreamDist=None): 1710 """addSubscriptionFilterTurn() -> None 1711 1712 Restricts vehicles returned by the last modified vehicle context subscription to foes on an upcoming junction 1713 """ 1714 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_TURN) 1715 if downstreamDist is not None: 1716 self.addSubscriptionFilterDownstreamDistance(downstreamDist) 1717 if upstreamDist is not None: 1718 self.addSubscriptionFilterUpstreamDistance(upstreamDist) 1719 1720 def addSubscriptionFilterVClass(self, vClasses): 1721 """addSubscriptionFilterVClass(list(String)) -> None 1722 1723 Restricts vehicles returned by the last modified vehicle context subscription to vehicles of the given classes 1724 """ 1725 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_VCLASS, vClasses) 1726 1727 def addSubscriptionFilterVType(self, vTypes): 1728 """addSubscriptionFilterVType(list(String)) -> None 1729 1730 Restricts vehicles returned by the last modified vehicle context subscription to vehicles of the given types 1731 """ 1732 self._connection._addSubscriptionFilter(tc.FILTER_TYPE_VTYPE, vTypes) 1733 1734 1735VehicleDomain() 1736