Instructions to use kenpeter123/microduck-rl with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Microduck
How to use kenpeter123/microduck-rl with Microduck:
# Replace SLOT with the slot specified in the model card (walk, stand, sitstand, ground_pick, kick_left, kick_right, roulade). sudo robotctl policy load SLOT kenpeter123/microduck-rl
- Notebooks
- Google Colab
- Kaggle
File size: 4,253 Bytes
1851ea6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | """eval_sprint_speed.py — 在 warp 训练环境内直接测 checkpoint 的真实速度。
绕开本地 CPU harness 的所有差异项(BAM/延迟/噪声/归一化烘焙),用训练同款
环境 + rsl_rl 推理策略(含 obs normalizer)回答:策略在原生环境里跑多快?
用法(实例上,工作目录 = repo 根):
uv run --no-sync python scripts/eval_sprint_speed.py \
--checkpoint logs/rsl_rl/sprint/<run>/model_1999.pt --vx 0.4 1.2 2.0
"""
from __future__ import annotations
import argparse
from dataclasses import asdict
import numpy as np
import torch
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--task", default="Mjlab-Sprint-Flat-MicroDuck")
ap.add_argument("--checkpoint", default=None)
ap.add_argument("--onnx", default=None, help="测 ONNX(归一化已烘焙)而非 .pt checkpoint")
ap.add_argument("--vx", type=float, nargs="+", default=[0.4, 0.8, 1.2, 1.6, 2.0])
ap.add_argument("--num-envs", type=int, default=64)
ap.add_argument("--seconds", type=float, default=8.0)
ap.add_argument("--device", default="cuda:0")
args = ap.parse_args()
import mjlab.tasks # noqa: F401 — populate the registry
import mjlab_microduck.tasks # noqa: F401 — microduck registrations
from mjlab.tasks.registry import load_env_cfg, load_rl_cfg, load_runner_cls
from mjlab.envs import ManagerBasedRlEnv
from mjlab.rl import RslRlVecEnvWrapper, MjlabOnPolicyRunner
env_cfg = load_env_cfg(args.task)
agent_cfg = load_rl_cfg(args.task)
env_cfg.scene.num_envs = args.num_envs
env = ManagerBasedRlEnv(cfg=env_cfg, device=args.device)
env = RslRlVecEnvWrapper(env, clip_actions=agent_cfg.clip_actions)
if args.onnx:
import onnxruntime as ort
session = ort.InferenceSession(args.onnx)
def policy(obs):
vec = obs["actor"].detach().cpu().numpy().astype(np.float32)
# 导出的 ONNX batch 维固定为 1,逐 env 推理
acts = [session.run(None, {session.get_inputs()[0].name: vec[i : i + 1]})[0]
for i in range(vec.shape[0])]
return torch.tensor(np.concatenate(acts, axis=0),
device=args.device, dtype=torch.float32)
else:
assert args.checkpoint, "--checkpoint or --onnx required"
runner_cls = load_runner_cls(args.task) or MjlabOnPolicyRunner
runner = runner_cls(env, asdict(agent_cfg), device=args.device)
runner.load(args.checkpoint, load_cfg={"actor": True}, strict=True,
map_location=args.device)
policy = runner.get_inference_policy(device=args.device)
uw = env.unwrapped
robot = uw.scene["robot"]
cmd_term = uw.command_manager.get_term("twist")
dt = uw.step_dt
print(f"policy: {args.onnx or args.checkpoint}")
print(f"control dt: {dt:.4f}s envs: {args.num_envs} task: {args.task}")
def force_cmd(vx):
cmd_term.vel_command_b[:, 0] = vx
cmd_term.vel_command_b[:, 1] = 0.0
cmd_term.vel_command_b[:, 2] = 0.0
cmd_term.is_standing_env[:] = False
obs, _ = env.reset()
for vx in args.vx:
obs, _ = env.reset()
force_cmd(vx)
# 2s 加速/稳定段
for _ in range(int(2.0 / dt)):
force_cmd(vx)
actions = policy(obs)
obs, _, _, _ = env.step(actions)
x0 = robot.data.root_link_pos_w[:, 0].clone()
y0 = robot.data.root_link_pos_w[:, 1].clone()
n_meas = int(args.seconds / dt)
dones_total = 0
for _ in range(n_meas):
force_cmd(vx)
actions = policy(obs)
obs, _, dones, _ = env.step(actions)
dones_total += int(dones.sum())
x1 = robot.data.root_link_pos_w[:, 0]
y1 = robot.data.root_link_pos_w[:, 1]
dist = torch.hypot(x1 - x0, y1 - y0)
speed = dist / args.seconds
alive = (dones_total == 0)
print(f"cmd={vx:4.1f} 实测 speed mean={speed.mean():.3f} "
f"p10={speed.quantile(0.1):.3f} p90={speed.quantile(0.9):.3f} "
f"max={speed.max():.3f} m/s resets={dones_total}")
env.close()
if __name__ == "__main__":
main()
|