Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert transferSlack configuration to duration #5897

Merged
merged 23 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c3c298e
Add test for transferSlack parsing
leonardehrenfried Jun 7, 2024
208a6fe
Convert tranferSlack to duration or int
leonardehrenfried Jun 7, 2024
5f46bea
Also set slack in APIs
leonardehrenfried Jun 7, 2024
e99b562
Fix mapping in API layer
leonardehrenfried Jun 7, 2024
5874b94
Add minTransferTime to integration test
leonardehrenfried Jun 7, 2024
60f407e
Add Javadoc
leonardehrenfried Jun 7, 2024
e5ea70d
Update and clarify documentation on board, alight and transfer slack
leonardehrenfried Jun 7, 2024
535546f
Update documentation
leonardehrenfried Jun 12, 2024
242f8bc
Merge remote-tracking branch 'upstream/dev-2.x' into transferslack
leonardehrenfried Jun 12, 2024
0784c7a
Fix code after rebase
leonardehrenfried Jun 12, 2024
409041e
Fix typo
leonardehrenfried Jun 12, 2024
9004bad
Fix small grammaer and punctuation errors
leonardehrenfried Jun 13, 2024
6213bb1
Apply suggestions from code review
leonardehrenfried Jun 17, 2024
22b5d36
Regenerate documentation
leonardehrenfried Jun 17, 2024
657e625
Apply review suggestions
leonardehrenfried Jun 17, 2024
4fac03c
Update src/main/java/org/opentripplanner/standalone/config/routereque…
leonardehrenfried Jul 1, 2024
8fc0d9f
Update compiled documentation
leonardehrenfried Jul 1, 2024
c321509
Update slack docs
leonardehrenfried Jul 2, 2024
98d28ee
Merge remote-tracking branch 'upstream/dev-2.x' into transferslack
leonardehrenfried Jul 3, 2024
ac2cb37
Re-apply update
leonardehrenfried Jul 3, 2024
6478829
Apply suggestions from code review
leonardehrenfried Jul 4, 2024
9ee2076
Update slack documentation
leonardehrenfried Jul 4, 2024
468bb83
Add Javadoc
leonardehrenfried Jul 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions docs/RouteRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe

