How to use curbside constraints with u-turn costs and force_curbside

Hiyas, trying to implement Curbside Approach but receiving error;

List<GHPoint> points = Arrays.asList(new GHPoint(RunSize.listOfAddressPoints.get(point).getLatitude(), RunSize.listOfAddressPoints.get(point).getLongitude()), new GHPoint(RunSize.listOfAddressPoints.get(point+1).getLatitude(), RunSize.listOfAddressPoints.get(point+1).getLongitude()));
GHResponse shortRoute = Graphhopper.graphHopper.route(new GHRequest(points).setCurbsides(Arrays.asList("left")).setProfile("car"));
ResponsePath shortPath = shortRoute.getBest();

RuntimeException: Cannot fetch best response if list is empty

Why is curbside not allowing me to getBest() from ResponsePath?

When calculating a route you should always check whether it was found or not:

if (!shortRoute.isFound())
  System.out.println(shortRoute.getErrors().toString());

Thanks,
If you pass curbside, you need to pass exactly one curbside for every point, empty curbsides will be ignored

if (shortRoute.hasErrors())
            System.out.println(shortRoute.getErrors().toString());

I didn’t realise the List CURBSIDES had to contain the curbside for every point if they are all the same.
For 2 points;
List<String> CURBSIDES = new ArrayList<>(Arrays.asList("left", "left"));

For 700 points;
List CURBSIDES = new ArrayList<>(Arrays.asList(“left” x700));

Could it be tied to the GHPoint? eg. Lat,Lon,Curbside
I know I could just curbsides.add(“left”) after adding each point to the request.

Also, the paths are weird, is it because uTurns are forbidden?
This is occurring;


Where in the real world we would expect
image

I suppose my aim is to force left curbside delivery but not restrict uTurns

Also, the paths are weird, is it because uTurns are forbidden?

Are you routing from 54 to 55 in this example? With curbsides enabled u-turns are forbidden at the query points, but you can setup finite u-turn costs at all junctions (see the documentation) so the route might go straight at the service locations, but then turn around at the next junction (if this is faster than doing a detour).

Where in the real world we would expect

Yes GH will calculate this route if you setup finite u-turn costs (the default is infinite).

Could it be tied to the GHPoint? eg. Lat,Lon,Curbside

Yes specifying curbside=left for all points might be a bit wasteful, but we can certainly not add it to GHPoint (and this would also not really solve the problem/reduce the size of the http request).

new ArrayList<>(Arrays.asList(“left” x700 ));

If this is really the problem maybe use a stream: IntStream.range(0, 700).mapToObj(i -> "left").collect(Collections.toList()); :wink:

Thanks Easbar :slight_smile:
Yes, routing 54 to 55. I will have a crack at finite u-turn costs.

Adding curbside to each point isn’t a problem, I just see it in my mind as;
When I add a point to the request I enter lat and lon, and I want it delivered from the left side of the road.

Thanks for your help and suggestions :smiley:

Can’t seem to get it to work :frowning:
In encoding manager;
EncodingManager encodingManager = EncodingManager.create(FlagEncoderFactory.CAR + "|turn_costs=true|u_turn_costs=3");

Setting the profile
new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(true)

Always blocks U-turns

I tried disabling CH but no difference.
shortRequest = new GHRequest().setProfile("car").setCurbsides(CURBSIDES).putHint(Parameters.CH.DISABLE, true);

You don’t need to add u_turn_costs to the flag encoder (it will have no effect or maybe this is the problem). Otherwise your settings look ok, maybe you forgot to delete the GH folder and run a new import? Then again with CH disabled there should be no need to do a new import…

Sure this seems reasonable on the client side, but the problem is that GHPoint is used for many many other things on the server side.

I’ve been rebuilding the graph just in case.
Don’t I have to specify a turn cost to reallow uturns? Otherwise uturns are forbidden?

Oh yes I mis-read your last comment.

It must be:

EncodingManager.create("car|turn_costs=true")

not

EncodingManager.create("car|turn_costs=true|u_turn_costs=3")

and

new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(true).putHint("u_turn_costs", 3);

not just

new Profile("car").setVehicle("car").setWeighting("fastest").setTurnCosts(true);
1 Like

Awesome, thanks easbar, appreciate your help.

I often get confused if these need to be put in encoder or profile.
Is there a list anywhere of all usable putHint profile entries? And also EncodingManager additional entries?

Works a treat (going from point 54 to 55);
image

@easbar sorry to be a pain. But how do you set the curbside_strictness to soft?
Is it done at profile level?

I’ve moved to GH-core v.2.1

This is still a bit inconsistent at the moment: The route optimization API has a curbside_strictness parameter. But the routing and matrix APIs do not have this parameter. The self-hosted routing engine, however, has a force_curbside parameter. It is documented here: https://github.com/graphhopper/graphhopper/blob/master/docs/web/api-doc.md#parameters

You need to set it per request.

Thanks again :slight_smile:

I am getting good results on the few instances that I have checked. The curbside left and uturn cost of 3 is allowing uturns at junctions
image

And also delivering right on a 1 way street is no-longer resulting in an error (186 -> 187-192(cluster of points) -> 193)
image
image

Ultimately, if it was returning an error on GHResponse with curbside left it would make it un-usable so it’s great to have a “soft curbside constraint”

For anyone following this or having issues with curbsides this is how I implemented on the request.
.setCurbsides(CURBSIDES).putHint(Parameters.Routing.FORCE_CURBSIDE, false);

Do you think we should add this to our new code examples?
See my new example: https://github.com/graphhopper/graphhopper/compare/tc_example

I like the example you have made :slight_smile:
I think you should include it

Powered by Discourse