机器人仿真: 训练自己第一个平衡机器人Cartpole

机器人仿真: 训练自己第一个平衡机器人Cartpole
小编2026 Spring 开启一段关于Robotics的学习,本文记录了在 Windows 系统上训练自己第一个机器人的过程。

Cartpole 代码是如何工作的

用 Isaac Lab 做强化学习时,一个任务是怎么被「注册」的?配置里的奖励、终止、观测到底在哪生效?训练脚本又是怎么把环境和 PPO 串起来的?这篇博客顺着「从注册到训练」的一条线,把 Cartpole 项目里的代码是怎么 work 的讲清楚。


当我们输入指令:

python scripts/rsl_rl/train.py --task Template-Cartpole-v0 --num_envs 4096

该指令会执行训练 Cartpole 任务(Template-Cartpole-v0),同时调用 4096 个并行环境 做 PPO 训练
背后大致是这几步:

  1. 启动 Isaac Sim
  2. 解析命令行
  3. 根据任务名找到「环境配置」和「算法配置」(Cartpole 的 MDP 和 PPO 超参)
  4. 用这份配置创建 Gym 环境(多个 Cartpole 并行仿真)
  5. 用 RSL-RL 的 PPO Runner 收集数据、更新策略,循环直到达到迭代数

一、任务识别 Gym 注册

source/Cartpole/Cartpole/tasks/manager_based/cartpole/__init__.py

import gymnasium as gym from.import agents gym.register(id="Template-Cartpole-v0", entry_point="isaaclab.envs:ManagerBasedRLEnv", disable_env_checker=True, kwargs={"env_cfg_entry_point":f"{__name__}.cartpole_env_cfg:CartpoleEnvCfg","rsl_rl_cfg_entry_point":f"{agents.__name__}.rsl_rl_ppo_cfg:PPORunnerCfg",},)
  • id:就是环境的名字。Gym 通过id定位环境。
  • entry_point:一个字符串,像门牌号一样指向「用哪个模块里的哪个类」。
  • **kwargs **:
    • env_cfg_entry_point:告诉程序「环境长什么样、奖励怎么算、什么时候结束」的配置类 CartpoleEnvCfg 在哪个文件里,程序会按这个路径去 import。
    • rsl_rl_cfg_entry_point:告诉程序「PPO 用多大网络、学多少轮」的配置类 PPORunnerCfg 在哪个文件里,同样按路径 import。

gym.register 把名字、通用环境类、以及「环境配置」和「PPO 配置」两个类的路径绑在一起。


二、环境配置 CartpoleEnvCfg

gym.make("Template-Cartpole-v0", cfg=env_cfg) 时,Isaac Lab 会按 env_cfg_entry_point 拿到 CartpoleEnvCfg。这个类就是「Cartpole 长什么样、怎么交互、怎么给奖励、什么时候结束」的一张总表。

它大致长这样(逻辑结构):

CartpoleEnvCfg ├── scene: CartpoleSceneCfg # 场景里有什么 ├── observations: ObservationsCfg # 智能体看到什么 ├── actions: ActionsCfg # 智能体能做什么 ├── events: EventCfg # 重置时怎么随机化 ├── rewards: RewardsCfg # 每一步怎么给奖励 ├── terminations: TerminationsCfg # 什么时候算结束 └── __post_init__ 里:仿真步长、回合长度、视角等 
  • scene:地面、Cartpole 机器人(每个环境一个)、灯光。机器人用的是 Isaac Lab Assets 里现成的 CARTPOLE_CFG,只是把 prim_path 换成带环境命名空间的,这样 4096 个环境就有 4096 个互不干扰的 Cartpole。
  • actions:当前只有一项——对「小车关节」slider_to_cart 施加力矩,scale 100,即动作 [-1,1] 映射到 ±100 的力。
  • observations:两项——关节位置、关节速度(都来自 mdp 里的通用函数),拼成一个向量给策略网络。
  • events:重置时给小车的位姿/速度、杆的角/角速度一个随机范围,让每局起始状态有变化。
  • rewards:下面单独说。
  • terminations:一是超时(例如 5 秒),二是小车跑出 [-3, 3] 就提前结束。

所以:配置类本身不「算」任何东西,它只是声明「用哪个函数、绑哪几个关节、权重多少」。真正在仿真里被调用的,是这些函数——它们多数来自 Isaac Lab 的 MDP 库,Cartpole 只自定义了一个奖励。


三:动作配置与关节力矩

Cartpole 的「动」完全由动作空间决定:策略网络输出一个标量,被转换成对小车滑轨关节的力矩,物理引擎再根据力矩更新小车和杆的状态。

