Lookup Table Example#

This example demonstrates how to convert a Routee Powertrain model into a lookup table format. Lookup tables are useful for fast energy consumption predictions across a predefined grid of operating conditions.

import nrel.routee.powertrain as pt
import numpy as np

Loading Models#

First, let's load a few different models to demonstrate lookup table generation. We'll use models with different feature sets to show the flexibility of the approach.

toyota_camry = pt.load_model("2016_TOYOTA_Camry_4cyl_2WD")
tesla_model3 = pt.load_model("2022_Tesla_Model_3_RWD")
tesla_with_temp = pt.load_model("2022_Tesla_Model_3_RWD_0F_110F_steady")

Let's examine the available features and targets for each model.

print("Toyota Camry features:", toyota_camry.feature_set_lists)
print("Toyota Camry targets:", toyota_camry.metadata.config.target.target_name_list)
print()
print("Tesla Model 3 features:", tesla_model3.feature_set_lists)
print("Tesla Model 3 targets:", tesla_model3.metadata.config.target.target_name_list)
print()
print("Tesla with Temperature features:", tesla_with_temp.feature_set_lists)
print(
    "Tesla with Temperature targets:",
    tesla_with_temp.metadata.config.target.target_name_list,
)
Toyota Camry features: [['speed_mph'], ['grade_percent', 'speed_mph'], ['grade_percent', 'speed_mph', 'turn_angle']]
Toyota Camry targets: ['gge']

Tesla Model 3 features: [['speed_mph'], ['grade_percent', 'speed_mph'], ['grade_percent', 'speed_mph', 'turn_angle']]
Tesla Model 3 targets: ['kwh']

Tesla with Temperature features: [['ambient_temp_f', 'speed_mph'], ['ambient_temp_f', 'grade_percent', 'speed_mph']]
Tesla with Temperature targets: ['kwh']

Single Feature Lookup Table#

Let's start with a simple single-feature lookup table using speed only. This creates a 1D lookup table showing how energy consumption varies with vehicle speed.

# Define feature parameters for speed-only lookup
speed_only_params = [
    {
        "feature_name": "speed_mph",
        "lower_bound": 5.0,
        "upper_bound": 80.0,
        "n_samples": 16,  # Every 5 mph from 5 to 80
    }
]

# Generate lookup table for Toyota Camry
camry_speed_lookup = toyota_camry.to_lookup_table(
    feature_parameters=speed_only_params,
    energy_target="gge",  # Gallons of gasoline equivalent
)

print("Single feature lookup table (first 5 rows):")
print(camry_speed_lookup.head())
Single feature lookup table (first 5 rows):
   speed_mph  gge_per_distance
0        5.0          0.079209
1       10.0          0.050484
2       15.0          0.045138
3       20.0          0.045888
4       25.0          0.042178

Two Feature Lookup Table#

Now let's create a more comprehensive 2D lookup table using both speed and grade. This shows how energy consumption varies with both vehicle speed and road grade.

# Define feature parameters for speed and grade
speed_grade_params = [
    {
        "feature_name": "speed_mph",
        "lower_bound": 25.0,
        "upper_bound": 65.0,
        "n_samples": 9,  # Every 5 mph from 25 to 65
    },
    {
        "feature_name": "grade_percent",
        "lower_bound": -6.0,
        "upper_bound": 6.0,
        "n_samples": 7,  # Every 2% grade from -6% to +6%
    },
]

# Generate lookup table for Tesla Model 3
tesla_speed_grade_lookup = tesla_model3.to_lookup_table(
    feature_parameters=speed_grade_params,
    energy_target="kwh",
)

print(f"Two feature lookup table shape: {tesla_speed_grade_lookup.shape}")
print("Sample rows:")
print(tesla_speed_grade_lookup.head(10))
Two feature lookup table shape: (63, 3)
Sample rows:
   speed_mph  grade_percent  kwh_per_distance
