布吉做网站的公司/成都seo达人
基于sumo实现交通灯控制算法的模板
目录
- 在windows安装
- run hello world
- network
- routes
- viewsettings & configuration
- simulation
- 交通灯控制系统
- 介绍
- 文件生成器类(FileGenerator)
- 道路网络(Network)
- 辅助函数
- 生成道路网络(GenerateNetwork)
- 生成路径(route)
- 生成车辆(vehicle)
- 生成交通信号灯(tlLogic)
- 生成探测器(detector)
- py程序接口(TraCI)
- 附录
- node
- edge
- connection
- route
- vehicle
- tlLogic
- TraCI
- Detector
- simulation
- 参考资料
- 有关文件
原文地址:https://www.wolai.com/7SsvyQLdZQr5TPikSDG9rR
代码在附录中
在windows安装
SUMO 软件包中的大多数应用程序都是命令行工具,目前只有sumo-gui和netedit不是。
SUMO 应用程序是普通的可执行文件。你只需在命令行中输入其名称即可启动它们;例如,netgenerate的调用方式是
netgenerate.exe
这只是启动应用程序(本例中为netgenerate)。由于没有给出参数,应用程序不知道要做什么,只能打印有关自身的信息:
SUMO 中有两个gui程序:
- netedit:生成network、routes等
- sumo-gui:执行simulation
这两个程序均可通过命令行启动:
启动netedit:
netedit
启动sumo-gui:
sumo-gui
run hello world
通过GUI创建和仿真的详细操作参考此处:https://sumo.dlr.de/docs/Tutorials/Hello_World.html
我们接下来要讨论的是通过文件创建和仿真,这将用到如下文件:
*.nod.xml
:记录节点信息*.edg.xml
:记录边信息*.net.xml
:记录网络信息,通过 netconvert 生成*.rou.xml
:记录车辆信息*.settings.xml
:记录仿真界面的配置信息*.sumocfg
:记录仿真信息,sumo通过此文件执行仿真
network
所有节点都有一个位置(x 坐标和 y 坐标,描述到原点的距离,以米为单位)和一个 ID,以供将来参考。因此,我们的简单节点文件如下:
<nodes><node id="1" x="-250.0" y="0.0" /><node id="2" x="+250.0" y="0.0" /><node id="3" x="+251.0" y="0.0" />
</nodes>
您可以使用自己选择的文本编辑器编辑文件,并将其保存为hello.nod.xml
,其中.nod.xml
是 Sumo 节点文件的默认后缀。
现在我们用边来连接节点。这听起来很简单。我们有一个源节点 ID、一个目标节点 ID 和一个边 ID,以备将来参考。边是有方向的,因此每辆车在这条边上行驶时,都会from
给出的源节点开始,在给出的to
节点结束。
<edges><edge from="1" id="1to2" to="2" /><edge from="2" id="out" to="3" />
</edges>
将这些数据保存到名为hello.edg.xml
的文件中。
现在我们有了节点和边,就可以调用第一个 SUMO 工具来创建网络了。 确保netconvert位于PATH
中的某个位置,然后调用
netconvert --node-files=hello.nod.xml --edge-files=hello.edg.xml --output-file=hello.net.xml
这将生成名为hello.net.xml
的网络。
启动netedit并查看文件:
netedit hello.net.xml
routes
更多信息请参阅"车辆、车辆类型和路线的定义"
定义如下几个字段:
vType
:车辆类型的信息route
:路径的信息vehicle
:车辆的信息
如下所示的hello.rou.xml
文件:
<routes><vType id="typeCar" accel="0.8" decel="4.5" sigma="0.5" length="5" minGap="2.5" maxSpeed="16.67" guiShape="passenger"/><route id="route0" edges="1to2 out"/><vehicle depart="1" id="veh0" route="route0" type="typeCar" /><vehicle depart="20" id="veh1" route="route0" type="typeCar" />
</routes>
注意:定义多辆车时,应该按照depart属性排序
viewsettings & configuration
使用图形用户界面进行模拟时,添加一个 gui-settings 文件非常有用,这样就不必在启动程序后更改设置。为此,创建一个viewsettings文件:
<viewsettings><viewport y="0" x="250" zoom="100"/><delay value="100"/>
</viewsettings>
将其保存为配置文件中包含的名称,在本例中就是hello.settings.xml
。
在这里,我们使用视口(viewport)来设置摄像机的位置,并使用延迟(delay)来设置模拟的每一步之间的延迟(毫秒)。
现在,我们将所有内容粘合到一个配置文件中:
<configuration><input><net-file value="hello.net.xml"/><route-files value="hello.rou.xml"/><gui-settings-file value="hello.settings.xml"/></input><time><begin value="0"/><end value="10000"/></time>
</configuration>
将其保存到hello.sumocfg
中
simulation
Using the Command Line Applications - SUMO Documentation (dlr.de)
我们就可以开始模拟了,方法如下:
sumo-gui -c hello.sumocfg
交通灯控制系统
看不懂的参数请看附录
介绍
Quick Start (old style) - SUMO Documentation (dlr.de)
我们的目的是生成如下类型的道路网络:
- 十字路口的规模是可自定义的
- 十字路口的道路是有专用转向车道的
道路网络network:
- 节点node
- 边edge
- 道路lane:每条边对应多条道路
- 连接connection:边与边之间的连接关系
我们的项目按照如下流程进行:
文件生成器类(FileGenerator)
import os
import subprocess
from sample.NetworkFileGenerator import NetworkFileGenerator
from sample.SumoFileGenerator import SumoFileGeneratorclass FileGenerator:def __init__(self):self._networkGenerator = NetworkFileGenerator()self._sumoGenerator = SumoFileGenerator()self.network = Nonepassdef GenerateAllFile(self, netconvert: str = "netconvert", cwd: str = "", name: str = "sample",height: int = 1, width: int = 1, unity: int = 100,avgCarAmount: int = 5, timePeriod: int = 100):if cwd == "":cwd = os.getcwd() + "/data" # 输出目录# 生成所需文件self._networkGenerator.GenerateAllFile(cwd, name, width, height, unity)self._sumoGenerator.GenerateAllFile(cwd, name, self._networkGenerator.network, avgCarAmount, timePeriod)p = subprocess.Popen([netconvert,"-c", "%s.netccfg" % (name),"--no-turnarounds.tls", "true"],stdin=subprocess.PIPE, stdout=subprocess.PIPE,cwd=cwd)p.wait()self.network = self._networkGenerator.networkpasspass
- 负责根据参数生成绝大多数有关文件
- 支持输出目录的自定义
- 支持输出文件名的自定义
- 外界通过调用GenerateAllFile以使用该类
道路网络(Network)
道路网络的数据结构:
from collections import defaultdictclass Network:def __init__(self):"""Node: (int, int)Edge: (Node, Node)Connection: (Node, Node, Node, lane: int)"""self.width = 1 # 水平方向的交通灯数量self.height = 1 # 竖直方向的交通灯数量self.nodes = [] # 节点self.edges = [] # 边self.connections = [] # 连接self.tlNodes = [] # 交通灯节点self.boundaryNodes = [] # 边界节点self.inEdges = defaultdict(list) # 入边表,Node -> [Edge]self.outEdges = defaultdict(list) # 出边表,Node -> [Edge]passpass
- 节点使用二维坐标来描述
- 边使用两个节点来描述
- 连接使用三个节点来描述
- width、height是交通灯的数量信息
辅助函数
def GetNodeId(i: int, j: int) -> str:return "%01d%01d" % (i, j)def GetEdgeId(i: int, j: int, u: int, v: int) -> str:# from (i, j) to (u, v)return "%sto%s" % (GetNodeId(i, j), GetNodeId(u, v))def GetRouteId(i: int, j: int, u: int, v: int, additional: int) -> str:# from (i, j) to (u, v)return "%s_%08d" % (GetEdgeId(i, j, u, v), additional)def GetLaneId(i: int, j: int, u: int, v: int, lane: int) -> str:# from (i, j) to (u, v)return "%s_%1d" % (GetEdgeId(i, j, u, v), lane)def GetDetectorId(i: int, j: int, u: int, v: int, lane: int) -> str:# from (i, j) to (u, v)return "det_%s" % (GetLaneId(i, j, u, v, lane))def IsTrafficLightNode(width: int, height: int, i: int, j: int) -> bool:# [1, width] * [1, height] 范围内是交通灯节点return 1 <= i and i <= width and 1 <= j and j <= heightdef IsBoundaryNode(width: int, height: int, i: int, j: int) -> bool:# [1, width] * [1, height] 范围外的一圈是边界return i == 0 or i == width + 1 or j == 0 or j == height + 1def IsIllegalNode(width: int, height: int, i: int, j: int) -> bool:# [0, width + 1] * [0, height + 1] 范围外是非法的return i < 0 or i > width + 1 or j < 0 or j > height + 1def IsCornerNode(width: int, height: int, i: int, j: int) -> bool:# (0, 0) (width + 1, 0) (0, height + 1) (width + 1, height + 1) 是角落return i == 0 and j == 0 or \i == width + 1 and j == 0 or \i == 0 and j == height + 1 or \i == width + 1 and j == height + 1def GetEdgesOfRoute(path: list) -> str:# 从节点列表,以字符串形式,给出途经的边ret = ""for i in range(1, len(path)):ret += GetEdgeId(*path[i - 1], *path[i]) + " "return retdef ToXMLElement(name: str, *arg: str):import xml.domdoc = xml.dom.minidom.Document()# doc = xml.dom.minidom.Document()element = doc.createElement(name)for i in range(1, len(arg), 2):element.setAttribute(arg[i - 1], arg[i])return elementpass
- [1, width] * [1, height]是交通灯的坐标
- [1, width] * [1, height] 范围外的一圈是边界
- [0, width + 1] * [0, height + 1] 范围外是非法的
- (0, 0) (width + 1, 0) (0, height + 1) (width + 1, height + 1) 是角落
生成道路网络(GenerateNetwork)
- 规定方向编号:参考极坐标系,角度与方向编号有线性关系
- 0:x轴正向
- 1:y轴正向
- 2:x轴负向
- 3:y轴负向
- 规定转向编号:即方向编号的差分量
- -1:右转
- 0:直行
- 1:左转
这样规定转向编号的原因是,转向编号与sumo的车道编号相对应。sumo的车道编号是从右到左的。
代码如下:
class NetworkFileGenerator:def __init__(self):self.cwd = None # 输出目录self.name = None # 文件名self.network = None # 道路网络self._unity = None # 单位长passdef GenerateNetwork(self, width: int, height: int) -> Network:self.network = Network()self.network.width = widthself.network.height = heightdx = [1, 0, -1, 0]dy = [0, 1, 0, -1]turn = [-1, 0, 1] # 车道编号 -> 转向编号,分别对应:右转,直行,左转for i in range(width + 2):for j in range(height + 2):# 生成节点 (i, j)# 角落不需要生成if Utils.IsCornerNode(width, height, i, j):continuenode1 = (i, j)self.network.nodes.append(node1)if Utils.IsTrafficLightNode(self.network.width, self.network.height, i, j):self.network.tlNodes.append(node1)else:self.network.boundaryNodes.append(node1)passfor dir in range(len(dx)):u = i + dx[dir]v = j + dy[dir]# 生成边 (i, j)->(u, v)# 排除非法节点if Utils.IsIllegalNode(width, height, u, v):continue# 角落不需要生成if Utils.IsCornerNode(width, height, u, v):continue# 边界节点与边界节点互不相连,排除if Utils.IsBoundaryNode(width, height, i, j) and Utils.IsBoundaryNode(width, height, u, v):continue# 生成边node2 = (u, v)edge = (node1, node2)self.network.edges.append(edge)self.network.outEdges[node1].append(edge)self.network.inEdges[node2].append(edge)passfor lane in range(len(turn)):dir2 = (dir + turn[lane] + len(dx)) % len(dx)x = u + dx[dir2]y = v + dy[dir2]# (i, j)->(u,v)->(x,y)# 排除非法的if Utils.IsIllegalNode(width, height, x, y):continue# 角落不需要生成if Utils.IsCornerNode(width, height, x, y):continue# 边界节点与边界节点互不相连if Utils.IsBoundaryNode(width, height, u, v) and Utils.IsBoundaryNode(width, height, x, y):continue# 生成连接node3 = (x, y)connection = (node1, node2, node3, lane)self.network.connections.append(connection)passpasspasspassreturn self.network
生成路径(route)
SUMO Road Networks - SUMO Documentation (dlr.de)
我们使用回溯算法生成所有可能的路径。
由于该算法的时间开销较大,如果地图大小超过4*4,那么建议导入路径而不是生成
import xml.dom
import numpy as np
import Utils
from Network import Network
from collections import defaultdictfrom sample.Utils import _GetEdgesOfRouteclass SumoFileGenerator:def __init__(self):self.cwd = None # 输出目录self.name = None # 文件名self.network = None # 道路网络# for dfsself._visit = Noneself._path = Noneself._ans = Nonepassdef _dfsrc(self, nodeP: tuple or None, nodeU: tuple):# 深度优先搜索递归核心 Depth First Search Recursive Coreif nodeU in self.network.boundaryNodes and nodeP is not None:self._ans.append([x for x in self._path])returnfor _, nodeV in self.network.outEdges[nodeU]:if self._visit[nodeV] is True:continueself._visit[nodeV] = Trueself._path.append(nodeV)self._dfsrc(nodeU, nodeV)self._path.pop()self._visit[nodeV] = Falsepassdef _GetRoutes(self, nodeU: tuple) -> list:# 生成所有以 nodeU 为起点的路径self._visit = defaultdict(bool)self._path = []self._ans = []self._visit[nodeU] = Trueself._path.append(nodeU)self._dfsrc(None, nodeU)return self._anspassdef _GenerateRouteFile(self, avgCarAmount, timePeriod)://...pass
生成车辆(vehicle)
用分布来模拟车辆到达,实际上是在采样。因为各个样本点独立同分布
设随机变量X是车辆到达的数量,P{X=k}是有k辆车到达的概率。
我们采取timePeriod个样本,各个样本就对应了各个时刻车辆的到达情况。
def _GenerateRouteFile(self, avgCarAmount, timePeriod):// ...# 创建车辆arrivals = np.random.poisson(avgCarAmount, timePeriod)vehicleId = 0for time in range(len(arrivals)):for i in range(arrivals[time]):rootElement.appendChild(Utils.ToXMLElement("vehicle","id", "%08d" % (vehicleId),"type", "typeCar","route", routeIds[np.random.randint(0, len(routeIds))],"depart", "%d" % (time),))vehicleId += 1pass// ...pass
生成交通信号灯(tlLogic)
直接遍历network中的交通灯节点,然后生成对应的XML元素,其中:
- id是节点id
- programID是随便填的
- 相位暂时使用默认相位,以进行测试
def _GenerateDefaultPhases(self) -> list:ret = []phase = "ggggrrgrrgrr"for i in range(4):ret.append(("17", phase))ret.append(("3", phase.replace("g", "y")))phase = phase[3:] + phase[:3]return retpassdef _GenerateTrafficLightFile(self):# *.add.xml,# 创建一个XML文档对象doc = xml.dom.minidom.Document()rootElement = doc.createElement("additional") # 根节点doc.appendChild(rootElement)defaultPhases = self._GenerateDefaultPhases() # 使用默认相位进行测试# attribute = ["id", "type", "programID", "offset"]for node in self.network.tlNodes:# 遍历交通灯节点TLElement = doc.createElement("tlLogic")rootElement.appendChild(TLElement)TLElement.setAttribute("id", Utils.GetNodeId(*node))TLElement.setAttribute("type", "static")TLElement.setAttribute("programID", "runner")TLElement.setAttribute("offset", "0")# 交通灯的相位for duration, state in defaultPhases:phaseElement = doc.createElement("phase")phaseElement.setAttribute("duration", duration)phaseElement.setAttribute("state", state)TLElement.appendChild(phaseElement)with open("%s/%s.add.xml" % (self.cwd, self.name), "w") as fileOut:fileOut.write(doc.toprettyxml())pass
生成探测器(detector)
为了使探测器能覆盖整条道路,我们只填入pos属性,而不填入endPos或length属性。
def _GenerateDetectorFile(self):# *.det.xml,# 创建一个XML文档对象doc = xml.dom.minidom.Document()rootElement = doc.createElement("additional") # 根节点doc.appendChild(rootElement)# attribute = ["id", "lane", "pos", "file", "friendlyPos"]for (i, j), (u, v) in self.network.edges:for lane in range(3):rootElement.appendChild(Utils.ToXMLElement("laneAreaDetector","id", Utils.GetDetectorId(i, j, u, v, lane),"lane", Utils.GetLaneId(i, j, u, v, lane),"pos", "0",# "endPos", "100",# "length", "%d" % (72.80),"file", "%s/%s.out.xml" % (self.cwd, self.name),"friendlyPos", "true", ))with open("%s/%s.det.xml" % (self.cwd, self.name), "w") as fileOut:fileOut.write(doc.toprettyxml())pass
py程序接口(TraCI)
TraCI 采用基于 TCP 的客户端/服务器架构来访问sumo。因此,使用附加命令行选项启动时,sumo将充当服务器:–remote-port <INT>,其中 是sumo用于监听传入连接的端口。
当使用 –remote-port<INT>选项启动时,sumo只准备模拟,等待所有外部应用程序连接并接管控制权。请注意,当sumo作为 TraCI 服务器运行时,–end <TIME>选项将被忽略。
使用sumo-gui作为服务器时,在处理 TraCI 命令之前,必须通过使用播放按钮或设置选项 –start来启动模拟。
import os
import sys
from FileGenerator import FileGenerator
from Network import Networktry:sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', "tools")) # tutorial in testssys.path.append(os.path.join(os.environ.get("SUMO_HOME", os.path.join(os.path.dirname(__file__), "..", "..", "..")), "tools")) # tutorial in docssys.path.append("/usr/local/Cellar/sumo/1.2.0/share/sumo/tools")from sumolib import checkBinary # noqa
except ImportError:sys.exit("please declare environment variable 'SUMO_HOME' as the root directory of your sumo installation""(it should contain folders 'bin', 'tools' and 'docs')")import traci# ====================================================================================================# adapted from SUMO tutorials
def run(network: Network):"""execute the TraCI control loop"""# step = 0# amber = 0# waits = []# phase = [0, 0, 0, 0, 0, 0, 0, 0, 0]# for i in range(0, NUM_JUNCTIONS):# waits.append([0] * len(PHASES))cnt = 0while traci.simulation.getMinExpectedNumber() > 0: # step <= 900:traci.simulationStep()traci.trafficlight.setPhase("11", cnt % 2)traci.trafficlight.setPhase("22", cnt % 2)cnt = cnt + 1# if step % PHASE_LENGTH == 0:# for i in range(0, NUM_JUNCTIONS):# if MAX_WAIT in waits[i]:# phase[i] = waits[i].index(MAX_WAIT)# else:# if noPhaseChange(phase[i], i) != True:# phase[i] = backPressure(i)# amber = amber + 1# traci.trafficlight.setPhase("0" + getNodeId(i), phase[i])# for j in range(0, len(PHASES), 2):# if j == phase[i]:# waits[i][j] = 0# else:# if waits[i][j] < MAX_WAIT:# waits[i][j] += 1# step += 1# logging.warning(amber)traci.close()sys.stdout.flush()if __name__ == '__main__':# constCWD = os.getcwd() + "/data"NAME = "sample"OUTPUTDIR = os.getcwd() + "/output"NETCONVERT = checkBinary('netconvert')SUMO = checkBinary('sumo-gui')# maingenerator = FileGenerator()generator.GenerateAllFile(NETCONVERT, CWD, NAME,2, 2, 100,2, 10) # 生成文件print("GenerateAll finish")traci.start([SUMO,"-c", "%s/%s.sumocfg" % (CWD, NAME),"--tripinfo-output", "%s/%s.tripinfo.xml" % (OUTPUTDIR, NAME),"--summary", "%s/%s.sum.xml" % (OUTPUTDIR, NAME)])run(generator.network)
附录
node
PlainXML - SUMO Documentation (dlr.de)
nod
的属性:
属性名称 | 类型 | 说明 |
---|---|---|
id | id (string) | 节点名称 |
x | float | 节点在平面上的 x 位置,以米为单位 |
y | float | 节点在平面上的 y 轴位置,以米为单位 |
z | float | 节点在平面上的 Z 位置,以米为单位 |
type | enum ( “priority”, “traffic_light”……) | 节点的可选类型 |
edge
PlainXML - SUMO Documentation (dlr.de)
edge
的属性:
属性名称 | 类型 | 说明 |
---|---|---|
id | id (string) | 边的 ID(必须唯一) |
from | referenced node id | The name of a node within the nodes-file the edge shall start at |
to | referenced node id | The name of a node within the nodes-file the edge shall end at |
type | referenced type id | The name of a type within the SUMO edge type file |
connection
PlainXML - SUMO Documentation (dlr.de)
SUMO Road Networks - SUMO Documentation (dlr.de)
connection
的属性:
名称 | 类型 | 说明 |
---|---|---|
from | edge id (string) | 开始连接的输入边 ID |
to | edge id (string) | 连接结束时出线边的 ID |
fromLane | index (unsigned int) | 开始连接的输入边的车道 |
toLane | index (unsigned int) | 连接结束时出线边缘的车道 |
route
Definition of Vehicles, Vehicle Types, and Routes - SUMO Documentation (dlr.de)
route
的属性:
属性名称 | 价值类型 | 说明 |
---|---|---|
id | id (string) | 路线名称 |
edges | id list | 车辆应行驶的路线,以 ID 表示,用空格隔开 |
vehicle
Definition of Vehicles, Vehicle Types, and Routes - SUMO Documentation (dlr.de)
vType
的属性:
属性名称 | 价值类型 | 默认值 | 说明 |
---|---|---|---|
id | id (string) | - | 车辆类型名称 |
accel | float | 2.6 | 此类车辆的加速能力(单位:m/s^2) |
decel | float | 4.5 | 此类车辆的减速能力(单位:m/s^2) |
sigma | float | 0.5 | 汽车跟随模型参数,见下文 |
length | float | 5.0 | 车辆长度(米) |
minGap | float | 2.5 | 最小车距(米) |
maxSpeed | float | 55.55(200 km/h), | 车辆的最大速度(米/秒) |
guiShape | shape (enum) | “unknown” | 绘制车辆形状。默认情况下,绘制的是标准客车车身。 |
vehicle
的属性:
属性名称 | 价值类型 | 说明 |
---|---|---|
id | string | 车辆名称 |
type | string | 该车辆使用的车辆类型 ID |
route | string | 车辆行驶路线的 ID |
depart | float(s) | 车辆进入网络的时间步长 |
tlLogic
Traffic Lights - SUMO Documentation (dlr.de)
tlLogic
的属性:
属性名称 | 价值类型 | 说明 |
---|---|---|
id | id (string) | 交通信号灯的 id。必须是 .net.xml 文件中已有的交通信号灯 id。交通信号灯的 id 通常与路口 id 相同。名称可通过右键单击受控路口前的红/绿条获得。 |
type | enum (static, actuated, delay_based) | 交通信号灯的类型(固定相位持续时间、基于车辆间时间间隔的相位延长(驱动式)或基于排队车辆累积时间损失的相位延长(基于延迟式) ) |
programID | id (string) | 交通灯程序的 id;必须是交通灯 id 的新程序名称。请注意,"off "为保留名,见下文。 |
offset | int | 程序的初始时间偏移 |
phase
的属性:
属性名称 | 价值类型 | 说明 |
---|---|---|
duration | time (int) | 阶段的持续时间 |
state | list of signal states | 该阶段的红绿灯状态如下 |
对于控制单个交叉路口的交通信号灯,由 netconvert 生成的默认指数以顺时针方式编号,从 12 点钟方向的 0 开始,右转顺序在直行和左转之前。人行横道总是被分配在最后,也是按顺时针方向。
如果将交通信号灯连接起来,由一个程序控制多个交叉路口,则每个交叉路口的排序保持不变,但指数会根据输入文件中受控路口的顺序增加。
例如:ggrgrrrggrrg
对应:
TraCI
TraCI - SUMO Documentation (dlr.de)
Detector
Detector - SUMO Documentation (dlr.de)
Lanearea Detectors (E2) - SUMO Documentation (dlr.de)
Attribute Name | Value Type | Description |
---|---|---|
id | id (string) | A string holding the id of the detector |
lane | referenced lane id | The id of the lane the detector shall be laid on. The lane must be a part of the network used. This argument excludes the argument lanes. |
pos | float | The position on the first lane covered by the detector. See information about the same attribute within the detector loop description for further information. Per default, the start position is placed at the first lane’s begin. |
endPos | float | The end position on the last lane covered by the detector. Per default the end position is placed at the last lane’s end. |
length | float | The length of the detector in meters. If the detector reaches over the lane’s end, it is extended to preceding / consecutive lanes. |
file | filename | The path to the output file. The path may be relative. |
friendlyPos | bool | If set, no error will be reported if the detector is placed behind the lane. Instead, the detector will be placed 0.1 meters from the lane’s end or at position 0.1, if the position was negative and larger than the lane’s length after multiplication with -1; default: false. |
simulation
参考资料
SUMO官方文档
SUMO学习入门(一)SUMO介绍 - 知乎 (zhihu.com)
SUMO 从入门到基础 SUMO入门一篇就够了_sumo文档-CSDN博客
XML - Wikipedia
有关文件
windows安装包:
sumo-win64-1.19.0.msi
相关文章:

