From 4c438f25bdf0c52399594bd0eaab65bf8eaecf09 Mon Sep 17 00:00:00 2001
From: oyzw2302
Date: Sat, 20 Dec 2025 17:16:07 +0800
Subject: [PATCH 01/12] =?UTF-8?q?=E6=96=B0=E5=88=9B=E5=BB=BA=E4=B8=80?=
=?UTF-8?q?=E4=B8=AA=E4=BB=BF=E7=9C=9F=E4=BA=BA=E6=A8=A1=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../humanoid_simulation.py | 138 ++++++++++++++++++
1 file changed, 138 insertions(+)
create mode 100644 src/humanoid_3d_animation/humanoid_simulation.py
diff --git a/src/humanoid_3d_animation/humanoid_simulation.py b/src/humanoid_3d_animation/humanoid_simulation.py
new file mode 100644
index 0000000000..68cdeedf1b
--- /dev/null
+++ b/src/humanoid_3d_animation/humanoid_simulation.py
@@ -0,0 +1,138 @@
+import mujoco
+import mujoco.viewer as viewer
+import os
+import time
+
+def create_humanoid_xml(file_path):
+ """自动创建humanoid.xml文件并写入模型代码"""
+ xml_content = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"""
+ with open(file_path, "w", encoding="utf-8") as f:
+ f.write(xml_content)
+ print(f"已自动在 {file_path} 创建humanoid.xml文件!")
+
+def run_humanoid_simulation():
+ # 直接写死桌面路径(替换成你的实际用户名,这里保留你的用户名)
+ # 注意:路径中的反斜杠用双反斜杠,或单反斜杠加r前缀
+ model_path = r"C:\Users\欧阳志威1\Desktop\humanoid.xml" # r前缀表示原始字符串,避免转义
+
+ # 打印路径
+ print(f"===== 模型文件路径 =====")
+ print(f"模型文件完整路径:{model_path}")
+ print(f"========================")
+
+ # 检查并创建文件
+ if not os.path.exists(model_path):
+ create_humanoid_xml(model_path)
+ else:
+ print("humanoid.xml文件已存在,无需重新创建!")
+
+ # 加载模型(新增:用Python内置的open函数测试是否能读取文件)
+ try:
+ # 先测试Python是否能读取该文件(排除系统权限问题)
+ with open(model_path, "r", encoding="utf-8") as f:
+ f.read()
+ print("Python内置函数已成功读取文件,权限正常!")
+ except Exception as e:
+ print(f"Python读取文件失败,权限/路径问题:{e}")
+ return
+
+ # 加载MuJoCo模型
+ try:
+ model = mujoco.MjModel.from_xml_path(model_path)
+ data = mujoco.MjData(model)
+ print("模型加载成功!开始启动仿真...")
+ except Exception as e:
+ print(f"MuJoCo加载模型失败:{e}")
+ # 备选方案:从字符串加载模型(绕过文件读取)
+ print("尝试从字符串直接加载模型...")
+ with open(model_path, "r", encoding="utf-8") as f:
+ xml_str = f.read()
+ model = mujoco.MjModel.from_xml_string(xml_str)
+ data = mujoco.MjData(model)
+ print("从字符串加载模型成功!开始启动仿真...")
+
+ # 运行仿真
+ with viewer.launch_passive(model, data) as v:
+ sim_steps = 10000
+ step_interval = 0.01
+ print("仿真开始,按窗口关闭按钮退出...")
+ for _ in range(sim_steps):
+ mujoco.mj_step(model, data)
+ v.sync()
+ time.sleep(step_interval)
+ print("仿真结束!")
+
+if __name__ == "__main__":
+ run_humanoid_simulation()
\ No newline at end of file
From a5107672b37afda5da2477f61786b9534f0e190a Mon Sep 17 00:00:00 2001
From: oyzw2302
Date: Sat, 20 Dec 2025 22:08:17 +0800
Subject: [PATCH 02/12] =?UTF-8?q?=E9=A1=B6=E9=83=A8=E5=AF=BC=E5=85=A5?=
=?UTF-8?q?=E5=8C=BA=E6=96=B0=E5=A2=9E=E6=95=B0=E5=AD=A6=E5=BA=93=20?=
=?UTF-8?q?=E4=BB=BF=E7=9C=9F=E5=BE=AA=E7=8E=AF=E4=B8=AD=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E5=85=B3=E8=8A=82=E6=8E=A7=E5=88=B6=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../humanoid_simulation.py | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/src/humanoid_3d_animation/humanoid_simulation.py b/src/humanoid_3d_animation/humanoid_simulation.py
index 68cdeedf1b..be34f09ab4 100644
--- a/src/humanoid_3d_animation/humanoid_simulation.py
+++ b/src/humanoid_3d_animation/humanoid_simulation.py
@@ -2,6 +2,8 @@
import mujoco.viewer as viewer
import os
import time
+# 新增:导入数学库,用于生成周期性的正弦/余弦运动信号
+import math
def create_humanoid_xml(file_path):
"""自动创建humanoid.xml文件并写入模型代码"""
@@ -129,6 +131,27 @@ def run_humanoid_simulation():
step_interval = 0.01
print("仿真开始,按窗口关闭按钮退出...")
for _ in range(sim_steps):
+ # ========== 新增:关节主动运动控制核心代码 ==========
+ # 1. 手臂运动:左肩关节和右肩关节做相反的正弦运动(周期性摆动)
+ # data.time:仿真累计时间(秒),驱动周期性运动
+ # math.sin(data.time * 2):2Hz频率的正弦波,取值[-1,1]
+ # * 1.0:运动幅度(可调整,越大摆动越剧烈)
+ data.ctrl[0] = math.sin(data.time * 2) * 1.0 # 左肩关节(对应actuator索引0)
+ data.ctrl[1] = -math.sin(data.time * 2) * 1.0 # 右肩关节(对应actuator索引1,负号表示反向)
+
+ # 2. 肘部运动:跟随肩部运动,幅度更小
+ data.ctrl[2] = math.sin(data.time * 2) * 0.5 # 左肘部(索引2)
+ data.ctrl[3] = -math.sin(data.time * 2) * 0.5 # 右肘部(索引3)
+
+ # 3. 腿部运动:左髋和右髋做余弦运动(与正弦波相位差90°,运动更协调)
+ data.ctrl[4] = math.cos(data.time * 1) * 0.8 # 左髋(索引4)
+ data.ctrl[5] = -math.cos(data.time * 1) * 0.8 # 右髋(索引5)
+
+ # 4. 膝盖运动:跟随髋部运动,幅度稍小
+ data.ctrl[6] = math.cos(data.time * 1) * 0.6 # 左膝盖(索引6)
+ data.ctrl[7] = -math.cos(data.time * 1) * 0.6 # 右膝盖(索引7)
+ # ================================================
+
mujoco.mj_step(model, data)
v.sync()
time.sleep(step_interval)
From 7cb0dae6d15589bcf88ad37de7ff7f8dfc79fc65 Mon Sep 17 00:00:00 2001
From: oyzw2302
Date: Sun, 21 Dec 2025 12:49:35 +0800
Subject: [PATCH 03/12] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=BF=E7=9C=9F?=
=?UTF-8?q?=E4=BA=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/humanoid_3d_animation/smpl_humanoid.py | 666 +++++++++++++++++++++
1 file changed, 666 insertions(+)
create mode 100644 src/humanoid_3d_animation/smpl_humanoid.py
diff --git a/src/humanoid_3d_animation/smpl_humanoid.py b/src/humanoid_3d_animation/smpl_humanoid.py
new file mode 100644
index 0000000000..ad7c806907
--- /dev/null
+++ b/src/humanoid_3d_animation/smpl_humanoid.py
@@ -0,0 +1,666 @@
+import mujoco
+import mujoco.viewer as viewer
+import numpy as np
+import time # 导入time库,用于实现等待功能
+
+def main():
+ # ==========================================================================
+ # 第一步:把你的XML内容粘贴到下面的这个字符串变量中(替换掉示例的简单XML)
+ # 注意:保持三引号的包裹格式,XML内容直接放在中间即可
+ # ==========================================================================
+ xml_content = """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ """
+ # ==========================================================================
+ # XML内容粘贴结束位置
+ # ==========================================================================
+
+ # 从XML字符串加载模型
+ try:
+ model = mujoco.MjModel.from_xml_string(xml_content)
+ data = mujoco.MjData(model)
+ print("✅ MuJoCo模型加载成功!")
+ except Exception as e:
+ print(f"❌ 模型加载失败:{e}")
+ return
+
+ # 运行仿真可视化
+ with viewer.launch_passive(model, data) as v:
+ # 设置相机视角(可根据需要调整)
+ v.cam.azimuth = 45
+ v.cam.elevation = -20
+ v.cam.distance = 3.0
+ v.cam.lookat = np.array([0.0, 0.0, 1.0])
+
+ # 仿真循环
+ while v.is_running():
+ # 修复:正确判断关节是否存在并获取关节ID的方式
+ t = data.time
+ # 方法1:使用try-except捕获关节不存在的异常(推荐)
+ try:
+ # 获取L_Hip_y关节的ID
+ l_hip_y_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT, "L_Hip_y")
+ if l_hip_y_id >= 0: # 确认ID有效(>=0表示存在)
+ data.ctrl[l_hip_y_id] = 0.5 * np.sin(t)
+ except:
+ # 关节不存在时跳过,不报错
+ pass
+
+ try:
+ # 获取R_Hip_y关节的ID
+ r_hip_y_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT, "R_Hip_y")
+ if r_hip_y_id >= 0:
+ data.ctrl[r_hip_y_id] = 0.5 * np.cos(t)
+ except:
+ pass
+
+ # 执行一步仿真
+ mujoco.mj_step(model, data)
+ # 更新可视化
+ v.sync()
+ # 修复:用time.sleep替代mujoco.mj_wait,实现相同的等待功能
+ time.sleep(model.opt.timestep)
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
From 7c4e76cd18ffd669cf69e50c940047f429aa5c58 Mon Sep 17 00:00:00 2001
From: oyzw2302
Date: Sun, 21 Dec 2025 14:33:04 +0800
Subject: [PATCH 04/12] =?UTF-8?q?=E4=B8=BA=E5=AF=BC=E5=85=A5=E7=9A=84?=
=?UTF-8?q?=E5=BA=93=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/humanoid_3d_animation/smpl_humanoid.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/humanoid_3d_animation/smpl_humanoid.py b/src/humanoid_3d_animation/smpl_humanoid.py
index ad7c806907..30348913dd 100644
--- a/src/humanoid_3d_animation/smpl_humanoid.py
+++ b/src/humanoid_3d_animation/smpl_humanoid.py
@@ -1,6 +1,6 @@
-import mujoco
-import mujoco.viewer as viewer
-import numpy as np
+import mujoco # 导入MuJoCo核心库,用于加载模型和运行仿真
+import mujoco.viewer as viewer # 导入MuJoCo的可视化器
+import numpy as np # 导入numpy库,用于数值计算(如三角函数、数组操作)
import time # 导入time库,用于实现等待功能
def main():
From 59c74288b560925ef4c99c536b09239ca94d78a4 Mon Sep 17 00:00:00 2001
From: oyzw2302
Date: Sun, 21 Dec 2025 21:26:03 +0800
Subject: [PATCH 05/12] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96=20?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../humanoid_simulation.py | 229 ++++++++++++++----
1 file changed, 185 insertions(+), 44 deletions(-)
diff --git a/src/humanoid_3d_animation/humanoid_simulation.py b/src/humanoid_3d_animation/humanoid_simulation.py
index be34f09ab4..92f4605c1f 100644
--- a/src/humanoid_3d_animation/humanoid_simulation.py
+++ b/src/humanoid_3d_animation/humanoid_simulation.py
@@ -2,34 +2,46 @@
import mujoco.viewer as viewer
import os
import time
-# 新增:导入数学库,用于生成周期性的正弦/余弦运动信号
import math
+import threading # 新增:用于监听控制台输入(实现重置指令)
+import numpy as np
def create_humanoid_xml(file_path):
- """自动创建humanoid.xml文件并写入模型代码"""
+ """
+ 自动创建humanoid.xml文件并写入模型代码
+ 优化点:XML内容格式化,增加注释,提升可读性
+ """
xml_content = """
+
+
+
+
+
+
+
+
@@ -39,6 +51,7 @@ def create_humanoid_xml(file_path):
+
@@ -48,6 +61,7 @@ def create_humanoid_xml(file_path):
+
@@ -57,6 +71,7 @@ def create_humanoid_xml(file_path):
@@ -69,27 +84,108 @@ def create_humanoid_xml(file_path):