opentripplanner / OpenTripPlanner

An open source multi-modal trip planner
http://www.opentripplanner.org
Other
2.18k stars 1.02k forks source link

OTP2 - negative waiting time #2955

Closed marcusyoung closed 2 years ago

marcusyoung commented 4 years ago

OTP2 is returning negative waiting times.

Attached is a screenshot of the legs of an itinerary where this occurs (the OTP response read into R Studio). As you can see the second leg begins before the end of the first leg. The reported total waiting time for this itinerary is -28 seconds.

legs

itin

This is the query:

req <- GET("http://localhost:8080/otp/routers/current/plan",
  query = list(fromPlace = '53.48805,-2.24258',
    toPlace = '53.36484,-2.27108',
    arriveBy = FALSE,
    mode = 'WALK,TRANSIT',
    date = '11-25-2018',
    time = '08:00:00',
    maxWalkDistance = 800,
    walkReluctance = 2,
    arriveBy = FALSE,
    transferPenalty = 0,
    minTransferTime = 0
  ))

The data used is from my otp_tutorial:

https://github.com/marcusyoung/otp-tutorial/tree/master/materials/data

Using the files:

Tested with the Beta version from:

OTP2 Beta 1 JAR file (~90MB) built from commit bf3d4e66357ff9e596c38a2074b02cba98e5fd38 on dev-2.x.

t2gran commented 4 years ago

Thank you for reporting this one, it is obvious a critical error, and I will put it on our short list of prioritized bug to fix. Also, it is good timing - we are tying up loose ends to get ready to test it in production at Entur.

gmellemstrand commented 4 years ago

@marcusyoung Do you still get the error when using the latest commit on dev-2.x?

marcusyoung commented 4 years ago

@gmellemstrand I've just tried the latest commit 53e260b. Oddly the query returned 13 itineraries, rather than the usual three?? Anyhow, as you can see the problem very much still happening:

2020-02-06_13-21-08

gmellemstrand commented 4 years ago

@marcusyoung Thanks for testing this with the latest commit. I was able to reproduce the problem.

This is related to how the Raptor routing simplifies walk legs. It calculates a an effectiveWalkingDistance and then divides it by the walk speed to get the duration. This accounts for height variations, but not other constant time additions, like turn costs.

When the itinerary is created after routing, we traverse all the street edges to create walk directions etc. We then use the duration calculated during this traversal, which is longer than the duration initially assumed. A quick way to fix this is to also use the initial duration calculated to use in the routing when creating itineraries. This will get rid of the negative wait times, but walk leg durations will be a bit shorter than expected by the model described in the StreetEdge class.

A more complete fix is to extend the Raptor Transfer class to use a more complex model for calculating durations. This could be adding a time constant in addition to the effectiveWalkDistance.

t2gran commented 4 years ago

The neg. wait times are not fixed. Below is a 2 itineraries from one search. The Norwegian graph is used. Almost any search is retuning negative wait time so it is easy to reproduce.

There is also a problem with the time-shift of the transfer(WALKING), it should start immediately after arriving, and there should be a "slack" before boarding.

Example dump (some data removed):