动作配置在 cartpole_env_cfg.py 里只有一段:

@configclassclassActionsCfg:"""Action specifications for the MDP.""" joint_effort = mdp.JointEffortActionCfg( asset_name="robot", joint_names=["slider_to_cart"], scale=100.0,)
  • asset_name=“robot”:作用对象是场景里的 robot(Cartpole 机器人)。
  • joint_names=[“slider_to_cart”]:只控制「小车相对世界」的那一个关节(滑轨),杆的转动由物理仿真自然产生,不直接给力矩。
  • scale=100.0:策略输出在 [-1, 1],会先乘 100 再当力矩(单位 N)送给关节,所以实际施加的是 ±100 的力。

数据流policy(obs) → 一个 float 在 [-1,1] → 乘 100 → 作为 slider_to_cart 的关节力矩 → 物理仿真一步 → 小车左右移动、杆摆动。所以「机器人怎么动」就是:策略决定向左/向右推小车的力有多大,物理引擎负责把力变成位置和速度。

四、如何计算奖励

RewardsCfg 里你会看到五类奖励项,例如:

alive = RewTerm(func=mdp.is_alive, weight=1.0) terminating = RewTerm(func=mdp.is_terminated, weight=-2.0) pole_pos = RewTerm(func=mdp.joint_pos_target_l2, weight=-1.0, params={...}) cart_vel = RewTerm(func=mdp.joint_vel_l1,...) pole_vel = RewTerm(func=mdp.joint_vel_l1,...)
  • alive:只要没因「失败条件」结束,就给 1.0,鼓励尽量别提前挂。
  • terminating:若是因失败结束(例如小车出界),给 -2.0。
  • pole_pos:希望杆保持竖直,所以用「关节角度相对 0 的偏差」当惩罚,这是 Cartpole 唯一自定义的奖励函数,在 mdp/rewards.py 里:
defjoint_pos_target_l2(env, target, asset_cfg): asset = env.scene[asset_cfg.name] joint_pos = wrap_to_pi(asset.data.joint_pos[:, asset_cfg.joint_ids])return torch.sum(torch.square(joint_pos - target), dim=1)

这里取的是「杆关节」相对竖直(0) 的角度的平方和,每个环境一个标量;配置里 target=0.0,所以杆越竖、这项越小(惩罚越小)。

  • cart_vel / pole_vel:用 Isaac Lab 自带的 joint_vel_l1,给「小车速度」和「杆角速度」一点小惩罚,鼓励平稳。

ManagerBasedRLEnv 会按配置调用这些函数,得到每个环境的标量,再乘 weight 加起来,得到这一步的总奖励。

五、PPO 配置:网络与超参

训练时用的算法是 RSL-RL 里的 PPO,超参和网络结构都在 agents/rsl_rl_ppo_cfg.pyPPORunnerCfg 里,在这里可以修改学习行为。

@configclassclassPPORunnerCfg(RslRlOnPolicyRunnerCfg): num_steps_per_env =16# 每个环境每次收集 16 步再更新 max_iterations =150# 训练总迭代次数(可被 --max_iterations 覆盖) save_interval =50# 每 50 次迭代存一次 checkpoint experiment_name ="cartpole_direct" policy = RslRlPpoActorCriticCfg( init_noise_std=1.0,# 策略初始探索噪声 actor_obs_normalization=False, critic_obs_normalization=False, actor_hidden_dims=[32,32],# Actor 两层、每层 32 维 critic_hidden_dims=[32,32],# Critic 两层、每层 32 维 activation="elu",) algorithm = RslRlPpoAlgorithmCfg( value_loss_coef=1.0, use_clipped_value_loss=True, clip_param=0.2,# PPO 的 clip 范围 entropy_coef=0.005, num_learning_epochs=5,# 每次收集数据后更新 5 轮 num_mini_batches=4, learning_rate=1.0e-3, schedule="adaptive", gamma=0.99, lam=0.95, desired_kl=0.01, max_grad_norm=1.0,)
  • 和机器人/环境的关系
    • actor_hidden_dims 决定「观测 → 动作」的 MLP 有多大;观测维度由上面的 ObservationsCfg(关节位置 + 关节速度)决定,动作维度由 ActionsCfg(一个关节力矩)决定。
    • gamma / lam 影响回报和优势估计,从而影响策略更关注短期还是长期奖励。
    • 所以:机器人怎么动看 ActionsCfg,奖励怎么算看 RewardsCfg,学多猛、网络多大看这个 PPORunnerCfg。

六、训练脚本

scripts/rsl_rl/train.py 核心就三件事:先启动 App、再按任务名拿到两份配置、最后建环境 + Runner 并调 learn()