| Config Parameter | Type | Summary | Req./Opt. | Default Value | Since |
|--------------------------------------------------------------------------------------------------------------|:----------------------:|------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|------------------|:-----:|
| [alightSlack](#rd_alightSlack) | `duration` | The minimum extra time after exiting a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 |
| [alightSlack](#rd_alightSlack) | `duration` | The extra time after exiting a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 |
leonardehrenfried marked this conversation as resolved.
Show resolved Hide resolved
| arriveBy | `boolean` | Whether the trip should depart or arrive at the specified date and time. | *Optional* | `false` | 2.0 |
| [boardSlack](#rd_boardSlack) | `duration` | The boardSlack is the minimum extra time to board a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 |
| [boardSlack](#rd_boardSlack) | `duration` | The extra time before boarding a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 |
leonardehrenfried marked this conversation as resolved.
Show resolved Hide resolved
| [drivingDirection](#rd_drivingDirection) | `enum` | The driving direction to use in the intersection traversal calculation | *Optional* | `"right"` | 2.2 |
| elevatorBoardCost | `integer` | What is the cost of boarding a elevator? | *Optional* | `90` | 2.0 |
| elevatorBoardTime | `integer` | How long does it take to get on an elevator, on average. | *Optional* | `90` | 2.0 |
Expand All @@ -38,7 +38,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe
| [searchWindow](#rd_searchWindow) | `duration` | The duration of the search-window. | *Optional* | | 2.0 |
| [streetRoutingTimeout](#rd_streetRoutingTimeout) | `duration` | The maximum time a street routing request is allowed to take before returning the results. | *Optional* | `"PT5S"` | 2.2 |
| [transferPenalty](#rd_transferPenalty) | `integer` | An additional penalty added to boardings after the first. | *Optional* | `0` | 2.0 |
| [transferSlack](#rd_transferSlack) | `integer` | The extra time needed to make a safe transfer in seconds. | *Optional* | `120` | 2.0 |
| [transferSlack](#rd_transferSlack) | `duration` | The extra time needed to make a safe transfer. | *Optional* | `"PT2M"` | 2.0 |
| turnReluctance | `double` | Multiplicative factor on expected turning time. | *Optional* | `1.0` | 2.0 |
| [unpreferredCost](#rd_unpreferredCost) | `cost-linear-function` | A cost function used to calculate penalty for an unpreferred route. | *Optional* | `"0s + 1.00 t"` | 2.2 |
| waitReluctance | `double` | How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. | *Optional* | `1.0` | 2.0 |
Expand Down Expand Up @@ -192,22 +192,33 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe
**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"`
**Path:** /routingDefaults

The minimum extra time after exiting a public transport vehicle.
The extra time after exiting a public transport vehicle.
leonardehrenfried marked this conversation as resolved.
Show resolved Hide resolved

The slack is added to the time after leaving the transit vehicle.
leonardehrenfried marked this conversation as resolved.
Show resolved Hide resolved

This also influences the time it takes to transfer.

Since some modes, like airplanes and subways, need more time than others, this is also configurable
per mode with `boardSlackForMode`.

The slack is added to the time when going from the transit vehicle to the stop.

<h3 id="rd_boardSlack">boardSlack</h3>

**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"`
**Path:** /routingDefaults

The boardSlack is the minimum extra time to board a public transport vehicle.
The extra time before boarding a public transport vehicle.

The board time is added to the time when going from the stop (offboard) to onboard a transit
vehicle.
The extra time is added to the time when entering a public transport vehicle. This is a useful
tool for agencies wanting to add a general buffer time so that passengers are instructed to be
a earlier at their stop than is strictly necessary. This is also added when transferring from one
vehicle to another.

This is the same as the `transferSlack`, except that this also applies to to the first
transit leg in the trip. This is the default value used, if not overridden by the `boardSlackList`.
It is similar to `transferSlack`, except that this also applies to the first transit leg in the
trip and `transferSlack` does not.

Some modes like, airplanes or subway, might need more of a slack than others, so this is also
configurable per mode with `boardSlackForMode`.


<h3 id="rd_drivingDirection">drivingDirection</h3>
Expand Down Expand Up @@ -351,16 +362,18 @@ significant time or walking will still be taken.

<h3 id="rd_transferSlack">transferSlack</h3>

**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `120`
**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT2M"`
**Path:** /routingDefaults

The extra time needed to make a safe transfer in seconds.
The extra time needed to make a safe transfer.

An expected transfer time in seconds that specifies the amount of time that must pass
between exiting one public transport vehicle and boarding another. This time is in
addition to time it might take to walk between stops plus `boardSlack` and
An extra buffer time that's applied when exiting one public transport vehicle and boarding another.
This time is in addition to time it might take to walk between stops plus `boardSlack` and
`alightSlack`.

It is useful to add extra time for passengers with mobility issues, who need extra time
when moving between vehicles.


<h3 id="rd_unpreferredCost">unpreferredCost</h3>

Expand Down Expand Up @@ -1181,7 +1194,7 @@ include stairs as a last result.
},
"waitReluctance" : 1.0,
"otherThanPreferredRoutesPenalty" : 300,
"transferSlack" : 120,
"transferSlack" : "2m",
"boardSlackForMode" : {
"AIRPLANE" : "35m"
},
Expand Down
2 changes: 1 addition & 1 deletion docs/RouterConfiguration.md
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ Used to group requests when monitoring OTP.
},
"waitReluctance" : 1.0,
"otherThanPreferredRoutesPenalty" : 300,
"transferSlack" : 120,
"transferSlack" : "2m",
"boardSlackForMode" : {
"AIRPLANE" : "35m"
},
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/entur/router-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
},
"waitReluctance": 1.0,
"otherThanPreferredRoutesPenalty": 300,
"transferSlack": 120,
"transferSlack": "2m",
// Default slack for any mode is 0 (zero)
"boardSlackForMode": {
"AIRPLANE" : "2100s"
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/ibi/portland/router-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"maxJourneyDuration": "6h",
"boardSlack": "0s",
"alightSlack": "0s",
"transferSlack": 180,
"transferSlack": "3m",
"waitReluctance": 0.9,
"walk": {
"reluctance": 1.75,
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/skanetrafiken/router-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"itineraryFilters": {
"filterItinerariesWithSameFirstOrLastTrip": true
},
"transferSlack": 180,
"transferSlack": "3m",
"waitReluctance": 0.175,
"walk": {
"reluctance": 5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private void mapTransfer(BoardAndAlightSlack boardAndAlightSlack) {
"Invalid parameters: 'minTransferTime' must be greater than or equal to board slack plus alight slack"
);
}
transfer.withSlack(req.minTransferTime - boardAndAlightSlack.value);
transfer.withSlackSec(req.minTransferTime - boardAndAlightSlack.value);
}

setIfNotNull(req.nonpreferredTransferPenalty, transfer::withNonpreferredCost);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public static RouteRequest toRouteRequest(
});
preferences.withTransfer(tx -> {
callWith.argument("transferPenalty", tx::withCost);
callWith.argument("minTransferTime", tx::withSlack);
callWith.argument("minTransferTime", tx::withSlackSec);
callWith.argument("waitReluctance", tx::withWaitReluctance);
callWith.argument("maxTransfers", tx::withMaxTransfers);
callWith.argument("nonpreferredTransferPenalty", tx::withNonpreferredCost);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static void mapPreferences(
preferences.withBike(bike -> mapBikePreferences(bike, callWith));
preferences.withCar(car -> mapCarPreferences(car, callWith));
preferences.withScooter(scooter -> mapScooterPreferences(scooter, callWith));
preferences.withTransfer(transfer -> mapTransferPreferences(transfer, environment, callWith));
preferences.withTransfer(transfer -> mapTransferPreferences(transfer, callWith));
preferences.withTransit(transit -> mapTransitPreferences(transit, environment, callWith));
preferences.withItineraryFilter(itineraryFilter ->
mapItineraryFilterPreferences(itineraryFilter, environment, callWith)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package org.opentripplanner.apis.transmodel.mapping.preferences;

import graphql.schema.DataFetchingEnvironment;
import org.opentripplanner.apis.transmodel.support.DataFetcherDecorator;
import org.opentripplanner.routing.api.request.preference.TransferPreferences;

public class TransferPreferencesMapper {

public static void mapTransferPreferences(
TransferPreferences.Builder transfer,
DataFetchingEnvironment environment,
DataFetcherDecorator callWith
) {
callWith.argument("transferPenalty", transfer::withCost);

// 'minimumTransferTime' is deprecated, that's why we are mapping 'slack' twice.
callWith.argument("minimumTransferTime", transfer::withSlack);
callWith.argument("transferSlack", transfer::withSlack);
callWith.argument("minimumTransferTime", transfer::withSlackSec);
callWith.argument("transferSlack", transfer::withSlackSec);

callWith.argument("waitReluctance", transfer::withWaitReluctance);
callWith.argument("maximumTransfers", transfer::withMaxTransfers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ private GraphQLObjectType createGraphQLType() {
"A global minimum transfer time (in seconds) that specifies the minimum amount of time that must pass between exiting one transit vehicle and boarding another."
)
.type(Scalars.GraphQLInt)
.dataFetcher(env -> preferences.transfer().slack())
.dataFetcher(env -> preferences.transfer().slack().toSeconds())
.build()
)
.field(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ Normally this is when the search is performed (now), plus a small grace period t
"This time is in addition to time it might take to walk between stops."
)
.type(Scalars.GraphQLInt)
.defaultValue(preferences.transfer().slack())
.defaultValue(preferences.transfer().slack().toSeconds())
.build()
)
.argument(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public RaptorRoutingRequestTransitData(

this.slackProvider =
new SlackProvider(
request.preferences().transfer().slack(),
(int) request.preferences().transfer().slack().toSeconds(),
request.preferences().transit().boardSlack(),
request.preferences().transit().alightSlack()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals;

import java.io.Serializable;
import java.time.Duration;
import java.util.Objects;
import java.util.function.Consumer;
import org.opentripplanner.framework.model.Cost;
import org.opentripplanner.framework.model.Units;
import org.opentripplanner.framework.time.DurationUtils;
import org.opentripplanner.framework.tostring.ToStringBuilder;
import org.opentripplanner.routing.algorithm.transferoptimization.api.TransferOptimizationParameters;

Expand All @@ -23,7 +25,7 @@ public final class TransferPreferences implements Serializable {
private static final int MAX_NUMBER_OF_TRANSFERS = 30;

private final Cost cost;
private final int slack;
private final Duration slack;
leonardehrenfried marked this conversation as resolved.
Show resolved Hide resolved
private final double waitReluctance;
private final int maxTransfers;
private final int maxAdditionalTransfers;
Expand All @@ -32,7 +34,7 @@ public final class TransferPreferences implements Serializable {

private TransferPreferences() {
this.cost = Cost.ZERO;
this.slack = 120;
this.slack = Duration.ofMinutes(2);
this.waitReluctance = 1.0;
this.maxTransfers = 12;
this.maxAdditionalTransfers = 5;
Expand All @@ -42,7 +44,7 @@ private TransferPreferences() {

private TransferPreferences(Builder builder) {
this.cost = builder.cost;
this.slack = Units.duration(builder.slack);
this.slack = DurationUtils.requireNonNegative(builder.slack);
this.waitReluctance = Units.reluctance(builder.waitReluctance);
this.maxTransfers = Units.count(builder.maxTransfers, MAX_NUMBER_OF_TRANSFERS);
this.maxAdditionalTransfers =
Expand Down Expand Up @@ -78,18 +80,18 @@ public int cost() {
}

/**
* A global minimum transfer time (in seconds) that specifies the minimum amount of time that must
* A global minimum transfer time that specifies the minimum amount of time that must
* pass between exiting one transit vehicle and boarding another. This time is in addition to time
* it might take to walk between transit stops, the {@link TransitPreferences#alightSlack()}, and the {@link
* TransitPreferences#boardSlack()}. This time should also be overridden by specific transfer timing information in
* transfers.txt
* TransitPreferences#boardSlack()}.
* This time can also be overridden by specific transfer timing information in transfers.txt
* <p>
* This only apply to transfer between two trips, it does not apply when boarding the first
* This only applies to transfer between two trips, it does not apply when boarding the first
* transit.
* <p>
* Unit is seconds. Default value is 2 minutes.
* Default value is 2 minutes.
*/
public int slack() {
public Duration slack() {
return slack;
}

Expand Down Expand Up @@ -183,7 +185,7 @@ public String toString() {
return ToStringBuilder
.of(TransferPreferences.class)
.addObj("cost", cost, DEFAULT.cost)
.addNum("slack", slack, DEFAULT.slack)
.addDuration("slack", slack, DEFAULT.slack)
.addNum("waitReluctance", waitReluctance, DEFAULT.waitReluctance)
.addNum("maxTransfers", maxTransfers, DEFAULT.maxTransfers)
.addNum("maxAdditionalTransfers", maxAdditionalTransfers, DEFAULT.maxAdditionalTransfers)
Expand All @@ -196,7 +198,7 @@ public static class Builder {

private final TransferPreferences original;
private Cost cost;
private int slack;
private Duration slack;
private Integer maxTransfers;
private Integer maxAdditionalTransfers;
private double waitReluctance;
Expand All @@ -223,7 +225,11 @@ public Builder withCost(int cost) {
return this;
}

public Builder withSlack(int slack) {
public Builder withSlackSec(Number seconds) {
return withSlack(Duration.ofSeconds(seconds.longValue()));
}

public Builder withSlack(Duration slack) {
this.slack = slack;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,22 @@ public Duration asDuration() {
return ofRequired(DURATION, node -> parseDuration(node.asText()));
}

/**
* Accepts both a string-formatted duration or a number of seconds as a number.
* In the documentation it will claim that it only accepts durations as the number is only for
* backwards compatibility.
*/
public Duration asDurationOrSeconds(Duration dflt) {
leonardehrenfried marked this conversation as resolved.
Show resolved Hide resolved
info.withType(DURATION);
setInfoOptional(dflt.toString());
var node = build();
if (node.isTextual()) {
return asDuration(dflt);
} else {
return Duration.ofSeconds((long) asDouble(dflt.toSeconds()));
}
}

public List<Duration> asDurations(List<Duration> defaultValues) {
return ofArrayAsList(DURATION, defaultValues, node -> parseDuration(node.asText()));
}
Expand Down
Loading