# Acrobot 双连杆 Acrobot 是一个双连杆摆动和平衡任务。目标是使用一个电机扭矩摆动双臂并到达目标位置。 ```{video} /_static/videos/acrobot.mp4 :poster: _static/images/poster/acrobot.jpg :nocontrols: :autoplay: :playsinline: :muted: :loop: :width: 100% ``` --- ## 任务描述 双连杆 Acrobot 由一个铰链关节驱动,该关节由单个电机控制。电机安装在肘关节处,这是系统中唯一的驱动关节。电机的扭矩使连杆在平面内旋转,实现从任意初始角度摆起并到达目标位置。扭矩受限于执行器的 ctrlrange;通过调节其大小和方向,策略必须积累能量以摆起并到达目标,同时保持稳定性。 ## 动作空间 | 项目 | 详情 | | -------- | ------------------------------- | | **类型** | `Box(-1.0, 1.0, (1,), float32)` | | **维度** | 1 | --- ## 观察空间 | 项目 | 详情 | | -------- | ------------------------------- | | **类型** | `Box(-inf, inf, (6,), float32)` | | **维度** | 6 | 顺序:`upper_arm_horizontal, lower_arm_horizontal, upper_arm_vertical, lower_arm_vertical, shoulder_velocity, elbow_velocity`。 --- ## 奖励函数设计 - 基础稀疏奖励:鼓励末端进入目标区域(半径 = 0.2) - 持续奖励:在目标区域内每步提供 0.1 的奖励 - 距离奖励:0.3 \* (1.0 - clip(distance / 2.0, 0, 1.0)) 鼓励向目标移动 - 速度惩罚:0.01 \* max(0, velocity_magnitude - 2.0) 惩罚过高的速度 --- ## 初始状态 - 肩关节角度随机于 `[-pi, pi]` - 肘关节角度随机于 `[-pi, pi]` - 角速度初始化为零 ## Episode 终止条件 - Episode 长度由 `max_episode_seconds` 限制 - 对观察值进行 NaN 检查 --- ### 1. 环境预览 ```bash uv run scripts/view.py --env acrobot ``` ### 2. 开始训练 ```bash # 使用默认参数训练 uv run scripts/train.py --env acrobot # 自定义并行环境数 uv run scripts/train.py --env acrobot --num-envs 1024 # 开启训练时渲染 uv run scripts/train.py --env acrobot --render ``` ### 3. 查看训练进度 ```bash uv run tensorboard --logdir runs/acrobot ``` ### 4. 测试训练结果 ```bash # 自动发现最佳策略(推荐) uv run scripts/play.py --env acrobot # 手动指定策略文件 uv run scripts/play.py --env acrobot --policy runs/acrobot/nn/best_policy.pickle ``` > **提示**:策略会从 `runs/acrobot/` 中自动选择。你可以使用 `--policy` 参数覆盖。 --- ## 配置参数 ### 环境配置 ```python @dataclass class AcrobotEnvCfg(EnvCfg): model_file: str = ".../acrobot.xml" # MJCF 模型 max_episode_seconds: float = 10.0 sim_dt: float = 0.01 ctrl_dt: float = 0.02 reset_noise_scale: float = 0.1 render_spacing: float = 2.0 ``` ### 训练配置(PPO 示例) ```python @rlcfg("acrobot", backend="jax") @dataclass class AcrobotPPO(PPOCfg): max_env_steps: int = 60_000_000 check_point_interval: int = 500 # 覆盖 PPO 配置 policy_hidden_layer_sizes: tuple[int, ...] = (32, 32) value_hidden_layer_sizes: tuple[int, ...] = (32, 32) rollouts: int = 64 learning_epochs: int = 5 mini_batches: int = 8 learning_rate: float = 3e-4 grad_norm_clip: float = 0.1 clip_predicted_values: bool = False value_clip: float = 10.0 entropy_loss_scale: float = 0.1 learning_rate_scheduler_kl_threshold: float = 0.02 discount_factor: float = 0.995 lambda_param: float = 0.97 ratio_clip: float = 0.2 value_loss_scale: float = 0.5 random_timesteps: int = 0 learning_starts: int = 0 kl_threshold: float = 0.03 ``` --- ## 预期训练结果 1. Acrobot 能够摆动双臂到达目标位置 2. 末端能够稳定地停留在目标区域内 3. 过高的震荡通过速度惩罚得到减少 4. 策略能够以平滑的动作高效地接近目标