78 lines
3.4 KiB
Python
78 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
@File : level_pipeline.py
|
|
@Time : 2025/12/22 20:38:11
|
|
@Author : wty-yy
|
|
@Version : 1.0
|
|
@Blog : https://wty-yy.github.io/
|
|
@Desc : Level Pipeline for Robogauge
|
|
'''
|
|
import yaml
|
|
|
|
from robogauge.tasks.pipeline.multi_pipeline import MultiPipeline
|
|
from robogauge.utils.logger import Logger
|
|
from robogauge.utils.progress_monitor import report_progress, ProgressTypes, ProgressData
|
|
from robogauge.utils.file_utils import compress_directory
|
|
|
|
level_logger = Logger() # LevelPipeline logger
|
|
|
|
class LevelPipeline:
|
|
def __init__(self, args, console_output=True, progress_data: ProgressData = None):
|
|
self.args = args
|
|
self.seeds = args.seeds
|
|
self.console_output = console_output
|
|
self.progress_data = progress_data
|
|
parent_log_dir = getattr(args, 'parent_log_dir', None)
|
|
level_logger.create(args.experiment_name+'_level', args.run_name, console_output=console_output, parent_log_dir=parent_log_dir)
|
|
self.args.parent_log_dir = str(level_logger.log_dir / "subtasks")
|
|
self.compress_logs = args.compress_logs
|
|
args.compress_logs = False # Disable child log compression
|
|
|
|
def run(self):
|
|
level_logger.info(f"🚀 Starting Level Searcher for '{self.args.experiment_name}'.")
|
|
level_logger.info(f"🔢 Seeds: {self.seeds}")
|
|
report_progress(self.progress_data, ProgressTypes.INIT, total=10, desc="🔍 Searching Max Level")
|
|
|
|
# binary search levels
|
|
l, r = 0, 10
|
|
all_level_results = {}
|
|
while l < r:
|
|
level = (l + r + 1) // 2
|
|
report_progress(self.progress_data, ProgressTypes.DESC, desc=f"🔍 Testing Level {level}")
|
|
all_success, results = self.test_level(level)
|
|
all_level_results[level] = results
|
|
if all_success:
|
|
l = level
|
|
else:
|
|
r = level - 1
|
|
report_progress(self.progress_data, ProgressTypes.UPDATE, value=1)
|
|
level = l
|
|
level_results = all_level_results.get(l, {
|
|
'model_path': results['model_path'],
|
|
'terrain_name': results['terrain_name'],
|
|
'terrain_level': 0,
|
|
})
|
|
if level >= 1:
|
|
level_logger.info(f"🏆 Found maximum level: {level}")
|
|
else:
|
|
level_logger.info(f"❌ No valid level found [1-10].")
|
|
with open(level_logger.log_dir / "level_search_results.yaml", 'w') as f:
|
|
yaml.dump(level_results, f, allow_unicode=True, sort_keys=False)
|
|
level_logger.logger.info(f"📂 Level search results saved to: {level_logger.log_dir / 'level_search_results.yaml'}")
|
|
if self.compress_logs:
|
|
compress_directory(level_logger.log_dir / "subtasks", delete_original=True, logger=level_logger)
|
|
return level, level_results
|
|
|
|
def test_level(self, level: int):
|
|
level_logger.info(f"🔍 Testing level {level}...")
|
|
self.args.level = level
|
|
multi_pipeline = MultiPipeline(self.args, console_output=self.console_output)
|
|
aggregated_results = multi_pipeline.run()
|
|
success_mean = float(aggregated_results['summary']['success']['mean'].split(' ')[0])
|
|
all_success = success_mean >= 0.8
|
|
if all_success:
|
|
level_logger.info(f"✅ Level {level} passed all tests, success mean: {success_mean}.")
|
|
else:
|
|
level_logger.info(f"❌ Level {level} failed some tests, success mean: {success_mean}.")
|
|
return all_success, aggregated_results
|