sumolib.output.convert.trj
This module includes functions for converting SUMO's fcd-output into data files read by SSAM. See the SSAM TRJ standard at https://github.com/OSADP/SSAM/blob/master/Documentation/SSAM%20File%20Format%20v1.04.pdf https://github.com/OSADP/SSAM/blob/master/Documentation/Open%20Source%20SSAM%20File%20Format%20v3.0.pdf
1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 2# Copyright (C) 2013-2026 German Aerospace Center (DLR) and others. 3# This program and the accompanying materials are made available under the 4# terms of the Eclipse Public License 2.0 which is available at 5# https://www.eclipse.org/legal/epl-2.0/ 6# This Source Code may also be made available under the following Secondary 7# Licenses when the conditions for such availability set forth in the Eclipse 8# Public License 2.0 are satisfied: GNU General Public License, version 2 9# or later which is available at 10# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html 11# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later 12 13# @file trj.py 14# @author Mirko Barthauer 15# @date 2021-03-31 16 17""" 18This module includes functions for converting SUMO's fcd-output into 19data files read by SSAM. 20See the SSAM TRJ standard at 21https://github.com/OSADP/SSAM/blob/master/Documentation/SSAM%20File%20Format%20v1.04.pdf 22https://github.com/OSADP/SSAM/blob/master/Documentation/Open%20Source%20SSAM%20File%20Format%20v3.0.pdf 23""" 24 25import sys 26import struct 27import math 28 29 30def fcd2trj(inpFCD, outSTRM, further): 31 endian = b'B' if sys.byteorder == "big" else b'L' 32 33 # write FORMAT block 34 outSTRM.write(struct.pack("=c", chr(0).encode())) 35 outSTRM.write(struct.pack("=c", endian)) 36 outSTRM.write(struct.pack("f", 3.0)) 37 outSTRM.write(struct.pack("=c", chr(1).encode())) 38 39 # write DIMENSIONS block 40 outSTRM.write(struct.pack("=c", chr(1).encode())) 41 outSTRM.write(struct.pack("=c", chr(1).encode())) 42 outSTRM.write(struct.pack("=f", 1.0)) 43 outSTRM.write(struct.pack("=i", int(further["bbox"][0][0]))) 44 outSTRM.write(struct.pack("=i", int(further["bbox"][0][1]))) 45 outSTRM.write(struct.pack("=i", int(further["bbox"][1][0]))) 46 outSTRM.write(struct.pack("=i", int(further["bbox"][1][1]))) 47 48 # go through fcd output and encode links and vehicle IDs 49 edgeDict = {} 50 trafficPartDict = {} 51 prevSpeed = {} 52 edgeCounter = 0 53 trafficPartCounter = 0 54 55 for timestep in inpFCD: 56 # write TIMESTEP block 57 outSTRM.write(struct.pack("=c", chr(2).encode())) 58 outSTRM.write(struct.pack("=f", timestep.time)) 59 60 for v in timestep.vehicle: 61 speed = float(v.speed) 62 if v.id not in trafficPartDict: 63 trafficPartDict[v.id] = trafficPartCounter 64 trafficPartCounter += 1 65 prevSpeed[v.id] = speed 66 numericID = trafficPartDict[v.id] 67 accel = (speed - prevSpeed[v.id])/further["timestep"] 68 if "_" not in v.lane: 69 edge = v.lane 70 laneIndex = 0 71 else: 72 edge, laneIndex = v.lane.rsplit("_", 1) 73 laneIndex = min(int(laneIndex), 9) 74 75 if edge not in edgeDict: 76 edgeDict[edge] = edgeCounter 77 edgeCounter += 1 78 edgeNumericID = edgeDict[edge] 79 80 # calculated values 81 x = float(v.x) 82 y = float(v.y) 83 z = float(v.z) 84 angle = float(v.angle) * math.pi/180. 85 slope = float(v.slope) * math.pi/180. 86 rearX = x - math.sin(angle) * further["length"] 87 rearY = y - math.cos(angle) * further["length"] 88 rearZ = z - math.sin(slope) * further["length"] 89 # write VEHICLE block 90 outSTRM.write(struct.pack("=c", chr(3).encode())) 91 outSTRM.write(struct.pack("=i", numericID)) 92 outSTRM.write(struct.pack("=i", edgeNumericID)) 93 outSTRM.write(struct.pack("=c", chr(laneIndex).encode())) 94 outSTRM.write(struct.pack("=f", x)) 95 outSTRM.write(struct.pack("=f", y)) 96 outSTRM.write(struct.pack("=f", rearX)) 97 outSTRM.write(struct.pack("=f", rearY)) 98 outSTRM.write(struct.pack("=f", further["length"])) 99 outSTRM.write(struct.pack("=f", further["width"])) 100 outSTRM.write(struct.pack("=f", speed)) 101 outSTRM.write(struct.pack("=f", accel)) 102 outSTRM.write(struct.pack("=f", z)) # front z coord 103 outSTRM.write(struct.pack("=f", rearZ)) # back z coord 104 # remember value for next timestep 105 prevSpeed[numericID] = speed
def
fcd2trj(inpFCD, outSTRM, further):
31def fcd2trj(inpFCD, outSTRM, further): 32 endian = b'B' if sys.byteorder == "big" else b'L' 33 34 # write FORMAT block 35 outSTRM.write(struct.pack("=c", chr(0).encode())) 36 outSTRM.write(struct.pack("=c", endian)) 37 outSTRM.write(struct.pack("f", 3.0)) 38 outSTRM.write(struct.pack("=c", chr(1).encode())) 39 40 # write DIMENSIONS block 41 outSTRM.write(struct.pack("=c", chr(1).encode())) 42 outSTRM.write(struct.pack("=c", chr(1).encode())) 43 outSTRM.write(struct.pack("=f", 1.0)) 44 outSTRM.write(struct.pack("=i", int(further["bbox"][0][0]))) 45 outSTRM.write(struct.pack("=i", int(further["bbox"][0][1]))) 46 outSTRM.write(struct.pack("=i", int(further["bbox"][1][0]))) 47 outSTRM.write(struct.pack("=i", int(further["bbox"][1][1]))) 48 49 # go through fcd output and encode links and vehicle IDs 50 edgeDict = {} 51 trafficPartDict = {} 52 prevSpeed = {} 53 edgeCounter = 0 54 trafficPartCounter = 0 55 56 for timestep in inpFCD: 57 # write TIMESTEP block 58 outSTRM.write(struct.pack("=c", chr(2).encode())) 59 outSTRM.write(struct.pack("=f", timestep.time)) 60 61 for v in timestep.vehicle: 62 speed = float(v.speed) 63 if v.id not in trafficPartDict: 64 trafficPartDict[v.id] = trafficPartCounter 65 trafficPartCounter += 1 66 prevSpeed[v.id] = speed 67 numericID = trafficPartDict[v.id] 68 accel = (speed - prevSpeed[v.id])/further["timestep"] 69 if "_" not in v.lane: 70 edge = v.lane 71 laneIndex = 0 72 else: 73 edge, laneIndex = v.lane.rsplit("_", 1) 74 laneIndex = min(int(laneIndex), 9) 75 76 if edge not in edgeDict: 77 edgeDict[edge] = edgeCounter 78 edgeCounter += 1 79 edgeNumericID = edgeDict[edge] 80 81 # calculated values 82 x = float(v.x) 83 y = float(v.y) 84 z = float(v.z) 85 angle = float(v.angle) * math.pi/180. 86 slope = float(v.slope) * math.pi/180. 87 rearX = x - math.sin(angle) * further["length"] 88 rearY = y - math.cos(angle) * further["length"] 89 rearZ = z - math.sin(slope) * further["length"] 90 # write VEHICLE block 91 outSTRM.write(struct.pack("=c", chr(3).encode())) 92 outSTRM.write(struct.pack("=i", numericID)) 93 outSTRM.write(struct.pack("=i", edgeNumericID)) 94 outSTRM.write(struct.pack("=c", chr(laneIndex).encode())) 95 outSTRM.write(struct.pack("=f", x)) 96 outSTRM.write(struct.pack("=f", y)) 97 outSTRM.write(struct.pack("=f", rearX)) 98 outSTRM.write(struct.pack("=f", rearY)) 99 outSTRM.write(struct.pack("=f", further["length"])) 100 outSTRM.write(struct.pack("=f", further["width"])) 101 outSTRM.write(struct.pack("=f", speed)) 102 outSTRM.write(struct.pack("=f", accel)) 103 outSTRM.write(struct.pack("=f", z)) # front z coord 104 outSTRM.write(struct.pack("=f", rearZ)) # back z coord 105 # remember value for next timestep 106 prevSpeed[numericID] = speed