把存储的 yaw 上限归一到 ±180
yaw 台转 ±180,实测点的第二组精确解落在 118° 之外:旧文件里的 ±90 会让求解器把位姿算成可达、运动守卫却拒绝这段 yaw,操作员看到的就是“到不了”。加载时把求解器与守卫两种写法的 yaw 上限一起归一,pitch 包络此前已按同一理由处理。
This commit is contained in:
@@ -122,6 +122,41 @@ def test_a_stored_block_without_a_new_limit_still_gets_it():
|
||||
assert "press_axis" not in prefs["sensor_setup"]
|
||||
|
||||
|
||||
def test_a_stored_quarter_turn_yaw_limit_is_normalised_to_the_bench_travel():
|
||||
"""A stored ±90 makes a solvable pose read as unreachable.
|
||||
|
||||
The yaw stage turns ±180, and a measured point's second exact solution sits past
|
||||
118° of yaw: at ±90 the solver is left with one branch and the move guard refuses
|
||||
the other, so a pose the preview aligned reports "cannot reach". Both spellings of
|
||||
the limit — the solver's ``finger_yaw_limit_deg`` and the guard's
|
||||
``safety_limits.max_yaw_deg`` — are the same bench fact, so both are normalised.
|
||||
"""
|
||||
from orisys_app_shared.paths import preference_path
|
||||
|
||||
from orisys_autocal.preferences import load_preferences
|
||||
|
||||
path = preference_path()
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"safety_limits": {"max_yaw_deg": 90.0, "max_pitch_deg": 360.0},
|
||||
"finger_yaw_limit_deg": 90.0,
|
||||
"finger_pitch_limit_deg": 360.0,
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
prefs = load_preferences()
|
||||
|
||||
assert prefs["safety_limits"]["max_yaw_deg"] == 180.0
|
||||
assert prefs["finger_yaw_limit_deg"] == 180.0
|
||||
# The pitch envelope keeps the correction it already had, so the two do not drift.
|
||||
assert prefs["safety_limits"]["max_pitch_deg"] == 90.0
|
||||
assert prefs["finger_pitch_limit_deg"] == 90.0
|
||||
|
||||
|
||||
def _walk(node, prefix: str = ""):
|
||||
for key, value in node.items():
|
||||
path = f"{prefix}{key}"
|
||||
|
||||
Reference in New Issue
Block a user