这是一个非常漂亮且实用的自定义机械臂!从你的描述和图片来看,这属于一个**类 SCARA(水平多关节)构型**的机械臂,带有一个直线 Z 轴和三个平面的旋转关节。 为了让数学表达更清晰,我们先统一一下坐标系和变量的定义。 ### 变量与坐标系定义 我们将基坐标系原点设在红色滑轨的零点位置。 * **$d_1$**: 关节 1(高度滑块)的位置变量。 * **$\theta_2$**: 关节 2 的旋转角度(相对于基坐标系 X 轴)。 * **$\theta_3$**: 关节 3 的旋转角度(相对于上一连杆 $L_1$)。 * **$\theta_4$**: 关节 4 的旋转角度(相对于上一连杆 $L_2$)。 * **$(X, Y, Z, \Phi)$**: 夹爪末端(TCP - Tool Center Point)在基坐标系下的位姿。其中 $(X, Y, Z)$ 是空间坐标,$\Phi$ 是夹爪在水平面上的总朝向角(偏航角)。 * **已知常量**: $L_1$(二三关节距离), $L_2$(三四关节距离), $x_4$(夹爪相对关节四的 X 偏移), $z_4$(夹爪相对关节四的高度偏移)。 --- ### 1. 运动学正解 (Forward Kinematics) 正解的目的是:**已知各个电机的角度和滑块高度 $(d_1, \theta_2, \theta_3, \theta_4)$,求夹爪末端的位置 $(X, Y, Z, \Phi)$。** 因为 Z 轴的直线运动与 XY 平面的旋转运动是完全解耦的,我们可以分别计算: **高度 (Z 轴):** $$Z = d_1 + z_4$$ **平面朝向角 (偏航角 $\Phi$):** $$\Phi = \theta_2 + \theta_3 + \theta_4$$ **平面坐标 (X, Y):** $$X = L_1 \cos(\theta_2) + L_2 \cos(\theta_2 + \theta_3) + x_4 \cos(\theta_2 + \theta_3 + \theta_4)$$ $$Y = L_1 \sin(\theta_2) + L_2 \sin(\theta_2 + \theta_3) + x_4 \sin(\theta_2 + \theta_3 + \theta_4)$$ *(注意:在实际编程中,如果你的电机零点不是一条直线,需要在角度上加上相应的初始偏置)* --- ### 2. 运动学逆解 (Inverse Kinematics) 逆解的目的是:**给出夹爪期望到达的目标位置和朝向 $(X, Y, Z, \Phi)$,求出各关节需要运动到的目标值 $(d_1, \theta_2, \theta_3, \theta_4)$。** > **注意:** 你的机械臂在 XY 平面上有 3 个旋转自由度,但平面位置只需要 2 个自由度 $(X,Y)$。这意味着如果只给定目标坐标,机械臂有无数种姿态可以到达(冗余)。因此,**为了得到唯一解,必须同时指定夹爪的最终期望朝向角 $\Phi$**。 下面是逆解的推导步骤,非常适合直接转化为固件中的控制代码: #### 第一步:求解滑块高度 $d_1$ 高度依然是解耦的,直接通过目标 $Z$ 坐标和常量偏移计算: $$d_1 = Z - z_4$$ #### 第二步:反推关节 4 的坐标 $(X_4, Y_4)$ 既然我们知道末端目标的坐标 $(X, Y)$ 和总朝向 $\Phi$,我们可以把夹爪的偏置 $x_4$ “剥离”掉,求出关节 4 中轴线在空间中的位置: $$X_4 = X - x_4 \cos(\Phi)$$ $$Y_4 = Y - x_4 \sin(\Phi)$$ #### 第三步:求解关节 3 的角度 $\theta_3$ 现在问题简化为了一个标准的双连杆(两轴)平面机械臂求逆解问题。目标点是 $(X_4, Y_4)$,连杆是 $L_1$ 和 $L_2$。 根据余弦定理,设目标点到原点的距离平方为 $r^2 = X_4^2 + Y_4^2$,有: $$\cos(\theta_3) = \frac{X_4^2 + Y_4^2 - L_1^2 - L_2^2}{2 L_1 L_2}$$ 设 $C_3 = \cos(\theta_3)$。在实际控制代码中,必须在这里做合法性检查:如果 $C_3 > 1$ 或 $C_3 < -1$,说明目标点超出了机械臂的物理工作空间(够不到)。 如果合法,则 $\theta_3$ 的正弦值为: $$S_3 = \pm \sqrt{1 - C_3^2}$$ *(这里的 $\pm$ 代表机械臂的两种姿态:“左手系/右臂”或“右手系/左臂”,也就是俗称的“手肘朝左”还是“手肘朝右”。你可以根据防碰撞需求或当前姿态选择其中一个)* 最终使用反正切函数求解 $\theta_3$: $$\theta_3 = \text{atan2}(S_3, C_3)$$ #### 第四步:求解关节 2 的角度 $\theta_2$ 利用几何关系和已经求出的 $\theta_3$,可以通过组合角度直接求出 $\theta_2$: $$\theta_2 = \text{atan2}(Y_4, X_4) - \text{atan2}(L_2 S_3, L_1 + L_2 C_3)$$ #### 第五步:求解关节 4 的角度 $\theta_4$ 因为总朝向 $\Phi = \theta_2 + \theta_3 + \theta_4$,所以: $$\theta_4 = \Phi - \theta_2 - \theta_3$$ --- ### 💡 嵌入式固件实现建议 由于你很可能需要将这些公式写入 MCU(比如利用 C/C++ 或 Rust 编写固件),这里有几个实践建议: 1. **使用 `atan2` 替代 `asin/acos**`:上面逆解公式中我全部使用了 $\text{atan2}(y, x)$。在标准库中,`atan2` 能够自动处理四个象限的符号问题,且能避免 $x=0$ 时的除零错误,这在底层驱动中至关重要。 2. **死区与奇异点保护**:当 $X_4^2 + Y_4^2 \approx 0$ 时(关节 4 缩回到了原点正上方),此时 $\theta_2$ 会失去意义(奇异点)。在代码中应当加入对 $X_4^2 + Y_4^2 < \epsilon$(一个极小值)的判断,防止产生 NaN。 3. **角度范围归一化**:计算出的角度可能会超出电机支持的物理限位范围(例如超出了 $[-180^\circ, +180^\circ]$),在下发脉冲或指令前,记得对 $\theta_2, \theta_3, \theta_4$ 进行归一化和软限位拦截。