Skip to content

Convenience API for modifying Single Run Data#43

Merged
alex-yang-upenn merged 2 commits into
mainfrom
srd-convenience-api
May 14, 2026
Merged

Convenience API for modifying Single Run Data#43
alex-yang-upenn merged 2 commits into
mainfrom
srd-convenience-api

Conversation

@alex-yang-upenn
Copy link
Copy Markdown
Collaborator

Make SingleRunData modifiable like a dictionary

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dict-style mutation API to SingleRunData (__setitem__, add, replace) and rewrites the local _replace / _add helpers in perda/utils/preprocessing.py to use it. The goal is to make derived-variable insertion and in-place overwrite a first-class capability of the data model rather than an ad-hoc utility.

Changes:

  • Add __setitem__, add, and replace methods to SingleRunData, with validation and synthetic-negative-ID assignment moved into the class.
  • Remove the private _add / _replace helpers from preprocessing.py and migrate patch_ned_velocity, convert_wheelspeeds_to_m_per_s, correct_motor_data, and CorrectSteeringAngleLambda to assign DataInstance values via data[name] = ....
  • Add a short docstring comment above the correct_steering_angle global noting it should be treated as a partially-applicable function.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
perda/core_data_structures/single_run_data.py Introduces dict-style mutation (__setitem__/add/replace) on SingleRunData with input validation and synthetic ID generation.
perda/utils/preprocessing.py Removes private _add/_replace helpers and rewrites callers to use the new dict-style API; adds an explanatory comment above correct_steering_angle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +119 to +163
synthetic_id = -(len(self.id_to_instance) + 1)
stored = DataInstance(
timestamp_np=di.timestamp_np,
value_np=di.value_np,
label=di.label,
var_id=synthetic_id,
cpp_name=cpp_name,
)
self.id_to_instance[synthetic_id] = stored
self.cpp_name_to_id[cpp_name] = synthetic_id
self.id_to_cpp_name[synthetic_id] = cpp_name
self.id_to_descript[synthetic_id] = di.label

def replace(self, cpp_name: str, di: DataInstance) -> None:
"""
Overwrite the values of an existing variable in-place.

Parameters
----------
cpp_name : str
C++ variable name of the variable to replace.
di : DataInstance
DataInstance whose ``value_np`` (and optionally updated timestamps) replaces the stored one.
Must have non-None ``label`` and ``cpp_name``.
"""
if di.label is None:
raise ValueError("DataInstance.label must be set before calling replace().")
if di.cpp_name is None:
raise ValueError(
"DataInstance.cpp_name must be set before calling replace()."
)
if cpp_name not in self:
raise KeyError(
f"'{cpp_name}' not found; use add() to insert a new variable."
)

var_id = self.cpp_name_to_id[cpp_name]
old = self.id_to_instance[var_id]
self.id_to_instance[var_id] = DataInstance(
timestamp_np=di.timestamp_np,
value_np=di.value_np,
label=di.label,
var_id=old.var_id,
cpp_name=old.cpp_name,
)
label=di.label,
var_id=old.var_id,
cpp_name=old.cpp_name,
)
Comment on lines +97 to +108
data[VECTORNAV_BODY_VEL_X] = DataInstance(
timestamp_np=vel_n1.timestamp_np,
value_np=vel_n * cos_y + vel_e * sin_y,
label=data[VECTORNAV_BODY_VEL_X].label,
cpp_name=VECTORNAV_BODY_VEL_X,
) # forward
data[VECTORNAV_BODY_VEL_Y] = DataInstance(
timestamp_np=vel_e1.timestamp_np,
value_np=-vel_n * sin_y + vel_e * cos_y,
label=data[VECTORNAV_BODY_VEL_Y].label,
cpp_name=VECTORNAV_BODY_VEL_Y,
) # right
@alex-yang-upenn alex-yang-upenn merged commit cfa49ff into main May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants