Skip to content

Commit

Permalink
implemented capacities from HBS
Browse files Browse the repository at this point in the history
  • Loading branch information
rakow committed May 13, 2024
1 parent 9d30365 commit 54d5679
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,35 @@
public class HBSMotorwayCapacity implements Predictor {
@Override
public double predict(Object2DoubleMap<String> features, Object2ObjectMap<String, String> categories) {
return 0;

// speed in km/h
int speed = (int) Math.round(features.getDouble("speed") * 3.6);
int lanes = (int) features.getOrDefault("lanes", 1);

// Capacity for 1 lane motorways is not defined in HBS
double capacity = 2000;
if (lanes == 2) {
if (speed >= 130)
capacity = 3700.0;
else if (speed >= 120)
capacity = 3800;
else
capacity = 3750;
} else if (lanes == 3) {
if (speed >= 130)
capacity = 5300;
else if (speed >= 120)
capacity = 5400;
else
capacity = 5350;
} else if (lanes >= 4) {
if (speed >= 130)
capacity = 7300;
else
capacity = 7400;
}

// Return capacity per lane
return capacity / lanes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public class HBSNetworkParams implements NetworkModel {

private static final Predictor MOTORWAY = new HBSMotorwayCapacity();
private static final Predictor ROAD = new HBSRoadCapacity();
private static final Predictor SIDEROAD = new HBSSideRoadCapacity();

@Override
public Predictor capacity(String junctionType, String highwayType) {
Expand All @@ -23,12 +22,10 @@ public Predictor capacity(String junctionType, String highwayType) {

if (highwayType.startsWith("motorway")) {
return MOTORWAY;
} else if (highwayType.startsWith("trunk") || highwayType.startsWith("primary") || highwayType.startsWith("secondary")) {
return ROAD;
}

// All lower category roads
return SIDEROAD;
return ROAD;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,87 @@
* Capacity for general roads, that are not motorways or residential roads.
*/
public class HBSRoadCapacity implements Predictor {
/**
* Capacity on primary roads (Landstraße)
*/
private static double capacityHighway(int lanes) {

// There is currently no way to differentiate Landstraße and Stadtstraße which can both have up to 70km/h

if (lanes == 1)
return 2846.990116534646;

if (lanes == 2)
return 3913.3439999999996 / 2;

// Own assumption of increasing capacity with more lanes
// This is not covered by the HBS and is a very rare case
return (3913.3439999999996) * 1.3 / lanes;
}

/**
* Capacity on a side road merging into a main road at a junction.
*
* @param qP the vehicle volume of the main road
*/
private static double capacityMerging(double qP) {

// See HBS page 5-20, eq. S5-12 table S5-5

// mean Folgezeitlücken of the different combinations
double tf = 3.5;

// mean Grenzzeitlücke
double tg = 6.36;


return Math.exp((-qP / 3600) * (tg - tf / 2)) * 3600 / tf;
}

/**
* Capacity of a side road of type merging into a main road.
*
* @param roadType type of the target road
* @param mainType type of the higher priority road
*/
private static double capacityMerging(String roadType, String mainType) {

if (mainType.equals("primary"))
return capacityMerging(600);

return capacityMerging(400);
}

@Override
public double predict(Object2DoubleMap<String> features, Object2ObjectMap<String, String> categories) {
return 0;

// Speed in km/h
int speed = (int) Math.round(features.getDouble("speed") * 3.6);
int lanes = (int) features.getOrDefault("lanes", 1);

if (speed >= 70) {
return capacityHighway(lanes);
}

String merging = categories.get("is_merging_into");

// Only merging with a single lane road is considered
if (!merging.isEmpty() && lanes == 1) {
return capacityMerging(categories.get("highway_type"), merging);
}

// Capacity for city roads
if (speed >= 40 || lanes >= 2) {
return switch (lanes) {
case 1 -> 1139.0625;
case 2 -> 2263.438914027149 / 2;
// Own assumption, rare edge-case
default -> 2263.438914027149 * 1.3 / lanes;
};
}

// Remaining are residential which are assumed to have high urbanisation
return 800.0/lanes;
}

}

This file was deleted.

11 changes: 8 additions & 3 deletions contribs/application/src/main/python/capacity/hbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ def calc_capacity_stadtstrasse(street):

if street.lanes == 1:
f = 1.0
if street.speed == 50:
# Assume middle-high "Erschließungsintensität"
if street.speed == 30:
k = 45
a = 38
b = 0.715
elif street.speed == 50:
k = 45
a = 54
b = 0.850
Expand Down Expand Up @@ -106,7 +111,7 @@ def calc_capacity_autobahn(street):
for lanes in range(1, 5):
capacities[osm_type][lanes] = {}
for speed in speeds:
if (osm_type == 'residential' and speed > 70) or (osm_type == 'residential' and speed < 50) or (osm_type == 'residential' and lanes > 2):
if (osm_type == 'residential' and speed > 70) or (osm_type == 'residential' and speed < 30) or (osm_type == 'residential' and lanes > 2):
continue
if (osm_type == 'unclassified' and speed > 100) or (osm_type == 'unclassified' and speed <= 50) or (osm_type == 'unclassified' and lanes > 2):
continue
Expand Down Expand Up @@ -166,7 +171,7 @@ def calc_capacity_autobahn(street):
capacity_compare.append(capacity_estimate(v))
fig.add_trace(go.Scatter(x=speeds_compare, y=capacity_compare, mode='lines', showlegend=True, name="REFERENZ"))

for qp in (0, 100, 400, 800):
for qp in (0, 200, 400, 600):
kontenpunkt_y = []
kontenpunkt_y.append(merge(qp))
kontenpunkt_y.append(merge(qp))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.matsim.application.prepare.network.params;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.contrib.sumo.SumoNetworkConverter;
import org.matsim.testcases.MatsimTestUtils;

import java.nio.file.Path;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class HBSNetworkParamsTest {

@RegisterExtension
MatsimTestUtils utils = new MatsimTestUtils();

@Test
void apply() throws Exception {

Path networkPath = Path.of(utils.getPackageInputDirectory()).resolve("osm.net.xml");

Path output = Path.of(utils.getOutputDirectory());

SumoNetworkConverter converter = SumoNetworkConverter.newInstance(List.of(networkPath),
output.resolve("network.xml"),
"EPSG:4326", "EPSG:4326");

converter.call();

assertThat(output.resolve("network.xml")).exists();
assertThat(output.resolve("network-ft.csv")).exists();

new ApplyNetworkParams().execute(
"capacity",
"--network", output.resolve("network.xml").toString(),
"--input-features", output.resolve("network-ft.csv").toString(),
"--output", output.resolve("network-hbs.xml").toString(),
"--model", "org.matsim.application.prepare.network.params.hbs.HBSNetworkParams"
);

assertThat(output.resolve("network-hbs.xml")).exists();
}
}

0 comments on commit 54d5679

Please sign in to comment.