1. 先启动 App,再解析参数

Isaac Lab 要求在 import 任何 isaaclab/isaacsim 仿真相关模块之前,必须先启动 App,然后解析 --task--num_envs--max_iterations 等,把 sys.argv 精简给 Hydra 用,再启动 Isaac Sim。

from isaaclab.app import AppLauncher import cli_args parser = argparse.ArgumentParser(...) parser.add_argument("--num_envs",...) parser.add_argument("--task",...) parser.add_argument("--max_iterations",...) cli_args.add_rsl_rl_args(parser) AppLauncher.add_app_launcher_args(parser) args_cli, hydra_args = parser.parse_known_args() sys.argv =[sys.argv[0]]+ hydra_args # 只留 Hydra 需要的 app_launcher = AppLauncher(args_cli) simulation_app = app_launcher.app 

2. Hydra 按任务名注入 env_cfg / agent_cfg

@hydra_task_config(args_cli.task, args_cli.agent) 会根据你传的 --task--agent,从注册表里找到两个 entry point,动态加载 CartpoleEnvCfgPPORunnerCfg,并注入到 main 的参数里。

import Cartpole.tasks # 执行后 Gym 里才有 Template-Cartpole-v0@hydra_task_config(args_cli.task, args_cli.agent)defmain(env_cfg: ManagerBasedRLEnvCfg |..., agent_cfg: RslRlBaseRunnerCfg):# main 里拿到的就是 cartpole_env_cfg.py 和 rsl_rl_ppo_cfg.py 里的那两份配置

3. main 里:建环境 → 包一层 → 建 Runner → learn()

main 里先用命令行覆盖 num_envs、max_iterations、seed、device 等,建好日志目录;然后建环境、包成 RSL-RL 接口、建 Runner、开训

defmain(env_cfg, agent_cfg):# 命令行覆盖 num_envs / max_iterations / seed / device 等,建 log_dir(略) env = gym.make(args_cli.task, cfg=env_cfg,...)# 配置在此生效:场景+MDP 都来自 env_cfg env = RslRlVecEnvWrapper(env, clip_actions=agent_cfg.clip_actions) runner = OnPolicyRunner(env, agent_cfg.to_dict(), log_dir=log_dir, device=agent_cfg.device)# 可选:runner.load(resume_path)、dump_yaml(env.yaml / agent.yaml) runner.learn(num_learning_iterations=agent_cfg.max_iterations, init_at_random_ep_len=True) env.close()if __name__ =="__main__": main() simulation_app.close()
  • gym.make(…, cfg=env_cfg):按 CartpoleEnvCfg 建场景和 MDP(动作/观测/奖励/终止都在这里生效)。
  • RslRlVecEnvWrapper:把 Isaac Lab 的向量化环境接口适配成 RSL-RL 的 step/obs 格式。
  • OnPolicyRunner:按 agent_cfg 建 Actor/Critic 和 PPO;runner.learn() 里才是「多环境 step 收集轨迹 → 算 returns/advantages → PPO 更新」的循环。

工作流

修改配置 (CartpoleEnvCfg / PPORunnerCfg) ↓ gym.make("Template-Cartpole-v0", cfg=env_cfg) → 建场景 (地面 + 4096 个 Cartpole) → 挂 MDP:动作=关节力矩,观测=关节位置+速度,奖励=alive+terminating+pole_pos+cart_vel+pole_vel,终止=超时/出界 ↓ env.step(actions) → 物理仿真一步 → 调用你配置的观测函数 → obs → 调用你配置的奖励函数 → reward → 调用你配置的终止函数 → done ↓ OnPolicyRunner 用 obs 跑 policy 得到 actions,再 env.step(actions),收集整段轨迹 → 算 returns / advantages → PPO 更新 Actor、Critic → 下一个 iteration 

代码是怎么 work 的通过 Gym 注册把你的任务名和两份配置(环境 + 算法)绑在一起;再用这份环境配置去建 ManagerBasedRLEnv,让「场景 + MDP」都按配置里的函数和参数跑;训练脚本只负责解析参数、建环境、建 Runner、调 runner.learn()。你要改行为,就改配置或配置所引用的 MDP 函数(例如 rewards.py)即可。


在这里插入图片描述

Read more

OpenClaw本地部署接入飞书机器人完全安装指南

OpenClaw本地部署接入飞书机器人完全安装指南

