机器人控制
一句话概述
强化学习在机器人控制中实现了从「手工编码控制器」到「数据驱动学习技能」的范式转变。核心挑战包括:高维连续动作空间、物理约束与安全性、仿真到真实环境的迁移(Sim-to-Real gap)。通过域随机化、模仿学习初始化和安全约束,RL已成功应用于机械臂操作、四足/双足机器人行走、无人机飞行等任务。
教学与演示
什么是机器人控制中的RL
传统机器人控制依靠工程师手工设计控制器——写出精确的数学方程来描述「当传感器读到X时,电机应该施加Y牛·米的力」。这对于简单任务是可行的(如PID控制的倒立摆),但一旦面对复杂任务(如让四足机器人走过碎石路面、让机械臂灵活抓取未知形状物体),手工建模就几乎不可能。
RL提供了一条全新的路径:让机器人自己「试」出来该怎么动。
输入是传感器读数(关节角度、摄像头、力传感器),输出是控制指令(电机力矩、目标关节角度)。策略π_θ直接从感知映射到动作——不需要中间任何手工建模步骤。
大白话 传统的机器人控制像「钢琴谱」——工程师把每个动作精确写下来。RL控制像「即兴爵士」——给机器人一个目标(比如「走到对面去」),让它自己摸索出怎么走。摸索的过程中会摔倒无数次(在仿真里摔),但最终学会的技能往往比人写的更自然、更鲁棒。
连续动作空间
机器人控制几乎无一例外是连续动作空间问题——电机力矩、关节角度、推进力都是连续实数,而不是离散的「上下左右」。
这要求RL算法能输出连续动作。主要方法有:
方法一:确定性策略(DDPG/TD3/SAC)
策略直接输出确定的动作值:a = μ_θ(s)。DDPG使用Actor-Critic架构,Actor输出确定动作,Critic评估Q值。
方法二:随机策略(PPO/TRPO)
策略输出动作分布的参数(如高斯分布均值μ和标准差σ),执行时从分布中采样:a ~ N(μ_θ(s), σ_θ(s))。
SAC(Soft Actor-Critic)是目前连续控制任务中最流行的算法:
SAC在最大化奖励的同时最大化策略熵H,鼓励充分探索。
大白话 离散动作像「选餐」——从菜单上点一道菜。连续动作像「放盐」——不是「放」或「不放」,而是「放多少克」。机器人控制几乎全是后者,要求算法能处理连续的、有量级的控制信号。
Sim-to-Real迁移
机器人RL面临一个核心困境:在真实机器人上训练代价极高——每次摔倒都要人去扶、可能损坏硬件、训练速度受限于实时物理。所以训练通常在仿真器(如MuJoCo、Isaac Gym)中进行。
但仿真器和现实世界之间存在Sim-to-Real Gap:
| 方面 | 仿真中 | 现实中 |
|---|---|---|
| 物理参数 | 精确已知 | 未知且变化(摩擦力、质量分布) |
| 传感器噪声 | 可加高斯噪声 | 复杂非线性噪声 |
| 执行器延迟 | 可忽略 | 通信+机械响应延迟 |
| 碰撞建模 | 近似 | 复杂形变与反弹 |
| 视觉 | 完美渲染 | 光照、遮挡、运动模糊 |
三大主流解决方案:
1. 域随机化(Domain Randomization) 在仿真训练期间,随机扰动所有物理参数(摩擦系数、质量、关节阻尼、传感器噪声等),迫使策略对所有可能的环境变化都鲁棒。OpenAI用此方法训练出了能用真实机械手转魔方的策略。
2. 域自适应(Domain Adaptation) 通过在仿真和现实数据之间学习不变的特征表示,或使用GAN将仿真图像「风格迁移」为真实图像,缩小域差距。
3. Sim-to-Real微调 先在仿真中训练到收敛,然后在真实机器人上用少量交互数据微调策略。样本效率高的off-policy算法(如SAC)更适合此方案。
大白话 Sim-to-Real就像飞行员先在飞行模拟器里训练成千上万小时,然后再上真机飞几次适应。关键技巧是让模拟器「故意不准确」——把摩擦力、重量、延迟都随机化,这样训练出的策略到真实世界后什么情况都能应付。
什么用
RL在机器人控制的实际应用:
- undefined
大白话 现在最前沿的机器人公司几乎都在用RL——传统的控制器只能处理可精确建模的情况,而真实世界太复杂。RL让机器人学会「适应」而不是「精确计算」。
哪些坑
| 坑点 | 原因 | 解决方案 |
|---|---|---|
| 仿真不真实 | 刚体碰撞、理想关节与真实物理差距大 | 域随机化、高保真仿真器(Isaac Gym) |
| 安全性 | RL探索过程可能损坏机器人或伤害人类 | 安全层、约束RL、仿真充分验证 |
| 样本效率低 | 物理环境无法加速,训练时间长 | 离线RL、模仿学习初始化、从演示中学习 |
| 策略脆弱 | 对环境扰动敏感,略微变化就失效 | 对抗训练、域随机化、多样性环境 |
| 奖励设计困难 | 「走得好」「抓得稳」难以用数学公式表达 | 逆强化学习、模仿学习、多目标奖励 |
| 硬件限制 | 真实机器人算力有限、实时性要求高 | 模型蒸馏、硬件优化(TensorRT)、边缘推理 |
核心代码演示
"""
连续动作空间RL演示 - SAC算法简化版
展示机器人连续控制的核心要素
"""
import numpy as np
# ===== 连续动作空间环境:2D到达任务 =====
class ReachEnv:
"""
2自由度机械臂的简化模型
智能体需要将末端执行器移动到目标位置
"""
def __init__(self):
self.link_length = 1.0
self.max_steps = 100
self.reset()
def reset(self):
# 关节角度 [θ1, θ2]
self.joint_angles = np.array([0.0, 0.0])
# 随机目标位置
self.target = np.random.uniform(-1.5, 1.5, size=2)
self.steps = 0
return self.get_state()
def forward_kinematics(self):
"""正向运动学:关节角度 → 末端执行器位置"""
theta1, theta2 = self.joint_angles
x = self.link_length * (np.cos(theta1) + np.cos(theta1 + theta2))
y = self.link_length * (np.sin(theta1) + np.sin(theta1 + theta2))
return np.array([x, y])
def get_state(self):
"""状态:关节角度 + 目标位置"""
ee_pos = self.forward_kinematics()
return np.concatenate([
self.joint_angles,
self.target,
ee_pos - self.target # 位置误差
])
def step(self, action):
"""
执行连续动作
action: [Δθ1, Δθ2],每个在[-0.1, 0.1]范围内
"""
# 限制动作幅度
action = np.clip(action, -0.1, 0.1)
self.joint_angles += action
# 计算末端位置并评估奖励
ee_pos = self.forward_kinematics()
distance = np.linalg.norm(ee_pos - self.target)
# 奖励:距离越近越好,加上平滑性奖励
reward = -distance - 0.01 * np.sum(action ** 2)
self.steps += 1
done = distance < 0.05 or self.steps >= self.max_steps
return self.get_state(), reward, done
# ===== SAC风格的连续控制智能体 =====
class SACAgent:
"""
SAC核心组件:高斯策略 + 双Q网络 + 熵正则化
"""
def __init__(self, state_dim, action_dim, lr=0.001, gamma=0.99,
tau=0.005, alpha=0.2):
self.state_dim = state_dim
self.action_dim = action_dim
self.gamma = gamma
self.tau = tau # 目标网络软更新系数
self.alpha = alpha # 熵温度系数
# Actor: 输出高斯分布的均值和对数标准差
self.actor_mean_w = np.random.randn(state_dim, action_dim) * 0.01
self.actor_log_std_w = np.random.randn(state_dim, action_dim) * 0.01
# 双Q网络(减少过估偏差)
self.q1_w = np.random.randn(state_dim + action_dim, 1) * 0.01
self.q2_w = np.random.randn(state_dim + action_dim, 1) * 0.01
# 目标Q网络
self.target_q1_w = self.q1_w.copy()
self.target_q2_w = self.q2_w.copy()
self.lr = lr
def get_action(self, state, deterministic=False):
"""
从高斯策略采样动作
连续动作的核心:输出分布参数而不是离散动作
"""
mean = state @ self.actor_mean_w
log_std = np.clip(state @ self.actor_log_std_w, -20, 2)
std = np.exp(log_std)
if deterministic:
return mean # 测试时用均值
# 重参数化技巧:a = μ + σ * ε, ε ~ N(0, 1)
epsilon = np.random.randn(self.action_dim)
action = mean + std * epsilon
return np.clip(action, -0.1, 0.1)
def get_q_value(self, state, action, q_weights):
"""Q(s, a)计算"""
sa = np.concatenate([state, action])
return np.dot(sa, q_weights).item()
# ===== 演示连续控制 =====
env = ReachEnv()
state_dim = 6 # 2关节角度 + 2目标位置 + 2位置误差
action_dim = 2 # 2个关节力矩
agent = SACAgent(state_dim, action_dim)
print("=== 连续动作空间控制演示 ===\n")
state = env.reset()
ee_start = state[4:6] + state[2:4] # 初始末端位置
print(f"初始关节角度: {state[:2]}")
print(f"目标位置: {state[2:4]}")
print(f"初始末端位置: {ee_start}")
# 演示几次动作选择
for i in range(3):
action = agent.get_action(state, deterministic=False)
print(f"\n第{i+1}次动作: [{action[0]:.4f}, {action[1]:.4f}]")
print(f"(连续动作 vs 离散动作的关键区别:")
print(f" 离散: 动作=0/1/2/3(上下左右)")
print(f" 连续: 动作=[-0.032, 0.047](精确的力矩值))")
next_state, reward, done = env.step(action)
print(f"奖励: {reward:.4f} (距离越近奖励越高)")
state = next_state
print("\n关键洞察:连续控制需要输出实数动作,")
print("不能用argmax(只能用于离散动作),而需要高斯采样!")
"""
域随机化(Domain Randomization)演示
在训练时随机扰动物理参数,使策略对真实世界的变化鲁棒
"""
import numpy as np
class DomainRandomizedEnv:
"""
带域随机化的环境包装器
每次reset时随机化物理参数,让策略学会适应各种条件
"""
def __init__(self, base_env):
self.base_env = base_env
self.randomize()
def randomize(self):
"""随机化物理参数"""
# 质量随机(实际质量 ± 20%)
self.mass_multiplier = np.random.uniform(0.8, 1.2)
# 摩擦力随机(0.3 到 1.2)
self.friction = np.random.uniform(0.3, 1.2)
# 关节阻尼随机
self.joint_damping = np.random.uniform(0.1, 1.5)
# 传感器噪声强度随机
self.sensor_noise = np.random.uniform(0.01, 0.1)
# 执行器延迟随机
self.actuator_delay = np.random.randint(0, 3) # 0-2步延迟
self.params = {
'mass_mult': self.mass_multiplier,
'friction': self.friction,
'damping': self.joint_damping,
'noise': self.sensor_noise,
'delay': self.actuator_delay
}
def apply_dynamics(self, action):
"""
将随机化的参数应用于物理仿真
(实际中这些修改会改变MuJoCo/Isaac Gym的物理参数)
"""
# 模拟质量对动作的影响
effective_action = action / self.mass_multiplier
# 模拟摩擦力
friction_loss = self.friction * np.sign(effective_action) * 0.01
# 模拟阻尼
damping_loss = self.joint_damping * 0.005
return effective_action - friction_loss - damping_loss
def reset(self):
"""每次重置时随机化参数"""
self.randomize()
state = self.base_env.reset()
# 添加传感器噪声
return state + np.random.randn(*state.shape) * self.sensor_noise
def step(self, action):
"""应用随机化物理 + 噪声"""
# 模拟执行器延迟
if self.actuator_delay > 0:
action = action * 0.9 # 延迟相当于动作衰减
modified_action = self.apply_dynamics(action)
return self.base_env.step(modified_action)
# ===== 演示域随机化的效果 =====
class SimpleRobotEnv:
"""简单机器人环境基类"""
def __init__(self):
self.position = 0.0
self.target = 1.0
def reset(self):
self.position = np.random.uniform(-0.1, 0.1)
return np.array([self.position, self.target])
def step(self, action):
self.position += action
reward = -abs(self.position - self.target)
return np.array([self.position, self.target]), reward, abs(self.position - self.target) < 0.05
base_env = SimpleRobotEnv()
randomized_env = DomainRandomizedEnv(base_env)
print("=== 域随机化演示 ===\n")
print("【传统训练】物理参数固定:")
print(" 质量=1.0, 摩擦=1.0, 无噪声 → 策略脆弱")
print(f"\n【域随机化训练】每次reset参数随机:")
for i in range(5):
state = randomized_env.reset()
print(f" Episode {i+1}: 质量={randomized_env.params['mass_mult']:.2f}, "
f"摩擦={randomized_env.params['friction']:.2f}, "
f"噪声={randomized_env.params['noise']:.3f}, "
f"延迟={randomized_env.params['delay']}步")
print(f"\n效果:策略在仿真中见过各种乱七八糟的物理参数,")
print("到了真实世界反而发现「不过如此」——因为真实世界")
print("只是参数空间中又一个没见过的点,而策略已经学会了泛化。")
print("这就是Sim-to-Real的核心思想!")概念关系图谱
| 概念 | 与机器人控制的关系 | 说明 |
|---|---|---|
| 连续动作空间 | 核心特征 | 机器人控制几乎全是连续控制信号(力矩、角度) |
| SAC | 主流算法 | Soft Actor-Critic,平衡探索与利用的连续控制算法 |
| Sim-to-Real | 核心挑战 | 仿真训练的策略需迁移到真实机器人 |
| 域随机化 | 关键技巧 | 训练时随机化物理参数使策略鲁棒 |
| 逆强化学习 | 辅助方法 | 从人类示教中推断奖励函数 |
| 安全性约束 | 必要条件 | 真实机器人需保证探索过程不造成伤害 |
| 模仿学习 | 初始化方法 | 用人类演示数据预训练策略,加速后续RL |
| 系统辨识 | 传统方法 | 通过数据拟合物理参数的传统控制路线 |
重点答疑
大白话 让机器人在仿真里学走路就像在玩一个超逼真的「GTA」——在里面练了10000小时后上真车,方向盘和离合的手感确实不一样,但驾驶的核心能力已经建立了,稍微适应几分钟就能上路。
💡 核心要点:机器人控制RL的三座大山——连续动作空间(算法能处理实数输出)、Sim-to-Real迁移(仿真学到的要能在真机上用)、安全性(不能把机器人摔坏)。SAC+域随机化是目前攀爬这三座山最有效的组合。
- undefined
章节单词汇总
| 英文 | 音标 | 术语 | 释义 |
|---|---|---|---|
| Continuous Action Space | /kənˈtɪnjuəs ˈækʃən speɪs/ | 连续动作空间 | 动作为实数的控制问题,如力矩、位置 |
| Sim-to-Real | /sɪm tuː riːl/ | 仿真到真实迁移 | 将在仿真器中学到的策略部署到真实机器人上 |
| Domain Randomization | /dəˈmeɪn ˌrændəmaɪˈzeɪʃən/ | 域随机化 | 训练时随机化物理参数以增强策略鲁棒性 |
| Inverse Reinforcement Learning | /ɪnˈvɜːs ˌriːɪnˈfɔːsmənt ˈlɜːnɪŋ/ | 逆强化学习 | 从专家演示数据中推断奖励函数 |
| Forward Kinematics | /ˈfɔːwəd kɪnəˈmætɪks/ | 正向运动学 | 从关节角度计算末端执行器位置 |
| Joint Torque | /dʒɔɪnt tɔːk/ | 关节力矩 | 施加在机器人关节上的旋转力 |
| Entropy Regularization | /ˈentrəpi ˌreɡjʊləraɪˈzeɪʃən/ | 熵正则化 | 最大化策略熵以鼓励充分探索 |
| Actuator | /ˈæktʃueɪtə/ | 执行器 | 将控制信号转化为物理运动的装置(如电机) |
| Degrees of Freedom | /dɪˈɡriːz əv ˈfriːdəm/ | 自由度 | 机器人能独立运动的关节数量 |
| End Effector | /end ɪˈfektə/ | 末端执行器 | 机器人链的末端工具(如机械手爪) |
面试练习
- undefined
- undefined