基于sumo实现交通灯控制算法的模板
基于sumo实现交通灯控制算法的模板 目录 在windows安装run hello world networkroutesviewsettings & configurationsimulation 交通灯控制系统 介绍文件生成器类(FileGenerator)道路网络(Network)辅助函数生成道路网络&am…...

设计模式之单例模式的懒饿汉
懒汉式 说白了就是你不叫我我不动,你叫我我才动。 类初始化模式,也叫延迟占位模式。在单例类的内部由一个私有静态内部类来持有这个单例类的实例。因为在 JVM 中,对类的加载和类初始化,由虚拟机保证线程安全。 public class Singl…...

多平台多账号一站式短视频管理矩阵营销系统下载
矩阵营销系统多平台多账号一站式管理,一键发布作品。智能标题,关键词优化,排名查询,混剪生成原创视频,账号分组,意向客户自动采集,智能回复,多账号评论聚合回复,免切换&a…...

go work
vscode gopls插件工具依赖go work,否则会报错 https://github.com/golang/tools/blob/master/gopls/doc/workspace.md Go 1.18 新特性多模块工作区教程-让多模块开发变得简单 - Go语言中文网 - Golang中文社区...

基于JavaWeb+BS架构+SpringBoot+Vue智能菜谱推荐系统的设计和实现
基于JavaWebBS架构SpringBootVue智能菜谱推荐系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 目 录 目 录 III 第一章 概述 1 1.1 研究背景 1 1.2研究目的及意义 1 1.3…...

