turtlebot3-burger_150.png
turtlebot3-waffle-pi_150.png
turtlebot3-arm_150.png
walking-y2_150.png
turbot3-multi_150.png
turbot3-dl-ros1_150.png
turbot3-ai.png
turbot3-dl-ros2_150.png
turbot3-slam_150.png
turbot3-arm_150.png
turtlebot4-lite_150.png
turtlebot4-pro_150.png
turbot4-dl_150.png
turbot4-ai_150.png
aidriving-racebot_150.png
aidriving-autodrive_150.png
turtlebot-arm_150.png
openmanipulator-x_150.png
Home » OpenDuckMini强化学习框架入门教程 » OpenDuckMini强化学习框架入门教程-动作过滤

OpenDuckMini强化学习框架入门教程-动作过滤

纠错,疑问,交流: 请进入讨论区请点击进入页面,扫码加入微信群或Q群进行交流

获取最新文章: 扫一扫加入“创客智造”公众号

欢迎加入我们的openduckmini交流群,微信扫描右侧二维码立即进群交流

群二维码

动作过滤

  • 理解动作过滤,包含过滤方式,动作过滤流程和代码中的使用等

概述

动作过滤是确保策略输出平滑、自然的关键环节。Open Duck Playground 提供了三种不同层次的动作过滤方式,从软约束(奖励函数鼓励)到硬约束(物理限制),全面防止机器人动作中出现不可取的抖动或突变。

三种过滤方式

┌──────────────────────────────────────────────────────────┐
│                  动作过滤方案对比                          │
├──────────────────────────────────────────────────────────┤
│                                                        │
│  1. 动作变化率代价 (cost_action_rate)                    │
│     ┌─────┐    ┌─────┐    ┌─────┐                      │
│     │ Soft │───→│ 鼓励 │───→│ 平滑 │                      │
│     └─────┘    └─────┘    └─────┘                      │
│     软约束,通过奖励引导策略输出平滑动作                   │
│                                                        │
│  2. 电机速度限制 (motor velocity limits)                 │
│     ┌──────┐    ┌──────┐    ┌──────┐                   │
│     │ Hard │───→│ 限制 │───→│ 安全 │                      │
│     └──────┘    └──────┘    └──────┘                   │
│     硬约束,物理上限制每步最大角度变化                     │
│                                                        │
│  3. 低通滤波器 (LowPassActionFilter)                    │
│     ┌─────┐    ┌──────┐    ┌──────┐                    │
│     │ DSP │───→│ 滤波 │───→│ 平滑 │                      │
│     └─────┘    └──────┘    └──────┘                    │
│     数字信号处理,一阶 RC 低通滤波                        │
│                                                        │
└──────────────────────────────────────────────────────────┘

1. 动作变化率代价

位置playground/common/rewards.pycost_action_rate()

工作原理: 通过奖励函数惩罚相邻动作之间的差异,鼓励策略自学产生平滑的动作序列。

def cost_action_rate(act, last_act):
    return jp.nan_to_num(jp.sum(jp.square(act - last_act)))

效果

  • 动作变化越小 → 代价越低 → 策略倾向于输出稳定的动作
  • 平方放大大的变化 → 大幅度抖动的惩罚远大于轻微变化
  • 这是一种软约束——策略可以选择违反它,但会付出奖励代价

权重配置

环境 权重 效果
Joystick -0.5 中度平滑约束
Standing -0.375 较弱的平滑约束(站立动作较慢)

2. 电机速度限制

位置joystick.pymujoco_infer.pyUSE_MOTOR_SPEED_LIMITS

工作原理: 限制每个控制周期内电机目标位置的最大变化量,模拟真实舵机的最大旋转速度。

max_motor_velocity = 5.24  # rad/s

# 每步最大允许变化
max_delta = max_motor_velocity * dt  # dt = 0.02s (控制周期)
# max_delta = 5.24 * 0.02 = 0.1048 rad ≈ 6°

# 限制动作
motor_targets = jp.clip(
    motor_targets,
    prev_motor_targets - max_delta,
    prev_motor_targets + max_delta,
)

参数说明

参数 物理意义
max_motor_velocity 5.24 rad/s 约 300°/s,接近 STS3215 舵机实际最大速度
控制周期 ctrl_dt 0.02 s 50 Hz 控制频率
每步最大变化 0.1048 rad 约 6°
仿真步长 sim_dt 0.002 s 500 Hz 物理仿真

为什么这很重要

无速度限制:
  action: [-1.0  →  +1.0]  (瞬间反转)
  motor_targets: [-0.25 → +0.25]  (0.5 rad 的突变)
  → 物理上不可能,舵机会丢步

