2020-08-09 17:51:13 +03:00
<!DOCTYPE HTML>
< html lang = "en" class = "sidebar-visible no-js light" >
< head >
<!-- Book generated using mdBook -->
< meta charset = "UTF-8" >
< title > Gridlock - A/B Street< / title >
< meta content = "text/html; charset=utf-8" http-equiv = "Content-Type" >
< meta name = "description" content = "" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< meta name = "theme-color" content = "#ffffff" / >
< link rel = "shortcut icon" href = "../favicon.png" >
< link rel = "stylesheet" href = "../css/variables.css" >
< link rel = "stylesheet" href = "../css/general.css" >
< link rel = "stylesheet" href = "../css/chrome.css" >
< link rel = "stylesheet" href = "../css/print.css" media = "print" >
<!-- Fonts -->
< link rel = "stylesheet" href = "../FontAwesome/css/font-awesome.css" >
< link href = "https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel = "stylesheet" type = "text/css" >
< link href = "https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel = "stylesheet" type = "text/css" >
<!-- Highlight.js Stylesheets -->
< link rel = "stylesheet" href = "../highlight.css" >
< link rel = "stylesheet" href = "../tomorrow-night.css" >
< link rel = "stylesheet" href = "../ayu-highlight.css" >
<!-- Custom theme stylesheets -->
< / head >
< body >
<!-- Provide site root to javascript -->
< script type = "text/javascript" >
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
< / script >
<!-- Work around some values being stored in localStorage wrapped in quotes -->
< script type = "text/javascript" >
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') & & theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') & & sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
< / script >
<!-- Set the theme before any content is loaded, prevents flash -->
< script type = "text/javascript" >
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
< / script >
<!-- Hide / unhide sidebar before it is displayed -->
< script type = "text/javascript" >
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
< / script >
< nav id = "sidebar" class = "sidebar" aria-label = "Table of contents" >
< div class = "sidebar-scrollbox" >
2020-11-09 22:42:58 +03:00
< ol class = "chapter" > < li class = "chapter-item expanded " > < a href = "../index.html" > < strong aria-hidden = "true" > 1.< / strong > Overview< / a > < / li > < li class = "chapter-item expanded " > < a href = "../howto/index.html" > < strong aria-hidden = "true" > 2.< / strong > Instructions< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../howto/map_parking.html" > < strong aria-hidden = "true" > 2.1.< / strong > How to map on-street parking< / a > < / li > < li class = "chapter-item expanded " > < a href = "../howto/new_city.html" > < strong aria-hidden = "true" > 2.2.< / strong > Importing a new city< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../how_it_works.html" > < strong aria-hidden = "true" > 3.< / strong > How it works< / a > < / li > < li class = "chapter-item expanded " > < a href = "../case_studies/index.html" > < strong aria-hidden = "true" > 4.< / strong > Case studies< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../case_studies/lake_wash.html" > < strong aria-hidden = "true" > 4.1.< / strong > Lake Washington Blvd Stay Healthy Street< / a > < / li > < li class = "chapter-item expanded " > < a href = "../case_studies/west_seattle.html" > < strong aria-hidden = "true" > 4.2.< / strong > West Seattle mitigations< / a > < / li > < li class = "spacer" > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../dev/index.html" > < strong aria-hidden = "true" > 5.< / strong > Developer guide< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../dev/misc_tricks.html" > < strong aria-hidden = "true" > 5.1.< / strong > Misc developer tricks< / a > < / li > < li class = "chapter-item expanded " > < a href = "../dev/api.html" > < strong aria-hidden = "true" > 5.2.< / strong > API< / a > < / li > < li class = "chapter-item expanded " > < a href = "../dev/testing.html" > < strong aria-hidden = "true" > 5.3.< / strong > Testing< / a > < / li > < li class = "chapter-item expanded " > < a href = "../dev/mass_import.html" > < strong aria-hidden = "true" > 5.4.< / strong > Importing many maps< / a > < / li > < li class = "chapter-item expanded " > < a href = "../dev/data.html" > < strong aria-hidden = "true" > 5.5.< / strong > Data organization< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../map/index.html" > < strong aria-hidden = "true" > 6.< / strong > Map model< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../map/details.html" > < strong aria-hidden = "true" > 6.1.< / strong > Details< / a > < / li > < li class = "chapter-item expanded " > < a href = "../map/importing/index.html" > < strong aria-hidden = "true" > 6.2.< / strong > Importing< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../map/importing/convert_osm.html" > < strong aria-hidden = "true" > 6.2.1.< / strong > convert_osm< / a > < / li > < li class = "chapter-item expanded " > < a href = "../map/importing/geometry.html" > < strong aria-hidden = "true" > 6.2.2.< / strong > Road/intersection geometry< / a > < / li > < li class = "chapter-item expanded " > < a href = "../map/importing/rest.html" > < strong aria-hidden = "true" > 6.2.3.< / strong > The rest< / a > < / li > < li class = "chapter-item expanded " > < a href = "../map/importing/misc.html" > < strong aria-hidden = "true" > 6.2.4.< / strong > Misc< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../map/edits.html" > < strong aria-hidden = "true" > 6.3.< / strong > Live edits< / a > < / li > < li class = "chapter-item expanded " > < a href = "../map/platform.html" > < strong aria-hidden = "true" > 6.4.< / strong > Exporting< / a > < / li > < / ol > < / li > < li class = "chapter-item expanded " > < a href = "../trafficsim/index.html" > < strong aria-hidden = "true" > 7.< / strong > Traffic simulation< / a > < / li > < li > < ol class = "section" > < li class = "chapter-item expanded " > < a href = "../trafficsim/discrete_event.html" > < strong aria-hidden = "true" > 7.1.< / strong > Discrete event simulation< / a > < / li > < li class = "chapter-item expanded " > < a href = "../trafficsim/travel_demand.html" > < strong aria-hidden = "true" > 7.2.< / strong > Travel demand< / a > < / li > < li class = "chapter-item expanded " > < a href = "../trafficsim/gridlock.html" class = "active" > < strong aria-hidden = "true" > 7.3.< / strong > Gridlock< / a > < / li > < li class = "chapter-item expanded " > < a href = "../trafficsim/trips.html" > < strong aria-hidden = "true" > 7.4.< / strong > Multi-modal trips< / a > < / li > < li class = "chapter-item expanded " > < a href = "../trafficsim/live_edits.html" > <
2020-08-09 17:51:13 +03:00
< / div >
< div id = "sidebar-resize-handle" class = "sidebar-resize-handle" > < / div >
< / nav >
< div id = "page-wrapper" class = "page-wrapper" >
< div class = "page" >
< div id = "menu-bar-hover-placeholder" > < / div >
< div id = "menu-bar" class = "menu-bar sticky bordered" >
< div class = "left-buttons" >
< button id = "sidebar-toggle" class = "icon-button" type = "button" title = "Toggle Table of Contents" aria-label = "Toggle Table of Contents" aria-controls = "sidebar" >
< i class = "fa fa-bars" > < / i >
< / button >
< button id = "theme-toggle" class = "icon-button" type = "button" title = "Change theme" aria-label = "Change theme" aria-haspopup = "true" aria-expanded = "false" aria-controls = "theme-list" >
< i class = "fa fa-paint-brush" > < / i >
< / button >
< ul id = "theme-list" class = "theme-popup" aria-label = "Themes" role = "menu" >
< li role = "none" > < button role = "menuitem" class = "theme" id = "light" > Light (default)< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "rust" > Rust< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "coal" > Coal< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "navy" > Navy< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "ayu" > Ayu< / button > < / li >
< / ul >
< button id = "search-toggle" class = "icon-button" type = "button" title = "Search. (Shortkey: s)" aria-label = "Toggle Searchbar" aria-expanded = "false" aria-keyshortcuts = "S" aria-controls = "searchbar" >
< i class = "fa fa-search" > < / i >
< / button >
< / div >
< h1 class = "menu-title" > A/B Street< / h1 >
< div class = "right-buttons" >
< a href = "../print.html" title = "Print this book" aria-label = "Print this book" >
< i id = "print-button" class = "fa fa-print" > < / i >
< / a >
< / div >
< / div >
< div id = "search-wrapper" class = "hidden" >
< form id = "searchbar-outer" class = "searchbar-outer" >
< input type = "search" name = "search" id = "searchbar" name = "searchbar" placeholder = "Search this book ..." aria-controls = "searchresults-outer" aria-describedby = "searchresults-header" >
< / form >
< div id = "searchresults-outer" class = "searchresults-outer hidden" >
< div id = "searchresults-header" class = "searchresults-header" > < / div >
< ul id = "searchresults" >
< / ul >
< / div >
< / div >
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
< script type = "text/javascript" >
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
< / script >
< div id = "content" class = "content" >
< main >
< h1 > < a class = "header" href = "#gridlock" id = "gridlock" > Gridlock< / a > < / h1 >
< p > Here " gridlock" refers to the general problem of trips getting permanently
stuck, preventing the full simulation from completing. Most of the work is
tracked < a href = "https://github.com/dabreegster/abstreet/issues/114" > here< / a > .< / p >
< p > The general lesson is: you can't code your way around all edge cases. The data
in OSM often needs manual fixes. It's often useful to spend coding effort on
tools to detect and fix OSM problems.< / p >
< h2 > < a class = "header" href = "#problems" id = "problems" > Problems< / a > < / h2 >
< p > The choices in the movement model matter. Some gridlock is inherent to any
system with queueing and conflicting turns. But in reality, people wiggle around
partly blocked turns. And some of this comes from the treatment of the
front/back of vehicles.< / p >
< ul >
< li > Short roads in OSM causing very weird geometry< / li >
< li > Intersection geometry being too large, requiring too much time to cross< / li >
< li > Unrealistic traffic patterns caused by everyone trying to park in one big
garage (downtown) or take some alley (the UW soundcast issue)< / li >
< li > Too many people try to take an unprotected left turn (often at a stop sign)< / li >
< li > Bad individual traffic signals, usually at 5- or 6-ways< / li >
< li > Groups of traffic signals logically acting as a single intersection< / li >
< li > Separate traffic signals along a corridor being unsynchronized< / li >
< li > Vehicles performing illegal sequences of turns< / li >
< li > Vehicles are stuck with their plan and not reacting to traffic by changing
route< / li >
< li > Real traffic would result in a gridlock without a deliberate actions to avoid
it. Such actions range from individual decisions of drivers to police manually
controlling traffic. Intelligent avoidance of gridlock is not simulated and is
extremely hard to simulate.< / li >
< li > Vehicles will wait in lane filled with already waiting vehicles, even if there
is a completely empty lane allowing travel in desired direction. It makes
easier for entire lane between crossings to fill, contributing to gridlocks.
Note that while this and other clearly stupid behaviors are clearly
unrealistic, it is not trivial to implement more realistic and more efficient
decisions.< / li >
< li > Issues caused by the unrealistic
2020-09-25 05:55:09 +03:00
< a href = "discrete_event.html#lane-changing" > lane-changing model< / a >
2020-08-09 17:51:13 +03:00
< ul >
< li > Two turns that go to the same lane (one going " straight" , the other often a
lane-change) conflict. The conflict is coarse, at the granularity of the
entire intersection. So if vehicles are piled up in two lanes trying to
merge into one, then one group is likely to go through as expected, but the
second group will wait for the first to completely clear the intersection.
Until then, it looks like a conflicting turn is being done.< / li >
< / ul >
< / li >
< / ul >
< h2 > < a class = "header" href = "#solutions" id = "solutions" > Solutions< / a > < / h2 >
< p > Divide into implemented or not.< / p >
< ul >
< li > Synchronizing pairs of signals< / li >
< li > Uber-turns
< ul >
< li > for interpreting OSM turn restrictions< / li >
< li > for synchronizing a group of signals< / li >
< li > for locking turn sequences
< ul >
< li > Once a vehicle starts an uber-turn, prevent others from starting
conflicting turns on nearby intersections. Until groups of traffic signals
are configured as one, this is necessary to prevent somebody from making
it halfway through a sequence then getting blocked.< / li >
< / ul >
< / li >
< / ul >
< / li >
< li > Cycle detector< / li >
< li > block-the-box protection
< ul >
< li > the manual list of overrides< / li >
< li > likely shouldn't apply during uber-turns< / li >
< li > is it always fine to block the box at degenerate intersections?< / li >
< / ul >
< / li >
< li > hacks to allow conflicting turns at really broken intersections< / li >
< li > manually timing signals< / li >
< li > penalties for lane choice to make lane usage realistic< / li >
< / ul >
< h3 > < a class = "header" href = "#not-implemented" id = "not-implemented" > Not implemented< / a > < / h3 >
< ul >
< li > Dynamic rerouting< / li >
< li > Allow multiple vehicles through intersection at once if there is enough space
on lane where given vehicle is going. Currrently vehicles travel through
crossings one by one (or, with < code > --disable_block_the_box< / code > enabled - will enter
crossing even if leaving it will be impossible).< / li >
< li > Last resort: if someone's waiting on a turn > 5m, just go.< / li >
< li > Uber-turns
< ul >
< li > Group both stop sign and traffic signal intersections when looking for
uber-turns. Even a single traffic signal surrounded by tiny roads with stop
signs is causing problems.< / li >
< / ul >
< / li >
< / ul >
2020-10-14 19:03:44 +03:00
< h2 > < a class = "header" href = "#strategy-for-resolving" id = "strategy-for-resolving" > Strategy for resolving< / a > < / h2 >
< p > Because there are so many different causes all tangled together, my approach is
to simplify the simulation as much as possible. A problem is much easier to
understand and fix when it's isolated. I've been trying this to get the downtown
weekday scenario to complete. A list of different techniques to simplify, in no
particular order:< / p >
< ul >
< li > Use the < code > --infinite_parking< / code > flag to just let everyone park directly in their
destination buildings. This is useful since downtown has many large parking
garages with high capacity, but I don't have a data source describing them.< / li >
< li > Use the < code > --disable_turn_conflicts< / code > flag, which greatly reduces realism, but
lets conflicting turns happen simultaneously. (Even with this and other flags,
downtown still gridlocks!) It also disables traffic signals, so bad inferred
timing isn't an issue.< / li >
< li > Use the < code > --disable_block_the_box< / code > flag to workaround short roads.< / li >
< li > If you notice problems forming from cars stacking up behind slower cyclists,
there's no over-taking implemented yet. Use the scenario modifiers to convert
2020-10-14 20:34:11 +03:00
all biking trip to driving:
< code > --scenario_modifiers='[{" ChangeMode" :{" to_mode" :" Drive" ," pct_ppl" :100," departure_filter" :[0.0,86400.0]," from_modes" :[" Bike" ]}}]'< / code > < / li >
2020-10-14 19:03:44 +03:00
< li > If all else fails, use the scenario modifiers to bluntly cancel some
percentage of all trips.< / li >
< / ul >
2020-08-09 17:51:13 +03:00
< h2 > < a class = "header" href = "#fixing-data-used-in-simulation" id = "fixing-data-used-in-simulation" > Fixing data used in simulation< / a > < / h2 >
< p > Give more examples of changesets.< / p >
< ul >
< li > upstreaming turn restrictions into OSM to prevent invalid U-turns and other
crazy movements
< ul >
2020-08-28 00:57:37 +03:00
< li > ex: < a href = "https://www.openstreetmap.org/changeset/87945050" > https://www.openstreetmap.org/changeset/87945050< / a > < / li >
2020-08-09 17:51:13 +03:00
< / ul >
< / li >
< li > upstreaming lane count fixes into OSM to improve geometry< / li >
< / ul >
< / main >
< nav class = "nav-wrapper" aria-label = "Page navigation" >
<!-- Mobile navigation buttons -->
< a rel = "prev" href = "../trafficsim/travel_demand.html" class = "mobile-nav-chapters previous" title = "Previous chapter" aria-label = "Previous chapter" aria-keyshortcuts = "Left" >
< i class = "fa fa-angle-left" > < / i >
< / a >
2020-08-24 00:32:20 +03:00
< a rel = "next" href = "../trafficsim/trips.html" class = "mobile-nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
2020-08-10 23:52:49 +03:00
< i class = "fa fa-angle-right" > < / i >
< / a >
2020-08-09 17:51:13 +03:00
< div style = "clear: both" > < / div >
< / nav >
< / div >
< / div >
< nav class = "nav-wide-wrapper" aria-label = "Page navigation" >
< a rel = "prev" href = "../trafficsim/travel_demand.html" class = "nav-chapters previous" title = "Previous chapter" aria-label = "Previous chapter" aria-keyshortcuts = "Left" >
< i class = "fa fa-angle-left" > < / i >
< / a >
2020-08-24 00:32:20 +03:00
< a rel = "next" href = "../trafficsim/trips.html" class = "nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
2020-08-10 23:52:49 +03:00
< i class = "fa fa-angle-right" > < / i >
< / a >
2020-08-09 17:51:13 +03:00
< / nav >
< / div >
< script type = "text/javascript" >
window.playpen_copyable = true;
< / script >
< script src = "../elasticlunr.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "../mark.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "../searcher.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "../clipboard.min.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "../highlight.js" type = "text/javascript" charset = "utf-8" > < / script >
< script src = "../book.js" type = "text/javascript" charset = "utf-8" > < / script >
<!-- Custom JS scripts -->
< / body >
< / html >