SpringSecurity集成JWT实现后端认证授权保姆级教程-授权配置篇
🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 💒 公众号:知识浅谈 🔥网站…...

关系型非关系型数据库区别,以MongoDB为例在express中连接MongoDB示例
目录 关系型数据库 关系型数据库常见的类型有: 关系型数据库的优点包括: 非关系型数据库 非关系型数据库常见的类型有: 非关系型数据库的特点包括: 关系型数据库和非关系型数据库区别 MongoDB是什么 MongoDB优势ÿ…...

Java版商城:Spring Cloud+SpringBoot b2b2c实现多商家入驻直播带货及 免 费 小程序商城搭建的完整指南
随着互联网的快速发展,越来越多的企业开始注重数字化转型,以提升自身的竞争力和运营效率。在这个背景下,鸿鹄云商SAAS云产品应运而生,为企业提供了一种简单、高效、安全的数字化解决方案。 鸿鹄云商SAAS云产品是一种基于云计算的软…...

【Spring Boot】SpringBoot maven 项目创建图文教程
创建一个Spring Boot项目并使用Maven进行构建是一项相对简单的任务。以下是使用IntelliJ IDEA创建Spring Boot Maven项目的详细教程: 步骤 1:安装 IntelliJ IDEA 确保你已经安装了最新版本的 IntelliJ IDEA。你可以从官方网站下载并安装。 步骤 2&am…...

