feat(training): release V0.9.1 避障训练与基础策略迁移
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import json
|
||||
import math
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
from task_config import ( # noqa: E402
|
||||
FLAT_TASK,
|
||||
OBSTACLE_TASK,
|
||||
TERRAIN_PRESETS,
|
||||
build_terrain_layout,
|
||||
deployment_metadata,
|
||||
navigation_candidates,
|
||||
validate_task_config,
|
||||
)
|
||||
|
||||
|
||||
class TaskConfigTest(unittest.TestCase):
|
||||
def test_flat_legacy_request_does_not_override_environment(self):
|
||||
self.assertIsNone(validate_task_config(FLAT_TASK, {}, 42))
|
||||
self.assertNotIn("terrain", deployment_metadata(FLAT_TASK, None, 42))
|
||||
|
||||
def test_layouts_are_bounded_finite_and_leave_flat_spawn_goal(self):
|
||||
for preset in (p for p in TERRAIN_PRESETS if p != "custom_boxes"):
|
||||
with self.subTest(preset=preset):
|
||||
custom = validate_task_config(OBSTACLE_TASK, {"terrainPreset": preset}, 42)
|
||||
layout = build_terrain_layout(custom)
|
||||
self.assertLessEqual(len(layout["boxes"]), 257)
|
||||
self.assertLess(len(json.dumps(layout)), 64 * 1024)
|
||||
self.assertEqual(layout["spawn"], [-5, 0, 0.32])
|
||||
self.assertEqual(layout["target"], [5, 0])
|
||||
for box in layout["boxes"]:
|
||||
self.assertTrue(all(math.isfinite(v) for v in box["pos"] + box["size"]))
|
||||
self.assertTrue(all(v > 0 for v in box["size"]))
|
||||
self.assertEqual(box["yaw"], 0)
|
||||
for box in layout["boxes"][1:]:
|
||||
self.assertGreaterEqual(box["pos"][0] - box["size"][0], -4)
|
||||
self.assertLessEqual(box["pos"][0] + box["size"][0], 4)
|
||||
|
||||
def test_layout_is_deterministic_and_export_is_authoritative(self):
|
||||
custom = validate_task_config(OBSTACLE_TASK, {}, 42)
|
||||
original = build_terrain_layout(custom)
|
||||
self.assertEqual(original, build_terrain_layout(custom))
|
||||
self.assertNotEqual(original, build_terrain_layout({**custom, "seed": 43}))
|
||||
metadata = deployment_metadata(OBSTACLE_TASK, custom, 42)
|
||||
self.assertEqual(metadata["terrain"], original)
|
||||
self.assertEqual(metadata["observationSize"], 47 + 32 + 2)
|
||||
self.assertEqual(metadata["jointNames"][0], "FL_hip_joint")
|
||||
self.assertEqual(metadata["navigation"]["distanceScale"], 12)
|
||||
self.assertTrue(metadata["sensorCfg"]["includeGround"])
|
||||
self.assertEqual(metadata["navigation"]["trainingReset"], "random-connected-free-pair")
|
||||
|
||||
def test_navigation_candidates_are_safe_connected_and_have_distant_fallbacks(self):
|
||||
layout = build_terrain_layout(validate_task_config(OBSTACLE_TASK, {}, 42))
|
||||
candidates = navigation_candidates(layout)
|
||||
self.assertGreater(len(candidates["points"]), 2)
|
||||
self.assertEqual(len(candidates["componentStarts"]), len(candidates["fallbackPairs"]))
|
||||
for point in candidates["points"]:
|
||||
self.assertTrue(all(abs(value) <= layout["size"] / 2 - 0.55 for value in point))
|
||||
for box in layout["boxes"][1:]:
|
||||
distance = math.hypot(
|
||||
max(abs(point[0] - box["pos"][0]) - box["size"][0], 0),
|
||||
max(abs(point[1] - box["pos"][1]) - box["size"][1], 0),
|
||||
)
|
||||
self.assertGreater(distance, candidates["clearance"])
|
||||
for first, second in candidates["fallbackPairs"]:
|
||||
self.assertGreaterEqual(math.dist(first, second), candidates["minDistance"])
|
||||
|
||||
def test_obstacle_count_is_capped_by_spacing_capacity(self):
|
||||
custom = validate_task_config(
|
||||
OBSTACLE_TASK,
|
||||
{
|
||||
"terrainParams": {"size": 8, "spacing": 3, "obstacle_count": 100},
|
||||
},
|
||||
0,
|
||||
)
|
||||
layout = build_terrain_layout(custom)
|
||||
self.assertEqual(layout["actualObstacleCount"], 2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user