0       25.0           -6.0         -0.211147
1       30.0           -6.0         -0.211147
2       35.0           -6.0         -0.211147
3       40.0           -6.0         -0.208576
4       45.0           -6.0         -0.201589
5       50.0           -6.0         -0.201589
6       55.0           -6.0         -0.201589
7       60.0           -6.0         -0.201589
8       65.0           -6.0         -0.201589
9       25.0           -4.0         -0.087312

Three Feature Lookup Table with Temperature#

For models that include temperature, we can create a 3D lookup table. This is particularly useful for electric vehicles where temperature significantly affects range.

# Define feature parameters including temperature
temp_params = [
    {
        "feature_name": "speed_mph",
        "lower_bound": 35.0,
        "upper_bound": 55.0,
        "n_samples": 3,  # 35, 45, 55 mph
    },
    {
        "feature_name": "grade_percent",
        "lower_bound": -2.0,
        "upper_bound": 4.0,
        "n_samples": 4,  # -2%, 0%, 2%, 4%
    },
    {
        "feature_name": "ambient_temp_f",
        "lower_bound": 20.0,
        "upper_bound": 80.0,
        "n_samples": 4,  # 20°F, 40°F, 60°F, 80°F
    },
]

# Generate lookup table with temperature
tesla_temp_lookup = tesla_with_temp.to_lookup_table(
    feature_parameters=temp_params,
    energy_target="kwh",
)

print(f"Three feature lookup table shape: {tesla_temp_lookup.shape}")
print("Sample rows showing temperature effects:")
print(tesla_temp_lookup.head(12))
Three feature lookup table shape: (48, 4)
Sample rows showing temperature effects:
    speed_mph  grade_percent  ambient_temp_f  kwh_per_distance
0        35.0           -2.0            20.0          0.124237
1        35.0           -2.0            40.0          0.063225
2        35.0           -2.0            60.0          0.063225
3        35.0           -2.0            80.0          0.063225
4        45.0           -2.0            20.0          0.124237
5        45.0           -2.0            40.0          0.063225
6        45.0           -2.0            60.0          0.063225
7        45.0           -2.0            80.0          0.063225
8        55.0           -2.0            20.0          0.124237
9        55.0           -2.0            40.0          0.063225
10       55.0           -2.0            60.0          0.063225
11       55.0           -2.0            80.0          0.063225

Practical Usage: Interpolation for Route Prediction#

Lookup tables can be used for fast interpolation to predict energy consumption for specific driving conditions. Here's how you might use a lookup table for route prediction:

# Example: Using lookup table for fast prediction
def interpolate_energy_from_lookup(lookup_table, speed, grade=None, temp=None):
    if grade is None and temp is None:
        # 1D interpolation for speed only
        return np.interp(speed, lookup_table["speed_mph"], lookup_table.iloc[:, -1])
    else:
        # For multi-dimensional interpolation, you'd typically use scipy.interpolate
        # This is a simplified example
        closest_row = lookup_table.iloc[
            (lookup_table["speed_mph"] - speed).abs().argsort()[:1]
        ]
        return closest_row.iloc[0, -1]


# Example usage
example_speed = 42.5
predicted_energy = interpolate_energy_from_lookup(camry_speed_lookup, example_speed)
print(
    f"Interpolated energy consumption at {example_speed} mph: {predicted_energy:.4f} gge/mile"
)
Interpolated energy consumption at 42.5 mph: 0.0264 gge/mile

Best Practices and Considerations#

When creating lookup tables, consider:

  1. Resolution vs. Size: More samples mean higher accuracy but larger tables

  2. Feature Ranges: Ensure your lookup table covers the expected operating conditions

  3. Interpolation: For values between grid points, you'll need interpolation

  4. Memory Usage: Large multi-dimensional tables can consume significant memory

  5. Update Frequency: Lookup tables are static - update them when models change

Use Cases#

Lookup tables are particularly useful for:

  • Real-time applications requiring fast predictions

  • Embedded systems with limited computational resources

  • Integration with external systems that can't run Python models directly