Skip to content
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
17c299d
提交选题
dengzhuo0119 Dec 19, 2025
5e6eb70
增加初始代码
dengzhuo0119 Dec 21, 2025
265bcd4
添加初始代码
dengzhuo0119 Dec 22, 2025
45ee132
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 22, 2025
8611cef
feat: v0.2-添加夹爪开合控制功能(修复XML ctrlrange属性错误)
dengzhuo0119 Dec 22, 2025
81cc517
feat: v0.3-实现夹爪与立方体的接触检测功能
dengzhuo0119 Dec 22, 2025
e8e7b35
feat: v0.1-初始版本-基础机械臂可视化
dengzhuo0119 Dec 22, 2025
be9b7ac
添加初始代码
dengzhuo0119 Dec 22, 2025
d7d8e9c
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 22, 2025
7596774
新增文件头注释和仿真休眠常量,支持Ctrl+C优雅退出
dengzhuo0119 Dec 23, 2025
12cfd77
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 23, 2025
50017ed
新增文件头注释和仿真休眠常量,支持Ctrl+C优雅退出
dengzhuo0119 Dec 23, 2025
c2d307a
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 23, 2025
88c69ac
提取PD控制参数为类内常量并添加类初始化文档字符串
dengzhuo0119 Dec 23, 2025
fd9472a
提取PD控制参数为类内常量并添加类初始化文档字符串
dengzhuo0119 Dec 23, 2025
9517f2e
提取雅克比阻尼系数为常量并完善_compute_jacobian文档
dengzhuo0119 Dec 24, 2025
9f209b4
Merge branch 'main' into main
dengzhuo0119 Dec 24, 2025
f5b25ba
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 24, 2025
1cf25b0
提取关节速度限制常量并完善_move_step文档字符串
dengzhuo0119 Dec 24, 2025
f3eb289
提取关节速度限制常量并完善_move_step文档字符串
dengzhuo0119 Dec 24, 2025
0d4223a
提取位置误差阈值常量并完善_gripper_step文档
dengzhuo0119 Dec 24, 2025
0bfd5cd
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 24, 2025
fc3a8e6
提取位置误差阈值常量并完善_gripper_step文档
dengzhuo0119 Dec 24, 2025
914736e
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 25, 2025
697865e
提取夹爪等待步数常量并完善_grab_phase_machine文档
dengzhuo0119 Dec 25, 2025
d255cb0
提取夹爪等待步数常量并完善_grab_phase_machine文档
dengzhuo0119 Dec 25, 2025
6683bd0
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 25, 2025
c9d1524
提取初始位置常量并添加位置方法的类型注解
dengzhuo0119 Dec 25, 2025
f7a93ac
提取初始位置常量并添加位置方法的类型注解
dengzhuo0119 Dec 25, 2025
2f11a70
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 26, 2025
5b43246
提取抬升高度增量常量并完善_compute_jacobian类型注解
dengzhuo0119 Dec 26, 2025
9165bbc
提取抬升高度增量常量并完善_compute_jacobian类型注解
dengzhuo0119 Dec 26, 2025
6ab783c
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 26, 2025
9682b40
提取相机参数常量并完善_move_step类型注解
dengzhuo0119 Dec 26, 2025
bc9daa7
提取相机参数常量并完善_move_step类型注解
dengzhuo0119 Dec 26, 2025
e29068c
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 27, 2025
ea8b777
提升仿真休眠时间为常量并完善_gripper_step类型注解
dengzhuo0119 Dec 27, 2025
5d62e0c
提升仿真休眠时间为常量并完善_gripper_step类型注解
dengzhuo0119 Dec 27, 2025
3c1301e
Merge branch 'OpenHUTB:main' into main
dengzhuo0119 Dec 27, 2025
79f45e4
重构相机初始化并完善_grab_phase_machine类型注解
dengzhuo0119 Dec 27, 2025
431314a
重构相机初始化并完善_grab_phase_machine类型注解
dengzhuo0119 Dec 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 14 additions & 35 deletions src/Robot_arm_motion/robot_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __init__(self):
self.CAM_DISTANCE = 1.8 # 相机距离
self.CAM_LOOKAT = np.array([0.4, 0.0, 0.1]) # 相机注视点

# 【优化1】将仿真休眠时间提升为类内常量
# 仿真控制参数
self.SIMULATION_SLEEP = 1 / 200 # 仿真循环的休眠时间

# 打印模型信息
Expand Down Expand Up @@ -129,28 +129,18 @@ def _move_step(self, target: np.ndarray, speed: float = 0.3) -> bool:
if error_norm < self.POS_TOLERANCE:
return True # 到达目标

# 计算雅克比矩阵
jacobian = self._compute_jacobian() # 3×7

# ========== 修正:正确的阻尼伪逆计算 ==========
# 方法1:使用正则化参数的伪逆(推荐)
jacobian = self._compute_jacobian()
jacobian_pinv = jacobian.T @ np.linalg.inv(jacobian @ jacobian.T + self.JACOBIAN_DAMPING * np.eye(3))

# 方法2:若方法1仍报错,可改用numpy伪逆(自动处理维度)
# jacobian_pinv = np.linalg.pinv(jacobian, rcond=1e-3)

# 关节速度指令
joint_vel_cmd = speed * jacobian_pinv @ error
joint_vel_cmd = np.clip(joint_vel_cmd, -self.JOINT_VEL_LIMIT, self.JOINT_VEL_LIMIT)

# PD力矩计算
torque = np.zeros(7)
for i in range(7):
angle_error = joint_vel_cmd[i] * 0.1
torque[i] = self.PD_KP * angle_error - self.PD_KD * self.data.qvel[self.joint_ids[i]]
torque[i] = np.clip(torque[i], -self.TORQUE_LIMIT, self.TORQUE_LIMIT)