有速度限制:
  action: [-1.0  →  +1.0]  (策略输出)
  motor_targets: [-0.25 → -0.145 → -0.038 → ... → +0.25]
  → 需要约 5 个控制周期 (0.1s) 完成反转,舵机的实际行为

3. 低通滤波器 (LowPassActionFilter)

位置playground/common/utils.pyLowPassActionFilter

工作原理: 一阶 IIR 低通滤波器,类似于模拟 RC 电路的数字实现。

class LowPassActionFilter:
    def __init__(self, control_freq, cutoff_frequency=37.5):
        self.alpha = (1/cutoff_freq) / (1/control_freq + 1/cutoff_freq)
    
    def push(self, action):
        self.current_action = action
    
    def get_filtered_action(self):
        # 一阶指数平滑
        self.last_action = (
            self.alpha * self.last_action + 
            (1 - self.alpha) * self.current_action
        )
        return self.last_action

频率响应

传递函数: H(s) = 1 / (1 + s/ωc)
其中: ωc = 2π * cutoff_frequency

幅频特性:
  - 截止频率: f_c = 37.5 Hz
  - 低于 f_c: 几乎无衰减
  - 高于 f_c: -20 dB/decade 衰减
  - 在 f_c: -3 dB

时间常数

τ = 1 / (2π * f_c)
  = 1 / (2π * 37.5)
  ≈ 4.24 ms

这意味滤波器对约 4ms 以上的变化基本无影响,
但对更快的高频抖动有显著抑制效果。

当前状态:在 joystick.pymujoco_infer.py 中,低通滤波器代码已被注释,因为电机速度限制提供了更符合物理实际的平滑效果。

三种方式的对比分析

特性 动作变化率代价 电机速度限制 低通滤波
约束类型 软约束 (奖励) 硬约束 (物理) 信号处理
训练/推理 训练 + 推理 训练 + 推理 仅推理
是否启用 ✅ 始终 ✅ 默认 ❌ 已注释
引入延迟 有 (1-5 步) 有 (约 τ)
物理逼真度 高 (模拟舵机行为)
实现复杂度 低 (单行) 中 (clip 操作) 低 (状态保持)

动作过滤流程(推理时)

策略输出 (action in [-1, 1])
    │
    ▼
  ┌─────────────────────────────────────┐
  │ 可选: LowPassActionFilter           │
  │  (当前已注释,未使用)                 │
  └─────────────────────────────────────┘
    │
    ▼
action * action_scale (0.25)
    │
    ▼
                    ┌───────────────────────────────┐
motor_targets = ───→│ 电机速度限制 (硬约束)            │
  default_actuator   │ max_motor_velocity = 5.24 rad/s│
  + scaled_action   └───────────────┬───────────────┘
    │                               │
    ▼                               ▼
 无限制目标位置 ───────────────→ 限制后的目标位置
                                  │
                                  ▼
                             MuJoCo 物理仿真
                                  │
                                  ▼
                           实际关节位置

代码中的使用

训练时 (joystick.py)

# 默认启用速度限制
USE_MOTOR_SPEED_LIMITS = True

if USE_MOTOR_SPEED_LIMITS:
    prev_motor_targets = state.info["motor_targets"]
    motor_targets = jp.clip(
        motor_targets,
        prev_motor_targets - self._config.max_motor_velocity * self.dt,
        prev_motor_targets + self._config.max_motor_velocity * self.dt,
    )

推理时 (mujoco_infer.py)

# 低通滤波器 (已注释)
# self.action_filter.push(action)
# action = self.action_filter.get_filtered_action()

# 使用速度限制
self.motor_targets = self.default_actuator + action * self.action_scale

if USE_MOTOR_SPEED_LIMITS:
    self.motor_targets = np.clip(
        self.motor_targets,
        self.prev_motor_targets - self.max_motor_velocity * dt,
        self.prev_motor_targets + self.max_motor_velocity * dt,
    )
    self.prev_motor_targets = self.motor_targets.copy()

最佳实践

  1. 训练时:同时使用 cost_action_rate(软约束)+ 速度限制(硬约束)
  2. 推理时:只使用速度限制(不需要奖励函数)
  3. 调参
    • 增大 max_motor_velocity → 动作更敏捷但可能抖动
    • 减小 max_motor_velocity → 动作更平滑但响应变慢
    • 调整 cost_action_rate 的权重 → 平衡平滑性和响应速度
  4. 部署到真实机器人:始终启用速度限制,必要时增加低通滤波作为额外平滑层

纠错,疑问,交流: 请进入讨论区请点击进入页面,扫码加入微信群或Q群进行交流

获取最新文章: 扫一扫加入“创客智造”公众号

欢迎加入我们的openduckmini交流群,微信扫描右侧二维码立即进群交流

群二维码

标签: OpenDuckMini强化学习框架