较稳定/十分稳定挡改为恒力夹持:接触后不锁位置持续以闭合力顶住;张开改为 Y 切向带符号拟合偏移(保护期后记基准,连续 6 帧超阈值),夹爪合到底判定物体脱出即张开。较稳定 70%/2s/0.6N,十分稳定 100%/2.5s/0.8N。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
cheng
2026-09-28 16:30:54 +08:00
parent 6393be9518
commit 8be8a80cff
8 changed files with 337 additions and 80 deletions
+83 -51
View File
@@ -1,13 +1,13 @@
"""Grip behavior presets: sensitive / stable / firm (open/release only)."""
"""Grip behavior presets: sensitive / stable / firm (grip force + release)."""
from __future__ import annotations
import copy
# sensitive = 灵敏:跟手释放,当前默认调参
# stable = 较稳定:原十分稳定档,明显更难误开
# firm = 十分稳定:约高一个数量级门槛,故意开合才响应
# sensitive = 灵敏:跟手释放,自适应夹持力
# stable = 较稳定:接触即 70% 恒力夹持,2 s 保护期,Y 拟合偏移 0.6 N 张开
# firm = 十分稳定:接触即 100% 恒力夹持,2.5 s 保护期,Y 拟合偏移 0.8 N 张开
GRIP_BEHAVIOR_MODES = ("sensitive", "stable", "firm")
GRIP_BEHAVIOR_LABELS = {
@@ -28,6 +28,21 @@ GRIP_TRIGGER_KEYS = (
# Keys rewritten by the behavior mode. Trigger params are not included —
# they stay locked to the sensitive profile via GRIP_TRIGGER_KEYS.
GRIP_BEHAVIOR_KEYS = (
"grip_contact_hold_position",
"close_force",
"grip_start_force",
"hold_force",
"force_ramp_step",
"force_ramp_interval",
"adaptive_force_min",
"adaptive_force_max",
"adaptive_force_step",
"adaptive_force_interval",
"release_guard_fast_paths",
"release_shear_axes",
"release_shear_displacement",
"release_shear_displacement_samples",
"release_object_lost_open",
"release_open_speed",
"release_open_accel",
"release_open_decel",
@@ -75,8 +90,44 @@ _SENSITIVE_TRIGGER = {
"open_wait_stable_trend_n": 0.015,
}
# Adaptive clamp: start light, climb with payload shear.
_ADAPTIVE_FORCE = {
"grip_contact_hold_position": True,
"close_force": 33,
"grip_start_force": 25,
"hold_force": 33,
"force_ramp_step": 1,
"force_ramp_interval": 0.1,
"adaptive_force_min": 33,
"adaptive_force_max": 80,
"adaptive_force_step": 5,
"adaptive_force_interval": 0.08,
}
def _constant_force(pct):
"""Close at *pct* and keep that close command squeezing after contact
(no position hold, no later ramp). Close speed stays the global speed."""
return {
"grip_contact_hold_position": False,
"close_force": pct,
"grip_start_force": pct,
"hold_force": pct,
"force_ramp_step": 5,
"force_ramp_interval": 0.03,
"adaptive_force_min": pct,
"adaptive_force_max": pct,
"adaptive_force_step": 5,
"adaptive_force_interval": 0.03,
}
_SENSITIVE_PROFILE = {
**_SENSITIVE_TRIGGER,
**_ADAPTIVE_FORCE,
"release_guard_fast_paths": False,
"release_shear_axes": "",
"release_shear_displacement": 0.0,
"release_shear_displacement_samples": 6,
"release_object_lost_open": False,
"release_open_speed": 55,
"release_open_accel": 70,
"release_open_decel": 70,
@@ -117,13 +168,24 @@ _SENSITIVE_PROFILE = {
}
_STABLE_PROFILE = {
"release_open_speed": 45,
"release_open_accel": 60,
"release_open_decel": 60,
**_constant_force(70),
"release_guard_fast_paths": True,
# Release looks at Y shear only, regardless of the global control axes.
"release_shear_axes": "y",
# Full clamp swings Y by several N and flips sign, so onset confirmation
# keeps cancelling; open on sustained fitted Y displacement instead.
"release_shear_displacement": 0.6,
"release_shear_displacement_samples": 6,
# The close command keeps pushing: reaching close_pos means the object is gone.
"release_object_lost_open": True,
"release_open_speed": 55,
"release_open_accel": 70,
"release_open_decel": 70,
"release_arm_delay_seconds": 0.55,
"release_min_hold_seconds": 1.2,
# Protection: no release of any kind within 2s of contact.
"release_min_hold_seconds": 2.0,
"release_settle_seconds": 0.22,
"release_min_change": 0.16,
"release_min_change": 0.12,
"release_touch_window_seconds": 0.22,
"release_side_touch_change": 0.24,
"release_confirm_window_seconds": 0.28,
@@ -139,61 +201,31 @@ _STABLE_PROFILE = {
"release_slope_window_seconds": 1.2,
"release_slope_settle_rate": 0.12,
"release_slope_min_points": 14,
"release_require_slope_settle": True,
# Full constant clamp: the protection window is the only arming gate.
"release_require_slope_settle": False,
"release_slope_hold_seconds": 0.9,
"release_settle_normal_only": True,
"release_shear_oscillation_open": True,
# Open by fitted Y shear displacement only, no oscillation path.
"release_shear_oscillation_open": False,
"release_shear_oscillation_window_seconds": 0.6,
"release_shear_oscillation_min_flips": 5,
"release_shear_oscillation_amplitude": 0.3,
"release_shear_oscillation_confirm_samples": 4,
# Normal only judges the clamp plateau; opening is by Y shear only.
"release_side_shear_enabled": True,
"release_side_normal_enabled": True,
"release_side_normal_enabled": False,
"release_shear_onset_enabled": True,
"release_normal_onset_enabled": True,
"release_normal_onset_enabled": False,
"rearm_seconds": 0.9,
"recover_stable_seconds": 0.9,
}
# Roughly ~10x harder to trip open than sensitive; intentional open needs clear force.
# Same release scheme as stable, with a harder clamp and larger margins.
_FIRM_PROFILE = {
"release_open_speed": 35,
"release_open_accel": 50,
"release_open_decel": 50,
"release_arm_delay_seconds": 1.2,
"release_min_hold_seconds": 3.0,
"release_settle_seconds": 0.5,
"release_min_change": 0.8,
"release_touch_window_seconds": 0.35,
"release_side_touch_change": 1.2,
"release_confirm_window_seconds": 0.5,
"release_sample_timeout_seconds": 0.4,
"release_confirm_samples": 12,
"release_slow_confirm_samples": 18,
"release_normal_rate": 20.0,
"release_shear_rate": 18.0,
"release_slow_rate": 0.08,
"release_normal_change": 4.0,
"release_shear_change": 3.5,
"release_curve_history": 60,
"release_slope_window_seconds": 2.0,
"release_slope_settle_rate": 0.06,
"release_slope_min_points": 20,
"release_require_slope_settle": True,
"release_slope_hold_seconds": 2.0,
"release_settle_normal_only": True,
# Keep path available, but require large rub/twist evidence.
"release_shear_oscillation_open": True,
"release_shear_oscillation_window_seconds": 0.8,
"release_shear_oscillation_min_flips": 6,
"release_shear_oscillation_amplitude": 1.5,
"release_shear_oscillation_confirm_samples": 6,
"release_side_shear_enabled": True,
"release_side_normal_enabled": True,
"release_shear_onset_enabled": True,
"release_normal_onset_enabled": True,
"rearm_seconds": 1.5,
"recover_stable_seconds": 1.5,
**_STABLE_PROFILE,
**_constant_force(100),
"release_min_hold_seconds": 2.5,
"release_shear_displacement": 0.8,
}
GRIP_BEHAVIOR_PROFILES = {
+28
View File
@@ -84,6 +84,9 @@ class Demo02Config:
force_ramp_step: int = 1
force_ramp_interval: float = 0.1
grip_settle_seconds: float = 0.1
# On contact: True = hold at the contact position; False = keep the close
# command squeezing toward close_pos at full commanded force.
grip_contact_hold_position: bool = True
grip_behavior_mode: str = "sensitive"
adaptive_grip_enabled: bool = True
adaptive_shear_start_force: float = 0.10
@@ -119,6 +122,16 @@ class Demo02Config:
release_shear_oscillation_min_flips: int = 3
release_shear_oscillation_amplitude: float = 0.15
release_shear_oscillation_confirm_samples: int = 2
# Block oscillation/side-touch release during contact hold and servo motion.
release_guard_fast_paths: bool = False
# Shear axes for release only: "" follows shear_control_axes; "y" | "x" | "xy".
release_shear_axes: str = ""
# >0: open when curve-fitted signed Y shear leaves its post-protection
# baseline by this much (N) for N consecutive samples; replaces onset paths.
release_shear_displacement: float = 0.0
release_shear_displacement_samples: int = 6
# Open when the gripper travels to close_pos while holding (object gone).
release_object_lost_open: bool = False
release_side_shear_enabled: bool = True
release_side_normal_enabled: bool = True
release_shear_onset_enabled: bool = True
@@ -212,6 +225,9 @@ class Demo02Config:
add("--force-ramp-step", type=int, default=get("force_ramp_step", cls.force_ramp_step))
add("--force-ramp-interval", type=float, default=get("force_ramp_interval", cls.force_ramp_interval))
add("--grip-settle-seconds", type=float, default=get("grip_settle_seconds", cls.grip_settle_seconds))
add("--grip-contact-hold-position", dest="grip_contact_hold_position", action="store_true",
default=get("grip_contact_hold_position", cls.grip_contact_hold_position))
add("--no-grip-contact-hold-position", dest="grip_contact_hold_position", action="store_false")
add(
"--grip-behavior-mode",
type=str,
@@ -265,6 +281,18 @@ class Demo02Config:
default=get("release_shear_oscillation_amplitude", cls.release_shear_oscillation_amplitude))
add("--release-shear-oscillation-confirm-samples", type=int,
default=get("release_shear_oscillation_confirm_samples", cls.release_shear_oscillation_confirm_samples))
add("--release-guard-fast-paths", dest="release_guard_fast_paths", action="store_true",
default=get("release_guard_fast_paths", cls.release_guard_fast_paths))
add("--no-release-guard-fast-paths", dest="release_guard_fast_paths", action="store_false")
add("--release-shear-axes", type=str, choices=["", "xy", "x", "y"],
default=str(get("release_shear_axes", cls.release_shear_axes) or "").strip().lower())
add("--release-shear-displacement", type=float,
default=get("release_shear_displacement", cls.release_shear_displacement))
add("--release-shear-displacement-samples", type=int,
default=get("release_shear_displacement_samples", cls.release_shear_displacement_samples))
add("--release-object-lost-open", dest="release_object_lost_open", action="store_true",
default=get("release_object_lost_open", cls.release_object_lost_open))
add("--no-release-object-lost-open", dest="release_object_lost_open", action="store_false")
add("--release-side-shear-enabled", dest="release_side_shear_enabled", action="store_true",
default=get("release_side_shear_enabled", cls.release_side_shear_enabled))
add("--no-release-side-shear", dest="release_side_shear_enabled", action="store_false")