{"abstract":"At b=180 the returned g has the wrong sign relation to the rotation.","category":"Inverse kinematics solvers","checks":7,"contract":"Input [R, flip]: R is a 3x3 wrist rotation R = Rz(a) Ry(b) Rz(g). Return [a,b,g] in degrees rounded to 4. With flip false b is in [0,180]; with flip true b is negative and a,g are shifted by 180 degrees. When hypot(R02,R12) < 1e-9 the wrist is singular: a=0 and b=0 (R22>0, g=atan2(R10,R00)) or b=180 (g=atan2(R01,-R00)).","evaluation_group":"w2-inverse_kinematics_solvers-spherical-wrist-zyz","failed_approach":"Negating R01 instead of R00 mirrors g about the x axis.","family":"w2-inverse_kinematics_solvers-spherical-wrist-zyz-inverted-singular-roll","id":"FA-88061","implementations":{"attempt":{"sha256":"450d62f363703e26767f12ed020de7c8e71e375cc5469b27b10939b9108f9911","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    R,flip=x\n    sb=math.hypot(R[0][2],R[1][2])\n    if sb<1e-9:\n        if R[2][2]>0: return [0.0,0.0,round(math.degrees(math.atan2(R[1][0],R[0][0])),4)]\n        return [0.0,180.0,round(math.degrees(math.atan2(-R[0][1],-R[0][0])),4)]\n    if flip:\n        b=math.atan2(-sb,R[2][2])\n        a=math.atan2(-R[1][2],-R[0][2])\n        g=math.atan2(-R[2][1],R[2][0])\n    else:\n        b=math.atan2(sb,R[2][2])\n        a=math.atan2(R[1][2],R[0][2])\n        g=math.atan2(R[2][1],-R[2][0])\n    return [round(math.degrees(v),4) for v in (a,b,g)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['large tilt no flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], False]], [-60.0, 130.0, 20.0]], ['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]]], [['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['negative angles', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], False]], [-120.0, 75.0, -150.0]], ['negative angles flip', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], True]], [60.0, -75.0, 30.0]]], [['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['negative angles', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], False]], [-120.0, 75.0, -150.0]], ['negative angles flip', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], True]], [60.0, -75.0, 30.0]], ['tilt 90', [[[[0.49999999999999994, -0.49999999999999994, 0.7071067811865476], [-0.49999999999999994, 0.5000000000000001, 0.7071067811865475], [-0.7071067811865476, -0.7071067811865475, 6.123233995736766e-17]], False]], [45.0, 90.0, -45.0]], ['back quadrant', [[[[-0.08550503583141712, 0.515076844803523, -0.8528685319524432], [-0.984923155196477, 0.08550503583141716, 0.15038373318043521], [0.15038373318043524, 0.8528685319524432, 0.5000000000000001]], False]], [170.0, 60.0, 100.0]], ['inverted with roll', [[[[0.49999999999999983, -0.8660254037844387, 1.2246467991473532e-16], [-0.8660254037844387, -0.49999999999999983, 0.0], [6.123233995736764e-17, -1.0605752387249069e-16, -1.0]], False]], [0.0, 180.0, -120.0]]], [['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['tilt 90', [[[[0.49999999999999994, -0.49999999999999994, 0.7071067811865476], [-0.49999999999999994, 0.5000000000000001, 0.7071067811865475], [-0.7071067811865476, -0.7071067811865475, 6.123233995736766e-17]], False]], [45.0, 90.0, -45.0]], ['back quadrant', [[[[-0.08550503583141712, 0.515076844803523, -0.8528685319524432], [-0.984923155196477, 0.08550503583141716, 0.15038373318043521], [0.15038373318043524, 0.8528685319524432, 0.5000000000000001]], False]], [170.0, 60.0, 100.0]], ['inverted with roll', [[[[0.49999999999999983, -0.8660254037844387, 1.2246467991473532e-16], [-0.8660254037844387, -0.49999999999999983, 0.0], [6.123233995736764e-17, -1.0605752387249069e-16, -1.0]], False]], [0.0, 180.0, -120.0]], ['small tilt flip', [[[[0.34136939837363944, -0.9398073646785109, 0.015134435901338627], [0.9360020627702564, 0.34136939837363944, 0.08583165117743129], [-0.08583165117743129, -0.01513443590133862, 0.9961946980917455]], True]], [-100.0, -5.0, 170.0]]], [['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['large tilt no flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], False]], [-60.0, 130.0, 20.0]], ['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['small tilt flip', [[[[0.34136939837363944, -0.9398073646785109, 0.015134435901338627], [0.9360020627702564, 0.34136939837363944, 0.08583165117743129], [-0.08583165117743129, -0.01513443590133862, 0.9961946980917455]], True]], [-100.0, -5.0, 170.0]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"97388db3d7b588f0120a1442fff12f621fee38b372f8e8cac17a2cec5b7ebc7d","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    R,flip=x\n    sb=math.hypot(R[0][2],R[1][2])\n    if sb<1e-9:\n        if R[2][2]>0: return [0.0,0.0,round(math.degrees(math.atan2(R[1][0],R[0][0])),4)]\n        return [0.0,180.0,round(math.degrees(math.atan2(R[1][0],R[0][0])),4)]\n    if flip:\n        b=math.atan2(-sb,R[2][2])\n        a=math.atan2(-R[1][2],-R[0][2])\n        g=math.atan2(-R[2][1],R[2][0])\n    else:\n        b=math.atan2(sb,R[2][2])\n        a=math.atan2(R[1][2],R[0][2])\n        g=math.atan2(R[2][1],-R[2][0])\n    return [round(math.degrees(v),4) for v in (a,b,g)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['large tilt no flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], False]], [-60.0, 130.0, 20.0]], ['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]]], [['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['negative angles', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], False]], [-120.0, 75.0, -150.0]], ['negative angles flip', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], True]], [60.0, -75.0, 30.0]]], [['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['negative angles', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], False]], [-120.0, 75.0, -150.0]], ['negative angles flip', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], True]], [60.0, -75.0, 30.0]], ['tilt 90', [[[[0.49999999999999994, -0.49999999999999994, 0.7071067811865476], [-0.49999999999999994, 0.5000000000000001, 0.7071067811865475], [-0.7071067811865476, -0.7071067811865475, 6.123233995736766e-17]], False]], [45.0, 90.0, -45.0]], ['back quadrant', [[[[-0.08550503583141712, 0.515076844803523, -0.8528685319524432], [-0.984923155196477, 0.08550503583141716, 0.15038373318043521], [0.15038373318043524, 0.8528685319524432, 0.5000000000000001]], False]], [170.0, 60.0, 100.0]], ['inverted with roll', [[[[0.49999999999999983, -0.8660254037844387, 1.2246467991473532e-16], [-0.8660254037844387, -0.49999999999999983, 0.0], [6.123233995736764e-17, -1.0605752387249069e-16, -1.0]], False]], [0.0, 180.0, -120.0]]], [['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['tilt 90', [[[[0.49999999999999994, -0.49999999999999994, 0.7071067811865476], [-0.49999999999999994, 0.5000000000000001, 0.7071067811865475], [-0.7071067811865476, -0.7071067811865475, 6.123233995736766e-17]], False]], [45.0, 90.0, -45.0]], ['back quadrant', [[[[-0.08550503583141712, 0.515076844803523, -0.8528685319524432], [-0.984923155196477, 0.08550503583141716, 0.15038373318043521], [0.15038373318043524, 0.8528685319524432, 0.5000000000000001]], False]], [170.0, 60.0, 100.0]], ['inverted with roll', [[[[0.49999999999999983, -0.8660254037844387, 1.2246467991473532e-16], [-0.8660254037844387, -0.49999999999999983, 0.0], [6.123233995736764e-17, -1.0605752387249069e-16, -1.0]], False]], [0.0, 180.0, -120.0]], ['small tilt flip', [[[[0.34136939837363944, -0.9398073646785109, 0.015134435901338627], [0.9360020627702564, 0.34136939837363944, 0.08583165117743129], [-0.08583165117743129, -0.01513443590133862, 0.9961946980917455]], True]], [-100.0, -5.0, 170.0]]], [['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['large tilt no flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], False]], [-60.0, 130.0, 20.0]], ['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['small tilt flip', [[[[0.34136939837363944, -0.9398073646785109, 0.015134435901338627], [0.9360020627702564, 0.34136939837363944, 0.08583165117743129], [-0.08583165117743129, -0.01513443590133862, 0.9961946980917455]], True]], [-100.0, -5.0, 170.0]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"429780cd5f6afad9aca9d348ea1357eb02bb3579c6193680fe0ebdf597cdadb0","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    R,flip=x\n    sb=math.hypot(R[0][2],R[1][2])\n    if sb<1e-9:\n        if R[2][2]>0: return [0.0,0.0,round(math.degrees(math.atan2(R[1][0],R[0][0])),4)]\n        return [0.0,180.0,round(math.degrees(math.atan2(R[0][1],-R[0][0])),4)]\n    if flip:\n        b=math.atan2(-sb,R[2][2])\n        a=math.atan2(-R[1][2],-R[0][2])\n        g=math.atan2(-R[2][1],R[2][0])\n    else:\n        b=math.atan2(sb,R[2][2])\n        a=math.atan2(R[1][2],R[0][2])\n        g=math.atan2(R[2][1],-R[2][0])\n    return [round(math.degrees(v),4) for v in (a,b,g)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['large tilt no flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], False]], [-60.0, 130.0, 20.0]], ['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]]], [['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['negative angles', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], False]], [-120.0, 75.0, -150.0]], ['negative angles flip', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], True]], [60.0, -75.0, 30.0]]], [['exact upright', [[[[0.766044443118978, -0.6427876096865393, 0.0], [0.6427876096865393, 0.766044443118978, 0.0], [-0.0, 0.0, 1.0]], False]], [0.0, 0.0, 40.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['negative angles', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], False]], [-120.0, 75.0, -150.0]], ['negative angles flip', [[[[-0.3209407678712127, -0.8147047612756303, -0.482962913144534], [0.44411428382689044, 0.3209407678712125, -0.8365163037378079], [0.8365163037378079, -0.4829629131445341, 0.25881904510252074]], True]], [60.0, -75.0, 30.0]], ['tilt 90', [[[[0.49999999999999994, -0.49999999999999994, 0.7071067811865476], [-0.49999999999999994, 0.5000000000000001, 0.7071067811865475], [-0.7071067811865476, -0.7071067811865475, 6.123233995736766e-17]], False]], [45.0, 90.0, -45.0]], ['back quadrant', [[[[-0.08550503583141712, 0.515076844803523, -0.8528685319524432], [-0.984923155196477, 0.08550503583141716, 0.15038373318043521], [0.15038373318043524, 0.8528685319524432, 0.5000000000000001]], False]], [170.0, 60.0, 100.0]], ['inverted with roll', [[[[0.49999999999999983, -0.8660254037844387, 1.2246467991473532e-16], [-0.8660254037844387, -0.49999999999999983, 0.0], [6.123233995736764e-17, -1.0605752387249069e-16, -1.0]], False]], [0.0, 180.0, -120.0]]], [['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['near inverted singular', [[[[-0.5, 0.8660254037844385, 1.718814073341628e-10], [0.8660254037844385, 0.5, 3.030732959515473e-11], [-5.969378631680947e-11, 1.6400732998718326e-10, -1.0]], False]], [0.0, 180.0, 60.0]], ['tilt 90', [[[[0.49999999999999994, -0.49999999999999994, 0.7071067811865476], [-0.49999999999999994, 0.5000000000000001, 0.7071067811865475], [-0.7071067811865476, -0.7071067811865475, 6.123233995736766e-17]], False]], [45.0, 90.0, -45.0]], ['back quadrant', [[[[-0.08550503583141712, 0.515076844803523, -0.8528685319524432], [-0.984923155196477, 0.08550503583141716, 0.15038373318043521], [0.15038373318043524, 0.8528685319524432, 0.5000000000000001]], False]], [170.0, 60.0, 100.0]], ['inverted with roll', [[[[0.49999999999999983, -0.8660254037844387, 1.2246467991473532e-16], [-0.8660254037844387, -0.49999999999999983, 0.0], [6.123233995736764e-17, -1.0605752387249069e-16, -1.0]], False]], [0.0, 180.0, -120.0]], ['small tilt flip', [[[[0.34136939837363944, -0.9398073646785109, 0.015134435901338627], [0.9360020627702564, 0.34136939837363944, 0.08583165117743129], [-0.08583165117743129, -0.01513443590133862, 0.9961946980917455]], True]], [-100.0, -5.0, 170.0]]], [['generic no flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], False]], [30.0, 40.0, 50.0]], ['generic flip', [[[[0.04341204441673269, -0.8295983733257066, 0.5566703992264194], [0.9096158864219903, 0.26325835480968696, 0.32139380484326957], [-0.4131759111665348, 0.49240387650610395, 0.766044443118978]], True]], [-150.0, -40.0, -130.0]], ['large tilt no flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], False]], [-60.0, 130.0, 20.0]], ['large tilt flip', [[[[-0.005813254051503125, 0.9237208365458508, 0.3830222215594891], [0.6941091380258464, 0.2794538206643772, -0.6634139481689384], [-0.7198463103929542, 0.2620026302293849, -0.6427876096865394]], True]], [120.0, -130.0, -160.0]], ['near upright singular', [[[[0.5, -0.8660254037844386, 1.5818054920253123e-10], [0.8660254037844386, 0.5, 7.376080146430387e-11], [-1.429690024728532e-10, 1.0010797326181444e-10, 1.0]], False]], [0.0, 0.0, 60.0]], ['exact inverted', [[[[-0.766044443118978, 0.6427876096865393, 1.2246467991473532e-16], [0.6427876096865393, 0.766044443118978, 0.0], [-9.381338752702731e-17, 7.871877887341985e-17, -1.0]], True]], [0.0, 180.0, 40.0]], ['small tilt flip', [[[[0.34136939837363944, -0.9398073646785109, 0.015134435901338627], [0.9360020627702564, 0.34136939837363944, 0.08583165117743129], [-0.08583165117743129, -0.01513443590133862, 0.9961946980917455]], True]], [-100.0, -5.0, 170.0]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"Deterministic planar or low-dimensional teaching model with a stipulated convention; not a general robotics library. 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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-inverse_kinematics_solvers-spherical-wrist-zyz-inverted-singular-roll","generated_at":"2026-09-29T14:51:04.560547+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Inverse kinematics code turns task-space goals into joint commands; a wrong branch, sign, limit or update order sends a real arm to the wrong pose.","repair":"For b=180 with a=0, use g = atan2(R01, -R00).","root_cause":"The b=180 branch computes g from atan2(R10,R00), which is only valid for b=0.","sha256":"564a7d1bd40f623b07425ebd005dfc5a022f3b6766809fc334a4d27ba0f70977","title":"Inverted wrist singularity reuses the upright roll formula · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":41.189,"exit_code":1,"observations":[{"actual":[30.0,40.0,50.0],"check":"generic no flip","expected":[30.0,40.0,50.0],"passed":true},{"actual":[-150.0,-40.0,-130.0],"check":"generic flip","expected":[-150.0,-40.0,-130.0],"passed":true},{"actual":[-60.0,130.0,20.0],"check":"large tilt no flip","expected":[-60.0,130.0,20.0],"passed":true},{"actual":[120.0,-130.0,-160.0],"check":"large tilt flip","expected":[120.0,-130.0,-160.0],"passed":true},{"actual":[0.0,0.0,60.0],"check":"near upright singular","expected":[0.0,0.0,60.0],"passed":true},{"actual":[0.0,180.0,-60.0],"check":"near inverted singular","expected":[0.0,180.0,60.0],"passed":false},{"actual":[0.0,0.0,40.0],"check":"exact upright","expected":[0.0,0.0,40.0],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"generic no flip\", \"actual\": [30.0, 40.0, 50.0], \"expected\": [30.0, 40.0, 50.0], \"passed\": true}, {\"check\": \"generic flip\", \"actual\": [-150.0, -40.0, -130.0], \"expected\": [-150.0, -40.0, -130.0], \"passed\": true}, {\"check\": \"large tilt no flip\", \"actual\": [-60.0, 130.0, 20.0], \"expected\": [-60.0, 130.0, 20.0], \"passed\": true}, {\"check\": \"large tilt flip\", \"actual\": [120.0, -130.0, -160.0], \"expected\": [120.0, -130.0, -160.0], \"passed\": true}, {\"check\": \"near upright singular\", \"actual\": [0.0, 0.0, 60.0], \"expected\": [0.0, 0.0, 60.0], \"passed\": true}, {\"check\": \"near inverted singular\", \"actual\": [0.0, 180.0, -60.0], \"expected\": [0.0, 180.0, 60.0], \"passed\": false}, {\"check\": \"exact upright\", \"actual\": [0.0, 0.0, 40.0], \"expected\": [0.0, 0.0, 40.0], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.436,"exit_code":1,"observations":[{"actual":[30.0,40.0,50.0],"check":"generic no flip","expected":[30.0,40.0,50.0],"passed":true},{"actual":[-150.0,-40.0,-130.0],"check":"generic flip","expected":[-150.0,-40.0,-130.0],"passed":true},{"actual":[-60.0,130.0,20.0],"check":"large tilt no flip","expected":[-60.0,130.0,20.0],"passed":true},{"actual":[120.0,-130.0,-160.0],"check":"large tilt flip","expected":[120.0,-130.0,-160.0],"passed":true},{"actual":[0.0,0.0,60.0],"check":"near upright singular","expected":[0.0,0.0,60.0],"passed":true},{"actual":[0.0,180.0,120.0],"check":"near inverted singular","expected":[0.0,180.0,60.0],"passed":false},{"actual":[0.0,0.0,40.0],"check":"exact upright","expected":[0.0,0.0,40.0],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"generic no flip\", \"actual\": [30.0, 40.0, 50.0], \"expected\": [30.0, 40.0, 50.0], \"passed\": true}, {\"check\": \"generic flip\", \"actual\": [-150.0, -40.0, -130.0], \"expected\": [-150.0, -40.0, -130.0], \"passed\": true}, {\"check\": \"large tilt no flip\", \"actual\": [-60.0, 130.0, 20.0], \"expected\": [-60.0, 130.0, 20.0], \"passed\": true}, {\"check\": \"large tilt flip\", \"actual\": [120.0, -130.0, -160.0], \"expected\": [120.0, -130.0, -160.0], \"passed\": true}, {\"check\": \"near upright singular\", \"actual\": [0.0, 0.0, 60.0], \"expected\": [0.0, 0.0, 60.0], \"passed\": true}, {\"check\": \"near inverted singular\", \"actual\": [0.0, 180.0, 120.0], \"expected\": [0.0, 180.0, 60.0], \"passed\": false}, {\"check\": \"exact upright\", \"actual\": [0.0, 0.0, 40.0], \"expected\": [0.0, 0.0, 40.0], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":38.627,"exit_code":0,"observations":[{"actual":[30.0,40.0,50.0],"check":"generic no flip","expected":[30.0,40.0,50.0],"passed":true},{"actual":[-150.0,-40.0,-130.0],"check":"generic flip","expected":[-150.0,-40.0,-130.0],"passed":true},{"actual":[-60.0,130.0,20.0],"check":"large tilt no flip","expected":[-60.0,130.0,20.0],"passed":true},{"actual":[120.0,-130.0,-160.0],"check":"large tilt flip","expected":[120.0,-130.0,-160.0],"passed":true},{"actual":[0.0,0.0,60.0],"check":"near upright singular","expected":[0.0,0.0,60.0],"passed":true},{"actual":[0.0,180.0,60.0],"check":"near inverted singular","expected":[0.0,180.0,60.0],"passed":true},{"actual":[0.0,0.0,40.0],"check":"exact upright","expected":[0.0,0.0,40.0],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"generic no flip\", \"actual\": [30.0, 40.0, 50.0], \"expected\": [30.0, 40.0, 50.0], \"passed\": true}, {\"check\": \"generic flip\", \"actual\": [-150.0, -40.0, -130.0], \"expected\": [-150.0, -40.0, -130.0], \"passed\": true}, {\"check\": \"large tilt no flip\", \"actual\": [-60.0, 130.0, 20.0], \"expected\": [-60.0, 130.0, 20.0], \"passed\": true}, {\"check\": \"large tilt flip\", \"actual\": [120.0, -130.0, -160.0], \"expected\": [120.0, -130.0, -160.0], \"passed\": true}, {\"check\": \"near upright singular\", \"actual\": [0.0, 0.0, 60.0], \"expected\": [0.0, 0.0, 60.0], \"passed\": true}, {\"check\": \"near inverted singular\", \"actual\": [0.0, 180.0, 60.0], \"expected\": [0.0, 180.0, 60.0], \"passed\": true}, {\"check\": \"exact upright\", \"actual\": [0.0, 0.0, 40.0], \"expected\": [0.0, 0.0, 40.0], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}