【Python】Sigmoid和Hard Sigmoid激活函数对比总结及示例
Sigmoid和Hard Sigmoid是两种常用的激活函数,它们在神经网络中起到非线性变换的作用。以下是它们之间的对比和优缺点总结: Sigmoid激活函数: 优点: 输出范围是0到1之间,可以用于二分类问题。函数形状相对平滑&#…...

ajax+axios——统一设置请求头参数——添加请求头入参——基础积累
最近在写后台管理系统(我怎么一直都只写管理系统啊啊啊啊啊啊啊),遇到一个需求,就是要在原有系统的基础上,添加一个仓库的切换,并且需要把选中仓库对应的id以请求头参数的形式传递到每一个接口当中。。。 …...

Redis高可用(主从复制、哨兵模式和Cluster集群)
目录 前瞻 主从复制 哨兵 集群 主从复制 主从复制的作用 主从复制流程 搭建Redis主从复制 实验准备 实验流程 修改 Redis 配置文件(Master节点操作) 修改 Redis 配置文件(Slave节点操作) 验证主从效果 哨兵模式 哨兵…...

【Web】CTFSHOW PHP命令执行刷题记录(全)
目录 web29 web30 web31 web32 web33 web34 web35 web36 web37-39 web40 web41 (y4✌脚本) web42 -44 web45 web46 -49 web50 web51 web52 web53 web54 web55-56 web57 web58 web59 web60 web61 web62 web63-65 web66-67 w…...

