robot_lab——rsl_rl的train.py整体逻辑
文章目录
- Go2机器人训练流程详细分析
- 概述
- 1. 训练启动流程
- 1.1 命令行参数解析
- RSL-RL相关参数组
- Isaac Sim应用启动参数组
- 1.2 RL配置
- 1.3 Isaac Sim启动
- 2. 环境配置加载
- 2.1 Hydra配置系统
- 3. 环境创建与初始化
- 3.1 Gym环境创建
- 3.2 Manager系统初始化
- 3.2.1 ObservationManager
- 3.2.2 ActionManager
- 3.2.3 RewardManager
- 3.2.4 TerminationManager
- 3.2.5 EventManager
- 3.2.6 CommandManager
- 4. 训练循环
- 4.1 RSL-RL包装器
- 4.2 训练器初始化
- 4.3 训练主循环
- 4.3.1 数据收集阶段(Rollout Phase)
- 4.3.2 优势函数计算(GAE - Generalized Advantage Estimation)
- 4.3.3 网络更新阶段(Policy Update Phase)
- 4.3.4 PPO损失函数详细实现
- 4.3.5 神经网络架构
- 4.3.6 学习率调度
- 4.3.7 训练监控和日志
- 4.3.8 完整训练循环
- 5. 仿真步骤详细流程
- 5.1 单步仿真流程
- 6 训练监控与日志
- 6.1 日志系统
- 6.2 监控指标
- 6. 总结
Go2机器人训练流程详细分析
概述
本文档详细分析了使用命令 python scripts/rsl_rl/base/train.py --task RobotLab-Isaac-Velocity-Rough-Unitree-Go2-v0 --headless
训练Go2机器人的完整流程,包括底层实现细节、MDP组件的使用以及Manager系统的工作原理。
1. 训练启动流程
1.1 命令行参数解析
# 在 train.py 中
parser = argparse.ArgumentParser(description="Train an RL agent with RSL-RL.")
parser.add_argument("--task", type=str, default=None, help="Name of the task.")
# 其他参数...
cli_args.add_rsl_rl_args(parser) # 添加RSL-RL特定参数
AppLauncher.add_app_launcher_args(parser) # 添加Isaac Sim启动参数
RSL-RL相关参数组
--experiment_name # 实验文件夹名称,日志将存储在此处
--run_name # 运行名称后缀,添加到日志目录
--resume # 是否从检查点恢复训练
--load_run # 要恢复的运行文件夹名称
--checkpoint # 要恢复的检查点文件
--logger # 日志记录模块 (wandb, tensorboard, neptune)
--log_project_name # 使用wandb或neptune时的项目名称
Isaac Sim应用启动参数组
--headless # 强制无头模式运行(无GUI)
--livestream # 启用直播流 (0:禁用, 1:原生[已弃用], 2:WebRTC)
--enable_cameras # 启用相机传感器和相关扩展依赖
--xr # 启用XR模式用于VR/AR应用
--device # 仿真运行设备 ("cpu", "cuda", "cuda:N")
--verbose # 启用详细级别的日志输出
--info # 启用信息级别的日志输出
--experience # 启动时加载的体验文件
--rendering_mode # 渲染模式 ("performance", "balanced", "quality", "xr")
--kit_args # 直接传递给Omniverse Kit的命令行参数
关键参数处理:
--task RobotLab-Isaac-Velocity-Rough-Unitree-Go2-v0
: 指定训练任务--headless
: 无头模式运行,不显示GUI--num_envs
: 并行环境数量(默认4096)--max_iterations
: 最大训练迭代次数
1.2 RL配置
import gymnasium as gym # 强化学习环境标准接口
import os # 文件路径操作
import torch # PyTorch 深度学习框架
from datetime import datetime # 时间戳生成
from rsl_rl.runners import OnPolicyRunner # RSL-RL 的策略梯度算法实现from isaaclab.envs import (DirectMARLEnv, # 多智能体直接控制环境DirectMARLEnvCfg, # 多智能体环境配置DirectRLEnvCfg, # 单智能体直接控制环境配置ManagerBasedRLEnvCfg, # 基于管理层的环境配置(复杂任务)multi_agent_to_single_agent, # 多智能体转单智能体的工具函数
)from isaaclab_rl.rsl_rl import (RslRlOnPolicyRunnerCfg, # RSL-RL 训练器配置RslRlVecEnvWrapper # 将环境包装为 RSL-RL 需要的矢量化格式
)from isaaclab_tasks.utils import get_checkpoint_path # 加载模型检查点
from isaaclab_tasks.utils.hydra import hydra_task_config # Hydra 配置集成
import robot_lab.tasks # noqa: F401 # 注册机器人任务到 Gymnasiumfrom isaaclab.utils.dict import print_dict # 美观打印字典
from isaaclab.utils.io import dump_pickle, dump_yaml # 保存配置文件torch.backends.cuda.matmul.allow_tf32 = True # 启用 TF32 加速矩阵运算
torch.backends.cudnn.allow_tf32 = True # 启用 cuDNN 的 TF32 支持
torch.backends.cudnn.deterministic = False # 禁用确定性算法(提升速度)
torch.backends.cudnn.benchmark = False # 禁用自动寻找最优卷积算法(避免波动)
OnPolicyRunner: 实现 PPO 等 on-policy 算法的训练流程(数据收集、策略更新、日志记录)。
1.3 Isaac Sim启动
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
底层实现:
- 初始化Omniverse Kit应用
- 配置GPU设备和渲染设置
- 设置物理引擎参数(PhysX)
2. 环境配置加载
2.1 Hydra配置系统
@hydra_task_config(args_cli.task, "rsl_rl_cfg_entry_point")
def main(env_cfg: ManagerBasedRLEnvCfg, agent_cfg: RslRlOnPolicyRunnerCfg):
配置加载过程:
-
根据任务名称
RobotLab-Isaac-Velocity-Rough-Unitree-Go2-v0
查找对应配置
-
加载环境配置 (
UnitreeGo2RoughEnvCfg
)
-
加载智能体配置 (
RslRlOnPolicyRunnerCfg
)
3. 环境创建与初始化
3.1 Gym环境创建
env = gym.make(args_cli.task, cfg=env_cfg, render_mode="rgb_array" if args_cli.video else None)
底层创建过程:
-
场景初始化 (
MySceneCfg
):- 地形生成(粗糙地形)
- 机器人模型加载(Go2 USD文件)
- 传感器配置(接触传感器、高度扫描器)
- 光照设置
-
物理世界设置:
- 重力设置
- 物理材料属性
- 碰撞检测配置
3.2 Manager系统初始化
环境使用ManagerBasedRLEnvCfg架构,包含以下Manager:
3.2.1 ObservationManager
@configclass
class ObservationsCfg:@configclassclass PolicyCfg(ObsGroup):# 基础运动状态观测base_lin_vel = ObsTerm(func=mdp.base_lin_vel, scale=2.0, noise=UniformNoise(n_min=-0.1, n_max=0.1))base_ang_vel = ObsTerm(func=mdp.base_ang_vel, scale=0.25, noise=UniformNoise(n_min=-0.2, n_max=0.2))# 重力投影向量(用于姿态感知)projected_gravity = ObsTerm(func=mdp.projected_gravity, noise=UniformNoise(n_min=-0.05, n_max=0.05))# 速度命令(目标速度)velocity_commands = ObsTerm(func=mdp.generated_commands)# 关节状态观测joint_pos = ObsTerm(func=mdp.joint_pos_rel, scale=1.0,noise=UniformNoise(n_min=-0.01, n_max=0.01),params={"asset_cfg": SceneEntityCfg("robot", joint_names=self.joint_names)})joint_vel = ObsTerm(func=mdp.joint_vel_rel,scale=0.05, noise=UniformNoise(n_min=-1.5, n_max=1.5),params={"asset_cfg": SceneEntityCfg("robot", joint_names=self.joint_names)})# 历史动作信息actions = ObsTerm(func=mdp.last_action)# 地形高度扫描(在Go2配置中被禁用)height_scan = None # 在Go2配置中设置为None
MDP函数调用时机:
- 每个仿真步骤后调用观测函数
- 从场景中提取机器人状态信息
- 应用噪声和归一化处理
- Go2特定配置:禁用了基础线速度和高度扫描观测
3.2.2 ActionManager
@configclass
class ActionsCfg:joint_pos = mdp.JointPositionActionCfg(asset_name="robot",joint_names=["FR_hip_joint", "FR_thigh_joint", "FR_calf_joint","FL_hip_joint", "FL_thigh_joint", "FL_calf_joint", "RR_hip_joint", "RR_thigh_joint", "RR_calf_joint","RL_hip_joint", "RL_thigh_joint", "RL_calf_joint"],# Go2特定的动作缩放:髋关节较小缩放,其他关节较大缩放scale={".*_hip_joint": 0.125, "^(?!.*_hip_joint).*": 0.25},clip={".*": (-100.0, 100.0)},use_default_offset=True)
动作处理流程:
- 接收神经网络输出的动作(12维向量,对应12个关节)
- 应用不同的缩放系数(髋关节0.125,其他关节0.25)
- 应用动作裁剪(±100.0)
- 转换为关节位置目标
- 发送给PD控制器
3.2.3 RewardManager
@configclass
class RewardsCfg:# 速度跟踪奖励(主要奖励)track_lin_vel_xy_exp = RewTerm(func=mdp.track_lin_vel_xy_exp,weight=3.0, # Go2中权重较高params={"command_name": "base_velocity", "std": math.sqrt(0.25)})track_ang_vel_z_exp = RewTerm(func=mdp.track_ang_vel_z_exp,weight=1.5,params={"command_name": "base_velocity", "std": math.sqrt(0.25)})# 运动约束惩罚lin_vel_z_l2 = RewTerm(func=mdp.lin_vel_z_l2, weight=-2.0) # 垂直速度惩罚ang_vel_xy_l2 = RewTerm(func=mdp.ang_vel_xy_l2, weight=-0.05) # 俯仰滚转惩罚# 关节相关惩罚joint_torques_l2 = RewTerm(func=mdp.joint_torques_l2, weight=-2.5e-5)joint_acc_l2 = RewTerm(func=mdp.joint_acc_l2, weight=-2.5e-7)joint_pos_limits = RewTerm(func=mdp.joint_pos_limits, weight=-5.0)joint_power = RewTerm(func=mdp.joint_power, weight=-2e-5)# 动作平滑性action_rate_l2 = RewTerm(func=mdp.action_rate_l2, weight=-0.01)# 接触相关奖励undesired_contacts = RewTerm(func=mdp.undesired_contacts,weight=-1.0,params={"sensor_cfg": SceneEntityCfg("contact_forces", body_names="^(?!.*_foot).*")})contact_forces = RewTerm(func=mdp.contact_forces,weight=-1.5e-4,params={"sensor_cfg": SceneEntityCfg("contact_forces", body_names=".*_foot")})# 足部高度控制feet_height_body = RewTerm(func=mdp.feet_height_body,weight=-5.0,params={"target_height": -0.2,"asset_cfg": SceneEntityCfg("robot", body_names=".*_foot")})# 向上运动奖励upward = RewTerm(func=mdp.upward, weight=1.0)
奖励计算过程:
- 每个仿真步骤计算所有奖励项
- 使用MDP模块中的奖励函数
- 应用权重并求和得到总奖励
- Go2特定:强调速度跟踪,禁用了多个奖励项(权重设为0或None)
3.2.4 TerminationManager
@configclass
class TerminationsCfg:# 超时终止time_out = DoneTerm(func=mdp.time_out, time_out=True)# 非法接触终止(在Go2配置中被禁用)illegal_contact = None # Go2配置中设置为None,不使用此终止条件
Go2特定配置:
- 只保留超时终止条件
- 禁用了非法接触终止,使训练更加稳定
3.2.5 EventManager
@configclass
class EventCfg:# 重置时的位置和速度随机化randomize_reset_base = EventTerm(func=mdp.reset_root_state_uniform,mode="reset",params={"pose_range": {"x": (-0.5, 0.5), "y": (-0.5, 0.5), "z": (0.0, 0.2),"roll": (-3.14, 3.14), "pitch": (-3.14, 3.14), "yaw": (-3.14, 3.14)},"velocity_range": {"x": (-0.5, 0.5), "y": (-0.5, 0.5), "z": (-0.5, 0.5),"roll": (-0.5, 0.5), "pitch": (-0.5, 0.5), "yaw": (-0.5, 0.5)}})# 启动时的质量随机化randomize_rigid_body_mass = EventTerm(func=mdp.randomize_rigid_body_mass,mode="startup",params={"asset_cfg": SceneEntityCfg("robot", body_names=["base"]),"mass_distribution_params": (-3.0, 3.0)})# 质心位置随机化randomize_com_positions = EventTerm(func=mdp.randomize_rigid_body_com,mode="startup", params={"asset_cfg": SceneEntityCfg("robot", body_names=["base"]),"com_distribution_params": {"x": (-0.1, 0.1), "y": (-0.1, 0.1), "z": (-0.1, 0.1)}})# 外力扰动randomize_apply_external_force_torque = EventTerm(func=mdp.apply_external_force_torque,mode="interval",params={"asset_cfg": SceneEntityCfg("robot", body_names=["base"]),"force_range": {"x": (-50.0, 50.0), "y": (-50.0, 50.0), "z": (0.0, 0.0)},"torque_range": {"x": (-10.0, 10.0), "y": (-10.0, 10.0), "z": (-10.0, 10.0)}})
3.2.6 CommandManager
@configclass
class CommandsCfg:base_velocity = mdp.UniformVelocityCommandCfg(asset_name="robot",resampling_time_range=(10.0, 10.0), # 每10秒重新采样命令rel_standing_envs=0.02, # 2%的环境保持静止rel_heading_envs=1.0, # 100%的环境包含航向命令ranges=mdp.UniformVelocityCommandCfg.Ranges(lin_vel_x=(-1.0, 1.0), # 前进后退速度范围lin_vel_y=(-1.0, 1.0), # 左右平移速度范围 ang_vel_z=(-1.0, 1.0), # 转向角速度范围heading=(-3.14, 3.14) # 航向角范围))
命令生成特点:
- 每10秒重新采样速度命令
- 支持全向运动(前后、左右、转向)
- 包含航向控制
- 少量环境保持静止状态用于训练稳定性
4. 训练循环
4.1 RSL-RL包装器
env = RslRlVecEnvWrapper(env, clip_actions=agent_cfg.clip_actions)
包装器功能:
- 适配RSL-RL接口
- 处理动作裁剪
- 批量环境管理
4.2 训练器初始化
runner = OnPolicyRunner(env, agent_cfg.to_dict(), log_dir=log_dir, device=agent_cfg.device)
OnPolicyRunner组件:
- PPO算法实现
- 经验缓冲区管理
- 策略和价值网络更新
4.3 训练主循环
runner.learn(num_learning_iterations=agent_cfg.max_iterations, init_at_random_ep_len=True)
每次迭代包含:
4.3.1 数据收集阶段(Rollout Phase)
def collect_rollouts(self):"""收集经验数据的详细流程"""# 重置经验缓冲区self.storage.clear()for step in range(self.num_steps_per_env): # 默认24步# 1. 获取当前观测obs = self.env.get_observations()["policy"] # 形状: [num_envs, obs_dim]# 2. 策略网络前向推理with torch.no_grad():actions, log_probs, values, mu, sigma = self.actor_critic.act(obs)# actions: [num_envs, action_dim] - 采样的动作# log_probs: [num_envs] - 动作的对数概率# values: [num_envs] - 状态价值估计# mu, sigma: 策略分布的均值和标准差# 3. 环境步进next_obs, rewards, dones, infos = self.env.step(actions)# 4. 存储经验到缓冲区self.storage.add_transitions(observations=obs,actions=actions,rewards=rewards,dones=dones,values=values,log_probs=log_probs,mu=mu,sigma=sigma)# 5. 处理环境重置if torch.any(dones):# 重置完成的环境reset_env_ids = torch.where(dones)[0]self.env.reset_idx(reset_env_ids)# 6. 计算最后一步的价值估计(用于优势函数计算)with torch.no_grad():last_values = self.actor_critic.evaluate(next_obs)# 7. 计算回报和优势函数self.storage.compute_returns(last_values, self.gamma, self.lam)
4.3.2 优势函数计算(GAE - Generalized Advantage Estimation)
def compute_returns(self, last_values, gamma=0.99, lam=0.95):"""使用GAE计算优势函数和回报"""# 初始化advantages = torch.zeros_like(self.rewards)returns = torch.zeros_like(self.rewards)# 从后往前计算gae = 0for step in reversed(range(self.num_steps_per_env)):if step == self.num_steps_per_env - 1:next_non_terminal = 1.0 - self.dones[step]next_values = last_valueselse:next_non_terminal = 1.0 - self.dones[step + 1]next_values = self.values[step + 1]# TD误差delta = (self.rewards[step] + gamma * next_values * next_non_terminal - self.values[step])# GAE优势函数gae = delta + gamma * lam * next_non_terminal * gaeadvantages[step] = gae# 回报 = 优势 + 价值估计returns[step] = gae + self.values[step]# 标准化优势函数self.advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-8)self.returns = returns
4.3.3 网络更新阶段(Policy Update Phase)
def update_policy(self):"""PPO策略更新的详细流程"""# 获取所有经验数据obs_batch = self.storage.observations.view(-1, *self.storage.observations.shape[2:])actions_batch = self.storage.actions.view(-1, *self.storage.actions.shape[2:])old_log_probs_batch = self.storage.log_probs.view(-1)advantages_batch = self.advantages.view(-1)returns_batch = self.returns.view(-1)old_values_batch = self.storage.values.view(-1)# 多轮更新for epoch in range(self.num_learning_epochs): # 默认5轮# 随机打乱数据indices = torch.randperm(obs_batch.size(0))# 分批更新for start in range(0, obs_batch.size(0), self.mini_batch_size):end = start + self.mini_batch_sizebatch_indices = indices[start:end]# 获取mini-batch数据obs_mini = obs_batch[batch_indices]actions_mini = actions_batch[batch_indices]old_log_probs_mini = old_log_probs_batch[batch_indices]advantages_mini = advantages_batch[batch_indices]returns_mini = returns_batch[batch_indices]old_values_mini = old_values_batch[batch_indices]# 前向传播log_probs, values, entropy = self.actor_critic.evaluate_actions(obs_mini, actions_mini)# 计算各种损失policy_loss = self._compute_policy_loss(log_probs, old_log_probs_mini, advantages_mini)value_loss = self._compute_value_loss(values, old_values_mini, returns_mini)entropy_loss = entropy.mean()# 总损失total_loss = (policy_loss + self.value_loss_coef * value_loss - self.entropy_coef * entropy_loss)# 反向传播和优化self.optimizer.zero_grad()total_loss.backward()torch.nn.utils.clip_grad_norm_(self.actor_critic.parameters(), self.max_grad_norm)self.optimizer.step()
4.3.4 PPO损失函数详细实现
def _compute_policy_loss(self, log_probs, old_log_probs, advantages):"""计算PPO策略损失(带裁剪)"""# 重要性采样比率ratio = torch.exp(log_probs - old_log_probs)# 未裁剪的策略损失surr1 = ratio * advantages# 裁剪的策略损失surr2 = torch.clamp(ratio, 1.0 - self.clip_param, # 默认0.21.0 + self.clip_param) * advantages# 取较小值(更保守的更新)policy_loss = -torch.min(surr1, surr2).mean()return policy_lossdef _compute_value_loss(self, values, old_values, returns):"""计算价值函数损失"""if self.use_clipped_value_loss:# 裁剪的价值损失values_clipped = old_values + torch.clamp(values - old_values,-self.clip_param,self.clip_param)value_loss1 = (values - returns).pow(2)value_loss2 = (values_clipped - returns).pow(2)value_loss = torch.max(value_loss1, value_loss2).mean()else:# 标准MSE损失value_loss = F.mse_loss(values, returns)return value_loss
4.3.5 神经网络架构
class ActorCritic(nn.Module):"""Actor-Critic网络架构"""def __init__(self, obs_dim, action_dim, hidden_dims=[512, 256, 128]):super().__init__()# 共享特征提取器self.feature_extractor = nn.Sequential(nn.Linear(obs_dim, hidden_dims[0]),nn.ELU(),nn.Linear(hidden_dims[0], hidden_dims[1]),nn.ELU(),nn.Linear(hidden_dims[1], hidden_dims[2]),nn.ELU())# Actor网络(策略)self.actor_mean = nn.Linear(hidden_dims[2], action_dim)self.actor_logstd = nn.Parameter(torch.zeros(action_dim))# Critic网络(价值函数)self.critic = nn.Linear(hidden_dims[2], 1)# 初始化权重self._init_weights()def forward(self, obs):"""前向传播"""features = self.feature_extractor(obs)# 策略分布参数action_mean = self.actor_mean(features)action_std = torch.exp(self.actor_logstd)# 状态价值value = self.critic(features)return action_mean, action_std, valuedef act(self, obs):"""采样动作"""action_mean, action_std, value = self.forward(obs)# 创建正态分布dist = torch.distributions.Normal(action_mean, action_std)# 采样动作action = dist.sample()log_prob = dist.log_prob(action).sum(dim=-1)return action, log_prob, value, action_mean, action_stddef evaluate_actions(self, obs, actions):"""评估给定动作的概率和价值"""action_mean, action_std, value = self.forward(obs)# 创建分布dist = torch.distributions.Normal(action_mean, action_std)# 计算对数概率和熵log_prob = dist.log_prob(actions).sum(dim=-1)entropy = dist.entropy().sum(dim=-1)return log_prob, value.squeeze(), entropy
4.3.6 学习率调度
def update_learning_rate(self, current_iteration):"""自适应学习率调度"""if self.schedule == "adaptive":# 基于KL散度调整学习率if self.mean_kl > self.desired_kl * 2.0:self.learning_rate = max(1e-5, self.learning_rate / 1.5)elif self.mean_kl < self.desired_kl / 2.0:self.learning_rate = min(1e-2, self.learning_rate * 1.5)elif self.schedule == "linear":# 线性衰减self.learning_rate = self.initial_lr * (1.0 - current_iteration / self.max_iterations)# 更新优化器学习率for param_group in self.optimizer.param_groups:param_group['lr'] = self.learning_rate
4.3.7 训练监控和日志
def log_training_info(self, iteration):"""记录训练信息"""# 计算统计信息mean_reward = self.storage.rewards.mean().item()mean_episode_length = self.episode_lengths.float().mean().item()# 策略相关指标mean_kl = self.mean_kl.item()policy_loss = self.policy_loss.item()value_loss = self.value_loss.item()entropy = self.entropy.item()# 记录到TensorBoard/WandBself.logger.log_scalar("Train/MeanReward", mean_reward, iteration)self.logger.log_scalar("Train/MeanEpisodeLength", mean_episode_length, iteration)self.logger.log_scalar("Train/PolicyLoss", policy_loss, iteration)self.logger.log_scalar("Train/ValueLoss", value_loss, iteration)self.logger.log_scalar("Train/Entropy", entropy, iteration)self.logger.log_scalar("Train/KL", mean_kl, iteration)self.logger.log_scalar("Train/LearningRate", self.learning_rate, iteration)# 打印训练进度print(f"Iteration {iteration}: "f"Reward={mean_reward:.2f}, "f"PolicyLoss={policy_loss:.4f}, "f"ValueLoss={value_loss:.4f}")
4.3.8 完整训练循环
def learn(self, num_learning_iterations, init_at_random_ep_len=True):"""完整的PPO训练循环"""# 初始化if init_at_random_ep_len:self.env.reset()for iteration in range(num_learning_iterations):start_time = time.time()# 1. 数据收集阶段self.collect_rollouts()# 2. 网络更新阶段self.update_policy()# 3. 学习率调度self.update_learning_rate(iteration)# 4. 记录日志self.log_training_info(iteration)# 5. 保存检查点if iteration % self.save_interval == 0:self.save_checkpoint(iteration)# 6. 计算训练时间end_time = time.time()print(f"Iteration {iteration} completed in {end_time - start_time:.2f}s")# 训练完成,保存最终模型self.save_checkpoint(num_learning_iterations)print("Training completed!")
关键超参数配置:
# PPO超参数(Go2默认配置)
{"num_steps_per_env": 24, # 每个环境收集的步数"num_learning_epochs": 5, # 每次更新的epoch数"num_mini_batches": 4, # mini-batch数量"clip_param": 0.2, # PPO裁剪参数"gamma": 0.99, # 折扣因子"lam": 0.95, # GAE lambda参数"learning_rate": 1e-3, # 初始学习率"value_loss_coef": 1.0, # 价值损失系数"entropy_coef": 0.01, # 熵损失系数"max_grad_norm": 1.0, # 梯度裁剪"desired_kl": 0.01, # 目标KL散度"schedule": "adaptive", # 学习率调度策略
}
5. 仿真步骤详细流程
5.1 单步仿真流程
1. 获取当前观测 (ObservationManager)├── 调用mdp.base_lin_vel()获取线速度├── 调用mdp.joint_pos_rel()获取关节位置├── 调用mdp.height_scan()获取地形信息└── 应用噪声和归一化2. 策略网络推理├── 输入观测向量└── 输出动作向量3. 动作执行 (ActionManager)├── 调用mdp.JointPositionActionCfg处理动作├── 应用缩放和偏移└── 发送给关节PD控制器4. 物理仿真步进├── PhysX物理引擎计算├── 碰撞检测└── 动力学积分5. 奖励计算 (RewardManager)├── 调用mdp.track_lin_vel_xy_exp()计算速度跟踪奖励├── 调用mdp.GaitReward()计算步态奖励├── 调用其他奖励函数└── 加权求和得到总奖励6. 终止条件检查 (TerminationManager)├── 调用mdp.time_out()检查超时├── 调用mdp.illegal_contact()检查非法接触└── 决定是否重置环境7. 事件处理 (EventManager)├── 检查是否需要随机化├── 调用相应的mdp事件函数└── 更新环境参数8. 命令更新 (CommandManager)├── 检查是否需要重新采样命令└── 生成新的速度命令
6 训练监控与日志
6.1 日志系统
log_dir = os.path.join("logs", "rsl_rl", agent_cfg.experiment_name)
dump_yaml(os.path.join(log_dir, "params", "env.yaml"), env_cfg)
dump_yaml(os.path.join(log_dir, "params", "agent.yaml"), agent_cfg)
6.2 监控指标
- 平均奖励
- 成功率
- 策略损失
- 价值损失
- 熵值
6. 总结
Go2机器人的训练流程是一个复杂的系统,涉及多个层次的组件协作:
- 顶层:训练脚本和命令行接口
- 配置层:Hydra配置系统和环境参数
- 环境层:Isaac Sim物理仿真和场景管理
- Manager层:观测、动作、奖励、终止、事件管理
- MDP层:具体的状态转移、奖励计算函数
- 算法层:RSL-RL的PPO实现
- 底层:GPU加速的物理仿真和张量计算
相关文章:

robot_lab——rsl_rl的train.py整体逻辑
文章目录 Go2机器人训练流程详细分析概述1. 训练启动流程1.1 命令行参数解析RSL-RL相关参数组Isaac Sim应用启动参数组 1.2 RL配置1.3 Isaac Sim启动 2. 环境配置加载2.1 Hydra配置系统 3. 环境创建与初始化3.1 Gym环境创建3.2 Manager系统初始化3.2.1 ObservationManager3.2.2…...
AI推荐系统演进史:从协同过滤到图神经网络与强化学习的融合
每一次滑动手机屏幕,电商平台向你推荐心仪商品的背后,是超过百亿量级的浮点运算。从早期的“猜你喜欢”到如今的“比你更懂你”,商品推荐引擎已悄然完成从简单规则到深度智能的技术跃迁。 一、协同过滤:推荐系统的基石与演进 协同…...
Java-IO流之压缩与解压缩流详解
Java-IO流之压缩与解压缩流详解 一、压缩与解压缩概述1.1 基本概念1.2 Java中的压缩类库1.3 核心类与接口 二、ZIP压缩与解压缩2.1 ZIP格式简介2.2 使用ZipOutputStream创建ZIP文件2.3 使用ZipInputStream读取ZIP文件 三、GZIP压缩与解压缩3.1 GZIP格式简介3.2 使用GZIPOutputS…...

.NET 原生驾驭 AI 新基建实战系列(三):Chroma ── 轻松构建智能应用的向量数据库
在人工智能AI和机器学习ML迅猛发展的今天,数据的存储和检索需求发生了巨大变化。传统的数据库擅长处理结构化数据,但在面对高维向量数据时往往力不从心。向量数据库作为一种新兴技术,专为AI应用设计,能够高效地存储和查询高维向量…...
有声书画本
有声书画本服务标准 有声喵连接 一、基础服务(5r/w字) 核心: 基础删(快捷键AltD)调,优化播讲流畅度 执行: 删除冗余旁白 删除角色动作/心理的重复描述(例:小明冷笑道…...
StarRocks与Apache Iceberg:构建高效湖仓一体的实时分析平台
## 引言:数据湖的挑战与演进 在数据驱动的时代,企业数据湖需要同时满足海量存储、高性能查询、多引擎协作和实时更新等复杂需求。传统基于 Hive 的数据湖方案面临元数据管理低效、缺乏 ACID 事务支持、查询性能瓶颈等问题。在此背景下,**Sta…...
WebRTC 与 WebSocket 的关联关系
WebRTC(Web Real-Time Communication)与 WebSocket 作为重要技术,被广泛应用于各类实时交互场景。虽然它们在功能和特性上存在明显差异,但在实际应用中也有着紧密的关联,共同为用户提供流畅的实时交互体验。 一、WebR…...

8.RV1126-OPENCV 视频中添加LOGO
一.视频中添加 LOGO 图像大体流程 首先初始化VI,VENC模块并使能,然后创建两个线程:1.把LOGO灰度化,然后获取VI原始数据,其次把VI数据Mat化并创建一个感兴趣区域,最后把LOGO放感兴趣区域里并把数据发送给VENC。2.专门获…...

API管理是什么?API自动化测试怎么搭建?
目录 一、API管理是什么 (一)API管理的定义 (二)API管理的重要性 二、API管理的主要内容 (一)API设计 1. 遵循标准规范 2. 考虑可扩展性 3. 保证接口的易用性 (二)API开发 …...
Next.js+prisma开发一
1.初始化Next.js项目 #按版本安装 npx create-next-app13.4.5 如果最新版本 执行:npx create-next-applatest2. 安装Prima和客户端 npm install prisma --save-dev npm install prisma/client3.初始化Prisma,以SQLit举例 # 初始化 Prisma 并配置 SQLi…...

GIC v3 v4 虚拟化架构
ARMV8-A架构中包含了对虚拟化的支持。为了与架构保持匹配,GICV3也对虚拟化做了支持。新增了以下特性: 对CPU interface的硬件虚拟化虚拟中断maintenance 中断:用于通知监管程序(例如hypervisor)一些特定的虚拟机事件 …...

2025远离Deno和Fresh
原创作者:庄晓立(LIIGO) 原创时间:2025年6月6日 原创链接:https://blog.csdn.net/liigo/article/details/148479884 版权所有,转载请注明出处! 相识 Deno,是Nodejs原开发者Ryan Da…...
相机camera开发之差异对比核查一:测试机和对比机的硬件配置差异对比
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、背景 二、:Camera硬件配置差异 2.1:硬件配置差异核查项 2.2 :核查方式 2.3 :高通camx平台核查 2.4 :MTK平台核查...

Flask+LayUI开发手记(七):头像的上传及突破static目录限制
看了看,上篇开发手记是去年8月份写的,到现在差2个月整一年了。停更这么长时间,第一个原因是中间帮朋友忙一个活,那个技术架构是用springboot的,虽然前端也用layUI,但和Flask-python完全不搭界,所…...
uv管理spaCy语言模型
本文记录如何在使用uv管理python项目dependencies时,把spaCy的模型也纳入其中. spaCy 一、spaCy简介 spaCy是一个开源的自然语言处理(NLP)库,它主要用于处理文本数据。它支持多种语言,包括英语、中文等。它是由Expl…...

MiniExcel模板填充Excel导出
目录 1.官方文档 2. 把要导出的数据new一个匿名对象 3.导出 4.注意事项 5.模板制作 6.结果 1.官方文档 https://gitee.com/dotnetchina/MiniExcel/#%E6%A8%A1%E6%9D%BF%E5%A1%AB%E5%85%85-excel // 1. By POCO var value new {Name "Jack",CreateDate n…...
NoSQL之redis哨兵
一、哨兵的核心功能 监控(Monitoring) 持续检查主节点和从节点的运行状态(是否存活、延迟等)。 自动故障转移(Automatic Failover) 当主节点不可用时,自动选举一个从节点升级为主节点。 更新…...

MCP协议重构AI Agent生态:万能插槽如何终结工具孤岛?
前言 在人工智能技术快速发展的2025年,MCP(Model Context Protocol,模型上下文协议)正逐渐成为AI Agent生态系统的关键基础设施。这一由Anthropic主导的开放协议,旨在解决AI模型与外部工具和数据源之间的连接难题,被业界形象地称…...

阿里云事件总线 EventBridge 正式商业化,构建智能化时代的企业级云上事件枢纽
作者:肯梦、稚柳 产品演进历程:在技术浪潮中的成长之路 早在 2018 年,Gartner 评估报告便将事件驱动模型(Event-Driven Model)列为十大战略技术趋势之一,指出事件驱动架构(EDA,Eve…...

CentOS8.3+Kubernetes1.32.5+Docker28.2.2高可用集群二进制部署
一、准备工作 1.1 主机列表 HostnameHost IPDocker IPRolek8s31.vm.com192.168.26.3110.26.31.1/24master&worker、etcd、dockerk8s32.vm.com192.168.26.3210.26.32.1/24master&worker、etcd、dockerk8s33.vm.com192.168.26.3310.26.33.1/24master&worker、etcd、…...

学习日记-day23-6.6
完成目标: 知识点: 1.IO流_转换流使用 ## 转换流_InputStreamReader1.字节流读取中文在编码一致的情况,也不要边读边看,因为如果字节读不准,读不全,输出的内容有可能会出现乱码 2.所以,我们学了字符流,字符流读取文本文档中的内容如果编码一致,就不会出…...

Pytorch安装后 如何快速查看经典的网络模型.py文件(例如Alexnet,VGG)(已解决)
当你用conda 安装好虚拟环境后, 找到你的Anaconda 的安装位置。 我的在D盘下; 然后 从Anaconda3文件夹开始:一级一级的查看,一直到models Anaconda3\envs\openmmlab\Lib\site-packages\torchvision\models 在models下面&#x…...
《ERP原理与应用教程》第3版习题和答案
ERP原理与应用教程是一门系统介绍企业资源计划(Enterprise Resource Planning, ERP)系统核心理论、技术架构及实施应用的综合性课程。它主要面向管理类、信息类、工程类等专业学生及企业管理者,旨在培养对现代企业信息化管理的理解与实践能力。以下是该课程的详细解析: 一…...
JavaScript中的正则表达式:文本处理的瑞士军刀
JavaScript中的正则表达式:文本处理的瑞士军刀 在编程世界中,正则表达式(Regular Expression,简称RegExp)被誉为“文本处理的瑞士军刀”。它能够高效地完成字符串匹配、替换、提取和验证等任务。无论是前端开发中的表…...
vue对axios的封装和使用
在 Vue 项目中,使用 axios 进行 HTTP 请求是非常常见的做法。为了提高代码的可维护性、统一错误处理和请求拦截/响应拦截逻辑,对axios进行封装使用。 一、基础封装(适用于 Vue 2 / Vue 3) 1. 安装 axios npm install axios2. 创…...
软考 系统架构设计师系列知识点之杂项集萃(82)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(81) 第148题 “41”视图主要用于描述系统逻辑架构,最早由Philippe Kruchten于1995年提出。其中( )视图用于描述对象模型,并说明系统应该…...
DrissionPage调试工具:网页自动化与数据采集的革新利器
在网页自动化测试与数据采集领域,开发者长期面临两难选择:使用Selenium等工具操作浏览器时效率不足,而直接调用Requests库又难以应对复杂动态页面。DrissionPage的出现完美解决了这一矛盾,这款基于Python开发的工具创新性地将浏览…...

有人-无人(人机)交互记忆、共享心智模型与AI准确率的边际提升
有人-无人(人机)交互记忆、共享心智模型与AI准确率的边际提升是人工智能发展中相互关联且各有侧重的三个方面。人机交互记忆通过记录和理解用户与机器之间的交互历史,增强机器对用户需求的个性化响应能力,从而提升用户体验和协作效…...
如何使用k8s安装redis呢
在Kubernetes (k8s) 上安装Redis 在Kubernetes上安装Redis有几种方法,下面我将介绍两种常见的方式:使用StatefulSet直接部署和使用Helm chart部署。 一、安装redis 1.1 拉去ARM镜像(7.4.2) docker pull registry.cn-hangzhou.ali…...
AI对测试行业的应用
AI对测试行业的应用 AI技术在软件测试领域的应用已从概念验证全面迈向工程化落地,正在重构测试流程、提升效率边界,并为质量保障体系带来范式级变革。以下从技术突破、行业实践与未来趋势三个维度展开深度解析: ⚙️ 一、核心技术突破&#…...