v1.0.3; fix multiprocess global variables bug

This commit is contained in:
wty-yy
2026-01-02 11:06:06 +08:00
parent 82683ba394
commit c81bdec934
4 changed files with 69 additions and 52 deletions

View File

@@ -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包

View File

@@ -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})

View File

@@ -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):

View File

@@ -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: