从LLM到机器人控制:构建AI智能体仿真原型的技术实践 在人工智能和机器人技术快速发展的今天顶尖人才的流动往往预示着行业格局的微妙变化和技术重心的转移。近期前 OpenAI 机器人部门主管 Caitlin Kalinowski 加入 Anthropic 的消息引起了技术社区的广泛关注。这不仅是一位资深技术管理者的职业变动更折射出大型语言模型公司与具身智能、机器人领域交叉融合的深层趋势。对于关注 AI 应用、机器人开发以及科技公司战略的工程师和研究者而言理解这种人才流动背后的技术逻辑和潜在影响有助于把握未来的技术发展方向和职业机会。Caitlin Kalinowski 的履历颇具分量她不仅曾领导 OpenAI 的机器人团队更早之前还在苹果公司主导了 Mac Pro 等关键硬件项目。这种横跨消费电子顶尖硬件与前沿 AI 机器人软件的双重背景在业内并不多见。她的加入无疑将为 Anthropic 这家以开发 Claude 系列大模型闻名的公司注入强大的工程化、产品化和硬件整合能力。这或许意味着 Anthropic 不再满足于纯软件层面的对话模型开始向更复杂的、需要软硬件深度协同的 AI 应用场景探索例如具身智能、AI 驱动的物理设备或下一代人机交互界面。本文将从技术实践者的视角解析这一事件背后的技术脉络。我们将探讨 OpenAI 机器人部门的遗产、Anthropic 可能的技术方向并重点分析在当下开发者如何构建一个连接大型语言模型与物理世界的简易“机器人”仿真原型。通过一个结合 Python、基础机器人学仿真和 OpenAI/Anthropic API 的示例项目你将理解如何让 AI 模型“思考”并“指挥”一个虚拟实体在环境中完成简单任务。这不仅是学习 AI 与机器人集成的好方法也能帮助你洞察未来人形机器人或智能体Agent开发所需的核心技能栈。1. 理解核心概念从大语言模型到具身智能在深入技术实现之前必须厘清几个关键概念及其相互关系。这决定了我们后续技术方案的设计边界和目标。1.1 大型语言模型LLM的能力与局限以 OpenAI 的 GPT 系列和 Anthropic 的 Claude 为代表的 LLM本质上是基于海量文本数据训练出的概率模型。它们擅长理解和生成自然语言进行对话、总结、翻译、创作。代码生成与解释根据注释或描述编写代码片段。逻辑推理在给定上下文中进行多步推理。知识问答基于训练数据中的知识回答问题。然而LLM 存在明显的“具身”局限缺乏物理常识对重力、摩擦力、物体三维结构等物理世界的直观理解薄弱。无实时感知无法直接接收摄像头、激光雷达、力传感器的实时数据流。无动作输出其输出是文本或代码而非可以直接驱动电机或执行器的控制指令。无长期记忆与状态跟踪在复杂、动态的环境中难以维持对世界状态的连贯认知。1.2 机器人技术与机器人操作系统ROS传统机器人技术关注如何在物理世界中感知、规划和控制。感知通过传感器如摄像头、激光雷达、IMU获取环境数据。规划基于感知数据和任务目标生成一系列动作序列如路径规划、运动规划。控制将规划出的动作序列转化为电机、舵机等执行器的具体控制信号。ROS机器人操作系统提供了一套通信中间件和工具集帮助模块化地开发机器人软件管理传感器数据流、计算任务调度和硬件驱动。传统机器人系统的“智能”往往依赖于预先编程的规则或基于特定环境的优化算法缺乏高层任务理解和灵活的自然语言交互能力。1.3 具身智能与 AI 智能体AI Agent“具身智能”强调智能必须通过与物理环境的交互来体现和学习。AI 智能体是实现这一理念的软件实体它通常包含感知模块处理传感器输入。决策大脑通常是 LLM负责理解任务、分析状态、制定高层策略。规划与执行模块将高层策略分解为可执行的动作序列并调用底层控制器。记忆与学习模块存储交互历史可能通过强化学习等方式进行优化。Caitlin Kalinowski 在 OpenAI 领导的机器人部门以及她加入 Anthropic 的动向核心正是探索如何将 LLM 的“大脑”与机器人技术的“身体”和“小脑”结合起来构建真正意义上的具身 AI 智能体。这需要解决跨模态理解将视觉/物理信息转化为语言描述、安全可靠的动作生成、以及高效的仿真到现实迁移等一系列工程与科研难题。2. 环境准备构建 AI 机器人仿真原型的技术栈为了模拟 LLM 与机器人的交互我们将搭建一个轻量级的仿真环境。这个环境不涉及真实的 ROS 或复杂的物理引擎而是用 Python 创建一个简化的网格世界和虚拟机器人让 LLM 通过 API 来指挥它。2.1 核心工具与库选择我们将使用以下工具它们平衡了学习成本、功能性和代表性Python 3.8: 主开发语言。OpenAI API 或 Anthropic API: 作为 LLM “大脑”。本文示例将使用 OpenAI GPT-4 的gpt-4o-mini模型因其易于获取和调用。使用 Anthropic Claude 3.5 Sonnet 的流程几乎完全一致只需替换 SDK。openaiPython SDK: 官方库用于调用 OpenAI API。pygame: 一个用于创建游戏和多媒体应用的 Python 库我们将用它来可视化简单的 2D 网格世界和机器人。虚拟环境管理工具venv或conda用于隔离项目依赖。2.2 项目初始化与依赖安装首先创建一个项目目录并初始化虚拟环境。# 创建项目目录 mkdir ai_robot_simulator cd ai_robot_simulator # 创建并激活虚拟环境 (使用 venv) python3 -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 创建 requirements.txt 文件并写入依赖 cat requirements.txt EOF openai1.0.0 pygame2.5.0 numpy1.24.0 EOF # 安装依赖 pip install -r requirements.txt2.3 获取并配置 API 密钥你需要一个有效的 OpenAI API 密钥。请勿在代码中硬编码密钥应使用环境变量。# 在 Linux/macOS 的终端中设置环境变量 (临时) export OPENAI_API_KEYyour-api-key-here # 在 Windows PowerShell 中设置环境变量 (临时) $env:OPENAI_API_KEYyour-api-key-here为了代码的可维护性我们创建一个配置文件或直接在代码中安全地读取环境变量。# config.py import os from openai import OpenAI # 从环境变量读取 API 密钥 api_key os.getenv(OPENAI_API_KEY) if not api_key: raise ValueError(请设置 OPENAI_API_KEY 环境变量) # 初始化 OpenAI 客户端 client OpenAI(api_keyapi_key) # 定义使用的模型 LLM_MODEL gpt-4o-mini # 也可替换为 gpt-4o 或 Anthropic 的模型标识3. 构建最小可行原型网格世界与语言控制机器人我们的目标是创建一个 10x10 的网格世界其中有一个虚拟机器人用一个方块表示和一个目标点用另一个方块表示。用户用自然语言下达指令如“向右移动两步然后向上移动一步”LLM 负责将指令解析成一系列基础动作上、下、左、右然后程序执行这些动作并更新可视化界面。3.1 定义世界状态与机器人首先我们定义核心的数据结构。# world.py from dataclasses import dataclass from enum import Enum class Action(Enum): 机器人可执行的基础动作 MOVE_UP UP MOVE_DOWN DOWN MOVE_LEFT LEFT MOVE_RIGHT RIGHT dataclass class RobotState: 机器人状态 x: int # 网格 X 坐标 (0-9) y: int # 网格 Y 坐标 (0-9) dataclass class WorldState: 世界状态 robot: RobotState target_x: int # 目标点 X 坐标 target_y: int # 目标点 Y 坐标 grid_size: int 10 # 网格大小 def is_robot_at_target(self): 检查机器人是否到达目标点 return self.robot.x self.target_x and self.robot.y self.target_y def is_position_valid(self, x, y): 检查坐标是否在世界边界内 return 0 x self.grid_size and 0 y self.grid_size3.2 实现 LLM 指令解析器这是连接自然语言与机器人动作的核心模块。我们将设计一个提示词Prompt让 LLM 严格按照指定格式输出动作序列。# llm_planner.py from config import client, LLM_MODEL from world import Action, WorldState import json class LLMPlanner: def __init__(self): self.system_prompt 你是一个机器人控制指令解析器。用户会描述想让机器人在一个10x10网格世界中如何移动。你的任务是将自然语言指令解析成一系列基础动作。 可用的基础动作只有UP, DOWN, LEFT, RIGHT分别代表向上、下、左、右移动一格。 当前机器人的位置是 ({robot_x}, {robot_y})目标位置是 ({target_x}, {target_y})。网格坐标从(0,0)到(9,9)。 你必须以严格的 JSON 数组格式输出动作序列例如[RIGHT, RIGHT, UP]。 如果指令无法解析或可能让机器人走出网格请输出一个空数组 []。 只输出 JSON不要有任何其他解释。 def plan_actions(self, user_instruction: str, world_state: WorldState) - list[Action]: 根据用户指令和当前世界状态调用 LLM 生成动作计划 # 构建动态的系统提示词 dynamic_system_prompt self.system_prompt.format( robot_xworld_state.robot.x, robot_yworld_state.robot.y, target_xworld_state.target_x, target_yworld_state.target_y ) # 构建用户消息 user_message f用户指令{user_instruction} try: response client.chat.completions.create( modelLLM_MODEL, messages[ {role: system, content: dynamic_system_prompt}, {role: user, content: user_message} ], temperature0.1, # 低随机性确保输出稳定 max_tokens150 ) llm_output response.choices[0].message.content.strip() # 解析 LLM 输出的 JSON action_strings json.loads(llm_output) # 将字符串转换为 Action 枚举 actions [Action(action_str) for action_str in action_strings] return actions except (json.JSONDecodeError, KeyError, ValueError) as e: print(fLLM 输出解析失败: {e}输出内容: {llm_output}) return [] # 解析失败返回空动作列表 except Exception as e: print(f调用 API 失败: {e}) return []3.3 实现世界模拟与可视化使用 Pygame 创建一个简单的窗口来显示网格、机器人和目标。# simulator.py import pygame import sys from world import WorldState, RobotState, Action from llm_planner import LLMPlanner # 颜色定义 WHITE (255, 255, 255) BLACK (0, 0, 0) RED (255, 50, 50) GREEN (50, 255, 50) BLUE (50, 100, 255) GRAY (200, 200, 200) class RobotSimulator: def __init__(self, world_state: WorldState): pygame.init() self.world world_state self.cell_size 60 # 每个网格单元的像素大小 self.width self.world.grid_size * self.cell_size self.height self.world.grid_size * self.cell_size 100 # 底部留出空间显示信息 self.screen pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption(AI 机器人网格仿真器) self.clock pygame.time.Clock() self.font pygame.font.SysFont(None, 28) self.planner LLMPlanner() self.instruction self.actions_queue [] # 待执行的动作队列 self.is_executing False def draw_grid(self): 绘制网格线 for x in range(0, self.width, self.cell_size): pygame.draw.line(self.screen, GRAY, (x, 0), (x, self.world.grid_size * self.cell_size), 1) for y in range(0, self.world.grid_size * self.cell_size, self.cell_size): pygame.draw.line(self.screen, GRAY, (0, y), (self.width, y), 1) def draw_robot_and_target(self): 绘制机器人和目标 # 绘制目标绿色方块 target_rect pygame.Rect( self.world.target_x * self.cell_size, self.world.target_y * self.cell_size, self.cell_size, self.cell_size ) pygame.draw.rect(self.screen, GREEN, target_rect) # 绘制机器人蓝色方块 robot_rect pygame.Rect( self.world.robot.x * self.cell_size, self.world.robot.y * self.cell_size, self.cell_size, self.cell_size ) pygame.draw.rect(self.screen, BLUE, robot_rect) # 在机器人上画个“R” robot_text self.font.render(R, True, WHITE) text_rect robot_text.get_rect(centerrobot_rect.center) self.screen.blit(robot_text, text_rect) def draw_info_panel(self): 绘制底部信息面板 panel_y self.world.grid_size * self.cell_size pygame.draw.rect(self.screen, (240, 240, 240), (0, panel_y, self.width, 100)) # 显示状态信息 state_text f机器人位置: ({self.world.robot.x}, {self.world.robot.y}) | 目标位置: ({self.world.target_x}, {self.world.target_y}) state_surface self.font.render(state_text, True, BLACK) self.screen.blit(state_surface, (10, panel_y 10)) # 显示当前指令 inst_text f指令: {self.instruction} inst_surface self.font.render(inst_text, True, BLACK) self.screen.blit(inst_surface, (10, panel_y 40)) # 显示动作队列 queue_text f待执行动作: {[a.value for a in self.actions_queue]} queue_surface self.font.render(queue_text, True, BLACK) self.screen.blit(queue_surface, (10, panel_y 70)) def execute_single_action(self, action: Action): 执行单个动作更新机器人状态 new_x, new_y self.world.robot.x, self.world.robot.y if action Action.MOVE_UP: new_y - 1 elif action Action.MOVE_DOWN: new_y 1 elif action Action.MOVE_LEFT: new_x - 1 elif action Action.MOVE_RIGHT: new_x 1 # 边界检查 if self.world.is_position_valid(new_x, new_y): self.world.robot.x new_x self.world.robot.y new_y return True else: print(f动作 {action.value} 会导致机器人走出边界已忽略。) return False def handle_events(self): 处理 Pygame 事件 for event in pygame.event.get(): if event.type pygame.QUIT: pygame.quit() sys.exit() elif event.type pygame.KEYDOWN: if event.key pygame.K_RETURN: # 按下回车提交指令给 LLM 规划 if self.instruction and not self.is_executing: print(f正在规划指令: {self.instruction}) self.actions_queue self.planner.plan_actions(self.instruction, self.world) print(f规划结果: {[a.value for a in self.actions_queue]}) self.is_executing True elif event.key pygame.K_BACKSPACE: # 退格删除 self.instruction self.instruction[:-1] elif event.key pygame.K_ESCAPE: # ESC 清空指令和队列 self.instruction self.actions_queue [] self.is_executing False else: # 输入指令 self.instruction event.unicode def run(self): 主循环 while True: self.handle_events() # 如果正在执行且队列不为空则按帧执行动作模拟延时 if self.is_executing and self.actions_queue: # 每 30 帧执行一个动作便于观察 if pygame.time.get_ticks() % 30 0: action self.actions_queue.pop(0) self.execute_single_action(action) if not self.actions_queue: self.is_executing False if self.world.is_robot_at_target(): print(成功到达目标) else: print(动作执行完毕。) # 绘制 self.screen.fill(WHITE) self.draw_grid() self.draw_robot_and_target() self.draw_info_panel() pygame.display.flip() self.clock.tick(60) # 60 FPS if __name__ __main__: # 初始化世界状态机器人在 (0,0)目标在 (7,7) initial_world WorldState( robotRobotState(x0, y0), target_x7, target_y7 ) simulator RobotSimulator(initial_world) simulator.run()4. 运行验证与结果分析4.1 启动仿真器确保你的OPENAI_API_KEY环境变量已设置然后在项目根目录下运行python simulator.py一个 Pygame 窗口将弹出显示一个 10x10 的网格。蓝色方块“R”代表机器人位于 (0,0)绿色方块代表目标位于 (7,7)。窗口底部有一个信息面板。4.2 输入指令进行测试点击 Pygame 窗口确保其获得焦点。用键盘输入自然语言指令例如move to the target移动到目标或更具体的go right five steps then go up two steps向右走五步然后向上走两步。按下回车键。程序会将你的指令和当前世界状态发送给 LLMGPT-4o-mini。观察控制台输出你会看到类似这样的信息正在规划指令: move to the target 规划结果: [RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, RIGHT, UP, UP, UP, UP, UP, UP, UP]在仿真器窗口中你会看到机器人开始按照规划的动作序列一步步移动每步之间有短暂延迟。动作队列会在底部信息面板显示。当机器人到达目标点绿色方块时控制台会打印“成功到达目标”。4.3 关键过程解析这个简单的原型演示了 AI 机器人控制的一个核心闭环感知输入用户通过自然语言下达任务指令。在实际机器人中这可能是语音指令或更复杂的多模态输入如图像描述任务。LLM 理解与规划LLMPlanner将当前世界状态机器人位置、目标位置和用户指令组合成提示词发送给 LLM。LLM 扮演“任务规划器”的角色将高层指令分解为原子动作序列。我们通过严格的 JSON 输出格式和系统提示词来约束 LLM 的行为。动作执行仿真器从 LLM 得到动作序列后将其放入队列并调用execute_single_action方法根据动作类型更新机器人的网格坐标同时进行边界检查。状态更新与可视化Pygame 主循环不断重绘界面反映机器人位置的变化形成实时反馈。任务完成判断每次状态更新后检查is_robot_at_target判断任务是否完成。这个流程抽象了真实机器人系统中“感知-思考-行动”循环的核心部分。LLM 提供了灵活的任务理解和分解能力而底层的仿真器或真实的机器人控制器负责确保动作在物理约束下的安全执行。5. 常见问题排查与优化在实际运行上述原型或将其扩展到更复杂场景时你可能会遇到以下问题。5.1 LLM 相关问题问题现象可能原因检查与解决方式调用 API 超时或失败1. 网络连接问题。2. API 密钥无效或余额不足。3. 服务器端繁忙。1. 检查网络尝试ping api.openai.com。2. 在 OpenAI 仪表板检查密钥状态和用量。3. 添加重试逻辑使用指数退避策略。LLM 返回的 JSON 格式错误1. 提示词约束不够强。2. 模型“幻觉”或温度参数过高。1. 强化系统提示词明确要求“只输出 JSON 数组”。2. 降低temperature参数如设为 0.1。3. 在代码中使用try...except捕获 JSON 解析异常并设置降级策略如返回空动作。动作规划不合理如绕远路、撞墙1. LLM 缺乏对网格世界的精确空间推理能力。2. 提示词未提供足够的环境约束信息。1. 在提示词中明确强调边界0-9和障碍物如果有。2. 可以引入更简单的规则引擎进行后处理过滤掉无效动作。3. 考虑使用思维链Chain-of-Thought提示让 LLM 先输出推理步骤。代码优化示例为 API 调用增加重试机制# llm_planner.py (优化版片段) import time from openai import APIConnectionError, APIStatusError class LLMPlanner: # ... 其他代码不变 ... def plan_actions_with_retry(self, user_instruction: str, world_state: WorldState, max_retries3) - list[Action]: 带重试的动作规划 for attempt in range(max_retries): try: return self.plan_actions(user_instruction, world_state) except (APIConnectionError, APIStatusError) as e: if attempt max_retries - 1: print(fAPI 调用失败已达最大重试次数: {e}) return [] wait_time 2 ** attempt # 指数退避 print(fAPI 调用失败第 {attempt1} 次重试等待 {wait_time} 秒...) time.sleep(wait_time) return []5.2 仿真与可视化问题问题现象可能原因检查与解决方式Pygame 窗口无法打开或闪退1. Pygame 未正确安装。2. 系统缺少显示驱动或运行在无图形界面的环境。1. 确认pip install pygame成功且版本兼容。2. 在服务器或无头环境运行可以设置虚拟显示如xvfb或直接关闭可视化只做逻辑模拟。机器人移动卡顿或不流畅1. 主循环帧率过低。2. API 调用是同步的会阻塞主线程。1. 确保clock.tick(60)在循环内。2.重要将耗时的 API 调用放入独立线程或使用异步编程asyncio避免阻塞事件循环。输入指令无响应1. Pygame 窗口未获得焦点。2. 事件处理逻辑有误。1. 点击窗口确保其激活。2. 检查handle_events函数中的按键事件处理逻辑特别是event.unicode对非字符键的处理。5.3 架构与扩展性问题问题说明与建议提示词工程脆弱当前系统提示词相对简单。复杂指令下LLM 可能输出无法解析的内容。需要持续迭代提示词加入更多示例Few-shot Learning或使用更结构化的输出格式如 JSON Schema。缺乏状态反馈LLM 在规划时只知道初始状态。如果动作执行失败如撞墙LLM 无法知晓并重新规划。理想情况下每次执行后应将新的世界状态反馈给 LLM形成闭环。动作粒度太粗目前只有四个方向移动。真实机器人需要更精细的动作如“抓取”、“旋转30度”。需要设计更丰富的动作原语并让 LLM 理解其语义。无多模态感知真实机器人依赖视觉、力觉等。需要扩展系统让 LLM 能处理图像描述或传感器数据摘要。这通常需要视觉语言模型VLM或额外的感知模块。6. 从原型到实践工程化与生产环境考量上述原型仅用于演示概念。要将 LLM 用于真实的机器人控制必须跨越原型与生产之间的巨大鸿沟。Caitlin Kalinowski 这类资深工程师的价值正是解决这些工程难题。6.1 安全性与可靠性设计在物理世界中错误的动作可能导致设备损坏或人员受伤。必须建立多层安全防护动作验证与过滤LLM 生成的动作计划必须经过一个严格的“验证器”模块。这个模块基于物理规则、环境模型和安全策略过滤掉任何不安全或不可行的动作。例如检查运动轨迹是否碰撞、关节角度是否超限、末端执行器速度是否过快。人工监督与紧急停止系统必须设计“人在环路”机制。对于关键任务或不确定的动作需要人工确认。同时必须有物理急停按钮和软件紧急停止信号。冗余与降级当 LLM 服务不可用或输出质量低下时系统应能降级到基于规则的保守策略或完全停止而不是盲目执行。6.2 系统架构演进生产系统不会在一个 Python 脚本里完成所有事情。典型的架构可能包括感知服务独立进程或容器专门处理传感器数据点云、图像生成环境的结构化描述如物体列表、位置、属性供 LLM 使用。任务规划服务封装 LLM 调用、提示词管理和动作序列生成。它接收高层任务和感知结果输出经过验证的动作序列。运动规划与控制服务接收原子动作指令如“移动到坐标(X,Y)”进行路径搜索、轨迹优化并生成底层电机控制指令。这部分通常由 ROS MoveIt、OMPlanner 等专业库完成。状态管理与通信使用 ROS 2支持实时性、分布式或类似的中间件来管理各服务间的消息传递、状态同步和生命周期。仿真与测试流水线在部署到真实机器人前必须在高保真仿真环境如 Isaac Sim、Gazebo中进行大量测试覆盖各种 corner case。6.3 提示词与模型管理版本控制提示词是核心资产应像代码一样进行版本控制Git。A/B 测试对不同版本的提示词或模型进行在线测试评估任务成功率和效率。模型微调对于特定领域如医疗手术、仓库分拣可能需要使用领域数据对基础 LLM 进行微调以提升其专业术语理解和任务分解的准确性。6.4 可观测性与调试机器人 AI 系统极其复杂必须拥有强大的可观测性工具详细日志记录 LLM 的输入提示词、输出响应、动作执行结果、系统状态变更。可视化工具实时显示机器人感知到的环境、LLM 的“思维链”、规划出的路径。数据记录与回放能够记录失败的交互序列用于离线分析和提示词改进。7. 总结与展望人才流动背后的技术趋势Caitlin Kalinowski 从 OpenAI 机器人部门转投 Anthropic这一事件本身是行业人才竞争的一个缩影但其背后反映的技术趋势更值得开发者关注LLM 作为机器人“大脑”已成为共识无论是 OpenAI 内部曾经的探索还是 Anthropic 未来的方向都表明将大语言模型与机器人控制相结合是通往通用具身智能的关键路径。我们的原型验证了其基本可行性。工程化能力至关重要拥有像 Kalinowski 这样兼具顶尖硬件苹果 Mac Pro和前沿 AI 软件经验的人才意味着 Anthropic 可能更注重将 AI 能力“产品化”和“实体化”。这不仅仅是算法问题更是系统工程、可靠性设计、安全标准和用户体验的问题。仿真到现实的鸿沟是下一个挑战在网格仿真中移动方块是简单的但在杂乱、动态的真实世界中控制人形机器人抓取易碎物品则极其困难。这需要更强大的多模态模型、更精确的物理仿真以及高效的 sim-to-real 迁移技术。对于开发者而言现在正是学习相关技能的时机。你可以从理解 LLM 的 API 调用和提示词工程开始进而学习机器人学基础运动学、动力学、机器人操作系统ROS 2并尝试在仿真环境中复现更复杂的任务。未来能够桥接 AI 算法与物理世界的工程师将在这个新兴领域拥有独特的优势。注意本文示例仅为教学目的展示了 LLM 与机器人控制集成的核心思想。任何计划在真实机器人上部署类似系统的尝试都必须经过严格的安全评估、大量的仿真测试并配备完善的安全冗余机制和人工监督流程。切勿将未经充分验证的 AI 决策系统直接用于控制具有物理动能的设备。