New Feature: Curbside approach

We are excited to announce a new feature which lets you specify whether you want to approach your delivery locations from the right or the left side. We call it curbside approach. It is as simple as adding a new field called “curbside” to your address object as follows:

"address": {
      "location_id": "myLocation",
      "lon": 11.539346,
      "lat": 48.118248,
      "curbside": "right"
}

The allowed values for “curbside” are right, left and any.

If you want to ignore your curbside specifications, you can just add this:

    "configuration": {
        "routing": {
            "ignore_curbsides": true
        }
    }

It is a beta feature. If you have questions or comments, please let us know. Happy testing!

Complete example:

{
    "configuration": {
        "routing": {
            "ignore_curbsides": false
        }
    },
    "vehicles": [
        {
            "vehicle_id": "my_vehicle",
            "start_address": {
                "location_id": "11.542511_48.118478",
                "lon": 11.540194,
                "lat": 48.119895
            }
        }
    ],
    "services": [
        {
            "id": "1",
            "address": {
                "location_id": "11.539335_48.118421",
                "lon": 11.539346,
                "lat": 48.118248,
                "curbside": "right"
            }
        },
        {
            "id": "2",
            "address": {
                "location_id": "11.538563_48.118450",
                "lon": 11.538563,
                "lat": 48.11845,
                "curbside": "right"
            }
        },
        {
            "id": "3",
            "address": {
                "location_id": "same",
                "lon": 11.538992,
                "lat": 48.118448,
                "curbside": "right"
            }
        },
        {
            "id": "4",
            "address": {
                "location_id": "same",
                "lon": 11.538992,
                "lat": 48.118448,
                "curbside": "right"
            }
        },
        {
            "id": "5",
            "address": {
                "location_id": "11.537833_48.120212",
                "lon": 11.537833,
                "lat": 48.120212,
                "curbside": "left"
            }
        }
    ]
}
3 Likes

If the curb side approach isn’t valid is there a way to ignore it instead of throwing an error? Such as exposing force_curb_side from https://github.com/graphhopper/graphhopper/pull/1697#issuecomment-532873172

You mean not valid because for example its on the wrong side of a one-way street? Thats a good question we discussed this internally and postponed the decision whether or not to expose the force_curbside parameter from GH (partly because for the optimization it might be easy to confuse with ignore_curbsides). What would you prefer?

  • current behavior (apparently not)
  • expose the force_curbside parameter (you seem to understand what it does)
  • auto-ignore curbside parameters that cannot be fulfilled?

Probably the second option assuming you don’t think it makes it confusing (I personally don’t think it does). I think it makes sense to default force_curbside to true as in GH, but the option to turn it off would be great.

@easbar Sorry to bug you! We’re eager to get this in production, but can’t if impossible curb sides throws an error. We could always retry the request and disable curb sides for the reported impossible stops but this is a lot of added complexity if a flag to ignore errors is around the corner. Could you give any rough timeline when we might see this in the API? No worries if not, just didn’t want to start work on the workaround if it could be coming in the next few weeks

2 Likes

Ah sorry I missed your previous comment and no worries for asking again. I’m glad you are eager to try the feature and if you say missing this flag would make it hard to use it we should definitely make this configurable (option 2). So yes I think this should get added the next few weeks.

2 Likes

Is this feature only available via the Route Optimization API?

No, its also part of the open source routing engine.

Additionally, it will be available for the Routing and Matrix API.

Do you have a use-case in mind where force_curbside=true (the current default) can be useful? I understand that force_curbside=false can be useful, but now I am wondering in which case the opposite could even be useful (we are thinking about either exposing the parameter or just changing the default). So far the idea was that if a curbside constraint could not be fulfilled users might rather be informed than seeing the constraint just silently be ignored.

@Sam_Ruston or would it be useful or a good solution for your case when the single problematic job lands in the unassigned list?

@easbar @karussell In our case we only have a use for it if it can be silently ignored when the constraint fails and would always set force_curbside=false. As we don’t know beforehand if it is possible we’re just using it as a helpful hint to improve optimization quality rather than a hard constraint. I.e. the driver would prefer this side, but if it’s not possible then they’ll have to access it the other way.

We refined the way our curbside approach is configured and introduced a new field called "curbside_strictness". It can either be "ignore", "soft" or "strict". For example:

"configuration": {
   "routing": {
      "curbside_strictness": "soft"
   }
}

"ignore": Ignores all curbside specifications, i.e. even if you specified a "curbside" for one of your services, it will be ignored.

"soft": It considers the curbside specifications. However, if a curbside specification cannot be met, for example, due to a one-way street, this particular specification is ignored.

"strict": In contrast to "soft" all curbside specifications are enforced. If this is not possible, e.g. because of a one-way street, an error is returned.

The default value is "soft".

Please note that the field "ignore_curbsides" from the previous configuration above is no longer available anymore.

2 Likes

Awesome, thanks!

1 Like

Has this been rolled out to the API? I’m still experiencing an error when “curbside_strictness” is set to “soft”. Example of the error:

{
“message”: “Impossible curbside constraint: ‘curbside=left’ at to_point 58. Its not possible to arrive at this point via this side”,
“details”: “class com.graphhopper.util.exceptions.DetailedIllegalArgumentException”
}

Would you mind to send me the job_id or the JSON of that particular problem?

  "vehicles": [
    {
      "vehicle_id": "0",
      "type_id": "default",
      "start_address": {
        "location_id": "start_0",
        "lon": -122.0840575,
        "lat": 37.4219999
      },
      "return_to_depot": false,
      "earliest_start": 1586438401
    }
  ],
  "vehicle_types": [
    {
      "type_id": "default",
      "profile": "car",
      "speed_factor": 1
    }
  ],
  "services": [
    {
      "id": "0iBwRuagmJJeiEdGpasx",
      "address": {
        "location_id": "0iBwRuagmJJeiEdGpasx",
        "lon": -122.0550637,
        "lat": 37.4055292,
        "curbside": "left"
      }
    },
    {
      "id": "FXqXa7xHbB50W0clCKNn",
      "address": {
        "location_id": "FXqXa7xHbB50W0clCKNn",
        "lon": -122.023654,
        "lat": 37.3843582,
        "curbside": "left"
      }
    }
  ],
  "configuration": {
    "routing": {
      "curbside_strictness": "soft",
      "network_data_provider": "openstreetmap"
    }
  }
}
1 Like

Thanks, @Sam_Ruston, for the example. We are analysing this.

@Sam_Ruston We still had something in our software that ignored curbside_strictness. We fixed it. Thus, your example can be solved now (even though the resulting route looks weird since Perimeter Road is a private road we do not snap to).

1 Like