大拇指安全限制去除

This commit is contained in:
lxp
2026-07-27 17:40:57 +08:00
parent fc7c66d30e
commit 0d92e5f998
5 changed files with 1010 additions and 9 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ _CANONICAL_COMMAND_NAMES = {
_CANONICAL_COMMAND_BOUNDS = {
"G20": [
*[(0, 255)] * 10,
(80, 255),
(0, 255),
*[(255, 255)] * 4,
*[(0, 255)] * 5,
],
@@ -174,8 +174,8 @@ CLI将GUI保存动作和状态选择共同视为人工确认,并立即写入
提示当前姿势,不会退出。程序被关闭或异常中断后,使用完全相同的命令
会校验型号、seed哈希、SN、固件、CAN、操作者和输出路径,并自动跳过已保存姿势。
若旧检查点中的某些命令超出profile安全范围,CLI会保留其他有效姿势,只移除并
重拍超限姿势。G20 GUI同时把 `thumb_cmc_yaw` 限制在80~255,并将4个保留通道
固定为255;不得为了复现超限手势而放宽这些安全范围。
重拍超限姿势。G20的 `thumb_cmc_yaw` 使用完整0~255命令范围,4个保留通道仍固定
为255;不得修改保留通道的固定值。
只有明确希望放弃旧进度时才在原命令末尾增加 `--fresh`;该选项会覆盖旧检查点,
从第一个姿势重新开始。
@@ -93,7 +93,7 @@
"command_bounds": [
[0, 255], [0, 255], [0, 255], [0, 255], [0, 255],
[0, 255], [0, 255], [0, 255], [0, 255], [0, 255],
[80, 255], [255, 255], [255, 255], [255, 255], [255, 255],
[0, 255], [255, 255], [255, 255], [255, 255], [255, 255],
[0, 255], [0, 255], [0, 255], [0, 255], [0, 255]
],
"reserved_channels": {
@@ -248,6 +248,24 @@ def test_seed_profiles_map_named_bounded_commands(model, length):
assert result.command[11:15] == (255, 255, 255, 255)
def test_g20_thumb_yaw_uses_full_command_range():
profile = load_robot_profile(
PROFILE_DIR / "g20_seed_profile.json", "G20"
)
assert profile["command_bounds"][10] == [0.0, 255.0]
yaw_channel = next(
channel
for channel in profile["channels"]
if channel["name"] == "thumb_cmc_yaw"
)
yaw_channel["points"] = [[0.0, 255.0], [1.0, 0.0]]
intent = {name: 0.0 for name in BASE_INTENT_NAMES}
intent["thumb_rotate"] = 1.0
result = RobotMapper(profile).map(intent)
assert result.raw_command[10] == 0.0
assert result.command[10] == 0
def test_paired_pinch_anchors_only_constrain_thumb_and_target_finger():
glove_profile = build_glove_profile(
_glove_captures(),
@@ -429,9 +447,7 @@ def test_thumb_mapping_ignores_four_finger_only_pose_commands():
altered_profile = copy.deepcopy(robot_profile)
for pose_name in ("fingers_together", "tabletop", "hook"):
for command_index in (0, 5, 10, 15):
altered_profile["poses"][pose_name]["cmd_u8"][command_index] = (
80.0 if command_index == 10 else 0.0
)
altered_profile["poses"][pose_name]["cmd_u8"][command_index] = 0.0
extractor = HandIntentExtractor(glove_profile)
reference_mapper = RobotMapper(robot_profile, glove_profile)
@@ -629,9 +645,9 @@ def test_robot_pose_checkpoint_resumes_and_rejects_identity_mismatch(tmp_path):
def test_robot_capture_rejects_commands_outside_profile_safety_bounds():
seed = load_robot_profile(PROFILE_DIR / "g20_seed_profile.json", "G20")
command = list(seed["poses"]["open_spread"]["cmd_u8"])
command[10] = 79.0
command[10] = -1.0
assert _command_bound_violations(seed, command) == (
"thumb_cmc_yaw=79,允许[80, 255]",
"thumb_cmc_yaw=-1,允许[0, 255]",
)