Skip to content

Commit f02b195

Browse files
DocGarbanzoclaude
andcommitted
Add time and distance fields to segment statistics for training optimization
The web UI segment statistics selector was missing the critical 'time' and 'distance' built-in metrics. These are essential for training optimization, particularly for selecting the fastest segment driving for each segment. Changes: - Added 'time' and 'distance' as built-in computed fields in get_available_fields() - Modified compute_segment_statistics() to handle built-in metrics without field aggregation (they're already computed during segment analysis) - Time rankings show percentile: 1.0 = fastest, 0.0 = slowest This enables users to train on minimal time spent per segment, creating a synthetic perfect lap from the best-driven instance of each segment. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent a47b6fd commit f02b195

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

donkeycar/web/imupath_data.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ def get_available_fields(self):
175175
tub = Tub(self.tub_path, read_only=True)
176176
try:
177177
fields = []
178+
179+
# Add built-in computed fields first (time and distance)
180+
fields.append({
181+
'name': 'time',
182+
'type': 'float',
183+
'is_vector': False,
184+
'dimensions': None,
185+
})
186+
fields.append({
187+
'name': 'distance',
188+
'type': 'float',
189+
'is_vector': False,
190+
'dimensions': None,
191+
})
192+
178193
# Iterate through input_types to get field metadata
179194
for field_name, field_type in tub.input_types.items():
180195
# Only include numeric scalars and vectors
@@ -214,9 +229,10 @@ def compute_segment_statistics(self, field_name, method, dimension=None):
214229
Uses TubStatistics session rankings for consistency with training.
215230
216231
Args:
217-
field_name: Name of the field to aggregate
232+
field_name: Name of the field to aggregate, or built-in metrics
233+
'time' or 'distance'
218234
method: Aggregation method ('delta', 'mean_abs', 'sum_abs',
219-
'max', 'min', 'norm')
235+
'max', 'min', 'norm'). Ignored for 'time' and 'distance'.
220236
dimension: For vector fields, which component (0=X, 1=Y, 2=Z,
221237
None=compute norm)
222238
@@ -226,10 +242,20 @@ def compute_segment_statistics(self, field_name, method, dimension=None):
226242
if not self.is_tub_data or not self.tub_path:
227243
return {}
228244

229-
spec = self._build_field_aggregation_spec(field_name, method, dimension)
230-
if spec is None:
231-
logger.error(f"Unknown aggregation method: {method}")
232-
return {}
245+
# Handle built-in computed metrics (time, distance)
246+
# These don't need field aggregation - they're already computed
247+
if field_name in ('time', 'distance'):
248+
sorting_key = field_name
249+
field_aggregations = []
250+
else:
251+
# Regular tub field - create aggregation spec
252+
spec = self._build_field_aggregation_spec(
253+
field_name, method, dimension)
254+
if spec is None:
255+
logger.error(f"Unknown aggregation method: {method}")
256+
return {}
257+
sorting_key = spec.output_key
258+
field_aggregations = [spec]
233259

234260
try:
235261
tub = Tub(self.tub_path, read_only=True)
@@ -248,13 +274,12 @@ def compute_segment_statistics(self, field_name, method, dimension=None):
248274
tub, session_id):
249275
segment_resolver = (
250276
self._build_visual_segment_resolver())
251-
sorting_strategy = SortingStrategy(
252-
[{'key': spec.output_key}])
277+
sorting_strategy = SortingStrategy([{'key': sorting_key}])
253278
stats = TubStatistics(
254279
tub,
255280
config=self.cfg,
256281
sorting_strategy=sorting_strategy,
257-
field_aggregations=[spec],
282+
field_aggregations=field_aggregations,
258283
)
259284
rankings_by_session = (
260285
stats.calculate_segment_performance(

0 commit comments

Comments
 (0)