-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathv2verifications.py
170 lines (136 loc) · 7.65 KB
/
v2verifications.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
"""
Helper functions that raise errors if a verification fails.
"""
import v2calculations
import logging
from v2calculations import calc_sphere_centers
from metrology import linePerpendicularity, angle_between, straightness, flatness
logger = logging.getLogger(__name__)
BEST_FIT_SPHERE_ERROR = 0.0254
LINEAR_HOMING_REPEATABILITY = 0.001 * 25.4 # 0.001 inches, 0.0254 mm
B_HOMING_REPEATABILITY = 0.05 # degrees
A_HOMING_REPEATABILITY = 0.08 # degrees
ANGULAR_ACCURACY = 0.05 # degrees
PERPENDICULARITY_SPEC = .002 # inches
L_BRACKET_FLATNESS = 0.0005 # inches
class CalibException(Exception):
pass
def verify_top_face_flatness(feature):
f = flatness(feature) / 25.4
logger.info(f"L bracket top face flatness is {f} inches, expected <= {L_BRACKET_FLATNESS}")
if f > L_BRACKET_FLATNESS:
err = f"L bracket top face flatness is {f} inches, expected <= {L_BRACKET_FLATNESS} inches. Ensure nothing is on the surface."
logger.error(err)
raise CalibException(err)
def verify_axes(xFeatures, yFeatures, zFeatures):
xLineFeature = calc_sphere_centers(xFeatures)
yLineFeature = calc_sphere_centers(yFeatures)
zLineFeature = calc_sphere_centers(zFeatures)
xLine = xLineFeature.line()
yLine = yLineFeature.line()
zLine = zLineFeature.line()
xyPerpendicularity = linePerpendicularity(yLineFeature, xLineFeature.line())/25.4
zyPerpendicularity = linePerpendicularity(yLineFeature, zLineFeature.line())/25.4
zxPerpendicularity = linePerpendicularity(xLineFeature, zLineFeature.line())/25.4
yxPerpendicularity = linePerpendicularity(xLineFeature, yLineFeature.line())/25.4
yzPerpendicularity = linePerpendicularity(zLineFeature, yLineFeature.line())/25.4
xzPerpendicularity = linePerpendicularity(zLineFeature, xLineFeature.line())/25.4
xStraightness = straightness(xLineFeature)/25.4
yStraightness = straightness(yLineFeature)/25.4
zStraightness = straightness(zLineFeature)/25.4
xyPerp = xyPerpendicularity if xStraightness < yStraightness else yxPerpendicularity
zxPerp = zxPerpendicularity if zStraightness < xStraightness else xzPerpendicularity
zyPerp = zyPerpendicularity if zStraightness < yStraightness else yzPerpendicularity
xyAngle = angle_between(xLine[1], yLine[1])
zxAngle = angle_between(zLine[1], xLine[1])
zyAngle = angle_between(zLine[1], yLine[1])
xyPass = xyPerp < PERPENDICULARITY_SPEC
zxPass = zxPerp < PERPENDICULARITY_SPEC
zyPass = zyPerp < PERPENDICULARITY_SPEC
overallPass = all([ xyPass, zxPass, zyPass ])
logger.info(f"XY Perpendicularity: {xyPerp:.6f} {'PASS' if xyPass else 'FAIL'}")
logger.info(f"XY Angle: {xyAngle}")
logger.info(f"ZX Perpendicularity: {zxPerp:.6f} {'PASS' if zxPass else 'FAIL'}")
logger.info(f"ZX Angle: {zxAngle}")
logger.info(f"ZY Perpendicularity: {zyPerp:.6f} {'PASS' if zyPass else 'FAIL'}")
logger.info(f"ZY Angle: {zyAngle}")
if not overallPass:
err = f"Failed perpendicularity spec of {PERPENDICULARITY_SPEC} in. XY: {xyPerp:.6f} in, {xyAngle:.4f} deg. ZX: {zxPerp:.6f} in, {zxAngle:.4f} deg. ZY: {zyPerp:.6f} in, {zyAngle:.4f} deg."
logger.error(err)
raise CalibException(err)
def verify_sphere_diameters_within_tolerance(features, expected_dia):
"""Verifies that all best fit sphere diameters in features are within BEST_FIT_SPHERE_ERROR of expected_dia."""
dia_error = v2calculations.calc_max_sphere_diameter_deviation(features, expected_dia)
if dia_error > BEST_FIT_SPHERE_ERROR:
raise CalibException("Deviation in best-fit sphere diameter. Expected <= %s, found %s" % (BEST_FIT_SPHERE_ERROR, dia_error))
def verify_linear_homing_repeatability(features, axis):
centers = v2calculations.calc_sphere_centers(features)
max_dist = v2calculations.calc_max_dist_between_points(centers)
if max_dist > LINEAR_HOMING_REPEATABILITY:
raise CalibException("%s repeatability failure, expected <= %s, found %s" % (axis, LINEAR_HOMING_REPEATABILITY, max_dist))
return (max_dist, LINEAR_HOMING_REPEATABILITY)
def verify_x_homing_accuracy(homing_features, offsets_features, x_dir, y_dir, z_dir):
homing_error = v2calculations.calc_home_offset_x_error(x_dir, y_dir, z_dir, homing_features, offsets_features)
if abs(homing_error) > LINEAR_HOMING_REPEATABILITY:
raise CalibException("X homing accuracy failure, expected error <= %s, found %s" % (LINEAR_HOMING_REPEATABILITY, homing_error))
return (homing_error, LINEAR_HOMING_REPEATABILITY)
def verify_y_homing_accuracy(homing_features, offsets_features, x_dir, y_dir, z_dir, origin):
homing_error = v2calculations.calc_home_offset_y_error(x_dir, y_dir, z_dir, homing_features, offsets_features)
if abs(homing_error) > LINEAR_HOMING_REPEATABILITY:
raise CalibException("Y homing accuracy failure, expected error <= %s, found %s" % (LINEAR_HOMING_REPEATABILITY, homing_error))
return (homing_error, LINEAR_HOMING_REPEATABILITY)
def verify_a_homing_accuracy(homing_features, x_dir, y_dir, z_dir, origin):
homing_error = v2calculations.calc_homing_error_a(homing_features, x_dir, y_dir, z_dir)
if abs(homing_error) > A_HOMING_REPEATABILITY:
raise CalibException("A homing accuracy failure, expected error <= %s, found %s" % (A_HOMING_REPEATABILITY, homing_error))
return (homing_error, LINEAR_HOMING_REPEATABILITY)
def verify_b_homing_accuracy(homing_features, x_dir, y_dir, z_dir, origin):
homing_error = v2calculations.calc_homing_error_b(homing_features, x_dir, y_dir, z_dir)
if abs(homing_error) > B_HOMING_REPEATABILITY:
raise CalibException("B homing accuracy failure, expected error <= %s, found %s" % (B_HOMING_REPEATABILITY, homing_error))
return (homing_error, LINEAR_HOMING_REPEATABILITY)
def verify_a_homing_repeatability(features, x_dir, y_dir, z_dir, origin):
positions = []
for a_line in features:
a_pos = v2calculations.calc_pos_a(a_line, x_dir, y_dir, z_dir, origin)
positions.append(a_pos)
max_diff = v2calculations.calc_max_diff(positions)
if max_diff > A_HOMING_REPEATABILITY:
raise CalibException("A repeatability failure, expected <= %s, found %s" % (A_HOMING_REPEATABILITY, max_diff))
return (max_diff, A_HOMING_REPEATABILITY)
def verify_b_homing_repeatability(features, x_dir, y_dir, z_dir, origin):
positions = []
for b_line in features:
b_pos = v2calculations.calc_pos_b(b_line, x_dir, y_dir, z_dir, origin)
positions.append(b_pos)
max_diff = v2calculations.calc_max_diff(positions)
if max_diff > B_HOMING_REPEATABILITY:
raise CalibException("B repeatability failure, expected <= %s, found %s" % (B_HOMING_REPEATABILITY, max_diff))
return (max_diff, B_HOMING_REPEATABILITY)
def verify_linear_axis_direction(dir1,dir2):
"""
Sanity check that linear axes are reasonably parallel with the L bracket.
The L bracket surfaces are not precision, so this is only a sanity check,
not any kind of spec.
"""
parallelism = v2calculations.calc_parallelism(dir1,dir2,6)
# error beyond above .05" over 6" (~.5 degrees)
LIMIT = .05
if parallelism > LIMIT:
raise CalibError("Linear axis parallelism exceeds reasonable limits: %s, %s, %s, expected <= %s" % (dir1,dir2,parallelism, LIMIT))
else:
logger.debug("Linear axis parallelism: %s, %s, %s, expected <= %s", dir1, dir2, parallelism, LIMIT)
def verify_rotary_accuracy(errors, axis):
"""
Check if error exceeded spec at any position for a set of rotary axis features
"""
max_error_pair = (0,0)
failures = []
for (pos, err) in errors:
if abs(err) > abs(max_error_pair[1]):
max_error_pair = (pos,err)
if abs(err) > ANGULAR_ACCURACY:
failures.append((pos,err))
if len(failures) > 0:
raise CalibException("%s accuracy failure. Expected max error <= %s exceeded at following points (pos, err): %s" % (axis, ANGULAR_ACCURACY, str(failures).strip('[]')))
return (max_error_pair,ANGULAR_ACCURACY)