NREL / routee-compass

An energy-aware routing engine
https://nrel.github.io/routee-compass/
BSD 3-Clause "New" or "Revised" License
10 stars 5 forks source link

State model updates testing #139

Closed nreinicke closed 6 months ago

nreinicke commented 6 months ago

I'm putting together some end-to-end tests and wanted to note a couple of things that have come up when testing the latest state model updates.

I'm hard time specifying the energy state variables. If I add the following to my config:

state = [
    { distance_unit = "kilometers", initial = 0.0 },
    { time_unit = "minutes", initial = 0.0 },
    { energy_unit = "kilowatt_hours", initial = 0.0 },
]

When running a query for a battery electric vehicle that looks like this:

{
    "destination_y": 39.62627481432341,
    "destination_x": -104.99460207519721,
    "origin_y": 39.798311884359094,
    "origin_x": -104.86796368632217,
    "model_name": "2017_CHEVROLET_Bolt",
    "state_variable_coefficients": {
        "distance": 1,
        "time": 1,
        "energy_electric": 1 
    },
    "start_time": "09:00:00 AM",
    "start_weekday": "monday",
}

I get an error: failure building search algorithm: failed to build cost model: invalid cost model configuration: coefficient for energy not provided. It seems like the energy state variable from the toml file is being read as the name energy but if I switch the query to look like this (and give an explicit vehicle state variable rate for `energy):

{
    "destination_y": 39.62627481432341,
    "destination_x": -104.99460207519721,
    "origin_y": 39.798311884359094,
    "origin_x": -104.86796368632217,
    "model_name": "2017_CHEVROLET_Bolt",
    "state_variable_coefficients": {
        "distance": 1,
        "time": 1,
        "energy": 1 
    },
    "start_time": "09:00:00 AM",
    "start_weekday": "monday",
}

The model runs but the cost summary looks like this:

{
    "cost": {
        "distance": 0.0,
        "energy": 0.0,
        "time": 9.474249213186411,
        "total_cost": 9.474249213186411
    },
    "info": {
        "cost_aggregation": "sum",
        "network_state_variable_rates": [
            {
                "type": "zero"
            },
            {
                "type": "zero"
            },
            {
                "type": "zero"
            }
        ],
        "state_variable_coefficients": [
            1.0,
            1.0,
            1.0
        ],
        "state_variable_indices": [
            [
                "distance",
                0
            ],
            [
                "time",
                1
            ],
            [
                "energy",
                2
            ]
        ],
        "vehicle_state_variable_rates": [
            {
                "factor": 0.655,
                "type": "factor"
            },
            {
                "factor": 0.333336,
                "type": "factor"
            },
            {
                "factor": 0.5,
                "type": "factor"
            }
        ]
    }
}

So, all this to say it looks like the mapping between the energy state variables and the cost model is a little bit out of whack.

nreinicke commented 6 months ago

Another thing to note is that the "traversal_summary" key in the result doesn't capture the summary but rather just shows the state model like this:

{
    "battery_state": {
        "feature": {
            "format": {
                "floating_point": {
                    "initial": 100.0
                }
            },
            "name": "soc",
            "unit": "percent"
        },
        "index": 4
    },
    "distance": {
        "feature": {
            "distance_unit": "kilometers",
            "initial": 0.0
        },
        "index": 0
    },
    "energy": {
        "feature": {
            "energy_unit": "kilowatt_hours",
            "initial": 0.0
        },
        "index": 2
    },
    "energy_electric": {
        "feature": {
            "energy_unit": "kilowatt_hours",
            "initial": 0.0
        },
        "index": 3
    },
    "time": {
        "feature": {
            "initial": 0.0,
            "time_unit": "minutes"
        },
        "index": 1
    }
}
nreinicke commented 6 months ago

Okay, sorry for the noise but the traversal summary serialization issue should be a simple fix, looks like this function is just over ridding the existing keys from the state model. We could just add a new key like "state_model" into the summary where we dump that info (or maybe we clean it up a bit to pair the state with the units and omit things like "index").

If I only serialize the state for the most recent query I get a summary that looks like this:

{
    "battery_state": 75.83717311517294,
    "distance": 0.0,
    "energy": 0.0,
    "energy_electric": 14.497696130896356,
    "time": 28.422520259397157
}

So, the "energy_electric" state var is being added properly, it's just the mixing with the cost model where we have an issue.

robfitzgerald commented 6 months ago

right. related to this: i didn't set up state model deserialization correctly. i have it expecting a JSON array"

[
  { "distance_unit": "kilometers", "initial": 0.0 },
  { "time_unit": "minutes", "initial": 0.0 },
  { "energy_unit": "minutes", "initial": 0.0 }
]

but then when building the hashmap for the state model, it just uses the unit type as the feature name, so we get:

HashMap::from({
  ("distance", StateFeature::Distance(...)),
  ("time", StateFeature::Time(...)),
  ("energy", StateFeature::Energy(...)),
})

but the keys for a PHEV should be "energy_electric" and "energy_liquid". StateModel deserialization should accept a JSON object with names as keys, not an array.

robfitzgerald commented 6 months ago

created issues in this milestone addressing the different problems listed here