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:
Resolution vs. Size: More samples mean higher accuracy but larger tables
Feature Ranges: Ensure your lookup table covers the expected operating conditions
Interpolation: For values between grid points, you'll need interpolation
Memory Usage: Large multi-dimensional tables can consume significant memory
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