Skip to content

机器人学:AI 在物理世界的应用

机器人学(Robotics)是 AI 与物理世界交互的学科,涉及感知、决策、控制、学习。

机器人核心架构

1. 感知(Perception)

从传感器获取环境信息:

  • 视觉:摄像头、RGB-D(Kinect, RealSense)
  • 触觉:力/力矩传感器、触觉皮肤
  • IMU:加速度计、陀螺仪(位姿估计)
  • LiDAR:激光雷达(3D 环境建模)
  • 里程计:轮式编码器、视觉里程计(VO)

2. 状态估计(State Estimation)

从传感器数据估计机器人位姿和环境模型:

SLAM(Simultaneous Localization and Mapping)

传感器输入 → 特征提取 → 数据关联(匹配) → 优化(位姿+地图) → 输出:位姿 + 地图

常用方法

  • 激光 SLAM:Cartographer, Hector SLAM
  • 视觉 SLAM (VSLAM):ORB-SLAM3, OpenVSLAM
  • 图优化:g2o, GTSAM
python
# ORB-SLAM3 示例(C++,但可通过 ROS 调用)
# 1. 启动 SLAM 节点
rosrun orb_slam3_ros Mono /path/to/vocabulary/orb_vocab.txt /path/to/config.yaml

# 2. 发布位姿话题
rostopic echo /orb_slam3/camera_pose

滤波方法

  • 卡尔曼滤波(KF):线性高斯系统
  • 扩展卡尔曼滤波(EKF):非线性线性化
  • 粒子滤波(PF):多假设,非高斯
python
import pykalman

kf = pykalman.KalmanFilter(
    transition_matrices=[[1, 1], [0, 1]],  # 状态转移
    observation_matrices=[[1, 0]],          # 观测矩阵
    initial_state_mean=[0, 0],
    initial_state_covariance=[[1, 0], [0, 1]]
)
state_means, state_covariances = kf.filter(observations)

3. 规划(Planning)

给定目标,规划安全高效的路径或轨迹。

路径规划(Path Planning)

搜索算法

  • A*(A-Star):启发式搜索,最优
  • Dijkstra:无启发,保证最优
  • RRT(Rapidly-exploring Random Tree):随机采样,适合高维空间
python
import numpy as np

def a_star(start, goal, grid):
    """grid: 0=free, 1=obstacle"""
    from heapq import heappop, heappush
    open_set = [(0, start)]
    came_from = {}
    g_score = {start: 0}
    f_score = {start: heuristic(start, goal)}
    
    while open_set:
        current = heappop(open_set)[1]
        if current == goal:
            return reconstruct_path(came_from, current)
        
        for neighbor in get_neighbors(current, grid):
            tentative_g = g_score[current] + cost(current, neighbor)
            if neighbor not in g_score or tentative_g < g_score[neighbor]:
                came_from[neighbor] = current
                g_score[neighbor] = tentative_g
                f_score[neighbor] = tentative_g + heuristic(neighbor, goal)
                heappush(open_set, (f_score[neighbor], neighbor))
    return None

采样算法

  • RRT:渐近最优*,后续连接优化
  • PRM(Probabilistic Roadmap):先构建路网,再查询

运动规划(Motion Planning)

考虑动力学约束,生成时间轨迹:

  • 时间弹性带(TEB):优化带时间参数的轨迹
  • CHOMP:梯度下降优化
  • TrajOpt:序列凸规划

4. 控制(Control)

执行规划好的轨迹,实时调整控制量。

经典控制

  • PID:位置/速度环
  • LQR:线性二次型调节器
  • MPC(模型预测控制):滚动优化
python
import control

# LQR 设计
A = np.array([[1, 1], [0, 1]])  # 状态矩阵
B = np.array([[0], [1]])        # 输入矩阵
Q = np.eye(2) * 10              # 状态权重
R = np.eye(1) * 1               # 控制权重

K, S, E = control.lqr(A, B, Q, R)  # 求解 LQR 增益
# u = -K @ x

5. 学习(Learning)

