上一篇讲了导纳控制核心是力→位置——用外力驱动末端运动。但实际工业场景中很多任务既需要精确的位置跟踪又需要控制接触力。比如机器人拧螺丝——位置和姿态要精确同时轴向力不能太大也不能太小。这种既要位置又要力的需求就是力位混合控制要解决的问题。说白了它把笛卡尔空间分成两个区域某些方向做位置控制另一些方向做力控制。一、为什么需要力位混合先想一个场景机器人在桌面上画圆。画笔需要沿着桌面移动位置控制同时笔尖要保持一定的按压力力控制。这两个需求发生在同一个末端但控制目标完全不同。如果你只用位置控制——画笔要么飘在空中力太小要么戳破桌面力太大。如果你只用力控制——笔尖的位置根本没法精确跟踪圆形轨迹。力位混合控制的思路很直接在不同的方向上分配不同的控制模式。画圆的例子里水平面内X、Y方向位置控制精确跟踪圆形轨迹垂直方向Z方向力控制保持恒定的按压力这就是混合的含义——同一时刻不同方向用不同的控制策略。二、选择矩阵——力控和位置控制的分界线力位混合控制的核心是一个选择矩阵S。它是一个对角矩阵对角线元素为0或1。S_i 1 表示第i个方向做位置控制 S_i 0 表示第i个方向做力控制import numpy as np # 6自由度末端[x, y, z, rx, ry, rz] # 场景桌面上画圆 # X, Y方向位置控制Z方向力控制 # 姿态全部位置控制 S_pos np.diag([1, 1, 0, 1, 1, 1]) # 位置控制选择 S_force np.diag([0, 0, 1, 0, 0, 0]) # 力控制选择 # 验证S_pos S_force I assert np.allclose(S_pos S_force, np.eye(6))选择矩阵的关键性质S_pos S_force I单位矩阵。每个方向要么做位置控制要么做力控制不能同时做两个也不能都不做。三、力位混合的控制架构经典的力位混合控制架构如下期望位置 x_d ──→ 位置控制器 ──→ 位置控制输出 τ_pos ↓ S_pos ↓ 期望力 F_d ──→ 力控制器 ──→ 力控制输出 τ_force ↓ S_force ↓ τ S_pos*τ_pos S_force*τ_force ↓ 关节力矩指令 → 电机位置控制器通常是PID输入是期望位置和实际位置的偏差。力控制器也是PID输入是期望力和实际力的偏差。两个输出通过选择矩阵加权求和得到最终的关节力矩。来看一段简化代码class HybridForcePositionController: def __init__(self, S_pos, S_force): self.S_pos S_pos self.S_force S_force self.pos_pid PIDController(kp100, ki1, kd10) self.force_pid PIDController(kp0.5, ki0.01, kd0.05) def compute(self, x_d, x_curr, F_d, F_curr, J): # 位置控制部分 pos_error x_d - x_curr F_pos self.S_pos self.pos_pid.compute(pos_error) # 力控制部分 force_error F_d - F_curr F_force self.S_force self.force_pid.compute(force_error) # 笛卡尔空间力 → 关节力矩 tau J.T (F_pos F_force) return tau这里有个细节力控制器的增益通常比位置控制器小很多。因为力的量级和位置的量级差很多——1mm的位置偏差和1N的力偏差对系统的影响完全不同。四、约束坐标系——选择矩阵在哪个坐标系下这是力位混合控制最容易搞混的地方。选择矩阵S定义在哪个坐标系下答案是约束坐标系constraint frame。约束坐标系是根据任务定义的不是基坐标系也不是工具坐标系。比如桌面画圆约束坐标系的Z轴垂直于桌面XY轴在桌面内孔轴装配约束坐标系的Z轴沿孔的轴线方向曲面打磨约束坐标系的Z轴沿曲面法线方向约束坐标系可以随任务变化。比如机械臂在曲面上打磨曲面法线方向一直在变约束坐标系也要跟着变。def get_constraint_frame(surface_normal): 根据曲面法线构建约束坐标系 z_axis surface_normal / np.linalg.norm(surface_normal) # 选一个不平行于z_axis的向量 if abs(z_axis[0]) 0.9: temp np.array([1, 0, 0]) else: temp np.array([0, 1, 0]) x_axis np.cross(temp, z_axis) x_axis / np.linalg.norm(x_axis) y_axis np.cross(z_axis, x_axis) # 6x6旋转矩阵 R np.eye(6) R[:3, :3] np.column_stack([x_axis, y_axis, z_axis]) R[3:, 3:] R[:3, :3] return R每次控制循环都要更新约束坐标系把力和位置误差变换到约束坐标系下再乘以选择矩阵。这个变换如果做错了力控方向就会跑偏。五、工业应用案例力位混合控制在工业界应用非常广泛举几个典型场景案例1轴孔装配。Z方向力控制保证插入力不超过阈值XY和姿态方向位置控制保证对准。这是最经典的力位混合应用。案例2去毛刺。刀具沿工件表面运动法线方向力控制保持恒定切削力切线方向位置控制跟踪轮廓。选择矩阵根据表面法线实时更新。案例3插拔连接器。插入时Z方向力控制XY方向位置控制。拔出时反过来——先力控检测是否松动再位置控制拔出。案例4精密研磨。法向力控制保证研磨压力恒定切向位置控制保证轨迹精度。研磨力通常在5-20N范围位置精度要求0.1mm以内。之前做AMR底盘装配的项目有一个工序是把电池连接器插入插槽。这个任务就是典型的力位混合——XY方向对准位置Z方向控制插入力。力控PID调了两天关键是力控增益不能太大否则连接器会被砸进去。六、面试实战Q力位混合控制和阻抗控制有什么区别A力位混合控制在不同方向分别做位置控制和力控制两者是独立的。阻抗控制不区分方向统一用力-位置关系来描述。力位混合适合方向明确的任务如垂直按压阻抗适合需要全方位柔顺的任务如拖拽示教。Q选择矩阵能不是对角矩阵吗A理论上可以但工程上几乎都用对角矩阵。对角矩阵的物理意义清晰——每个方向独立选择控制模式。非对角矩阵意味着方向之间的耦合调试难度大增。Q力位混合控制能处理未知环境吗A比较困难。选择矩阵需要预先知道哪个方向该力控、哪个方向该位置控。如果环境几何未知选择矩阵没法确定。这种情况用阻抗控制更合适。Q力控方向的PID怎么调A力控PID和位置PID的调法类似但增益量级不同。一般先只开P从小到大加直到力响应够快但不振荡。然后加D抑制振荡最后加I消除稳态误差。力控频率通常比位置控制低所以增益要相应减小。小结力位混合控制的核心用选择矩阵把笛卡尔空间分成位置控制区和力控制区。不同方向用不同的控制策略互不干扰。选择矩阵定义在约束坐标系下约束坐标系根据任务定义。力控方向和位置控制方向的切换通过矩阵元素0/1实现。工业应用中最常见的场景是法向力控切向位置控——打磨、装配、插拔都是这个套路。下一篇我们聊关节空间控制和笛卡尔空间控制的选型——这两种控制策略的差异比你想的要大。如果这篇文章对你有帮助欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。「机器人软件开发面试·从入门到精通」连载系列上一篇第202篇 导纳控制——力控场景的另一种实现思路下一篇预告第204篇 关节空间控制vs笛卡尔空间控制——两种控制策略的选型有任何问题欢迎评论区留言我会尽量回复。