Skip to content

Commit

Permalink
Add auto_rename, windows test
Browse files Browse the repository at this point in the history
  • Loading branch information
toruseo committed Mar 21, 2024
1 parent f5b4485 commit 64cc98c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/run-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ on:

jobs:
run-examples:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.9", "3.12"]
steps:
- uses: actions/checkout@v4
Expand Down
44 changes: 32 additions & 12 deletions uxsim/uxsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

import numpy as np
import matplotlib.pyplot as plt
import random, glob, os, csv, time
import random, glob, os, csv, time, math, string
import pandas as pd
import math
from PIL import Image, ImageDraw, ImageFont, ImageOps
from PIL.Image import Resampling, Transpose
from tqdm.auto import tqdm
Expand All @@ -26,7 +25,7 @@ class Node:
"""
Node in a network.
"""
def __init__(s, W, name, x, y, signal=[0], signal_offset=0, flow_capacity=None):
def __init__(s, W, name, x, y, signal=[0], signal_offset=0, flow_capacity=None, auto_rename=False):
"""
Create a node
Expand All @@ -48,6 +47,8 @@ def __init__(s, W, name, x, y, signal=[0], signal_offset=0, flow_capacity=None):
The offset of the signal. Default is 0.
flow_capacity : float, optional
The maximum flow capacity of the node. Default is None, meaning infinite capacity.
auto_rename : bool, optional
Whether to automatically rename the node if the name is already used. Default is False.
Attributes
----------
Expand Down Expand Up @@ -106,7 +107,10 @@ def __init__(s, W, name, x, y, signal=[0], signal_offset=0, flow_capacity=None):
s.id = len(s.W.NODES)
s.name = name
if s.name in [n.name for n in s.W.NODES]:
raise ValueError(f"Node name {s.name} already used by another node. Please specify a unique name.")
if auto_rename:
s.name = s.name+"_renamed"+"".join(random.choices(string.ascii_letters + string.digits, k=8))
else:
raise ValueError(f"Node name {s.name} already used by another node. Please specify a unique name.")
s.W.NODES.append(s)

def __repr__(s):
Expand Down Expand Up @@ -254,7 +258,7 @@ class Link:
"""
Link in a network.
"""
def __init__(s, W, name, start_node, end_node, length, free_flow_speed, jam_density, merge_priority=1, signal_group=0, capacity_out=None, capacity_in=None, eular_dx=None, attribute=None):
def __init__(s, W, name, start_node, end_node, length, free_flow_speed, jam_density, merge_priority=1, signal_group=0, capacity_out=None, capacity_in=None, eular_dx=None, attribute=None, auto_rename=False):
"""
Create a link
Expand Down Expand Up @@ -286,6 +290,8 @@ def __init__(s, W, name, start_node, end_node, length, free_flow_speed, jam_dens
The default space aggregation size for link traffic state computation, default is None. If None, the global eular_dx value is used.
attribute : any, optinonal
Additional (meta) attributes defined by users.
auto_rename : bool, optional
Whether to automatically rename the link if the name is already used. Default is False.
Attributes
----------
Expand Down Expand Up @@ -373,7 +379,10 @@ def __init__(s, W, name, start_node, end_node, length, free_flow_speed, jam_dens
s.id = len(s.W.LINKS)
s.name = name
if s.name in [l.name for l in s.W.LINKS]:
raise ValueError(f"Link name {s.name} already used by another link. Please specify a unique name.")
if auto_rename:
s.name = s.name+"_renamed"+"".join(random.choices(string.ascii_letters + string.digits, k=8))
else:
raise ValueError(f"Link name {s.name} already used by another link. Please specify a unique name.")
s.W.LINKS.append(s)
s.start_node.outlinks[s.name] = s
s.end_node.inlinks[s.name] = s
Expand Down Expand Up @@ -610,7 +619,7 @@ class Vehicle:
"""
Vehicle or platoon in a network.
"""
def __init__(s, W, orig, dest, departure_time, name=None, route_pref=None, route_choice_principle=None, links_prefer=[], links_avoid=[], trip_abort=1, departure_time_is_time_step=0, attribute=None):
def __init__(s, W, orig, dest, departure_time, name=None, route_pref=None, route_choice_principle=None, links_prefer=[], links_avoid=[], trip_abort=1, departure_time_is_time_step=0, attribute=None, auto_rename=False):
"""
Create a vehicle (more precisely, platoon)
Expand Down Expand Up @@ -638,6 +647,8 @@ def __init__(s, W, orig, dest, departure_time, name=None, route_pref=None, route
Whether to abort the trip if a dead end is reached, default is 1.
attribute : any, optinonal
Additional (meta) attributes defined by users.
auto_rename : bool, optional
Whether to automatically rename the vehicle if the name is already used. Default is False.
"""

s.W = W
Expand Down Expand Up @@ -709,8 +720,11 @@ def __init__(s, W, orig, dest, departure_time, name=None, route_pref=None, route
s.name = name
else:
s.name = str(s.id)+"_autoid"
# if s.name in [veh.name for veh in s.W.VEHICLES.values()]:
# raise ValueError(f"Vehicle name {s.name} already used by another vehicle. Please specify a unique name.")
if s.name in [veh.name for veh in s.W.VEHICLES.values()]:
if auto_rename:
s.name = s.name+"_renamed"+"".join(random.choices(string.ascii_letters + string.digits, k=8))
else:
raise ValueError(f"Vehicle name {s.name} already used by another vehicle. Please specify a unique name.")
s.W.VEHICLES[s.name] = s
s.W.VEHICLES_LIVING[s.name] = s

Expand Down Expand Up @@ -2626,12 +2640,12 @@ def osm_network_to_World(W, nodes, links, default_jam_density=0.2, coef_degree_t
nname = str(node[0])
if nname in [n.name for n in W.NODES.values()]:
nname + f"_osm{i}"
W.addNode(str(node[0]), x=node[1], y=node[2])
W.addNode(str(node[0]), x=node[1], y=node[2], auto_rename=True)
for i, link in enumerate(links):
lname = str(link[0])
if lname in [l.name for l in W.LINKS.values()]:
lname + f"_osm{i}"
W.addLink(lname, str(link[1]), str(link[2]), length=link[5]*coef_degree_to_meter, free_flow_speed=link[4], jam_density=default_jam_density)
W.addLink(lname, str(link[1]), str(link[2]), length=link[5]*coef_degree_to_meter, free_flow_speed=link[4], jam_density=default_jam_density, auto_rename=True)


class World:
Expand Down Expand Up @@ -2748,6 +2762,8 @@ def addNode(W, *args, **kwargs):
The offset of the signal. Default is 0.
flow_capacity : float, optional
The maximum flow capacity of the node. Default is None, meaning infinite capacity.
auto_rename : bool, optional
Whether to automatically rename the node if the name is already used. Default is False.
Returns
-------
Expand Down Expand Up @@ -2782,7 +2798,7 @@ def addLink(W, *args, **kwargs):
merge_priority : float, optional
The priority of the link when merging at the downstream node, default is 1.
signal_group : int or list, optional
The signal group to which the link belongs, default is 0.
The signal group to which the link belongs, default is 0. If `signal_group` is int, say 0, it becomes green if `end_node.signal_phase` is 0. the If `signal_group` is list, say [0,1], it becomes green if the `end_node.signal_phase` is 0 or 1.
capacity_out : float, optional
The capacity out of the link, default is calculated based on other parameters.
capacity_in : float, optional
Expand All @@ -2791,6 +2807,8 @@ def addLink(W, *args, **kwargs):
The default space aggregation size for link traffic state computation, default is None. If None, the global eular_dx value is used.
attribute : any, optinonal
Additional (meta) attributes defined by users.
auto_rename : bool, optional
Whether to automatically rename the link if the name is already used. Default is False.
Returns
-------
Expand Down Expand Up @@ -2830,6 +2848,8 @@ def addVehicle(W, *args, **kwargs):
Whether to abort the trip if a dead end is reached, default is 1.
attribute : any, optinonal
Additional (meta) attributes defined by users.
auto_rename : bool, optional
Whether to automatically rename the vehicle if the name is already used. Default is False.
Returns
-------
Expand Down

0 comments on commit 64cc98c

Please sign in to comment.