用数据驱动替代或增强传统模块:

  • 强化学习(RL):端到端策略学习
  • 模仿学习(IL):从专家演示学习
  • 元学习:快速适应新任务

强化学习在机器人中的应用

为什么用 RL?

传统控制需要精确模型,但机器人动力学复杂(摩擦、柔性)。RL 直接从交互中学习策略。

常见算法

1. 深度 Q 网络(DQN)

离散动作空间:

python
import torch
import torch.nn as nn
import torch.optim as optim
from collections import deque
import random

class QNetwork(nn.Module):
    def __init__(self, state_dim, action_dim):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(state_dim, 128),
            nn.ReLU(),
            nn.Linear(128, 128),
            nn.ReLU(),
            nn.Linear(action_dim, 1)
        )
    
    def forward(self, state):
        return self.net(state)

class ReplayBuffer:
    def __init__(self, capacity):
        self.buffer = deque(maxlen=capacity)
    def push(self, transition):
        self.buffer.append(transition)
    def sample(self, batch_size):
        return random.sample(self.buffer, batch_size)

class DQNAgent:
    def __init__(self, state_dim, action_dim):
        self.q_net = QNetwork(state_dim, action_dim)
        self.target_net = QNetwork(state_dim, action_dim)
        self.target_net.load_state_dict(self.q_net.state_dict())
        self.buffer = ReplayBuffer(10000)
        self.optimizer = optim.Adam(self.q_net.parameters(), lr=1e-3)
    
    def select_action(self, state, epsilon=0.1):
        if random.random() < epsilon:
            return random.randint(0, action_dim-1)
        with torch.no_grad():
            q_values = self.q_net(torch.FloatTensor(state))
            return q_values.argmax().item()
    
    def update(self, batch_size=64):
        batch = self.buffer.sample(batch_size)
        states, actions, rewards, next_states, dones = zip(*batch)
        states = torch.FloatTensor(states)
        actions = torch.LongTensor(actions).unsqueeze(1)
        rewards = torch.FloatTensor(rewards)
        next_states = torch.FloatTensor(next_states)
        dones = torch.FloatTensor(dones)
        
        current_q = self.q_net(states).gather(1, actions).squeeze()
        next_q = self.target_net(next_states).max(1)[0]
        target = rewards + 0.99 * next_q * (1 - dones)
        
        loss = nn.MSELoss()(current_q, target)
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()

2. PPO(Proximal Policy Optimization)

连续动作空间(关节力矩):

python
import torch
import torch.nn as nn
import torch.optim as optim

class Actor(nn.Module):
    def __init__(self, state_dim, action_dim):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(state_dim, 256),
            nn.ReLU(),
            nn.Linear(256, 256),
            nn.ReLU(),
        )
        self.mu = nn.Linear(256, action_dim)  # 均值
        self.log_std = nn.Parameter(torch.zeros(action_dim))  # 对数标准差
    
    def forward(self, state):
        x = self.net(state)
        return self.mu(x), self.log_std.exp()

class Critic(nn.Module):
    def __init__(self, state_dim):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(state_dim, 256),
            nn.ReLU(),
            nn.Linear(256, 256),
            nn.ReLU(),
            nn.Linear(256, 1)
        )
    def forward(self, state):
        return self.net(state)

class PPO:
    def __init__(self, state_dim, action_dim):
        self.actor = Actor(state_dim, action_dim)
        self.critic = Critic(state_dim)
        self.optimizer = optim.Adam(list(self.actor.parameters()) + list(self.critic.parameters()), lr=3e-4)
    
    def update(self, states, actions, old_log_probs, rewards, dones, clip_eps=0.2, epochs=10):
        # 计算 advantages
        values = self.critic(states).squeeze()
        returns = compute_returns(rewards, dones)  # Generalized Advantage Estimation
        advantages = returns - values.detach()
        advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-8)
        
        for _ in range(epochs):
            new_log_probs, entropy = self.actor.evaluate(states, actions)
            ratio = (new_log_probs - old_log_probs).exp()
            surr1 = ratio * advantages
            surr2 = torch.clamp(ratio, 1-clip_eps, 1+clip_eps) * advantages
            actor_loss = -torch.min(surr1, surr2).mean() - 0.01 * entropy.mean()
            critic_loss = nn.MSELoss()(values, returns)
            loss = actor_loss + 0.5 * critic_loss
            
            self.optimizer.zero_grad()
            loss.backward()
            self.optimizer.step()

