32
32
33
33
# Test Parameters
34
34
FORCE_SPEED = 10
35
- FORCE_MARGIN = 15 # Percentage
36
- FORCE_TEST_SETTINGS = [
37
- {"CURRENT" : 0.15 , "F_MAX" : 50 },
38
- {"CURRENT" : 0.2 , "F_MAX" : 73 },
39
- {"CURRENT" : 0.3 , "F_MAX" : 120 },
40
- {"CURRENT" : 0.4 , "F_MAX" : 160 },
41
- {"CURRENT" : 0.5 , "F_MAX" : 200 },
42
- {"CURRENT" : 0.6 , "F_MAX" : 230 },
43
- {"CURRENT" : 0.7 , "F_MAX" : 260 },
44
- {"CURRENT" : 1.4 , "F_MAX" : 480 },
45
- {"CURRENT" : 1.5 , "F_MAX" : 520 },
35
+ FORCE_MARGIN = 35 # Percentage
36
+ FORCE_TEST_LEFT_SETTINGS = [
37
+ {"CURRENT" : 0.15 , "F_MAX" : 39 },
38
+ {"CURRENT" : 0.2 , "F_MAX" : 63 },
39
+ {"CURRENT" : 0.3 , "F_MAX" : 107 },
40
+ {"CURRENT" : 0.4 , "F_MAX" : 148 },
41
+ {"CURRENT" : 0.5 , "F_MAX" : 189 },
42
+ {"CURRENT" : 0.6 , "F_MAX" : 226 },
43
+ {"CURRENT" : 0.7 , "F_MAX" : 259 },
44
+ {"CURRENT" : 1.4 , "F_MAX" : 498 },
45
+ {"CURRENT" : 1.5 , "F_MAX" : 528 },
46
46
]
47
+ FORCE_TEST_RIGHT_SETTINGS = [
48
+ {"CURRENT" : 0.15 , "F_MAX" : 35 },
49
+ {"CURRENT" : 0.2 , "F_MAX" : 57 },
50
+ {"CURRENT" : 0.3 , "F_MAX" : 98 },
51
+ {"CURRENT" : 0.4 , "F_MAX" : 129 },
52
+ {"CURRENT" : 0.5 , "F_MAX" : 168 },
53
+ {"CURRENT" : 0.6 , "F_MAX" : 196 },
54
+ {"CURRENT" : 0.7 , "F_MAX" : 228 },
55
+ {"CURRENT" : 1.4 , "F_MAX" : 410 },
56
+ {"CURRENT" : 1.5 , "F_MAX" : 448 },
57
+ ]
58
+
59
+ ONLY_COUNT_USING_CURRENT_YIELD = True
47
60
CYCLES_CURRENT = 5
48
61
49
- TEST_PARAMETERS : Dict [str , float ] = {
62
+ TEST_LEFT_PARAMETERS : Dict [str , float ] = {
63
+ "SPEED" : FORCE_SPEED ,
64
+ "FORCE_MARGIN" : FORCE_MARGIN ,
65
+ "CYCLES" : CYCLES_CURRENT ,
66
+ }
67
+
68
+ TEST_RIGHT_PARAMETERS : Dict [str , float ] = {
50
69
"SPEED" : FORCE_SPEED ,
51
70
"FORCE_MARGIN" : FORCE_MARGIN ,
52
71
"CYCLES" : CYCLES_CURRENT ,
53
72
}
54
- for i in FORCE_TEST_SETTINGS :
55
- TEST_PARAMETERS [str (i ["CURRENT" ])] = i ["F_MAX" ]
56
73
74
+ for i in FORCE_TEST_LEFT_SETTINGS :
75
+ TEST_LEFT_PARAMETERS [str (i ["CURRENT" ])] = i ["F_MAX" ]
76
+
77
+ for i in FORCE_TEST_RIGHT_SETTINGS :
78
+ TEST_RIGHT_PARAMETERS [str (i ["CURRENT" ])] = i ["F_MAX" ]
57
79
58
80
# Global variables
59
81
thread_sensor = False
60
82
force_output = []
83
+ valid_fail = []
61
84
62
85
63
86
def _connect_to_mark10_fixture (simulate : bool ) -> Union [Mark10 , SimMark10 ]:
@@ -81,7 +104,7 @@ def build_test_lines() -> List[Union[CSVLine, CSVLineRepeating]]:
81
104
mount_data_line : List [Union [CSVLine , CSVLineRepeating ]] = [
82
105
CSVLine ("TEST_CURRENTS" , [str , str , str , str , str ])
83
106
]
84
- for setting in FORCE_TEST_SETTINGS :
107
+ for setting in FORCE_TEST_LEFT_SETTINGS :
85
108
mount_data_line .append (
86
109
CSVLine (
87
110
_get_test_tag (setting ["CURRENT" ]),
@@ -98,8 +121,18 @@ def _build_csv_report() -> CSVReport:
98
121
test_name = "z-stage-test-qc-ot3" ,
99
122
sections = [
100
123
CSVSection (
101
- title = "TEST_PARAMETERS" ,
102
- lines = [CSVLine (parameter , [int ]) for parameter in TEST_PARAMETERS ],
124
+ title = "TEST_LEFT_PARAMETERS" ,
125
+ lines = [
126
+ CSVLine (parameter , [int , CSVResult ])
127
+ for parameter in TEST_LEFT_PARAMETERS
128
+ ],
129
+ ),
130
+ CSVSection (
131
+ title = "TEST_RIGHT_PARAMETERS" ,
132
+ lines = [
133
+ CSVLine (parameter , [int , CSVResult ])
134
+ for parameter in TEST_RIGHT_PARAMETERS
135
+ ],
103
136
),
104
137
CSVSection (
105
138
title = OT3Mount .LEFT .name ,
@@ -190,7 +223,6 @@ def check_force(
190
223
qc_pass = True
191
224
else :
192
225
qc_pass = False
193
-
194
226
_tag = _get_test_tag (current )
195
227
report (
196
228
mount .name ,
@@ -203,12 +235,15 @@ def check_force(
203
235
CSVResult .from_bool (qc_pass ),
204
236
],
205
237
)
206
-
207
238
return qc_pass
208
239
209
240
210
241
async def _force_gauge (
211
- api : OT3API , mount : OT3Mount , report : CSVReport , simulate : bool
242
+ api : OT3API ,
243
+ mount : OT3Mount ,
244
+ report : CSVReport ,
245
+ simulate : bool ,
246
+ arguments : argparse .Namespace ,
212
247
) -> bool :
213
248
"""Apply force to the gague and log."""
214
249
global thread_sensor
@@ -235,11 +270,40 @@ async def _force_gauge(
235
270
["MAX" , "MAX_RANGE" , "AVERAGE" , "AVERAGE_RANGE" , "RESULT" ],
236
271
)
237
272
# Test each current setting
238
- for test in FORCE_TEST_SETTINGS :
273
+ if mount == OT3Mount .LEFT :
274
+ force_test_setting = FORCE_TEST_LEFT_SETTINGS
275
+ else :
276
+ force_test_setting = FORCE_TEST_RIGHT_SETTINGS
277
+ for test in force_test_setting :
239
278
# Test each current setting several times and average the results
240
279
max_results = []
241
280
avg_results = []
242
281
test_current = test ["CURRENT" ]
282
+ if arguments .user_current == "None" :
283
+ pass
284
+ else :
285
+ if test_current != float (arguments .user_current ):
286
+ continue
287
+ else :
288
+ for i in range (100 ):
289
+ await api .move_to (mount = mount , abs_position = pre_test_pos )
290
+ ui .print_header (f"Cycle { i + 1 } : Testing Current = { test_current } " )
291
+ try :
292
+ async with api ._backend .motor_current ():
293
+ await api ._backend .set_active_current ({z_ax : test_current })
294
+ await api .move_to (
295
+ mount = mount ,
296
+ abs_position = press_pos ,
297
+ speed = FORCE_SPEED ,
298
+ expect_stalls = True ,
299
+ )
300
+ finally :
301
+ pass
302
+ await api ._update_position_estimation ([Axis .by_mount (mount )])
303
+ await api .refresh_positions ()
304
+
305
+ await api .move_to (mount = mount , abs_position = pre_test_pos )
306
+
243
307
for i in range (CYCLES_CURRENT ):
244
308
# Move to just above force gauge
245
309
await api .move_to (mount = mount , abs_position = pre_test_pos )
@@ -272,10 +336,12 @@ async def _force_gauge(
272
336
avg_results .append (round (analyzed_avg , 1 ))
273
337
else :
274
338
ui .print_error (
275
- "DATA INVALID - z-stage did not contact or guage not zeroed"
339
+ "DATA INVALID - z-stage did not contact or guage not zeroed \n "
340
+ f"Mount { mount .name } fail !"
276
341
)
342
+ valid_fail .append (mount .name )
277
343
qc_pass = False
278
- break
344
+ return False
279
345
280
346
# we expect a stall has happened during pick up, so we want to
281
347
# update the motor estimation
@@ -296,7 +362,12 @@ async def _force_gauge(
296
362
ui .print_header (f"CURRENT: { test_current } - PASS" )
297
363
else :
298
364
ui .print_header (f"CURRENT: { test_current } - FAIL" )
299
- qc_pass = qc_pass and res
365
+ # only calculate 0.2 & 0.5
366
+ if ONLY_COUNT_USING_CURRENT_YIELD :
367
+ if test_current == 0.2 or test_current == 0.5 :
368
+ qc_pass = qc_pass and res
369
+ else :
370
+ qc_pass = qc_pass and res
300
371
301
372
return qc_pass
302
373
@@ -306,11 +377,15 @@ async def _run(api: OT3API, arguments: argparse.Namespace, report: CSVReport) ->
306
377
qc_pass = True
307
378
308
379
if not arguments .skip_left :
309
- res = await _force_gauge (api , OT3Mount .LEFT , report , arguments .simulate )
380
+ res = await _force_gauge (
381
+ api , OT3Mount .LEFT , report , arguments .simulate , arguments
382
+ )
310
383
qc_pass = res and qc_pass
311
384
312
385
if not arguments .skip_right :
313
- res = await _force_gauge (api , OT3Mount .RIGHT , report , arguments .simulate )
386
+ res = await _force_gauge (
387
+ api , OT3Mount .RIGHT , report , arguments .simulate , arguments
388
+ )
314
389
qc_pass = res and qc_pass
315
390
316
391
return qc_pass
@@ -327,8 +402,12 @@ async def _main(arguments: argparse.Namespace) -> None:
327
402
dut = helpers_ot3 .DeviceUnderTest .OTHER
328
403
helpers_ot3 .set_csv_report_meta_data_ot3 (api , report , dut = dut )
329
404
330
- for k , v in TEST_PARAMETERS .items ():
331
- report ("TEST_PARAMETERS" , k , [v ])
405
+ # NOTE: We submit an automatic "PASS" result for these parameter lists.
406
+ # They do not test any logic but only add the list of parameters used to the CSV
407
+ for k , v in TEST_LEFT_PARAMETERS .items ():
408
+ report ("TEST_LEFT_PARAMETERS" , k , [v , CSVResult .PASS ])
409
+ for k , v in TEST_RIGHT_PARAMETERS .items ():
410
+ report ("TEST_RIGHT_PARAMETERS" , k , [v , CSVResult .PASS ])
332
411
333
412
# Attempt to home if first homing fails because of OT-3 in box Y axis issue
334
413
try :
@@ -354,6 +433,14 @@ async def _main(arguments: argparse.Namespace) -> None:
354
433
355
434
try :
356
435
qc_pass = await _run (api , arguments , report )
436
+ await api .home (
437
+ [
438
+ Axis .X ,
439
+ Axis .Y ,
440
+ Axis .by_mount (OT3Mount .LEFT ),
441
+ Axis .by_mount (OT3Mount .RIGHT ),
442
+ ]
443
+ )
357
444
except KeyboardInterrupt :
358
445
print ("Cancelled" )
359
446
except Exception as e :
@@ -364,6 +451,12 @@ async def _main(arguments: argparse.Namespace) -> None:
364
451
ui .print_title ("Test Done - PASSED" )
365
452
else :
366
453
ui .print_title ("Test Done - FAILED" )
454
+ if len (valid_fail ) == 0 :
455
+ pass
456
+ else :
457
+ print ("Data Invalid, Please Re-Test This Unit (数据验证失败, 请复测当前Z轴) !" )
458
+ for item in valid_fail :
459
+ print (f"Mount { item } Fail" )
367
460
report .save_to_disk ()
368
461
report .print_results ()
369
462
@@ -373,6 +466,7 @@ async def _main(arguments: argparse.Namespace) -> None:
373
466
arg_parser .add_argument ("--simulate" , action = "store_true" )
374
467
arg_parser .add_argument ("--skip_left" , action = "store_true" )
375
468
arg_parser .add_argument ("--skip_right" , action = "store_true" )
469
+ arg_parser .add_argument ("--user_current" , type = str , default = "None" )
376
470
old_stall_setting = get_adv_setting ("disableStallDetection" , RobotTypeEnum .FLEX )
377
471
try :
378
472
asyncio .run (set_adv_setting ("disableStallDetection" , True ))
0 commit comments