鸿蒙开发已解决-Failed to connect to gitee.com port 443: Time out 连接超时提示
文章目录 项目场景:问题描述原因分析:解决方案:解决方案1解决方案2:解决方案3:此Bug解决方案总结解决方案总结**心得体会:解决连接超时问题的三种方案**项目场景: 导入Sample时遇到导入失败的情况,并提示“Failed to connect to gitee.com port 443: Time out”连接超…...

使用cURL命令在Linux中测试HTTP服务器的性能
cURL是一个强大的命令行工具,用于从或向服务器传输数据。它支持多种协议,包括HTTP、HTTPS、FTP等。在Linux系统中,cURL可以用于测试和评估HTTP服务器的性能。下面是一些使用cURL命令测试HTTP服务器性能的示例和说明。 1. 基本请求 要向指定…...

机器学习 -- 余弦相似度
场景 我有一个 页面如下(随便找的): 我的需求是拿到所有回答的链接, 再或者我在找房子网上,爬到所有的房产信息,我们并不想做过多的处理,我只要告诉程序,请帮我爬一个类似 xxx 相似…...

LeNet-5(fashion-mnist)
文章目录 前言LeNet模型训练 前言 LeNet是最早发布的卷积神经网络之一。该模型被提出用于识别图像中的手写数字。 LeNet LeNet-5由以下两个部分组成 卷积编码器(2)全连接层(3) 卷积块由一个卷积层、一个sigmoid激活函数和一个…...

