Mujoco documantation: https://mujoco.readthedocs.io/en/stable/overview.html
링크: https://github.com/google-deepmind/mujoco?tab=readme-ov-file
pip install mujoco
import mujoco
로 패키지 불러옴
Mujoco는 메모리에 직접 접근해서 데이터 가져오려면 copy()를 써야함. 아님 overwrite됨.
positions.append(data.body('my_body').xpos.copy())
구조체(Struct)는 시뮬레이터의 모든 핵심 데이터 담고 있는 컨테이너 - 물리엔진이 어떤 물체가 있고, 어떤 상태이며, 어떤 힘 받고 있고, 어떤 결과를 냈는가 정보를 관리
| 대표 구조체 | 주요역할 | 설명 |
|---|---|---|
| MjModel | 정적 모델 구조 | XML에서 읽은 모델구조 |
| MjData | 동적 상태 | 시뮬에서 진행되며 계속 업데이트 되는 데이터 (Ex) 위치, 속도, 힘, 센서값..) mj_step(model, data)가 실행될 때마다 구조체 값 바뀜 |
| MjvScene | 시각화용 장면 데이터 | geometry, camera, light 등 렌더링할 때 사용할 그래픽 요소 |
| MjCamera | 카메라 설정 정보 | 뷰어나 렌더러에서 사용할 카메라 위치, 방향,줌 정보 |
| MjvOption / MjOption | 시뮬레이션 설정 옵션 | 중력, 마찰, 시뮬 정확도 등 환경 설정 |
| MjrContext | 렌더링 컨텍스트 | OpenGL 등 그래픽스 관련 리소스 관리 |
| MjvFigure / MjvPerturb 등 | 시각화 또는 디버깅용 부가 구조체 | 그래프 출력, 마우스로 물체잡기 등 인터렉티브 작업에 사용 |
mujoco.MjOption
처럼 구조체 실행하고, default 인스턴스 만들어짐
mujoco.MjvScene(model, maxgeom=10)
처럼 객체 만들수 있고, 파이썬 객체가 삭제될 때, 자동으로 리로스 해제됨
예외
mujoco.MjModel.from_xml_string(xml_str) # 문자열로 된 XML 모델을 읽어들여 생성
mujoco.MjModel.from_xml_path("path/to/model.xml") # XML 파일 경로를 통해 생성
mujoco.MjModel.from_binary_path("path/to/model.mjb") # 바이너리 모델 파일(MLB) 통해 생성
C함수들이 그대로 파이썬에서 포팅 가능
C에서 배열 받는 함수들은 NumPy나 list로 가능
Python 바인딩에서 자주 반복 호출되는 mj_step() 을 위해 nstep 인자를 지원함
# (1) GIL을 한 번만 해제하고 20 스텝 실행 - 동시에 멀티 스레드 가능하다는 뜻
mujoco.mj_step(model, data, nstep=20)
function과 enum은 나중에 필요할때마다 서치 - 지금은 그닥 정리 필요 없어보임
XML 파일에서 body, joint, geom, sensor등 name이 붙음. 모델이 mjModel 인스턴스로 변환되면 내부적으로 정수 ID로 매핑되어 각 배열(qpos, geom_rgba)에 접근 가능
"Named Access API 으로 제공
import mujoco
# 모델과 데이터 불러오기
model = mujoco.MjModel.from_xml_path("robot.xml")
data = mujoco.MjData(model)
# geom 이름으로 접근
geom = model.geom('gizmo')
# RGBA 색상 접근 (NumPy view)
print(geom.rgba) # == model.geom_rgba[4*i:4*i+4]
# ID와 이름
print(geom.id) # == mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_GEOM, 'gizmo')
print(model.geom(geom.id).name) # == 'gizmo'
자세한 건 documentation 확인
파이프라인 중 사용자 코드 실행을 위한 콜백함수 제공 -> 시뮬레이션 중간에 Mujoco의 내부 계산 흐름에 직접 개입 가능
| 동작 | 함수 예시 | 설명 |
|---|---|---|
| 콜백 등록 | mujoco.set_mjcb_foo(func) | 특정 콜백에 Python 함수(func)를 연결 |
| 콜백 해제 | mujoco.set_mjcb_foo(None) | 등록된 콜백을 제거 |
| 현재 콜백 확인 | mujoco.get_mjcb_foo() | 현재 설정된 콜백 반환 (단, Python에서 등록된 경우만 안전함) |
주요 Callbacks
| 콜백 이름 | 역할 |
|---|---|
mjcb_sensor | 사용자 정의 센서 계산 |
mjcb_control | 사용자 정의 제어기 (actuator 출력 정의) |
mjcb_time | 사용자 정의 시간 제어 |
mjcb_passive | 수동(passive) 힘 계산 |
mjcb_contactfilter | 충돌(contact) 처리 필터 |
mjcb_act_dyn | actuator dynamics 정의 |
mjcb_act_gain | actuator gain 함수 |
mjcb_act_bias | actuator bias 함수 |
mjcb_user_warning | 사용자 정의 경고 메시지 출력 |
*파이썬으로 실험하고 C라이브러리로 포팅해서 최적화 가능
from ctypes import CDLL
import mujoco
lib = CDLL("my_custom_callbacks.so")
mujoco.set_mjcb_control(lib.my_control)
이 방식은 python의 GIL 건드리지 않고 바로 C 레벨에서 실행해서 속도 저하 없고, 실시간 제어용으로 적합함
이 파트에서는 XML파일을 수정하지 않고, Mujoco에서 파일을 포팅한 후 따로 수정하는 방법 소개
-> 자세한 건 documentation 보기