exoskeleton/code/test/test_bilateral_calibration_v2.py

99 lines
3.3 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""Configuration propagation and bounded-size contracts for bilateral v2."""
from pathlib import Path
import sys
import unittest
CODE_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(CODE_ROOT))
from experiments.executors import _bilateral_scenario_and_config # noqa: E402
from experiments.plan import build_trial_plan, load_document # noqa: E402
from experiments.rng import named_seed_record # noqa: E402
CONFIG_ROOT = CODE_ROOT / "config" / "experiments"
def bilateral_trial():
return {
"method": {"method_id": "proposed_energy"},
"trajectory": {
"trajectory_id": "unit_contact",
"family": "contact_roundtrip",
"duration_s": 0.8,
"contact_probe_fraction": 0.01,
},
"factors": {
"map_policy": "source_stamped",
"network_profile": {
"forward_delay_s": 0.04,
"return_delay_s": 0.08,
"forward_jitter_s": 0.003,
"return_jitter_s": 0.004,
"forward_packet_loss": 0.01,
"return_packet_loss": 0.02,
},
"haptic_profile": {
"feedback_strength": 0.25,
"energy_min": 0.0,
"energy_max": 0.3,
"energy_initial": 0.1,
},
# A direct factor must override the coupled profile.
"forward_delay_s": 0.02,
"energy_initial": 0.12,
},
"seeds": named_seed_record(7, {"test": "bilateral-v2"}),
}
class BilateralCalibrationV2Test(unittest.TestCase):
def test_haptic_and_network_factors_reach_simulation_config(self):
scenario, config = _bilateral_scenario_and_config(bilateral_trial())
self.assertEqual(scenario.map_policy, "source_stamped")
self.assertEqual(config.feedback_strength, 0.25)
self.assertEqual(config.energy_min, 0.0)
self.assertEqual(config.energy_max, 0.3)
self.assertEqual(config.energy_initial, 0.12)
self.assertEqual(config.forward_delay_s, 0.02)
self.assertEqual(config.feedback_delay_s, 0.08)
self.assertEqual(config.forward_jitter_s, 0.003)
self.assertEqual(config.return_jitter_s, 0.004)
self.assertEqual(config.forward_packet_loss, 0.01)
self.assertEqual(config.return_packet_loss, 0.02)
def test_v2_grids_are_directional_and_bounded(self):
energy = build_trial_plan(
load_document(CONFIG_ROOT / "bilateral_calibration_v2_energy.json")
)
network = build_trial_plan(
load_document(CONFIG_ROOT / "bilateral_calibration_v2_network.json")
)
self.assertEqual(energy["pair_count"], 36)
self.assertEqual(energy["trial_count"], 36)
self.assertEqual(network["pair_count"], 12)
self.assertEqual(network["trial_count"], 36)
profiles = {
trial["factors"]["network_profile"]["profile_id"]
for trial in network["trials"]
}
self.assertEqual(
profiles,
{
"nominal",
"return_delay_80ms",
"forward_delay_40ms",
"asymmetric_delay",
"asymmetric_delay_plus_jitter",
"asymmetric_delay_plus_loss",
},
)
if __name__ == "__main__":
unittest.main()