机器人学习框架

1. ROS / ROS 2(Robot Operating System)

事实标准机器人中间件:

ros2 topic list          # 查看话题
ros2 topic echo /camera/image_raw  # 查看图像
ros2 service list        # 查看服务
ros2 node list           # 查看节点

包管理rosdep install --from-paths src --rosdistro humble -r

2. Gym / Gymnasium

强化学习环境标准接口:

python
import gymnasium as gym
env = gym.make('FetchPickAndPlace-v2')
obs, info = env.reset()
for _ in range(1000):
    action = env.action_space.sample()  # 随机策略
    obs, reward, terminated, truncated, info = env.step(action)

机器人环境

  • PyBullet:物理仿真,内置 Kuka、Fetch 等机器人
  • MuJoCo(DeepMind):高质量物理,现在开源免费
  • Isaac Gym(NVIDIA):GPU 加速,大规模并行
python
import gymnasium as gym
import robodesk  # 或以下之一

env = gym.make('AdroitHandDoor-v1')  # 灵巧手开门
env = gym.make('ShadowHandGrasp-v0') # Shadow-hand 抓取
env = gym.make('XArm7Reach-v0')      # XArm7 机械臂

3. PyRobot

Facebook 的机器人 API 封装:

python
from pyrobot.robots import Fetch
robot = Fetch()
robot.base.go_to(1, 0, 0)  # 移动到 (1, 0, 0)
robot.arm.traj_play('/path/to/trajectory.txt')

实战:机械臂抓取

任务

随机位置抓取物体(如块、球)。

解决方案

感知

  • RGB-D 相机(RealSense)
  • 目标检测(YOLO)→ 位姿估计(ICP)

规划

  • 抓取点采样(基于深度图)
  • 逆运动学(IK)求解关节角度

控制

  • 关节空间 PID
  • 末端轨迹跟踪

代码结构(ROS 2 + Python)

python
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from geometry_msgs.msg import PoseStamped
from control_msgs.action import FollowJointTrajectory
import cv2
import numpy as np

class PickPlaceNode(Node):
    def __init__(self):
        super().__init__('pick_place')
        self.image_sub = self.create_subscription(Image, '/camera/color/image_raw', self.image_callback, 10)
        self.pose_pub = self.create_publisher(PoseStamped, '/target_pose', 10)
        self.trajectory_client = ActionClient(self, FollowJointTrajectory, '/arm_controller/follow_joint_trajectory')
    
    def image_callback(self, msg):
        # 1. RGB-D → 目标检测(YOLO)
        img = self.bridge.imgmsg_to_cv2(msg, "bgr8")
        detections = yolo_model(img)
        
        # 2. 深度图 + 位姿估计
        depth = self.get_depth()
        target_pose = self.estimate_pose(detections[0], depth)
        
        # 3. 发送目标位姿
        pose_msg = PoseStamped()
        pose_msg.pose = target_pose
        self.pose_pub.publish(pose_msg)
        
        # 4. 发送抓取轨迹(预定义或 IK 求解)
        self.send_grasp_trajectory(target_pose)

def main():
    rclpy.init()
    node = PickPlaceNode()
    rclpy.spin(node)

仿真到现实(Sim2Real)

仿真环境与真实世界有差异(dynamics gap),策略直接部署会失败。

域随机化(Domain Randomization)

在仿真中随机化参数,提升鲁棒性:

python
# PyBullet 中的随机化
import pybullet as p

p.setAdditionalSearchPath(pybullet_data.getDataPath())
p.loadURDF("plane.urdf", [0, 0, -0.1])  # 地面

# 随机化摩擦、质量、光照等
for body_id in object_ids:
    p.changeDynamics(body_id, -1, lateralFriction=np.random.uniform(0.3, 0.8))
    p.changeVisualShape(body_id, -1, rgbaColor=np.random.rand(3).tolist() + [1])