# 设置关节力矩
for i in range(7):
self.data.ctrl[self.joint_ids[i]] = torque[i]

Expand All @@ -166,34 +156,30 @@ def _gripper_step(self, pos: float) -> None:
j_id = self.model.joint(j_name).id
self.data.ctrl[j_id] = pos

def _grab_phase_machine(self):
def _grab_phase_machine(self) -> None:
"""抓取状态机:按阶段执行机械臂的抓取、移动、放置等一系列动作

状态机分为12个阶段,从初始位置移动→识别立方体→抓取→放置→返回,
每个阶段完成后自动切换到下一个阶段,直到抓取任务完成。
"""
if self.current_phase == 0:
# 阶段0:移动到初始位置
if self._move_step(self.INIT_EE_POS):
print("\n✅ 到达初始位置")
self.current_phase = 1
self.step_counter = 0

elif self.current_phase == 1:
# 阶段1:获取立方体位置
self.cube_pos = self.get_cube_pos()
print(f"\n🎯 识别到立方体位置:{np.round(self.cube_pos, 3)}")
self.current_phase = 2

elif self.current_phase == 2:
# 阶段2:移动到立方体上方
if self._move_step(self.cube_pos + np.array([0, 0, self.safe_lift_height]), speed=0.4):
print("\n✅ 到达立方体上方")
self.current_phase = 3
self.step_counter = 0

elif self.current_phase == 3:
# 阶段3:打开夹爪
if self.step_counter == 0:
self._gripper_step(self.gripper_open_pos)
print("\n✋ 打开夹爪")
Expand All @@ -203,14 +189,12 @@ def _grab_phase_machine(self):
self.step_counter += 1

elif self.current_phase == 4:
# 阶段4:下降抓取
if self._move_step(self.cube_pos + np.array([0, 0, self.grab_height]), speed=0.2):
print("\n✅ 下降到抓取高度")
self.current_phase = 5
self.step_counter = 0

elif self.current_phase == 5:
# 阶段5:闭合夹爪
if self.step_counter == 0:
self._gripper_step(self.gripper_close_pos)
print("\n🤏 闭合夹爪抓取")
Expand All @@ -220,29 +204,25 @@ def _grab_phase_machine(self):
self.step_counter += 1

elif self.current_phase == 6:
# 阶段6:抬升立方体
lift_target = self.cube_pos + np.array([0, 0, self.safe_lift_height + self.LIFT_HEIGHT_INCREMENT])
if self._move_step(lift_target, speed=0.3):
print("\n✅ 抬升立方体")
self.current_phase = 7
self.step_counter = 0

elif self.current_phase == 7:
# 阶段7:移动到放置点上方
if self._move_step(self.target_place_pos + np.array([0, 0, self.safe_lift_height]), speed=0.4):
print("\n✅ 到达放置点上方")
self.current_phase = 8
self.step_counter = 0

elif self.current_phase == 8:
# 阶段8:下降放置
if self._move_step(self.target_place_pos + np.array([0, 0, self.grab_height]), speed=0.2):
print("\n✅ 下降到放置高度")
self.current_phase = 9
self.step_counter = 0

elif self.current_phase == 9:
# 阶段9:释放立方体
if self.step_counter == 0:
self._gripper_step(self.gripper_open_pos)
print("\n🫳 释放立方体")
Expand All @@ -252,57 +232,56 @@ def _grab_phase_machine(self):
self.step_counter += 1

elif self.current_phase == 10:
# 阶段10:撤离机械臂
if self._move_step(self.target_place_pos + np.array([0, 0, self.safe_lift_height]), speed=0.3):
print("\n✅ 撤离机械臂")
self.current_phase = 11
self.step_counter = 0

elif self.current_phase == 11:
# 阶段11:返回初始位置
if self._move_step(self.INIT_EE_POS, speed=0.4):
print("\n✅ 返回初始位置")
self.current_phase = 12

elif self.current_phase == 12:
# 阶段12:抓取完成
if not self.grab_complete:
print("\n" + "=" * 50)
print("✅ 智能抓取任务完成!")
print("=" * 50)
self.grab_complete = True

def run(self):
"""单线程仿真主循环"""
# 初始化Viewer
self.viewer = viewer.launch_passive(self.model, self.data)
# 【优化1】新增方法:集中初始化相机参数
def _init_camera(self) -> None:
"""初始化Viewer的相机视角"""
self.viewer.cam.azimuth = self.CAM_AZIMUTH
self.viewer.cam.elevation = self.CAM_ELEVATION
self.viewer.cam.distance = self.CAM_DISTANCE
self.viewer.cam.lookat = self.CAM_LOOKAT

def run(self):
"""单线程仿真主循环"""
# 初始化Viewer
self.viewer = viewer.launch_passive(self.model, self.data)

# 【优化2】调用新方法初始化相机
self._init_camera()

print("\n🚀 仿真已启动,开始自动抓取...")
print("💡 关闭Viewer窗口可退出程序")

# 单线程主循环
# 添加KeyboardInterrupt捕获,支持Ctrl+C优雅退出
try:
while self.viewer.is_running():
if self.running and not self.grab_complete:
self._grab_phase_machine()
else:
# 抓取完成后归零力矩
for i in range(7):
self.data.ctrl[self.joint_ids[i]] = 0

mujoco.mj_step(self.model, self.data)
self.viewer.sync()
# 【优化2】使用类内常量替代局部变量
time.sleep(self.SIMULATION_SLEEP)
except KeyboardInterrupt:
print("\n⚠️ 检测到Ctrl+C,正在退出仿真...")

# 清理
self.running = False
self.viewer.close()
print("\n👋 仿真结束")
Expand Down
Loading