Instructions to use JackDH/microduck-rolling-start with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Microduck
How to use JackDH/microduck-rolling-start 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 JackDH/microduck-rolling-start
- Notebooks
- Google Colab
- Kaggle
Download training/run.py from JackDH/microduck-rolling-start: direct link, hf CLI and curl.
- Browser
- Download file 3.95 kB
-
https://huggingface.co/JackDH/microduck-rolling-start/resolve/main/training/run.py
- Command line
-
hf download hf://JackDH/microduck-rolling-start/training/run.py
-
curl -L -o run.py https://huggingface.co/JackDH/microduck-rolling-start/resolve/main/training/run.py
3.95 kB
| """Train or replay the roller landing on Pollen's Got a Talent simulation.""" | |
| import argparse | |
| import json | |
| from pathlib import Path | |
| import learn as landing | |
| from arena.cast import cast_of | |
| from arena.hub_fetch import check_manifest, rig_of | |
| from arena.policy import load_policy | |
| from arena.runner import run_stage | |
| from arena.timeline import load_troupe | |
| from export_actor import export | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| commands = parser.add_subparsers(dest="command", required=True) | |
| training = commands.add_parser("train") | |
| training.add_argument("--output", type=Path, required=True) | |
| training.add_argument( | |
| "--start-from", | |
| type=Path, | |
| help="checkpoint.json with the 32 learned coefficients", | |
| ) | |
| training.add_argument("--generations", type=int, default=25) | |
| training.add_argument("--population", type=int, default=40) | |
| training.add_argument( | |
| "--batch", | |
| type=int, | |
| default=8, | |
| help="simulated starts per candidate per generation", | |
| ) | |
| training.add_argument("--workers", type=int, default=12) | |
| training.add_argument("--random-seed", type=int, default=11062026) | |
| training.add_argument("--speed", type=float, default=0.65) | |
| training.add_argument("--roll-at", type=float, default=1.65) | |
| build = commands.add_parser("export") | |
| build.add_argument("checkpoint", type=Path) | |
| build.add_argument("output", type=Path) | |
| replay = commands.add_parser("replay") | |
| replay.add_argument("model_folder", type=Path) | |
| replay.add_argument("--seeds", nargs="+", type=int, default=[1]) | |
| args = parser.parse_args() | |
| if args.command == "export": | |
| ck = json.loads(args.checkpoint.read_text()) | |
| export(ck["theta"], args.output) | |
| return | |
| if args.command == "train": | |
| if ( | |
| args.population % 2 | |
| or args.population < 10 | |
| or min(args.generations, args.batch, args.workers) < 1 | |
| or args.batch > 520 | |
| ): | |
| parser.error( | |
| "Use at least one generation, worker and seed (up to 520) and an even population of at least 10." | |
| ) | |
| if not 0 <= args.speed <= 2 or not 0.7 <= args.roll_at <= 12: | |
| parser.error( | |
| "Use a speed from 0 to 2 m/s and a roll time from 0.7 to 12 seconds." | |
| ) | |
| if args.output.exists() and any(args.output.iterdir()): | |
| parser.error("Choose a new or empty training directory.") | |
| args.output.mkdir(parents=True, exist_ok=True) | |
| warm = ( | |
| json.loads(args.start_from.read_text())["theta"] | |
| if args.start_from | |
| else None | |
| ) | |
| landing.configure(args.speed, args.roll_at) | |
| landing.save(args.output / "timeline.json", landing.timeline_dict()) | |
| landing.train( | |
| args.generations, | |
| args.population, | |
| args.batch, | |
| warm, | |
| args.output, | |
| random_seed=args.random_seed, | |
| workers=args.workers, | |
| ) | |
| candidates = json.loads((args.output / "checkpoints.json").read_text()) | |
| landing.save(args.output / "checkpoint.json", candidates[0]) | |
| return | |
| folder = args.model_folder | |
| event = landing.EVENT | |
| manifest = json.loads((folder / "manifest.json").read_text()) | |
| check_manifest(manifest, event) | |
| policy = load_policy(folder / "policy.onnx") | |
| troupe = load_troupe(folder / "timeline.json", event) | |
| cast = cast_of(event, troupe, policy, rig_of(manifest), {}) | |
| schedule = troupe.ducks[0].timeline | |
| landing.configure(schedule.commands[1][0], schedule.times[2]) | |
| for seed in args.seeds: | |
| result = run_stage(event, cast.performers, seed) | |
| row = {"seed": seed, "status": result.status} | |
| if result.status == "finish": | |
| row.update(landing.metrics(result.trace[0])) | |
| print(json.dumps(row)) | |
| if __name__ == "__main__": | |
| main() | |