Unity中URP下开启和使用深度图
文章目录 前言一、在Unity中打开URP下的深度图二、在Shader中开启深度图1、使用不透明渲染队列才可以使用深度图2、半透明渲染队列深度图就会关闭 三、URP深度图 和 BRP深度图的区别四、在Shader中,使用深度图1、定义纹理和采样器2、在片元着色器对深度图采样并且输…...

类似东郊到家上门预约系统需要具备哪些功能,预约系统应该怎么做
随着上门服务需求的持续增长,各类APP小程序应运而生。吸引了无数商家投资者,纷纷想要开发一款类似于"东郊到家"这样的上门服务软件。要想成功,这样的软件需具备以下核心功能: 1. 快速注册与登录:用户能通过手…...

鸿蒙APP和Android的区别
鸿蒙(HarmonyOS)和Android是两个不同的操作系统,它们有一些区别,包括架构、开发者支持、应用生态和一些设计理念。以下是鸿蒙APP和Android APP之间的一些主要区别,希望对大家有所帮助。北京木奇移动技术有限公司&#…...

给Flutter + FireBase 增加 badge 徽章,App启动器 通知红点。
在此之前需要配置好 firebase 在flutter 在项目中。(已经配置好的可以忽略此提示) Firebase 配置教程:flutter firebase 云消息通知教程 (android-安卓、ios-苹果)_flutter firebase_messaging ios环境配置-CSDN博客 由于firebase 提供的消息…...

