v0.1.8
This commit is contained in:
@@ -11,7 +11,9 @@ import yaml
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
from functools import partial
|
||||
from collections import defaultdict
|
||||
|
||||
import numpy as np
|
||||
from robogauge.utils.logger import logger
|
||||
from robogauge.utils.helpers import class_to_dict, snake_to_pascal
|
||||
|
||||
@@ -56,7 +58,7 @@ class BaseGauge:
|
||||
metric_class = eval(metric_class_name)
|
||||
self.metrics.append(metric_class(robot_cfg=robot_cfg, **self.metrics_cfg[name]))
|
||||
log_str += f" - Metric: {name}\n"
|
||||
self.info['metric'].append(metric_class_name)
|
||||
self.info['metric'].append(name)
|
||||
logger.info(log_str.strip())
|
||||
|
||||
if len(self.goals) == 0:
|
||||
@@ -109,22 +111,36 @@ class BaseGauge:
|
||||
logger.info(f"New Goal [{self.goal_idx+1}/{len(self.goals)}] [{goal_obj.count+1}/{goal_obj.total}]: {self.goal_str}")
|
||||
return goal
|
||||
|
||||
def update_metrics(self, sim_data: SimData):
|
||||
def update_metrics(self, sim_data: SimData, goal_data: GoalData):
|
||||
if sim_data.n_step % int(self.cfg.metrics.metric_dt / sim_data.sim_dt) != 0:
|
||||
return
|
||||
metrics_results = {}
|
||||
for metric_name, metric_obj in zip(self.info['metric'], self.metrics):
|
||||
val = metric_obj(sim_data)
|
||||
val = metric_obj(sim_data, goal_data)
|
||||
if metric_name not in ['visualization']:
|
||||
metrics_results[metric_name] = val
|
||||
self.goals[self.goal_idx].update_metrics(metrics_results)
|
||||
|
||||
def save_results(self):
|
||||
""" Save the results to a yaml file. """
|
||||
metrics = defaultdict(lambda: defaultdict(list))
|
||||
for goal in self.results:
|
||||
for metric_name, quantiles in self.results[goal].items():
|
||||
for quantile, val in quantiles.items():
|
||||
metrics[metric_name][quantile].append(val)
|
||||
self.results['summary'] = {}
|
||||
for metric_name, quantiles in metrics.items():
|
||||
if metric_name not in self.results['summary']:
|
||||
self.results['summary'][metric_name] = {}
|
||||
for quantile, vals in quantiles.items():
|
||||
mean = float(np.mean(vals))
|
||||
std = float(np.std(vals))
|
||||
self.results['summary'][metric_name][quantile] = f"{mean:.4f} ± {std:.4f}"
|
||||
|
||||
save_path = Path(logger.log_dir) / "results.yaml"
|
||||
with open(save_path, 'w') as file:
|
||||
yaml.dump(self.results, file)
|
||||
yaml_str = yaml.dump(self.results)
|
||||
yaml.dump(self.results, file, allow_unicode=True)
|
||||
yaml_str = yaml.dump(self.results, allow_unicode=True)
|
||||
logger.info(
|
||||
f"""\n{'='*20} Goals and Metrics results {'='*20}\n"""
|
||||
f"""{yaml_str}"""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from robogauge.utils.logger import logger
|
||||
from robogauge.tasks.robots import RobotConfig
|
||||
from robogauge.tasks.simulator.sim_data import SimData
|
||||
from robogauge.tasks.gauge.goals.base_goal import GoalData
|
||||
|
||||
class BaseMetric:
|
||||
""" Base class for all metric functions. """
|
||||
@@ -9,7 +10,7 @@ class BaseMetric:
|
||||
def __init__(self, robot_cfg: RobotConfig, **kwargs):
|
||||
self.robot_cfg = robot_cfg
|
||||
|
||||
def __call__(self, sim_data: SimData) -> float:
|
||||
def __call__(self, sim_data: SimData, goal_data: GoalData) -> float:
|
||||
value = 0.0
|
||||
logger.log(value, self.name, step=sim_data.n_step)
|
||||
return value
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import numpy as np
|
||||
|
||||
from robogauge.tasks.robots import RobotConfig
|
||||
from robogauge.tasks.simulator.sim_data import SimData
|
||||
from robogauge.tasks.gauge.metrics.base_metric import BaseMetric
|
||||
from robogauge.tasks.gauge.metrics.base_metric import BaseMetric, GoalData, SimData
|
||||
|
||||
from robogauge.utils.logger import logger
|
||||
|
||||
@@ -21,7 +20,7 @@ class DofLimitsMetric(BaseMetric):
|
||||
self.soft_dof_limit_ratio = soft_dof_limit_ratio
|
||||
self.calc_dof_names = dof_names
|
||||
|
||||
def __call__(self, sim_data: SimData) -> float:
|
||||
def __call__(self, sim_data: SimData, goal_data: GoalData) -> float:
|
||||
values = []
|
||||
for i in range(len(sim_data.proprio.joint.limits)):
|
||||
lower_limit = sim_data.proprio.joint.limits[i, 0]
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import numpy as np
|
||||
|
||||
from robogauge.tasks.robots import RobotConfig
|
||||
from robogauge.tasks.simulator.sim_data import SimData
|
||||
from robogauge.tasks.gauge.metrics.base_metric import BaseMetric
|
||||
from robogauge.tasks.gauge.goals.base_goal import GoalData
|
||||
from robogauge.tasks.gauge.metrics.base_metric import BaseMetric, SimData, GoalData
|
||||
|
||||
from robogauge.utils.logger import logger
|
||||
from robogauge.utils.helpers import class_to_dict
|
||||
|
||||
|
||||
class LinVelErrMetric(BaseMetric):
|
||||
@@ -15,13 +14,11 @@ class LinVelErrMetric(BaseMetric):
|
||||
def __init__(self, robot_cfg: RobotConfig, **kwargs):
|
||||
super().__init__(robot_cfg)
|
||||
max_ranges = []
|
||||
cfg_commands = class_to_dict(robot_cfg.commands)
|
||||
for name in ['lin_vel_x', 'lin_vel_y', 'lin_vel_z']:
|
||||
max_ranges.append(
|
||||
max(
|
||||
abs(getattr(robot_cfg.commands, name)[0]),
|
||||
abs(getattr(robot_cfg.commands, name)[1])
|
||||
)
|
||||
)
|
||||
cmds = cfg_commands.get(name)
|
||||
if cmds is not None:
|
||||
max_ranges.append(max(abs(cmds[0]), abs(cmds[1])))
|
||||
self.norm_vel = np.linalg.norm(max_ranges)
|
||||
|
||||
def __call__(self, sim_data: SimData, goal_data: GoalData) -> float:
|
||||
@@ -41,16 +38,11 @@ class AngVelErrMetric(BaseMetric):
|
||||
def __init__(self, robot_cfg: RobotConfig, **kwargs):
|
||||
super().__init__(robot_cfg)
|
||||
max_ranges = []
|
||||
cfg_commands = class_to_dict(robot_cfg.commands)
|
||||
for name in ['ang_vel_roll', 'ang_vel_pitch', 'ang_vel_yaw']:
|
||||
cmd_range = getattr(robot_cfg.commands, name)
|
||||
if cmd_range is None:
|
||||
cmd_range = [0, 0]
|
||||
max_ranges.append(
|
||||
max(
|
||||
abs(cmd_range[0]),
|
||||
abs(cmd_range[1])
|
||||
)
|
||||
)
|
||||
cmds = cfg_commands.get(name)
|
||||
if cmds is not None:
|
||||
max_ranges.append(max(abs(cmds[0]), abs(cmds[1])))
|
||||
self.norm_vel = np.linalg.norm(max_ranges)
|
||||
|
||||
def __call__(self, sim_data: SimData, goal_data: GoalData) -> float:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from robogauge.tasks.robots import RobotConfig
|
||||
from robogauge.tasks.simulator.sim_data import SimData
|
||||
from robogauge.tasks.gauge.metrics.base_metric import BaseMetric
|
||||
from robogauge.tasks.gauge.metrics.base_metric import BaseMetric, SimData, GoalData
|
||||
|
||||
from robogauge.utils.logger import logger
|
||||
|
||||
@@ -18,7 +17,7 @@ class VisualizationMetric(BaseMetric):
|
||||
self.dof_force = dof_force
|
||||
self.dof_pos = dof_pos
|
||||
|
||||
def __call__(self, sim_data: SimData) -> float:
|
||||
def __call__(self, sim_data: SimData, goal_data: GoalData) -> float:
|
||||
for i in range(len(sim_data.proprio.joint.force)):
|
||||
name = sim_data.proprio.joint.names[i]
|
||||
if self.dof_force:
|
||||
|
||||
Reference in New Issue
Block a user