Skip to content

Latest commit

 

History

History
129 lines (107 loc) · 6.49 KB

osrm_traffic_update.md

File metadata and controls

129 lines (107 loc) · 6.49 KB

OSRM Traffic

How live traffic is updated

Update logic could be found in updater.cpp, both MLD and CH use LoadAndUpdateEdgeExpandedGraph to update graph cost

Duration penalty update

For duration change in the following format(More details)

from_osm_id,to_osm_id,edge_speed_in_km_h

After loading csv data into a sorted array, it will iterate from/to pairs in OSRM data to update segment cost(code)

        // Iterate all edges and get (begin_node_id, end_node_id) as (u,v) pair
        // Try to find (u, v) in traffic.csv file
        if (auto value = segment_speed_lookup({u, v}))
        {
            // if there exists update, then update duration and weight
            auto segment_length = segment_lengths[segment_offset];
            auto new_duration = convertToDuration(value->speed, segment_length);
            auto new_weight =
                convertToWeight(fwd_weights_range[segment_offset], *value, segment_length);
            fwd_was_updated = true;

            fwd_weights_range[segment_offset] = new_weight;
            fwd_durations_range[segment_offset] = new_duration;
            fwd_datasources_range[segment_offset] = value->source;
            counters[value->source] += 1;
            }

Turn penalty update

Turn penalty should be input in the following format(More details)

from_osm_id,via_osm_id,to_osm_id,penalty_in_secs

After loading into sorted array, then iterate all turns to check whether it needs to be updated(code)

        // osm_turn is a tuple generated by {from_node_id, via_node_id, to_node_id}
        if (auto value = turn_penalty_lookup(osm_turn))
        {
            turn_duration_penalty =
                boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
            turn_weight_penalty = boost::numeric_cast<TurnPenalty>(std::round(
                std::isfinite(value->weight) ? value->weight * weight_multiplier
                                             : turn_duration_penalty * weight_multiplier / 10.));

            turn_duration_penalties[edge_index] = turn_duration_penalty;
            turn_weight_penalties[edge_index] = turn_weight_penalty;
            updated_turns.push_back(edge_index);
        }

End to end debug case

Based on Berlin OSM data, we tried to prove customization step would update specific link's weight/duration.

Here is the selected routing case. we picked one wayid in the middle of the route.

From OSM map data, there are totally 4 points in that wayid

25663401 (part of ways Friedrichstraße (435164424), Krausenstraße (4588225), and Krausenstraße (458953718))
25663409 (part of ways Schützenstraße (24242838) and Schützenstraße (4611773))
25663743 (part of way Mauerstraße (24242835))
25663420 (part of ways Zimmerstraße (66071387), Friedrichstraße (327979624), Friedrichstraße (32938172), and Zimmerstraße (4611774))

Create a traffic.csv file

25663401,25663409,1
25663409,25663743,1
25663743,25663420,1

The last 1 means the speed is 1 km/h.

By the commend we found weight matrix be updated based on traffic.csv.

./osrm-customize berlin.osrm  --segment-speed-file traffic.csv 

In OSRM, Here is the place to update segment cost

Comments

  1. Based on debug, we prove that update unit is the node pairs inside each way. Which is aligned with osrm-wiki
The from/to ids are OSM node IDs that are directly connected. To update the speed for an entire way, you must list each node pair along the way in the CSV file.
  1. To debug TBB, please set thread = 1 at the beginning of main
tbb::task_scheduler_init init(1);
  1. On Mac with XCode, I met issue related with osrm_update and osrm_store could not generate libosrm_store.a and libosrm_update.a, solve the issue by modifying CMakeLists.txt under osrm-backend
-add_library(osrm_update $<TARGET_OBJECTS:UPDATER> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
-add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
+add_library(osrm_update src/updater/csv_source.cpp src/updater/updater.cpp $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
+add_library(osrm_store src/storage/io_config.cpp src/storage/storage.cpp $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
  1. The input of custmization is osm_id pairs, OSRM would convert internal NodeID to osm_id for the matching
std::vector<util::Coordinate> coordinates;
extractor::PackedOSMIDs osm_node_ids;
extractor::files::readNodes(config.GetPath(".osrm.nbg_nodes"), coordinates, osm_node_ids);
// ...
auto u = osm_node_ids[internal_node_id];

In service's code or unit test code, you could use facade to do similar conversion

auto osm_nodeid = facade.GetOSMNodeIDOfNode(internal_node_id);
auto node_coordinate = facade.GetCoordinateOfNode(internal_node_id);

Reference