2024年中国杭州|网络安全技能大赛(CTF)正式开启竞赛报名
前言 一、CTF简介 CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。CTF起源于1996年DEFCON全球黑客大会,以代替之前黑客们通过互相发起真实攻击进行技术比拼的…...

112.Qt中的窗口类
我们在通过Qt向导窗口基于窗口的应用程序的项目过程中倒数第二步让我们选择跟随项目创建的第一个窗口的基类, 下拉菜单中有三个选项, 分别为: QMainWindow、QDialog、QWidget如下图: 常用的窗口类有3个 在创建Qt窗口的时候, 需要让自己的窗口类继承上述三个窗口类的…...

如何设置电脑桌面提醒,电脑笔记软件哪个好?
对于大多数上班族来说,每天要完成的待办事项实在太多了,如果不能及时去处理,很容易因为各种因素导致忘记,从而给自己带来不少麻烦。所以,我们往往会借助一些提醒类的软件将各项任务逐一记录下来,然后设置上…...

C# HttpClient Get Post简单封装
文章目录 前言封装好的代码测试接口测试代码 前言 微软官方有Get和Post请求,我把他简单化处理一下 封装好的代码 public class MyHttpHelper{private string baseUrl;/// <summary>/// 基础Api/// </summary>public string BaseUrl{get{return baseUr…...

创建网格(Grid/GridItem)
目录 1、概述 2、布局与约束 3、设置排列方式 3.1设置行列数量与占比 3.2、设置子组件所占行列数 3.3、设置主轴方向 3.4、在网格布局中显示数据 3.5、设置行列间距 4、构建可滚动的网格布局 5、实现简单的日历功能 6、性能优化 1、概述 网格布局是由“行”和“列”分…...

思科路由器忘记密码怎么重置
断电重启路由器,在开机过程中按下CtrlPause/break,或者只按下Pause/break(没有测试),在PT(Cisco Packet Tracert)中则需要按CtrlC。路由器会进入rommon >模式。 切换到0x2142模式࿰…...

JVM基础(2)——JVM内存模型
一、简介 JVM会加载类到内存中,所以 JVM 中必然会有一块内存区域来存放我们写的那些类。Java中有类对象、普通对象、本地变量、方法信息等等各种对象信息,所以JVM会对内存区域进行划分: JDK1.8及以后,上图中的方法区变成了Metasp…...

使用 Process Explorer 和 Windbg 排查软件线程堵塞问题
目录 1、问题说明 2、线程堵塞的可能原因分析 3、使用Windbg和Process Explorer确定线程中发生了死循环 4、根据Windbg中显示的函数调用堆栈去查看源码,找到问题 4.1、在Windbg定位发生死循环的函数的方法 4.2、在Windbg中查看变量的值去辅助分析 4.3、是循环…...

做科技类的展台3d模型用什么材质比较好---模大狮模型网
对于科技类展台3D模型,以下是几种常用的材质选择: 金属材质:金属材质常用于科技展台的现代感设计,如不锈钢、铝合金或镀铬材质。金属材质可以赋予展台一个科技感和高档感,同时还可以反射光线,增加模型的真实…...