์ฝํ ๋ถ์๊ธฐ(Crusher) ์ Isaac Sim โ MuJoCo ๋ง์ด๊ทธ๋ ์ด์
๋ฐ ์ ์ (Tablet) ํ์ ์๋ฎฌ๋ ์ด์
ํตํฉ ์ ์ฅ์์
๋๋ค.
ํ๋ก์ ํธ ๊ฐ์
๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ
๋น ๋ฅธ ์์
๋ณ๊ฒฝ ์ด๋ ฅ
์์กด์ฑ ์ค์น
์ฃผ์ ์ฌํญ
โ
2026-05-29 ์
๋ฐ์ดํธ โ Moving-window stall ๊ฐ์ง ๊ธฐ๋ฐ ์๋ฐฉํฅ ํฌ๋ญํฌ ์ญ์ (CCW โ CW ๋ฐ๋ณต), ์ค์๊ฐ ๋ฒ์ ๋ฐ๋ ฅ ํ๋กฏ (plt.ion()), ํฌ๋ญํฌ ๊ฐ์๋ ํ๋กฏ ์ถ๊ฐ.
โ Crusher + Tablet ์๋ฎฌ๋ ์ด์
๋ฐ๋ก๊ฐ๊ธฐ
๊ตฌ์ฑ ์์
์ค๋ช
Crusher_IsaacSim_description
ROS URDF + Isaac Sim USD ์๋ณธ ๊ธฐ์ ํ์ผ
MuJoCo_PlayGround
Crusher ๋ชจ๋ธ์ MuJoCo(MJCF)๋ก ๋ณํยท์๋ฎฌ๋ ์ด์
tablets_stl
๊ฒฝ๊ตฌ์ (Tablet) ํ์ ํ๋ผ๋ฏธํฐ ๊ธฐ๋ฐ STL ์์ฑยท์๊ฐํยท์ถฉ๋ ๋ถํด
Crusher_IsaacSim/
โ
โโโ README.md โ ์ด ํ์ผ
โโโ requirements.txt โ Python ์์กด์ฑ ๋ชฉ๋ก
โโโ .gitignore โ STL ๋ฐ์ด๋๋ฆฌ ์ ์ธ ์ค์
โ
โโโ Crusher_IsaacSim_description/ โ ROS ํจํค์ง ์๋ณธ
โ โโโ urdf/ โ URDF / xacro / USD ํ์ผ
โ โโโ meshes/ โ ๋ถํ๋ณ STL ๋ฉ์
โ โโโ Code/ โ ๋ณด์กฐ ์คํฌ๋ฆฝํธ (์ง๋/๊ด์ฑ ๊ฒ์ฌ, ์ฌ์ง ๋ฑ)
โ
โโโ CODES/ โ ์ด๊ธฐ Isaac Sim ๋๋ฒ๊ทธ ์คํฌ๋ฆฝํธ ๋ชจ์
โ
โโโ 20260505/ ~ 20260513/ โ ๋ ์ง๋ณ Isaac Sim ์์
์คํฌ๋ฆฝํธ
โ
โโโ MuJoCo_PlayGround/ โ MuJoCo ์๋ฎฌ๋ ์ด์
์์
๊ณต๊ฐ
โ โโโ MJCF/
โ โ โโโ Crusher_IsaacSim.xml โ ๊ธฐ๋ณธ MJCF (์์ ์์)
โ โ โโโ Crusher_IsaacSim_colored.xml โ ์์ + Ground + ํ๋ฃจํ ์ ์ฝ ์์ฑ๋ณธ
โ โ โโโ Ground.stl โ ๋ฐ๋ฅ ๋ฉ์
โ โ โโโ L*.stl / base_link.stl โ ๋ถํ ๋ฉ์ (42๊ฐ)
โ โ
โ โโโ 20260514/ view_mjcf.py โ ์ด๊ธฐ MJCF ๋ก๋
โ โโโ 20260515/ open_crusher.py โ ๊ธฐ๋ณธ XML ๋ทฐ์ด (๊ฒฝ๊ณ ์ต์ ํฌํจ)
โ โโโ 20260518/ โ ์์ ํ์ดํ๋ผ์ธ ์คํฌ๋ฆฝํธ
โ โ โโโ apply_csv_to_mjcf.py โ mesh_colors.csv โ MJCF material ์ ์ฉ
โ โ โโโ extract_materials.py โ USD์์ ์ฌ์ง ์ถ์ถ
โ โ โโโ make_mesh_csv.py โ ๋ฉ์-์์ CSV ์์ฑ
โ โ โโโ fusion360/ โ Fusion 360 appearances.json ๊ธฐ๋ฐ ์ ์ฉ
โ โ
โ โโโ 20260520/
โ โ โโโ open_crusher_colored.py โ โ
์์+Ground XML Python ๋ทฐ์ด (์ ๊ท)
โ โ
โ โโโ 20260527/
โ โ โโโ crusher_tablet_sim.py โ โ
Crusher + Tablet ํตํฉ ์๋ฎฌ๋ ์ด์
(2-Phase)
โ โ
โ โโโ mujoco.bat โ โ
๋๋ธํด๋ฆญ์ผ๋ก ๋ทฐ์ด ์คํ (์๋๊ฒฝ๋ก ์์ )
โ โโโ convert_urdf_to_mjcf.py โ URDF โ MJCF ๋ณํ๊ธฐ
โ
โโโ tablets_stl/ โ ์ ์ ํ์ ๋๊ตฌ ๋ชจ์
โโโ stl/
โ โโโ _tablet_index.csv โ 1000๊ฐ ์ ์ ํ๋ผ๋ฏธํฐ ๋ฉํ๋ฐ์ดํฐ
โ โโโ tablet_R*.stl โ ์์ฑ๋ STL ํ์ผ (git ์ ์ธ)
โ
โโโ Codes/
โโโ viewer_desktop.py โ โ
PyVista 3-์ฌ๋ผ์ด๋ ํ์ ๋ทฐ์ด + MuJoCo ์ฐ๋
โโโ launch_mujoco.py โ โ
STL โ MuJoCo ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์
๋ฐ์ฒ
โโโ collision_viewer.py โ โ
๋ณผ๋ก ๋ถํด 4-๋ชจ๋ ์ถฉ๋ ๋ทฐ์ด
โโโ tablet_generator.py โ Fusion 360 AddIn (๋ก์ปฌ ์คํ ๋ถ๊ฐ, ์ฐธ์กฐ์ฉ)
โโโ viewer.html โ ์น ๊ธฐ๋ฐ STL ๋ธ๋ผ์ฐ์
โโโ start_viewer.bat โ viewer_desktop.py ์คํ ๋ฐฐ์น
โโโ run_collision_viewer.bat โ collision_viewer.py ์คํ ๋ฐฐ์น
โโโ install_and_run.bat โ ์์กด์ฑ ์ค์น + ๋ทฐ์ด ์คํ ๋ฐฐ์น
1. Crusher MuJoCo ๋ทฐ์ด ์คํ
# ๋ฐฉ๋ฒ A โ ๋๋ธํด๋ฆญ (๊ถ์ฅ)
MuJoCo_PlayGround/mujoco.bat
# ๋ฐฉ๋ฒ B โ Python ์คํฌ๋ฆฝํธ
conda activate isaac_sim
python MuJoCo_PlayGround/20260520/open_crusher_colored.py
mujoco.bat์ .py ํ์ผ์ ๊ฒฝ์ ํ์ง ์๊ณ python -m mujoco.viewer --mjcf ๋ช
๋ น์ผ๋ก
์ค์น๋ MuJoCo ํจํค์ง์ CLI ๋ทฐ์ด๋ฅผ ์ง์ ์คํํฉ๋๋ค.
2. ์ ์ ํ์ ๋ทฐ์ด ์คํ
conda activate isaac_sim
python tablets_stl/Codes/viewer_desktop.py
์ฌ๋ผ์ด๋๋ก R / AR / CV ํ๋ผ๋ฏธํฐ ์กฐ์ โ ํ์ ์ค์๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
[MuJoCo์์ ์ด๊ธฐ] ๋ฒํผ โ ์ ํํ STL์ ๋ณ๋ ์ฐฝ์์ ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์
3. ์ถฉ๋ ๋ฉ์ ๋ถํด ๋ทฐ์ด ์คํ
conda activate isaac_sim
python tablets_stl/Codes/collision_viewer.py
4๊ฐ์ง ๋ณด๊ธฐ ๋ชจ๋: ์๋ณธ ๋ฉ์ / ๋ณผ๋ก ๊ป์ง / ๊ฒน์นจ ๋ณด๊ธฐ / ๋ฉด ๋ฒ์
๊ฑฐ์น(8) / ํ์ค(16) / ์ ๋ฐ(32) / ์ต์ ๋ฐ(64) hull ํ๋ฆฌ์
5. Crusher + Tablet ํตํฉ ์๋ฎฌ๋ ์ด์
์คํ
conda activate isaac_sim
python MuJoCo_PlayGround/20260527/crusher_tablet_sim.py < tablet.stl>
# ํ์ผ ์ ํ ๋ค์ด์ผ๋ก๊ทธ๋ก ์คํ
python MuJoCo_PlayGround/20260527/crusher_tablet_sim.py
๋จ๊ณ
๋ด์ฉ
Phase 1 (๋ทฐ์ด ์์, 500 ์คํ
)
lock_crank equality ํ์ฑ (โ90ยฐ ๊ณ ์ ) โ Crusher ๋ฉ์ปค๋์ฆ ์์ ํ
Phase 2 โ ๋๊ธฐ (0 ~ 3 s)
๋ทฐ์ด ์คํ, ๋ชจํฐ OFF. ์์ฝ์ mocap body๋ก ์ถฉ๋ํ ๋ฒฝ๋ฉด์ ๊ณ ์
Phase 2 โ ์์ถ (3 s ~)
lock_crank ํด์ โ Motor CCW โ0.5 Nยทm ๊ตฌ๋ โ ์ฌ๋ผ์ด๋ ์ ์ง, ๋ฒ์ ๋ฐ๋ ฅ ์ธก์
Phase 2 โ ์ญ์ (stall ๊ฐ์ง)
ํฌ๋ญํฌ ๊ฐ์๋ |ฯ| < 0.05 rad/s ๊ฐ 30 step ์ฐ์ โ ๋ฐฉํฅ ์ ํ (CCWโCW ๋ฐ๋ณต)
XML ํ์ผ ์์ โ Crusher_IsaacSim_colored.xml ์ ๋ฉ๋ชจ๋ฆฌ์์ ํ์ฑ, Tablet body ๋
ธ๋๋ฅผ ๋์ ์ฝ์
ํ MjModel.from_xml_string() ์ผ๋ก ์ง์ ๋ก๋
์์ฝ ๊ณ ์ ๋ฐฉ์ โ mocap body โ mocap="true" ์ ์ธ์ผ๋ก MuJoCo๊ฐ ์์ฝ์ ๋ถ๊ฐ์นจ ๊ฐ์ฒด ๋ฒฝ์ผ๋ก ์ธ์. data.mocap_pos / mocap_quat ์ผ๋ก ์์นยท์์ธ ์ ์ด. ๊ดํต ์์
์ ์ด๋ ฅ ์ธก์ โ data.contact + mj_contactForce() โ contact frame โ world frame ๋ณํ. ์์ฝ์ ์์ฉํ๋ ๋ฒ์ ๋ฐ๋ ฅ(F_Y) ์์ง
ํฌ๋ญํฌ ์ ์ด โ lock_crank equality (polycoef=โฯ/2) ๋ฐํ์ ํด์ (data.eq_active), moving-window stall ๊ฐ์ง ๊ธฐ๋ฐ ์๋ฐฉํฅ ์๋ ์ญ์
์์ฝ ์์ธ โ X์ถ 90ยฐ + Y์ถ 90ยฐ ํฉ์ฑ ์ฟผํฐ๋์ธ [0.5, 0.5, 0.5, โ0.5] โ ์ฅ์ถ์ด ์์ง(world-Z) ๋ฐฉํฅ
์ค์๊ฐ ํ๋กฏ โ plt.ion() ๊ธฐ๋ฐ ์ค์๊ฐ F_Y ์ฐฝ์ด ์๋ฎฌ๋ ์ดํฐ์ ๋์ ์
๋ฐ์ดํธ (20 step ๋ง๋ค)
์ถ๋ ฅ โ ์์นยทํยท์ํ์คยท๊ฐ์๋ ๊ทธ๋ํ 5์ข
์ PNG๋ก ์ ์ฅ
์์ฝ ๋ฐฐ์น ์ขํ (MuJoCo world frame)
์ถ
๊ฐ
์๋ฏธ
X
โ47.879 mm
์ถฉ๋ํ ์ค์ฌ ์ ๋ ฌ
Y
336.199 mm
์ถฉ๋ํ(back wall) ๋ฉด์ ๋ฐ์ฐฉ
Z
50.108 mm
์์ง ๋์ด
4. ์ ์ STL ์์ฑ (Fusion 360 ์ ์ฉ)
tablets_stl/Codes/tablet_generator.py ์ฐธ์กฐ.
๋ก์ปฌ์์ ์ง์ ์คํ ๋ถ๊ฐ โ Fusion 360 ๋ด๋ถ AddIn์ผ๋ก๋ง ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
2026-05-29 โ Moving-window ์ญ์ ์๊ณ ๋ฆฌ์ฆ + ์ค์๊ฐ ๋ฐ๋ ฅ ํ๋กฏ
ํญ๋ชฉ
๋ณ๊ฒฝ ์
๋ณ๊ฒฝ ํ
ํฌ๋ญํฌ ์ญ์ ๋ฐฉ์
์ ์ด๋ ฅ ์๊ณ(|F_Y| > 5 N) โ CCWโCW ๋จ๋ฐฉํฅ, ๋ณต๊ท ์์
Moving-window stall ๊ฐ์ง โ ์๋ฐฉํฅ (CCWโCW ๋ฐ๋ณต)
์ญ์ ํธ๋ฆฌ๊ฑฐ ์กฐ๊ฑด
์ ์ด๋ ฅ ํฌ๊ธฐ ๊ธฐ๋ฐ
ํฌ๋ญํฌ ๊ฐ์๋ |ฯ| < 0.05 rad/s 30 step ์ฐ์ ์ ์ง
์ค์๊ฐ ํ๋กฏ
์์ (์๋ฎฌ ์ข
๋ฃ ํ ์ ์ PNG๋ง)
plt.ion() ๊ธฐ๋ฐ F_Y ์ค์๊ฐ ์ฐฝ (20 step ๊ฐ๊ฒฉ ๊ฐฑ์ )
์ถ๋ ฅ ๊ทธ๋ํ
3์ข
(์์น, ํ, XYZ ์ฑ๋ถ)
5์ข
โ ์์น, ํ+์ํ์ค, XYZ ์ฑ๋ถ, ์ค์๊ฐ ์ค๋
์ท , ํฌ๋ญํฌ ๊ฐ์๋
์ฝ์ ์ถ๋ ฅ
์์นยทํยท์ ์ด ์
์์นยทํยท๊ฐ์๋ยทํ์ฌ ๋ฐฉํฅ([CCW]/[CW])
โ Moving-window stall ๊ฐ์ง ๊ธฐ๋ฐ ์๋ฐฉํฅ ์ญ์
STALL_WINDOW = 30 # ์ฐ์ ํ์ ์คํ
์ (0.002 s ร 30 = 0.06 s)
STALL_VEL_THR = 0.05 # ํฌ๋ญํฌ ์๋ ์๊ณ [rad/s]
deque(maxlen=30) โ ์ต์ 30 ์คํ
์ |ฯ| < threshold ๋ถ๋ฆฌ์ธ ๊ธฐ๋ก
all(stall_buf) ๊ฐ True ๋๋ ์๊ฐ motor_dir = -motor_dir ์ ํ, deque ์ด๊ธฐํ
๋ถํธ ๊ท์น: data.ctrl[act_crank] = motor_dir ร MOTOR_CTRL
motor_dir = +1 (CCW) โ ctrl = โ0.5 Nยทm
motor_dir = โ1 (CW) โ ctrl = +0.5 Nยทm
CCWโCW, CWโCCW ๋ชจ๋ ์๋ ์ฒ๋ฆฌ. ์ญ์ ํ์ยท์๊ฐ ์ฝ์ ์ถ๋ ฅ ๋ฐ ํ๋กฏ ๋ง์ปค ๊ธฐ๋ก
โก ์ค์๊ฐ ๋ฒ์ ๋ฐ๋ ฅ ํ๋กฏ (plt.ion())
์๋ฎฌ๋ ์ดํฐ ๋ทฐ์ด์ ๋์์ ๋ณ๋ ์ฐฝ์ผ๋ก F_Y [N] ์ค์๊ฐ ํ์
20 step(0.04 s)๋ง๋ค line_fy.set_data() + ax_rt.relim() + flush_events()
๋ฐฉํฅ ์ ํ ์ด๋ฒคํธ ์์ง์ (axvline)์ ์ค์๊ฐ ๊ฐฑ์
์๋ฎฌ ์ข
๋ฃ ํ crusher_tablet_realtime_force.png ๋ก ์ ์ฅ
โข ํฌ๋ญํฌ ๊ฐ์๋ ํ๋กฏ ์ถ๊ฐ (๊ทธ๋ฆผ 4)
data.qvel[crank_vadr] ๋ก๊ทธ๋ฅผ ์๊ฐ ์ถ์ผ๋ก ํ์
stall ์๊ณ์ ยฑSTALL_VEL_THR ์ํ์ ํ์
๋ฐฉํฅ ์ ํ ์ด๋ฒคํธ ์์ง์ ๋๊ธฐํ
ํ์ผ
์์ ๋ด์ฉ
MuJoCo_PlayGround/20260527/crusher_tablet_sim.py
v5 โ moving-window ์ญ์ , ์ค์๊ฐ ํ๋กฏ, ๊ฐ์๋ ํ๋กฏ, ๋ค์ค ์ญ์ ์ด๋ฒคํธ ์ถ์
2026-05-28 โ ์์ฝ ๋ฌผ๋ฆฌ ๊ณ ์ ๋ฐฉ์ ์ ํ ๋ฐ ๋ฐ๋ ฅ ์ธก์ ํ์ดํ๋ผ์ธ ์์ฑ
ํญ๋ชฉ
๋ณ๊ฒฝ ์
๋ณ๊ฒฝ ํ
์์ฝ ๊ณ ์ ๋ฐฉ์
freejoint + ๋งค ์คํ
qpos/qvel ๋ฎ์ด์ฐ๊ธฐ (kinematic hold)
mocap="true" body โ ๊ดํต ์๋ ๋ถ๊ฐ์นจ ๊ฐ์ฒด ๋ฒฝ
์ ์ด๋ ฅ ์ธก์
cfrc_ext (๋ถ์ ํ, ์ ๋ น body ๋ฌธ์ )
data.contact + mj_contactForce() โ world frame ๋ณํ
ํฌ๋ญํฌ ์ด๊ธฐ ๊ฐ๋
+90ยฐ
โ90ยฐ
๋ชจํฐ ๋ฐฉํฅ
CW (+0.5 Nยทm)
CCW (โ0.5 Nยทm) , 3์ด ์ง์ฐ ํ ๊ตฌ๋
ํฌ๋ญํฌ ์ญ์ ํธ๋ฆฌ๊ฑฐ
gap ๊ธฐ๋ฐ (์ฌ๋ผ์ด๋ ์์น) โ ๋ฒฝ ์ ์ด ์ ๊ณ ์ฐฉ์ผ๋ก ๋์ ์ ๋จ
์ ์ด๋ ฅ ๊ธฐ๋ฐ `
์์ฝ ์์ธ
X์ถ 90ยฐ (๋ํ)
X์ถ 90ยฐ + Y์ถ 90ยฐ ํฉ์ฑ โ ์ธ๋ก(์์ง) ๋ฐฉํฅ
โ mocap body ์ ํ (๊ดํต ๋ฌธ์ ํด๊ฒฐ)
freejoint ๋ฐฉ์์์๋ MuJoCo contact solver๊ฐ ๋ถ๋ฆฌ impulse๋ฅผ ๊ณ์ฐํด๋ ๋งค ์คํ
qpos๋ฅผ ๋ฎ์ด์จ์ ์ฌ๋ผ์ด๋๊ฐ ์์ฝ์ ๊ดํตํ๋ ๋ฌธ์ ๋ฐ์
mocap="true" body๋ ๋ฌผ๋ฆฌ ์์ง์ด ์ง์ ๋ถ๊ฐ์นจ ๊ฐ์ฒด๋ก ์ทจ๊ธ โ ์ฌ๋ผ์ด๋๊ฐ ์์ฝ์ ๋ฐ์ด๋ด๊ณ ์์ฝ์ ๊ณ ์ ์ ์ง
์์นยท์์ธ ์ ์ด: data.mocap_pos[mocap_id], data.mocap_quat[mocap_id]
โก lock_crank equality ๋ฐํ์ ํ ๊ธ
Crusher_IsaacSim_colored.xml ์ lock_crank (polycoef=โ1.5708, solref=โ100000) ๋ก Phase 1์์ ํฌ๋ญํฌ๋ฅผ โ90ยฐ์ ๊ณ ์
Phase 2 ์์ 3์ด ํ data.eq_active[eq_lock_id] = 0 ์ผ๋ก ํด์ โ ๋ชจํฐ CCW ๊ตฌ๋
โข ์ ์ด๋ ฅ ๊ธฐ๋ฐ ํฌ๋ญํฌ ์ญ์
๊ธฐ์กด gap ๊ธฐ๋ฐ: ์ฌ๋ผ์ด๋๊ฐ mocap ๋ฒฝ์ ๋งํ๋ฉด gap์ด ์ต์๊ฐ์ ๊ณ ์ฐฉ โ elif gap > min + 0.5mm ์กฐ๊ฑด ์์ํ ๋ถ์ถฉ์กฑ
์์ : |F_Y| > REVERSE_F_THRESHOLD (5 N) ์ด๊ณผ ์์ ์ ctrl = +0.5 Nยทm (CW) ์ญ์
์ญ์ ์๊ฐ, ์ ์ด๋ ฅ, gap ๊ฐ์ ์ฝ์ ์ถ๋ ฅ ๋ฐ ํ๋กฏ ๋ง์ปค๋ก ๊ธฐ๋ก
โฃ ๋ฒ์ ๋ฐ๋ ฅ ํ๋กฏ ๊ฐ์
F_Y ๊ทธ๋ํ ๋ ์ด๋ธ์ "Normal Contact Force (World-Y)" ๋ก ๋ช
ํํ
๋ชจํฐ ON ์๊ฐ, ํฌ๋ญํฌ ์ญ์ ์๊ฐ์ ์์ง์ (axvline)์ผ๋ก ํ์
์์ถ(์)/์ธ์ฅ(์) ๊ตฌ๊ฐ fill_between ์ ๊ตฌ๋ถ
โค Tablet Shape Viewer ๋จ์ถํค ํจ๋ ์ถ๊ฐ
viewer_desktop.py ์ข์ธก ํจ๋ ํ๋จ์ PyVista ๋จ์ถํค ์น์
์ถ๊ฐ
๋ง์ฐ์ค ์กฐ์ / ๋ ๋๋ง(W ์์ด์ดํ๋ ์ โ
) / ์นด๋ฉ๋ผ / ๊ธฐํ 4๊ฐ ์น์
ํ์ผ
์์ ๋ด์ฉ
MuJoCo_PlayGround/20260527/crusher_tablet_sim.py
mocap body, lock_crank ํ ๊ธ, CCW ๋ชจํฐ, ์ญ์ ๋ก์ง, ๋ฒ์ ๋ฐ๋ ฅ ํ๋กฏ
MuJoCo_PlayGround/MJCF/Crusher_IsaacSim_colored.xml
lock_crank polycoef โ1.5708 ๋ณต์
tablets_stl/Codes/viewer_desktop.py
PyVista ๋จ์ถํค ํจ๋ ์ถ๊ฐ
2026-05-27 โ Crusher + Tablet ํตํฉ ์๋ฎฌ๋ ์ด์
์์ฑ
ํ์ผ
๋ด์ฉ
MuJoCo_PlayGround/20260527/crusher_tablet_sim.py
Crusher XML + Tablet STL์ ๋ฉ๋ชจ๋ฆฌ์์ ์กฐํฉํด 2-Phase ํตํฉ ์๋ฎฌ๋ ์ด์
์คํ. Phase 1(๋ฉ์ปค๋์ฆ ์์ ํ) โ Phase 2(์์ฝ ๊ณ ์ + ์ ์ด๋ ฅ ์ธก์ + ๊ทธ๋ํ ์ ์ฅ)
ํญ๋ชฉ
๋ด์ฉ
์์ฝ ๊ณ ์ ๋ฐฉ์
freejoint(6์์ ๋) + ๋งค ์คํ
kinematic hold (qpos/qvel ๋ฎ์ด์ฐ๊ธฐ) โ ์์ฝ์ ๊ณต๊ฐ์ ๊ณ ์ ํ๋ฉด์ cfrc_ext ์ ์ด ๋ฐ๋ ฅ ์ธก์ ๊ฐ๋ฅ
์์ฝ ๋ฐฐ์น
Y ์ขํ๋ฅผ WALL_Y_MM(336.199 mm)์ผ๋ก ์ค์ โ ์ถฉ๋ํ ๋ฒฝ๋ฉด์ ์ค์ฌ ๋ฐ์ฐฉ
MJCF ๊ตฌ์ฑ
๋ณ๋ XML ํ์ผ ์์ โ ๊ธฐ์กด Crusher XML์ ๋ฉ๋ชจ๋ฆฌ์์ ํ์ฑ ํ Tablet body / sensor ๋
ธ๋ ๋์ ์ฝ์
๋ทฐ์ด site ๊ตฌ ์ ๊ฑฐ
sitegroup ์ ์ฒด False โ ์ค์ฌ๋ถ ๊ตฌ ํํ gizmo ๋นํ์
2026-05-26 โ Crank-Slider ๋ฉ์ปค๋์ฆ ์ง๋จ ๋ฐ ์ขํ๊ณ ๋ถ์
ํญ๋ชฉ
๋ด์ฉ
Equality Constraint ํ์
์ค๋ฅ
connect๋ ์์น(3-DOF)๋ง ๊ตฌ์ โ L7-L8 ์ฌ์ด ํ์ ์์ ๋ ๋ฏธ๊ตฌ์์ผ๋ก ์ง๋ ๋ฐ์. weld(์์น+๋ฐฉํฅ ์์ ๊ณ ์ )๋ก ๊ต์ฒด ํ์
Constraint Gap ์์ธ ๋ถ์
anchor=0.027 ์ค์ ์ L8 body์ 10 mm ๊ฐญ ๋ฐ์ โ ์ ์ฝ๋ ฅ 500 N (์ค๋ ฅ 12.7 N์ 39๋ฐฐ ) โ CCW ๋น์ ์ ํ์ ์ ๋ฐ
ํฌ๋ญํฌ ํ์ ์ถ ์คํด
XML axis="0 0 1" (body local Z) + quat="0.5 0.5 0.5 0.5" โ ์ค์ world ํ์ ์ถ = [1, 0, 0] (world X) . ์ค๋ ฅ(-Z)๊ณผ ์์ง์ด๋ฏ๋ก ์ต๋ ํ ํฌ ๋ฐ์
MuJoCo ์ขํ๊ณ ๋ณํ
quat="0.5 0.5 0.5 0.5" โ R=[[0,0,1],[1,0,0],[0,1,0]] : URDF XโMuJoCo Y, URDF YโMuJoCo Z, URDF ZโMuJoCo X
ํ์ผ
๋ด์ฉ
MuJoCo_PlayGround/20260526/coordinate_gizmo.py
MuJoCo ์๋ ์ขํ๊ณ(XYZ ๊ธฐ์ฆ๋ชจ) ํ์ธ ์คํฌ๋ฆฝํธ. ๋ทฐ์ด ์์ ์ body frame ํ์
MuJoCo_PlayGround/20260526/open_urdf.py
์๋ณธ URDF๋ฅผ MuJoCo๋ก ์ง์ ๋ก๋ํด ๊ฐ body ์๋ ์์นยทjoint ๋ชฉ๋ก ์ถ๋ ฅ ๋ฐ ๋ทฐ์ด ์คํ
MJCF ์์ ์ด๋ ฅ (Crusher_IsaacSim_colored.xml)
์์
๋ด์ฉ
L5-L6, L6-L7 hinge damping ์ถ๊ฐ
damping="0.5" โ ์ด๊ธฐ ๋ถ์์ ์ง๋ ์ต์
L8 slide joint damping ์ถ๊ฐ
damping="5"
L8_Link3_Shaft_1 body pos ์์
Rigid32 ์ ํฉ ์์น = (-0.048302, 0.236278, 0.049431) (URDF ์ค์ธก ๊ฒ์ฆ ์๋ฃ)
Equality Constraint anchor
URDF Rigid32 joint xyz=(0.037, 0, -0.005) ๊ธฐ์ค. ๋ค์ ๋จ๊ณ: connect โ weld ๊ต์ฒด ์์
๋ทฐ์ด ์ค์
mjVIS_CONVEXHULL=False, geomgroup[3]=False โ visual mesh ์ ์ฉ ํ์
2026-05-21 โ macOS ํธํ์ฑ ์์ ๋ฐ tablet_generator Fusion 360 ๋ฑ๋ก
ํ์ผ
๋ณ๊ฒฝ ๋ด์ฉ
tablets_stl/Codes/viewer_desktop.py
subprocess.CREATE_NEW_CONSOLE (Windows ์ ์ฉ) โ platform.system() ๊ฐ์ง ํ ์กฐ๊ฑด๋ถ ์ ์ฉ์ผ๋ก macOS ํธํ ์์
tablets_stl/stl/_tablet_index.csv
Fusion 360 tablet_generator AddIn ์คํ์ผ๋ก ์ ์ STL 1,000๊ฐ ์์ฑ ๋ฐ ์ธ๋ฑ์ค ๊ฐฑ์
2026-05-20 โ MuJoCo ํตํฉ ์์ฑ ๋ฐ ๊ตฌ์กฐ ์ ๋ฆฌ
ํ์ผ
๋ณ๊ฒฝ ๋ด์ฉ
mujoco.bat
ํ๋์ฝ๋ฉ๋ ์ ๋๊ฒฝ๋ก โ %~dp0 ๊ธฐ๋ฐ ์๋๊ฒฝ๋ก๋ก ์ ๋ฉด ์์ ; conda ํ์ฑํ ๊ฒฝ๋ก๋ %USERPROFILE% ๋ณ์๋ก ํฌํฐ๋ธํ
20260520/open_crusher_colored.py
์ ๊ท โ Crusher_IsaacSim_colored.xml(Ground.stl ํฌํจ)์ Python API(mujoco.viewer.launch)๋ก ์ฌ๋ ์คํฌ๋ฆฝํธ; __file__ ๊ธฐ์ค ์๋๊ฒฝ๋ก ์ฌ์ฉ
ํ์ผ
๋ณ๊ฒฝ ๋ด์ฉ
Codes/viewer_desktop.py
[MuJoCo์์ ์ด๊ธฐ] ๋ฒํผ ์ถ๊ฐ; STL ๋ก๋ ์ฑ๊ณต ์ ํ์ฑํ, subprocess.Popen์ผ๋ก ๋น์ฐจ๋จ ์คํ
Codes/launch_mujoco.py
์ ๊ท โ ์ ํ๋ STL์ ๋ฉ๋ชจ๋ฆฌ ๋ด MJCF๋ก ๋ณํ(from_xml_string + assets), ๋ฌผ๋ฆฌ ํ๋ผ๋ฏธํฐ(๋ฐ๋ 1200 kg/mยณ, ๋ง์ฐฐ 0.5) ์ค์ ํ ๋ทฐ์ด ์คํ
Codes/launch_mujoco.py
๋ฒ๊ทธ ์์ โ _print_params() ์ ๊ท์์ด ํ์ผ๋ช
์ .stl ํ์ฅ์๊น์ง ์บก์ฒํ์ฌ float('0.20.') ์ค๋ฅ ๋ฐ์ โ os.path.splitext() ๋ก ํ์ฅ์ ์ ๊ฑฐ ํ ์ ๊ท์ ์ ์ฉ
Codes/collision_viewer.py
์ ๊ท โ ๋ณผ๋ก ๋ถํด(CoACD โ VHACD โ single hull fallback) ๋
๋ฆฝ ๋ทฐ์ด; 4-๋ชจ๋ ์๊ฐํ
ํ์ผ
๋ณ๊ฒฝ ๋ด์ฉ
requirements.txt
์ ๊ท โ ๊ทธ๋ฃน๋ณ ์์กด์ฑ ์ ๋ฆฌ (์์น์ฐ์ฐ / 3D์๊ฐํ / ๋ฉ์์ฒ๋ฆฌ / MuJoCo / JAX / ์ด๋ฏธ์ง์ฒ๋ฆฌ); ๋นpip ํจํค์ง(Isaac Sim, Fusion 360, Blender) ์ค์น ์๋ด ์ฃผ์ ํฌํจ
.gitignore
์ ๊ท โ tablets_stl/stl/*.stl, tablets_stl/collision/*.stl ๋ฐ์ด๋๋ฆฌ ์ ์ธ; Python ์บ์ ์ ์ธ
2026-05-18 โ Crusher ์์ ํ์ดํ๋ผ์ธ ์์ฑ
๋ณ๊ฒฝ ๋ด์ฉ
Fusion 360 appearance JSON ์ถ์ถ ์คํฌ๋ฆฝํธ (extract_appearance.py)
mesh_colors.csv ๊ธฐ๋ฐ MJCF material ์๋ ์ ์ฉ (apply_csv_to_mjcf.py) โ RGB 0-255 โ 0-1 ๋ณํ, ์กฐ๋ช
3๊ฐ ์๋ ์ถ๊ฐ
Crusher_IsaacSim_colored.xml ์์ฑ โ ์์ยท์กฐ๋ช
ยทGround.stlยทCrank-slider ํ๋ฃจํ equality constraintยทMotor1_crank ์ก์ถ์์ดํฐยทL1_Slider_jig ํ๋ฆฌ์ฆ๋งคํฑ ์กฐ์ธํธ ํฌํจ
2026-05-15 โ MuJoCo ์ด๊ธฐ ๋ง์ด๊ทธ๋ ์ด์
๋ณ๊ฒฝ ๋ด์ฉ
URDF โ MJCF ๋ณํ (convert_urdf_to_mjcf.py)
๊ธฐ๋ณธ ๋ทฐ์ด ์คํฌ๋ฆฝํธ 20260515/open_crusher.py (MuJoCo UserWarning ์ต์ )
2026-05-05 ~ 2026-05-13 โ Isaac Sim ๋๋ฒ๊ทธ ๋ฐ ๊ด์ ์ค์
์์
๊ตฌ๋๋ถ ๊ด์ (Drive, Prismatic, Mimic) ์ค์ ๋ฐ ์ง๋จ ์คํฌ๋ฆฝํธ
Rack-and-Pinion ๊ธฐ์ด ์ฐ๊ฒฐ ๋๋ฒ๊ทธ
CoACD ์ถฉ๋ ๋ฉ์ ์ต์ ํ
์ง๋/๊ด์ฑ ํ
์ ๊ฒ์ฌ ๋ฐ ์์
conda activate isaac_sim
pip install -r requirements.txt
โ ๏ธ ์๋ ํจํค์ง๋ pip์ผ๋ก ์ค์น๋์ง ์์ต๋๋ค.
Isaac Sim (omni.*, carb, pxr) โ NVIDIA Isaac Sim ์ค์น ์ ๋ฒ๋ค ์ ๊ณต
Fusion 360 API (adsk) โ Autodesk Fusion 360 ๋ด๋ถ ์คํ ์ ์ฉ
Blender Python (bpy) โ Blender ๋ด๋ถ ์คํ ์ ์ฉ
STL ๋ฐ์ด๋๋ฆฌ (tablets_stl/stl/*.stl) ๋ .gitignore์ ์ํด Git์์ ์ ์ธ๋ฉ๋๋ค.
STL ํ์ผ์ Fusion 360 AddIn(tablet_generator.py)์ผ๋ก ๋ก์ปฌ์์ ์์ฑํ์ธ์.
tablet_generator.py๋ adsk ๋ชจ๋ ์์กด์ฑ์ผ๋ก ์ธํด Fusion 360 ์ธ๋ถ์์ ์คํ ๋ถ๊ฐ ํฉ๋๋ค.
ํ์ผ ๋ด ์ฃผ์์ ์ค์น ๊ฒฝ๋ก ์๋ด๋ฅผ ๋ฐ๋ฅด์ธ์.
MuJoCo STL ๋จ์๋ mm โ m ์๋ ๋ณํ (scale 0.001)์ด ์ ์ฉ๋ฉ๋๋ค.
Fusion 360 ๊ธฐ๋ณธ STL ๋ด๋ณด๋ด๊ธฐ ๋จ์๊ฐ mm์ด๊ธฐ ๋๋ฌธ์
๋๋ค.