FA-12101 / Robotics frame conventions / Open access
An inverse sensor pose negates translation in the wrong frame · case 01
An inverse sensor pose negates translation in the wrong frame.
ROOT CAUSE
Translation is negated without applying the inverse orientation.
VERIFIED REPAIR
Use inverse rotation on both coordinates and negated origin.
Unsuccessful approach: Rotating the negative translation by the forward orientation only works at some headings.
Case contract
Pose maps child to parent by p_parent=R(q)*p_child+t. Return inverse translation for integer t and quarter-turn q.
Why this case matters
Robot adapters must preserve the declared frame, reference point, and representation conventions across interfaces.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
def rot(v, q):
x,y = v
return [(x,y),(-y,x),(-x,-y),(y,-x)][q%4]
N = 1
observations = []
def solve(t, q):
return [-t[0],-t[1]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('quarter turn', solve([N,2*N],1), [-2*N,N])
check('negative quarter', solve([N,2*N],-1), [2*N,-N])
check('identity', solve([N,2*N],0), [-N,-2*N])
check('half turn', solve([N,2*N],2), [N,2*N])
check('origin', solve([0,0],1), [0,0])
check('full turns', solve([N,-N],5), [N,N])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| quarter turn | [-1, -2] | [-2, 1] | Failed |
| negative quarter | [-1, -2] | [2, -1] | Failed |
| identity | [-1, -2] | [-1, -2] | Passed |
| half turn | [-1, -2] | [1, 2] | Failed |
| origin | [0, 0] | [0, 0] | Passed |
| full turns | [-1, 1] | [1, 1] | Failed |
SHA-256 / 271434660dde3e375e2dd475fdf709ec21acee8513b58a19553b5a2bc6f8b4a5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
def rot(v, q):
x,y = v
return [(x,y),(-y,x),(-x,-y),(y,-x)][q%4]
N = 1
observations = []
def solve(t, q):
return list(rot([-t[0],-t[1]],q))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('quarter turn', solve([N,2*N],1), [-2*N,N])
check('negative quarter', solve([N,2*N],-1), [2*N,-N])
check('identity', solve([N,2*N],0), [-N,-2*N])
check('half turn', solve([N,2*N],2), [N,2*N])
check('origin', solve([0,0],1), [0,0])
check('full turns', solve([N,-N],5), [N,N])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| quarter turn | [2, -1] | [-2, 1] | Failed |
| negative quarter | [-2, 1] | [2, -1] | Failed |
| identity | [-1, -2] | [-1, -2] | Passed |
| half turn | [1, 2] | [1, 2] | Passed |
| origin | [0, 0] | [0, 0] | Passed |
| full turns | [-1, -1] | [1, 1] | Failed |
SHA-256 / 090c364a99aca2fbcc3f13b86dadc5a3170abf388cd3f8edf9fc7b6bfb6de1c5
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
def rot(v, q):
x,y = v
return [(x,y),(-y,x),(-x,-y),(y,-x)][q%4]
N = 1
observations = []
def solve(t, q):
return list(rot([-t[0],-t[1]],-q))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('quarter turn', solve([N,2*N],1), [-2*N,N])
check('negative quarter', solve([N,2*N],-1), [2*N,-N])
check('identity', solve([N,2*N],0), [-N,-2*N])
check('half turn', solve([N,2*N],2), [N,2*N])
check('origin', solve([0,0],1), [0,0])
check('full turns', solve([N,-N],5), [N,N])
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| quarter turn | [-2, 1] | [-2, 1] | Passed |
| negative quarter | [2, -1] | [2, -1] | Passed |
| identity | [-1, -2] | [-1, -2] | Passed |
| half turn | [1, 2] | [1, 2] | Passed |
| origin | [0, 0] | [0, 0] | Passed |
| full turns | [1, 1] | [1, 1] | Passed |
SHA-256 / c7d8caf0a640864b82a91dd32bc70ef04a65325a8a1923be30e01638e66ad766
Verification & scope
Small exact offline frame model; not a robot middleware implementation or continuous pose estimator. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:38:53.733618+00:00.
Case digest / 86b8b2281b199258c9b5cc20057f52107e1190f85141919652322ac7c59ded19