Itinerary{nTransfers:3, ..., waitingTime:3m48s, legs:[ Leg{ from:Place{name:'Origin', lon:10.78391, lat:59.92274end:}, to:Place{name:'Grenseveien', lon:10.78069, lat:59.92480end:}, start:01:21:01, end:01:27:30, mode:WALK }, Leg{ from:Place{name:'Fougners vei', stopId:ET:NSR:Quay:102015, lon:10.78069, lat:59.92482}, to:Place{name:'Carl Berners plass T', stopId:ET:NSR:Quay:11089, lon:10.77729, lat:59.92602}, start:01:27:00, end:01:28:00, mode:BUS, route:'Fornebu vest - Økern T', serviceDate:'20191111', routeShortName:'28'}, Leg{ from:Place{name:'Plattform 4', lon:10.77729, lat:59.92602end:}, to:Place{name:'Kreuzung mit Plattform 11', lon:10.77674, lat:59.92677end:}, start:01:28:01, end:01:30:00, mode:WALK}, Leg{ from:Place{name:'Carl Berners plass', stopId:ET:NSR:Quay:11037, lon:10.77674, lat:59.92677}, to:Place{name:'Sinsen T', stopId:ET:NSR:Quay:11082, lon:10.78253, lat:59.93629}, start:01:31:00, end:01:33:00, mode:BUS, route:'Snarøya - Fornebu - Tonsenhagen - Grorud', serviceDate:'20191111', routeShortName:'31'}, Leg{ from:Place{name:'Bürgersteig', lon:10.78257, lat:59.93627end:}, to:Place{name:'Plattform 1;2', lon:10.78188, lat:59.93719end:}, start:01:33:01, end:01:35:24, mode:WALK}, Leg{ from:Place{name:'Sinsen', stopId:ET:NSR:Quay:11077, lon:10.78187, lat:59.93719}, to:Place{name:'Storo', stopId:ET:NSR:Quay:11115, lon:10.77862, lat:59.94453}, start:01:39:00, end:01:40:00, mode:SUBWAY, route:'Vestli - Bergkrystallen', serviceDate:'20191111', routeShortName:'4'}, Leg{ from:Place{name:'Kreuzung mit Storo', lon:10.77863, lat:59.94453end:}, to:Place{name:'Plattform C', lon:10.77847, lat:59.94522end:}, start:01:42:01, end:01:44:22, mode:WALK}, Leg{ from:Place{name:'Storo', stopId:ET:NSR:Quay:104047, lon:10.77848, lat:59.94521}, to:Place{name:'Myrerskogveien', stopId:ET:NSR:Quay:101934, lon:10.78621, lat:59.95991}, start:01:42:00, end:01:50:00, mode:BUS, route:'Buss for linje 11', serviceDate:'20191111', routeShortName:'11B'}, Leg{ from:Place{name:'Kjelsåsveien', lon:10.78618, lat:59.95991end:}, to:Place{name:'Destination', lon:10.79584, lat:59.96844end:}, start:01:50:01, end:02:07:58, mode:WALK}], fare:Fare() }

Itinerary{nTransfers:1, waitingTime:-2m9s, legs:[ Leg{ from:Place{name:'Origin', lon:10.78391, lat:59.92274end:}, to:Place{name:'Kreuzung mit Plattform 1;2', lon:10.79038, lat:59.92988end:}, start:01:20:36, end:01:38:49, mode:WALK}, Leg{ from:Place{name:'Løren', stopId:ET:NSR:Quay:102018, lon:10.79036, lat:59.92986}, to:Place{name:'Storo', stopId:ET:NSR:Quay:11115, lon:10.77862, lat:59.94453}, start:01:37:00, end:01:40:00, mode:SUBWAY, route:'Vestli - Bergkrystallen', serviceDate:'20191111', routeShortName:'4'}, Leg{ from:Place{name:'Kreuzung mit Storo', lon:10.77863, lat:59.94453end:}, to:Place{name:'Plattform C', lon:10.77847, lat:59.94522end:}, start:01:42:01, end:01:44:22, mode:WALK}, Leg{ from:Place{name:'Storo', stopId:ET:NSR:Quay:104047, lon:10.77848, lat:59.94521}, to:Place{name:'Myrerskogveien', stopId:ET:NSR:Quay:101934, lon:10.78621, lat:59.95991}, start:01:42:00, end:01:50:00, mode:BUS, route:'Buss for linje 11', serviceDate:'20191111', routeShortName:'11B'}, Leg{ from:Place{name:'Kjelsåsveien', lon:10.78618, lat:59.95991end:}, to:Place{name:'Destination', lon:10.79584, lat:59.96844end:}, start:01:50:01, end:02:07:58, mode:WALK}], fare:Fare() }

gmellemstrand commented 4 years ago

I'm keeping this issue open, because although the immediate issue has been fixed, we will need to do a more complete fix later.

"A more complete fix is to extend the Raptor Transfer class to use a more complex model for calculating durations. This could be adding a time constant in addition to the effectiveWalkDistance."

t2gran commented 2 years ago

I think this is fixed now, I will close this.