2015-05-01 14:06:45 -04:00
|
|
|
-- Car profile
|
|
|
|
local find_access_tag = require("lib/access").find_access_tag
|
2016-04-27 07:24:25 -04:00
|
|
|
local get_destination = require("lib/destination").get_destination
|
2016-06-24 10:06:45 -04:00
|
|
|
local set_classification = require("lib/guidance").set_classification
|
|
|
|
local get_turn_lanes = require("lib/guidance").get_turn_lanes
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2016-11-07 05:03:15 -05:00
|
|
|
require("lib/tag_cache")
|
|
|
|
|
2015-05-01 14:06:45 -04:00
|
|
|
-- Begin of globals
|
2015-01-09 13:15:00 -05:00
|
|
|
barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["checkpoint"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["lift_gate"] = true, ["no"] = true, ["entrance"] = true }
|
2015-09-03 05:15:03 -04:00
|
|
|
access_tag_whitelist = { ["yes"] = true, ["motorcar"] = true, ["motor_vehicle"] = true, ["vehicle"] = true, ["permissive"] = true, ["designated"] = true, ["destination"] = true }
|
2016-04-04 05:49:40 -04:00
|
|
|
access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true, ["emergency"] = true, ["psv"] = true, ["delivery"] = true }
|
2012-09-19 12:35:45 -04:00
|
|
|
access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
2016-04-04 05:09:13 -04:00
|
|
|
access_tags_hierarchy = { "motorcar", "motor_vehicle", "vehicle", "access" }
|
2016-10-17 19:07:51 -04:00
|
|
|
service_tag_restricted = { ["parking_aisle"] = true, ["parking"] = true }
|
2016-08-24 05:40:57 -04:00
|
|
|
service_tag_forbidden = { ["emergency_access"] = true }
|
2016-09-09 06:34:04 -04:00
|
|
|
restrictions = { "motorcar", "motor_vehicle", "vehicle" }
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2016-04-22 05:31:46 -04:00
|
|
|
-- A list of suffixes to suppress in name change instructions
|
2016-04-28 04:54:14 -04:00
|
|
|
suffix_list = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "North", "South", "West", "East" }
|
2016-04-22 05:31:46 -04:00
|
|
|
|
2013-06-26 13:40:25 -04:00
|
|
|
speed_profile = {
|
|
|
|
["motorway"] = 90,
|
2014-10-06 07:42:30 -04:00
|
|
|
["motorway_link"] = 45,
|
2013-06-26 13:40:25 -04:00
|
|
|
["trunk"] = 85,
|
2014-10-06 07:42:30 -04:00
|
|
|
["trunk_link"] = 40,
|
2012-09-27 05:35:56 -04:00
|
|
|
["primary"] = 65,
|
2014-10-06 07:42:30 -04:00
|
|
|
["primary_link"] = 30,
|
2012-09-27 05:35:56 -04:00
|
|
|
["secondary"] = 55,
|
2014-10-06 07:42:30 -04:00
|
|
|
["secondary_link"] = 25,
|
2012-09-27 05:35:56 -04:00
|
|
|
["tertiary"] = 40,
|
2014-10-06 07:42:30 -04:00
|
|
|
["tertiary_link"] = 20,
|
2012-09-27 05:35:56 -04:00
|
|
|
["unclassified"] = 25,
|
|
|
|
["residential"] = 25,
|
2012-09-19 12:35:45 -04:00
|
|
|
["living_street"] = 10,
|
|
|
|
["service"] = 15,
|
|
|
|
-- ["track"] = 5,
|
|
|
|
["ferry"] = 5,
|
2015-02-26 08:56:01 -05:00
|
|
|
["movable"] = 5,
|
2013-02-04 12:38:15 -05:00
|
|
|
["shuttle_train"] = 10,
|
2013-08-19 11:36:15 -04:00
|
|
|
["default"] = 10
|
2012-09-19 12:35:45 -04:00
|
|
|
}
|
|
|
|
|
2016-08-24 05:40:57 -04:00
|
|
|
-- service speeds
|
|
|
|
service_speeds = {
|
|
|
|
["alley"] = 5,
|
2016-10-17 19:07:51 -04:00
|
|
|
["parking"] = 5,
|
2016-10-14 15:05:30 -04:00
|
|
|
["parking_aisle"] = 5,
|
2016-10-17 19:07:51 -04:00
|
|
|
["driveway"] = 5,
|
|
|
|
["drive-through"] = 5
|
2016-08-24 05:40:57 -04:00
|
|
|
}
|
2014-03-24 08:44:23 -04:00
|
|
|
|
2014-10-07 07:50:53 -04:00
|
|
|
-- surface/trackype/smoothness
|
|
|
|
-- values were estimated from looking at the photos at the relevant wiki pages
|
|
|
|
|
|
|
|
-- max speed for surfaces
|
|
|
|
surface_speeds = {
|
2014-10-10 04:34:34 -04:00
|
|
|
["asphalt"] = nil, -- nil mean no limit. removing the line has the same effect
|
2014-10-07 07:50:53 -04:00
|
|
|
["concrete"] = nil,
|
|
|
|
["concrete:plates"] = nil,
|
|
|
|
["concrete:lanes"] = nil,
|
|
|
|
["paved"] = nil,
|
2014-03-24 08:44:23 -04:00
|
|
|
|
|
|
|
["cement"] = 80,
|
|
|
|
["compacted"] = 80,
|
|
|
|
["fine_gravel"] = 80,
|
2014-10-10 04:34:34 -04:00
|
|
|
|
2014-03-24 08:44:23 -04:00
|
|
|
["paving_stones"] = 60,
|
|
|
|
["metal"] = 60,
|
|
|
|
["bricks"] = 60,
|
|
|
|
|
|
|
|
["grass"] = 40,
|
|
|
|
["wood"] = 40,
|
|
|
|
["sett"] = 40,
|
|
|
|
["grass_paver"] = 40,
|
|
|
|
["gravel"] = 40,
|
|
|
|
["unpaved"] = 40,
|
|
|
|
["ground"] = 40,
|
|
|
|
["dirt"] = 40,
|
|
|
|
["pebblestone"] = 40,
|
|
|
|
["tartan"] = 40,
|
|
|
|
|
|
|
|
["cobblestone"] = 30,
|
|
|
|
["clay"] = 30,
|
|
|
|
|
2014-10-07 07:50:53 -04:00
|
|
|
["earth"] = 20,
|
2014-03-24 08:44:23 -04:00
|
|
|
["stone"] = 20,
|
|
|
|
["rocky"] = 20,
|
|
|
|
["sand"] = 20,
|
|
|
|
|
|
|
|
["mud"] = 10
|
|
|
|
}
|
|
|
|
|
2014-10-07 07:50:53 -04:00
|
|
|
-- max speed for tracktypes
|
2014-03-24 08:44:23 -04:00
|
|
|
tracktype_speeds = {
|
|
|
|
["grade1"] = 60,
|
|
|
|
["grade2"] = 40,
|
|
|
|
["grade3"] = 30,
|
|
|
|
["grade4"] = 25,
|
|
|
|
["grade5"] = 20
|
|
|
|
}
|
|
|
|
|
2014-10-07 07:50:53 -04:00
|
|
|
-- max speed for smoothnesses
|
2014-03-24 08:44:23 -04:00
|
|
|
smoothness_speeds = {
|
|
|
|
["intermediate"] = 80,
|
|
|
|
["bad"] = 40,
|
|
|
|
["very_bad"] = 20,
|
|
|
|
["horrible"] = 10,
|
|
|
|
["very_horrible"] = 5,
|
|
|
|
["impassable"] = 0
|
|
|
|
}
|
|
|
|
|
2014-10-04 08:12:14 -04:00
|
|
|
-- http://wiki.openstreetmap.org/wiki/Speed_limits
|
|
|
|
maxspeed_table_default = {
|
|
|
|
["urban"] = 50,
|
|
|
|
["rural"] = 90,
|
|
|
|
["trunk"] = 110,
|
|
|
|
["motorway"] = 130
|
|
|
|
}
|
|
|
|
|
|
|
|
-- List only exceptions
|
|
|
|
maxspeed_table = {
|
2014-12-23 05:30:45 -05:00
|
|
|
["ch:rural"] = 80,
|
|
|
|
["ch:trunk"] = 100,
|
|
|
|
["ch:motorway"] = 120,
|
2014-10-04 08:12:14 -04:00
|
|
|
["de:living_street"] = 7,
|
|
|
|
["ru:living_street"] = 20,
|
|
|
|
["ru:urban"] = 60,
|
|
|
|
["ua:urban"] = 60,
|
|
|
|
["at:rural"] = 100,
|
|
|
|
["de:rural"] = 100,
|
|
|
|
["at:trunk"] = 100,
|
|
|
|
["cz:trunk"] = 0,
|
|
|
|
["ro:trunk"] = 100,
|
|
|
|
["cz:motorway"] = 0,
|
|
|
|
["de:motorway"] = 0,
|
|
|
|
["ru:motorway"] = 110,
|
|
|
|
["gb:nsl_single"] = (60*1609)/1000,
|
|
|
|
["gb:nsl_dual"] = (70*1609)/1000,
|
|
|
|
["gb:motorway"] = (70*1609)/1000,
|
|
|
|
["uk:nsl_single"] = (60*1609)/1000,
|
|
|
|
["uk:nsl_dual"] = (70*1609)/1000,
|
2016-04-08 18:04:11 -04:00
|
|
|
["uk:motorway"] = (70*1609)/1000,
|
2016-08-22 06:28:38 -04:00
|
|
|
["nl:rural"] = 80,
|
|
|
|
["nl:trunk"] = 100,
|
2016-04-08 18:04:11 -04:00
|
|
|
["none"] = 140
|
2014-10-04 08:12:14 -04:00
|
|
|
}
|
|
|
|
|
2016-03-21 17:42:47 -04:00
|
|
|
-- set profile properties
|
|
|
|
properties.u_turn_penalty = 20
|
|
|
|
properties.traffic_signal_penalty = 2
|
2016-11-01 17:13:10 -04:00
|
|
|
properties.max_speed_for_map_matching = 180/3.6 -- 180kmph -> m/s
|
2016-03-21 17:42:47 -04:00
|
|
|
properties.use_turn_restrictions = true
|
2016-04-12 12:47:00 -04:00
|
|
|
properties.continue_straight_at_waypoint = true
|
2016-07-18 09:34:12 -04:00
|
|
|
properties.left_hand_driving = false
|
2014-04-28 11:26:31 -04:00
|
|
|
|
2016-03-21 17:42:47 -04:00
|
|
|
local side_road_speed_multiplier = 0.8
|
2015-12-15 05:23:27 -05:00
|
|
|
|
2016-09-06 12:07:00 -04:00
|
|
|
local turn_penalty = 7.5
|
2015-08-30 13:17:19 -04:00
|
|
|
-- Note: this biases right-side driving. Should be
|
|
|
|
-- inverted for left-driving countries.
|
2016-09-06 12:07:00 -04:00
|
|
|
local turn_bias = properties.left_hand_driving and 1/1.075 or 1.075
|
2015-08-30 13:17:19 -04:00
|
|
|
|
2016-03-21 17:42:47 -04:00
|
|
|
local obey_oneway = true
|
|
|
|
local ignore_areas = true
|
2016-07-31 12:19:50 -04:00
|
|
|
local ignore_hov_ways = true
|
2016-08-18 10:48:17 -04:00
|
|
|
local ignore_toll_ways = false
|
2014-02-14 12:17:37 -05:00
|
|
|
|
|
|
|
local abs = math.abs
|
|
|
|
local min = math.min
|
|
|
|
local max = math.max
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2014-05-09 05:11:14 -04:00
|
|
|
local speed_reduction = 0.8
|
2014-03-27 13:22:04 -04:00
|
|
|
|
2016-04-22 05:31:46 -04:00
|
|
|
function get_name_suffix_list(vector)
|
|
|
|
for index,suffix in ipairs(suffix_list) do
|
|
|
|
vector:Add(suffix)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-09-09 06:34:04 -04:00
|
|
|
function get_restrictions(vector)
|
|
|
|
for i,v in ipairs(restrictions) do
|
2014-03-27 16:19:26 -04:00
|
|
|
vector:Add(v)
|
|
|
|
end
|
2012-11-12 11:00:36 -05:00
|
|
|
end
|
|
|
|
|
2012-11-03 03:19:01 -04:00
|
|
|
local function parse_maxspeed(source)
|
2014-03-27 16:19:26 -04:00
|
|
|
if not source then
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
local n = tonumber(source:match("%d*"))
|
2014-10-04 08:12:14 -04:00
|
|
|
if n then
|
|
|
|
if string.match(source, "mph") or string.match(source, "mp/h") then
|
2015-09-02 06:23:26 -04:00
|
|
|
n = (n*1609)/1000
|
2014-10-04 08:12:14 -04:00
|
|
|
end
|
|
|
|
else
|
|
|
|
-- parse maxspeed like FR:urban
|
|
|
|
source = string.lower(source)
|
|
|
|
n = maxspeed_table[source]
|
|
|
|
if not n then
|
|
|
|
local highway_type = string.match(source, "%a%a:(%a+)")
|
|
|
|
n = maxspeed_table_default[highway_type]
|
|
|
|
if not n then
|
|
|
|
n = 0
|
|
|
|
end
|
|
|
|
end
|
2014-03-27 16:19:26 -04:00
|
|
|
end
|
|
|
|
return n
|
2012-11-03 03:19:01 -04:00
|
|
|
end
|
|
|
|
|
2014-08-27 10:44:40 -04:00
|
|
|
function node_function (node, result)
|
2014-03-27 16:19:26 -04:00
|
|
|
-- parse access and barrier tags
|
2016-04-04 05:09:13 -04:00
|
|
|
local access = find_access_tag(node, access_tags_hierarchy)
|
2015-05-15 11:01:21 -04:00
|
|
|
if access and access ~= "" then
|
2014-03-27 16:19:26 -04:00
|
|
|
if access_tag_blacklist[access] then
|
2014-08-27 10:44:40 -04:00
|
|
|
result.barrier = true
|
2014-03-27 16:19:26 -04:00
|
|
|
end
|
2014-08-27 10:44:40 -04:00
|
|
|
else
|
|
|
|
local barrier = node:get_value_by_key("barrier")
|
|
|
|
if barrier and "" ~= barrier then
|
2015-08-25 08:46:05 -04:00
|
|
|
-- make an exception for rising bollard barriers
|
|
|
|
local bollard = node:get_value_by_key("bollard")
|
|
|
|
local rising_bollard = bollard and "rising" == bollard
|
|
|
|
|
|
|
|
if not barrier_whitelist[barrier] and not rising_bollard then
|
2014-08-27 10:44:40 -04:00
|
|
|
result.barrier = true
|
|
|
|
end
|
2014-03-27 16:19:26 -04:00
|
|
|
end
|
|
|
|
end
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2014-08-27 10:44:40 -04:00
|
|
|
-- check if node is a traffic light
|
|
|
|
local tag = node:get_value_by_key("highway")
|
|
|
|
if tag and "traffic_signals" == tag then
|
2015-09-02 06:23:26 -04:00
|
|
|
result.traffic_lights = true
|
2014-08-27 10:44:40 -04:00
|
|
|
end
|
|
|
|
end
|
2014-07-24 12:00:37 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- abort early if this way is obviouslt not routable
|
2016-11-10 09:36:40 -05:00
|
|
|
function handle_initial_check(data)
|
|
|
|
return TagCache.get(data,'highway') ~= nil or
|
|
|
|
TagCache.get(data,'route') ~= nil or
|
|
|
|
TagCache.get(data,'bridge') ~= nil
|
2016-11-07 05:03:15 -05:00
|
|
|
end
|
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- handle high occupancy vehicle tags
|
|
|
|
function handle_hov(data)
|
2016-07-31 12:19:50 -04:00
|
|
|
-- respect user-preference for HOV-only ways
|
2016-09-19 05:35:16 -04:00
|
|
|
if ignore_hov_ways then
|
2016-11-07 05:03:15 -05:00
|
|
|
local hov = TagCache.get(data,"hov")
|
2016-09-19 05:35:16 -04:00
|
|
|
if hov and "designated" == hov then
|
2016-11-08 13:20:14 -05:00
|
|
|
return false
|
2016-09-19 05:35:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
-- also respect user-preference for HOV-only ways when all lanes are HOV-designated
|
|
|
|
local function has_all_designated_hov_lanes(lanes)
|
|
|
|
local all = true
|
2016-10-25 16:22:06 -04:00
|
|
|
-- This gmatch call effectively splits the string on | chars.
|
|
|
|
-- we append an extra | to the end so that we can match the final part
|
|
|
|
for lane in (lanes .. '|'):gmatch("([^|]*)|") do
|
2016-09-19 05:35:16 -04:00
|
|
|
if lane and lane ~= "designated" then
|
|
|
|
all = false
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return all
|
|
|
|
end
|
|
|
|
|
2016-11-07 05:03:15 -05:00
|
|
|
local hov_lanes = TagCache.get(data,"hov:lanes")
|
|
|
|
local hov_lanes_forward = TagCache.get(data,"hov:lanes:forward")
|
|
|
|
local hov_lanes_backward = TagCache.get(data,"hov:lanes:backward")
|
2016-09-19 05:35:16 -04:00
|
|
|
|
|
|
|
local hov_all_designated = hov_lanes and hov_lanes ~= ""
|
|
|
|
and has_all_designated_hov_lanes(hov_lanes)
|
|
|
|
|
|
|
|
local hov_all_designated_forward = hov_lanes_forward and hov_lanes_forward ~= ""
|
|
|
|
and has_all_designated_hov_lanes(hov_lanes_forward)
|
|
|
|
|
|
|
|
local hov_all_designated_backward = hov_lanes_backward and hov_lanes_backward ~= ""
|
|
|
|
and has_all_designated_hov_lanes(hov_lanes_backward)
|
|
|
|
|
|
|
|
-- forward/backward lane depend on a way's direction
|
2016-11-07 05:03:15 -05:00
|
|
|
local oneway = TagCache.get(data,"oneway")
|
2016-09-19 05:35:16 -04:00
|
|
|
local reverse = oneway and oneway == "-1"
|
|
|
|
|
|
|
|
if hov_all_designated or hov_all_designated_forward then
|
|
|
|
if reverse then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.backward_mode = mode.inaccessible
|
2016-09-19 05:35:16 -04:00
|
|
|
else
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_mode = mode.inaccessible
|
2016-09-19 05:35:16 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if hov_all_designated_backward then
|
|
|
|
if reverse then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_mode = mode.inaccessible
|
2016-09-19 05:35:16 -04:00
|
|
|
else
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.backward_mode = mode.inaccessible
|
2016-09-19 05:35:16 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- handle squares and other areas
|
|
|
|
function handle_area(data)
|
|
|
|
-- we dont route over areas
|
|
|
|
local area = TagCache.get(data,"area")
|
|
|
|
if ignore_areas and area and "yes" == area then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
2016-07-31 12:19:50 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- handle toll roads
|
|
|
|
function handle_toll(data)
|
2016-08-04 06:04:49 -04:00
|
|
|
-- respect user-preference for toll=yes ways
|
2016-11-07 05:03:15 -05:00
|
|
|
local toll = TagCache.get(data,"toll")
|
2016-08-04 06:04:49 -04:00
|
|
|
if ignore_toll_ways and toll and "yes" == toll then
|
2016-11-08 13:20:14 -05:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- handle various that can block access
|
|
|
|
function handle_blocking(data)
|
|
|
|
if handle_area(data) == false then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if handle_hov(data) == false then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if handle_toll(data) == false then
|
|
|
|
return false
|
2016-08-04 06:04:49 -04:00
|
|
|
end
|
|
|
|
|
2016-10-08 12:14:35 -04:00
|
|
|
-- Reversible oneways change direction with low frequency (think twice a day):
|
|
|
|
-- do not route over these at all at the moment because of time dependence.
|
|
|
|
-- Note: alternating (high frequency) oneways are handled below with penalty.
|
2016-11-07 05:03:15 -05:00
|
|
|
local oneway = TagCache.get(data,"oneway")
|
2014-08-27 10:44:40 -04:00
|
|
|
if oneway and "reversible" == oneway then
|
2016-11-08 13:20:14 -05:00
|
|
|
return false
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2016-11-07 05:03:15 -05:00
|
|
|
local impassable = TagCache.get(data,"impassable")
|
2014-08-27 10:44:40 -04:00
|
|
|
if impassable and "yes" == impassable then
|
2016-11-08 13:20:14 -05:00
|
|
|
return false
|
2013-11-18 10:54:52 -05:00
|
|
|
end
|
|
|
|
|
2016-11-07 05:03:15 -05:00
|
|
|
local status = TagCache.get(data,"status")
|
2014-08-27 10:44:40 -04:00
|
|
|
if status and "impassable" == status then
|
2016-11-08 13:20:14 -05:00
|
|
|
return false
|
2013-11-18 10:54:52 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
-- set default mode
|
|
|
|
function handle_default_mode(data)
|
|
|
|
data.result.forward_mode = mode.driving
|
|
|
|
data.result.backward_mode = mode.driving
|
|
|
|
end
|
2013-11-18 10:54:52 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- check accessibility by traversing our acces tag hierarchy
|
|
|
|
function handle_access(data)
|
|
|
|
data.access = find_access_tag(data.way, access_tags_hierarchy)
|
|
|
|
if access_tag_blacklist[data.access] then
|
|
|
|
return false
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2012-10-04 08:18:39 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- handling ferries and piers
|
|
|
|
function handle_ferries(data)
|
|
|
|
local route = TagCache.get(data,"route")
|
2014-02-14 12:17:37 -05:00
|
|
|
local route_speed = speed_profile[route]
|
2015-02-26 08:56:01 -05:00
|
|
|
if (route_speed and route_speed > 0) then
|
2016-11-08 13:20:14 -05:00
|
|
|
TagCache.set(data,"highway",route)
|
|
|
|
local duration = TagCache.get(data,"duration")
|
|
|
|
if duration and durationIsValid(duration) then
|
|
|
|
data.result.duration = max( parseDuration(duration), 1 )
|
|
|
|
end
|
|
|
|
data.result.forward_mode = mode.ferry
|
|
|
|
data.result.backward_mode = mode.ferry
|
|
|
|
data.result.forward_speed = route_speed
|
|
|
|
data.result.backward_speed = route_speed
|
2014-02-14 12:17:37 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2014-02-14 12:17:37 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- handling movable bridges
|
|
|
|
function handle_movables(data)
|
|
|
|
local bridge = TagCache.get(data,"bridge")
|
2015-02-26 08:56:01 -05:00
|
|
|
local bridge_speed = speed_profile[bridge]
|
2016-11-07 05:03:15 -05:00
|
|
|
local capacity_car = TagCache.get(data,"capacity:car")
|
2015-02-26 10:22:18 -05:00
|
|
|
if (bridge_speed and bridge_speed > 0) and (capacity_car ~= 0) then
|
2016-11-07 05:03:15 -05:00
|
|
|
TagCache.set(data,"highway",bridge)
|
|
|
|
local duration = TagCache.get(data,"duration")
|
2015-02-26 08:56:01 -05:00
|
|
|
if duration and durationIsValid(duration) then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.duration = max( parseDuration(duration), 1 )
|
2015-02-26 08:56:01 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = bridge_speed
|
|
|
|
data.result.backward_speed = bridge_speed
|
2013-02-04 06:13:30 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2013-06-26 13:40:25 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- handle speed (excluding maxspeed)
|
|
|
|
function handle_speed(data)
|
|
|
|
if data.result.forward_speed == -1 then
|
2016-11-07 05:03:15 -05:00
|
|
|
local highway_speed = speed_profile[TagCache.get(data,"highway")]
|
|
|
|
local max_speed = parse_maxspeed( TagCache.get(data,"maxspeed") )
|
2014-02-14 12:17:37 -05:00
|
|
|
-- Set the avg speed on the way if it is accessible by road class
|
|
|
|
if highway_speed then
|
2014-08-27 10:44:40 -04:00
|
|
|
if max_speed and max_speed > highway_speed then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = max_speed
|
|
|
|
data.result.backward_speed = max_speed
|
2014-02-14 12:17:37 -05:00
|
|
|
-- max_speed = math.huge
|
|
|
|
else
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = highway_speed
|
|
|
|
data.result.backward_speed = highway_speed
|
2014-02-14 12:17:37 -05:00
|
|
|
end
|
2013-06-26 13:40:25 -04:00
|
|
|
else
|
2014-02-14 12:17:37 -05:00
|
|
|
-- Set the avg speed on ways that are marked accessible
|
2016-11-08 13:20:14 -05:00
|
|
|
if access_tag_whitelist[data.access] then
|
|
|
|
data.result.forward_speed = speed_profile["default"]
|
|
|
|
data.result.backward_speed = speed_profile["default"]
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2012-09-19 12:35:45 -04:00
|
|
|
end
|
2014-02-14 12:17:37 -05:00
|
|
|
if 0 == max_speed then
|
|
|
|
max_speed = math.huge
|
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = min(data.result.forward_speed, max_speed)
|
|
|
|
data.result.backward_speed = min(data.result.backward_speed, max_speed)
|
2013-02-04 06:13:30 -05:00
|
|
|
end
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
if -1 == data.result.forward_speed and -1 == data.result.backward_speed then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2016-11-10 09:36:40 -05:00
|
|
|
if handle_side_roads(data) == false then return false end
|
|
|
|
if handle_surface(data) == false then return false end
|
|
|
|
if handle_maxspeed(data) == false then return false end
|
|
|
|
if handle_speed_scaling(data) == false then return false end
|
|
|
|
if handle_alternating_speed(data) == false then return false end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
-- reduce speed on special side roads
|
|
|
|
function handle_side_roads(data)
|
2016-11-07 05:03:15 -05:00
|
|
|
local sideway = TagCache.get(data,"side_road")
|
2015-12-15 05:23:27 -05:00
|
|
|
if "yes" == sideway or
|
|
|
|
"rotary" == sideway then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = data.result.forward_speed * side_road_speed_multiplier
|
|
|
|
data.result.backward_speed = data.result.backward_speed * side_road_speed_multiplier
|
2015-12-15 05:23:27 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2015-12-15 05:23:27 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- reduce speed on bad surfaces
|
|
|
|
function handle_surface(data)
|
2016-11-07 05:03:15 -05:00
|
|
|
local surface = TagCache.get(data,"surface")
|
|
|
|
local tracktype = TagCache.get(data,"tracktype")
|
|
|
|
local smoothness = TagCache.get(data,"smoothness")
|
2014-03-24 08:44:23 -04:00
|
|
|
|
|
|
|
if surface and surface_speeds[surface] then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = math.min(surface_speeds[surface], data.result.forward_speed)
|
|
|
|
data.result.backward_speed = math.min(surface_speeds[surface], data.result.backward_speed)
|
2014-03-24 08:44:23 -04:00
|
|
|
end
|
|
|
|
if tracktype and tracktype_speeds[tracktype] then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = math.min(tracktype_speeds[tracktype], data.result.forward_speed)
|
|
|
|
data.result.backward_speed = math.min(tracktype_speeds[tracktype], data.result.backward_speed)
|
2014-03-24 08:44:23 -04:00
|
|
|
end
|
|
|
|
if smoothness and smoothness_speeds[smoothness] then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = math.min(smoothness_speeds[smoothness], data.result.forward_speed)
|
|
|
|
data.result.backward_speed = math.min(smoothness_speeds[smoothness], data.result.backward_speed)
|
2014-03-24 08:44:23 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2014-03-24 08:44:23 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- handles name, including ref and pronunciation
|
|
|
|
function handle_names(data)
|
2014-02-14 12:17:37 -05:00
|
|
|
-- parse the remaining tags
|
2016-11-07 05:03:15 -05:00
|
|
|
local name = TagCache.get(data,"name")
|
|
|
|
local pronunciation = TagCache.get(data,"name:pronunciation")
|
|
|
|
local ref = TagCache.get(data,"ref")
|
2014-02-14 12:17:37 -05:00
|
|
|
|
|
|
|
-- Set the name that will be used for instructions
|
2016-11-08 13:20:14 -05:00
|
|
|
if name then
|
|
|
|
data.result.name = name
|
2016-05-25 21:35:38 -04:00
|
|
|
end
|
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
if ref then
|
|
|
|
data.result.ref = canonicalizeStringList(ref, ";")
|
2016-09-05 09:01:51 -04:00
|
|
|
end
|
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
if pronunciation then
|
|
|
|
data.result.pronunciation = pronunciation
|
2014-02-14 12:17:37 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2014-02-14 12:17:37 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- handle turn lanes
|
|
|
|
function handle_turn_lanes(data)
|
2016-05-13 13:18:00 -04:00
|
|
|
local turn_lanes = ""
|
|
|
|
local turn_lanes_forward = ""
|
|
|
|
local turn_lanes_backward = ""
|
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
turn_lanes, turn_lanes_forward, turn_lanes_backward = get_turn_lanes(data.way)
|
|
|
|
if turn_lanes and turn_lanes ~= "" then
|
|
|
|
data.result.turn_lanes_forward = turn_lanes;
|
|
|
|
data.result.turn_lanes_backward = turn_lanes;
|
2016-05-13 13:18:00 -04:00
|
|
|
else
|
2016-06-28 05:00:01 -04:00
|
|
|
if turn_lanes_forward and turn_lanes_forward ~= "" then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.turn_lanes_forward = turn_lanes_forward;
|
2016-05-13 13:18:00 -04:00
|
|
|
end
|
|
|
|
|
2016-06-28 05:00:01 -04:00
|
|
|
if turn_lanes_backward and turn_lanes_backward ~= "" then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.turn_lanes_backward = turn_lanes_backward;
|
2016-05-13 13:18:00 -04:00
|
|
|
end
|
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2016-05-13 13:18:00 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- junctions
|
|
|
|
function handle_junctions(data)
|
|
|
|
if TagCache.get(data,"junction") == "roundabout" then
|
|
|
|
data.result.roundabout = true
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2013-02-04 06:13:30 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- Set access restriction flag if access is allowed under certain restrictions only
|
|
|
|
function handle_restricted(data)
|
|
|
|
if data.access ~= "" and access_tag_restricted[data.access] then
|
|
|
|
data.result.is_access_restricted = true
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- service roads
|
|
|
|
function handle_service(data)
|
|
|
|
local service = TagCache.get(data,"service")
|
|
|
|
if service then
|
2016-08-24 05:40:57 -04:00
|
|
|
-- Set access restriction flag if service is allowed under certain restrictions only
|
|
|
|
if service_tag_restricted[service] then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.is_access_restricted = true
|
2016-08-24 05:40:57 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Set don't allow access to certain service roads
|
|
|
|
if service_tag_forbidden[service] then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_mode = mode.inaccessible
|
|
|
|
data.result.backward_mode = mode.inaccessible
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- scale speeds to get better average driving times
|
|
|
|
function handle_speed_scaling(data)
|
|
|
|
local width = math.huge
|
|
|
|
local lanes = math.huge
|
|
|
|
if data.result.forward_speed > 0 or data.result.backward_speed > 0 then
|
|
|
|
local width_string = TagCache.get(data,"width")
|
|
|
|
if width_string and tonumber(width_string:match("%d*")) then
|
|
|
|
width = tonumber(width_string:match("%d*"))
|
|
|
|
end
|
|
|
|
|
|
|
|
local lanes_string = TagCache.get(data,"lanes")
|
|
|
|
if lanes_string and tonumber(lanes_string:match("%d*")) then
|
|
|
|
lanes = tonumber(lanes_string:match("%d*"))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local is_bidirectional = data.result.forward_mode ~= mode.inaccessible and
|
|
|
|
data.result.backward_mode ~= mode.inaccessible
|
|
|
|
|
|
|
|
local service = TagCache.get(data,"service")
|
|
|
|
if data.result.forward_speed > 0 then
|
|
|
|
local scaled_speed = data.result.forward_speed * speed_reduction
|
|
|
|
local penalized_speed = math.huge
|
|
|
|
if service and service ~= "" and service_speeds[service] then
|
|
|
|
penalized_speed = service_speeds[service]
|
|
|
|
elseif width <= 3 or (lanes <= 1 and is_bidirectional) then
|
|
|
|
penalized_speed = data.result.forward_speed / 2
|
|
|
|
end
|
|
|
|
data.result.forward_speed = math.min(penalized_speed, scaled_speed)
|
|
|
|
end
|
|
|
|
|
|
|
|
if data.result.backward_speed > 0 then
|
|
|
|
local scaled_speed = data.result.backward_speed * speed_reduction
|
|
|
|
local penalized_speed = math.huge
|
|
|
|
if service and service ~= "" and service_speeds[service]then
|
|
|
|
penalized_speed = service_speeds[service]
|
|
|
|
elseif width <= 3 or (lanes <= 1 and is_bidirectional) then
|
|
|
|
penalized_speed = data.result.backward_speed / 2
|
2016-08-24 05:40:57 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.backward_speed = math.min(penalized_speed, scaled_speed)
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2013-06-26 13:40:25 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- oneways
|
|
|
|
function handle_oneway(data)
|
|
|
|
local oneway = TagCache.get(data,"oneway")
|
2014-08-27 10:44:40 -04:00
|
|
|
if obey_oneway then
|
2014-03-27 16:19:26 -04:00
|
|
|
if oneway == "-1" then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_mode = mode.inaccessible
|
2016-10-18 12:58:39 -04:00
|
|
|
|
|
|
|
local is_forward = false
|
2016-11-08 13:20:14 -05:00
|
|
|
local destination = get_destination(data.way, is_forward)
|
|
|
|
data.result.destinations = canonicalizeStringList(destination, ",")
|
2013-07-17 10:23:57 -04:00
|
|
|
elseif oneway == "yes" or
|
2016-11-08 13:20:14 -05:00
|
|
|
oneway == "1" or
|
|
|
|
oneway == "true" or
|
|
|
|
TagCache.get(data,"junction") == "roundabout" or
|
|
|
|
(TagCache.get(data,"highway") == "motorway" and oneway ~= "no") then
|
2016-10-18 12:58:39 -04:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.backward_mode = mode.inaccessible
|
2016-10-18 12:58:39 -04:00
|
|
|
|
|
|
|
local is_forward = true
|
2016-11-08 13:20:14 -05:00
|
|
|
local destination = get_destination(data.way, is_forward)
|
|
|
|
data.result.destinations = canonicalizeStringList(destination, ",")
|
2012-09-19 12:35:45 -04:00
|
|
|
end
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2013-02-04 09:58:35 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- maxspeed and advisory maxspeed
|
|
|
|
function handle_maxspeed(data)
|
2013-02-04 09:58:35 -05:00
|
|
|
-- Override speed settings if explicit forward/backward maxspeeds are given
|
2016-11-07 05:03:15 -05:00
|
|
|
local maxspeed_forward = parse_maxspeed(TagCache.get(data,"maxspeed:forward"))
|
|
|
|
local maxspeed_backward = parse_maxspeed(TagCache.get(data,"maxspeed:backward"))
|
2014-08-27 10:44:40 -04:00
|
|
|
if maxspeed_forward and maxspeed_forward > 0 then
|
2016-11-08 13:20:14 -05:00
|
|
|
if mode.inaccessible ~= data.result.forward_mode and
|
|
|
|
mode.inaccessible ~= data.result.backward_mode then
|
|
|
|
data.result.backward_speed = data.result.forward_speed
|
2013-02-04 09:58:35 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = maxspeed_forward
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2014-08-27 10:44:40 -04:00
|
|
|
if maxspeed_backward and maxspeed_backward > 0 then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.backward_speed = maxspeed_backward
|
2013-06-26 13:40:25 -04:00
|
|
|
end
|
2013-02-04 09:58:35 -05:00
|
|
|
|
2015-11-18 12:46:29 -05:00
|
|
|
-- Override speed settings if advisory forward/backward maxspeeds are given
|
2016-11-07 05:03:15 -05:00
|
|
|
local advisory_speed = parse_maxspeed(TagCache.get(data,"maxspeed:advisory"))
|
|
|
|
local advisory_forward = parse_maxspeed(TagCache.get(data,"maxspeed:advisory:forward"))
|
|
|
|
local advisory_backward = parse_maxspeed(TagCache.get(data,"maxspeed:advisory:backward"))
|
2015-11-18 12:46:29 -05:00
|
|
|
-- apply bi-directional advisory speed first
|
|
|
|
if advisory_speed and advisory_speed > 0 then
|
2016-11-08 13:20:14 -05:00
|
|
|
if mode.inaccessible ~= data.result.forward_mode then
|
|
|
|
data.result.forward_speed = advisory_speed
|
2015-11-18 12:46:29 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
if mode.inaccessible ~= data.result.backward_mode then
|
|
|
|
data.result.backward_speed = advisory_speed
|
2015-11-18 12:46:29 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
if advisory_forward and advisory_forward > 0 then
|
2016-11-08 13:20:14 -05:00
|
|
|
if mode.inaccessible ~= data.result.forward_mode and mode.inaccessible ~= data.result.backward_mode then
|
|
|
|
data.result.backward_speed = data.result.forward_speed
|
2015-11-18 12:46:29 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.forward_speed = advisory_forward
|
2015-11-18 12:46:29 -05:00
|
|
|
end
|
|
|
|
if advisory_backward and advisory_backward > 0 then
|
2016-11-08 13:20:14 -05:00
|
|
|
data.result.backward_speed = advisory_backward
|
2015-11-18 12:46:29 -05:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2015-11-18 12:46:29 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- Handle high frequency reversible oneways (think traffic signal controlled, changing direction every 15 minutes).
|
|
|
|
-- Scaling speed to take average waiting time into account plus some more for start / stop.
|
2016-11-10 09:36:40 -05:00
|
|
|
function handle_alternating_speed(data)
|
2016-11-08 13:20:14 -05:00
|
|
|
if "alternating" == TagCache.get(data,'oneway') then
|
|
|
|
local scaling_factor = 0.4
|
|
|
|
if data.result.forward_speed ~= math.huge then
|
|
|
|
data.result.forward_speed = data.result.forward_speed * scaling_factor
|
2015-06-18 11:31:49 -04:00
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
if data.result.backward_speed ~= math.huge then
|
|
|
|
data.result.backward_speed = data.result.backward_speed * scaling_factor
|
2015-06-18 11:31:49 -04:00
|
|
|
end
|
|
|
|
end
|
2016-11-08 13:20:14 -05:00
|
|
|
end
|
2015-02-19 09:17:04 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- determine if this way can be used as a start/end point for routing
|
|
|
|
function handle_startpoint(data)
|
|
|
|
-- only allow this road as start point if it not a ferry
|
|
|
|
data.result.is_startpoint = data.result.forward_mode == mode.driving or
|
|
|
|
data.result.backward_mode == mode.driving
|
|
|
|
end
|
2015-06-26 08:34:49 -04:00
|
|
|
|
2016-11-10 09:36:40 -05:00
|
|
|
-- leave early if this way is not accessible
|
|
|
|
function handle_way_type(data)
|
|
|
|
if "" == TagCache.get(data,"highway") then return false end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- set the road classification based on guidance globals configuration
|
|
|
|
function handle_classification(data)
|
|
|
|
set_classification(TagCache.get(data,"highway"),data.result,data.way)
|
|
|
|
end
|
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
-- main entry point for processsing a way
|
|
|
|
function way_function(way, result)
|
|
|
|
|
|
|
|
-- define a table that we can pass around to helper functions
|
|
|
|
-- so they have access to the input/output objects.
|
|
|
|
|
|
|
|
-- we also use a table as a local cache of tags, to avoid calling
|
|
|
|
-- into C++ more than once for each tag, without having to
|
|
|
|
-- pass lists of already fetches tags around.
|
2015-02-19 09:17:04 -05:00
|
|
|
|
2016-11-08 13:20:14 -05:00
|
|
|
local data = {
|
|
|
|
way = way,
|
|
|
|
result = result,
|
|
|
|
cache = {},
|
|
|
|
}
|
|
|
|
|
|
|
|
-- perform each procesing step sequentially.
|
|
|
|
-- most steps can abort processing, meaning the way
|
2016-11-10 09:36:40 -05:00
|
|
|
-- is not routable
|
2016-11-08 13:20:14 -05:00
|
|
|
|
2016-11-10 09:36:40 -05:00
|
|
|
if handle_initial_check(data) == false then return end
|
|
|
|
if handle_default_mode(data) == false then return end--
|
2016-11-08 13:20:14 -05:00
|
|
|
if handle_blocking(data) == false then return end
|
|
|
|
if handle_access(data) == false then return end
|
2016-11-10 09:36:40 -05:00
|
|
|
if handle_ferries(data) == false then return end--
|
|
|
|
if handle_movables(data) == false then return end--
|
2016-11-08 13:20:14 -05:00
|
|
|
if handle_service(data) == false then return end
|
2016-11-10 09:36:40 -05:00
|
|
|
if handle_oneway(data) == false then return end--
|
|
|
|
if handle_speed(data) == false then return end
|
|
|
|
if handle_turn_lanes(data) == false then return end--
|
|
|
|
if handle_junctions(data) == false then return end--
|
|
|
|
if handle_startpoint(data) == false then return end--
|
|
|
|
if handle_restricted(data) == false then return end--
|
|
|
|
if handle_classification(data) == false then return end--
|
|
|
|
if handle_names(data) == false then return end--
|
2012-09-27 05:35:56 -04:00
|
|
|
end
|
2012-11-03 03:19:01 -04:00
|
|
|
|
2015-08-30 13:17:19 -04:00
|
|
|
function turn_function (angle)
|
2016-09-06 12:07:00 -04:00
|
|
|
-- Use a sigmoid function to return a penalty that maxes out at turn_penalty
|
|
|
|
-- over the space of 0-180 degrees. Values here were chosen by fitting
|
|
|
|
-- the function to some turn penalty samples from real driving.
|
2016-08-19 07:51:53 -04:00
|
|
|
-- multiplying by 10 converts to deci-seconds see issue #1318
|
2015-08-30 13:17:19 -04:00
|
|
|
if angle>=0 then
|
2016-09-06 12:07:00 -04:00
|
|
|
return 10 * turn_penalty / (1 + 2.718 ^ - ((13 / turn_bias) * angle/180 - 6.5*turn_bias))
|
2015-08-30 13:17:19 -04:00
|
|
|
else
|
2016-09-06 12:07:00 -04:00
|
|
|
return 10 * turn_penalty / (1 + 2.718 ^ - ((13 * turn_bias) * - angle/180 - 6.5/turn_bias))
|
2015-08-30 13:17:19 -04:00
|
|
|
end
|
|
|
|
end
|