Skip to main content Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/MIUAV/vibe-coding-ros2 --skill mujocoThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository Related occupations SOC
Based on SOC occupation classification
name mujoco description MuJoCo 物理仿真开发技能 - 高性能物理引擎、强化学习环境、MJCF 模型、GPU 加速 argument-hint mujoco仿真 OR 强化学习 OR MJCF模型 OR 机器人控制 user-invocable true
MuJoCo Physics Simulation Skill
用于 MuJoCo 物理仿真环境的配置和开发
何时使用
当需要以下帮助时使用此技能:
安装和配置 MuJoCo
创建 MJCF 模型
编写强化学习环境
使用 GPU 加速
集成 ROS
快速参考
安装 MuJoCo
pip install mujoco-py
pip install mujoco
基本使用
import mujoco
import mujoco.viewer as viewer
model = mujoco.MjModel.from_xml_path("robot.xml" )
data = model.data
v = viewer.launch_passive(model, data)
for _ in range (1000 ):
mujoco.mj_step(model, data)
v.sync()
MJCF 模型
基本结构
<mujoco model ="my_robot" >
<compiler angle ="radian" meshdir ="meshes" autolimits ="true" />
<option timestep ="0.002" integrator ="Euler" iterations ="50" tolerance ="1e-10" />
<global >
<gravity gravity ="0 0 -9.81" />
<wind wind ="0 0 0" />
<density density ="1.0" />
<viscosity viscosity ="0.0" />
</global >
<worldbody >
<geom type ="plane" size ="10 10 0.1" rgba ="0.5 0.5 0.5 1" friction ="0.4 0.005 0.0001" />
完整机器人示例 - 双足机器人
<mujoco model ="biped_robot" >
<compiler angle ="radian" meshdir ="meshes" autolimits ="true" />
<option timestep ="0.002" iterations ="100" solver ="Newton" gravity ="0 0 -9.81" />
<worldbody >
<body name ="torso" pos ="0 0 1.0" >
<freejoint />
<inertial pos ="0 0 0" mass ="8" diaginertia ="0.1 0.08 0.08" />
<geom type ="capsule" size ="0.07 0.2" rgba ="0.4 0.4 0.4 1" friction ="0.5" />
<body name ="head" pos ="0 0 0.25" >
<inertial pos = = = />
强化学习环境
使用 Gymnasium
import gymnasium as gym
from gym import spaces
import numpy as np
class MuJoCoEnv (gym.Env):
def __init__ (self, model_path="robot.xml" ):
super ().__init__()
self .model = mujoco.MjModel.from_xml_path(model_path)
self .data = self .model.data
self .action_space = spaces.Box(
low=-1 , high=1 ,
shape=(self .model.nu,),
dtype=np.float32
)
self .observation_space = spaces.Box(
low=-np.inf, high=np.inf,
shape=(self .model.nq + self .model.nv + self .model.nu,),
dtype=np.float32
)
def reset (self, seed=None , options=None ):
mujoco.mj_resetData(self .model, self .data)
obs = self ._get_obs()
return obs, {}
def step (self, action ):
self .data.ctrl[:] = action
mujoco.mj_step( .model, .data)
obs = ._get_obs()
reward = ._compute_reward()
done = ._is_done()
obs, reward, done, , {}
( ):
np.concatenate([
.data.qpos,
.data.qvel,
.data.ctrl
])
( ):
( ):
( ):
使用 DM Control
from dm_control import suite
import numpy as np
env = suite.load(domain_name="walker" , task_name="run" )
action_spec = env.action_spec()
observation_spec = env.observation_spec()
time_step = env.reset()
while not time_step.last():
action = np.random.uniform(action_spec.minimum, action_spec.maximum)
time_step = env.step(action)
print (f"Reward: {time_step.reward} " )
控制器
PD 控制器
def pd_control (model, data, kp=1.0 , kd=0.5 ):
"""PD 控制器"""
q_des = np.zeros(model.nq)
qdot_des = np.zeros(model.nv)
q_error = q_des - data.qpos
qdot_error = qdot_des - data.qvel
ctrl = kp * q_error + kd * qdot_error
return ctrl
阻抗控制
def impedance_control (model, data, target_pos, k_p=100 , k_d=10 ):
"""阻抗控制器"""
current_pos = data.body_xpos[-1 ]
error = target_pos - current_pos
f = k_p * error - k_d * data.cvel
ctrl = np.zeros(model.nu)
return ctrl
GPU 加速
GPU 仿真
print (mujoco.get_platform())
model = mujoco.MjModel.from_xml_path("robot.xml" ,
nthread=4 ,
nsubsteps=2 )
并行环境
from dm_control import composer
from dm_control import suite
env = suite.load(domain_name="cartpole" ,
task_name="balance" ,
visualize_reward=False )
for _ in range (1000 ):
action = env.action_spec().sample()
time_step = env.step(action)
传感器
读取传感器数据
qpos = data.qpos
qvel = data.qvel
qfrc = data.qfrc
end_effector_pos = data.body_xpos[-1 ]
contact_force = data.eforce
for i in range (model.ncon):
contact = data.contact[i]
ROS 集成
ROS2 控制器
import rclpy
from rclpy.node import Node
import mujoco
class MuJoCoROS2 (Node ):
def __init__ (self ):
super ().__init__('mujoco_ros2' )
self .model = mujoco.MjModel.from_xml_path('/path/to/robot.xml' )
self .data = self .model.data
self .create_subscription(
Float64MultiArray,
'/joint_commands' ,
self .cmd_callback,
10 )
self .timer = self .create_timer(0.002 , self .step_callback)
def cmd_callback (self, msg ):
self .data.ctrl[:] = msg.data
def step_callback (self ):
mujoco.mj_step(self .model, self .data)
常见问题
问题 1: 模型不稳定
解决方案 :
增加 solver iterations
调整 timestep
检查质量分布
问题 2: 仿真速度慢
解决方案 :
问题 3: 碰撞检测失败
解决方案 :
检查 geom 类型
调整碰撞容差
使用正确的摩擦系数
相关资源
另见
<light pos ="0 0 5" dir ="0 0 -1" diffuse ="0.8 0.8 0.8" specular ="0.3 0.3 0.3" />
</worldbody >
<actuator >
<motor joint ="shoulder" ctrllimited ="true" ctrlrange ="-50 50" gear ="100" />
</actuator >
</mujoco >
"0 0 0"
mass
"1.5"
diaginertia
"0.01 0.01 0.01"
<geom type ="sphere" size ="0.1" rgba ="0.6 0.6 0.6 1" />
<camera name ="eye" pos ="0.05 0 0.05" fovy ="90" />
</body >
<body name ="left_hip" pos ="0 0.1 -0.2" >
<joint name ="hip_flexion" type ="hinge" axis ="1 0 0" range ="-90 90" damping ="0.1" />
<inertial pos ="0 0 -0.1" mass ="2" diaginertia ="0.02 0.01 0.02" />
<geom type ="capsule" size ="0.04 0.2" rgba ="0.3 0.3 0.3 1" />
<body name ="left_knee" pos ="0 0 -0.2" >
<joint name ="knee" type ="hinge" axis ="1 0 0" range ="-150 0" damping ="0.1" />
<inertial pos ="0 0 -0.1" mass ="1.5" diaginertia ="0.015 0.01 0.015" />
<geom type ="capsule" size ="0.035 0.2" rgba ="0.35 0.35 0.35 1" />
<body name ="left_foot" pos ="0 0 -0.2" >
<joint name ="ankle" type ="hinge" axis ="1 0 0" range ="-45 45" damping ="0.05" />
<inertial pos ="0 0 -0.05" mass ="0.5" diaginertia ="0.005 0.003 0.005" />
<geom type ="box" size ="0.06 0.04 0.02" rgba ="0.2 0.2 0.2 1" friction ="1.0 0.005 0.0001" />
</body >
</body >
</body >
<body name ="right_hip" pos ="0 -0.1 -0.2" >
<joint name ="hip_flexion" type ="hinge" axis ="1 0 0" range ="-90 90" damping ="0.1" />
<inertial pos ="0 0 -0.1" mass ="2" diaginertia ="0.02 0.01 0.02" />
<geom type ="capsule" size ="0.04 0.2" rgba ="0.3 0.3 0.3 1" />
<body name ="right_knee" pos ="0 0 -0.2" >
<joint name ="knee" type ="hinge" axis ="1 0 0" range ="-150 0" damping ="0.1" />
<inertial pos ="0 0 -0.1" mass ="1.5" diaginertia ="0.015 0.01 0.015" />
<geom type ="capsule" size ="0.035 0.2" rgba ="0.35 0.35 0.35 1" />
<body name ="right_foot" pos ="0 0 -0.2" >
<joint name ="ankle" type ="hinge" axis ="1 0 0" range ="-45 45" damping ="0.05" />
<inertial pos ="0 0 -0.05" mass ="0.5" diaginertia ="0.005 0.003 0.005" />
<geom type ="box" size ="0.06 0.04 0.02" rgba ="0.2 0.2 0.2 1" friction ="1.0 0.005 0.0001" />
</body >
</body >
</body >
<body name ="left_shoulder" pos ="0.15 0 0.15" >
<joint name ="shoulder_flexion" type ="hinge" axis ="0 0 1" range ="-180 180" damping ="0.05" />
<inertial pos ="0 0 0" mass ="0.8" diaginertia ="0.005 0.005 0.002" />
<geom type ="capsule" size ="0.025 0.15" rgba ="0.4 0.4 0.4 1" />
<body name ="left_elbow" pos ="0 0 -0.15" >
<joint name ="elbow" type ="hinge" axis ="0 0 1" range ="-150 0" damping ="0.05" />
<inertial pos ="0 0 0" mass ="0.5" diaginertia ="0.003 0.003 0.001" />
<geom type ="capsule" size ="0.02 0.12" rgba ="0.45 0.45 0.45 1" />
</body >
</body >
<body name ="right_shoulder" pos ="0.15 0 0.15" >
<joint name ="shoulder_flexion" type ="hinge" axis ="0 0 1" range ="-180 180" damping ="0.05" />
<inertial pos ="0 0 0" mass ="0.8" diaginertia ="0.005 0.005 0.002" />
<geom type ="capsule" size ="0.025 0.15" rgba ="0.4 0.4 0.4 1" />
<body name ="right_elbow" pos ="0 0 -0.15" >
<joint name ="elbow" type ="hinge" axis ="0 0 1" range ="-150 0" damping ="0.05" />
<inertial pos ="0 0 0" mass ="0.5" diaginertia ="0.003 0.003 0.001" />
<geom type ="capsule" size ="0.02 0.12" rgba ="0.45 0.45 0.45 1" />
</body >
</body >
</body >
</worldbody >
<actuator >
<motor joint ="hip_flexion" ctrllimited ="true" ctrlrange ="-50 50" gear ="50" />
<motor joint ="knee" ctrllimited ="true" ctrlrange ="-30 30" gear ="30" />
<motor joint ="ankle" ctrllimited ="true" ctrlrange ="-20 20" gear ="20" />
<motor joint ="shoulder_flexion" ctrllimited ="true" ctrlrange ="-20 20" gear ="20" />
<motor joint ="elbow" ctrllimited ="true" ctrlrange ="-15 15" gear ="15" />
</actuator >
<sensor >
<framepos objtype ="body" objname ="left_foot" />
<framepos objtype ="body" objname ="right_foot" />
<jointpos joint ="hip_flexion" />
<jointpos joint ="knee" />
<jointpos joint ="ankle" />
<gyro site ="torso" />
<accelerometer site ="torso" />
</sensor >
</mujoco >
self
self
self
self
self
return
False
def
_get_obs
self
return
self
self
self
def
_compute_reward
self
return
0
def
_is_done
self
return
False
def
render
self
pass