渐进式域适应(Progressive Nets)

仿真 → 仿真(随机化增强) → 真实

在线微调

在真实世界少量交互,微调策略:

python
# 使用离线 RL 预训练 + 在线微调
pretrained_policy = offline_rl_train(sim_data)
real_policy = online_fine_tune(pretrained_policy, real_robot, epochs=100)

具身智能与基础模型

新兴方向:将大语言模型(LLM)作为机器人的"大脑"。

示例:Google RT-2 (Robotic Transformer 2)

  • 用互联网图像-文本数据预训练
  • 指令跟随: "把红色方块放到蓝色盒子里"
  • 零样本 generalization:无需机器人数据训练
python
# 伪代码
llm = GPT4V()  # 多模态大模型

def robot_policy(observation, instruction):
    # observation: RGB-D + 关节状态
    prompt = f"""
    你是一个机器人控制器。给定图片和指令,输出动作。

    指令:{instruction}
    当前状态:{observation}

    可能的动作:
    1. 移动到 (x, y, z)
    2. 抓取
    3. 释放
    4. 旋转 45°

    输出格式:JSON {{"action": "...", "params": ...}}
    """
    response = llm.generate(prompt)
    action = parse_json(response)
    return execute_action(action)

优点:通用性强,无需大量机器人数据。 缺点:延迟高(LLM 推理)、安全性未知、难以低层控制。


开源项目与数据集

开源硬件

  • UR5e / UR3:Universal Robots,6 自由度协作臂
  • Franka Emika Panda:7 自由度,力控优秀
  • TurtleBot3:入门移动机器人
  • Unitree Go1:四足机器人,价格亲民

仿真环境

环境特点
PyBullet易用,免费,多种机器人
MuJoCo物理真实感强,现在免费
Isaac SimNVIDIA,GPU 加速,照片级渲染
** CoppeliaSim (V-REP)**老牌,支持多机器人

数据集

数据集内容用途
RLBench100+ 机器人任务(Sim)模仿学习 / RL
BEHAVIOR120 个日常任务具身 AI
Oxford RobotCar真实驾驶数据SLAM, 自动驾驶
KITTI自动驾驶视觉、激光雷达
Matterport3D3D 室内场景导航

工业应用案例

1. 仓储物流(Amazon Robotics)

  • Kiva 机器人:货架到人
  • 感知:2D 激光 + 里程计 + 二维码定位
  • 规划:多机器人路径规划(避免碰撞)
  • 控制:差速轮,导航到货架

2. 汽车制造(特斯拉)

  • 机器人焊接/涂胶:轨迹精确,力控
  • 感知:3D 视觉定位工件
  • 规划:离线编程(Offline Programming),示教再现

3. 手术机器人(达芬奇)

  • 主从控制:医生操作主手,机械臂从手复制
  • 力反馈:触觉反馈,医生感受组织阻力
  • 稳定性: tremor filtering(滤除手抖)

挑战与未来

挑战

  1. Sim2Real Gap:仿真到现实性能下降
  2. 安全性:碰撞检测、紧急停止、人机协作
  3. 长尾场景:罕见情况(如电缆缠绕、轮子打滑)
  4. 能耗:移动机器人续航有限

未来方向

  1. 多模态基础模型:视觉-语言-动作统一(RT-2, PALIM)
  2. 自监督学习:机器人自己探索,无需人工标注
  3. 人形机器人:Tesla Optimus, Boston Dynamics Atlas
  4. 群体智能:多机器人协作(蜂群、编队)

入门建议

  1. 仿真先行:PyBullet + Gymnasium,不用真机器人
  2. ROS 2:学习机器人中间件,工业界标准
  3. 算法:从经典控制(PID)→ 运动规划(RRT)→ 强化学习(PPO)
  4. 硬件:TurtleBot3 或 UR5e(如果有条件)
  5. 课程:Coursera "Robotics Specialization"(Penn),"CS237B"(Berkeley)

机器人学是软硬结合、理论与实践并重的学科,动手写代码 + 仿真实验是关键!