作者:网心 2026-3-10 在 Windows 系统上从头开始部署 OpenClaw,并将其配置为可以接入飞书的智能机器人。我们将以实战中遇到的问题为鉴,确保安装过程顺畅无误。 第一章:准备工作与环境检查 在正式开始安装前,请确保您的电脑满足以下基础条件,并理解我们将要使用的关键命令。 1. 系统要求 操作系统: Windows 10 或 Windows 11 (需使用管理员权限运行 PowerShell)。 网络环境: 能够正常访问 GitHub 和 npm 仓库。如果您在网络受限的环境中,可能需要提前准备代理或镜像配置。 2. 核心命令解释 在整个安装过程中,有两个核心命令您需要理解: 一键安装命令:iwr -useb https://openclaw.ai/install.ps1 | iex iwr:Invoke-WebRequest 的别名,用于从指定网址下载文件。

Magic API:低代码接口开发平台完全指南

Magic API:低代码接口开发平台完全指南

Magic API:低代码接口开发平台完全指南 🌟 你好,我是 励志成为糕手 ! 🌌 在代码的宇宙中,我是那个追逐优雅与性能的星际旅人。 ✨ 每一行代码都是我种下的星光,在逻辑的土壤里生长成璀璨的银河; 🛠️ 每一个算法都是我绘制的星图,指引着数据流动的最短路径; 🔍 每一次调试都是星际对话,用耐心和智慧解开宇宙的谜题。 🚀 准备好开始我们的星际编码之旅了吗? 目录 * Magic API:低代码接口开发平台完全指南 * 摘要 * 1. Magic API概述与核心概念 * 1.1 什么是Magic API * 1.2 Magic API的核心特性 * 1.3 Magic API的设计理念 * 2. Magic API架构设计与组件分析 * 2.1 整体架构概览 * 2.2 API引擎工作原理 * 2.3 脚本引擎与SQL执行机制 * 3. Magic API核心功能实现

基于YOLOv8/YOLOv10/YOLOv11/YOLOv12与SpringBoot的跌倒检测系统(千问+DeepSeek智能分析+web交互界面+前后端分离+YOLO数据)

基于YOLOv8/YOLOv10/YOLOv11/YOLOv12与SpringBoot的跌倒检测系统(千问+DeepSeek智能分析+web交互界面+前后端分离+YOLO数据)

项目摘要 本项目旨在设计并实现一个高效、智能且用户友好的基于多版本YOLO深度学习模型与SpringBoot Web框架的实时跌倒检测系统。随着全球老龄化社会的加速到来,老年人在日常生活中发生跌倒的风险日益增高,及时、准确地检测跌倒事件对于保障其生命安全与健康具有重大社会意义。传统监控或穿戴式设备存在隐私侵扰、用户体验不佳或漏报率高等局限。因此,本项目融合了当前前沿的计算机视觉技术与现代Web开发架构,构建了一个集智能分析、实时监控、数据管理与远程交互于一体的综合性解决方案。 系统的核心检测引擎采用了性能卓越的YOLO系列目标检测算法,并创新性地集成了YOLOv8、YOLOv10、YOLOv11及YOLOv12四种最新版本模型,为用户提供了灵活、可对比的算法选择,以适应不同的精度与速度需求。模型在精心标注的自定义数据集上进行训练与验证,该数据集包含 ‘fallen’(已跌倒)、‘falling’(正在跌倒)和‘stand’(站立/正常) 三个关键类别,共计3,888张图像(训练集3,594张,验证集294张),确保了系统对跌倒过程动态的精确识别能力。 系统后端采用SpringB

科哥OCR WebUI太香了!紫蓝渐变界面操作丝滑又高效

科哥OCR WebUI太香了!紫蓝渐变界面操作丝滑又高效 1. 这不是又一个OCR工具,而是一次体验升级 你有没有过这样的经历: 花半小时配环境、改路径、调参数,终于跑通一个OCR模型,结果打开网页——灰扑扑的Gradio默认界面,按钮挤在角落,上传框像上世纪的网页表单,检测完还得手动翻JSON看坐标? 科哥做的这个cv_resnet18_ocr-detection WebUI,彻底改写了这个剧本。 它没有堆砌炫技功能,却把“好用”刻进了每一处交互细节:紫蓝渐变的标题栏不刺眼、悬停有微光反馈、检测进度条带实时耗时显示、结果文本一键全选复制、坐标数据自动格式化为可读结构……这不是给工程师看的调试面板,而是为真实使用者设计的工作台。 更关键的是——它足够轻量。 不用GPU也能跑,CPU上单图检测3秒出结果;模型基于ResNet18轻量架构,显存占用低,连GTX 1060都能稳稳扛住批量处理;所有功能模块(单图/批量/训练/导出)都封装在同一个Web界面里,无需切终端、不用记命令,点几下就完成从前要写脚本才能做的事。 这篇文章不讲模型结构、