Replies: 1 comment 2 replies
-
|
Hi, thanks for using UXsim and your careful observation! Indeed, this is a complicated issue, as it is also related to the route choice model. I was aware of this kind of U-turn movements and thought that this is a minor issue, but after some investigation, I recognize that this is not very minor. Please give me some time to find the best way to fix this issue. In the meantime, you can use the following workaround (so-called "monkey patch") to eliminate U-turn. This is little bit complicated, but I confirmed that it works. Insert this code block import types
def route_next_link_choice_mod(s):
"""
Select a next link from the current link.
"""
if s.specified_route == None:
if s.dest != s.link.end_node:
outlinks = list(s.link.end_node.outlinks.values())
if len(outlinks):
#if links_prefer is given and available at the node, select only from the links in the list. if links_avoid is given, select links not in the list.
if set(outlinks) & set(s.links_prefer):
outlinks = sorted(set(outlinks) & set(s.links_prefer), key=lambda l:l.name)
if set(outlinks) & set(s.links_avoid):
outlinks = sorted(set(outlinks) - set(s.links_avoid), key=lambda l:l.name)
#this restrict vehicle's U-turn-like movements
traveled_nodes = set([l[1].start_node for l in s.log_t_link[1:]])
outlinks_no_overlapping_nodes = [l for l in outlinks if l.end_node not in traveled_nodes]
if len(outlinks_no_overlapping_nodes) > 0:
outlinks = outlinks_no_overlapping_nodes
preference = np.array([s.route_pref[l.id] for l in outlinks], dtype=float)
if s.W.hard_deterministic_mode == False:
if sum(preference) > 0:
s.route_next_link = s.W.rng.choice(outlinks, p=preference/sum(preference))
else:
s.route_next_link = s.W.rng.choice(outlinks)
else:
s.route_next_link = max(zip(preference, outlinks), key=lambda x:x[0])[1]
else:
s.route_next_link = None
else:
outlinks = list(s.link.end_node.outlinks.values())
if len(outlinks):
number_of_traveled_links = len(s.log_t_link)-1
if s.specified_route[number_of_traveled_links] in outlinks:
s.route_next_link = s.specified_route[number_of_traveled_links]
else:
raise ValueError(f"Vehicle {s.name}: specified route {s.specified_route} is inconsistent at the current link {s.link}. Debug info: {number_of_traveled_links=}, {outlinks=}")
else:
s.route_next_link = None
for veh in W.VEHICLES.values():
veh.route_next_link_choice = types.MethodType(route_next_link_choice_mod, veh)just before you call |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello! I've been using UXsim for my masters project in urban planning to predict a load on an existing street grid from a new development, and it's been of great help so far, thanks a lot!! But recently I ran into some weird car behavior. In network_fancy animation it seems that cars do a U turn in a node with 2 links, which is a straight street. Normally when driving you would have to find some side road or an intersection to do a 180 turn. Unless the street is completely empty, you can't just do that in the middle of it. And that can happen several times in a row with the same car in the same node, as it seeks for an optimal path, i suppose.
This observation led me to look for a way to restrict turn possibilities in a node, cause besides the U turn example, there might be other cases where you can't turn left on an intersection, for instance, But right now i can't seem to find a feature to do that. I'm new to python, but i imagine this could be done in a form of a matrix with booleans, stored as a node parameter, where you could set connections between all links in a node, e.g. L1 - L3 = True, L1 - L2 (180 turn) = False, etc. By default, all connection would be True. This would improve the accuracy of simulation, and make animation more believable. Have you ever considered adding something like this?
Beta Was this translation helpful? Give feedback.
All reactions