서론
이 페이지는 실제 RSL_RL을 이용해 강화학습을 하고자 할 때 환경, 에이전트, 정책 등에 대해 어떻게 구성해야하는지 에대한 아키텍처?를 이해기위해 설명한다
Isaac Sim
역할
로봇과 주변 물체가 존재하는 물리적 시뮬레이션 세계를 만들고, 그 세계에서 발생하는 물리현상을 계산하는 시뮬레이터이다.
Sim에서 제공하거나 처리하는 요소는 다음과 같다.
로봇 모델
평면 또는 울퉁불퉁한 지형
벽, 나무, 장애물
카메라와 각종 센서
중력과 마찰
충돌과 접촉력
관절 운동
정책이 로봇 관절에 명령을 내리면 Isaac Sim은 물리 법칙을 이용하여 다음 상태를 계산한다.
예를 들어 Go1의 다리가 지면에 닿았을 때 Isaac Sim은 다음을 계산한다.
발이 실제로 지면에 닿았는가?
접촉력은 몇 N인가?
발이 미끄러지는가?
관절이 얼마나 움직였는가?
로봇 몸체가 얼마나 기울어졌는가?
Isaac Lab
역할
Isaac Lab은 Isaac Sim을 이용하여 어떤 물리 환경을 만들 것인지 설정하고, 그 환경을 강화학습 문제로 구성하는 프레임워크이다.
Isaac Lab에서는 다음을 설정한다.
어떤 로봇을 사용할 것인가?
어떤 지형을 사용할 것인가?
로봇과 장애물을 어디에 배치할 것인가?
마찰계수와 질량을 얼마로 설정할 것인가?
정책이 어떤 정보를 관측할 것인가?
정책의 출력을 로봇에 어떻게 적용할 것인가?
어떤 행동에 보상을 줄 것인가?
언제 에피소드를 종료할 것인가?
예를 들어 Isaac Lab에서 다음과 같이 설정할 수 있다.
Go1 로봇을 사용한다.
지면은 평면으로 만든다.
지면 마찰계수는 0.8로 설정한다.
앞쪽에 장애물을 하나 배치한다.
목표 속도는 0.2 m/s로 설정한다.
넘어지면 에피소드를 종료한다.
속도를 잘 따라가면 보상을 준다.
Isaac Lab은 이 설정을 이용하여 Isaac Sim 내부에 로봇, 지형, 센서 등을 생성하도록 구성한다.
또한 구성된 환경내에서 강화학습 문제로 바꾸어 무엇을 학습할지 정의하는 도구이다.
- 어떤 에피소드가 나오면 종료할지
- 리워드는 어떻게 설정할지 등
Sim vs Lab의 차이
Isaac Sim은 로봇, 지형, 센서 등의 시뮬레이션 객체와 물리 엔진을 제공하고, Isaac Lab은 이러한 요소들을 선택하고 조합하여 강화학습 환경을 구성한 뒤, Isaac Sim의 물리 계산 결과를 observation, reward, termination으로 변환한다.
Manager-based 환경
Isaac Lab의 Manager-Based 방식은 환경의 기능을 여러 부분으로 분리한다.
Observation
Action
Reward
Termination
Event
Command
Curriculum
각 기능을 독립적으로 설정하면 기존 환경에서 특정 term만 추가·제거하거나 가중치만 변경하여 새로운 실험을 만들기 쉽다. 이처럼 환경 실행 코드와 설정을 분리해 재사용성을 높이는 방식을 사용한다.
예를 들어 세 보행 정책을 비교할 때 전체 환경 코드를 다시 작성하지 않고 다음 값만 변경할 수 있다.
Antalgic # 부상 보행 정책
pain weight = -0.05
symmetry weight = 0
Fault-tolerant # alive bonus
pain weight = 0
symmetry weight = 0
Symmetry # 대칭 보행 정책
pain weight = 0
symmetry weight = -2.0
Manager 종류
- ObservationManager: 학습하고자 하는 정책의 입력정보를 계산
- ActionManager: 정책 출력을 실제 관절 명령으로 변환
- RewardManager: 행동 결과의 보상 점수를 계산
- TerminationManager: 에피소드가 끝났는지 판단
- EventManager: reset, 손상 다리 선택, 마찰 랜덤화 등을 수행
- CommandManager: 목표 속도나 목표 방향을 생성
- CurriculumManager: 학습 난이도를 점진적으로 변경
Example
정책에 따라 action 출력
↓
ActionManager가 목표 관절각으로 변환
↓
Isaac Sim이 로봇의 물리 움직임 계산
↓
RewardManager가 보상 계산
↓
TerminationManager가 종료 여부 계산
↓
ObservationManager가 다음 관측 계산
상세 동작 구조
① 계산 함수
↓
② TermCfg
↓
③ Manager용 Cfg
↓
④ ManagerBasedRLEnvCfg
↓
⑤ 실제 Manager가 매 step 실행
- 계산함수: 실제 observation, reward, termination 값을 계산
- TermCfg: 어떤 함수를 어떤 파라미터로 사용할지 등록
- ObservationsCfg, RewardsCfg 등: 같은 종류의 여러 term을 모음
- ManagerBasedRLEnvCfg: 전체 환경 설정을 하나로 결합
- Manager: 설정을 읽고 매 step 실제 계산을 실행
Example
간단한 Go1 속도 추종 환경을 예로 들어본다.
목표: Go1이 0.2 m/s0.2\,\mathrm{m/s}0.2m/s로 걷는다.목표 속도에 가까울수록 보상을 주고, 몸통이 지면에 닿으면 종료한다.
속도 추종 보상을 계산하는 함수를 만든다.
현재 로봇 상태를 보고 실제 보상값을 계산한다.
실제 속도 0.20 m/s → 보상 약 1.00
실제 속도 0.15 m/s → 보상 약 0.998
실제 속도 0.00 m/s → 보상 약 0.961
import torch
def track_forward_speed(env):
# Isaac Sim이 계산한 실제 전진속도
actual_speed = env.scene["robot"].data.root_lin_vel_b[:, 0]
# 목표 전진속도
target_speed = 0.2
# 목표 속도와 실제 속도의 차이
error = actual_speed - target_speed
# 오차가 작을수록 1에 가까운 보상
reward = torch.exp(-(error ** 2))
return reward
계산 함수를 어떻게 사용할지 설정한다.
func=track_forward_speed
→ 어떤 계산 함수를 실행할 것인가?
weight=2.0
→ 계산된 보상에 얼마를 곱할 것인가?
from isaaclab.managers import RewardTermCfg as RewTerm
track_speed = RewTerm(
func=track_forward_speed,
weight=2.0,
)
실제 환경에는 속도 보상만 있는 것이 아니다.
예를들면 세 개의 reward term있을 수 있다.
from isaaclab.utils import configclass
@configclass
class RewardsCfg:
track_speed = RewTerm(
func=track_forward_speed,
weight=2.0,
)
energy = RewTerm(
func=joint_energy,
weight=-0.01,
)
alive = RewTerm(
func=is_alive,
weight=1.0,
)
track_speed
→ 목표 속도 추종 보상
energy
→ 에너지 사용 패널티
alive
→ 살아 있는 동안 생존 보상
rewardscfg는 환경에서 사용할 모든 reward 항목을 하나로 합쳐준다.
rewardscfg말고도 Observationcfgs과 Terminationcfgs 들도 존재한다. 이것들도 마찬가지의 구조로 동작한다.
*cfgs들을 하나로 결합한다.
이제 각각의 설정을 하나의 환경 설정으로 모은다.
scene
→ Go1과 지형은 무엇인가?
observations
→ 정책은 무엇을 보는가?
actions
→ 정책 출력은 무엇을 의미하는가?
rewards
→ 무엇을 잘했다고 평가하는가?
terminations
→ 언제 에피소드를 끝내는가?
@configclass
class Go1WalkingEnvCfg(ManagerBasedRLEnvCfg):
scene = Go1SceneCfg()
observations = ObservationsCfg()
actions = ActionsCfg()
rewards = RewardsCfg()
terminations = TerminationsCfg()
강화학습 환경 전체의 최종 설계도라고 생각할 수 있다.
환경이 생성되면 Isaac Lab이 각 Manager를 자동으로 만든다.
ObservationsCfg
→ ObservationManager
RewardsCfg
→ RewardManager
TerminationsCfg
→ TerminationManager
예를 들어 RewardManager는 rewardcfgs에 등록한 설정을 읽어 매 step 다음 작업한다.
1. track_forward_speed() 실행
2. joint_energy() 실행
3. is_alive() 실행
4. 각각 weight를 곱함
5. 모두 더해서 최종 reward 반환
RewardsCfg만 작성하면 Isaac Lab의 ManagerBasedRLEnv가 Manager를 자동으로 구성하고
위 step작업 들을 수행한다
Gymnasium
역할
Isaac Lab에서는 어떤 지형과 로봇을 사용할지, 어떤 센서를 부착할지, 정책이 무엇을 관측하고 어떤 행동을 출력할지, 보상과 종료 조건을 어떻게 설정할지 등을 하나의 강화학습 환경으로 구성한다.
그러면 Gymnasium에는 이 환경의 생성 방법을 특정 이름으로 등록해 둔다.
이후 사용자는 복잡한 설정을 하나씩 다시 작성하지 않고 gym.make("환경 이름")만 호출하여 해당 Isaac Lab 환경 전체를 한 번에 생성하고 사용할 수 있다.
RSL-RL
역할
RSL-RL은 Isaac Lab에서 만든 강화학습 환경을 반복해서 실행하면서 Actor와 Critic 신경망을 PPO 알고리즘으로 학습하는 라이브러리이다.
Isaac Lab과 RSL-RL의 관계
Go1 환경을 예로 들면 Isaac Lab은 다음을 정의한다.
Observation
- 관절 위치
- 관절 속도
- 몸체 각속도
- 목표 속도
- 손상 다리 정보
Action
- 12개 관절의 목표 위치
Reward
- 속도 추종 보상
- 에너지 패널티
- pain penalty
- 생존 보상
Termination
- 몸통이 지면에 접촉
- 몸체가 과도하게 기울어짐
- 시간 초과
그러면 RSL-RL은 Isaac Lab 환경으로부터 다음 데이터를 반복해서 받는다.
현재 observation
정책이 선택한 action
환경이 계산한 reward
에피소드 종료 여부 done
다음 observation
이 경험을 이용하여 PPO로 정책을 개선한다.
Isaac Lab
강화학습 문제 구성 및 실행
↓ observation
RSL-RL Actor
action 생성
↓ action
Isaac Lab + Isaac Sim
물리 계산, reward와 done 계산
↓ reward, done, next observation
RSL-RL
경험 저장 및 PPO 업데이트
Rollout Storage
rollout Storage는 환경에서 수집한 경험을 임시로 저장하는 공간이다.
각 step에서 다음과 같은 데이터를 저장한다.
observation
action
reward
done
value
action log probability
예를 들어 병렬 환경이 64개이고 환경당 24 step을 수집한다면, 한 iteration에서 수집하는 transition 수는 64*24 = 1536개이다.
OnPolicyRunner
OnPolicyRunner는 RSL-RL의 전체 학습 과정을 관리하는 실행자다.
1. 환경에서 observation 받기
2. Actor로 action 생성
3. 환경에 action 전달
4. reward, done, next observation 받기
5. Rollout Storage에 경험 저장
6. 일정 step 동안 반복
7. Return과 Advantage 계산
8. PPO로 Actor와 Critic 업데이트
9. 로그와 checkpoint 저장
10. 다음 iteration 진행
코드에서는 아래와 같이 사용한다.
OnPolicyRunner는 환경을 받아 PPO 알고리즘과 로깅 구성을 생성한 뒤 learn() 학습 루프를 실행한다.
runner = OnPolicyRunner(
env=env,
train_cfg=agent_cfg,
log_dir=log_dir,
device="cuda",
)
runner.learn(
num_learning_iterations=18000,
)
RSL-RL의 Agent Config
주어진 환경에서 정책 신경망을 어떤 방식으로 학습할 것인가?
Actor와 Critic의 신경망 크기
learning rate
discount factor gamma
GAE lambda
PPO clip 값
mini-batch 개수
한 환경에서 수집할 step 수
최대 학습 iteration
checkpoint 저장 주기
RslRlVecEnvWrapper
Isaac Lab 환경과 RSL-RL은 서로 다른 라이브러리이므로 두 라이브러리가 기대하는 환경 인터페이스를 연결해야 한다.
그 역할을 하는 것이 다음 Wrapper다.
RslRlVecEnvWrapper는 Isaac Lab 환경을 RSL-RL이 사용할 수 있는 형식으로 감싼다.
Isaac Lab 공식 문서도 이를 Isaac Lab 환경을 RSL-RL 인터페이스에 맞게 변환하는 Wrapper로 설명한다.
주요 역할은 다음과 같다.
Isaac Lab의 observation 구조
→ RSL-RL이 사용할 observation 형식으로 전달
Isaac Lab의 step 결과
→ RSL-RL이 기대하는 reward, done, extras 형식으로 전달
정책 action
→ 필요한 범위로 clipping
병렬 환경 수와 device 정보
→ RSL-RL에 제공
예시코드는 아래와 같다.
# 1. Isaac Lab 환경 생성
env = gym.make(
task_name,
cfg=env_cfg,
)
# 2. RSL-RL 형식으로 변환
env = RslRlVecEnvWrapper(
env,
clip_actions=agent_cfg.clip_actions,
)
# 3. RSL-RL 학습 실행자 생성
runner = OnPolicyRunner(
env,
agent_cfg.to_dict(),
log_dir=log_dir,
device=agent_cfg.device,
)
# 4. PPO 학습 시작
runner.learn(
num_learning_iterations=agent_cfg.max_iterations,
)
Leaner 내부 동작
obs = env.get_observations()
for iteration in range(max_iterations):
for step in range(num_steps_per_env):
actions = self.alg.act(obs)
obs, rewards, dones, extras = self.env.step(actions)
self.alg.process_env_step(
obs,
rewards,
dones,
extras,
)
self.alg.compute_returns(obs)
loss_dict = self.alg.update()
self.alg.act(obs)
Actor가 observation을 보고 action 생성
self.env.step(actions)
Isaac Lab이 action을 관절 명령으로 변환
Isaac Sim이 물리 계산
Isaac Lab이 reward, done, next observation 계산
process_env_step(...)
이번 step의 경험을 Rollout Storage에 저장
compute_returns(obs)
미래 누적보상 Return과 Advantage 계산
update()
PPO loss 계산
역전파
Actor와 Critic 파라미터 업데이트
전체 관계
Isaac Lab 환경
ObservationManager가 observation 생성
↓
RslRlVecEnvWrapper
환경 데이터를 RSL-RL 형식으로 전달
↓
RSL-RL Actor
action 생성
↓
RslRlVecEnvWrapper
action을 Isaac Lab 환경에 전달
↓
Isaac Lab ActionManager
관절 목표값으로 변환
↓
Isaac Sim
로봇의 물리 움직임 계산
↓
Isaac Lab
reward, done, next observation 계산
↓
RSL-RL Rollout Storage
경험 저장
↓
RSL-RL PPO
Actor와 Critic 업데이트
Comment