#!/usr/bin/env bash # Continue training the Go2 SRU navigation policy with explicit CLI flags. # # Examples: # # Continue from the latest checkpoint of the latest run, train 1000 more iters. # ./scripts/continue_go2.sh --iters 1000 # # # Resume from a specific iteration of the latest run. # ./scripts/continue_go2.sh --iters 2000 --from-iter 1000 # # # Resume from a specific run directory + iteration. # ./scripts/continue_go2.sh --iters 500 \ # --run-dir 2026-06-12_08-16-50_resume_from_33 --from-iter 600 # # # Pin an exact checkpoint file (in-container path). # ./scripts/continue_go2.sh --iters 500 \ # --checkpoint /workspace/IsaacLab/logs/rsl_rl/go2_navigation_ppo_dev/2026-06-12_08-16-50_resume_from_33/model_1000.pt # # # GUI mode, fewer envs. # ./scripts/continue_go2.sh --iters 200 --envs 8 --gui # # # Switch to the full-PPO task (different experiment_name dir). # ./scripts/continue_go2.sh --iters 2000 --task Isaac-Nav-PPO-Go2-v0 \ # --experiment go2_navigation_ppo_ft_from_b2w # # Behavior: # - --load-optimizer is ON by default (true PPO resume); disable with --no-load-optimizer. # - A new timestamped run directory is created; old runs are preserved. # - The new run's --max_iterations is the *absolute* PPO iteration target, # so set it to (start_iter + extra_iters). For convenience you can pass # --extra-iters N which will be added to the resumed start_iter. # set -euo pipefail REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" # ---- defaults ---- TASK="Isaac-Nav-PPO-Go2-Dev-v0" EXPERIMENT="go2_navigation_ppo_dev" # log subdir under outputs/logs/rsl_rl/ NUM_ENVS=1024 ITERS="" # absolute target iteration count EXTRA_ITERS="" # alternative: N more iters past the resumed checkpoint FROM_ITER="" # specific iteration number to resume from RUN_DIR="" # specific run dir name under / CHECKPOINT="" # explicit in-container checkpoint path (overrides everything) SEED=42 RUN_NAME="" # auto-generated if empty GUI=0 LOAD_OPTIMIZER=1 usage() { sed -n '1,30p' "$0" echo echo "Flags:" echo " --iters N Absolute target PPO iteration count (overrides max_iterations)." echo " --extra-iters N Iters to train past the resumed start (alternative to --iters)." echo " --from-iter N Resume from model_.pt within the chosen run dir." echo " --run-dir NAME Run dir name under outputs/logs/rsl_rl//." echo " --checkpoint PATH Explicit in-container checkpoint path (overrides above)." echo " --task NAME Gym task id (default: $TASK)." echo " --experiment NAME Log subdir to scan (default: $EXPERIMENT)." echo " --envs N Parallel envs (default: $NUM_ENVS)." echo " --seed N Seed (default: $SEED)." echo " --run-name STR Suffix for the new run dir (default: resume_from_)." echo " --gui Show Isaac Sim GUI (X11)." echo " --no-load-optimizer Load model only (cold optimizer)." echo " -h, --help Show this help." exit 0 } # ---- arg parsing ---- while [[ $# -gt 0 ]]; do case "$1" in --iters) ITERS="$2"; shift 2 ;; --extra-iters) EXTRA_ITERS="$2"; shift 2 ;; --from-iter) FROM_ITER="$2"; shift 2 ;; --run-dir) RUN_DIR="$2"; shift 2 ;; --checkpoint) CHECKPOINT="$2"; shift 2 ;; --task) TASK="$2"; shift 2 ;; --experiment) EXPERIMENT="$2"; shift 2 ;; --envs) NUM_ENVS="$2"; shift 2 ;; --seed) SEED="$2"; shift 2 ;; --run-name) RUN_NAME="$2"; shift 2 ;; --gui) GUI=1; shift ;; --no-load-optimizer) LOAD_OPTIMIZER=0; shift ;; -h|--help) usage ;; *) echo "[error] Unknown arg: $1" >&2; usage ;; esac done HOST_LOG_ROOT="$REPO_ROOT/outputs/logs/rsl_rl/$EXPERIMENT" # ---- resolve checkpoint ---- if [[ -z "$CHECKPOINT" ]]; then if [[ -z "$RUN_DIR" ]]; then RUN_DIR="$(ls -1 "$HOST_LOG_ROOT" 2>/dev/null | sort | tail -n 1 || true)" [[ -z "$RUN_DIR" ]] && { echo "[error] No runs under $HOST_LOG_ROOT" >&2; exit 1; } fi RUN_PATH="$HOST_LOG_ROOT/$RUN_DIR" [[ -d "$RUN_PATH" ]] || { echo "[error] Run dir not found: $RUN_PATH" >&2; exit 1; } if [[ -n "$FROM_ITER" ]]; then HOST_CKPT="$RUN_PATH/model_${FROM_ITER}.pt" [[ -f "$HOST_CKPT" ]] || { echo "[error] Checkpoint not found: $HOST_CKPT" >&2; exit 1; } else HOST_CKPT="$(ls -1 "$RUN_PATH"/model_*.pt 2>/dev/null | sort -V | tail -n 1)" [[ -z "$HOST_CKPT" ]] && { echo "[error] No model_*.pt in $RUN_PATH" >&2; exit 1; } fi CHECKPOINT="${HOST_CKPT/$REPO_ROOT\/outputs\/logs/\/workspace\/IsaacLab\/logs}" else HOST_CKPT="${CHECKPOINT/\/workspace\/IsaacLab\/logs/$REPO_ROOT\/outputs\/logs}" fi # ---- derive start iter from filename if possible ---- START_ITER="$(basename "$HOST_CKPT" | sed -nE 's/model_([0-9]+)\.pt/\1/p')" [[ -z "$START_ITER" ]] && START_ITER=0 # ---- resolve target iteration count ---- if [[ -z "$ITERS" && -n "$EXTRA_ITERS" ]]; then ITERS=$(( START_ITER + EXTRA_ITERS )) fi if [[ -z "$ITERS" ]]; then echo "[error] Must provide --iters N (absolute) or --extra-iters N (relative)." >&2 exit 1 fi [[ -z "$RUN_NAME" ]] && RUN_NAME="resume_from_${START_ITER}" # ---- GUI plumbing ---- HEADLESS_FLAG="--headless" EXTRA_DOCKER_ARGS=() if [[ "$GUI" == "1" ]]; then HEADLESS_FLAG="" xhost +local:root >/dev/null 2>&1 || xhost +local:docker >/dev/null 2>&1 || true EXTRA_DOCKER_ARGS+=(-e "DISPLAY=${DISPLAY:-:1}" -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v "$HOME/.Xauthority:/root/.Xauthority:ro") fi OPT_FLAG="" [[ "$LOAD_OPTIMIZER" == "1" ]] && OPT_FLAG="--load_optimizer" cat <