Sim-to-Real: Model Uncertainty와 Action Delay · 학습
실행 조건
- 필요 패키지: gymnasium·stable-baselines3·PyTorch.
- SB3 정책:
MlpPolicy. - Gymnasium
step: 5개 반환값. - 공개 환경 시각화:
gymnasium[classic-control]추가.
필요한 패키지가 없으면 Colab·Jupyter 코드 셀에서 %pip install control==0.10.2 gymnasium==1.3.0 stable-baselines3==2.9.2를 실행하세요.
이번에 배울 내용
시뮬레이터에서 좋은 정책도 물리 계수와 지연이 달라지면 실패할 수 있습니다. 실제 장치로 옮기기 전에 이 차이를 수치로 확인합니다.
Reality gap
물리 계수·센서 잡음·Action 지연·Normalization 차이 때문에 Simulator 정책이 실제 장치에서 달라질 수 있습니다. 한 번에 한 요인을 바꾸어 취약점을 찾습니다.
식별과 Randomization
System identification은 관측으로 모델을 추정하고, Domain randomization은 가능한 변화 범위에서 학습합니다. 평가 범위는 학습 범위와 구분해 설계합니다.
풀이 예제
Motor 기준 모델과 P 제어입니다. Reference Angular Velocity 0.5·1·1.5를 비교합니다.
"""Synthetic motor; not a hardware interface. dt=0.1 s, scalar speed and bounded input."""
import numpy as np
class Motor:
def reset(self, seed=0, reference=1., noise=.01):
self.rng = np.random.default_rng(seed)
self.omega, self.t = 0., 0
self.reference, self.noise = reference, noise
return np.array([self.omega / 5, reference / 2], dtype=np.float32)
def step(self, action):
u = 2 * float(np.clip(np.asarray(action).item(), -1, 1))
self.omega += .1 * (-.4 * self.omega + .8 * u + self.rng.uniform(-self.noise, self.noise))
self.t += 1; error = self.reference - self.omega
reward = -(error**2 + .05 * u**2)
return np.array([self.omega / 5, self.reference / 2], dtype=np.float32), reward, abs(self.omega) > 5, self.t >= 100, {'error': error, 'u': u}
def motor_evaluate(policy, references=(.5, 1., 1.5)):
rows=[]
for reference in references:
env=Motor(); obs=env.reset(100, reference)
errors=[]; inputs=[]; total=0.
while True:
obs,r,terminated,truncated,info=env.step(policy(obs))
errors.append(info['error']);inputs.append(info['u']);total+=r
if terminated or truncated:break
rows.append([reference, np.sqrt(np.mean(np.square(errors))),np.mean(np.square(inputs)),int(terminated),total])
return np.array(rows)
def proportional(obs):return np.clip((2 * obs[1] - 5 * obs[0]), -1, 1)
print('reference / RMSE / mean u² / safety termination / Return')
print(motor_evaluate(proportional))
reference / RMSE / mean u² / safety termination / Return [[ 0.5 0.12626501 0.07338515 0. -1.96121101] [ 1. 0.25292968 0.29432127 0. -7.86894852] [ 1.5 0.3970162 0.6158097 0. -18.84123509]]