This is an old revision of the document!
In this lab, you train a quadruped robot, Pupper, to stand and walk using Reinforcement Learning.
You do not manually program each leg movement. Instead, you define what “good movement” means through a reward function. The training algorithm runs many simulated Pupper robots in parallel, tests different behaviours and gradually improves the neural policy.
The main idea is:
This lab uses a Stanford-style Reinforcement Learning workflow based on Legged Gym / Isaac Gym. The training runs on the UPB GPU cluster through SLURM.
There are two different parts of the Pupper workflow:
These are not the same thing.
The deploy repository may contain files such as:
config.yaml;launch.py;estop_controller.cpp;deploy.py;rebuild_neural_controller.py;parkour_policy.json;test_policy.json.Those files are used for loading and deploying trained policies. They are not the full Reinforcement Learning training environment.
Do not modify the reward function in config.yaml. That file points the controller to an already trained policy.
For this lab, you need the training environment. The reward functions are edited in the Legged Gym training code, usually in files related to the Pupper environment.
In this lab, you will:
Download the Lab 5 HPC pack from OCW:
lab5_hpc_pack.zip
After extracting it, you should have this folder:
| File | Purpose |
|---|---|
README.txt | Short explanation of the pack |
lab5_gpu_check.slurm | Checks whether your GPU job works |
setup_leggedgym_env.sh | Prepares the project folder and clones the repositories |
lab5_train_leggedgym.slurm | Submits a Pupper training job |
lab5_play_leggedgym.slurm | Tests or visualizes a trained policy |
lab5_hpc_ocw_section.txt | Extra OCW text section, if needed |
Use SSH to connect to the FEP.
| Step | Command |
|---|---|
| Connect to the FEP | ssh -X -o ServerAliveInterval=100 [user.name@fep.grid.pub.ro](mailto:user.name@fep.grid.pub.ro) |
Replace user.name with your faculty account.
Important: do not run the training directly on the FEP. The FEP is only the access node. Training must be submitted as a SLURM job.
After connecting, check the available partitions.
| What you want to do | Command |
|---|---|
| Check available partitions | sinfo -o ”%10P %55N %8c %10m %20G” |
| Check all partition information | sinfo |
| Check jobs on the A100 partition | squeue -p dgxa100 |
| Check jobs on the H100 partition | squeue -p dgxh100 |
Look for GPU partitions such as:
dgxa100;dgxh100;ucsx;ml.For this lab, use one GPU per job.
If an A100 partition is available, prefer it for the old Stanford-style Legged Gym workflow. H100 is more powerful, but older simulator stacks can be more sensitive to software compatibility.
Check the available software modules.
| What you want to do | Command |
|---|---|
| Show all available modules | module avail |
| Search for CUDA modules | module avail cuda |
| Show currently loaded modules | module list |
| Clear loaded modules | module purge |
| Load CUDA 12.3 | module load libraries/cuda-12.3 |
| Check loaded modules again | module list |
If libraries/cuda-12.3 is not available, use module avail cuda and choose the CUDA module available on the cluster.
Create a working folder on the FEP.
| Step | Command |
|---|---|
| Create the project folder | mkdir -p ~/pupper_lab5 |
| Go to the project folder | cd ~/pupper_lab5 |
| Create the logs folder | mkdir -p logs |
| Check the folder content | ls |
Copy or upload the files from lab5_hpc_pack.zip into ~/pupper_lab5.
After copying the files, check that they are there.
| What you want to check | Command |
|---|---|
| List files | ls |
| Make setup script executable | chmod +x setup_leggedgym_env.sh |
| Make GPU check file executable | chmod +x lab5_gpu_check.slurm |
| Make training file executable | chmod +x lab5_train_leggedgym.slurm |
| Make play file executable | chmod +x lab5_play_leggedgym.slurm |
You should see:
README.txt;lab5_gpu_check.slurm;setup_leggedgym_env.sh;lab5_train_leggedgym.slurm;lab5_play_leggedgym.slurm;lab5_hpc_ocw_section.txt.Before installing or running the training environment, test that you can submit a GPU job.
| Step | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Submit the GPU check job | sbatch lab5_gpu_check.slurm |
| Check your jobs | squeue -u $USER |
| List the log files | ls logs |
After you submit the job, SLURM prints something similar to:
Submitted batch job 123456
The number 123456 is an example job ID. Your job ID will be different.
When the job finishes, inspect the logs.
| What you want to do | Example command |
|---|---|
| Open the GPU check output | cat logs/gpu_check_123456.out |
| Open the GPU check error file | cat logs/gpu_check_123456.err |
Replace 123456 with your real job ID.
The output should show information from:
nvidia-smi;python3 –version;nvcc –version.If this job fails, do not continue to the training part. Fix the GPU job first.
The training environment is based on Legged Gym.
| Step | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Run the setup script | ./setup_leggedgym_env.sh |
| Check the project folder | ls ~/pupper_lab5 |
The setup script creates a Python virtual environment and clones the required repositories.
You should get folders similar to:
~/pupper_lab5/leggedgym;~/pupper_lab5/rsl_rl;~/pupper_lab5/.venv;~/pupper_lab5/logs.Important: this script does not automatically install Isaac Gym. The old Stanford-style workflow may require Isaac Gym Preview and specific Python / PyTorch / CUDA versions.
If the instructor provides a prepared environment, container or module, use that instead of manually installing everything.
The simulator is not lab_5_fall_2025.
For this lab, the simulator is the Legged Gym training environment. This environment runs many simulated robots in parallel on the GPU.
The important argument is:
–num_envs=2000
This means that the training process uses many parallel simulated Pupper environments. Each simulated Pupper collects experience, and the PPO algorithm uses that experience to update the policy.
A simplified view:
This is why a GPU is needed.
Go to the Legged Gym repository and search for the Pupper files.
| What you want to do | Command |
|---|---|
| Go to the repository | cd ~/pupper_lab5/leggedgym |
| List files | ls |
| Search for Pupper files | find . -iname ” *pupper *” |
| Search for reward functions | grep -R “_reward” legged_gym/envs |
| Search for velocity-related code | grep -R “velocity” legged_gym/envs |
| Search for torque-related code | grep -R “torque” legged_gym/envs |
| Search for height-related code | grep -R “height” legged_gym/envs |
You are looking for files similar to:
legged_gym/envs/pupper/pupper.py;legged_gym/envs/pupper/pupper_config.py.The exact path may differ depending on the repository version.
A reward function tells the robot what behaviour is good.
For example, a walking robot can receive:
Common reward terms include:
A reward function is not just about making the robot fast. If you reward only speed, the robot may move aggressively, fall or use too much energy.
A good policy balances:
Open the training SLURM file.
| What you want to do | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Open the training file | nano lab5_train_leggedgym.slurm |
Look for these variables:
| Variable | Meaning |
|---|---|
TASK=“${TASK:-pupper_flat}” | The training task. The default task is pupper_flat. |
NUM_ENVS=“${NUM_ENVS:-2000}” | The number of parallel simulated environments. |
MAX_ITERATIONS=“${MAX_ITERATIONS:-300}” | The number of training iterations. |
RUN_NAME=“${RUN_NAME:-team_${SLURM_JOB_ID}_pupper_flat}” | The experiment name. |
For a first test, keep the default values.
Submit the training job.
| Step | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Submit the training job | sbatch lab5_train_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
After you submit the job, SLURM prints something similar to:
Submitted batch job 123457
The number 123457 is an example. Your job ID will be different.
Use your real job ID to check the logs.
| What you want to do | Example command |
|---|---|
| Watch the output live | tail -f logs/pupper_train_123457.out |
| Open the output file | cat logs/pupper_train_123457.out |
| Open the error file | cat logs/pupper_train_123457.err |
| Stop watching a live log | CTRL + C |
| Cancel the job if needed | scancel 123457 |
Replace 123457 with your real job ID.
After the job finishes, check the training logs.
| What you want to do | Command |
|---|---|
| Go to the Legged Gym repository | cd ~/pupper_lab5/leggedgym |
| Find generated log files | find logs -maxdepth 3 -type f | head |
| Find saved models | find . -type f -name ” *.pt” |
| Find videos | find . -type f -name ” *.mp4” |
| Find images | find . -type f -name ” *.png” |
Save the output files. You need them for the report.
Before changing the reward function, run a very short experiment to make sure the pipeline works.
| What you want to do | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Run a debug experiment | MAX_ITERATIONS=50 RUN_NAME=“debug_${USER}” sbatch lab5_train_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
| List logs | ls logs |
This run is not meant to produce a good policy. It is only a debugging run.
Check:
If the debug run fails, fix the environment before changing the reward function.
Open the Pupper environment file.
| What you want to do | Command |
|---|---|
| Go to the Legged Gym repository | cd ~/pupper_lab5/leggedgym |
| Search for Pupper files | find . -iname ” *pupper *” |
| Search for reward functions | grep -R “_reward” legged_gym/envs |
| Open a file with nano | nano legged_gym/envs/pupper/pupper.py |
If the file path is different, use the result from find . -iname ” *pupper *”.
Identify at least three reward functions.
Complete this table in your report:
| Reward term | Reward or penalty? | What behaviour does it encourage or discourage? |
|---|---|---|
| forward velocity | ||
| torque / effort | ||
| base height | ||
| stability / orientation | ||
| smoothness |
Write short explanations. Do not copy code without explaining it.
In this experiment, focus on forward movement.
Find the reward term related to forward velocity.
Possible names include:
_reward_forward_velocity;tracking_lin_vel;lin_vel_x;forward_velocity.Increase the importance of forward movement.
Do not delete the other reward terms. You still need the robot to stay stable.
Run a new job.
| What you want to do | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Run the velocity experiment | RUN_NAME=“velocity_${USER}” MAX_ITERATIONS=300 sbatch lab5_train_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
| List logs | ls logs |
After the job finishes, save:
Answer:
In this experiment, focus on reducing effort.
Find the reward term related to torque or effort.
Possible names include:
_reward_torques;torque_penalty;energy;effort.Increase the penalty for using too much torque.
Run a new job.
| What you want to do | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Run the effort experiment | RUN_NAME=“effort_${USER}” MAX_ITERATIONS=300 sbatch lab5_train_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
| List logs | ls logs |
Compare this result with the velocity-focused run.
Answer:
In this experiment, focus on stability.
Find reward terms related to:
Increase the importance of stability.
Run a new job.
| What you want to do | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Run the stability experiment | RUN_NAME=“stability_${USER}” MAX_ITERATIONS=300 sbatch lab5_train_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
| List logs | ls logs |
Answer:
Create your own reward configuration.
Your goal is to balance:
Run a final experiment.
| Situation | Command |
|---|---|
| Normal final run | RUN_NAME=“final_${USER}” MAX_ITERATIONS=500 sbatch lab5_train_leggedgym.slurm |
| Shorter final run if the queue is busy | RUN_NAME=“final_${USER}” MAX_ITERATIONS=200 sbatch lab5_train_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
| List logs | ls logs |
Save the final reward configuration.
Explain:
Use the play script only after you have a trained policy or checkpoint.
| Step | Command |
|---|---|
| Go to the project folder | cd ~/pupper_lab5 |
| Submit the play job | sbatch lab5_play_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
| List logs | ls logs |
After the job finishes, check the output.
| What you want to do | Example command |
|---|---|
| Open the play output | cat logs/pupper_play_123458.out |
| Open the play error file | cat logs/pupper_play_123458.err |
| Find generated files | cd ~/pupper_lab5/leggedgym && find logs -type f | head -20 |
| Search for videos | cd ~/pupper_lab5/leggedgym && find . -type f -name ” *.mp4” |
Replace 123458 with your real job ID.
If no video is generated, use the training logs and SLURM output for your report.
Compare at least three runs:
Complete the table:
| Run name | Main reward change | Iterations | Result observed | Main problem |
|---|---|---|---|---|
| baseline/debug | none | |||
| velocity | increased forward movement reward | |||
| effort | increased effort penalty | |||
| stability | increased stability terms | |||
| final | custom configuration |
Then answer:
A policy trained in simulation may not work perfectly on the real robot. This difference is called the sim-to-real gap.
Possible causes:
Answer:
Do this only if the instructor confirms that the physical Pupper robot is ready.
The deploy repository is used only after the policy has been trained.
On the Raspberry Pi of the robot, the deploy repository may contain:
config.yaml;launch.py;deploy.py;rebuild_neural_controller.py;policy.json.Run deployment scripts only on the robot's Raspberry Pi, not on the FEP and not on your laptop.
If you see paths such as /home/pi/…, that script is meant for the Raspberry Pi.
Do not run robot deployment scripts on the HPC cluster.
Use this section when you work on the HPC cluster.
| What you want to do | Command |
|---|---|
| Submit the GPU check job | sbatch lab5_gpu_check.slurm |
| Submit the training job | sbatch lab5_train_leggedgym.slurm |
| Submit the play / test job | sbatch lab5_play_leggedgym.slurm |
| Check your jobs | squeue -u $USER |
| Check jobs on the A100 partition | squeue -p dgxa100 |
| Check jobs on the H100 partition | squeue -p dgxh100 |
| Cancel a job | scancel 123457 |
| Check information about a finished job | sacct -j 123457 |
| Check detailed job information | sacct -j 123457 –format=JobID,JobName,Partition,State,Elapsed,MaxRSS,AllocGRES |
| List log files | ls logs |
| Open GPU check output | cat logs/gpu_check_123456.out |
| Open GPU check error file | cat logs/gpu_check_123456.err |
| Open training output | cat logs/pupper_train_123457.out |
| Open training error file | cat logs/pupper_train_123457.err |
| Watch a running training log | tail -f logs/pupper_train_123457.out |
| Show the last lines of a training log | tail logs/pupper_train_123457.out |
| Show the last 50 lines of a training log | tail -n 50 logs/pupper_train_123457.out |
| Check available partitions | sinfo |
| Check partitions in compact format | sinfo -o ”%10P %55N %8c %10m %20G” |
| Check available modules | module avail |
| Search for CUDA modules | module avail cuda |
| Clear loaded modules | module purge |
| Load CUDA | module load libraries/cuda-12.3 |
| Check loaded modules | module list |
| Check GPU information | nvidia-smi |
| Search for Pupper files | find . -iname ” *pupper *” |
| Search for reward functions | grep -R “_reward” legged_gym/envs |
| Find generated files in logs | find logs -type f | head -20 |
| Search for saved models | find . -type f -name ” *.pt” |
| Search for videos | find . -type f -name ” *.mp4” |
| Search for images | find . -type f -name ” *.png” |
The numbers 123456 and 123457 are examples. Replace them with your real job ID.
After submitting a job with sbatch, SLURM prints something like:
Submitted batch job 123457
In that case, 123457 is the job ID.
Use this sequence for a normal run:
| Step | Command |
|---|---|
| 1. Go to the project folder | cd ~/pupper_lab5 |
| 2. Submit GPU check | sbatch lab5_gpu_check.slurm |
| 3. Check queue | squeue -u $USER |
| 4. List logs | ls logs |
| 5. Open GPU output | cat logs/gpu_check_123456.out |
| 6. Submit training | sbatch lab5_train_leggedgym.slurm |
| 7. Check queue again | squeue -u $USER |
| 8. Watch training output | tail -f logs/pupper_train_123457.out |
| 9. Open final output | cat logs/pupper_train_123457.out |
| 10. Open error output | cat logs/pupper_train_123457.err |
Use these commands for different experiments:
| Experiment | Command |
|---|---|
| Short debug run | MAX_ITERATIONS=50 RUN_NAME=“debug_${USER}” sbatch lab5_train_leggedgym.slurm |
| Velocity-focused run | RUN_NAME=“velocity_${USER}” MAX_ITERATIONS=300 sbatch lab5_train_leggedgym.slurm |
| Effort-focused run | RUN_NAME=“effort_${USER}” MAX_ITERATIONS=300 sbatch lab5_train_leggedgym.slurm |
| Stability-focused run | RUN_NAME=“stability_${USER}” MAX_ITERATIONS=300 sbatch lab5_train_leggedgym.slurm |
| Final run | RUN_NAME=“final_${USER}” MAX_ITERATIONS=500 sbatch lab5_train_leggedgym.slurm |
| Shorter final run if the queue is busy | RUN_NAME=“final_${USER}” MAX_ITERATIONS=200 sbatch lab5_train_leggedgym.slurm |
Run these commands inside the Legged Gym repository.
| What you want to do | Command |
|---|---|
| Go to the repository | cd ~/pupper_lab5/leggedgym |
| List files | ls |
| Find Pupper files | find . -iname ” *pupper *” |
| Find reward functions | grep -R “_reward” legged_gym/envs |
| Find Python files containing torque | grep -R “torque” legged_gym/envs |
| Find Python files containing velocity | grep -R “velocity” legged_gym/envs |
| Find Python files containing height | grep -R “height” legged_gym/envs |
| Find logs | find logs -type f | head -20 |
| Find saved models | find . -type f -name ” *.pt” |
| Find videos | find . -type f -name ” *.mp4” |
Do not run the training command directly on the FEP.
Do not run this directly in the terminal:
python legged_gym/scripts/train.py –task=pupper_flat –num_envs=2000 –max_iterations=300 –headless
Instead, run:
sbatch lab5_train_leggedgym.slurm
This sends the training job to a GPU compute node through SLURM.
Submit one archive containing:
team_name_lab5.zip
Inside the archive, include:
report.pdf;slurm_outputs/;reward_code/;screenshots/;logs/;videos_optional/.Your report must include:
Answer these questions in your report:
–num_envs=2000 mean?Check your jobs with:
squeue -u $USER
The cluster may be busy. Wait or reduce the requested time.
Check available CUDA modules with:
module avail cuda
Choose an available CUDA module and modify the SLURM files.
You may not be on the correct cluster environment. Reconnect to the FEP and try again.
Check both files:
cat logs/pupper_train_123457.out;cat logs/pupper_train_123457.err.
Replace 123457 with your real job ID.
The error file usually contains the useful information.
The Python environment is not ready. Activate the correct environment or install the required dependencies.
The training script checks this automatically.
If the output says False for CUDA availability, check:
sbatch, not direct execution on FEP.Search for it with:
cd ~/pupper_lab5/leggedgym;find . -iname ” *pupper *”;grep -R “_reward” legged_gym/envs.Use fewer iterations for testing:
MAX_ITERATIONS=50 sbatch lab5_train_leggedgym.slurm
Do not use long runs until the short run works.
That is normal for short training runs. The goal is to understand reward shaping and compare experiments, not necessarily to produce a perfect robot gait in one lab session.
Discuss the sim-to-real gap. Do not assume the training failed only because real-world deployment is imperfect.
In this lab, you used a Stanford-style Reinforcement Learning workflow to train Pupper in simulation. You submitted GPU jobs through SLURM, inspected reward functions, changed reward terms and compared policies.
The key idea is that robot learning is not only about running a training script. The quality of the learned behaviour depends strongly on how the reward function is designed.
A fast robot is not always a good robot. A stable robot is not always fast. A useful policy balances speed, effort, stability and smoothness.