Isaac Lab and robot simulation · Learning
English translation
Execution conditions
- CPU path: Gymnasium, NumPy, and Matplotlib.
- Official SO-101 tutorial: Python 3.12, uv, Git LFS, Linux/Windows + NVIDIA GPU.
- GPU environment: Check before class. Prefer personal equipment, supplemented by shared resources.
- Jetson extension: edge inference and latency measurement.
Topics covered
Go beyond running a new simulator example: Identify the observations, actions, and physics that your research task requires you to change.
Simulator components
The task defines observations, actions, rewards, resets, and terminations. The physics backend handles physics calculations, the renderer generates images, and the RL library trains policies.
Mapping periods
The physics step and policy control period may differ. Align action scale, joint units, and control decimation to transfer a policy to another simulator or robot.
Hardware path
The basic CPU path also includes transition analysis and task component mapping. When a GPU is available, prioritize personal equipment and supplement it with shared environments.
Use Jetson for policy inference and latency measurement, and check simulator compatibility separately.
Worked example
Start from CartPole-v1 observations, actions, resets, and time limits.
"""Small public-environment benchmark; evaluation traces are ordinary numeric arrays."""
import json
from importlib.metadata import version
from pathlib import Path
import numpy as np
import gymnasium as gym
def collect(env_id='CartPole-v1', policy=None, seeds=range(100,103)):
env=gym.make(env_id); transitions=[]; summary=[]
for seed in seeds:
obs,info=env.reset(seed=seed);env.action_space.seed(seed);total=0.;length=0
while True:
action=env.action_space.sample() if policy is None else policy(obs)
nxt,reward,terminated,truncated,info=env.step(action)
transitions.append((obs.copy(),np.asarray(action).copy(),reward,nxt.copy(),terminated,truncated,seed))
obs=nxt;total+=reward;length+=1
if terminated or truncated:break
summary.append([seed,total,length,int(terminated),int(truncated)])
env.close()
columns=list(zip(*transitions))
data={k:np.asarray(v) for k,v in zip(['observations','actions','rewards','next_observations','terminated','truncated','episode_seed'],columns)}
return np.asarray(summary),data
def cartpole_rule(obs):return int(obs[2]+.25*obs[3]>0)
def zero_torque(obs):return np.zeros(1,dtype=np.float32)
def save_trace(path, env_id, data, policy_name, seeds):
# Contains numeric arrays and JSON text only; never requires pickle.
metadata=dict(env_id=env_id,policy=policy_name,seeds=list(seeds),gymnasium=version('gymnasium'))
np.savez_compressed(path,**data,metadata_json=np.array(json.dumps(metadata)))
with np.load(path,allow_pickle=False) as saved:
assert len(saved['observations'])==len(saved['rewards'])
print(json.loads(str(saved['metadata_json'])))
def public_model(algorithm='DQN',env_id='CartPole-v1',seed=7,steps=2048,**changes):
from stable_baselines3 import DQN,PPO,SAC
options=dict(policy_kwargs=dict(net_arch=[32,32]),seed=seed,verbose=0,device='cpu')
if algorithm=='DQN':options.update(buffer_size=5000,learning_starts=100,target_update_interval=100,batch_size=32)
if algorithm=='PPO':options.update(n_steps=128,batch_size=64,n_epochs=3)
if algorithm=='SAC':options.update(buffer_size=5000,learning_starts=100,batch_size=64)
options.update(changes)
env=gym.make(env_id)
model={'DQN':DQN,'PPO':PPO,'SAC':SAC}[algorithm]('MlpPolicy',env,**options)
model.learn(total_timesteps=steps)
env.close()
return model
print('Gymnasium',version('gymnasium'))
env=gym.make('CartPole-v1')
print('Observation:',env.observation_space,'Action:',env.action_space,'Limit:',env.spec.max_episode_steps)
env.close()
# For visual inspection, create a separate env with render_mode='rgb_array'.
# Rendering requires gymnasium[classic-control]; do not render every training step.
rows,trace=collect(policy=cartpole_rule,seeds=[100]);print(rows)
Gymnasium 1.3.0 Observation: Box([-4.8 -inf -0.41887903 -inf], [4.8 inf 0.41887903 inf], (4,), float32) Action: Discrete(2) Limit: 500 [[100. 500. 500. 0. 1.]]