v1.0.3; fix multiprocess global variables bug
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
# UPDATE
|
# UPDATE
|
||||||
|
## 20260101
|
||||||
|
### v1.0.3
|
||||||
|
Fix bug: 修复多进程中修改全局参数配置的问题, 同一个进程池中修改的全局变量会被保留, 因此task_register中需要实例化对象
|
||||||
## 20251231
|
## 20251231
|
||||||
### v1.0.2
|
### v1.0.2
|
||||||
1. 删除pyproject.toml文件, 使用`pip install -e .`就可以安装到pip easy-install.pth中, vscode能找到robogauge包
|
1. 删除pyproject.toml文件, 使用`pip install -e .`就可以安装到pip easy-install.pth中, vscode能找到robogauge包
|
||||||
|
|||||||
@@ -28,12 +28,14 @@ class BasePipeline:
|
|||||||
run_name: str,
|
run_name: str,
|
||||||
simulator_cfg: MujocoConfig,
|
simulator_cfg: MujocoConfig,
|
||||||
robot_cfg: RobotConfig,
|
robot_cfg: RobotConfig,
|
||||||
gauge_cfg: BaseGaugeConfig
|
gauge_cfg: BaseGaugeConfig,
|
||||||
|
args,
|
||||||
):
|
):
|
||||||
self.run_name = run_name
|
self.run_name = run_name
|
||||||
self.sim_cfg = simulator_cfg
|
self.sim_cfg = simulator_cfg
|
||||||
self.robot_cfg = robot_cfg
|
self.robot_cfg = robot_cfg
|
||||||
self.gauge_cfg = gauge_cfg
|
self.gauge_cfg = gauge_cfg
|
||||||
|
self.args = args
|
||||||
|
|
||||||
self.sim: MujocoSimulator = eval(simulator_cfg.simulator_class)(simulator_cfg)
|
self.sim: MujocoSimulator = eval(simulator_cfg.simulator_class)(simulator_cfg)
|
||||||
self.robot: BaseRobot = eval(robot_cfg.robot_class)(robot_cfg)
|
self.robot: BaseRobot = eval(robot_cfg.robot_class)(robot_cfg)
|
||||||
@@ -44,7 +46,7 @@ class BasePipeline:
|
|||||||
|
|
||||||
# save configs
|
# save configs
|
||||||
cfg = {}
|
cfg = {}
|
||||||
for name in ['sim_cfg', 'robot_cfg', 'gauge_cfg']:
|
for name in ['args', 'sim_cfg', 'robot_cfg', 'gauge_cfg']:
|
||||||
obj = getattr(self, name)
|
obj = getattr(self, name)
|
||||||
obj_dict = class_to_dict(obj)
|
obj_dict = class_to_dict(obj)
|
||||||
cfg.update({name: obj_dict})
|
cfg.update({name: obj_dict})
|
||||||
|
|||||||
@@ -38,54 +38,66 @@ GOALS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def run_pipeline(args, progress_queue, data):
|
def run_pipeline(args, progress_queue, data):
|
||||||
args = deepcopy(args)
|
try:
|
||||||
task_id = data['task_id']
|
args = deepcopy(args)
|
||||||
search = data['search_max_level']
|
task_id = data['task_id']
|
||||||
task_label = f"[{data['terrain_name']}] M:{data['base_mass']} F:{data['friction']}"
|
search = data['search_max_level']
|
||||||
progress_data = ProgressData(
|
task_label = f"[{data['terrain_name']}] M:{data['base_mass']} F:{data['friction']}"
|
||||||
task_id=task_id,
|
progress_data = ProgressData(
|
||||||
msg_prefix=task_label + ' ',
|
task_id=task_id,
|
||||||
progress_queue=progress_queue
|
msg_prefix=task_label + ' ',
|
||||||
)
|
progress_queue=progress_queue
|
||||||
|
)
|
||||||
|
|
||||||
args.friction = data['friction']
|
args.friction = data['friction']
|
||||||
args.frictions = [data['friction']]
|
args.frictions = [data['friction']]
|
||||||
args.base_mass = data['base_mass']
|
args.base_mass = data['base_mass']
|
||||||
args.base_masses = [data['base_mass']]
|
args.base_masses = [data['base_mass']]
|
||||||
args.task_name = f"{data['task_robot_model']}.{data['terrain_name']}"
|
|
||||||
args.experiment_name = f"{args.experiment_name}_{data['terrain_name']}_M{data['base_mass']}_F{data['friction']}"
|
|
||||||
|
|
||||||
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)")
|
|
||||||
results = {
|
|
||||||
'success': False,
|
|
||||||
'results': level_results,
|
|
||||||
'data': data,
|
|
||||||
'level': 0,
|
|
||||||
}
|
|
||||||
return results
|
|
||||||
report_progress(progress_data, ProgressTypes.RESET, total=0, desc=f"✅ Found Lv {level} -> Running")
|
|
||||||
progress_data.msg_prefix += f"(Lv {level}) "
|
|
||||||
else:
|
|
||||||
level = None # flat terrain
|
|
||||||
args.task_name = f"{data['task_robot_model']}.{data['terrain_name']}"
|
args.task_name = f"{data['task_robot_model']}.{data['terrain_name']}"
|
||||||
args.experiment_name = f"{args.experiment_name}_{data['terrain_name']}"
|
args.experiment_name = f"{args.experiment_name}_{data['terrain_name']}_M{data['base_mass']}_F{data['friction']}"
|
||||||
|
|
||||||
args.level = level
|
if search is True:
|
||||||
args.goals = GOALS['multi_pipeline']
|
args.goals = GOALS['level_pipeline']
|
||||||
args.spawn_type = "level_eval"
|
args.spawn_type = "level_search"
|
||||||
results = {
|
level, level_results = LevelPipeline(args, console_output=False, progress_data=progress_data).run()
|
||||||
'success': True,
|
if level == 0: # no valid level found
|
||||||
'results': MultiPipeline(args, console_output=False, progress_data=progress_data).run(),
|
report_progress(progress_data, ProgressTypes.FINISH, desc=f"❌ Failed (Lv 0)")
|
||||||
'data': data,
|
results = {
|
||||||
'level': level,
|
'success': False,
|
||||||
}
|
'results': level_results,
|
||||||
report_progress(progress_data, ProgressTypes.FINISH, desc=f"✅ Done (Lv {level})")
|
'data': data,
|
||||||
return results
|
'level': 0,
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
report_progress(progress_data, ProgressTypes.RESET, total=0, desc=f"✅ Found Lv {level} -> Running")
|
||||||
|
progress_data.msg_prefix += f"(Lv {level}) "
|
||||||
|
else:
|
||||||
|
level = None # flat terrain
|
||||||
|
args.task_name = f"{data['task_robot_model']}.{data['terrain_name']}"
|
||||||
|
args.experiment_name = f"{args.experiment_name}_{data['terrain_name']}"
|
||||||
|
|
||||||
|
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(),
|
||||||
|
'data': data,
|
||||||
|
'level': level,
|
||||||
|
}
|
||||||
|
report_progress(progress_data, ProgressTypes.FINISH, desc=f"✅ Done (Lv {level})")
|
||||||
|
return results
|
||||||
|
except Exception as e:
|
||||||
|
error_context = (
|
||||||
|
f"\n{'='*20} 💥 CRASH CONTEXT 💥 {'='*20}\n"
|
||||||
|
f"Terrain : {data.get('terrain_name')}\n"
|
||||||
|
f"Friction : {data.get('friction')}\n"
|
||||||
|
f"Base Mass : {data.get('base_mass')}\n"
|
||||||
|
f"Task ID : {data.get('task_id')}\n"
|
||||||
|
f"Original Error: {str(e)}\n"
|
||||||
|
f"{'='*60}"
|
||||||
|
)
|
||||||
|
raise RuntimeError(error_context) from e
|
||||||
|
|
||||||
class StressPipeline:
|
class StressPipeline:
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ class TaskRegister():
|
|||||||
def get_cfgs(self, name):
|
def get_cfgs(self, name):
|
||||||
if name not in self.sim_cfgs:
|
if name not in self.sim_cfgs:
|
||||||
raise ValueError(f"Task '{name}' is not registered, checkout '{ROBOGAUGE_ROOT_DIR}/robogauge/tasks/__init__.py'.")
|
raise ValueError(f"Task '{name}' is not registered, checkout '{ROBOGAUGE_ROOT_DIR}/robogauge/tasks/__init__.py'.")
|
||||||
sim_cfg = self.sim_cfgs[name]
|
sim_cfg = self.sim_cfgs[name]()
|
||||||
gauger_cfg = self.gauger_cfgs[name]
|
gauger_cfg = self.gauger_cfgs[name]()
|
||||||
robot_cfg = self.robot_cfgs[name]
|
robot_cfg = self.robot_cfgs[name]()
|
||||||
return sim_cfg, gauger_cfg, robot_cfg
|
return sim_cfg, gauger_cfg, robot_cfg
|
||||||
|
|
||||||
def make_pipeline(self, args=None, sim_cfg=None, gauger_cfg=None, robot_cfg=None, create_logger=True):
|
def make_pipeline(self, args=None, sim_cfg=None, gauger_cfg=None, robot_cfg=None, create_logger=True):
|
||||||
@@ -55,7 +55,7 @@ class TaskRegister():
|
|||||||
run_name = args.run_name + f'_{args.seed}'
|
run_name = args.run_name + f'_{args.seed}'
|
||||||
if create_logger:
|
if create_logger:
|
||||||
logger.create(args.experiment_name, run_name)
|
logger.create(args.experiment_name, run_name)
|
||||||
return pipeline_class(run_name, sim_cfg, robot_cfg, gauger_cfg)
|
return pipeline_class(run_name, sim_cfg, robot_cfg, gauger_cfg, args)
|
||||||
|
|
||||||
def update_args_to_cfg(self, sim_cfg, gauger_cfg, robot_cfg, args):
|
def update_args_to_cfg(self, sim_cfg, gauger_cfg, robot_cfg, args):
|
||||||
if args.model_path is not None:
|
if args.model_path is not None:
|
||||||
|
|||||||
Reference in New Issue
Block a user