v0.1.18
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from robogauge.utils.task_register import task_register
|
||||
from robogauge.tasks.simulator.mujoco_config import MujocoConfig
|
||||
from robogauge.tasks.robots import RobotConfig, Go2Config, Go2MoEConfig, Go2TerrainConfig, Go2MoETerrainConfig
|
||||
from robogauge.tasks.robots import RobotConfig, Go2Config, Go2MoEConfig, Go2TerrainConfig, Go2MoETerrainConfig, Go2StairsConfig, Go2MoEStairsConfig
|
||||
from robogauge.tasks.pipeline import BasePipeline
|
||||
from robogauge.tasks.gauge import BaseGaugeConfig
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class Go2FlatGaugeConfig(FlatGaugeConfig):
|
||||
cmd_duration = 6.0
|
||||
|
||||
class target_pos_velocity(FlatGaugeConfig.goals.target_pos_velocity): # goal to reach a target position by velocity command, config target at assets.target_pos
|
||||
enabled = True
|
||||
enabled = False
|
||||
target_pos = [2, 2, 0] # x y z [m], target position in the environment, used for target position goal
|
||||
lin_vel_x = 1.0 # +/- m/s
|
||||
lin_vel_y = 1.0 # +/- m/s
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
@Blog : https://wty-yy.github.io/
|
||||
@Desc : Go2 Wave Task Configuration
|
||||
'''
|
||||
from robogauge.tasks.robots import Go2Config, Go2MoEConfig
|
||||
from robogauge.tasks.gauge import StairsUpGaugeConfig
|
||||
from robogauge.tasks.simulator.mujoco_config import MujocoConfig
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
'''
|
||||
from robogauge.utils.config import Config
|
||||
|
||||
SEARCH_LEVELS_TERRAINS = ['slope', 'wave', 'stairs_up', 'stairs_down', 'obstacle']
|
||||
|
||||
class TerrainSearchLevelsConfig(Config):
|
||||
class flat:
|
||||
levels = [0]
|
||||
@@ -91,6 +93,9 @@ class TerrainSearchLevelsConfig(Config):
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
class TerrainEvalLevelsConfig(Config):
|
||||
class flat:
|
||||
levels = [0]
|
||||
|
||||
class slope:
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
spawns = [
|
||||
@@ -105,3 +110,63 @@ class TerrainEvalLevelsConfig(Config):
|
||||
[5.0, 0, 4.2 * (0.57 - 0.047)],
|
||||
[5.0, 0, 4.2 * 0.57],
|
||||
]
|
||||
|
||||
class wave:
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
spawns = [
|
||||
[4.55, 0, 0.65 - 0.075 * 9],
|
||||
[4.55, 0, 0.65 - 0.075 * 8],
|
||||
[4.55, 0, 0.65 - 0.075 * 7],
|
||||
[4.55, 0, 0.65 - 0.075 * 6],
|
||||
[4.55, 0, 0.65 - 0.075 * 5],
|
||||
[4.55, 0, 0.65 - 0.075 * 4],
|
||||
[4.55, 0, 0.65 - 0.075 * 3],
|
||||
[4.55, 0, 0.65 - 0.075 * 2],
|
||||
[4.55, 0, 0.65 - 0.075 * 1],
|
||||
[4.55, 0, 0.65],
|
||||
]
|
||||
|
||||
class stairs_up:
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
spawns = [
|
||||
[5.0, 0.0, 1.35],
|
||||
[5.0, 0.0, 1.80],
|
||||
[5.0, 0.0, 2.25 + 0.03],
|
||||
[5.0, 0.0, 2.70 + 0.08],
|
||||
[5.0, 0.0, 2.85 + 0.1],
|
||||
[5.0, 0.0, 3.00 + 0.12],
|
||||
[5.0, 0.0, 3.15 + 0.14],
|
||||
[5.0, 0.0, 3.30 + 0.16],
|
||||
[5.0, 0.0, 3.45 + 0.18],
|
||||
[5.0, 0.0, 3.60 + 0.2],
|
||||
]
|
||||
|
||||
class stairs_down:
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
spawns = [
|
||||
[5.1, 0.0, 1.35],
|
||||
[5.1, 0.0, 1.80 + 0.08],
|
||||
[5.1, 0.0, 2.25 + 0.15],
|
||||
[5.1, 0.0, 2.70 + 0.25],
|
||||
[5.1, 0.0, 2.85 + 0.27],
|
||||
[5.1, 0.0, 3.00 + 0.30],
|
||||
[5.1, 0.0, 3.15 + 0.33],
|
||||
[5.1, 0.0, 3.30 + 0.36],
|
||||
[5.1, 0.0, 3.45 + 0.39],
|
||||
[5.1, 0.0, 3.60 + 0.42],
|
||||
]
|
||||
|
||||
class obstacle:
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
spawns = [
|
||||
[5, 0.0, 0.20 - 0.023 * 9],
|
||||
[5, 0.0, 0.20 - 0.023 * 8],
|
||||
[5, 0.0, 0.20 - 0.023 * 7],
|
||||
[5, 0.0, 0.20 - 0.023 * 6],
|
||||
[5, 0.0, 0.20 - 0.023 * 5],
|
||||
[5, 0.0, 0.20 - 0.023 * 4],
|
||||
[5, 0.0, 0.20 - 0.023 * 3],
|
||||
[5, 0.0, 0.20 - 0.023 * 2],
|
||||
[5, 0.0, 0.20 - 0.023 * 1],
|
||||
[5, 0.0, 0.20],
|
||||
]
|
||||
|
||||
@@ -25,6 +25,7 @@ from robogauge.utils.logger import Logger
|
||||
from robogauge.utils.process_utils import NoDaemonPool
|
||||
from robogauge.utils.progress_monitor import report_progress, ProgressTypes, ProgressData
|
||||
from robogauge.utils.file_utils import compress_directory
|
||||
from robogauge.tasks.gauge.gauge_configs.terrain_levels_config import SEARCH_LEVELS_TERRAINS
|
||||
|
||||
multi_logger = Logger() # MultiPipeline logger
|
||||
|
||||
@@ -132,7 +133,7 @@ class MultiPipeline:
|
||||
""" Process results from all processes and aggregate them. """
|
||||
multi_logger.info("📊 Aggregating Results from all runs...")
|
||||
|
||||
summary = {'success': {}, **self.static_info, 'summary': {}}
|
||||
summary = {'success': {}, **self.static_info, 'summary': {}, 'quality_score': {}, 'terrain_quality_score': {}}
|
||||
finish_msg = (
|
||||
f"""\n{'='*20} Run Finish Summary {'='*20}\n"""
|
||||
f"""{'Seed':^10}{'Base Mass':^15}{'Friction':^15}{'Status':^10}\n"""
|
||||
@@ -151,6 +152,7 @@ class MultiPipeline:
|
||||
multi_logger.error("No results to aggregate.")
|
||||
return
|
||||
|
||||
quality_score, terrain_quality_score = summary['quality_score'], summary['terrain_quality_score']
|
||||
value_collections = defaultdict(lambda: defaultdict(list))
|
||||
for result in all_results:
|
||||
for goal, metrics in result['results'].items():
|
||||
@@ -159,11 +161,22 @@ class MultiPipeline:
|
||||
for metric, means in metrics.items():
|
||||
for mean_name, mean_value in means.items():
|
||||
value_collections[metric][mean_name].append(float(mean_value.split(' ')[0]))
|
||||
quality_score[mean_name] = 1
|
||||
|
||||
for metric, means in value_collections.items():
|
||||
summary['summary'][metric] = {}
|
||||
for mean_name, values in means.items():
|
||||
summary['summary'][metric][mean_name] = f"{float(np.mean(values)):.4f} ± {float(np.std(values)):.4f}"
|
||||
v = float(np.mean(values))
|
||||
summary['summary'][metric][mean_name] = f"{v:.4f} ± {float(np.std(values)):.4f}"
|
||||
weight = 1
|
||||
if metric in ['ang_vel_err', 'lin_vel_err']:
|
||||
weight = 2
|
||||
quality_score[mean_name] *= min(max(1e-9, v), 1.0) ** weight
|
||||
for mean_name in quality_score:
|
||||
quality_score[mean_name] = quality_score[mean_name] ** (1 / 8) # 2 + 2 + 1 * 4
|
||||
terrain_quality_score[mean_name] = quality_score[mean_name]
|
||||
if summary['terrain_name'] in SEARCH_LEVELS_TERRAINS:
|
||||
terrain_quality_score[mean_name] = 0.09 * (summary['terrain_level'] - 1) + 0.19 * quality_score[mean_name]
|
||||
|
||||
save_path = multi_logger.log_dir / "aggregated_results.yaml"
|
||||
with open(save_path, 'w') as file:
|
||||
|
||||
@@ -27,7 +27,7 @@ from robogauge.utils.logger import Logger
|
||||
from robogauge.utils.process_utils import NoDaemonPool
|
||||
from robogauge.utils.progress_monitor import report_progress, ProgressTypes, start_progress_monitor_thread, ProgressData
|
||||
from robogauge.tasks.pipeline import MultiPipeline, LevelPipeline
|
||||
from robogauge.tasks.gauge.gauge_configs.terrain_levels_config import TerrainSearchLevelsConfig
|
||||
from robogauge.tasks.gauge.gauge_configs.terrain_levels_config import SEARCH_LEVELS_TERRAINS
|
||||
from robogauge.utils.file_utils import compress_directory
|
||||
|
||||
stress_logger = Logger() # StressPipeline logger
|
||||
@@ -57,6 +57,7 @@ def run_pipeline(args, progress_queue, data):
|
||||
|
||||
if search is True:
|
||||
args.goals = GOALS['level_pipeline']
|
||||
args.spawn_type = "level_search"
|
||||
level, level_results = LevelPipeline(args, console_output=False, progress_data=progress_data).run()
|
||||
if level == 0: # no valid level found
|
||||
report_progress(progress_data, ProgressTypes.FINISH, desc=f"❌ Failed (Lv 0)")
|
||||
@@ -76,6 +77,7 @@ def run_pipeline(args, progress_queue, data):
|
||||
|
||||
args.level = level
|
||||
args.goals = GOALS['multi_pipeline']
|
||||
args.spawn_type = "level_eval"
|
||||
results = {
|
||||
'success': True,
|
||||
'results': MultiPipeline(args, console_output=False, progress_data=progress_data).run(),
|
||||
@@ -113,12 +115,9 @@ class StressPipeline:
|
||||
|
||||
### Build worker data ###
|
||||
workers_data = []
|
||||
terrain_search_levels_config = TerrainSearchLevelsConfig()
|
||||
for terrain_name in terrain_names:
|
||||
search_max_level = True
|
||||
terrain_level_cfg = getattr(terrain_search_levels_config, terrain_name, None)
|
||||
assert terrain_level_cfg is not None, f"Terrain '{terrain_name}' not found in TerrainSearchLevelsConfig."
|
||||
if len(terrain_level_cfg.levels) == 1: # Flattened terrain
|
||||
if terrain_name not in SEARCH_LEVELS_TERRAINS: # Flattened terrain
|
||||
search_max_level = False
|
||||
data = {
|
||||
'task_robot_model': self.task_robot_model,
|
||||
@@ -179,8 +178,9 @@ class StressPipeline:
|
||||
stress_logger.error("No results to aggregate.")
|
||||
return
|
||||
|
||||
summary = {**self.static_info, 'summary': {}, 'final_score': {}}
|
||||
value_collections = defaultdict(lambda: defaultdict(list))
|
||||
summary = {**self.static_info, 'summary': {}, 'robust_score': {}, 'benchmark_score': 0.0}
|
||||
metric_collections = defaultdict(lambda: defaultdict(list))
|
||||
terrain_collections = defaultdict(lambda: defaultdict(list))
|
||||
zero_terrain_count = 0
|
||||
for result in all_results:
|
||||
terrain_name = result['data']['terrain_name']
|
||||
@@ -194,21 +194,27 @@ class StressPipeline:
|
||||
summary[key] = result['results']
|
||||
|
||||
for metric, means in result['results']['summary'].items():
|
||||
for mean_name, mean_value in means.items():
|
||||
value = float(mean_value.split(' ')[0])
|
||||
if terrain_level is not None: # level terrain
|
||||
value = (terrain_level - 1) * 0.1 + value * 0.1
|
||||
value_collections[metric][mean_name].append(value)
|
||||
for mean_name, value_str in means.items():
|
||||
value = float(value_str.split(' ± ')[0])
|
||||
metric_collections[metric][mean_name].append(value)
|
||||
for mean_name, value in result['results']['terrain_quality_score'].items():
|
||||
terrain_collections[terrain_name][mean_name].append(value)
|
||||
|
||||
final_metrics = defaultdict(list)
|
||||
for metric, means in value_collections.items():
|
||||
for metric, means in metric_collections.items():
|
||||
summary['summary'][metric] = {}
|
||||
for mean_name, values in means.items():
|
||||
values.extend([0.0] * zero_terrain_count) # include zero terrains
|
||||
summary['summary'][metric][mean_name] = f"{float(np.mean(values)):.4f} ± {float(np.std(values)):.4f}"
|
||||
final_metrics[mean_name].append(np.mean(values))
|
||||
for mean_name, values in final_metrics.items():
|
||||
summary['final_score'][mean_name] = float(np.mean(values))
|
||||
|
||||
robust_score = defaultdict(dict)
|
||||
robust_scores = []
|
||||
for terrain_name, means in terrain_collections.items():
|
||||
for mean_name, values in means.items():
|
||||
values.extend([0.0] * zero_terrain_count) # include zero terrains
|
||||
robust_score[terrain_name][mean_name] = float(np.mean(values))
|
||||
robust_scores.append(robust_score[terrain_name][mean_name])
|
||||
summary['robust_score'] = dict(robust_score)
|
||||
summary['benchmark_score'] = float(np.mean(robust_scores))
|
||||
|
||||
save_path = stress_logger.log_dir / "stress_benchmark_results.yaml"
|
||||
with open(save_path, 'w') as file:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from .base_robot_config import RobotConfig
|
||||
from .base_robot import BaseRobot
|
||||
from .go2.go2_config import Go2Config, Go2TerrainConfig
|
||||
from .go2.go2_config import Go2Config, Go2TerrainConfig, Go2StairsConfig
|
||||
from .go2.go2 import Go2
|
||||
from .go2.go2_moe_config import Go2MoEConfig, Go2MoETerrainConfig
|
||||
from .go2.go2_moe_config import Go2MoEConfig, Go2MoETerrainConfig, Go2MoEStairsConfig
|
||||
from .go2.go2_moe import Go2MoE
|
||||
|
||||
Reference in New Issue
Block a user