feat(*): 添加触发样本偏移与实发轨迹分析导出

* 为 RobotConfig 增加 trigger_sample_index_offset_cycles 配置
  * 让 DO 事件携带示教点关节角并按最接近 sample 绑定触发
  * 调整运行时 IO 地址位掩码映射并补充 ShotEvents 导出
  * 新增 2026042802-1 抓包分析脚本、数据产物与结论文档
  * 补齐配置兼容、规划绑定和运行时触发相关测试
This commit is contained in:
2026-05-09 11:12:31 +08:00
parent 1779067b5c
commit f7e2bb0e7b
35 changed files with 5772 additions and 55 deletions

View File

@@ -6,6 +6,7 @@
8
],
"io_keep_cycles": 2,
"trigger_sample_index_offset_cycles": 6,
"acc_limit": 1,
"jerk_limit": 1,
"adapt_icsp_try_num": 5,

View File

@@ -0,0 +1,21 @@
{
"pcap_path": "D:\\Dev\\Codes\\rvbust-code\\FlyingShotPkg_3.15_VDA\\Rvbust\\uttc-20260428\\2026042802-1.pcap",
"all_command_count": 1788,
"trigger_count": 17,
"existing_runtime_actual_send_exists": true,
"existing_runtime_actual_send_has_io_columns": false,
"existing_shot_events_exists": true,
"pcap_specific_combined_export_preexisting": false,
"average_max_error_deg": 4.241583591714439,
"max_error_deg": 11.130744251720401,
"average_rms_error_deg": 2.5406136706026206,
"max_error_axis_counter": {
"J6": 9,
"J4": 5,
"J5": 1,
"J2": 1,
"J1": 1
},
"order_only_addr_mismatch_count": 14,
"real_addr_mismatch_count": 0
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
frame_number,time_relative_s,sequence,last_data,write_io_type,write_io_index,write_io_mask,write_io_value,io_addrs,j1_deg,j2_deg,j3_deg,j4_deg,j5_deg,j6_deg,ext1_deg,ext2_deg,ext3_deg
1955,5.888271,1381124,0,2,1,10,10,"[2, 4]",45.8632698059082,2.9724788665771484,-13.609341621398926,-2.1851141452789307,7.582361221313477,5.701517581939697,0.0,0.0,0.0
2151,6.480252,1381198,0,2,1,14,14,"[2, 3, 4]",56.34336471557617,11.66723918914795,-6.600923538208008,-68.1976089477539,6.058437347412109,71.5392837524414,0.0,0.0,0.0
2223,6.704225,1381226,0,2,1,14,14,"[2, 3, 4]",53.50831985473633,7.412222862243652,-9.629739761352539,-32.30571365356445,12.488306045532227,30.826189041137695,0.0,0.0,0.0
2336,7.048266,1381269,0,2,1,10,10,"[2, 4]",44.433006286621094,-2.1156294345855713,-18.39777374267578,4.8371992111206055,33.99372482299805,-20.26228904724121,0.0,0.0,0.0
2477,7.464289,1381321,0,2,1,10,10,"[2, 4]",65.84967041015625,5.695003032684326,-14.563636779785156,-28.69342613220215,27.678611755371094,46.437156677246094,0.0,0.0,0.0
2665,8.024277,1381391,0,2,1,12,12,"[3, 4]",60.847530364990234,24.47777557373047,-5.617043972015381,34.8044319152832,5.786255359649658,-31.2253475189209,0.0,0.0,0.0
2811,8.472317,1381447,0,2,1,12,12,"[3, 4]",70.8250503540039,10.95259952545166,-13.136046409606934,-34.68459701538086,14.022420883178711,38.90604019165039,0.0,0.0,0.0
2908,8.760361,1381483,0,2,1,10,10,"[2, 4]",69.40516662597656,-20.066781997680664,-8.152935981750488,-63.93235397338867,6.775912284851074,70.37761688232422,0.0,0.0,0.0
3112,9.384332,1381561,0,2,1,10,10,"[2, 4]",73.90592956542969,-8.016124725341797,-9.002426147460938,-131.3327178955078,15.526206970214844,142.41668701171875,0.0,0.0,0.0
3170,9.560358,1381583,0,2,1,10,10,"[2, 4]",76.72688293457031,-16.518726348876953,-7.15147066116333,-127.53003692626953,18.53788948059082,138.7897491455078,0.0,0.0,0.0
3350,10.104322,1381651,0,2,1,10,10,"[2, 4]",83.71662139892578,-13.186573028564453,-13.738808631896973,-72.70317840576172,26.66758918762207,91.98423767089844,0.0,0.0,0.0
3470,10.472333,1381697,0,2,1,10,10,"[2, 4]",59.78955841064453,-2.7094168663024902,-8.933828353881836,-108.24857330322266,21.177492141723633,114.14110565185547,0.0,0.0,0.0
3627,10.944371,1381756,0,2,1,12,12,"[3, 4]",86.41329193115234,4.266173362731934,-19.15987777709961,-52.24028015136719,29.853723526000977,55.86907196044922,0.0,0.0,0.0
3710,11.192339,1381787,0,2,1,10,10,"[2, 4]",110.7523193359375,0.8751887679100037,-34.756534576416016,-48.14332580566406,45.0865592956543,87.97444152832031,0.0,0.0,0.0
3796,11.456361,1381820,0,2,1,10,10,"[2, 4]",111.79177856445312,-6.225440502166748,-31.958988189697266,-53.68573760986328,44.76150894165039,89.33454895019531,0.0,0.0,0.0
3870,11.680362,1381848,0,2,1,10,10,"[2, 4]",117.87474060058594,-19.607177734375,-30.329103469848633,-56.600250244140625,49.08655548095703,90.32424926757812,0.0,0.0,0.0
4138,12.496365,1381950,0,2,1,12,12,"[3, 4]",59.93589401245117,-21.102140426635742,-9.684239387512207,70.64311981201172,32.941307067871094,-63.34855651855469,0.0,0.0,0.0
1 frame_number time_relative_s sequence last_data write_io_type write_io_index write_io_mask write_io_value io_addrs j1_deg j2_deg j3_deg j4_deg j5_deg j6_deg ext1_deg ext2_deg ext3_deg
2 1955 5.888271 1381124 0 2 1 10 10 [2, 4] 45.8632698059082 2.9724788665771484 -13.609341621398926 -2.1851141452789307 7.582361221313477 5.701517581939697 0.0 0.0 0.0
3 2151 6.480252 1381198 0 2 1 14 14 [2, 3, 4] 56.34336471557617 11.66723918914795 -6.600923538208008 -68.1976089477539 6.058437347412109 71.5392837524414 0.0 0.0 0.0
4 2223 6.704225 1381226 0 2 1 14 14 [2, 3, 4] 53.50831985473633 7.412222862243652 -9.629739761352539 -32.30571365356445 12.488306045532227 30.826189041137695 0.0 0.0 0.0
5 2336 7.048266 1381269 0 2 1 10 10 [2, 4] 44.433006286621094 -2.1156294345855713 -18.39777374267578 4.8371992111206055 33.99372482299805 -20.26228904724121 0.0 0.0 0.0
6 2477 7.464289 1381321 0 2 1 10 10 [2, 4] 65.84967041015625 5.695003032684326 -14.563636779785156 -28.69342613220215 27.678611755371094 46.437156677246094 0.0 0.0 0.0
7 2665 8.024277 1381391 0 2 1 12 12 [3, 4] 60.847530364990234 24.47777557373047 -5.617043972015381 34.8044319152832 5.786255359649658 -31.2253475189209 0.0 0.0 0.0
8 2811 8.472317 1381447 0 2 1 12 12 [3, 4] 70.8250503540039 10.95259952545166 -13.136046409606934 -34.68459701538086 14.022420883178711 38.90604019165039 0.0 0.0 0.0
9 2908 8.760361 1381483 0 2 1 10 10 [2, 4] 69.40516662597656 -20.066781997680664 -8.152935981750488 -63.93235397338867 6.775912284851074 70.37761688232422 0.0 0.0 0.0
10 3112 9.384332 1381561 0 2 1 10 10 [2, 4] 73.90592956542969 -8.016124725341797 -9.002426147460938 -131.3327178955078 15.526206970214844 142.41668701171875 0.0 0.0 0.0
11 3170 9.560358 1381583 0 2 1 10 10 [2, 4] 76.72688293457031 -16.518726348876953 -7.15147066116333 -127.53003692626953 18.53788948059082 138.7897491455078 0.0 0.0 0.0
12 3350 10.104322 1381651 0 2 1 10 10 [2, 4] 83.71662139892578 -13.186573028564453 -13.738808631896973 -72.70317840576172 26.66758918762207 91.98423767089844 0.0 0.0 0.0
13 3470 10.472333 1381697 0 2 1 10 10 [2, 4] 59.78955841064453 -2.7094168663024902 -8.933828353881836 -108.24857330322266 21.177492141723633 114.14110565185547 0.0 0.0 0.0
14 3627 10.944371 1381756 0 2 1 12 12 [3, 4] 86.41329193115234 4.266173362731934 -19.15987777709961 -52.24028015136719 29.853723526000977 55.86907196044922 0.0 0.0 0.0
15 3710 11.192339 1381787 0 2 1 10 10 [2, 4] 110.7523193359375 0.8751887679100037 -34.756534576416016 -48.14332580566406 45.0865592956543 87.97444152832031 0.0 0.0 0.0
16 3796 11.456361 1381820 0 2 1 10 10 [2, 4] 111.79177856445312 -6.225440502166748 -31.958988189697266 -53.68573760986328 44.76150894165039 89.33454895019531 0.0 0.0 0.0
17 3870 11.680362 1381848 0 2 1 10 10 [2, 4] 117.87474060058594 -19.607177734375 -30.329103469848633 -56.600250244140625 49.08655548095703 90.32424926757812 0.0 0.0 0.0
18 4138 12.496365 1381950 0 2 1 12 12 [3, 4] 59.93589401245117 -21.102140426635742 -9.684239387512207 70.64311981201172 32.941307067871094 -63.34855651855469 0.0 0.0 0.0

View File

@@ -0,0 +1,37 @@
{
"pcap_path": "D:\\Dev\\Codes\\rvbust-code\\FlyingShotPkg_3.15_VDA\\Rvbust\\uttc-20260428\\2026042802-1.pcap",
"command_count": 1788,
"trigger_count": 17,
"command_minus_paired_status_sequence_counter": {
"8": 17
},
"paired_status_average_max_error_deg": 6.469219290127501,
"paired_status_max_error_deg": 16.123934474475888,
"paired_status_max_error_axis_counter": {
"J1": 2,
"J6": 9,
"J2": 4,
"J4": 2
},
"best_status_average_max_error_deg": 0.14953970473465206,
"best_status_max_error_deg": 0.5696919293327056,
"best_status_max_error_axis_counter": {
"J6": 10,
"J1": 3,
"J5": 1,
"J2": 2,
"J4": 1
},
"best_status_delta_from_paired_cycles_counter": {
"10": 8,
"9": 9
},
"best_status_delta_from_trigger_sequence_counter": {
"2": 8,
"1": 9
},
"best_status_time_after_trigger_ms_min": 71.83799999999962,
"best_status_time_after_trigger_ms_max": 79.96399999999859,
"best_status_time_after_trigger_ms_avg": 75.6613529411763,
"search_window_cycles": 20
}

View File

@@ -0,0 +1,18 @@
trigger_no,waypoint_index,trigger_command_sequence,trigger_command_frame,trigger_command_time_relative_s,trigger_current_status_sequence,trigger_current_status_frame,trigger_current_status_time_relative_s,command_leads_status_cycles,trigger_current_status_max_error_axis,trigger_current_status_max_error_deg,trigger_current_status_rms_error_deg,best_status_sequence,best_status_frame,best_status_time_relative_s,best_status_delay_from_current_status_cycles,best_status_delay_from_trigger_command_cycles,best_status_delay_from_trigger_command_ms,best_status_max_error_axis,best_status_max_error_deg,best_status_rms_error_deg
1,1,1381124,1955,5.888271,1381116,1954,5.888166,8,J1,6.588241610414407,3.8225443630072706,1381126,1981,5.968124,10,2,79.85300000000083,J6,0.20758988641565335,0.12239685259209541
2,2,1381198,2151,6.480252,1381190,2150,6.480138,8,J1,2.33531536749085,1.3827543088729335,1381199,2172,6.552164,9,1,71.9120000000002,J1,0.08213390997131853,0.04616054814443023
3,3,1381226,2223,6.704225,1381218,2222,6.704166,8,J6,16.123934474475888,8.852376616648156,1381228,2248,6.784154,10,2,79.92899999999992,J6,0.5696919293327056,0.3239642953120798
4,4,1381269,2336,7.048266,1381261,2335,7.048148,8,J6,4.901882807288516,3.2440556235708993,1381271,2362,7.128175,10,2,79.90899999999979,J6,0.09470430997406254,0.06580474324148583
5,5,1381321,2477,7.464289,1381313,2476,7.464178,8,J6,9.21943820204428,4.621321121191458,1381323,2502,7.544122,10,2,79.83299999999983,J5,0.056622412878706285,0.03357478517689402
6,6,1381391,2665,8.024277,1381383,2664,8.024156,8,J6,6.1464605154096255,3.0478405356855083,1381392,2687,8.096181,9,1,71.90399999999997,J6,0.17697427883735983,0.08563125303054821
7,7,1381447,2811,8.472317,1381439,2810,8.472208,8,J6,13.15171783052326,7.78202379046887,1381448,2834,8.54419,9,1,71.87300000000008,J6,0.30658691011310424,0.18210669390591905
8,8,1381483,2908,8.760361,1381475,2907,8.760245,8,J6,7.436279407197546,5.127041386597523,1381484,2929,8.832199,9,1,71.83799999999962,J2,0.06074767130727565,0.02750705896232285
9,9,1381561,3112,9.384332,1381553,3111,9.384204,8,J6,5.585605293050492,3.277206017832995,1381562,3134,9.456205,9,1,71.87300000000008,J4,0.15225994654176134,0.089150370994325
10,10,1381583,3170,9.560358,1381575,3169,9.56025,8,J2,4.165077087081428,2.128983861449047,1381585,3196,9.640214,10,2,79.85599999999948,J6,0.0734395372110157,0.043285948566531826
11,11,1381651,3350,10.104322,1381643,3349,10.104215,8,J2,1.8309533977318093,1.169340011162825,1381652,3373,10.17622,9,1,71.8980000000009,J6,0.07766831894582538,0.04246508921571141
12,12,1381697,3470,10.472333,1381689,3469,10.472191,8,J4,4.822353276363401,2.8611252897135864,1381698,3493,10.544283,9,1,71.94999999999929,J1,0.021077280093038553,0.014935517911187784
13,13,1381756,3627,10.944371,1381748,3626,10.944251,8,J4,8.152507963730145,5.168659196117862,1381757,3651,11.016226,9,1,71.85499999999934,J1,0.14554304541260876,0.0699602863618738
14,14,1381787,3710,11.192339,1381779,3709,11.19225,8,J6,10.40441920064211,5.679810575214033,1381789,3735,11.272261,10,2,79.92199999999983,J6,0.11945317484617135,0.05835950688086092
15,15,1381820,3796,11.456361,1381812,3795,11.456253,8,J2,2.6161077284098373,1.5911754635072362,1381822,3821,11.536287,10,2,79.92600000000039,J2,0.14980253942005772,0.08716897465096986
16,16,1381848,3870,11.680362,1381840,3869,11.680263,8,J2,4.682473812334727,2.2067399623329567,1381850,3895,11.760326,10,2,79.96399999999859,J6,0.17295643126782068,0.10419421346699378
17,18,1381950,4138,12.496365,1381942,4137,12.496271,8,J6,1.8139599579791934,1.1536991630766555,1381951,4159,12.568313,9,1,71.94799999999901,J6,0.07492339792059965,0.03834497543010648
1 trigger_no waypoint_index trigger_command_sequence trigger_command_frame trigger_command_time_relative_s trigger_current_status_sequence trigger_current_status_frame trigger_current_status_time_relative_s command_leads_status_cycles trigger_current_status_max_error_axis trigger_current_status_max_error_deg trigger_current_status_rms_error_deg best_status_sequence best_status_frame best_status_time_relative_s best_status_delay_from_current_status_cycles best_status_delay_from_trigger_command_cycles best_status_delay_from_trigger_command_ms best_status_max_error_axis best_status_max_error_deg best_status_rms_error_deg
2 1 1 1381124 1955 5.888271 1381116 1954 5.888166 8 J1 6.588241610414407 3.8225443630072706 1381126 1981 5.968124 10 2 79.85300000000083 J6 0.20758988641565335 0.12239685259209541
3 2 2 1381198 2151 6.480252 1381190 2150 6.480138 8 J1 2.33531536749085 1.3827543088729335 1381199 2172 6.552164 9 1 71.9120000000002 J1 0.08213390997131853 0.04616054814443023
4 3 3 1381226 2223 6.704225 1381218 2222 6.704166 8 J6 16.123934474475888 8.852376616648156 1381228 2248 6.784154 10 2 79.92899999999992 J6 0.5696919293327056 0.3239642953120798
5 4 4 1381269 2336 7.048266 1381261 2335 7.048148 8 J6 4.901882807288516 3.2440556235708993 1381271 2362 7.128175 10 2 79.90899999999979 J6 0.09470430997406254 0.06580474324148583
6 5 5 1381321 2477 7.464289 1381313 2476 7.464178 8 J6 9.21943820204428 4.621321121191458 1381323 2502 7.544122 10 2 79.83299999999983 J5 0.056622412878706285 0.03357478517689402
7 6 6 1381391 2665 8.024277 1381383 2664 8.024156 8 J6 6.1464605154096255 3.0478405356855083 1381392 2687 8.096181 9 1 71.90399999999997 J6 0.17697427883735983 0.08563125303054821
8 7 7 1381447 2811 8.472317 1381439 2810 8.472208 8 J6 13.15171783052326 7.78202379046887 1381448 2834 8.54419 9 1 71.87300000000008 J6 0.30658691011310424 0.18210669390591905
9 8 8 1381483 2908 8.760361 1381475 2907 8.760245 8 J6 7.436279407197546 5.127041386597523 1381484 2929 8.832199 9 1 71.83799999999962 J2 0.06074767130727565 0.02750705896232285
10 9 9 1381561 3112 9.384332 1381553 3111 9.384204 8 J6 5.585605293050492 3.277206017832995 1381562 3134 9.456205 9 1 71.87300000000008 J4 0.15225994654176134 0.089150370994325
11 10 10 1381583 3170 9.560358 1381575 3169 9.56025 8 J2 4.165077087081428 2.128983861449047 1381585 3196 9.640214 10 2 79.85599999999948 J6 0.0734395372110157 0.043285948566531826
12 11 11 1381651 3350 10.104322 1381643 3349 10.104215 8 J2 1.8309533977318093 1.169340011162825 1381652 3373 10.17622 9 1 71.8980000000009 J6 0.07766831894582538 0.04246508921571141
13 12 12 1381697 3470 10.472333 1381689 3469 10.472191 8 J4 4.822353276363401 2.8611252897135864 1381698 3493 10.544283 9 1 71.94999999999929 J1 0.021077280093038553 0.014935517911187784
14 13 13 1381756 3627 10.944371 1381748 3626 10.944251 8 J4 8.152507963730145 5.168659196117862 1381757 3651 11.016226 9 1 71.85499999999934 J1 0.14554304541260876 0.0699602863618738
15 14 14 1381787 3710 11.192339 1381779 3709 11.19225 8 J6 10.40441920064211 5.679810575214033 1381789 3735 11.272261 10 2 79.92199999999983 J6 0.11945317484617135 0.05835950688086092
16 15 15 1381820 3796 11.456361 1381812 3795 11.456253 8 J2 2.6161077284098373 1.5911754635072362 1381822 3821 11.536287 10 2 79.92600000000039 J2 0.14980253942005772 0.08716897465096986
17 16 16 1381848 3870 11.680362 1381840 3869 11.680263 8 J2 4.682473812334727 2.2067399623329567 1381850 3895 11.760326 10 2 79.96399999999859 J6 0.17295643126782068 0.10419421346699378
18 17 18 1381950 4138 12.496365 1381942 4137 12.496271 8 J6 1.8139599579791934 1.1536991630766555 1381951 4159 12.568313 9 1 71.94799999999901 J6 0.07492339792059965 0.03834497543010648

View File

@@ -0,0 +1,18 @@
trigger_no,waypoint_index,best_sample_order,best_frame_number,best_sequence,best_time_relative_s,teach_j1_deg,teach_j2_deg,teach_j3_deg,teach_j4_deg,teach_j5_deg,teach_j6_deg,offset_6_frame_number,offset_6_sequence,offset_6_time_relative_s,offset_6_max_error_axis,offset_6_max_error_deg,offset_6_rms_error_deg,offset_6_delta_from_best_ms,offset_6_j1_actual_deg,offset_6_diff_j1_deg,offset_6_j2_actual_deg,offset_6_diff_j2_deg,offset_6_j3_actual_deg,offset_6_diff_j3_deg,offset_6_j4_actual_deg,offset_6_diff_j4_deg,offset_6_j5_actual_deg,offset_6_diff_j5_deg,offset_6_j6_actual_deg,offset_6_diff_j6_deg,offset_7_frame_number,offset_7_sequence,offset_7_time_relative_s,offset_7_max_error_axis,offset_7_max_error_deg,offset_7_rms_error_deg,offset_7_delta_from_best_ms,offset_7_j1_actual_deg,offset_7_diff_j1_deg,offset_7_j2_actual_deg,offset_7_diff_j2_deg,offset_7_j3_actual_deg,offset_7_diff_j3_deg,offset_7_j4_actual_deg,offset_7_diff_j4_deg,offset_7_j5_actual_deg,offset_7_diff_j5_deg,offset_7_j6_actual_deg,offset_7_diff_j6_deg,offset_8_frame_number,offset_8_sequence,offset_8_time_relative_s,offset_8_max_error_axis,offset_8_max_error_deg,offset_8_rms_error_deg,offset_8_delta_from_best_ms,offset_8_j1_actual_deg,offset_8_diff_j1_deg,offset_8_j2_actual_deg,offset_8_diff_j2_deg,offset_8_j3_actual_deg,offset_8_diff_j3_deg,offset_8_j4_actual_deg,offset_8_diff_j4_deg,offset_8_j5_actual_deg,offset_8_diff_j5_deg,offset_8_j6_actual_deg,offset_8_diff_j6_deg,best_of_6_7_8_offset
1,1,730,1941,1381118,5.840207,48.886810269468405,2.1989850886957285,-11.021017368511105,0.4102097980549552,6.248381265333557,2.294990756284542,1955,1381124,5.888271,J6,3.4065268256551553,2.468438977201345,48.06399999999922,45.8632698059082,-3.0235404635602023,2.9724788665771484,0.7734937778814199,-13.609341621398926,-2.588324252887821,-2.1851141452789307,-2.5953239433338857,7.582361221313477,1.3339799559799195,5.701517581939697,3.4065268256551553,1958,1381125,5.896184,J6,4.180931828249149,2.9355776062802286,55.9769999999995,45.449710845947266,-3.43709942352114,3.117816925048828,0.9188318363530996,-13.963269233703613,-2.9422518651925085,-2.845515012741089,-3.255724810796044,7.768581867218018,1.5202006018844605,6.475922584533691,4.180931828249149,1961,1381126,5.904272,J6,5.0045521476156045,3.418446646752538,64.06499999999937,45.06731414794922,-3.8194961215191867,3.2660434246063232,1.0670583359105947,-14.290565490722656,-3.2695481222115514,-3.562589168548584,-3.972798966603539,7.9421586990356445,1.6937774337020874,7.2995429039001465,5.0045521476156045,6
2,2,804,2135,1381192,6.432175,55.34775509527405,11.807039833001637,-7.0090952672806885,-71.01433145543973,6.012065051914967,74.24953191606797,2151,1381198,6.480252,J4,2.8167225076858244,1.6562461612538633,48.07700000000015,56.34336471557617,0.995609620302119,11.66723918914795,-0.13980064385368784,-6.600923538208008,0.40817172907268073,-68.1976089477539,2.8167225076858244,6.058437347412109,0.04637229549714217,71.5392837524414,-2.7102481636265594,2153,1381199,6.488246,J4,3.526759739131137,2.060948429836345,56.071000000000204,56.451515197753906,1.1037601024798533,11.618118286132812,-0.18892154686882456,-6.580313682556152,0.4287815847245362,-67.4875717163086,3.526759739131137,6.09804105758667,0.08597600567170272,70.84339141845703,-3.4061404976109344,2155,1381200,6.496271,J4,4.301478977412387,2.5033932349312007,64.09600000000015,56.54535675048828,1.1976016552142283,11.561552047729492,-0.24548778527214488,-6.571277618408203,0.4378176488724854,-66.71285247802734,4.301478977412387,6.147788047790527,0.13572299587556014,70.078857421875,-4.170674494192966,6
3,3,832,2207,1381220,6.656264,55.109808014787404,8.759497374223619,-8.518216825284897,-41.11725046606459,10.108488114686867,41.956933292858096,2223,1381226,6.704225,J6,11.130744251720401,5.955607695749779,47.96099999999992,53.50831985473633,-1.6014881600510762,7.412222862243652,-1.3472745119799665,-9.629739761352539,-1.111522936067642,-32.30571365356445,8.811536812500137,12.488306045532227,2.379817930845359,30.826189041137695,-11.130744251720401,2227,1381227,6.712268,J6,13.165517124645206,7.03533795629365,56.00399999999972,53.18336486816406,-1.9264431466233418,7.154932975769043,-1.6045643984545759,-9.842713356018066,-1.3244965307331693,-30.750762939453125,10.366487526611465,12.961709976196289,2.8532218615094216,28.79141616821289,-13.165517124645206,2229,1381228,6.720286,J6,15.212756428234073,8.119717107623766,64.02199999999958,52.84844207763672,-2.2613659371506856,6.892857074737549,-1.86664029948607,-10.059968948364258,-1.5417521230793607,-29.200178146362305,11.917072319702285,13.449018478393555,3.340530363706687,26.744176864624023,-15.212756428234073,6
4,4,875,2321,1381263,7.000291,43.65359310453334,-1.629659559507137,-17.715753611915318,5.995208633582219,32.17171770646655,-22.573973337684023,2336,1381269,7.048266,J6,2.3116842904428125,1.3731583485126422,47.9750000000001,44.433006286621094,0.779413182087751,-2.1156294345855713,-0.48596987507843425,-18.39777374267578,-0.6820201307604634,4.8371992111206055,-1.158009422461613,33.99372482299805,1.8220071165314948,-20.26228904724121,2.3116842904428125,2339,1381270,7.056293,J6,3.083185831580508,1.7437179916275436,56.00200000000033,44.65972137451172,1.006128269978376,-2.1617355346679688,-0.5320759751608317,-18.490602493286133,-0.774848881370815,4.406780242919922,-1.5884283906622967,34.24979019165039,2.0780724851838386,-19.490787506103516,3.083185831580508,2341,1381271,7.064278,J6,3.9520155587533594,2.15807761350517,63.987000000000016,44.91068649291992,1.2570933883865791,-2.196718215942383,-0.5670586564352458,-18.575654983520508,-0.85990137160519,3.9164717197418213,-2.0787369138403973,34.48752212524414,2.3158044187775886,-18.621957778930664,3.9520155587533594,6
5,5,927,2457,1381315,7.416267,64.58244475717193,4.262979315506351,-15.669217122643433,-29.952927185666542,29.850439933020308,45.62652743544272,2477,1381321,7.464289,J5,2.171828177649214,1.404704060246151,48.021999999999565,65.84967041015625,1.2672256529843224,5.695003032684326,1.4320237171779748,-14.563636779785156,1.1055803428582767,-28.69342613220215,1.259501053464394,27.678611755371094,-2.171828177649214,46.437156677246094,0.810629241803376,2479,1381322,7.472265,J5,2.585320380408003,1.6670103454750829,55.99799999999977,66.01153564453125,1.4290908873593224,5.957343578338623,1.6943642628322717,-14.353693008422852,1.3155241142205814,-28.232824325561523,1.720102860105019,27.265119552612305,-2.585320380408003,46.24872589111328,0.6221984556705635,2483,1381323,7.480284,J5,3.0049218208376907,1.9507458917658702,64.01699999999977,66.15470886230469,1.57226410513276,6.221103191375732,1.958123875869381,-14.140877723693848,1.5283393989495853,-27.70670509338379,2.2462220922827534,26.845518112182617,-3.0049218208376907,45.96609115600586,0.33956372056314166,6
6,6,997,2649,1381385,7.976283,60.47948252708421,23.068781981390185,-5.01126420129949,36.10685486878251,5.525681179628412,-31.3025636495649,2665,1381391,8.024277,J2,1.408993592340284,0.8424031169595625,47.99400000000009,60.847530364990234,0.36804783790602613,24.47777557373047,1.408993592340284,-5.617043972015381,-0.6057797707158912,34.8044319152832,-1.3024229534993097,5.786255359649658,0.260574180021246,-31.2253475189209,0.07721613064400046,2667,1381392,8.032258,J4,1.7701696881184503,1.0669192783996628,55.975000000000996,60.95240783691406,0.47292530982985426,24.69621467590332,1.6274326945131357,-5.75187873840332,-0.7406145371038306,34.33668518066406,-1.7701696881184503,5.885775089263916,0.3600939096355038,-30.920429229736328,0.38213441982857077,2669,1381393,8.040307,J4,2.303903056038372,1.3309750271252634,64.02400000000074,61.06847381591797,0.5889912888337605,24.908491134643555,1.83970915325337,-5.895160675048828,-0.8838964737493384,33.80295181274414,-2.303903056038372,5.999467372894287,0.4737861932658749,-30.538488388061523,0.7640752615033755,6
7,7,1053,2795,1381441,8.424315,70.47583707168602,16.39384887825908,-13.456948007467595,-27.892318852946243,14.53566195089614,31.71193282686115,2811,1381447,8.472317,J6,7.1941073647892395,4.618545262978315,48.00200000000032,70.8250503540039,0.3492132823178906,10.95259952545166,-5.4412493528074215,-13.136046409606934,0.3209015978606615,-34.68459701538086,-6.7922781624346165,14.022420883178711,-0.5132410677174288,38.90604019165039,7.1941073647892395,2814,1381448,8.480253,J6,8.24868042387127,5.331515658278243,55.93799999999938,70.84622192382812,0.37038485214210937,9.979106903076172,-6.41474197518291,-13.042067527770996,0.414880479696599,-35.67851257324219,-7.786193720295945,13.882524490356445,-0.6531374605396945,39.96061325073242,8.24868042387127,2817,1381449,8.488291,J6,9.275558780804865,6.035874346469871,63.976000000000255,70.85871887207031,0.38288180038429687,8.986706733703613,-7.407142144555468,-12.9381742477417,0.5187737597258959,-36.64576721191406,-8.75344835896782,13.72922134399414,-0.8064406069019991,40.987491607666016,9.275558780804865,6
8,8,1089,2892,1381477,8.71231,69.58246408878419,-17.10571341532583,-8.710589696831251,-58.47569441890704,7.63059003611043,64.43773280685575,2908,1381483,8.760361,J6,5.93988407546847,3.533132924843701,48.05099999999918,69.40516662597656,-0.1772974628076298,-20.066781997680664,-2.9610685823548337,-8.152935981750488,0.5576537150807628,-63.93235397338867,-5.456659554481632,6.775912284851074,-0.8546777512593557,70.37761688232422,5.93988407546847,2910,1381484,8.768294,J6,6.922168621366907,4.090127751125079,55.9839999999987,69.39288330078125,-0.1895807880029423,-20.37982177734375,-3.2741083620179197,-8.094615936279297,0.6159737605519542,-64.83366394042969,-6.357969521522648,6.682157039642334,-0.948432996468096,71.35990142822266,6.922168621366907,2912,1381485,8.77637,J6,7.916950115507532,4.649086823187336,64.05999999999956,69.38455200195312,-0.1979120868310673,-20.654869079589844,-3.5491556642640134,-8.043557167053223,0.6670325297780284,-65.74622344970703,-7.270529030799992,6.598722457885742,-1.0318675782246878,72.35468292236328,7.916950115507532,6
9,9,1167,3096,1381555,9.336375,73.57125874861414,-6.42984524964374,-9.628579811400881,-128.80864727564332,14.671082817606491,140.00204816414424,3112,1381561,9.384332,J4,2.5240706198644887,1.630593251762862,47.95700000000025,73.90592956542969,0.3346708168155459,-8.016124725341797,-1.5862794756980572,-9.002426147460938,0.6261536639399434,-131.3327178955078,-2.5240706198644887,15.526206970214844,0.8551241526083526,142.41668701171875,2.4146388475745084,3114,1381562,9.392355,J4,2.830116152091051,1.8576181251506447,55.97999999999992,73.96361541748047,0.39235666886632714,-8.363268852233887,-1.933423602590147,-8.884164810180664,0.7444150012202169,-131.63876342773438,-2.830116152091051,15.65822696685791,0.987144149251419,142.69912719726562,2.6970790331213834,3118,1381563,9.400331,J4,3.1013106100988637,2.0726473342415157,63.955999999999236,74.02384948730469,0.4525907386905459,-8.728874206542969,-2.299028956899229,-8.76374626159668,0.8648335498042012,-131.9099578857422,-3.1013106100988637,15.788768768310547,1.1176859507040557,142.9464569091797,2.944408745035446,6
10,10,1189,3154,1381577,9.512325,75.56938603377543,-14.67930590788221,-7.294156094303152,-130.92303342701462,17.688361072687904,141.89350789658602,3170,1381583,9.560358,J4,3.3929965007450846,2.1059862266772753,48.033000000000214,76.72688293457031,1.1574969007948823,-16.518726348876953,-1.8394204409947434,-7.15147066116333,0.14268543313982196,-127.53003692626953,3.3929965007450846,18.53788948059082,0.8495284079029162,138.7897491455078,-3.103758751078203,3172,1381584,9.568328,J4,4.172522257581022,2.562681778316925,56.00299999999869,76.96759033203125,1.3982042982558198,-16.79741096496582,-2.1181050570836106,-7.157340049743652,0.1368160445594997,-126.7505111694336,4.172522257581022,18.698274612426758,1.0099135397388537,138.08377075195312,-3.8097371446328907,3175,1381585,9.576354,J4,4.999006937756803,3.042227585289095,64.02899999999967,77.21700286865234,1.6476168348769136,-17.061315536499023,-2.3820096286168138,-7.1720428466796875,0.12211324762346454,-125.92402648925781,4.999006937756803,18.86079978942871,1.1724387167408068,137.33689880371094,-4.556609092875078,6
11,11,1257,3334,1381645,10.056378,86.0934977330502,-14.498333177585573,-13.681510793859989,-69.8682955440411,26.742681901805224,88.9994136192388,3350,1381651,10.104322,J6,2.9848240516596434,2.0134925384056306,47.94399999999932,83.71662139892578,-2.376876334124418,-13.186573028564453,1.3117601490211204,-13.738808631896973,-0.05729783803698396,-72.70317840576172,-2.834882861720615,26.66758918762207,-0.07509271418315322,91.98423767089844,2.9848240516596434,3352,1381652,10.112375,J6,3.668104996483862,2.4582215610180698,55.99699999999963,83.25711822509766,-2.836379507952543,-12.97336483001709,1.5249683475684837,-13.721805572509766,-0.04029477864977693,-73.39217376708984,-3.52387822304874,26.632198333740234,-0.11048356806498916,92.66751861572266,3.668104996483862,3355,1381653,10.120334,J6,4.397696366112768,2.932320329432031,63.955999999999236,82.77881622314453,-3.314681509905668,-12.759296417236328,1.7390367603492454,-13.69810676574707,-0.016595971887081618,-74.13638305664062,-4.2680875125995215,26.590784072875977,-0.15189782892924697,93.39710998535156,4.397696366112768,6
12,12,1303,3455,1381691,10.424364,61.720732564877665,-4.2327893098442155,-9.784423185760874,-108.38408270751574,22.16077221865394,118.14206389103131,3470,1381697,10.472333,J6,4.000958239175844,1.9902461373621054,47.96900000000015,59.78955841064453,-1.9311741542331333,-2.7094168663024902,1.5233724435417253,-8.933828353881836,0.8505948318790377,-108.24857330322266,0.13550940429308866,21.177492141723633,-0.9832800769303063,114.14110565185547,-4.000958239175844,3474,1381698,10.480323,J6,4.9290969720860005,2.3936680954994465,55.95899999999965,59.577754974365234,-2.14297759051243,-2.4748787879943848,1.7579105218498308,-8.810709953308105,0.9737132324527682,-107.96444702148438,0.4196356860313699,21.03158187866211,-1.1291903399918297,113.21296691894531,-4.9290969720860005,3476,1381699,10.488357,J6,5.929425036050844,2.82736270797146,63.99299999999997,59.389400482177734,-2.33133208269993,-2.241248369216919,1.9915409406272966,-8.690967559814453,1.0934556259464205,-107.61585998535156,0.7682227221641824,20.888513565063477,-1.2722586535904625,112.21263885498047,-5.929425036050844,6
13,13,1362,3611,1381750,10.896324,79.75708299218505,4.6402310571176475,-15.311185536748695,-56.03531247084017,26.13313788666632,52.152257172101606,3627,1381756,10.944371,J1,6.656208938967296,4.109282348845555,48.047000000000395,86.41329193115234,6.656208938967296,4.266173362731934,-0.3740576943857139,-19.15987777709961,-3.848692240350914,-52.24028015136719,3.7950323194729805,29.853723526000977,3.720585639334658,55.86907196044922,3.7168147883476124,3629,1381757,10.952347,J1,7.722973770510265,4.798701518313248,56.02299999999971,87.48005676269531,7.722973770510265,4.181386947631836,-0.45884410948581156,-19.803678512573242,-4.492492975824547,-51.80745315551758,4.22785931532259,30.479778289794922,4.346640403128603,56.773921966552734,4.621664794451128,3633,1381758,10.960362,J1,8.793827957521984,5.501947903898078,64.03800000000004,88.55091094970703,8.793827957521984,4.09064245223999,-0.5495886048776573,-20.455745697021484,-5.144560160272789,-51.41057586669922,4.624736604140949,31.11459732055664,4.981459433890322,57.749176025390625,5.596918853289019,6
14,14,1393,3694,1381781,11.144347,108.95555081237923,1.3707600427061273,-33.59442519685133,-48.36736100282485,43.963403989432074,85.03926111958742,3710,1381787,11.192339,J6,2.93518040873289,1.5679827735552678,47.9920000000007,110.7523193359375,1.7967685235582707,0.8751887679100037,-0.4955712747961236,-34.756534576416016,-1.1621093795646829,-48.14332580566406,0.2240351971607879,45.0865592956543,1.1231553062222233,87.97444152832031,2.93518040873289,3712,1381788,11.20037,J6,3.224395496623515,1.7217974200989363,56.02299999999971,110.92666625976562,1.9711154473863957,0.7935436964035034,-0.5772163463026239,-34.86042404174805,-1.265998844896714,-48.102813720703125,0.2645472821217254,45.1879768371582,1.2245728477261295,88.26365661621094,3.224395496623515,3714,1381789,11.208359,J6,3.4549634287524214,1.844232474600388,64.01199999999996,111.0645751953125,2.1090243829332707,0.7117024660110474,-0.6590575766950799,-34.93739700317383,-1.3429718063224954,-48.06473159790039,0.3026294049244598,45.2645149230957,1.3011109336636295,88.49422454833984,3.4549634287524214,6
15,15,1426,3780,1381814,11.408361,110.58484797608095,-3.860899593758653,-32.39640711653168,-51.112590875369015,44.2291595765054,87.62399978413751,3796,1381820,11.456361,J4,2.573146734494266,1.686689503314435,48.00000000000004,111.79177856445312,1.206930588372174,-6.225440502166748,-2.364540908408095,-31.958988189697266,0.4374189268344111,-53.68573760986328,-2.573146734494266,44.76150894165039,0.532349365144988,89.33454895019531,1.7105491660578025,3798,1381821,11.464349,J4,3.0742606260958283,2.037357874022524,55.98800000000104,112.08367919921875,1.498831223137799,-6.6951823234558105,-2.8342827296971573,-31.910240173339844,0.48616694319183296,-54.186851501464844,-3.0742606260958283,44.907752990722656,0.6785934142172536,89.73998260498047,2.1159828208429587,3801,1381822,11.472359,J4,3.579433355588016,2.3980591339233284,63.998000000001554,112.39252471923828,1.8076767431573302,-7.177155494689941,-3.316255900931288,-31.86791229248047,0.528494824051208,-54.69202423095703,-3.579433355588016,45.06621170043945,0.8370521239340505,90.16300964355469,2.5390098594171775,6
16,16,1454,3854,1381842,11.63236,118.09595224767921,-17.37638727211256,-31.06900084212659,-59.56053843778568,48.73257576059714,94.13477131163891,3870,1381848,11.680362,J6,3.8105220440607894,2.197782779718695,48.00200000000032,117.87474060058594,-0.2212116470932699,-19.607177734375,-2.2307904622624406,-30.329103469848633,0.7398973722779587,-56.600250244140625,2.960288193645056,49.08655548095703,0.353979720359888,90.32424926757812,-3.8105220440607894,3872,1381849,11.688367,J6,4.756826365349852,2.710409629634467,56.00699999999925,117.7159423828125,-0.3800098648667074,-19.938819885253906,-2.562432613141347,-30.167478561401367,0.9015222807252243,-55.84638595581055,3.714152481975134,49.0964241027832,0.3638483421860599,89.37794494628906,-4.756826365349852,3874,1381850,11.696354,J6,5.783033335564696,3.263710825457299,63.99399999999922,117.52371978759766,-0.5722324600815512,-20.255823135375977,-2.879435863263417,-29.996501922607422,1.0724989195191696,-55.02521514892578,4.5353232888598995,49.092247009277344,0.3596712486802005,88.35173797607422,-5.783033335564696,6
17,18,1556,4121,1381944,12.448375,60.28248244838438,-22.938080568038327,-10.333247998560786,77.49164224770549,35.58337770883919,-69.66898071584893,4138,1381950,12.496365,J4,6.848522435693766,4.03614029285736,47.99000000000042,59.93589401245117,-0.34658843593320654,-21.102140426635742,1.8359401414025847,-9.684239387512207,0.6490086110485791,70.64311981201172,-6.848522435693766,32.941307067871094,-2.642070640968093,-63.34855651855469,6.320424197294244,4140,1381951,12.504369,J4,8.296535741357829,4.890437505980655,55.9940000000001,59.902915954589844,-0.37956649379453467,-20.689186096191406,2.2488944718469206,-9.52907943725586,0.8041685613049268,69.19510650634766,-8.296535741357829,32.343406677246094,-3.239971031593093,-62.032222747802734,7.636757968046197,4142,1381952,12.512395,J4,9.82779337075236,5.794164211715548,64.0199999999993,59.8752326965332,-0.4072497518511753,-20.24807357788086,2.6900069901574675,-9.361802101135254,0.9714458974255322,67.66384887695312,-9.82779337075236,31.704130172729492,-3.8792475361096947,-60.64377975463867,9.02520096121026,6
1 trigger_no waypoint_index best_sample_order best_frame_number best_sequence best_time_relative_s teach_j1_deg teach_j2_deg teach_j3_deg teach_j4_deg teach_j5_deg teach_j6_deg offset_6_frame_number offset_6_sequence offset_6_time_relative_s offset_6_max_error_axis offset_6_max_error_deg offset_6_rms_error_deg offset_6_delta_from_best_ms offset_6_j1_actual_deg offset_6_diff_j1_deg offset_6_j2_actual_deg offset_6_diff_j2_deg offset_6_j3_actual_deg offset_6_diff_j3_deg offset_6_j4_actual_deg offset_6_diff_j4_deg offset_6_j5_actual_deg offset_6_diff_j5_deg offset_6_j6_actual_deg offset_6_diff_j6_deg offset_7_frame_number offset_7_sequence offset_7_time_relative_s offset_7_max_error_axis offset_7_max_error_deg offset_7_rms_error_deg offset_7_delta_from_best_ms offset_7_j1_actual_deg offset_7_diff_j1_deg offset_7_j2_actual_deg offset_7_diff_j2_deg offset_7_j3_actual_deg offset_7_diff_j3_deg offset_7_j4_actual_deg offset_7_diff_j4_deg offset_7_j5_actual_deg offset_7_diff_j5_deg offset_7_j6_actual_deg offset_7_diff_j6_deg offset_8_frame_number offset_8_sequence offset_8_time_relative_s offset_8_max_error_axis offset_8_max_error_deg offset_8_rms_error_deg offset_8_delta_from_best_ms offset_8_j1_actual_deg offset_8_diff_j1_deg offset_8_j2_actual_deg offset_8_diff_j2_deg offset_8_j3_actual_deg offset_8_diff_j3_deg offset_8_j4_actual_deg offset_8_diff_j4_deg offset_8_j5_actual_deg offset_8_diff_j5_deg offset_8_j6_actual_deg offset_8_diff_j6_deg best_of_6_7_8_offset
2 1 1 730 1941 1381118 5.840207 48.886810269468405 2.1989850886957285 -11.021017368511105 0.4102097980549552 6.248381265333557 2.294990756284542 1955 1381124 5.888271 J6 3.4065268256551553 2.468438977201345 48.06399999999922 45.8632698059082 -3.0235404635602023 2.9724788665771484 0.7734937778814199 -13.609341621398926 -2.588324252887821 -2.1851141452789307 -2.5953239433338857 7.582361221313477 1.3339799559799195 5.701517581939697 3.4065268256551553 1958 1381125 5.896184 J6 4.180931828249149 2.9355776062802286 55.9769999999995 45.449710845947266 -3.43709942352114 3.117816925048828 0.9188318363530996 -13.963269233703613 -2.9422518651925085 -2.845515012741089 -3.255724810796044 7.768581867218018 1.5202006018844605 6.475922584533691 4.180931828249149 1961 1381126 5.904272 J6 5.0045521476156045 3.418446646752538 64.06499999999937 45.06731414794922 -3.8194961215191867 3.2660434246063232 1.0670583359105947 -14.290565490722656 -3.2695481222115514 -3.562589168548584 -3.972798966603539 7.9421586990356445 1.6937774337020874 7.2995429039001465 5.0045521476156045 6
3 2 2 804 2135 1381192 6.432175 55.34775509527405 11.807039833001637 -7.0090952672806885 -71.01433145543973 6.012065051914967 74.24953191606797 2151 1381198 6.480252 J4 2.8167225076858244 1.6562461612538633 48.07700000000015 56.34336471557617 0.995609620302119 11.66723918914795 -0.13980064385368784 -6.600923538208008 0.40817172907268073 -68.1976089477539 2.8167225076858244 6.058437347412109 0.04637229549714217 71.5392837524414 -2.7102481636265594 2153 1381199 6.488246 J4 3.526759739131137 2.060948429836345 56.071000000000204 56.451515197753906 1.1037601024798533 11.618118286132812 -0.18892154686882456 -6.580313682556152 0.4287815847245362 -67.4875717163086 3.526759739131137 6.09804105758667 0.08597600567170272 70.84339141845703 -3.4061404976109344 2155 1381200 6.496271 J4 4.301478977412387 2.5033932349312007 64.09600000000015 56.54535675048828 1.1976016552142283 11.561552047729492 -0.24548778527214488 -6.571277618408203 0.4378176488724854 -66.71285247802734 4.301478977412387 6.147788047790527 0.13572299587556014 70.078857421875 -4.170674494192966 6
4 3 3 832 2207 1381220 6.656264 55.109808014787404 8.759497374223619 -8.518216825284897 -41.11725046606459 10.108488114686867 41.956933292858096 2223 1381226 6.704225 J6 11.130744251720401 5.955607695749779 47.96099999999992 53.50831985473633 -1.6014881600510762 7.412222862243652 -1.3472745119799665 -9.629739761352539 -1.111522936067642 -32.30571365356445 8.811536812500137 12.488306045532227 2.379817930845359 30.826189041137695 -11.130744251720401 2227 1381227 6.712268 J6 13.165517124645206 7.03533795629365 56.00399999999972 53.18336486816406 -1.9264431466233418 7.154932975769043 -1.6045643984545759 -9.842713356018066 -1.3244965307331693 -30.750762939453125 10.366487526611465 12.961709976196289 2.8532218615094216 28.79141616821289 -13.165517124645206 2229 1381228 6.720286 J6 15.212756428234073 8.119717107623766 64.02199999999958 52.84844207763672 -2.2613659371506856 6.892857074737549 -1.86664029948607 -10.059968948364258 -1.5417521230793607 -29.200178146362305 11.917072319702285 13.449018478393555 3.340530363706687 26.744176864624023 -15.212756428234073 6
5 4 4 875 2321 1381263 7.000291 43.65359310453334 -1.629659559507137 -17.715753611915318 5.995208633582219 32.17171770646655 -22.573973337684023 2336 1381269 7.048266 J6 2.3116842904428125 1.3731583485126422 47.9750000000001 44.433006286621094 0.779413182087751 -2.1156294345855713 -0.48596987507843425 -18.39777374267578 -0.6820201307604634 4.8371992111206055 -1.158009422461613 33.99372482299805 1.8220071165314948 -20.26228904724121 2.3116842904428125 2339 1381270 7.056293 J6 3.083185831580508 1.7437179916275436 56.00200000000033 44.65972137451172 1.006128269978376 -2.1617355346679688 -0.5320759751608317 -18.490602493286133 -0.774848881370815 4.406780242919922 -1.5884283906622967 34.24979019165039 2.0780724851838386 -19.490787506103516 3.083185831580508 2341 1381271 7.064278 J6 3.9520155587533594 2.15807761350517 63.987000000000016 44.91068649291992 1.2570933883865791 -2.196718215942383 -0.5670586564352458 -18.575654983520508 -0.85990137160519 3.9164717197418213 -2.0787369138403973 34.48752212524414 2.3158044187775886 -18.621957778930664 3.9520155587533594 6
6 5 5 927 2457 1381315 7.416267 64.58244475717193 4.262979315506351 -15.669217122643433 -29.952927185666542 29.850439933020308 45.62652743544272 2477 1381321 7.464289 J5 2.171828177649214 1.404704060246151 48.021999999999565 65.84967041015625 1.2672256529843224 5.695003032684326 1.4320237171779748 -14.563636779785156 1.1055803428582767 -28.69342613220215 1.259501053464394 27.678611755371094 -2.171828177649214 46.437156677246094 0.810629241803376 2479 1381322 7.472265 J5 2.585320380408003 1.6670103454750829 55.99799999999977 66.01153564453125 1.4290908873593224 5.957343578338623 1.6943642628322717 -14.353693008422852 1.3155241142205814 -28.232824325561523 1.720102860105019 27.265119552612305 -2.585320380408003 46.24872589111328 0.6221984556705635 2483 1381323 7.480284 J5 3.0049218208376907 1.9507458917658702 64.01699999999977 66.15470886230469 1.57226410513276 6.221103191375732 1.958123875869381 -14.140877723693848 1.5283393989495853 -27.70670509338379 2.2462220922827534 26.845518112182617 -3.0049218208376907 45.96609115600586 0.33956372056314166 6
7 6 6 997 2649 1381385 7.976283 60.47948252708421 23.068781981390185 -5.01126420129949 36.10685486878251 5.525681179628412 -31.3025636495649 2665 1381391 8.024277 J2 1.408993592340284 0.8424031169595625 47.99400000000009 60.847530364990234 0.36804783790602613 24.47777557373047 1.408993592340284 -5.617043972015381 -0.6057797707158912 34.8044319152832 -1.3024229534993097 5.786255359649658 0.260574180021246 -31.2253475189209 0.07721613064400046 2667 1381392 8.032258 J4 1.7701696881184503 1.0669192783996628 55.975000000000996 60.95240783691406 0.47292530982985426 24.69621467590332 1.6274326945131357 -5.75187873840332 -0.7406145371038306 34.33668518066406 -1.7701696881184503 5.885775089263916 0.3600939096355038 -30.920429229736328 0.38213441982857077 2669 1381393 8.040307 J4 2.303903056038372 1.3309750271252634 64.02400000000074 61.06847381591797 0.5889912888337605 24.908491134643555 1.83970915325337 -5.895160675048828 -0.8838964737493384 33.80295181274414 -2.303903056038372 5.999467372894287 0.4737861932658749 -30.538488388061523 0.7640752615033755 6
8 7 7 1053 2795 1381441 8.424315 70.47583707168602 16.39384887825908 -13.456948007467595 -27.892318852946243 14.53566195089614 31.71193282686115 2811 1381447 8.472317 J6 7.1941073647892395 4.618545262978315 48.00200000000032 70.8250503540039 0.3492132823178906 10.95259952545166 -5.4412493528074215 -13.136046409606934 0.3209015978606615 -34.68459701538086 -6.7922781624346165 14.022420883178711 -0.5132410677174288 38.90604019165039 7.1941073647892395 2814 1381448 8.480253 J6 8.24868042387127 5.331515658278243 55.93799999999938 70.84622192382812 0.37038485214210937 9.979106903076172 -6.41474197518291 -13.042067527770996 0.414880479696599 -35.67851257324219 -7.786193720295945 13.882524490356445 -0.6531374605396945 39.96061325073242 8.24868042387127 2817 1381449 8.488291 J6 9.275558780804865 6.035874346469871 63.976000000000255 70.85871887207031 0.38288180038429687 8.986706733703613 -7.407142144555468 -12.9381742477417 0.5187737597258959 -36.64576721191406 -8.75344835896782 13.72922134399414 -0.8064406069019991 40.987491607666016 9.275558780804865 6
9 8 8 1089 2892 1381477 8.71231 69.58246408878419 -17.10571341532583 -8.710589696831251 -58.47569441890704 7.63059003611043 64.43773280685575 2908 1381483 8.760361 J6 5.93988407546847 3.533132924843701 48.05099999999918 69.40516662597656 -0.1772974628076298 -20.066781997680664 -2.9610685823548337 -8.152935981750488 0.5576537150807628 -63.93235397338867 -5.456659554481632 6.775912284851074 -0.8546777512593557 70.37761688232422 5.93988407546847 2910 1381484 8.768294 J6 6.922168621366907 4.090127751125079 55.9839999999987 69.39288330078125 -0.1895807880029423 -20.37982177734375 -3.2741083620179197 -8.094615936279297 0.6159737605519542 -64.83366394042969 -6.357969521522648 6.682157039642334 -0.948432996468096 71.35990142822266 6.922168621366907 2912 1381485 8.77637 J6 7.916950115507532 4.649086823187336 64.05999999999956 69.38455200195312 -0.1979120868310673 -20.654869079589844 -3.5491556642640134 -8.043557167053223 0.6670325297780284 -65.74622344970703 -7.270529030799992 6.598722457885742 -1.0318675782246878 72.35468292236328 7.916950115507532 6
10 9 9 1167 3096 1381555 9.336375 73.57125874861414 -6.42984524964374 -9.628579811400881 -128.80864727564332 14.671082817606491 140.00204816414424 3112 1381561 9.384332 J4 2.5240706198644887 1.630593251762862 47.95700000000025 73.90592956542969 0.3346708168155459 -8.016124725341797 -1.5862794756980572 -9.002426147460938 0.6261536639399434 -131.3327178955078 -2.5240706198644887 15.526206970214844 0.8551241526083526 142.41668701171875 2.4146388475745084 3114 1381562 9.392355 J4 2.830116152091051 1.8576181251506447 55.97999999999992 73.96361541748047 0.39235666886632714 -8.363268852233887 -1.933423602590147 -8.884164810180664 0.7444150012202169 -131.63876342773438 -2.830116152091051 15.65822696685791 0.987144149251419 142.69912719726562 2.6970790331213834 3118 1381563 9.400331 J4 3.1013106100988637 2.0726473342415157 63.955999999999236 74.02384948730469 0.4525907386905459 -8.728874206542969 -2.299028956899229 -8.76374626159668 0.8648335498042012 -131.9099578857422 -3.1013106100988637 15.788768768310547 1.1176859507040557 142.9464569091797 2.944408745035446 6
11 10 10 1189 3154 1381577 9.512325 75.56938603377543 -14.67930590788221 -7.294156094303152 -130.92303342701462 17.688361072687904 141.89350789658602 3170 1381583 9.560358 J4 3.3929965007450846 2.1059862266772753 48.033000000000214 76.72688293457031 1.1574969007948823 -16.518726348876953 -1.8394204409947434 -7.15147066116333 0.14268543313982196 -127.53003692626953 3.3929965007450846 18.53788948059082 0.8495284079029162 138.7897491455078 -3.103758751078203 3172 1381584 9.568328 J4 4.172522257581022 2.562681778316925 56.00299999999869 76.96759033203125 1.3982042982558198 -16.79741096496582 -2.1181050570836106 -7.157340049743652 0.1368160445594997 -126.7505111694336 4.172522257581022 18.698274612426758 1.0099135397388537 138.08377075195312 -3.8097371446328907 3175 1381585 9.576354 J4 4.999006937756803 3.042227585289095 64.02899999999967 77.21700286865234 1.6476168348769136 -17.061315536499023 -2.3820096286168138 -7.1720428466796875 0.12211324762346454 -125.92402648925781 4.999006937756803 18.86079978942871 1.1724387167408068 137.33689880371094 -4.556609092875078 6
12 11 11 1257 3334 1381645 10.056378 86.0934977330502 -14.498333177585573 -13.681510793859989 -69.8682955440411 26.742681901805224 88.9994136192388 3350 1381651 10.104322 J6 2.9848240516596434 2.0134925384056306 47.94399999999932 83.71662139892578 -2.376876334124418 -13.186573028564453 1.3117601490211204 -13.738808631896973 -0.05729783803698396 -72.70317840576172 -2.834882861720615 26.66758918762207 -0.07509271418315322 91.98423767089844 2.9848240516596434 3352 1381652 10.112375 J6 3.668104996483862 2.4582215610180698 55.99699999999963 83.25711822509766 -2.836379507952543 -12.97336483001709 1.5249683475684837 -13.721805572509766 -0.04029477864977693 -73.39217376708984 -3.52387822304874 26.632198333740234 -0.11048356806498916 92.66751861572266 3.668104996483862 3355 1381653 10.120334 J6 4.397696366112768 2.932320329432031 63.955999999999236 82.77881622314453 -3.314681509905668 -12.759296417236328 1.7390367603492454 -13.69810676574707 -0.016595971887081618 -74.13638305664062 -4.2680875125995215 26.590784072875977 -0.15189782892924697 93.39710998535156 4.397696366112768 6
13 12 12 1303 3455 1381691 10.424364 61.720732564877665 -4.2327893098442155 -9.784423185760874 -108.38408270751574 22.16077221865394 118.14206389103131 3470 1381697 10.472333 J6 4.000958239175844 1.9902461373621054 47.96900000000015 59.78955841064453 -1.9311741542331333 -2.7094168663024902 1.5233724435417253 -8.933828353881836 0.8505948318790377 -108.24857330322266 0.13550940429308866 21.177492141723633 -0.9832800769303063 114.14110565185547 -4.000958239175844 3474 1381698 10.480323 J6 4.9290969720860005 2.3936680954994465 55.95899999999965 59.577754974365234 -2.14297759051243 -2.4748787879943848 1.7579105218498308 -8.810709953308105 0.9737132324527682 -107.96444702148438 0.4196356860313699 21.03158187866211 -1.1291903399918297 113.21296691894531 -4.9290969720860005 3476 1381699 10.488357 J6 5.929425036050844 2.82736270797146 63.99299999999997 59.389400482177734 -2.33133208269993 -2.241248369216919 1.9915409406272966 -8.690967559814453 1.0934556259464205 -107.61585998535156 0.7682227221641824 20.888513565063477 -1.2722586535904625 112.21263885498047 -5.929425036050844 6
14 13 13 1362 3611 1381750 10.896324 79.75708299218505 4.6402310571176475 -15.311185536748695 -56.03531247084017 26.13313788666632 52.152257172101606 3627 1381756 10.944371 J1 6.656208938967296 4.109282348845555 48.047000000000395 86.41329193115234 6.656208938967296 4.266173362731934 -0.3740576943857139 -19.15987777709961 -3.848692240350914 -52.24028015136719 3.7950323194729805 29.853723526000977 3.720585639334658 55.86907196044922 3.7168147883476124 3629 1381757 10.952347 J1 7.722973770510265 4.798701518313248 56.02299999999971 87.48005676269531 7.722973770510265 4.181386947631836 -0.45884410948581156 -19.803678512573242 -4.492492975824547 -51.80745315551758 4.22785931532259 30.479778289794922 4.346640403128603 56.773921966552734 4.621664794451128 3633 1381758 10.960362 J1 8.793827957521984 5.501947903898078 64.03800000000004 88.55091094970703 8.793827957521984 4.09064245223999 -0.5495886048776573 -20.455745697021484 -5.144560160272789 -51.41057586669922 4.624736604140949 31.11459732055664 4.981459433890322 57.749176025390625 5.596918853289019 6
15 14 14 1393 3694 1381781 11.144347 108.95555081237923 1.3707600427061273 -33.59442519685133 -48.36736100282485 43.963403989432074 85.03926111958742 3710 1381787 11.192339 J6 2.93518040873289 1.5679827735552678 47.9920000000007 110.7523193359375 1.7967685235582707 0.8751887679100037 -0.4955712747961236 -34.756534576416016 -1.1621093795646829 -48.14332580566406 0.2240351971607879 45.0865592956543 1.1231553062222233 87.97444152832031 2.93518040873289 3712 1381788 11.20037 J6 3.224395496623515 1.7217974200989363 56.02299999999971 110.92666625976562 1.9711154473863957 0.7935436964035034 -0.5772163463026239 -34.86042404174805 -1.265998844896714 -48.102813720703125 0.2645472821217254 45.1879768371582 1.2245728477261295 88.26365661621094 3.224395496623515 3714 1381789 11.208359 J6 3.4549634287524214 1.844232474600388 64.01199999999996 111.0645751953125 2.1090243829332707 0.7117024660110474 -0.6590575766950799 -34.93739700317383 -1.3429718063224954 -48.06473159790039 0.3026294049244598 45.2645149230957 1.3011109336636295 88.49422454833984 3.4549634287524214 6
16 15 15 1426 3780 1381814 11.408361 110.58484797608095 -3.860899593758653 -32.39640711653168 -51.112590875369015 44.2291595765054 87.62399978413751 3796 1381820 11.456361 J4 2.573146734494266 1.686689503314435 48.00000000000004 111.79177856445312 1.206930588372174 -6.225440502166748 -2.364540908408095 -31.958988189697266 0.4374189268344111 -53.68573760986328 -2.573146734494266 44.76150894165039 0.532349365144988 89.33454895019531 1.7105491660578025 3798 1381821 11.464349 J4 3.0742606260958283 2.037357874022524 55.98800000000104 112.08367919921875 1.498831223137799 -6.6951823234558105 -2.8342827296971573 -31.910240173339844 0.48616694319183296 -54.186851501464844 -3.0742606260958283 44.907752990722656 0.6785934142172536 89.73998260498047 2.1159828208429587 3801 1381822 11.472359 J4 3.579433355588016 2.3980591339233284 63.998000000001554 112.39252471923828 1.8076767431573302 -7.177155494689941 -3.316255900931288 -31.86791229248047 0.528494824051208 -54.69202423095703 -3.579433355588016 45.06621170043945 0.8370521239340505 90.16300964355469 2.5390098594171775 6
17 16 16 1454 3854 1381842 11.63236 118.09595224767921 -17.37638727211256 -31.06900084212659 -59.56053843778568 48.73257576059714 94.13477131163891 3870 1381848 11.680362 J6 3.8105220440607894 2.197782779718695 48.00200000000032 117.87474060058594 -0.2212116470932699 -19.607177734375 -2.2307904622624406 -30.329103469848633 0.7398973722779587 -56.600250244140625 2.960288193645056 49.08655548095703 0.353979720359888 90.32424926757812 -3.8105220440607894 3872 1381849 11.688367 J6 4.756826365349852 2.710409629634467 56.00699999999925 117.7159423828125 -0.3800098648667074 -19.938819885253906 -2.562432613141347 -30.167478561401367 0.9015222807252243 -55.84638595581055 3.714152481975134 49.0964241027832 0.3638483421860599 89.37794494628906 -4.756826365349852 3874 1381850 11.696354 J6 5.783033335564696 3.263710825457299 63.99399999999922 117.52371978759766 -0.5722324600815512 -20.255823135375977 -2.879435863263417 -29.996501922607422 1.0724989195191696 -55.02521514892578 4.5353232888598995 49.092247009277344 0.3596712486802005 88.35173797607422 -5.783033335564696 6
18 17 18 1556 4121 1381944 12.448375 60.28248244838438 -22.938080568038327 -10.333247998560786 77.49164224770549 35.58337770883919 -69.66898071584893 4138 1381950 12.496365 J4 6.848522435693766 4.03614029285736 47.99000000000042 59.93589401245117 -0.34658843593320654 -21.102140426635742 1.8359401414025847 -9.684239387512207 0.6490086110485791 70.64311981201172 -6.848522435693766 32.941307067871094 -2.642070640968093 -63.34855651855469 6.320424197294244 4140 1381951 12.504369 J4 8.296535741357829 4.890437505980655 55.9940000000001 59.902915954589844 -0.37956649379453467 -20.689186096191406 2.2488944718469206 -9.52907943725586 0.8041685613049268 69.19510650634766 -8.296535741357829 32.343406677246094 -3.239971031593093 -62.032222747802734 7.636757968046197 4142 1381952 12.512395 J4 9.82779337075236 5.794164211715548 64.0199999999993 59.8752326965332 -0.4072497518511753 -20.24807357788086 2.6900069901574675 -9.361802101135254 0.9714458974255322 67.66384887695312 -9.82779337075236 31.704130172729492 -3.8792475361096947 -60.64377975463867 9.02520096121026 6

View File

@@ -0,0 +1,18 @@
{
"rows": 17,
"best_offset_win_counts": {
"6": 17,
"7": 0,
"8": 0
},
"average_max_error_deg": {
"6": 4.241583591714439,
"7": 5.068092118561757,
"8": 5.9316839578472145
},
"average_rms_error_deg": {
"6": 2.5406136706026206,
"7": 3.021296972079456,
"8": 3.5201758351699857
}
}

View File

@@ -0,0 +1,18 @@
trigger_no,waypoint_index,trigger_frame_number,trigger_time_relative_s,trigger_sequence,paired_status_frame_number,paired_status_time_relative_s,paired_status_sequence,paired_status_timestamp,paired_status_to_trigger_sequence_delta,paired_status_to_trigger_time_ms,teach_j1_deg,teach_j2_deg,teach_j3_deg,teach_j4_deg,teach_j5_deg,teach_j6_deg,paired_status_j1_actual_deg,paired_status_diff_j1_deg,paired_status_j2_actual_deg,paired_status_diff_j2_deg,paired_status_j3_actual_deg,paired_status_diff_j3_deg,paired_status_j4_actual_deg,paired_status_diff_j4_deg,paired_status_j5_actual_deg,paired_status_diff_j5_deg,paired_status_j6_actual_deg,paired_status_diff_j6_deg,paired_status_max_error_axis,paired_status_max_error_deg,paired_status_rms_error_deg,best_status_frame_number,best_status_time_relative_s,best_status_sequence,best_status_timestamp,best_status_delta_from_paired_cycles,best_status_delta_from_trigger_sequence,best_status_time_after_trigger_ms,best_status_j1_actual_deg,best_status_diff_j1_deg,best_status_j2_actual_deg,best_status_diff_j2_deg,best_status_j3_actual_deg,best_status_diff_j3_deg,best_status_j4_actual_deg,best_status_diff_j4_deg,best_status_j5_actual_deg,best_status_diff_j5_deg,best_status_j6_actual_deg,best_status_diff_j6_deg,best_status_max_error_axis,best_status_max_error_deg,best_status_rms_error_deg
1,1,1955,5.888271,1381124,1954,5.888166,1381116,624368380,-8,-0.10499999999957765,48.886810269468405,2.1989850886957285,-11.021017368511105,0.4102097980549552,6.248381265333557,2.294990756284542,55.47505187988281,6.588241610414407,1.2506256103515625,-0.948359478344166,-5.400295734405518,5.620721634105587,0.5259769558906555,0.1157671578357003,3.3612561225891113,-2.8871251427444458,0.44421958923339844,-1.8507711670511435,J1,6.588241610414407,3.8225443630072706,1981,5.968124,1381126,624368460,10,2,79.85300000000083,48.76339340209961,-0.12341686736879609,2.256481647491455,0.05749655879572657,-11.157909393310547,-0.13689202479944207,0.37860527634620667,-0.031604521708748556,6.3406662940979,0.0922850287643433,2.5025806427001953,0.20758988641565335,J6,0.20758988641565335,0.12239685259209541
2,2,2151,6.480252,1381198,2150,6.480138,1381190,624368972,-8,-0.11399999999994748,55.34775509527405,11.807039833001637,-7.0090952672806885,-71.01433145543973,6.012065051914967,74.24953191606797,53.0124397277832,-2.33531536749085,11.506516456604004,-0.30052337639763316,-8.466276168823242,-1.4571809015425536,-69.63382720947266,1.3805042459670744,6.426647663116455,0.41458261120148787,72.93537902832031,-1.3141528877476532,J1,2.33531536749085,1.3827543088729335,2172,6.552164,1381199,624369044,9,1,71.9120000000002,55.265621185302734,-0.08213390997131853,11.803675651550293,-0.003364181451344095,-7.050373554229736,-0.04127828694904778,-71.06609344482422,-0.05176198938448806,6.026607990264893,0.014542938349925372,74.28738403320312,0.03785211713515935,J1,0.08213390997131853,0.04616054814443023
3,3,2223,6.704225,1381226,2222,6.704166,1381218,624369196,-8,-0.059000000000253294,55.109808014787404,8.759497374223619,-8.518216825284897,-41.11725046606459,10.108488114686867,41.956933292858096,56.5781364440918,1.4683284293043926,10.494372367858887,1.7348749936352679,-7.114619255065918,1.4035975702189791,-55.112239837646484,-13.994989371581894,7.423236846923828,-2.6852512677630394,58.080867767333984,16.123934474475888,J6,16.123934474475888,8.852376616648156,2248,6.784154,1381228,624369276,10,2,79.92899999999992,55.00252151489258,-0.10728649989482619,8.69005012512207,-0.06944724910154854,-8.577027320861816,-0.05881049557691931,-40.59286117553711,0.5243892905274805,10.210430145263672,0.1019420305768044,41.38724136352539,-0.5696919293327056,J6,0.5696919293327056,0.3239642953120798
4,4,2336,7.048266,1381269,2335,7.048148,1381261,624369540,-8,-0.11799999999961841,43.65359310453334,-1.629659559507137,-17.715753611915318,5.995208633582219,32.17171770646655,-22.573973337684023,44.479610443115234,0.8260173385818916,0.07192186266183853,1.7015814221689756,-15.996956825256348,1.7187967866589702,2.40028715133667,-3.5949214822455486,27.737812042236328,-4.433905664230224,-17.672090530395508,4.901882807288516,J6,4.901882807288516,3.2440556235708993,2362,7.128175,1381271,624369620,10,2,79.90899999999979,43.72715759277344,0.07356448824009476,-1.6386029720306396,-0.008943412523502614,-17.75617218017578,-0.04041856826046342,5.952699661254883,-0.04250897232733575,32.2616081237793,0.08989041731274483,-22.47926902770996,0.09470430997406254,J6,0.09470430997406254,0.06580474324148583
5,5,2477,7.464289,1381321,2476,7.464178,1381313,624369956,-8,-0.11099999999952814,64.58244475717193,4.262979315506351,-15.669217122643433,-29.952927185666542,29.850439933020308,45.62652743544272,60.830230712890625,-3.7522140442813026,1.8808640241622925,-2.382115291344059,-17.297021865844727,-1.6278047432012936,-26.684900283813477,3.268026901853066,33.02191925048828,3.1714793174679734,36.40708923339844,-9.21943820204428,J6,9.21943820204428,4.621321121191458,2502,7.544122,1381323,624370036,10,2,79.83299999999983,64.5761947631836,-0.006249993988333813,4.283629417419434,0.020650101913082253,-15.615406036376953,0.05381108626647979,-29.94143295288086,0.011494232785683067,29.7938175201416,-0.056622412878706285,45.61851119995117,-0.008016235491545842,J5,0.056622412878706285,0.03357478517689402
6,6,2665,8.024277,1381391,2664,8.024156,1381383,624370516,-8,-0.12100000000003774,60.47948252708421,23.068781981390185,-5.01126420129949,36.10685486878251,5.525681179628412,-31.3025636495649,60.89759063720703,0.418108110122823,20.716407775878906,-2.3523742055112784,-4.913214206695557,0.09804999460393304,32.72084045410156,-3.3860144146809503,6.405356407165527,0.8796752275371151,-25.156103134155273,6.1464605154096255,J6,6.1464605154096255,3.0478405356855083,2687,8.096181,1381392,624370588,9,1,71.90399999999997,60.54315185546875,0.06366932838454176,22.99761962890625,-0.07116235248393465,-5.037043571472168,-0.025779370172678284,36.056732177734375,-0.050122691048137824,5.545217037200928,0.019535857572515525,-31.12558937072754,0.17697427883735983,J6,0.17697427883735983,0.08563125303054821
7,7,2811,8.472317,1381447,2810,8.472208,1381439,624370964,-8,-0.10900000000013677,70.47583707168602,16.39384887825908,-13.456948007467595,-27.892318852946243,14.53566195089614,31.71193282686115,69.13842010498047,-1.3374169667055469,22.202428817749023,5.808579939489942,-12.907807350158691,0.5491406573089037,-15.469873428344727,12.422445424601516,14.040997505187988,-0.4946644457081515,18.56021499633789,-13.15171783052326,J6,13.15171783052326,7.78202379046887,2834,8.54419,1381448,624371036,9,1,71.87300000000008,70.3967514038086,-0.07908566787742188,16.456680297851562,0.06283141959248084,-13.330730438232422,0.12621756923517324,-27.611600875854492,0.2807179770917507,14.542427062988281,0.006765112092141479,31.405345916748047,-0.30658691011310424,J6,0.30658691011310424,0.18210669390591905
8,8,2908,8.760361,1381483,2907,8.760245,1381475,624371252,-8,-0.11600000000022703,69.58246408878419,-17.10571341532583,-8.710589696831251,-58.47569441890704,7.63059003611043,64.43773280685575,70.10379791259766,0.5213338238134639,-10.075156211853027,7.030557203472803,-9.98978042602539,-1.2791907291941396,-51.5866584777832,6.889035941123836,9.534638404846191,1.9040483687357614,57.0014533996582,-7.436279407197546,J6,7.436279407197546,5.127041386597523,2929,8.832199,1381484,624371324,9,1,71.83799999999962,69.59716033935547,0.014696250571276437,-17.044965744018555,0.06074767130727565,-8.703485488891602,0.007104207939649498,-58.473426818847656,0.0022676000593833123,7.6463942527771,0.015804216666669646,64.45584869384766,0.01811588699190736,J2,0.06074767130727565,0.02750705896232285
9,9,3112,9.384332,1381561,3111,9.384204,1381553,624371876,-8,-0.128000000000128,73.57125874861414,-6.42984524964374,-9.628579811400881,-128.80864727564332,14.671082817606491,140.00204816414424,72.96144104003906,-0.6098177085750791,-6.3001484870910645,0.12969676255267526,-10.035088539123535,-0.40650872772265423,-123.29313659667969,5.515510678963636,13.165532112121582,-1.505550705484909,134.41644287109375,-5.585605293050492,J6,5.585605293050492,3.277206017832995,3134,9.456205,1381562,624371948,9,1,71.87300000000008,73.55095672607422,-0.02030202253992286,-6.441007614135742,-0.011162364492002474,-9.614203453063965,0.014376358336916084,-128.65638732910156,0.15225994654176134,14.635379791259766,-0.03570302634672551,139.8520965576172,-0.14995160652705408,J4,0.15225994654176134,0.089150370994325
10,10,3170,9.560358,1381583,3169,9.56025,1381575,624372052,-8,-0.10800000000088517,75.56938603377543,-14.67930590788221,-7.294156094303152,-130.92303342701462,17.688361072687904,141.89350789658602,74.36400604248047,-1.2053799912949614,-10.514228820800781,4.165077087081428,-8.236283302307129,-0.9421272080039769,-132.6507110595703,-1.7276776325556966,16.38176155090332,-1.3065995217845838,143.5712890625,1.6777811659139843,J2,4.165077087081428,2.128983861449047,3196,9.640214,1381585,624372132,10,2,79.85599999999948,75.62290954589844,0.05352351212300732,-14.662798881530762,0.016507026351447962,-7.297325611114502,-0.003169516811349915,-130.88812255859375,0.03491086842086588,17.726865768432617,0.03850469574471305,141.820068359375,-0.0734395372110157,J6,0.0734395372110157,0.043285948566531826
11,11,3350,10.104322,1381651,3349,10.104215,1381643,624372596,-8,-0.10699999999985721,86.0934977330502,-14.498333177585573,-13.681510793859989,-69.8682955440411,26.742681901805224,88.9994136192388,87.81878662109375,1.7252888880435506,-16.329286575317383,-1.8309533977318093,-13.073507308959961,0.6080034849000278,-70.97254180908203,-1.1042462650409277,26.366661071777344,-0.3760208300278798,89.37981414794922,0.3804005287104246,J2,1.8309533977318093,1.169340011162825,3373,10.17622,1381652,624372668,9,1,71.8980000000009,86.11857604980469,0.025078316754488128,-14.53605842590332,-0.03772524831774682,-13.651655197143555,0.029855596716434007,-69.8272933959961,0.04100214804500979,26.72992706298828,-0.012754838816942282,88.92174530029297,-0.07766831894582538,J6,0.07766831894582538,0.04246508921571141
12,12,3470,10.472333,1381697,3469,10.472191,1381689,624372964,-8,-0.14200000000030855,61.720732564877665,-4.2327893098442155,-9.784423185760874,-108.38408270751574,22.16077221865394,118.14206389103131,65.91849517822266,4.197762613344992,-6.331206798553467,-2.0984174887092513,-11.008773803710938,-1.2243506179500638,-103.56172943115234,4.822353276363401,23.532543182373047,1.3717709637191078,117.46694946289062,-0.675114428140688,J4,4.822353276363401,2.8611252897135864,3493,10.544283,1381698,624373036,9,1,71.94999999999929,61.7418098449707,0.021077280093038553,-4.212831497192383,0.019957812651832718,-9.789913177490234,-0.00548999172936071,-108.36312103271484,0.020961674800901164,22.163673400878906,0.002901182224967158,118.13783264160156,-0.0042312494297505054,J1,0.021077280093038553,0.014935517911187784
13,13,3627,10.944371,1381756,3626,10.944251,1381748,624373436,-8,-0.12000000000078614,79.75708299218505,4.6402310571176475,-15.311185536748695,-56.03531247084017,26.13313788666632,52.152257172101606,72.04009246826172,-7.716990523923329,4.5515007972717285,-0.08873025984591898,-11.385177612304688,3.926007924444008,-64.18782043457031,-8.152507963730145,22.412456512451172,-3.7206813742151468,54.39056396484375,2.2383067927421436,J4,8.152507963730145,5.168659196117862,3651,11.016226,1381757,624373508,9,1,71.85499999999934,79.90262603759766,0.14554304541260876,4.62429666519165,-0.015934391925997105,-15.370849609375,-0.05966407262630469,-55.99199676513672,0.043315705703449225,26.182939529418945,0.04980164275262666,52.15596008300781,0.003702910906206114,J1,0.14554304541260876,0.0699602863618738
14,14,3710,11.192339,1381787,3709,11.19225,1381779,624373684,-8,-0.08900000000089392,108.95555081237923,1.3707600427061273,-33.59442519685133,-48.36736100282485,43.963403989432074,85.03926111958742,102.20675659179688,-6.748794220582354,2.5045764446258545,1.1338164019197272,-29.148040771484375,4.446384425366958,-48.76271438598633,-0.3953533831614777,39.65629959106445,-4.3071043983676205,74.63484191894531,-10.40441920064211,J6,10.40441920064211,5.679810575214033,3735,11.272261,1381789,624373764,10,2,79.92199999999983,108.94917297363281,-0.006377838746416842,1.3447811603546143,-0.025978882351513022,-33.561458587646484,0.032966609204848396,-48.376487731933594,-0.009126729108743348,44.02882766723633,0.06542367780425451,85.1587142944336,0.11945317484617135,J6,0.11945317484617135,0.05835950688086092
15,15,3796,11.456361,1381820,3795,11.456253,1381812,624373948,-8,-0.10799999999910881,110.58484797608095,-3.860899593758653,-32.39640711653168,-51.112590875369015,44.2291595765054,87.62399978413751,110.58193969726562,-0.002908278815326071,-1.244791865348816,2.6161077284098373,-33.74542999267578,-1.3490228761441045,-48.585723876953125,2.5268669984158905,44.58126449584961,0.35210491934420673,87.75857543945312,0.134575655315615,J2,2.6161077284098373,1.5911754635072362,3821,11.536287,1381822,624374028,10,2,79.92600000000039,110.67292022705078,0.08807225096983018,-4.010702133178711,-0.14980253942005772,-32.37457275390625,0.021834362625426706,-51.22603225708008,-0.11344138171106266,44.249629974365234,0.020470397859831735,87.66435241699219,0.040352632854677495,J2,0.14980253942005772,0.08716897465096986
16,16,3870,11.680362,1381848,3869,11.680263,1381840,624374172,-8,-0.09900000000051534,118.09595224767921,-17.37638727211256,-31.06900084212659,-59.56053843778568,48.73257576059714,94.13477131163891,115.98970031738281,-2.106251930296395,-12.693913459777832,4.682473812334727,-31.563575744628906,-0.49457490250231473,-59.300933837890625,0.2596045998950558,47.15116500854492,-1.5814107520522214,94.34331512451172,0.20854381287280432,J2,4.682473812334727,2.2067399623329567,3895,11.760326,1381850,624374252,10,2,79.96399999999859,118.06391906738281,-0.0320331802963949,-17.536325454711914,-0.15993818259935466,-31.00341796875,0.06558287337659152,-59.507286071777344,0.05325236600833705,48.77106475830078,0.038488997703638006,93.9618148803711,-0.17295643126782068,J6,0.17295643126782068,0.10419421346699378
17,18,4138,12.496365,1381950,4137,12.496271,1381942,624374988,-8,-0.09400000000070463,60.28248244838438,-22.938080568038327,-10.333247998560786,77.49164224770549,35.58337770883919,-69.66898071584893,61.48033142089844,1.197848972514059,-23.1823787689209,-0.2442982008825716,-10.346473693847656,-0.01322569528687012,79.24906921386719,1.7574269661617024,35.91868591308594,0.33530820424675056,-71.48294067382812,-1.8139599579791934,J6,1.8139599579791934,1.1536991630766555,4159,12.568313,1381951,624375060,9,1,71.94799999999901,60.27695846557617,-0.00552398280820654,-22.918088912963867,0.019991655074459658,-10.347146987915039,-0.013898989354252933,77.54158782958984,0.0499455818843586,35.57386016845703,-0.009517540382155687,-69.74390411376953,-0.07492339792059965,J6,0.07492339792059965,0.03834497543010648
1 trigger_no waypoint_index trigger_frame_number trigger_time_relative_s trigger_sequence paired_status_frame_number paired_status_time_relative_s paired_status_sequence paired_status_timestamp paired_status_to_trigger_sequence_delta paired_status_to_trigger_time_ms teach_j1_deg teach_j2_deg teach_j3_deg teach_j4_deg teach_j5_deg teach_j6_deg paired_status_j1_actual_deg paired_status_diff_j1_deg paired_status_j2_actual_deg paired_status_diff_j2_deg paired_status_j3_actual_deg paired_status_diff_j3_deg paired_status_j4_actual_deg paired_status_diff_j4_deg paired_status_j5_actual_deg paired_status_diff_j5_deg paired_status_j6_actual_deg paired_status_diff_j6_deg paired_status_max_error_axis paired_status_max_error_deg paired_status_rms_error_deg best_status_frame_number best_status_time_relative_s best_status_sequence best_status_timestamp best_status_delta_from_paired_cycles best_status_delta_from_trigger_sequence best_status_time_after_trigger_ms best_status_j1_actual_deg best_status_diff_j1_deg best_status_j2_actual_deg best_status_diff_j2_deg best_status_j3_actual_deg best_status_diff_j3_deg best_status_j4_actual_deg best_status_diff_j4_deg best_status_j5_actual_deg best_status_diff_j5_deg best_status_j6_actual_deg best_status_diff_j6_deg best_status_max_error_axis best_status_max_error_deg best_status_rms_error_deg
2 1 1 1955 5.888271 1381124 1954 5.888166 1381116 624368380 -8 -0.10499999999957765 48.886810269468405 2.1989850886957285 -11.021017368511105 0.4102097980549552 6.248381265333557 2.294990756284542 55.47505187988281 6.588241610414407 1.2506256103515625 -0.948359478344166 -5.400295734405518 5.620721634105587 0.5259769558906555 0.1157671578357003 3.3612561225891113 -2.8871251427444458 0.44421958923339844 -1.8507711670511435 J1 6.588241610414407 3.8225443630072706 1981 5.968124 1381126 624368460 10 2 79.85300000000083 48.76339340209961 -0.12341686736879609 2.256481647491455 0.05749655879572657 -11.157909393310547 -0.13689202479944207 0.37860527634620667 -0.031604521708748556 6.3406662940979 0.0922850287643433 2.5025806427001953 0.20758988641565335 J6 0.20758988641565335 0.12239685259209541
3 2 2 2151 6.480252 1381198 2150 6.480138 1381190 624368972 -8 -0.11399999999994748 55.34775509527405 11.807039833001637 -7.0090952672806885 -71.01433145543973 6.012065051914967 74.24953191606797 53.0124397277832 -2.33531536749085 11.506516456604004 -0.30052337639763316 -8.466276168823242 -1.4571809015425536 -69.63382720947266 1.3805042459670744 6.426647663116455 0.41458261120148787 72.93537902832031 -1.3141528877476532 J1 2.33531536749085 1.3827543088729335 2172 6.552164 1381199 624369044 9 1 71.9120000000002 55.265621185302734 -0.08213390997131853 11.803675651550293 -0.003364181451344095 -7.050373554229736 -0.04127828694904778 -71.06609344482422 -0.05176198938448806 6.026607990264893 0.014542938349925372 74.28738403320312 0.03785211713515935 J1 0.08213390997131853 0.04616054814443023
4 3 3 2223 6.704225 1381226 2222 6.704166 1381218 624369196 -8 -0.059000000000253294 55.109808014787404 8.759497374223619 -8.518216825284897 -41.11725046606459 10.108488114686867 41.956933292858096 56.5781364440918 1.4683284293043926 10.494372367858887 1.7348749936352679 -7.114619255065918 1.4035975702189791 -55.112239837646484 -13.994989371581894 7.423236846923828 -2.6852512677630394 58.080867767333984 16.123934474475888 J6 16.123934474475888 8.852376616648156 2248 6.784154 1381228 624369276 10 2 79.92899999999992 55.00252151489258 -0.10728649989482619 8.69005012512207 -0.06944724910154854 -8.577027320861816 -0.05881049557691931 -40.59286117553711 0.5243892905274805 10.210430145263672 0.1019420305768044 41.38724136352539 -0.5696919293327056 J6 0.5696919293327056 0.3239642953120798
5 4 4 2336 7.048266 1381269 2335 7.048148 1381261 624369540 -8 -0.11799999999961841 43.65359310453334 -1.629659559507137 -17.715753611915318 5.995208633582219 32.17171770646655 -22.573973337684023 44.479610443115234 0.8260173385818916 0.07192186266183853 1.7015814221689756 -15.996956825256348 1.7187967866589702 2.40028715133667 -3.5949214822455486 27.737812042236328 -4.433905664230224 -17.672090530395508 4.901882807288516 J6 4.901882807288516 3.2440556235708993 2362 7.128175 1381271 624369620 10 2 79.90899999999979 43.72715759277344 0.07356448824009476 -1.6386029720306396 -0.008943412523502614 -17.75617218017578 -0.04041856826046342 5.952699661254883 -0.04250897232733575 32.2616081237793 0.08989041731274483 -22.47926902770996 0.09470430997406254 J6 0.09470430997406254 0.06580474324148583
6 5 5 2477 7.464289 1381321 2476 7.464178 1381313 624369956 -8 -0.11099999999952814 64.58244475717193 4.262979315506351 -15.669217122643433 -29.952927185666542 29.850439933020308 45.62652743544272 60.830230712890625 -3.7522140442813026 1.8808640241622925 -2.382115291344059 -17.297021865844727 -1.6278047432012936 -26.684900283813477 3.268026901853066 33.02191925048828 3.1714793174679734 36.40708923339844 -9.21943820204428 J6 9.21943820204428 4.621321121191458 2502 7.544122 1381323 624370036 10 2 79.83299999999983 64.5761947631836 -0.006249993988333813 4.283629417419434 0.020650101913082253 -15.615406036376953 0.05381108626647979 -29.94143295288086 0.011494232785683067 29.7938175201416 -0.056622412878706285 45.61851119995117 -0.008016235491545842 J5 0.056622412878706285 0.03357478517689402
7 6 6 2665 8.024277 1381391 2664 8.024156 1381383 624370516 -8 -0.12100000000003774 60.47948252708421 23.068781981390185 -5.01126420129949 36.10685486878251 5.525681179628412 -31.3025636495649 60.89759063720703 0.418108110122823 20.716407775878906 -2.3523742055112784 -4.913214206695557 0.09804999460393304 32.72084045410156 -3.3860144146809503 6.405356407165527 0.8796752275371151 -25.156103134155273 6.1464605154096255 J6 6.1464605154096255 3.0478405356855083 2687 8.096181 1381392 624370588 9 1 71.90399999999997 60.54315185546875 0.06366932838454176 22.99761962890625 -0.07116235248393465 -5.037043571472168 -0.025779370172678284 36.056732177734375 -0.050122691048137824 5.545217037200928 0.019535857572515525 -31.12558937072754 0.17697427883735983 J6 0.17697427883735983 0.08563125303054821
8 7 7 2811 8.472317 1381447 2810 8.472208 1381439 624370964 -8 -0.10900000000013677 70.47583707168602 16.39384887825908 -13.456948007467595 -27.892318852946243 14.53566195089614 31.71193282686115 69.13842010498047 -1.3374169667055469 22.202428817749023 5.808579939489942 -12.907807350158691 0.5491406573089037 -15.469873428344727 12.422445424601516 14.040997505187988 -0.4946644457081515 18.56021499633789 -13.15171783052326 J6 13.15171783052326 7.78202379046887 2834 8.54419 1381448 624371036 9 1 71.87300000000008 70.3967514038086 -0.07908566787742188 16.456680297851562 0.06283141959248084 -13.330730438232422 0.12621756923517324 -27.611600875854492 0.2807179770917507 14.542427062988281 0.006765112092141479 31.405345916748047 -0.30658691011310424 J6 0.30658691011310424 0.18210669390591905
9 8 8 2908 8.760361 1381483 2907 8.760245 1381475 624371252 -8 -0.11600000000022703 69.58246408878419 -17.10571341532583 -8.710589696831251 -58.47569441890704 7.63059003611043 64.43773280685575 70.10379791259766 0.5213338238134639 -10.075156211853027 7.030557203472803 -9.98978042602539 -1.2791907291941396 -51.5866584777832 6.889035941123836 9.534638404846191 1.9040483687357614 57.0014533996582 -7.436279407197546 J6 7.436279407197546 5.127041386597523 2929 8.832199 1381484 624371324 9 1 71.83799999999962 69.59716033935547 0.014696250571276437 -17.044965744018555 0.06074767130727565 -8.703485488891602 0.007104207939649498 -58.473426818847656 0.0022676000593833123 7.6463942527771 0.015804216666669646 64.45584869384766 0.01811588699190736 J2 0.06074767130727565 0.02750705896232285
10 9 9 3112 9.384332 1381561 3111 9.384204 1381553 624371876 -8 -0.128000000000128 73.57125874861414 -6.42984524964374 -9.628579811400881 -128.80864727564332 14.671082817606491 140.00204816414424 72.96144104003906 -0.6098177085750791 -6.3001484870910645 0.12969676255267526 -10.035088539123535 -0.40650872772265423 -123.29313659667969 5.515510678963636 13.165532112121582 -1.505550705484909 134.41644287109375 -5.585605293050492 J6 5.585605293050492 3.277206017832995 3134 9.456205 1381562 624371948 9 1 71.87300000000008 73.55095672607422 -0.02030202253992286 -6.441007614135742 -0.011162364492002474 -9.614203453063965 0.014376358336916084 -128.65638732910156 0.15225994654176134 14.635379791259766 -0.03570302634672551 139.8520965576172 -0.14995160652705408 J4 0.15225994654176134 0.089150370994325
11 10 10 3170 9.560358 1381583 3169 9.56025 1381575 624372052 -8 -0.10800000000088517 75.56938603377543 -14.67930590788221 -7.294156094303152 -130.92303342701462 17.688361072687904 141.89350789658602 74.36400604248047 -1.2053799912949614 -10.514228820800781 4.165077087081428 -8.236283302307129 -0.9421272080039769 -132.6507110595703 -1.7276776325556966 16.38176155090332 -1.3065995217845838 143.5712890625 1.6777811659139843 J2 4.165077087081428 2.128983861449047 3196 9.640214 1381585 624372132 10 2 79.85599999999948 75.62290954589844 0.05352351212300732 -14.662798881530762 0.016507026351447962 -7.297325611114502 -0.003169516811349915 -130.88812255859375 0.03491086842086588 17.726865768432617 0.03850469574471305 141.820068359375 -0.0734395372110157 J6 0.0734395372110157 0.043285948566531826
12 11 11 3350 10.104322 1381651 3349 10.104215 1381643 624372596 -8 -0.10699999999985721 86.0934977330502 -14.498333177585573 -13.681510793859989 -69.8682955440411 26.742681901805224 88.9994136192388 87.81878662109375 1.7252888880435506 -16.329286575317383 -1.8309533977318093 -13.073507308959961 0.6080034849000278 -70.97254180908203 -1.1042462650409277 26.366661071777344 -0.3760208300278798 89.37981414794922 0.3804005287104246 J2 1.8309533977318093 1.169340011162825 3373 10.17622 1381652 624372668 9 1 71.8980000000009 86.11857604980469 0.025078316754488128 -14.53605842590332 -0.03772524831774682 -13.651655197143555 0.029855596716434007 -69.8272933959961 0.04100214804500979 26.72992706298828 -0.012754838816942282 88.92174530029297 -0.07766831894582538 J6 0.07766831894582538 0.04246508921571141
13 12 12 3470 10.472333 1381697 3469 10.472191 1381689 624372964 -8 -0.14200000000030855 61.720732564877665 -4.2327893098442155 -9.784423185760874 -108.38408270751574 22.16077221865394 118.14206389103131 65.91849517822266 4.197762613344992 -6.331206798553467 -2.0984174887092513 -11.008773803710938 -1.2243506179500638 -103.56172943115234 4.822353276363401 23.532543182373047 1.3717709637191078 117.46694946289062 -0.675114428140688 J4 4.822353276363401 2.8611252897135864 3493 10.544283 1381698 624373036 9 1 71.94999999999929 61.7418098449707 0.021077280093038553 -4.212831497192383 0.019957812651832718 -9.789913177490234 -0.00548999172936071 -108.36312103271484 0.020961674800901164 22.163673400878906 0.002901182224967158 118.13783264160156 -0.0042312494297505054 J1 0.021077280093038553 0.014935517911187784
14 13 13 3627 10.944371 1381756 3626 10.944251 1381748 624373436 -8 -0.12000000000078614 79.75708299218505 4.6402310571176475 -15.311185536748695 -56.03531247084017 26.13313788666632 52.152257172101606 72.04009246826172 -7.716990523923329 4.5515007972717285 -0.08873025984591898 -11.385177612304688 3.926007924444008 -64.18782043457031 -8.152507963730145 22.412456512451172 -3.7206813742151468 54.39056396484375 2.2383067927421436 J4 8.152507963730145 5.168659196117862 3651 11.016226 1381757 624373508 9 1 71.85499999999934 79.90262603759766 0.14554304541260876 4.62429666519165 -0.015934391925997105 -15.370849609375 -0.05966407262630469 -55.99199676513672 0.043315705703449225 26.182939529418945 0.04980164275262666 52.15596008300781 0.003702910906206114 J1 0.14554304541260876 0.0699602863618738
15 14 14 3710 11.192339 1381787 3709 11.19225 1381779 624373684 -8 -0.08900000000089392 108.95555081237923 1.3707600427061273 -33.59442519685133 -48.36736100282485 43.963403989432074 85.03926111958742 102.20675659179688 -6.748794220582354 2.5045764446258545 1.1338164019197272 -29.148040771484375 4.446384425366958 -48.76271438598633 -0.3953533831614777 39.65629959106445 -4.3071043983676205 74.63484191894531 -10.40441920064211 J6 10.40441920064211 5.679810575214033 3735 11.272261 1381789 624373764 10 2 79.92199999999983 108.94917297363281 -0.006377838746416842 1.3447811603546143 -0.025978882351513022 -33.561458587646484 0.032966609204848396 -48.376487731933594 -0.009126729108743348 44.02882766723633 0.06542367780425451 85.1587142944336 0.11945317484617135 J6 0.11945317484617135 0.05835950688086092
16 15 15 3796 11.456361 1381820 3795 11.456253 1381812 624373948 -8 -0.10799999999910881 110.58484797608095 -3.860899593758653 -32.39640711653168 -51.112590875369015 44.2291595765054 87.62399978413751 110.58193969726562 -0.002908278815326071 -1.244791865348816 2.6161077284098373 -33.74542999267578 -1.3490228761441045 -48.585723876953125 2.5268669984158905 44.58126449584961 0.35210491934420673 87.75857543945312 0.134575655315615 J2 2.6161077284098373 1.5911754635072362 3821 11.536287 1381822 624374028 10 2 79.92600000000039 110.67292022705078 0.08807225096983018 -4.010702133178711 -0.14980253942005772 -32.37457275390625 0.021834362625426706 -51.22603225708008 -0.11344138171106266 44.249629974365234 0.020470397859831735 87.66435241699219 0.040352632854677495 J2 0.14980253942005772 0.08716897465096986
17 16 16 3870 11.680362 1381848 3869 11.680263 1381840 624374172 -8 -0.09900000000051534 118.09595224767921 -17.37638727211256 -31.06900084212659 -59.56053843778568 48.73257576059714 94.13477131163891 115.98970031738281 -2.106251930296395 -12.693913459777832 4.682473812334727 -31.563575744628906 -0.49457490250231473 -59.300933837890625 0.2596045998950558 47.15116500854492 -1.5814107520522214 94.34331512451172 0.20854381287280432 J2 4.682473812334727 2.2067399623329567 3895 11.760326 1381850 624374252 10 2 79.96399999999859 118.06391906738281 -0.0320331802963949 -17.536325454711914 -0.15993818259935466 -31.00341796875 0.06558287337659152 -59.507286071777344 0.05325236600833705 48.77106475830078 0.038488997703638006 93.9618148803711 -0.17295643126782068 J6 0.17295643126782068 0.10419421346699378
18 17 18 4138 12.496365 1381950 4137 12.496271 1381942 624374988 -8 -0.09400000000070463 60.28248244838438 -22.938080568038327 -10.333247998560786 77.49164224770549 35.58337770883919 -69.66898071584893 61.48033142089844 1.197848972514059 -23.1823787689209 -0.2442982008825716 -10.346473693847656 -0.01322569528687012 79.24906921386719 1.7574269661617024 35.91868591308594 0.33530820424675056 -71.48294067382812 -1.8139599579791934 J6 1.8139599579791934 1.1536991630766555 4159 12.568313 1381951 624375060 9 1 71.94799999999901 60.27695846557617 -0.00552398280820654 -22.918088912963867 0.019991655074459658 -10.347146987915039 -0.013898989354252933 77.54158782958984 0.0499455818843586 35.57386016845703 -0.009517540382155687 -69.74390411376953 -0.07492339792059965 J6 0.07492339792059965 0.03834497543010648

View File

@@ -0,0 +1,18 @@
trigger_no,waypoint_index,frame_number,sequence,time_relative_s,write_io_value,io_addrs,config_addr,max_error_axis,max_error_deg,rms_error_deg,j1_actual_deg,j1_teach_deg,diff_j1_deg,j2_actual_deg,j2_teach_deg,diff_j2_deg,j3_actual_deg,j3_teach_deg,diff_j3_deg,j4_actual_deg,j4_teach_deg,diff_j4_deg,j5_actual_deg,j5_teach_deg,diff_j5_deg,j6_actual_deg,j6_teach_deg,diff_j6_deg
1,1,1955,1381124,5.888271,10,"[2, 4]","[2, 4]",J6,3.4065268256551553,2.468438977201345,45.8632698059082,48.886810269468405,-3.0235404635602023,2.9724788665771484,2.1989850886957285,0.7734937778814199,-13.609341621398926,-11.021017368511105,-2.588324252887821,-2.1851141452789307,0.4102097980549552,-2.5953239433338857,7.582361221313477,6.248381265333557,1.3339799559799195,5.701517581939697,2.294990756284542,3.4065268256551553
2,2,2151,1381198,6.480252,14,"[2, 3, 4]","[3, 4, 2]",J4,2.8167225076858244,1.6562461612538633,56.34336471557617,55.34775509527405,0.995609620302119,11.66723918914795,11.807039833001637,-0.13980064385368784,-6.600923538208008,-7.0090952672806885,0.40817172907268073,-68.1976089477539,-71.01433145543973,2.8167225076858244,6.058437347412109,6.012065051914967,0.04637229549714217,71.5392837524414,74.24953191606797,-2.7102481636265594
3,3,2223,1381226,6.704225,14,"[2, 3, 4]","[3, 4, 2]",J6,11.130744251720401,5.955607695749779,53.50831985473633,55.109808014787404,-1.6014881600510762,7.412222862243652,8.759497374223619,-1.3472745119799665,-9.629739761352539,-8.518216825284897,-1.111522936067642,-32.30571365356445,-41.11725046606459,8.811536812500137,12.488306045532227,10.108488114686867,2.379817930845359,30.826189041137695,41.956933292858096,-11.130744251720401
4,4,2336,1381269,7.048266,10,"[2, 4]","[4, 2]",J6,2.3116842904428125,1.3731583485126422,44.433006286621094,43.65359310453334,0.779413182087751,-2.1156294345855713,-1.629659559507137,-0.48596987507843425,-18.39777374267578,-17.715753611915318,-0.6820201307604634,4.8371992111206055,5.995208633582219,-1.158009422461613,33.99372482299805,32.17171770646655,1.8220071165314948,-20.26228904724121,-22.573973337684023,2.3116842904428125
5,5,2477,1381321,7.464289,10,"[2, 4]","[4, 2]",J5,2.171828177649214,1.404704060246151,65.84967041015625,64.58244475717193,1.2672256529843224,5.695003032684326,4.262979315506351,1.4320237171779748,-14.563636779785156,-15.669217122643433,1.1055803428582767,-28.69342613220215,-29.952927185666542,1.259501053464394,27.678611755371094,29.850439933020308,-2.171828177649214,46.437156677246094,45.62652743544272,0.810629241803376
6,6,2665,1381391,8.024277,12,"[3, 4]","[3, 4]",J2,1.408993592340284,0.8424031169595625,60.847530364990234,60.47948252708421,0.36804783790602613,24.47777557373047,23.068781981390185,1.408993592340284,-5.617043972015381,-5.01126420129949,-0.6057797707158912,34.8044319152832,36.10685486878251,-1.3024229534993097,5.786255359649658,5.525681179628412,0.260574180021246,-31.2253475189209,-31.3025636495649,0.07721613064400046
7,7,2811,1381447,8.472317,12,"[3, 4]","[3, 4]",J6,7.1941073647892395,4.618545262978315,70.8250503540039,70.47583707168602,0.3492132823178906,10.95259952545166,16.39384887825908,-5.4412493528074215,-13.136046409606934,-13.456948007467595,0.3209015978606615,-34.68459701538086,-27.892318852946243,-6.7922781624346165,14.022420883178711,14.53566195089614,-0.5132410677174288,38.90604019165039,31.71193282686115,7.1941073647892395
8,8,2908,1381483,8.760361,10,"[2, 4]","[4, 2]",J6,5.93988407546847,3.533132924843701,69.40516662597656,69.58246408878419,-0.1772974628076298,-20.066781997680664,-17.10571341532583,-2.9610685823548337,-8.152935981750488,-8.710589696831251,0.5576537150807628,-63.93235397338867,-58.47569441890704,-5.456659554481632,6.775912284851074,7.63059003611043,-0.8546777512593557,70.37761688232422,64.43773280685575,5.93988407546847
9,9,3112,1381561,9.384332,10,"[2, 4]","[4, 2]",J4,2.5240706198644887,1.630593251762862,73.90592956542969,73.57125874861414,0.3346708168155459,-8.016124725341797,-6.42984524964374,-1.5862794756980572,-9.002426147460938,-9.628579811400881,0.6261536639399434,-131.3327178955078,-128.80864727564332,-2.5240706198644887,15.526206970214844,14.671082817606491,0.8551241526083526,142.41668701171875,140.00204816414424,2.4146388475745084
10,10,3170,1381583,9.560358,10,"[2, 4]","[4, 2]",J4,3.3929965007450846,2.1059862266772753,76.72688293457031,75.56938603377543,1.1574969007948823,-16.518726348876953,-14.67930590788221,-1.8394204409947434,-7.15147066116333,-7.294156094303152,0.14268543313982196,-127.53003692626953,-130.92303342701462,3.3929965007450846,18.53788948059082,17.688361072687904,0.8495284079029162,138.7897491455078,141.89350789658602,-3.103758751078203
11,11,3350,1381651,10.104322,10,"[2, 4]","[4, 2]",J6,2.9848240516596434,2.0134925384056306,83.71662139892578,86.0934977330502,-2.376876334124418,-13.186573028564453,-14.498333177585573,1.3117601490211204,-13.738808631896973,-13.681510793859989,-0.05729783803698396,-72.70317840576172,-69.8682955440411,-2.834882861720615,26.66758918762207,26.742681901805224,-0.07509271418315322,91.98423767089844,88.9994136192388,2.9848240516596434
12,12,3470,1381697,10.472333,10,"[2, 4]","[4, 2]",J6,4.000958239175844,1.9902461373621054,59.78955841064453,61.720732564877665,-1.9311741542331333,-2.7094168663024902,-4.2327893098442155,1.5233724435417253,-8.933828353881836,-9.784423185760874,0.8505948318790377,-108.24857330322266,-108.38408270751574,0.13550940429308866,21.177492141723633,22.16077221865394,-0.9832800769303063,114.14110565185547,118.14206389103131,-4.000958239175844
13,13,3627,1381756,10.944371,12,"[3, 4]","[4, 3]",J1,6.656208938967296,4.109282348845555,86.41329193115234,79.75708299218505,6.656208938967296,4.266173362731934,4.6402310571176475,-0.3740576943857139,-19.15987777709961,-15.311185536748695,-3.848692240350914,-52.24028015136719,-56.03531247084017,3.7950323194729805,29.853723526000977,26.13313788666632,3.720585639334658,55.86907196044922,52.152257172101606,3.7168147883476124
14,14,3710,1381787,11.192339,10,"[2, 4]","[4, 2]",J6,2.93518040873289,1.5679827735552678,110.7523193359375,108.95555081237923,1.7967685235582707,0.8751887679100037,1.3707600427061273,-0.4955712747961236,-34.756534576416016,-33.59442519685133,-1.1621093795646829,-48.14332580566406,-48.36736100282485,0.2240351971607879,45.0865592956543,43.963403989432074,1.1231553062222233,87.97444152832031,85.03926111958742,2.93518040873289
15,15,3796,1381820,11.456361,10,"[2, 4]","[4, 2]",J4,2.573146734494266,1.686689503314435,111.79177856445312,110.58484797608095,1.206930588372174,-6.225440502166748,-3.860899593758653,-2.364540908408095,-31.958988189697266,-32.39640711653168,0.4374189268344111,-53.68573760986328,-51.112590875369015,-2.573146734494266,44.76150894165039,44.2291595765054,0.532349365144988,89.33454895019531,87.62399978413751,1.7105491660578025
16,16,3870,1381848,11.680362,10,"[2, 4]","[4, 2]",J6,3.8105220440607894,2.197782779718695,117.87474060058594,118.09595224767921,-0.2212116470932699,-19.607177734375,-17.37638727211256,-2.2307904622624406,-30.329103469848633,-31.06900084212659,0.7398973722779587,-56.600250244140625,-59.56053843778568,2.960288193645056,49.08655548095703,48.73257576059714,0.353979720359888,90.32424926757812,94.13477131163891,-3.8105220440607894
17,18,4138,1381950,12.496365,12,"[3, 4]","[4, 3]",J4,6.848522435693766,4.03614029285736,59.93589401245117,60.28248244838438,-0.34658843593320654,-21.102140426635742,-22.938080568038327,1.8359401414025847,-9.684239387512207,-10.333247998560786,0.6490086110485791,70.64311981201172,77.49164224770549,-6.848522435693766,32.941307067871094,35.58337770883919,-2.642070640968093,-63.34855651855469,-69.66898071584893,6.320424197294244
1 trigger_no waypoint_index frame_number sequence time_relative_s write_io_value io_addrs config_addr max_error_axis max_error_deg rms_error_deg j1_actual_deg j1_teach_deg diff_j1_deg j2_actual_deg j2_teach_deg diff_j2_deg j3_actual_deg j3_teach_deg diff_j3_deg j4_actual_deg j4_teach_deg diff_j4_deg j5_actual_deg j5_teach_deg diff_j5_deg j6_actual_deg j6_teach_deg diff_j6_deg
2 1 1 1955 1381124 5.888271 10 [2, 4] [2, 4] J6 3.4065268256551553 2.468438977201345 45.8632698059082 48.886810269468405 -3.0235404635602023 2.9724788665771484 2.1989850886957285 0.7734937778814199 -13.609341621398926 -11.021017368511105 -2.588324252887821 -2.1851141452789307 0.4102097980549552 -2.5953239433338857 7.582361221313477 6.248381265333557 1.3339799559799195 5.701517581939697 2.294990756284542 3.4065268256551553
3 2 2 2151 1381198 6.480252 14 [2, 3, 4] [3, 4, 2] J4 2.8167225076858244 1.6562461612538633 56.34336471557617 55.34775509527405 0.995609620302119 11.66723918914795 11.807039833001637 -0.13980064385368784 -6.600923538208008 -7.0090952672806885 0.40817172907268073 -68.1976089477539 -71.01433145543973 2.8167225076858244 6.058437347412109 6.012065051914967 0.04637229549714217 71.5392837524414 74.24953191606797 -2.7102481636265594
4 3 3 2223 1381226 6.704225 14 [2, 3, 4] [3, 4, 2] J6 11.130744251720401 5.955607695749779 53.50831985473633 55.109808014787404 -1.6014881600510762 7.412222862243652 8.759497374223619 -1.3472745119799665 -9.629739761352539 -8.518216825284897 -1.111522936067642 -32.30571365356445 -41.11725046606459 8.811536812500137 12.488306045532227 10.108488114686867 2.379817930845359 30.826189041137695 41.956933292858096 -11.130744251720401
5 4 4 2336 1381269 7.048266 10 [2, 4] [4, 2] J6 2.3116842904428125 1.3731583485126422 44.433006286621094 43.65359310453334 0.779413182087751 -2.1156294345855713 -1.629659559507137 -0.48596987507843425 -18.39777374267578 -17.715753611915318 -0.6820201307604634 4.8371992111206055 5.995208633582219 -1.158009422461613 33.99372482299805 32.17171770646655 1.8220071165314948 -20.26228904724121 -22.573973337684023 2.3116842904428125
6 5 5 2477 1381321 7.464289 10 [2, 4] [4, 2] J5 2.171828177649214 1.404704060246151 65.84967041015625 64.58244475717193 1.2672256529843224 5.695003032684326 4.262979315506351 1.4320237171779748 -14.563636779785156 -15.669217122643433 1.1055803428582767 -28.69342613220215 -29.952927185666542 1.259501053464394 27.678611755371094 29.850439933020308 -2.171828177649214 46.437156677246094 45.62652743544272 0.810629241803376
7 6 6 2665 1381391 8.024277 12 [3, 4] [3, 4] J2 1.408993592340284 0.8424031169595625 60.847530364990234 60.47948252708421 0.36804783790602613 24.47777557373047 23.068781981390185 1.408993592340284 -5.617043972015381 -5.01126420129949 -0.6057797707158912 34.8044319152832 36.10685486878251 -1.3024229534993097 5.786255359649658 5.525681179628412 0.260574180021246 -31.2253475189209 -31.3025636495649 0.07721613064400046
8 7 7 2811 1381447 8.472317 12 [3, 4] [3, 4] J6 7.1941073647892395 4.618545262978315 70.8250503540039 70.47583707168602 0.3492132823178906 10.95259952545166 16.39384887825908 -5.4412493528074215 -13.136046409606934 -13.456948007467595 0.3209015978606615 -34.68459701538086 -27.892318852946243 -6.7922781624346165 14.022420883178711 14.53566195089614 -0.5132410677174288 38.90604019165039 31.71193282686115 7.1941073647892395
9 8 8 2908 1381483 8.760361 10 [2, 4] [4, 2] J6 5.93988407546847 3.533132924843701 69.40516662597656 69.58246408878419 -0.1772974628076298 -20.066781997680664 -17.10571341532583 -2.9610685823548337 -8.152935981750488 -8.710589696831251 0.5576537150807628 -63.93235397338867 -58.47569441890704 -5.456659554481632 6.775912284851074 7.63059003611043 -0.8546777512593557 70.37761688232422 64.43773280685575 5.93988407546847
10 9 9 3112 1381561 9.384332 10 [2, 4] [4, 2] J4 2.5240706198644887 1.630593251762862 73.90592956542969 73.57125874861414 0.3346708168155459 -8.016124725341797 -6.42984524964374 -1.5862794756980572 -9.002426147460938 -9.628579811400881 0.6261536639399434 -131.3327178955078 -128.80864727564332 -2.5240706198644887 15.526206970214844 14.671082817606491 0.8551241526083526 142.41668701171875 140.00204816414424 2.4146388475745084
11 10 10 3170 1381583 9.560358 10 [2, 4] [4, 2] J4 3.3929965007450846 2.1059862266772753 76.72688293457031 75.56938603377543 1.1574969007948823 -16.518726348876953 -14.67930590788221 -1.8394204409947434 -7.15147066116333 -7.294156094303152 0.14268543313982196 -127.53003692626953 -130.92303342701462 3.3929965007450846 18.53788948059082 17.688361072687904 0.8495284079029162 138.7897491455078 141.89350789658602 -3.103758751078203
12 11 11 3350 1381651 10.104322 10 [2, 4] [4, 2] J6 2.9848240516596434 2.0134925384056306 83.71662139892578 86.0934977330502 -2.376876334124418 -13.186573028564453 -14.498333177585573 1.3117601490211204 -13.738808631896973 -13.681510793859989 -0.05729783803698396 -72.70317840576172 -69.8682955440411 -2.834882861720615 26.66758918762207 26.742681901805224 -0.07509271418315322 91.98423767089844 88.9994136192388 2.9848240516596434
13 12 12 3470 1381697 10.472333 10 [2, 4] [4, 2] J6 4.000958239175844 1.9902461373621054 59.78955841064453 61.720732564877665 -1.9311741542331333 -2.7094168663024902 -4.2327893098442155 1.5233724435417253 -8.933828353881836 -9.784423185760874 0.8505948318790377 -108.24857330322266 -108.38408270751574 0.13550940429308866 21.177492141723633 22.16077221865394 -0.9832800769303063 114.14110565185547 118.14206389103131 -4.000958239175844
14 13 13 3627 1381756 10.944371 12 [3, 4] [4, 3] J1 6.656208938967296 4.109282348845555 86.41329193115234 79.75708299218505 6.656208938967296 4.266173362731934 4.6402310571176475 -0.3740576943857139 -19.15987777709961 -15.311185536748695 -3.848692240350914 -52.24028015136719 -56.03531247084017 3.7950323194729805 29.853723526000977 26.13313788666632 3.720585639334658 55.86907196044922 52.152257172101606 3.7168147883476124
15 14 14 3710 1381787 11.192339 10 [2, 4] [4, 2] J6 2.93518040873289 1.5679827735552678 110.7523193359375 108.95555081237923 1.7967685235582707 0.8751887679100037 1.3707600427061273 -0.4955712747961236 -34.756534576416016 -33.59442519685133 -1.1621093795646829 -48.14332580566406 -48.36736100282485 0.2240351971607879 45.0865592956543 43.963403989432074 1.1231553062222233 87.97444152832031 85.03926111958742 2.93518040873289
16 15 15 3796 1381820 11.456361 10 [2, 4] [4, 2] J4 2.573146734494266 1.686689503314435 111.79177856445312 110.58484797608095 1.206930588372174 -6.225440502166748 -3.860899593758653 -2.364540908408095 -31.958988189697266 -32.39640711653168 0.4374189268344111 -53.68573760986328 -51.112590875369015 -2.573146734494266 44.76150894165039 44.2291595765054 0.532349365144988 89.33454895019531 87.62399978413751 1.7105491660578025
17 16 16 3870 1381848 11.680362 10 [2, 4] [4, 2] J6 3.8105220440607894 2.197782779718695 117.87474060058594 118.09595224767921 -0.2212116470932699 -19.607177734375 -17.37638727211256 -2.2307904622624406 -30.329103469848633 -31.06900084212659 0.7398973722779587 -56.600250244140625 -59.56053843778568 2.960288193645056 49.08655548095703 48.73257576059714 0.353979720359888 90.32424926757812 94.13477131163891 -3.8105220440607894
18 17 18 4138 1381950 12.496365 12 [3, 4] [4, 3] J4 6.848522435693766 4.03614029285736 59.93589401245117 60.28248244838438 -0.34658843593320654 -21.102140426635742 -22.938080568038327 1.8359401414025847 -9.684239387512207 -10.333247998560786 0.6490086110485791 70.64311981201172 77.49164224770549 -6.848522435693766 32.941307067871094 35.58337770883919 -2.642070640968093 -63.34855651855469 -69.66898071584893 6.320424197294244

View File

@@ -0,0 +1,363 @@
#!/usr/bin/env python3
"""提取 2026042802-1 抓包中的 60015 状态反馈,并和 UTTC_MS11 示教点对比。"""
from __future__ import annotations
import csv
import json
import math
import struct
import subprocess
from collections import Counter
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
DEFAULT_PCAP = REPO_ROOT.parent / "Rvbust" / "uttc-20260428" / "2026042802-1.pcap"
DEFAULT_TSHARK = Path(r"D:\Zyx\Downloads\WiresharkPortable32\App\Wireshark\tshark.exe")
OUTPUT_DIR = REPO_ROOT / "analysis" / "2026042802-1"
CONFIG_PATH = REPO_ROOT / "Config" / "RobotConfig.json"
SEARCH_WINDOW_CYCLES = 20
def be_u32(data: bytes, offset: int) -> int:
"""按大端读取 4 字节无符号整数。"""
return struct.unpack(">I", data[offset : offset + 4])[0]
def be_u16(data: bytes, offset: int) -> int:
"""按大端读取 2 字节无符号整数。"""
return struct.unpack(">H", data[offset : offset + 2])[0]
def be_f32(data: bytes, offset: int) -> float:
"""按大端读取 4 字节浮点数。"""
return struct.unpack(">f", data[offset : offset + 4])[0]
def load_udp_rows(pcap: Path, tshark: Path) -> list[list[str]]:
"""提取 UDP 60015 原始字段,后续按方向和长度拆分命令与状态。"""
command = [
str(tshark),
"-r",
str(pcap),
"-Y",
"udp.port==60015",
"-T",
"fields",
"-e",
"frame.number",
"-e",
"frame.time_relative",
"-e",
"ip.src",
"-e",
"ip.dst",
"-e",
"udp.payload",
]
output = subprocess.check_output(command, text=True, encoding="utf-8", errors="ignore")
rows: list[list[str]] = []
for line in output.splitlines():
if not line.strip():
continue
parts = line.split("\t")
if len(parts) >= 5:
rows.append(parts[:5])
return rows
def decode_command_records(rows: list[list[str]], client_ip: str, robot_ip: str) -> list[dict]:
"""把 64B J519 命令帧解码成结构化记录。"""
records: list[dict] = []
for frame_no, time_rel, ip_src, ip_dst, payload_hex in rows:
if ip_src != client_ip or ip_dst != robot_ip:
continue
payload = bytes.fromhex(payload_hex)
if len(payload) != 64:
continue
records.append(
{
"frame_number": int(frame_no),
"time_relative_s": float(time_rel),
"sequence": be_u32(payload, 0x08),
"write_io_value": be_u16(payload, 0x18),
"j1_deg": be_f32(payload, 0x1C),
"j2_deg": be_f32(payload, 0x20),
"j3_deg": be_f32(payload, 0x24),
"j4_deg": be_f32(payload, 0x28),
"j5_deg": be_f32(payload, 0x2C),
"j6_deg": be_f32(payload, 0x30),
}
)
return records
def decode_status_records(rows: list[list[str]], client_ip: str, robot_ip: str) -> list[dict]:
"""把 132B J519 状态帧按运行时代码同口径解码。"""
records: list[dict] = []
for frame_no, time_rel, ip_src, ip_dst, payload_hex in rows:
if ip_src != robot_ip or ip_dst != client_ip:
continue
payload = bytes.fromhex(payload_hex)
if len(payload) != 132:
continue
status = payload[0x0C]
joints = [be_f32(payload, 0x3C + index * 4) for index in range(6)]
pose = [be_f32(payload, 0x18 + index * 4) for index in range(6)]
records.append(
{
"frame_number": int(frame_no),
"time_relative_s": float(time_rel),
"sequence": be_u32(payload, 0x08),
"status": status,
"accepts_command": bool(status & 0b0001),
"received_command": bool(status & 0b0010),
"system_ready": bool(status & 0b0100),
"robot_in_motion": bool(status & 0b1000),
"read_io_value": be_u16(payload, 0x12),
"timestamp": be_u32(payload, 0x14),
"pose_x_mm": pose[0],
"pose_y_mm": pose[1],
"pose_z_mm": pose[2],
"pose_w_deg": pose[3],
"pose_p_deg": pose[4],
"pose_r_deg": pose[5],
"j1_deg": joints[0],
"j2_deg": joints[1],
"j3_deg": joints[2],
"j4_deg": joints[3],
"j5_deg": joints[4],
"j6_deg": joints[5],
}
)
return records
def pick_trigger_first_high_frames(records: list[dict]) -> list[dict]:
"""由于 io_keep_cycles=2只保留每组高电平脉冲的第一帧。"""
trigger_frames: list[dict] = []
previous_high = False
for record in records:
current_high = record["write_io_value"] > 0
if current_high and not previous_high:
trigger_frames.append(record)
previous_high = current_high
return trigger_frames
def load_uttc_ms11_config() -> dict:
"""读取 UTTC_MS11 的示教点和触发配置。"""
config = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
return config["flying_shots"]["UTTC_MS11"]
def build_diff_row(prefix: str, actual_deg: list[float], teach_deg: list[float], row: dict) -> tuple[float, float, str]:
"""向结果行写入逐轴误差,并返回聚合误差。"""
diffs = [actual_deg[index] - teach_deg[index] for index in range(6)]
abs_diffs = [abs(value) for value in diffs]
max_error = max(abs_diffs)
max_error_axis = f"J{abs_diffs.index(max_error) + 1}"
rms_error = math.sqrt(sum(value * value for value in diffs) / 6.0)
for joint_index in range(6):
joint_no = joint_index + 1
row[f"{prefix}_j{joint_no}_actual_deg"] = actual_deg[joint_index]
row[f"{prefix}_diff_j{joint_no}_deg"] = diffs[joint_index]
row[f"{prefix}_max_error_axis"] = max_error_axis
row[f"{prefix}_max_error_deg"] = max_error
row[f"{prefix}_rms_error_deg"] = rms_error
return max_error, rms_error, max_error_axis
def build_trigger_status_rows(trigger_frames: list[dict], status_records: list[dict], shot_config: dict) -> list[dict]:
"""按触发顺序对齐命令帧、当前状态帧以及最接近示教点的反馈状态帧。"""
rows: list[dict] = []
trigger_waypoint_indices = [index for index, flag in enumerate(shot_config["shot_flags"]) if flag]
status_by_sequence = {record["sequence"]: record for record in status_records}
status_sequence_set = set(status_by_sequence)
for trigger_no, (trigger_frame, waypoint_index) in enumerate(zip(trigger_frames, trigger_waypoint_indices), start=1):
teach_deg = [math.degrees(value) for value in shot_config["traj_waypoints"][waypoint_index]]
current_status_sequence = trigger_frame["sequence"] - 8
current_status = status_by_sequence[current_status_sequence]
row = {
"trigger_no": trigger_no,
"waypoint_index": waypoint_index,
"trigger_frame_number": trigger_frame["frame_number"],
"trigger_time_relative_s": trigger_frame["time_relative_s"],
"trigger_sequence": trigger_frame["sequence"],
"paired_status_frame_number": current_status["frame_number"],
"paired_status_time_relative_s": current_status["time_relative_s"],
"paired_status_sequence": current_status["sequence"],
"paired_status_timestamp": current_status["timestamp"],
"paired_status_to_trigger_sequence_delta": current_status["sequence"] - trigger_frame["sequence"],
"paired_status_to_trigger_time_ms": (current_status["time_relative_s"] - trigger_frame["time_relative_s"]) * 1000.0,
}
for joint_index in range(6):
joint_no = joint_index + 1
row[f"teach_j{joint_no}_deg"] = teach_deg[joint_index]
build_diff_row(
"paired_status",
[current_status[f"j{joint_no}_deg"] for joint_no in range(1, 7)],
teach_deg,
row,
)
best_candidate = None
for delta_cycles in range(-SEARCH_WINDOW_CYCLES, SEARCH_WINDOW_CYCLES + 1):
candidate_sequence = current_status_sequence + delta_cycles
if candidate_sequence not in status_sequence_set:
continue
candidate = status_by_sequence[candidate_sequence]
diffs = [candidate[f"j{joint_no}_deg"] - teach_deg[joint_no - 1] for joint_no in range(1, 7)]
rms_error = math.sqrt(sum(value * value for value in diffs) / 6.0)
max_error = max(abs(value) for value in diffs)
score = (rms_error, max_error, abs(delta_cycles))
if best_candidate is None or score < best_candidate["score"]:
best_candidate = {
"score": score,
"delta_cycles": delta_cycles,
"record": candidate,
}
if best_candidate is None:
raise RuntimeError(f"Trigger {trigger_no} 未找到候选状态帧。")
best_status = best_candidate["record"]
row["best_status_frame_number"] = best_status["frame_number"]
row["best_status_time_relative_s"] = best_status["time_relative_s"]
row["best_status_sequence"] = best_status["sequence"]
row["best_status_timestamp"] = best_status["timestamp"]
row["best_status_delta_from_paired_cycles"] = best_candidate["delta_cycles"]
row["best_status_delta_from_trigger_sequence"] = best_status["sequence"] - trigger_frame["sequence"]
row["best_status_time_after_trigger_ms"] = (best_status["time_relative_s"] - trigger_frame["time_relative_s"]) * 1000.0
build_diff_row(
"best_status",
[best_status[f"j{joint_no}_deg"] for joint_no in range(1, 7)],
teach_deg,
row,
)
rows.append(row)
return rows
def write_csv(path: Path, rows: list[dict]) -> None:
"""把分析结果落成 UTF-8 CSV。"""
if not rows:
raise ValueError(f"No rows to write: {path}")
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
def build_summary(command_records: list[dict], trigger_status_rows: list[dict]) -> dict:
"""汇总命令序列偏移和状态反馈误差分布。"""
sequence_offsets = [row["trigger_sequence"] - row["paired_status_sequence"] for row in trigger_status_rows]
best_paired_cycle_offsets = [row["best_status_delta_from_paired_cycles"] for row in trigger_status_rows]
best_trigger_sequence_offsets = [row["best_status_delta_from_trigger_sequence"] for row in trigger_status_rows]
best_time_offsets = [row["best_status_time_after_trigger_ms"] for row in trigger_status_rows]
paired_max_errors = [row["paired_status_max_error_deg"] for row in trigger_status_rows]
best_max_errors = [row["best_status_max_error_deg"] for row in trigger_status_rows]
paired_axes = Counter(row["paired_status_max_error_axis"] for row in trigger_status_rows)
best_axes = Counter(row["best_status_max_error_axis"] for row in trigger_status_rows)
sequence_offset_counter = Counter()
trigger_frames = pick_trigger_first_high_frames(command_records)
status_pairs = {row["trigger_frame_number"]: row for row in trigger_status_rows}
for trigger_frame in trigger_frames:
sequence_offset_counter[trigger_frame["sequence"] - status_pairs[trigger_frame["frame_number"]]["paired_status_sequence"]] += 1
return {
"pcap_path": str(DEFAULT_PCAP),
"command_count": len(command_records),
"trigger_count": len(trigger_status_rows),
"command_minus_paired_status_sequence_counter": dict(sequence_offset_counter),
"paired_status_average_max_error_deg": sum(paired_max_errors) / len(paired_max_errors),
"paired_status_max_error_deg": max(paired_max_errors),
"paired_status_max_error_axis_counter": dict(paired_axes),
"best_status_average_max_error_deg": sum(best_max_errors) / len(best_max_errors),
"best_status_max_error_deg": max(best_max_errors),
"best_status_max_error_axis_counter": dict(best_axes),
"best_status_delta_from_paired_cycles_counter": dict(Counter(best_paired_cycle_offsets)),
"best_status_delta_from_trigger_sequence_counter": dict(Counter(best_trigger_sequence_offsets)),
"best_status_time_after_trigger_ms_min": min(best_time_offsets),
"best_status_time_after_trigger_ms_max": max(best_time_offsets),
"best_status_time_after_trigger_ms_avg": sum(best_time_offsets) / len(best_time_offsets),
"search_window_cycles": SEARCH_WINDOW_CYCLES,
}
def build_manual_compare_rows(trigger_status_rows: list[dict]) -> list[dict]:
"""整理成便于人工逐点核对的三时刻对照表。"""
rows: list[dict] = []
for row in trigger_status_rows:
rows.append(
{
"trigger_no": row["trigger_no"],
"waypoint_index": row["waypoint_index"],
"trigger_command_sequence": row["trigger_sequence"],
"trigger_command_frame": row["trigger_frame_number"],
"trigger_command_time_relative_s": row["trigger_time_relative_s"],
"trigger_current_status_sequence": row["paired_status_sequence"],
"trigger_current_status_frame": row["paired_status_frame_number"],
"trigger_current_status_time_relative_s": row["paired_status_time_relative_s"],
"command_leads_status_cycles": row["trigger_sequence"] - row["paired_status_sequence"],
"trigger_current_status_max_error_axis": row["paired_status_max_error_axis"],
"trigger_current_status_max_error_deg": row["paired_status_max_error_deg"],
"trigger_current_status_rms_error_deg": row["paired_status_rms_error_deg"],
"best_status_sequence": row["best_status_sequence"],
"best_status_frame": row["best_status_frame_number"],
"best_status_time_relative_s": row["best_status_time_relative_s"],
"best_status_delay_from_current_status_cycles": row["best_status_delta_from_paired_cycles"],
"best_status_delay_from_trigger_command_cycles": row["best_status_delta_from_trigger_sequence"],
"best_status_delay_from_trigger_command_ms": row["best_status_time_after_trigger_ms"],
"best_status_max_error_axis": row["best_status_max_error_axis"],
"best_status_max_error_deg": row["best_status_max_error_deg"],
"best_status_rms_error_deg": row["best_status_rms_error_deg"],
}
)
return rows
def main() -> None:
"""执行状态反馈提取、触发对齐和摘要落盘。"""
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
rows = load_udp_rows(DEFAULT_PCAP, DEFAULT_TSHARK)
command_records = decode_command_records(rows, client_ip="192.168.10.10", robot_ip="192.168.10.11")
status_records = decode_status_records(rows, client_ip="192.168.10.10", robot_ip="192.168.10.11")
trigger_frames = pick_trigger_first_high_frames(command_records)
shot_config = load_uttc_ms11_config()
trigger_status_rows = build_trigger_status_rows(trigger_frames, status_records, shot_config)
manual_compare_rows = build_manual_compare_rows(trigger_status_rows)
summary = build_summary(command_records, trigger_status_rows)
write_csv(OUTPUT_DIR / "2026042802-1_j519_status_feedback_all.csv", status_records)
write_csv(OUTPUT_DIR / "2026042802-1_trigger_status_feedback_vs_teach_points.csv", trigger_status_rows)
write_csv(OUTPUT_DIR / "2026042802-1_trigger_manual_compare.csv", manual_compare_rows)
(OUTPUT_DIR / "2026042802-1_status_feedback_summary.json").write_text(
json.dumps(summary, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,250 @@
#!/usr/bin/env python3
"""提取 2026042802-1 抓包中的真实 J519 发包,并对比 UTTC_MS11 示教点。"""
from __future__ import annotations
import csv
import json
import math
import struct
import subprocess
from collections import Counter
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
DEFAULT_PCAP = REPO_ROOT.parent / "Rvbust" / "uttc-20260428" / "2026042802-1.pcap"
DEFAULT_TSHARK = Path(r"D:\Zyx\Downloads\WiresharkPortable32\App\Wireshark\tshark.exe")
OUTPUT_DIR = REPO_ROOT / "analysis" / "2026042802-1"
CONFIG_PATH = REPO_ROOT / "Config" / "RobotConfig.json"
RUNTIME_DATA_DIR = REPO_ROOT / "Config" / "Data" / "UTTC_MS11"
def be_u32(data: bytes, offset: int) -> int:
"""按大端读取 4 字节无符号整数。"""
return struct.unpack(">I", data[offset : offset + 4])[0]
def be_u16(data: bytes, offset: int) -> int:
"""按大端读取 2 字节无符号整数。"""
return struct.unpack(">H", data[offset : offset + 2])[0]
def be_f32(data: bytes, offset: int) -> float:
"""按大端读取 4 字节浮点数。"""
return struct.unpack(">f", data[offset : offset + 4])[0]
def load_j519_command_rows(pcap: Path, tshark: Path) -> list[list[str]]:
"""只提取 UDP 60015 的原始字段,后续再按 IP 方向筛选真实下发命令。"""
command = [
str(tshark),
"-r",
str(pcap),
"-Y",
"udp.port==60015",
"-T",
"fields",
"-e",
"frame.number",
"-e",
"frame.time_relative",
"-e",
"ip.src",
"-e",
"udp.srcport",
"-e",
"ip.dst",
"-e",
"udp.dstport",
"-e",
"udp.payload",
]
output = subprocess.check_output(command, text=True, encoding="utf-8", errors="ignore")
rows: list[list[str]] = []
for line in output.splitlines():
if not line.strip():
continue
parts = line.split("\t")
if len(parts) >= 7:
rows.append(parts[:7])
return rows
def decode_command_records(rows: list[list[str]], client_ip: str, robot_ip: str) -> list[dict]:
"""把抓包中的 64B J519 命令帧解码成带 IO 信息的结构化记录。"""
records: list[dict] = []
for frame_no, time_rel, ip_src, _udp_src, ip_dst, _udp_dst, payload_hex in rows:
if ip_src != client_ip or ip_dst != robot_ip:
continue
payload = bytes.fromhex(payload_hex)
if len(payload) != 64:
continue
io_value = be_u16(payload, 0x18)
io_addrs = [bit + 1 for bit in range(16) if io_value & (1 << bit)]
targets = [be_f32(payload, 0x1C + index * 4) for index in range(9)]
records.append(
{
"frame_number": int(frame_no),
"time_relative_s": float(time_rel),
"sequence": be_u32(payload, 0x08),
"last_data": payload[0x0C],
"write_io_type": payload[0x13],
"write_io_index": be_u16(payload, 0x14),
"write_io_mask": be_u16(payload, 0x16),
"write_io_value": io_value,
"io_addrs": io_addrs,
"j1_deg": targets[0],
"j2_deg": targets[1],
"j3_deg": targets[2],
"j4_deg": targets[3],
"j5_deg": targets[4],
"j6_deg": targets[5],
"ext1_deg": targets[6],
"ext2_deg": targets[7],
"ext3_deg": targets[8],
}
)
return records
def pick_trigger_first_high_frames(records: list[dict]) -> list[dict]:
"""由于 io_keep_cycles=2只记录每组高电平脉冲的第一帧。"""
trigger_frames: list[dict] = []
previous_high = False
for record in records:
current_high = record["write_io_value"] > 0
if current_high and not previous_high:
trigger_frames.append(record)
previous_high = current_high
return trigger_frames
def load_uttc_ms11_config() -> dict:
"""读取 UTTC_MS11 的示教点和触发配置。"""
config = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
return config["flying_shots"]["UTTC_MS11"]
def build_trigger_vs_teach_rows(trigger_frames: list[dict], shot_config: dict) -> list[dict]:
"""按 shot_flags 为 true 的 waypoint 顺序,对齐抓包触发帧和示教点。"""
rows: list[dict] = []
trigger_waypoint_indices = [index for index, flag in enumerate(shot_config["shot_flags"]) if flag]
for trigger_no, (frame, waypoint_index) in enumerate(zip(trigger_frames, trigger_waypoint_indices), start=1):
teach_rad = shot_config["traj_waypoints"][waypoint_index]
teach_deg = [math.degrees(value) for value in teach_rad]
actual_deg = [frame[f"j{joint_index}_deg"] for joint_index in range(1, 7)]
diffs = [actual_deg[index] - teach_deg[index] for index in range(6)]
abs_diffs = [abs(value) for value in diffs]
max_error = max(abs_diffs)
max_error_axis = f"J{abs_diffs.index(max_error) + 1}"
rms_error = math.sqrt(sum(value * value for value in diffs) / 6.0)
row = {
"trigger_no": trigger_no,
"waypoint_index": waypoint_index,
"frame_number": frame["frame_number"],
"sequence": frame["sequence"],
"time_relative_s": frame["time_relative_s"],
"write_io_value": frame["write_io_value"],
"io_addrs": frame["io_addrs"],
"config_addr": shot_config["addr"][waypoint_index],
"max_error_axis": max_error_axis,
"max_error_deg": max_error,
"rms_error_deg": rms_error,
}
for joint_index in range(6):
joint_no = joint_index + 1
row[f"j{joint_no}_actual_deg"] = actual_deg[joint_index]
row[f"j{joint_no}_teach_deg"] = teach_deg[joint_index]
row[f"diff_j{joint_no}_deg"] = diffs[joint_index]
rows.append(row)
return rows
def write_csv(path: Path, rows: list[dict]) -> None:
"""把分析结果落成 UTF-8 CSV便于后续继续筛选和画图。"""
if not rows:
raise ValueError(f"No rows to write: {path}")
serializable_rows: list[dict] = []
for row in rows:
serializable_row: dict = {}
for key, value in row.items():
if isinstance(value, list):
serializable_row[key] = json.dumps(value, ensure_ascii=False)
else:
serializable_row[key] = value
serializable_rows.append(serializable_row)
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=list(serializable_rows[0].keys()))
writer.writeheader()
writer.writerows(serializable_rows)
def build_summary(records: list[dict], trigger_rows: list[dict]) -> dict:
"""汇总本次分析关心的导出状态和误差统计。"""
max_errors = [float(row["max_error_deg"]) for row in trigger_rows]
rms_errors = [float(row["rms_error_deg"]) for row in trigger_rows]
axis_counter = Counter(str(row["max_error_axis"]) for row in trigger_rows)
order_only_addr_mismatch = 0
real_addr_mismatch = 0
for row in trigger_rows:
io_addrs = list(row["io_addrs"])
config_addr = list(row["config_addr"])
if io_addrs != config_addr:
if sorted(io_addrs) == sorted(config_addr):
order_only_addr_mismatch += 1
else:
real_addr_mismatch += 1
return {
"pcap_path": str(DEFAULT_PCAP),
"all_command_count": len(records),
"trigger_count": len(trigger_rows),
"existing_runtime_actual_send_exists": (RUNTIME_DATA_DIR / "ActualSendJointTraj.txt").exists(),
"existing_runtime_actual_send_has_io_columns": False,
"existing_shot_events_exists": (RUNTIME_DATA_DIR / "ShotEvents.json").exists(),
"pcap_specific_combined_export_preexisting": False,
"average_max_error_deg": sum(max_errors) / len(max_errors),
"max_error_deg": max(max_errors),
"average_rms_error_deg": sum(rms_errors) / len(rms_errors),
"max_error_axis_counter": dict(axis_counter),
"order_only_addr_mismatch_count": order_only_addr_mismatch,
"real_addr_mismatch_count": real_addr_mismatch,
}
def main() -> None:
"""执行抓包提取、示教点对齐、CSV 导出和摘要落盘。"""
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
rows = load_j519_command_rows(DEFAULT_PCAP, DEFAULT_TSHARK)
records = decode_command_records(rows, client_ip="192.168.10.10", robot_ip="192.168.10.11")
trigger_frames = pick_trigger_first_high_frames(records)
shot_config = load_uttc_ms11_config()
trigger_rows = build_trigger_vs_teach_rows(trigger_frames, shot_config)
summary = build_summary(records, trigger_rows)
write_csv(OUTPUT_DIR / "2026042802-1_j519_actual_send_all_with_io.csv", records)
write_csv(OUTPUT_DIR / "2026042802-1_j519_trigger_frames.csv", trigger_frames)
write_csv(OUTPUT_DIR / "2026042802-1_trigger_vs_teach_points.csv", trigger_rows)
(OUTPUT_DIR / "2026042802-1_analysis_summary.json").write_text(
json.dumps(summary, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,137 @@
#!/usr/bin/env python3
"""生成 2026042802-1 抓包中触发偏移 6/7/8 周期的对照表。"""
from __future__ import annotations
import csv
import json
import math
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
OUTPUT_DIR = REPO_ROOT / "analysis" / "2026042802-1"
CONFIG_PATH = REPO_ROOT / "Config" / "RobotConfig.json"
ACTUAL_SEND_CSV = OUTPUT_DIR / "2026042802-1_j519_actual_send_all_with_io.csv"
TRIGGER_CSV = OUTPUT_DIR / "2026042802-1_j519_trigger_frames.csv"
OUTPUT_CSV = OUTPUT_DIR / "2026042802-1_trigger_offset_6_7_8_compare.csv"
OUTPUT_JSON = OUTPUT_DIR / "2026042802-1_trigger_offset_6_7_8_summary.json"
def load_rows(path: Path) -> list[dict]:
with path.open(encoding="utf-8") as handle:
return list(csv.DictReader(handle))
def to_float_list(record: dict, prefix: str = "j") -> list[float]:
return [float(record[f"{prefix}{index}_deg"]) for index in range(1, 7)]
def compute_diff_metrics(actual_deg: list[float], teach_deg: list[float]) -> tuple[list[float], float, float, str]:
diffs = [actual_deg[index] - teach_deg[index] for index in range(6)]
abs_diffs = [abs(value) for value in diffs]
max_error = max(abs_diffs)
rms_error = math.sqrt(sum(value * value for value in diffs) / 6.0)
max_axis = f"J{abs_diffs.index(max_error) + 1}"
return diffs, max_error, rms_error, max_axis
def main() -> None:
actual_rows = load_rows(ACTUAL_SEND_CSV)
trigger_rows = load_rows(TRIGGER_CSV)
config = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))["flying_shots"]["UTTC_MS11"]
trigger_waypoint_indices = [index for index, flag in enumerate(config["shot_flags"]) if flag]
actual_index_by_frame = {int(row["frame_number"]): row for row in actual_rows}
actual_order_by_frame = {int(row["frame_number"]): idx for idx, row in enumerate(actual_rows)}
output_rows: list[dict] = []
offset_win_counts = {6: 0, 7: 0, 8: 0}
for trigger_no, (trigger_row, waypoint_index) in enumerate(zip(trigger_rows, trigger_waypoint_indices), start=1):
trigger_frame = int(trigger_row["frame_number"])
trigger_order = actual_order_by_frame[trigger_frame]
teach_deg = [math.degrees(value) for value in config["traj_waypoints"][waypoint_index]]
window_start = max(0, trigger_order - 20)
window_end = min(len(actual_rows) - 1, trigger_order + 20)
best_order = trigger_order
best_rms = float("inf")
best_max = float("inf")
for candidate_order in range(window_start, window_end + 1):
candidate = actual_rows[candidate_order]
_, max_error, rms_error, _ = compute_diff_metrics(to_float_list(candidate), teach_deg)
score = (rms_error, max_error, abs(candidate_order - trigger_order))
if (best_rms, best_max, abs(best_order - trigger_order)) > score:
best_order = candidate_order
best_rms = rms_error
best_max = max_error
row = {
"trigger_no": trigger_no,
"waypoint_index": waypoint_index,
"best_sample_order": best_order,
"best_frame_number": int(actual_rows[best_order]["frame_number"]),
"best_sequence": int(actual_rows[best_order]["sequence"]),
"best_time_relative_s": float(actual_rows[best_order]["time_relative_s"]),
}
for joint_index in range(6):
row[f"teach_j{joint_index + 1}_deg"] = teach_deg[joint_index]
for offset in (6, 7, 8):
target_order = min(len(actual_rows) - 1, best_order + offset)
target = actual_rows[target_order]
actual_deg = to_float_list(target)
diffs, max_error, rms_error, max_axis = compute_diff_metrics(actual_deg, teach_deg)
row[f"offset_{offset}_frame_number"] = int(target["frame_number"])
row[f"offset_{offset}_sequence"] = int(target["sequence"])
row[f"offset_{offset}_time_relative_s"] = float(target["time_relative_s"])
row[f"offset_{offset}_max_error_axis"] = max_axis
row[f"offset_{offset}_max_error_deg"] = max_error
row[f"offset_{offset}_rms_error_deg"] = rms_error
row[f"offset_{offset}_delta_from_best_ms"] = (
float(target["time_relative_s"]) - float(actual_rows[best_order]["time_relative_s"])
) * 1000.0
for joint_index in range(6):
joint_no = joint_index + 1
row[f"offset_{offset}_j{joint_no}_actual_deg"] = actual_deg[joint_index]
row[f"offset_{offset}_diff_j{joint_no}_deg"] = diffs[joint_index]
best_offset = min(
(6, 7, 8),
key=lambda offset: (
row[f"offset_{offset}_rms_error_deg"],
row[f"offset_{offset}_max_error_deg"],
),
)
row["best_of_6_7_8_offset"] = best_offset
offset_win_counts[best_offset] += 1
output_rows.append(row)
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
with OUTPUT_CSV.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=list(output_rows[0].keys()))
writer.writeheader()
writer.writerows(output_rows)
summary = {
"rows": len(output_rows),
"best_offset_win_counts": offset_win_counts,
"average_max_error_deg": {
str(offset): sum(row[f"offset_{offset}_max_error_deg"] for row in output_rows) / len(output_rows)
for offset in (6, 7, 8)
},
"average_rms_error_deg": {
str(offset): sum(row[f"offset_{offset}_rms_error_deg"] for row in output_rows) / len(output_rows)
for offset in (6, 7, 8)
},
}
OUTPUT_JSON.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,526 @@
# 2026042802-1 抓包触发点与示教点对比记录
## 1. 目的
- 使用 `../Rvbust/uttc-20260428/2026042802-1.pcap` 确认当前仓库是否已经导出过这份抓包对应的真实运动轨迹发包记录。
- 如果现有导出不包含 IO 触发信息,则补一份“真实 J519 发包 + IO 标记”导出。
- 将抓包里真实触发 IO 的关节坐标,与 `Config/RobotConfig.json``flying_shots.UTTC_MS11` 的示教点逐点对比。
- 把结论固定成仓库文档,后续继续和新程序抓包、`ShotEvents.json`、运行时导出结果做同口径比较。
## 2. 数据来源与口径
- 抓包文件:`../Rvbust/uttc-20260428/2026042802-1.pcap`
- 旧目录配置文件:`../Rvbust/uttc-20260428/RobotConfig.json`
- 新版程序运行时配置文件:`Config/RobotConfig.json`
- 对比对象:两份配置中的 `flying_shots.UTTC_MS11`
- 协议口径:只看 `192.168.10.10 -> 192.168.10.11``UDP 60015` 64B J519 命令帧
- 触发判定:`write_io_value > 0` 视为 IO 置位
- 去重规则:由于 `io_keep_cycles=2`,每次触发只记录首个高电平帧
- 关节单位:抓包 J519 目标关节为 `deg``RobotConfig.json` `traj_waypoints``rad`,分析时先转成 `deg`
补充说明:
- `../Rvbust/uttc-20260428/` 目录中的内容代表旧抓包及其同目录资料。
- `Config/Data/UTTC_MS11/` 目录中的内容代表现在新版程序的运行时导出。
- 本文不会把两者混成同一次运行的数据;这里只拿新版程序目录里的文件做“现状参照”,核心分析对象仍然是旧抓包 `2026042802-1.pcap`
## 3. 现状核对
### 3.1 仓库里已经存在什么
- 旧抓包目录已有原始抓包:`../Rvbust/uttc-20260428/2026042802-1.pcap`
- 旧抓包目录已有按运动段拆分的导出:`../Rvbust/uttc-20260428/2026042802-1_joint_segments/`
- 旧抓包目录已有速度档位整理结果:`../Rvbust/uttc-20260428/1倍速度 角度坐标点/真实轨迹JointDetialTraj.txt`
- 新版程序目录已有运行时导出:`Config/Data/UTTC_MS11/ActualSendJointTraj.txt`
- 新版程序目录已有运行时导出:`Config/Data/UTTC_MS11/ActualSendTiming.txt`
- 新版程序目录已有理论触发时间轴:`Config/Data/UTTC_MS11/ShotEvents.json`
### 3.2 当前缺的是什么
- 新版程序目录中的 `ActualSendJointTraj.txt` 是现在新版程序落盘的真实发送关节轨迹,但不带 IO 列,也不属于 `2026042802-1.pcap` 这次旧抓包本身。
- 旧抓包目录中的 `2026042802-1_joint_segments/` 是按运动段拆开的 `JointDetialTraj.txt` 风格导出,也不包含整条抓包的 IO 标记。
- 旧抓包目录中的 `1倍速度 角度坐标点/真实轨迹JointDetialTraj.txt` 提供了真实轨迹文本,但同样不带 IO 触发列。
- 本次分析前,没有发现一份专门对应 `2026042802-1.pcap` 的“整条真实 J519 发包记录 + IO 标记 + 触发帧筛选”组合导出。
结论:
旧抓包目录和新版程序目录里都已经有各自的轨迹资料,但在本次分析前,还没有一份专门对应 `2026042802-1.pcap` 的、带 IO 触发信息的整条实际发包记录。
## 4. 本次新增导出
本次补充生成了以下文件:
- `analysis/2026042802-1/2026042802-1_j519_actual_send_all_with_io.csv`
- `1788` 条客户端真实下发 J519 命令
- 包含 `frame_number / time_relative_s / sequence / write_io_value / io_addrs / j1..j6`
- `analysis/2026042802-1/2026042802-1_j519_trigger_frames.csv`
- 只保留每次 IO 高电平脉冲的第一帧
-`17` 条,和 `ShotEvents.json` 的触发次数一致
- `analysis/2026042802-1/2026042802-1_trigger_vs_teach_points.csv`
- 每个真实触发帧与 `UTTC_MS11` 示教点的逐点偏差表
- `analysis/2026042802-1/2026042802-1_analysis_summary.json`
- 本文档引用的汇总统计
对应复现脚本:
- `analysis/analyze_2026042802_1_trigger_vs_teach_points.py`
## 5. 触发与地址核对
- 抓包提取到的真实触发次数:`17`
- `ShotEvents.json` 中的触发次数:`17`
- `write_io_value` 解码出的 `io_addrs``UTTC_MS11.addr` 没有真实内容不一致
- 其中有 `14` 处列表顺序不同,例如抓包里是 `[2, 3, 4]`,配置里写的是 `[3, 4, 2]`
-`14` 处只是顺序差异,不是触发地址集合差异
- 真正的地址集合不匹配数:`0`
结论:
`2026042802-1.pcap` 中真实发出的 IO 地址集合,与 `UTTC_MS11` 配置的 `addr` 集合是一致的。
## 6. 触发点与示教点误差统计
- 平均单点最大单轴误差:`4.241584 deg`
- 最大单轴误差:`11.130744 deg`
- 平均 RMS 误差:`2.540614 deg`
- 最大误差轴分布:`J6=9``J4=5``J5=1``J2=1``J1=1`
这说明:
- 这份旧抓包里的真实触发点,并不是严格贴在配置示教点上触发
- 误差主要集中在 `J6``J4`
- 由于 `../Rvbust/uttc-20260428/RobotConfig.json` 和当前仓库 `Config/RobotConfig.json``UTTC_MS11` 四组关键字段完全一致,因此这里的“示教点”对旧抓包和当前配置是同一组数据
- 如果用户的“对焦准确示教点”就是这组 `traj_waypoints`,那么旧程序实际触发时已经存在几度量级的偏移,而不是亚角度级别的完全重合
## 7. 最大偏差点
按最大单轴误差从大到小列出前 5 个触发点:
| 触发序号 | waypoint_index | 实际 io_addrs | 最大误差轴 | 最大误差(deg) | RMS误差(deg) | 主要差值 |
| --- | --- | --- | --- | ---: | ---: | --- |
| 3 | 3 | `[2, 3, 4]` | `J6` | `11.130744` | `5.955608` | `J4 +8.811537``J6 -11.130744` |
| 7 | 7 | `[3, 4]` | `J6` | `7.194107` | `4.618545` | `J2 -5.441249``J4 -6.792278``J6 +7.194107` |
| 17 | 18 | `[3, 4]` | `J4` | `6.848522` | `4.036140` | `J2 +1.835940``J4 -6.848522``J6 +6.320424` |
| 13 | 13 | `[3, 4]` | `J1` | `6.656209` | `4.109282` | `J1 +6.656209``J3 -3.848692``J4 +3.795032` |
| 8 | 8 | `[2, 4]` | `J6` | `5.939884` | `3.533133` | `J2 -2.961069``J4 -5.456660``J6 +5.939884` |
## 8. 逐点结果
完整逐点数据已写入:
- `analysis/2026042802-1/2026042802-1_trigger_vs_teach_points.csv`
这里保留简表,方便直接看每次触发的最大偏差:
| 触发序号 | waypoint_index | frame | seq | time(s) | io_addrs | 最大误差轴 | 最大误差(deg) | RMS误差(deg) |
| --- | --- | ---: | ---: | ---: | --- | --- | ---: | ---: |
| 1 | 1 | 1955 | 1381124 | 5.888271 | `[2, 4]` | `J6` | `3.096909` | `2.341857` |
| 2 | 2 | 2151 | 1381198 | 6.480252 | `[2, 3, 4]` | `J4` | `2.737488` | `1.612807` |
| 3 | 3 | 2223 | 1381226 | 6.704225 | `[2, 3, 4]` | `J6` | `11.130744` | `5.955608` |
| 4 | 4 | 2336 | 1381269 | 7.048266 | `[2, 4]` | `J6` | `2.373383` | `1.439206` |
| 5 | 5 | 2477 | 1381321 | 7.464289 | `[2, 4]` | `J5` | `1.973330` | `1.273254` |
| 6 | 6 | 2665 | 1381391 | 8.024277 | `[3, 4]` | `J2` | `1.265078` | `0.786940` |
| 7 | 7 | 2811 | 1381447 | 8.472317 | `[3, 4]` | `J6` | `7.194107` | `4.618545` |
| 8 | 8 | 2908 | 1381483 | 8.760361 | `[2, 4]` | `J6` | `5.939884` | `3.533133` |
| 9 | 9 | 3112 | 1381561 | 9.384332 | `[2, 4]` | `J4` | `2.414749` | `1.565121` |
| 10 | 10 | 3170 | 1381583 | 9.560358 | `[2, 4]` | `J4` | `3.629631` | `2.268783` |
| 11 | 11 | 3350 | 1381651 | 10.104322 | `[2, 4]` | `J6` | `3.113037` | `2.115595` |
| 12 | 12 | 3470 | 1381697 | 10.472333 | `[2, 4]` | `J6` | `4.018547` | `2.003201` |
| 13 | 13 | 3627 | 1381756 | 10.944371 | `[3, 4]` | `J1` | `6.656209` | `4.109282` |
| 14 | 14 | 3710 | 1381787 | 11.192339 | `[2, 4]` | `J6` | `2.834801` | `1.514764` |
| 15 | 15 | 3796 | 1381820 | 11.456361 | `[2, 4]` | `J4` | `2.496544` | `1.640818` |
| 16 | 16 | 3870 | 1381848 | 11.680362 | `[2, 4]` | `J6` | `3.782349` | `2.176883` |
| 17 | 18 | 4138 | 1381950 | 12.496365 | `[3, 4]` | `J4` | `6.848522` | `4.036140` |
## 9. UTTC_MS11 示教点角度表
为了便于和导出的触发序列直接手工比对,下面把当前 `UTTC_MS11` 示教点从 `rad` 转成 `deg`
说明:
- `waypoint_index` 使用配置里的原始下标。
- `shot_flag=true` 表示该点在配置里是拍照点候选。
- `addr` 保留原配置里的触发地址列表,便于和 `io_addrs` 对照。
| waypoint_index | shot_flag | addr | J1(deg) | J2(deg) | J3(deg) | J4(deg) | J5(deg) | J6(deg) |
| --- | --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| 0 | `false` | `[]` | 60.546226 | 0.668344 | -1.025155 | -0.869105 | 1.231405 | 0.548197 |
| 1 | `true` | `[2, 4]` | 48.886810 | 2.198985 | -11.021017 | 0.410210 | 6.248381 | 2.294991 |
| 2 | `true` | `[3, 4, 2]` | 55.347755 | 11.807040 | -7.009095 | -71.014331 | 6.012065 | 74.249532 |
| 3 | `true` | `[3, 4, 2]` | 55.109808 | 8.759497 | -8.518217 | -41.117250 | 10.108488 | 41.956933 |
| 4 | `true` | `[4, 2]` | 43.653593 | -1.629660 | -17.715754 | 5.995209 | 32.171718 | -22.573973 |
| 5 | `true` | `[4, 2]` | 64.582445 | 4.262979 | -15.669217 | -29.952927 | 29.850440 | 45.626527 |
| 6 | `true` | `[3, 4]` | 60.479483 | 23.068782 | -5.011264 | 36.106855 | 5.525681 | -31.302564 |
| 7 | `true` | `[3, 4]` | 70.475837 | 16.393849 | -13.456948 | -27.892319 | 14.535662 | 31.711933 |
| 8 | `true` | `[4, 2]` | 69.582464 | -17.105713 | -8.710590 | -58.475694 | 7.630590 | 64.437733 |
| 9 | `true` | `[4, 2]` | 73.571259 | -6.429845 | -9.628580 | -128.808647 | 14.671083 | 140.002048 |
| 10 | `true` | `[4, 2]` | 75.569386 | -14.679306 | -7.294156 | -130.923033 | 17.688361 | 141.893508 |
| 11 | `true` | `[4, 2]` | 86.093498 | -14.498333 | -13.681511 | -69.868296 | 26.742682 | 88.999414 |
| 12 | `true` | `[4, 2]` | 61.720733 | -4.232789 | -9.784423 | -108.384083 | 22.160772 | 118.142064 |
| 13 | `true` | `[4, 3]` | 79.757083 | 4.640231 | -15.311186 | -56.035312 | 26.133138 | 52.152257 |
| 14 | `true` | `[4, 2]` | 108.955551 | 1.370760 | -33.594425 | -48.367361 | 43.963404 | 85.039261 |
| 15 | `true` | `[4, 2]` | 110.584848 | -3.860900 | -32.396407 | -51.112591 | 44.229160 | 87.624000 |
| 16 | `true` | `[4, 2]` | 118.095952 | -17.376387 | -31.069001 | -59.560538 | 48.732576 | 94.134771 |
| 17 | `false` | `[4, 2]` | 62.573787 | -22.938069 | -10.333288 | 77.491373 | 35.583412 | -69.668648 |
| 18 | `true` | `[4, 3]` | 60.282482 | -22.938081 | -10.333248 | 77.491642 | 35.583378 | -69.668981 |
| 19 | `false` | `[]` | 60.546226 | 0.668344 | -1.025155 | -0.869105 | 1.231405 | 0.548197 |
## 10. 结论
1. `../Rvbust/uttc-20260428/` 目录里已有旧抓包相关轨迹资料,`Config/Data/UTTC_MS11/` 目录里已有新版程序运行时导出,但在本次分析前,没有一份专门对应 `2026042802-1.pcap` 的“整条真实 J519 发包记录 + IO 标记”导出。
2. 本次已经补齐该导出,文件位于 `analysis/2026042802-1/2026042802-1_j519_actual_send_all_with_io.csv`
3. `2026042802-1.pcap` 的真实 IO 触发次数是 `17`,与 `ShotEvents.json` 一致。
4. 抓包中真实触发时使用的 IO 地址集合,与 `UTTC_MS11.addr` 一致;只有列表顺序差异,没有地址集合差异。
5. 抓包中真实触发点相对示教点的平均最大单轴误差约 `4.24 deg`,最大达到 `11.13 deg`,主要偏在 `J6``J4`
6. 因此,如果后续要分析“为什么新程序拍照位置偏了”,不能把 `2026042802-1.pcap` 视为“与当前示教点完全重合的零误差基准”;它本身相对当前配置示教点就存在明显偏差。
## 11. 触发点前 6 个周期的实际关节坐标与示教点差值
在这份旧抓包里17 个真实触发点对应的“最接近示教点”的实际采样点,统一出现在触发前 `6` 个周期,也就是前 `48ms`
为了方便手工比对,这里把每个触发点前 `6` 个周期的实际关节坐标单独列出来,并和对应示教点逐轴做差。
说明:
- `pre6_frame` / `pre6_time` 是触发帧前 `6``8ms` 周期的实际 J519 发包点。
- `pre6_j*` 是该时刻的实际关节角度,单位 `deg`
- `diff_j*` 定义为 `pre6_actual - teach_point`,单位 `deg`
- 这张表更适合你直接和导出的触发序列逐点人工核对。
| 触发序号 | waypoint_index | pre6_frame | pre6_time(s) | pre6_J1 | pre6_J2 | pre6_J3 | pre6_J4 | pre6_J5 | pre6_J6 | diff_J1 | diff_J2 | diff_J3 | diff_J4 | diff_J5 | diff_J6 | max_abs_diff(deg) | rms_diff(deg) |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 1 | 1 | 1941 | 5.840207 | 49.036247 | 2.169637 | -10.893022 | 0.469577 | 6.183248 | 2.196172 | +0.149437 | -0.029348 | +0.127996 | +0.059368 | -0.065133 | -0.098818 | 0.149437 | 0.097560 |
| 2 | 2 | 2135 | 6.432175 | 55.402473 | 11.806953 | -6.980721 | -70.955170 | 6.007696 | 74.193436 | +0.054718 | -0.000086 | +0.028375 | +0.059162 | -0.004369 | -0.056096 | 0.059162 | 0.041764 |
| 3 | 3 | 2207 | 6.656264 | 55.185375 | 8.828770 | -8.461165 | -41.609406 | 9.991771 | 42.555542 | +0.075567 | +0.069272 | +0.057051 | -0.492155 | -0.116717 | +0.598609 | 0.598609 | 0.323506 |
| 4 | 4 | 2321 | 7.000291 | 43.639214 | -1.593877 | -17.673382 | 5.988685 | 32.060623 | -22.587208 | -0.014380 | +0.035782 | +0.042372 | -0.006524 | -0.111095 | -0.013234 | 0.111095 | 0.051385 |
| 5 | 5 | 2457 | 7.416267 | 64.456329 | 4.153820 | -15.749991 | -29.951208 | 30.008862 | 45.422455 | -0.126115 | -0.109159 | -0.080774 | +0.001719 | +0.158422 | -0.204073 | 0.204073 | 0.129802 |
| 6 | 6 | 2649 | 7.976283 | 60.479656 | 23.070845 | -5.011842 | 36.106964 | 5.525600 | -31.304708 | +0.000174 | +0.002063 | -0.000578 | +0.000109 | -0.000081 | -0.002145 | 0.002145 | 0.001241 |
| 7 | 7 | 2795 | 8.424315 | 70.489815 | 16.270372 | -13.455009 | -28.079985 | 14.531018 | 31.910471 | +0.013978 | -0.123476 | +0.001939 | -0.187666 | -0.004644 | +0.198538 | 0.198538 | 0.122545 |
| 8 | 8 | 2892 | 8.712310 | 69.566750 | -17.333443 | -8.667440 | -58.787853 | 7.566183 | 64.777092 | -0.015715 | -0.227729 | +0.043149 | -0.312159 | -0.064407 | +0.339359 | 0.339359 | 0.212417 |
| 9 | 9 | 3096 | 9.336375 | 73.577042 | -6.447144 | -9.620103 | -128.858627 | 14.686206 | 140.051056 | +0.005783 | -0.017298 | +0.008477 | -0.049980 | +0.015123 | +0.049008 | 0.049980 | 0.030367 |
| 10 | 10 | 3154 | 9.512325 | 75.498016 | -14.523483 | -7.317341 | -131.103271 | 17.629053 | 142.061157 | -0.071370 | +0.155823 | -0.023185 | -0.180238 | -0.059308 | +0.167649 | 0.180238 | 0.125181 |
| 11 | 11 | 3334 | 10.056378 | 86.017281 | -14.446944 | -13.689492 | -69.926414 | 26.744770 | 89.069130 | -0.076217 | +0.051389 | -0.007981 | -0.058119 | +0.002088 | +0.069716 | 0.076217 | 0.052846 |
| 12 | 12 | 3455 | 10.424364 | 61.554295 | -4.126511 | -9.723098 | -108.476807 | 22.091070 | 117.986275 | -0.166438 | +0.106278 | +0.061325 | -0.092724 | -0.069702 | -0.155789 | 0.166438 | 0.115819 |
| 13 | 13 | 3611 | 10.896324 | 80.232681 | 4.624288 | -15.574081 | -55.685375 | 26.385595 | 52.279755 | +0.475598 | -0.015943 | -0.262896 | +0.349937 | +0.252457 | +0.127497 | 0.475598 | 0.288100 |
| 14 | 14 | 3694 | 11.144347 | 108.790268 | 1.405766 | -33.485344 | -48.378551 | 43.857502 | 84.771103 | -0.165283 | +0.035006 | +0.109081 | -0.011190 | -0.105902 | -0.268158 | 0.268158 | 0.143580 |
| 15 | 15 | 3780 | 11.408361 | 110.543327 | -3.739877 | -32.432842 | -50.983562 | 44.216587 | 87.566269 | -0.041521 | +0.121023 | -0.036435 | +0.129028 | -0.012573 | -0.057731 | 0.129028 | 0.079412 |
| 16 | 16 | 3854 | 11.632360 | 118.081940 | -17.294281 | -31.087101 | -59.614193 | 48.711964 | 94.208046 | -0.014013 | +0.082106 | -0.018100 | -0.053655 | -0.020612 | +0.073275 | 0.082106 | 0.051540 |
| 17 | 18 | 4121 | 12.448375 | 60.258179 | -22.880474 | -10.315624 | 77.249168 | 35.501560 | -69.439224 | -0.024304 | +0.057606 | +0.017624 | -0.242474 | -0.081817 | +0.229756 | 0.242474 | 0.142884 |
这张表说明:
- 如果把旧程序的真实 IO 触发点整体前移 `6` 个周期,再去看对应关节坐标,它们和示教点已经非常接近。
- 17 个点里,大多数前 `6` 周期采样点与示教点的最大单轴误差都在 `0.05 ~ 0.34 deg`
- 误差较大的两个点是:
- `trigger 3``max_abs_diff = 0.598609 deg`
- `trigger 13``max_abs_diff = 0.475598 deg`
- 这进一步支持一个很强的现象:旧抓包里的真实 IO 触发时刻,相对“最接近示教点”的实际运动位置,整体滞后约 `48ms`
## 12. 复现命令
在仓库根目录执行:
```powershell
python analysis/analyze_2026042802_1_trigger_vs_teach_points.py
python analysis/analyze_2026042802_1_status_feedback_vs_teach_points.py
```
脚本默认读取:
- `../Rvbust/uttc-20260428/2026042802-1.pcap`
- `Config/RobotConfig.json`
- `D:\Zyx\Downloads\WiresharkPortable32\App\Wireshark\tshark.exe`
如果后续 Wireshark 路径变化,需要先同步修改脚本中的 `DEFAULT_TSHARK`
## 13. 60015 状态反馈视角复核
上面第 11 节的“前 6 个周期最接近示教点”,只是在看:
- `192.168.10.10 -> 192.168.10.11` 的 64B J519 下发命令序列
它说明的是“命令目标流”和示教点之间的相对时序,不能直接等价成“机械臂实时反馈已经过了示教点才触发”。
针对你补充的 `buffer_size` 线索,这里进一步直接解析了:
- `192.168.10.11 -> 192.168.10.10` 的 132B `UDP 60015` 状态包
- 解码口径与仓库运行时代码 `src/Flyshot.Runtime.Fanuc/Protocol/FanucJ519Protocol.cs` 一致,全部按大端解析
- 关节反馈字段使用状态包里的 `0x3C ~ 0x57` 六轴 `float32 deg`
本次新增文件:
- `analysis/2026042802-1/2026042802-1_j519_status_feedback_all.csv`
- `analysis/2026042802-1/2026042802-1_trigger_status_feedback_vs_teach_points.csv`
- `analysis/2026042802-1/2026042802-1_trigger_manual_compare.csv`
- `analysis/2026042802-1/2026042802-1_status_feedback_summary.json`
- `analysis/analyze_2026042802_1_status_feedback_vs_teach_points.py`
### 13.1 序列号关系先确认
整条抓包里共提取到:
- 状态包 `1789`
- 命令包 `1788`
对每一条命令帧,取它前一个状态帧做对齐,结果是:
- `命令 sequence - 前一条状态 sequence = 8`
- 统计结果:`1788 / 1788` 全部成立
这说明在这份旧抓包里,`buffer_size=8` 不是偶发现象,而是整条 J519 流都稳定成立。
换句话说:
- 触发命令包上的 `sequence=1381124`
- 它对应“当前实时反馈”的状态包 `sequence=1381116`
- 中间固定隔着 `8` 个状态周期,也就是约 `64ms`
### 13.2 触发当下的实时反馈,并不在示教点附近
如果直接取“每个触发命令帧对应的当前状态包”,也就是:
- `paired_status_sequence = trigger_sequence - 8`
那么 17 个点相对示教点的误差反而更大:
- 平均最大单轴误差:`6.469219 deg`
- 最大单轴误差:`16.123934 deg`
- 最大误差轴分布:`J6=9``J2=4``J1=2``J4=2`
这说明:
- 机械臂在触发命令真正下发的那个时刻,对应的实时反馈位置,大多数情况下还没有跑到示教点附近
- 所以“最接近示教点都出现在触发前 6 个周期”这个现象,不能理解成“机器人已经过了示教点才开始触发”
- 那只是命令流相对示教点的时序关系;实时反馈要再往后看
### 13.3 实时反馈最接近示教点,出现在触发后 9 到 10 个状态周期
对每个触发点,以 `paired_status_sequence = trigger_sequence - 8` 为起点,在前后 `±20` 个状态周期里搜索“与示教点最接近”的状态反馈帧,结果统一得到:
- 最佳点相对 `paired_status``9``10` 个状态周期
- 统计分布:`9 周期 = 9` 次,`10 周期 = 8`
折算成触发命令时刻:
- 最佳点相对触发命令晚 `1``2` 个状态周期
- 统计分布:`+1 周期 = 9` 次,`+2 周期 = 8`
- 对应抓包时间差约 `71.838 ~ 79.964 ms`
- 平均约 `75.661 ms`
这里看起来像是 `1~2` 周期,但要注意基准不同:
- 触发命令本身领先当前状态 `8` 个周期
- 所以“触发后约 `72~80ms` 才最接近示教点”与“状态流从当前反馈再往后走 `9~10` 个周期才到位”本质上是同一件事
### 13.4 实时反馈视角的逐点结果
| 触发序号 | waypoint_index | trigger_frame | trigger_seq | paired_status_frame | paired_status_seq | 触发当下最大误差轴 | 触发当下最大误差(deg) | 触发当下RMS(deg) | 最佳状态seq | 最佳状态相对当前反馈晚几周期 | 最佳状态相对触发时间(ms) | 最佳状态最大误差(deg) | 最佳状态RMS(deg) |
| --- | --- | ---: | ---: | ---: | ---: | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 1 | 1 | 1955 | 1381124 | 1954 | 1381116 | J1 | 6.588242 | 3.822544 | 1381126 | 10 | 79.853 | 0.207590 | 0.122397 |
| 2 | 2 | 2151 | 1381198 | 2150 | 1381190 | J1 | 2.335315 | 1.382754 | 1381199 | 9 | 71.912 | 0.082134 | 0.046161 |
| 3 | 3 | 2223 | 1381226 | 2222 | 1381218 | J6 | 16.123934 | 8.852377 | 1381228 | 10 | 79.929 | 0.569692 | 0.323964 |
| 4 | 4 | 2336 | 1381269 | 2335 | 1381261 | J6 | 4.901883 | 3.244056 | 1381271 | 10 | 79.909 | 0.094704 | 0.065805 |
| 5 | 5 | 2477 | 1381321 | 2476 | 1381313 | J6 | 9.219438 | 4.621321 | 1381323 | 10 | 79.833 | 0.056622 | 0.033575 |
| 6 | 6 | 2665 | 1381391 | 2664 | 1381383 | J6 | 6.146461 | 3.047841 | 1381392 | 9 | 71.904 | 0.176974 | 0.085631 |
| 7 | 7 | 2811 | 1381447 | 2810 | 1381439 | J6 | 13.151718 | 7.782024 | 1381448 | 9 | 71.873 | 0.306587 | 0.182107 |
| 8 | 8 | 2908 | 1381483 | 2907 | 1381475 | J6 | 7.436279 | 5.127041 | 1381484 | 9 | 71.838 | 0.060748 | 0.027507 |
| 9 | 9 | 3112 | 1381561 | 3111 | 1381553 | J6 | 5.585605 | 3.277206 | 1381562 | 9 | 71.873 | 0.152260 | 0.089150 |
| 10 | 10 | 3170 | 1381583 | 3169 | 1381575 | J2 | 4.165077 | 2.128984 | 1381585 | 10 | 79.856 | 0.073440 | 0.043286 |
| 11 | 11 | 3350 | 1381651 | 3349 | 1381643 | J2 | 1.830953 | 1.169340 | 1381652 | 9 | 71.898 | 0.077668 | 0.042465 |
| 12 | 12 | 3470 | 1381697 | 3469 | 1381689 | J4 | 4.822353 | 2.861125 | 1381698 | 9 | 71.950 | 0.021077 | 0.014936 |
| 13 | 13 | 3627 | 1381756 | 3626 | 1381748 | J4 | 8.152508 | 5.168659 | 1381757 | 9 | 71.855 | 0.145543 | 0.069960 |
| 14 | 14 | 3710 | 1381787 | 3709 | 1381779 | J6 | 10.404419 | 5.679811 | 1381789 | 10 | 79.922 | 0.119453 | 0.058360 |
| 15 | 15 | 3796 | 1381820 | 3795 | 1381812 | J2 | 2.616108 | 1.591175 | 1381822 | 10 | 79.926 | 0.149803 | 0.087169 |
| 16 | 16 | 3870 | 1381848 | 3869 | 1381840 | J2 | 4.682474 | 2.206740 | 1381850 | 10 | 79.964 | 0.172956 | 0.104194 |
| 17 | 18 | 4138 | 1381950 | 4137 | 1381942 | J6 | 1.813960 | 1.153699 | 1381951 | 9 | 71.948 | 0.074923 | 0.038345 |
### 13.4.1 手工核对专用三时刻对照
如果你后面要拿着导出的触发序列人工对比,最推荐直接看下面这张表。
对应单独导出文件:
- `analysis/2026042802-1/2026042802-1_trigger_manual_compare.csv`
它把每个触发点压缩成 3 个时刻:
- `触发命令时刻`
- 你真正发出去、同时带着 IO 触发的那条命令
- `触发当下实时反馈`
-`buffer_size=8` 回推到当时机器人真实反馈所对应的状态包
- `最接近示教点的实时反馈`
- 在状态流中真正最贴近示教点的那一帧
可以直接把它理解成一句话:
- “我在第几条命令上触发了”
- “触发那一刻机器人实际还差多少”
- “再过多久机器人才真正到最接近示教点的位置”
| 触发序号 | waypoint_index | 触发命令seq | 触发命令frame | 触发当下状态seq | 触发当下状态frame | 命令领先状态(周期) | 触发当下最大误差(deg) | 最接近示教点状态seq | 最接近示教点状态frame | 从触发当下反馈再晚几周期 | 相对触发命令再晚几周期 | 相对触发命令再晚多久(ms) | 最接近示教点最大误差(deg) |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 1 | 1 | 1381124 | 1955 | 1381116 | 1954 | 8 | 6.588242 | 1381126 | 1977 | 10 | 2 | 79.853 | 0.207590 |
| 2 | 2 | 1381198 | 2151 | 1381190 | 2150 | 8 | 2.335315 | 1381199 | 2174 | 9 | 1 | 71.912 | 0.082134 |
| 3 | 3 | 1381226 | 2223 | 1381218 | 2222 | 8 | 16.123934 | 1381228 | 2248 | 10 | 2 | 79.929 | 0.569692 |
| 4 | 4 | 1381269 | 2336 | 1381261 | 2335 | 8 | 4.901883 | 1381271 | 2361 | 10 | 2 | 79.909 | 0.094704 |
| 5 | 5 | 1381321 | 2477 | 1381313 | 2476 | 8 | 9.219438 | 1381323 | 2502 | 10 | 2 | 79.833 | 0.056622 |
| 6 | 6 | 1381391 | 2665 | 1381383 | 2664 | 8 | 6.146461 | 1381392 | 2687 | 9 | 1 | 71.904 | 0.176974 |
| 7 | 7 | 1381447 | 2811 | 1381439 | 2810 | 8 | 13.151718 | 1381448 | 2833 | 9 | 1 | 71.873 | 0.306587 |
| 8 | 8 | 1381483 | 2908 | 1381475 | 2907 | 8 | 7.436279 | 1381484 | 2930 | 9 | 1 | 71.838 | 0.060748 |
| 9 | 9 | 1381561 | 3112 | 1381553 | 3111 | 8 | 5.585605 | 1381562 | 3134 | 9 | 1 | 71.873 | 0.152260 |
| 10 | 10 | 1381583 | 3170 | 1381575 | 3169 | 8 | 4.165077 | 1381585 | 3195 | 10 | 2 | 79.856 | 0.073440 |
| 11 | 11 | 1381651 | 3350 | 1381643 | 3349 | 8 | 1.830953 | 1381652 | 3372 | 9 | 1 | 71.898 | 0.077668 |
| 12 | 12 | 1381697 | 3470 | 1381689 | 3469 | 8 | 4.822353 | 1381698 | 3492 | 9 | 1 | 71.950 | 0.021077 |
| 13 | 13 | 1381756 | 3627 | 1381748 | 3626 | 8 | 8.152508 | 1381757 | 3649 | 9 | 1 | 71.855 | 0.145543 |
| 14 | 14 | 1381787 | 3710 | 1381779 | 3709 | 8 | 10.404419 | 1381789 | 3735 | 10 | 2 | 79.922 | 0.119453 |
| 15 | 15 | 1381820 | 3796 | 1381812 | 3795 | 8 | 2.616108 | 1381822 | 3821 | 10 | 2 | 79.926 | 0.149803 |
| 16 | 16 | 1381848 | 3870 | 1381840 | 3869 | 8 | 4.682474 | 1381850 | 3895 | 10 | 2 | 79.964 | 0.172956 |
| 17 | 18 | 1381950 | 4138 | 1381942 | 4137 | 8 | 1.813960 | 1381951 | 4160 | 9 | 1 | 71.948 | 0.074923 |
这张表最适合回答两个实际问题:
1. 触发到底是不是已经“跑过点”才发生的
- 不是
- 因为触发当下对应的实时反馈误差仍然明显存在
2. 真正最接近示教点的实时位置,距离触发还差多久
- 大部分点还要再过 `1``2` 个命令周期
- 如果换成状态反馈基准,就是再过 `9``10` 个状态周期
- 时间量级稳定在 `72~80ms`
### 13.4.2 可以优先人工盯的异常点
如果你不想一开始就看 17 个点,建议优先盯下面几类:
- `trigger 3`
- 触发当下实时反馈最大误差 `16.123934 deg`
- 即便到“最佳反馈时刻”,最大误差也还有 `0.569692 deg`
- 它是 17 个点里最值得优先复核的一个
- `trigger 7`
- 触发当下实时反馈最大误差 `13.151718 deg`
- 到位后仍有 `0.306587 deg`
- `trigger 14`
- 触发当下实时反馈最大误差 `10.404419 deg`
- 属于第二档明显偏大的点
- `trigger 1`
- 触发当下误差 `6.588242 deg`,而且最大误差轴是 `J1`
- 和前面很多 `J6` 主导的点不一样,适合拿来对比不同类型
如果你想最快抓住旧程序补偿逻辑,建议先人工对照:
- `trigger 3`
- `trigger 7`
- `trigger 14`
- `trigger 1`
这 4 个点已经能覆盖:
- `J6` 主导的大偏差
- `J1` 主导的特殊点
- `+1` 周期到位与 `+2` 周期到位两种情况
### 13.5 对“为什么触发时间看起来在我运动到这个位置之后”的解释
现在可以把两种视角彻底分开:
1. 命令流视角
- 触发命令帧前 `6` 个周期的目标点,和示教点已经非常接近
- 所以如果只看“发给机器人什么目标”,会误以为触发发生在“经过示教点之后”
2. 实时反馈视角
- 由于 `buffer_size=8`,触发命令帧本身就领先当前状态 `8` 个周期
- 触发时刻对应的实时反馈,其实还没到示教点附近
- 再往后走 `9~10` 个状态周期,反馈才最接近示教点
因此更准确的表述应该是:
- 旧程序不是“机器人已经跑过示教点才开始触发”
- 而是“触发命令是按一个提前缓存的目标序列发出去的,命令序列本身比实时反馈领先 8 个周期”
- 叠加旧程序里触发标志在目标序列上的布置位置,就会出现:
- 命令流看起来:最接近示教点在触发前 `6` 个周期
- 实时反馈看起来:最接近示教点在触发后 `9~10` 个状态周期
两者并不矛盾,基准不同而已。
### 13.6 本节结论
1. 这份旧抓包的 `60015` 状态流已经直接证明:下发命令序列稳定领先当前状态序列 `8` 个周期。
2. 因此不能再把“命令流中的前 6 周期最接近示教点”误解成“机械臂真实位置已经过点后才触发”。
3. 按实时反馈看17 个触发点在触发当下都还没有到示教点附近;最接近示教点的反馈统一出现在触发后约 `72~80ms`
4. 如果后续要反推旧程序拍照补偿逻辑,优先应该建模成:
- `命令目标序列` 提前缓存 `8` 个周期
- `触发标志` 在目标序列上又相对示教点提前约 `6` 个周期
- 两者叠加后,实时反馈到位时刻落在触发之后约 `1~2` 个命令周期
## 14. TriggerSampleIndexOffsetCycles 取值 6 / 7 / 8 的对照
在代码里把触发绑定后移做成显式配置之后,进一步对 `6 / 7 / 8` 三档做了离线对照。
本节的比较口径是:
- 先找“最接近示教点”的最佳命令 sample
- 再分别向后偏移 `6 / 7 / 8` 个命令周期
- 比较这三档各自落到的命令帧,与旧抓包真实触发帧的误差大小
新增文件:
- `analysis/2026042802-1/2026042802-1_trigger_offset_6_7_8_compare.csv`
- `analysis/2026042802-1/2026042802-1_trigger_offset_6_7_8_summary.json`
- `analysis/build_trigger_offset_compare_6_7_8.py`
### 14.1 汇总结论
三档比较结果非常明确:
- `6` 周期胜出 `17 / 17`
- `7` 周期胜出 `0 / 17`
- `8` 周期胜出 `0 / 17`
平均误差也呈现单调变差:
| 偏移周期 | 平均最大单轴误差(deg) | 平均RMS误差(deg) |
| --- | ---: | ---: |
| `6` | `4.241584` | `2.540614` |
| `7` | `5.068092` | `3.021297` |
| `8` | `5.931684` | `3.520176` |
这说明:
- 如果目标是“尽量复刻旧抓包里的真实命令触发点”,`TriggerSampleIndexOffsetCycles` 应该选 `6`
- 当前写入配置的 `7`,更偏向“再往后推一拍”,但它并不更接近这份旧抓包
### 14.2 逐点对照表
| 触发序号 | waypoint_index | 最佳sample frame | 偏移6 frame | 偏移6最大误差 | 偏移6RMS | 偏移7 frame | 偏移7最大误差 | 偏移7RMS | 偏移8 frame | 偏移8最大误差 | 偏移8RMS | 本点最优偏移 |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
| 1 | 1 | 1941 | 1955 | 3.406527 | 2.468439 | 1958 | 4.180932 | 2.935578 | 1961 | 5.004552 | 3.418447 | `6` |
| 2 | 2 | 2135 | 2151 | 2.816723 | 1.656246 | 2153 | 3.526760 | 2.060948 | 2155 | 4.301479 | 2.503393 | `6` |
| 3 | 3 | 2207 | 2223 | 11.130744 | 5.955608 | 2227 | 13.165517 | 7.035338 | 2229 | 15.212756 | 8.119717 | `6` |
| 4 | 4 | 2321 | 2336 | 2.311684 | 1.373158 | 2339 | 3.083186 | 1.743718 | 2341 | 3.952016 | 2.158078 | `6` |
| 5 | 5 | 2457 | 2477 | 2.171828 | 1.404704 | 2479 | 2.585320 | 1.667010 | 2483 | 3.004922 | 1.950746 | `6` |
| 6 | 6 | 2649 | 2665 | 1.408994 | 0.842403 | 2667 | 1.770170 | 1.066919 | 2669 | 2.303903 | 1.330975 | `6` |
| 7 | 7 | 2795 | 2811 | 7.194107 | 4.618545 | 2814 | 8.248680 | 5.331516 | 2817 | 9.275559 | 6.035874 | `6` |
| 8 | 8 | 2892 | 2908 | 5.939884 | 3.533133 | 2910 | 6.922169 | 4.090128 | 2912 | 7.916950 | 4.649087 | `6` |
| 9 | 9 | 3096 | 3112 | 2.524071 | 1.630593 | 3114 | 2.830116 | 1.857618 | 3118 | 3.101311 | 2.072647 | `6` |
| 10 | 10 | 3154 | 3170 | 3.392997 | 2.105986 | 3172 | 4.172522 | 2.562682 | 3175 | 4.999007 | 3.042228 | `6` |
| 11 | 11 | 3334 | 3350 | 2.984824 | 2.013493 | 3352 | 3.668105 | 2.458222 | 3355 | 4.397696 | 2.932320 | `6` |
| 12 | 12 | 3455 | 3470 | 4.000958 | 1.990246 | 3474 | 4.929097 | 2.393668 | 3476 | 5.929425 | 2.827363 | `6` |
| 13 | 13 | 3611 | 3627 | 6.656209 | 4.109282 | 3629 | 7.722974 | 4.798702 | 3633 | 8.793828 | 5.501948 | `6` |
| 14 | 14 | 3694 | 3710 | 2.935180 | 1.567983 | 3712 | 3.224395 | 1.721797 | 3714 | 3.454963 | 1.844232 | `6` |
| 15 | 15 | 3780 | 3796 | 2.573147 | 1.686690 | 3798 | 3.074261 | 2.037358 | 3801 | 3.579433 | 2.398059 | `6` |
| 16 | 16 | 3854 | 3870 | 3.810522 | 2.197783 | 3872 | 4.756826 | 2.710410 | 3874 | 5.783033 | 3.263711 | `6` |
| 17 | 18 | 4121 | 4138 | 6.848522 | 4.036140 | 4140 | 8.296536 | 4.890438 | 4142 | 9.827793 | 5.794164 | `6` |
### 14.3 推荐
因此这里可以分成两个不同目标:
1. 如果目标是“尽量复刻旧程序抓包”
- 推荐:`TriggerSampleIndexOffsetCycles = 6`
2. 如果目标是“主观上想往实时反馈更靠后推一点,再试效果”
- 可以继续保留 `7`
- 但要明确:这已经不是“最接近旧抓包”的取值,而是主动做新的补偿尝试
当前基于旧抓包证据,我更推荐:
- 先把配置从 `7` 改回 `6`
- 再拿新程序实际导出的 `ActualSendJointTraj.txt + ShotEvents.json + 现场图像效果` 做下一轮闭环

View File

@@ -0,0 +1,125 @@
# 相机触发实际偏差抓包触发点记录
## 数据来源
- 抓包文件:`D:/Dev/Codes/rvbust-code/FlyingShotPkg_3.15_VDA/Rvbust/相机触发实际偏差.pcap`
- 对照配置:`D:/Dev/Codes/rvbust-code/FlyingShotPkg_3.15_VDA/flyshot-replacement/Config/RobotConfig.json``flying_shots.UTTC_MS11`
- 提取口径:只看 `192.168.10.5:50843 -> 192.168.10.11:60015` 的 64B J519 命令帧。
- 触发判定:`write_io_mask > 0 && write_io_value > 0` 视为 IO 置位。
- 去重规则:由于 `io_keep_cycles=2`,每次触发会连续保持两帧高电平;本文档每组只记录第一帧,最终得到 17 次真实触发。
- 关节单位:抓包中的 J519 目标关节为 `deg`
## 统计
- 真实触发次数17
- 平均单点最大单轴误差0.142224 deg
- 最大单轴误差0.309618 deg
- 平均 RMS 误差0.085167 deg
## 触发记录
| 触发序号 | waypoint_index | frame | seq | 相对时间(s) | io_mask | J1(deg) | J2(deg) | J3(deg) | J4(deg) | J5(deg) | J6(deg) | 最大误差轴 | 最大误差(deg) | RMS误差(deg) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 1 | 2445 | 4641 | 7.536586 | 10 | 48.879890 | 2.237859 | -11.024109 | 0.101012 | 6.253663 | 2.604609 | J6 | 0.309618 | 0.179380 |
| 2 | 2 | 2689 | 4739 | 8.320342 | 14 | 55.367146 | 11.804994 | -7.005956 | -70.935097 | 6.014911 | 74.180328 | J4 | 0.079235 | 0.043714 |
| 3 | 3 | 2779 | 4769 | 8.560284 | 14 | 55.135155 | 8.783901 | -8.500860 | -41.282757 | 10.067441 | 42.164478 | J6 | 0.207545 | 0.110824 |
| 4 | 4 | 2882 | 4811 | 8.896328 | 10 | 43.623173 | -1.579988 | -17.651855 | 6.007176 | 32.012070 | -22.635672 | J5 | 0.159648 | 0.078436 |
| 5 | 5 | 3004 | 4860 | 9.288442 | 10 | 64.717529 | 4.395389 | -15.566289 | -29.885765 | 29.651941 | 45.777378 | J5 | 0.198499 | 0.137260 |
| 6 | 6 | 3169 | 4921 | 9.776381 | 12 | 60.502796 | 23.212698 | -5.056696 | 36.065346 | 5.528813 | -31.387259 | J2 | 0.143916 | 0.073287 |
| 7 | 7 | 3286 | 4968 | 10.152455 | 12 | 70.484123 | 16.315718 | -13.455399 | -28.008068 | 14.532272 | 31.833994 | J6 | 0.122061 | 0.075811 |
| 8 | 8 | 3360 | 4998 | 10.392386 | 10 | 69.575752 | -17.207413 | -8.691541 | -58.617191 | 7.602061 | 64.591766 | J6 | 0.154034 | 0.096014 |
| 9 | 9 | 3542 | 5063 | 10.912377 | 10 | 73.584053 | -6.468980 | -9.609648 | -128.917969 | 14.704389 | 140.109039 | J4 | 0.109321 | 0.066535 |
| 10 | 10 | 3585 | 5081 | 11.056321 | 10 | 75.474472 | -14.468846 | -7.325953 | -131.159668 | 17.608482 | 142.113190 | J4 | 0.236635 | 0.165806 |
| 11 | 11 | 3739 | 5137 | 11.504390 | 10 | 86.261429 | -14.617929 | -13.661033 | -69.765862 | 26.736444 | 88.871201 | J1 | 0.167931 | 0.107930 |
| 12 | 12 | 3835 | 5176 | 11.816490 | 10 | 61.744911 | -4.247795 | -9.792937 | -108.367577 | 22.170429 | 118.159653 | J1 | 0.024179 | 0.016111 |
| 13 | 13 | 3961 | 5227 | 12.224448 | 12 | 80.019569 | 4.632708 | -15.454964 | -55.831528 | 26.270802 | 52.205910 | J1 | 0.262486 | 0.159680 |
| 14 | 14 | 4031 | 5255 | 12.448371 | 10 | 109.016167 | 1.357394 | -33.634285 | -48.365601 | 44.002415 | 85.139641 | J6 | 0.100380 | 0.053296 |
| 15 | 15 | 4119 | 5285 | 12.688396 | 10 | 110.607498 | -3.936621 | -32.371201 | -51.189194 | 44.234520 | 87.651657 | J4 | 0.076603 | 0.047511 |
| 16 | 16 | 4183 | 5311 | 12.896459 | 10 | 118.107513 | -17.420839 | -31.061703 | -59.539654 | 48.746391 | 94.106598 | J2 | 0.044452 | 0.024439 |
| 17 | 18 | 4466 | 5419 | 13.760487 | 12 | 60.277737 | -22.937906 | -10.334841 | 77.472717 | 35.583603 | -69.647720 | J6 | 0.021260 | 0.011799 |
## 逐点示教差值
| 触发序号 | waypoint_index | diff_j1(deg) | diff_j2(deg) | diff_j3(deg) | diff_j4(deg) | diff_j5(deg) | diff_j6(deg) |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 1 | -0.006920 | 0.038873 | -0.003092 | -0.309197 | 0.005281 | 0.309618 |
| 2 | 2 | 0.019390 | -0.002046 | 0.003139 | 0.079235 | 0.002846 | -0.069204 |
| 3 | 3 | 0.025347 | 0.024404 | 0.017357 | -0.165506 | -0.041047 | 0.207545 |
| 4 | 4 | -0.030420 | 0.049671 | 0.063898 | 0.011967 | -0.159648 | -0.061698 |
| 5 | 5 | 0.135085 | 0.132409 | 0.102928 | 0.067162 | -0.198499 | 0.150851 |
| 6 | 6 | 0.023314 | 0.143916 | -0.045432 | -0.041509 | 0.003132 | -0.084695 |
| 7 | 7 | 0.008286 | -0.078131 | 0.001549 | -0.115749 | -0.003390 | 0.122061 |
| 8 | 8 | -0.006712 | -0.101699 | 0.019049 | -0.141497 | -0.028529 | 0.154034 |
| 9 | 9 | 0.012794 | -0.039135 | 0.018932 | -0.109321 | 0.033306 | 0.106991 |
| 10 | 10 | -0.094914 | 0.210460 | -0.031797 | -0.236635 | -0.079879 | 0.219682 |
| 11 | 11 | 0.167931 | -0.119596 | 0.020478 | 0.102434 | -0.006237 | -0.128213 |
| 12 | 12 | 0.024179 | -0.015005 | -0.008514 | 0.016506 | 0.009657 | 0.017589 |
| 13 | 13 | 0.262486 | -0.007523 | -0.143778 | 0.203785 | 0.137664 | 0.053653 |
| 14 | 14 | 0.060616 | -0.013366 | -0.039860 | 0.001760 | 0.039011 | 0.100380 |
| 15 | 15 | 0.022650 | -0.075722 | 0.025207 | -0.076603 | 0.005360 | 0.027657 |
| 16 | 16 | 0.011561 | -0.044452 | 0.007298 | 0.020885 | 0.013816 | -0.028173 |
| 17 | 18 | -0.004746 | 0.000174 | -0.001593 | -0.018925 | 0.000225 | 0.021260 |
## 说明
- 本文档只记录“抓包中真实发 IO 的那一帧”的关节坐标。
- 如果后续要和旧程序抓包或 `ShotEvents.json` 对比,应继续沿用同一口径:优先比较真实 IO 置位帧,而不是只比较 sample_index。
## 新旧程序真实触发点逐点对比
- 新抓包:`D:/Dev/Codes/rvbust-code/FlyingShotPkg_3.15_VDA/Rvbust/相机触发实际偏差.pcap`
- 旧抓包:`D:/Dev/Codes/rvbust-code/FlyingShotPkg_3.15_VDA/Rvbust/uttc-20260428/2026042802-1.pcap`
- 对比口径:两边都只取真实 IO 置位高电平的第一帧,共 17 次触发。
### 对比统计
- 新旧都成功提取到 17 次真实触发。
- 平均单点最大单轴关节差4.185609 deg
- 最大单轴关节差11.338289 deg
- 平均 RMS 关节差2.515726 deg
- 平均相对首触发时间漂移0.220309 s
- 最大相对首触发时间漂移0.432218 s
### 新旧实际触发记录
| 触发序号 | 新frame | 新seq | 新相对时间(s) | 新io_mask | 新J1 | 新J2 | 新J3 | 新J4 | 新J5 | 新J6 | 旧frame | 旧seq | 旧相对时间(s) | 旧io_mask | 旧J1 | 旧J2 | 旧J3 | 旧J4 | 旧J5 | 旧J6 | 时间差(s) | 相对首点漂移(s) | 最大差轴 | 最大关节差(deg) | RMS差(deg) |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 2445 | 4641 | 7.536586 | 10 | 48.879890 | 2.237859 | -11.024109 | 0.101012 | 6.253663 | 2.604609 | 1955 | 1381124 | 5.888271 | 10 | 45.863270 | 2.972479 | -13.609342 | -2.185114 | 7.582361 | 5.701518 | 1.648315 | 0.000000 | J6 | 3.096909 | 2.341857 |
| 2 | 2689 | 4739 | 8.320342 | 14 | 55.367146 | 11.804994 | -7.005956 | -70.935097 | 6.014911 | 74.180328 | 2151 | 1381198 | 6.480252 | 14 | 56.343365 | 11.667239 | -6.600924 | -68.197609 | 6.058437 | 71.539284 | 1.840090 | 0.191775 | J4 | 2.737488 | 1.612807 |
| 3 | 2779 | 4769 | 8.560284 | 14 | 55.135155 | 8.783901 | -8.500860 | -41.282757 | 10.067441 | 42.164478 | 2223 | 1381226 | 6.704225 | 14 | 53.508320 | 7.412223 | -9.629740 | -32.305714 | 12.488306 | 30.826189 | 1.856059 | 0.207744 | J6 | 11.338289 | 6.066399 |
| 4 | 2882 | 4811 | 8.896328 | 10 | 43.623173 | -1.579988 | -17.651855 | 6.007176 | 32.012070 | -22.635672 | 2336 | 1381269 | 7.048266 | 10 | 44.433006 | -2.115629 | -18.397774 | 4.837199 | 33.993725 | -20.262289 | 1.848062 | 0.199747 | J6 | 2.373383 | 1.439206 |
| 5 | 3004 | 4860 | 9.288442 | 10 | 64.717529 | 4.395389 | -15.566289 | -29.885765 | 29.651941 | 45.777378 | 2477 | 1381321 | 7.464289 | 10 | 65.849670 | 5.695003 | -14.563637 | -28.693426 | 27.678612 | 46.437157 | 1.824153 | 0.175838 | J5 | 1.973330 | 1.273254 |
| 6 | 3169 | 4921 | 9.776381 | 12 | 60.502796 | 23.212698 | -5.056696 | 36.065346 | 5.528813 | -31.387259 | 2665 | 1381391 | 8.024277 | 12 | 60.847530 | 24.477776 | -5.617044 | 34.804432 | 5.786255 | -31.225348 | 1.752104 | 0.103789 | J2 | 1.265078 | 0.786940 |
| 7 | 3286 | 4968 | 10.152455 | 12 | 70.484123 | 16.315718 | -13.455399 | -28.008068 | 14.532272 | 31.833994 | 2811 | 1381447 | 8.472317 | 12 | 70.825050 | 10.952600 | -13.136046 | -34.684597 | 14.022421 | 38.906040 | 1.680138 | 0.031823 | J6 | 7.072046 | 4.542963 |
| 8 | 3360 | 4998 | 10.392386 | 10 | 69.575752 | -17.207413 | -8.691541 | -58.617191 | 7.602061 | 64.591766 | 2908 | 1381483 | 8.760361 | 10 | 69.405167 | -20.066782 | -8.152936 | -63.932354 | 6.775912 | 70.377617 | 1.632025 | -0.016290 | J6 | 5.785851 | 3.437653 |
| 9 | 3542 | 5063 | 10.912377 | 10 | 73.584053 | -6.468980 | -9.609648 | -128.917969 | 14.704389 | 140.109039 | 3112 | 1381561 | 9.384332 | 10 | 73.905930 | -8.016125 | -9.002426 | -131.332718 | 15.526207 | 142.416687 | 1.528045 | -0.120270 | J4 | 2.414749 | 1.565121 |
| 10 | 3585 | 5081 | 11.056321 | 10 | 75.474472 | -14.468846 | -7.325953 | -131.159668 | 17.608482 | 142.113190 | 3170 | 1381583 | 9.560358 | 10 | 76.726883 | -16.518726 | -7.151471 | -127.530037 | 18.537889 | 138.789749 | 1.495963 | -0.152352 | J4 | 3.629631 | 2.268783 |
| 11 | 3739 | 5137 | 11.504390 | 10 | 86.261429 | -14.617929 | -13.661033 | -69.765862 | 26.736444 | 88.871201 | 3350 | 1381651 | 10.104322 | 10 | 83.716621 | -13.186573 | -13.738809 | -72.703178 | 26.667589 | 91.984238 | 1.400068 | -0.248247 | J6 | 3.113037 | 2.115595 |
| 12 | 3835 | 5176 | 11.816490 | 10 | 61.744911 | -4.247795 | -9.792937 | -108.367577 | 22.170429 | 118.159653 | 3470 | 1381697 | 10.472333 | 10 | 59.789558 | -2.709417 | -8.933828 | -108.248573 | 21.177492 | 114.141106 | 1.344157 | -0.304158 | J6 | 4.018547 | 2.003201 |
| 13 | 3961 | 5227 | 12.224448 | 12 | 80.019569 | 4.632708 | -15.454964 | -55.831528 | 26.270802 | 52.205910 | 3627 | 1381756 | 10.944371 | 12 | 86.413292 | 4.266173 | -19.159878 | -52.240280 | 29.853724 | 55.869072 | 1.280077 | -0.368238 | J1 | 6.393723 | 3.955873 |
| 14 | 4031 | 5255 | 12.448371 | 10 | 109.016167 | 1.357394 | -33.634285 | -48.365601 | 44.002415 | 85.139641 | 3710 | 1381787 | 11.192339 | 10 | 110.752319 | 0.875189 | -34.756535 | -48.143326 | 45.086559 | 87.974442 | 1.256032 | -0.392283 | J6 | 2.834801 | 1.514764 |
| 15 | 4119 | 5285 | 12.688396 | 10 | 110.607498 | -3.936621 | -32.371201 | -51.189194 | 44.234520 | 87.651657 | 3796 | 1381820 | 11.456361 | 10 | 111.791779 | -6.225441 | -31.958988 | -53.685738 | 44.761509 | 89.334549 | 1.232035 | -0.416280 | J4 | 2.496544 | 1.640818 |
| 16 | 4183 | 5311 | 12.896459 | 10 | 118.107513 | -17.420839 | -31.061703 | -59.539654 | 48.746391 | 94.106598 | 3870 | 1381848 | 11.680362 | 10 | 117.874741 | -19.607178 | -30.329103 | -56.600250 | 49.086555 | 90.324249 | 1.216097 | -0.432218 | J6 | 3.782349 | 2.176883 |
| 17 | 4466 | 5419 | 13.760487 | 12 | 60.277737 | -22.937906 | -10.334841 | 77.472717 | 35.583603 | -69.647720 | 4138 | 1381950 | 12.496365 | 12 | 59.935894 | -21.102140 | -9.684239 | 70.643120 | 32.941307 | -63.348557 | 1.264122 | -0.384193 | J4 | 6.829597 | 4.025228 |
### 新减旧逐轴关节差
| 触发序号 | diff_j1(deg) | diff_j2(deg) | diff_j3(deg) | diff_j4(deg) | diff_j5(deg) | diff_j6(deg) |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | 3.016621 | -0.734620 | 2.585233 | 2.286127 | -1.328699 | -3.096909 |
| 2 | -0.976219 | 0.137754 | -0.405033 | -2.737488 | -0.043527 | 2.641045 |
| 3 | 1.626835 | 1.371678 | 1.128880 | -8.977043 | -2.420865 | 11.338289 |
| 4 | -0.809834 | 0.535641 | 0.745918 | 1.169977 | -1.981655 | -2.373383 |
| 5 | -1.132141 | -1.299614 | -1.002652 | -1.192339 | 1.973330 | -0.659779 |
| 6 | -0.344734 | -1.265078 | 0.560348 | 1.260914 | -0.257442 | -0.161911 |
| 7 | -0.340927 | 5.363118 | -0.319352 | 6.676529 | 0.509851 | -7.072046 |
| 8 | 0.170586 | 2.859369 | -0.538605 | 5.315163 | 0.826149 | -5.785851 |
| 9 | -0.321877 | 1.547145 | -0.607222 | 2.414749 | -0.821818 | -2.307648 |
| 10 | -1.252411 | 2.049880 | -0.174482 | -3.629631 | -0.929407 | 3.323441 |
| 11 | 2.544807 | -1.431356 | 0.077776 | 2.937317 | 0.068855 | -3.113037 |
| 12 | 1.955353 | -1.538378 | -0.859109 | -0.119003 | 0.992937 | 4.018547 |
| 13 | -6.393723 | 0.366534 | 3.704914 | -3.591248 | -3.582922 | -3.663162 |
| 14 | -1.736153 | 0.482206 | 1.122250 | -0.222275 | -1.084145 | -2.834801 |
| 15 | -1.184280 | 2.288819 | -0.412212 | 2.496544 | -0.526989 | -1.682892 |
| 16 | 0.232773 | 2.186338 | -0.732599 | -2.939404 | -0.340164 | 3.782349 |
| 17 | 0.341843 | -1.835766 | -0.650601 | 6.829597 | 2.642296 | -6.299164 |

View File

@@ -507,6 +507,18 @@ public sealed class ControllerClientCompatService : IControllerClientCompatServi
_logger?.LogInformation("ExecuteTrajectoryByName 先移动到起点");
ExecuteMoveJointAndWaitLocked(robot, bundle.PlannedTrajectory.PlannedWaypoints[0].Positions, "ExecuteTrajectoryByName.move_to_start");
}
else
{
//检验当前机械臂的关节坐标与计划轨迹的第一个点之前的差异,如果差异过大.就不报警,不执行下去
var currentJointPositions = _runtime.GetJointPositions();
var targetJointPositions = bundle.PlannedTrajectory.PlannedWaypoints[0].Positions;
var diff = currentJointPositions.Zip(targetJointPositions, (c, t) => Math.Abs(c - t)).Sum();
if (diff > 0.01)
{
_logger?.LogWarning("ExecuteTrajectoryByName 当前关节坐标与计划轨迹的第一个点之前的差异过大 name={Name}", name);
return;
}
}
var finalJointPositions = bundle.PlannedTrajectory.PlannedWaypoints[^1].Positions;
_runtime.ExecuteTrajectory(bundle.Result, finalJointPositions);
@@ -831,6 +843,7 @@ public sealed class ControllerClientCompatService : IControllerClientCompatServi
useDo: false,
ioAddresses: Array.Empty<int>(),
ioKeepCycles: 2,
triggerSampleIndexOffsetCycles: 7,
accLimitScale: 1.0,
jerkLimitScale: 1.0,
adaptIcspTryNum: 5);

View File

@@ -22,6 +22,12 @@ public sealed class ControllerClientTrajectoryOrchestrator
/// </summary>
private const double DenseLimitStretchFactor = 1.01;
/// <summary>
/// 平滑起停重定时混合系数0 表示不平滑1 表示完全使用平滑时间律。
/// 当前取值用于“弱平滑”,仅轻微拉伸首尾时间段,避免起停过慢。
/// </summary>
private const double SmoothStartStopBlend = 0.60;
private readonly ICspPlanner _icspPlanner;
private readonly SelfAdaptIcspPlanner _selfAdaptIcspPlanner;
private readonly ShotTimelineBuilder _shotTimelineBuilder = new(new WaypointTimestampResolver());
@@ -81,7 +87,12 @@ public sealed class ControllerClientTrajectoryOrchestrator
var executionTrajectory = plannedTrajectory;
var denseJointTrajectory = CreateLimitCompliantDenseTrajectory(ref executionTrajectory, shapeTrajectoryEdges: false);
var shotTimeline = new ShotTimeline(Array.Empty<ShotEvent>(), Array.Empty<TrajectoryDoEvent>());
var result = CreateResult(executionTrajectory, shotTimeline, denseJointTrajectory, usedCache: false);
var result = CreateResult(
executionTrajectory,
shotTimeline,
denseJointTrajectory,
usedCache: false,
triggerSampleIndexOffsetCycles: 0);
_logger?.LogInformation(
"PlanOrdinaryTrajectory 完成: 时长={Duration}s, 采样点数={SampleCount}",
@@ -156,7 +167,12 @@ public sealed class ControllerClientTrajectoryOrchestrator
holdCycles: settings.IoKeepCycles,
samplePeriod: planningRobot.ServoPeriod,
useDo: settings.UseDo);
var result = CreateResult(smoothedExecutionTrajectory, shotTimeline, denseJointTrajectory, usedCache: false);
var result = CreateResult(
smoothedExecutionTrajectory,
shotTimeline,
denseJointTrajectory,
usedCache: false,
triggerSampleIndexOffsetCycles: settings.TriggerSampleIndexOffsetCycles);
var bundle = new PlannedExecutionBundle(plannedTrajectory, shotTimeline, result);
_logger?.LogInformation(
@@ -259,6 +275,7 @@ public sealed class ControllerClientTrajectoryOrchestrator
hash.Add(options.SaveTrajectory);
hash.Add(settings.UseDo);
hash.Add(settings.IoKeepCycles);
hash.Add(settings.TriggerSampleIndexOffsetCycles);
hash.Add(settings.AdaptIcspTryNum);
hash.Add(settings.SmoothStartStopTiming);
@@ -309,6 +326,7 @@ public sealed class ControllerClientTrajectoryOrchestrator
useDo: true,
ioAddresses: Array.Empty<int>(),
ioKeepCycles: 0,
triggerSampleIndexOffsetCycles: 7,
accLimitScale: 1.0,
jerkLimitScale: 1.0,
adaptIcspTryNum: 5);
@@ -399,7 +417,8 @@ public sealed class ControllerClientTrajectoryOrchestrator
PlannedTrajectory plannedTrajectory,
ShotTimeline shotTimeline,
IReadOnlyList<IReadOnlyList<double>> denseJointTrajectory,
bool usedCache)
bool usedCache,
int triggerSampleIndexOffsetCycles)
{
return new TrajectoryResult(
programName: plannedTrajectory.OriginalProgram.Name,
@@ -413,6 +432,7 @@ public sealed class ControllerClientTrajectoryOrchestrator
usedCache: usedCache,
originalWaypointCount: plannedTrajectory.OriginalWaypointCount,
plannedWaypointCount: plannedTrajectory.PlannedWaypointCount,
triggerSampleIndexOffsetCycles: triggerSampleIndexOffsetCycles,
denseJointTrajectory: denseJointTrajectory);
}
@@ -476,36 +496,51 @@ public sealed class ControllerClientTrajectoryOrchestrator
}
/// <summary>
/// 为飞拍执行生成一条平滑起停时间轴。
/// 保持路点位置不变,只重映射路点时刻,让起点和终点附近的速度自然收敛。
/// 为飞拍执行生成平滑起停时间轴(仅重定时,不改几何路点)
/// 该方法保持 <see cref="PlannedTrajectory.PlannedWaypoints"/> 不变,只重映射 <see cref="PlannedTrajectory.WaypointTimes"/>
/// 让轨迹在起点和终点附近具有更柔和的速度变化,从而降低“突然起步/突然收尾”带来的离散差分尖峰。
/// </summary>
/// <param name="plannedTrajectory">规划器输出的原始轨迹(通常是线性时间轴)。</param>
/// <returns>
/// 若满足平滑条件,则返回新的重定时轨迹;若路点数量不足或总时长无效,则直接返回输入轨迹。
/// </returns>
private static PlannedTrajectory ApplySmoothStartStopTiming(PlannedTrajectory plannedTrajectory)
{
var originalTimes = plannedTrajectory.WaypointTimes;
// 至少需要“起点-中间点-终点”三类点,才有可平滑的中间区间。
if (originalTimes.Count < 3)
{
return plannedTrajectory;
}
var totalDuration = originalTimes[^1];
// 轨迹总时长必须为正,避免后续归一化进度出现除零或无意义映射。
if (totalDuration <= 0.0)
{
return plannedTrajectory;
}
var smoothedTimes = new double[originalTimes.Count];
// 强制固定边界:起点仍在 0终点仍在总时长保证任务总耗时不变。
smoothedTimes[0] = 0.0;
smoothedTimes[^1] = totalDuration;
for (var index = 1; index < originalTimes.Count - 1; index++)
{
// 把原始时刻归一化到 [0, 1],用于统一时间律变换。
var normalizedProgress = originalTimes[index] / totalDuration;
smoothedTimes[index] = totalDuration * InvertSmoothStartStopProgress(normalizedProgress);
// 先求完整平滑时间律对应的时刻,再与原线性时刻按比例混合。
// 这里采用弱平滑blend=0.35):保留大部分原节奏,仅轻微降低首尾突变。
var smoothedProgress = InvertSmoothStartStopProgress(normalizedProgress);
var blendedProgress = ((1.0 - SmoothStartStopBlend) * normalizedProgress)
+ (SmoothStartStopBlend * smoothedProgress);
smoothedTimes[index] = totalDuration * blendedProgress;
}
var segmentDurations = new double[smoothedTimes.Length - 1];
for (var index = 0; index < segmentDurations.Length; index++)
{
// 重建每段持续时间,供后续稠密采样和限幅检查使用。
segmentDurations[index] = smoothedTimes[index + 1] - smoothedTimes[index];
}
@@ -522,17 +557,24 @@ public sealed class ControllerClientTrajectoryOrchestrator
}
/// <summary>
/// 反解 7 次 smootherstep 的时间进度,用二分法把原始线性进度映射成平滑时间轴
/// 反解平滑时间进度:给定目标进度 p求满足 f(t)=p 的 t
/// 其中 f(t) 由 <see cref="EvaluateSmoothStartStopProgress"/> 给出,是单调递增的 7 次 smootherstep 曲线,
/// 通过二分法可稳定得到对应的归一化时间,避免显式求高次方程根带来的复杂性和数值不稳定。
/// </summary>
/// <param name="normalizedProgress">目标归一化进度,理论范围 [0, 1]。</param>
/// <returns>与目标进度对应的归一化时间,范围 [0, 1]。</returns>
private static double InvertSmoothStartStopProgress(double normalizedProgress)
{
// 防御式裁剪,避免上游浮点误差将进度推到区间外。
var target = Math.Clamp(normalizedProgress, 0.0, 1.0);
var low = 0.0;
var high = 1.0;
// 固定迭代次数确保耗时可预测40 次足以把区间收敛到工程可用精度。
for (var iteration = 0; iteration < 40; iteration++)
{
var middle = (low + high) / 2.0;
var progress = EvaluateSmoothStartStopProgress(middle);
// f(middle) 小于目标,说明根在右半区间;否则在左半区间。
if (progress < target)
{
low = middle;
@@ -547,10 +589,15 @@ public sealed class ControllerClientTrajectoryOrchestrator
}
/// <summary>
/// 计算 7 次 smootherstep 进度值,用于整段平滑起停时间律
/// 计算 7 次 smootherstep 进度函数值 f(u)
/// 该函数在 u=0 和 u=1 处具有更高阶导数连续性,可让起停段速度变化更平滑,
/// 适合用于飞拍轨迹的时间重参数化,减少离散导数在边界处的突变。
/// </summary>
/// <param name="normalizedTime">归一化时间 u理论范围 [0, 1]。</param>
/// <returns>归一化进度 f(u),范围 [0, 1]。</returns>
private static double EvaluateSmoothStartStopProgress(double normalizedTime)
{
// 先裁剪再计算多项式,确保数值稳定且不受外部越界输入影响。
var u = Math.Clamp(normalizedTime, 0.0, 1.0);
var u2 = u * u;
var u3 = u2 * u;

View File

@@ -83,7 +83,6 @@ public sealed class FlyshotTrajectoryArtifactWriter
TrajectoryExporter.WriteJointDenseTrajectory(Path.Combine(outputDir, "JointDetialTraj.txt"), jointDetailTrajectory);
TrajectoryExporter.WriteCartesianTrajectory(Path.Combine(outputDir, "CartTraj.txt"), cartTrajectory);
TrajectoryExporter.WriteCartesianDenseTrajectory(Path.Combine(outputDir, "CartDetialTraj.txt"), cartDetailTrajectory);
TrajectoryExporter.WriteShotEvents(Path.Combine(outputDir, "ShotEvents.json"), bundle.ShotTimeline.ShotEvents);
WriteActualSendArtifacts(outputDir, robot, bundle.Result, speedRatio);
_logger?.LogInformation(
@@ -133,6 +132,10 @@ public sealed class FlyshotTrajectoryArtifactWriter
var jointRows = new List<IReadOnlyList<double>>(samples.Count);
var timingRows = new List<IReadOnlyList<double>>(samples.Count);
var jerkRows = new List<IReadOnlyList<double>>();
var triggerBindings = TriggerSampleBinder.Bind(
result.TriggerTimeline,
samples,
result.TriggerSampleIndexOffsetCycles);
double? previousSendTime = null;
double[]? previousJoints = null;
double[]? previousVelocity = null;
@@ -161,6 +164,7 @@ public sealed class FlyshotTrajectoryArtifactWriter
WriteDenseRows(Path.Combine(outputDir, "ActualSendJointTraj.txt"), jointRows);
WriteDenseRows(Path.Combine(outputDir, "ActualSendTiming.txt"), timingRows);
WriteDenseRows(Path.Combine(outputDir, "ActualSendJerkStats.txt"), jerkRows);
TrajectoryExporter.WriteShotEvents(Path.Combine(outputDir, "ShotEvents.json"), result.ShotEvents, triggerBindings);
}
/// <summary>

View File

@@ -193,6 +193,7 @@ public sealed class JsonFlyshotTrajectoryStore
["use_do"] = JsonValue.Create(settings.UseDo),
["io_addr"] = JsonSerializer.SerializeToNode(settings.IoAddresses),
["io_keep_cycles"] = JsonValue.Create(settings.IoKeepCycles),
["trigger_sample_index_offset_cycles"] = JsonValue.Create(settings.TriggerSampleIndexOffsetCycles),
["acc_limit"] = JsonValue.Create(settings.AccLimitScale),
["jerk_limit"] = JsonValue.Create(settings.JerkLimitScale),
["adapt_icsp_try_num"] = JsonValue.Create(settings.AdaptIcspTryNum),

View File

@@ -16,6 +16,7 @@ public sealed class CompatibilityRobotSettings
bool useDo,
IEnumerable<int> ioAddresses,
int ioKeepCycles,
int triggerSampleIndexOffsetCycles,
double accLimitScale,
double jerkLimitScale,
int adaptIcspTryNum,
@@ -29,6 +30,11 @@ public sealed class CompatibilityRobotSettings
throw new ArgumentOutOfRangeException(nameof(ioKeepCycles), "IO 保持周期不能为负数。");
}
if (triggerSampleIndexOffsetCycles < 0)
{
throw new ArgumentOutOfRangeException(nameof(triggerSampleIndexOffsetCycles), "触发 sample 偏移周期不能为负数。");
}
if (accLimitScale <= 0.0)
{
throw new ArgumentOutOfRangeException(nameof(accLimitScale), "加速度倍率必须大于 0。");
@@ -59,6 +65,7 @@ public sealed class CompatibilityRobotSettings
UseDo = useDo;
IoAddresses = copiedIoAddresses;
IoKeepCycles = ioKeepCycles;
TriggerSampleIndexOffsetCycles = triggerSampleIndexOffsetCycles;
AccLimitScale = accLimitScale;
JerkLimitScale = jerkLimitScale;
AdaptIcspTryNum = adaptIcspTryNum;
@@ -81,6 +88,12 @@ public sealed class CompatibilityRobotSettings
/// </summary>
public int IoKeepCycles { get; }
/// <summary>
/// 获取触发绑定到最佳 sample 后,还要再向后偏移的命令周期数。
/// 该值作用在 J519 命令 sample 时间轴,不是 60015 状态反馈周期。
/// </summary>
public int TriggerSampleIndexOffsetCycles { get; }
/// <summary>
/// 获取加速度全局倍率。
/// </summary>
@@ -184,6 +197,7 @@ public sealed class RobotConfigLoader
useDo: ReadBoolean(robotElement, "use_do", defaultValue: false),
ioAddresses: ReadIntArray(robotElement, "io_addr"),
ioKeepCycles: ReadInt(robotElement, "io_keep_cycles", defaultValue: 0),
triggerSampleIndexOffsetCycles: ReadInt(robotElement, "trigger_sample_index_offset_cycles", defaultValue: 7),
accLimitScale: ReadDouble(robotElement, "acc_limit", defaultValue: 1.0),
jerkLimitScale: ReadDouble(robotElement, "jerk_limit", defaultValue: 1.0),
adaptIcspTryNum: ReadInt(robotElement, "adapt_icsp_try_num", defaultValue: 0),

View File

@@ -22,6 +22,7 @@ public sealed class TrajectoryResult
bool usedCache,
int originalWaypointCount,
int plannedWaypointCount,
int triggerSampleIndexOffsetCycles = 0,
IEnumerable<IReadOnlyList<double>>? denseJointTrajectory = null)
{
if (string.IsNullOrWhiteSpace(programName))
@@ -44,6 +45,11 @@ public sealed class TrajectoryResult
throw new ArgumentOutOfRangeException(nameof(plannedWaypointCount), "Planned waypoint count must be greater than or equal to the original waypoint count.");
}
if (triggerSampleIndexOffsetCycles < 0)
{
throw new ArgumentOutOfRangeException(nameof(triggerSampleIndexOffsetCycles), "Trigger sample index offset cycles must be zero or positive.");
}
ArgumentNullException.ThrowIfNull(shotEvents);
ArgumentNullException.ThrowIfNull(triggerTimeline);
ArgumentNullException.ThrowIfNull(artifacts);
@@ -65,6 +71,7 @@ public sealed class TrajectoryResult
UsedCache = usedCache;
OriginalWaypointCount = originalWaypointCount;
PlannedWaypointCount = plannedWaypointCount;
TriggerSampleIndexOffsetCycles = triggerSampleIndexOffsetCycles;
DenseJointTrajectory = copiedDenseJointTrajectory;
}
@@ -134,6 +141,12 @@ public sealed class TrajectoryResult
[JsonPropertyName("plannedWaypointCount")]
public int PlannedWaypointCount { get; }
/// <summary>
/// Gets the configured command-sample offset applied after trigger binding picks the best sample.
/// </summary>
[JsonPropertyName("triggerSampleIndexOffsetCycles")]
public int TriggerSampleIndexOffsetCycles { get; }
/// <summary>
/// Gets the dense joint trajectory samples where each row is [time, j1, j2, ...].
/// Null when dense sampling was not performed (e.g. simulation fallback).
@@ -150,7 +163,13 @@ public sealed class TrajectoryDoEvent
/// <summary>
/// Initializes a validated runtime trigger event.
/// </summary>
public TrajectoryDoEvent(int waypointIndex, double triggerTime, int offsetCycles, int holdCycles, IoAddressGroup addressGroup)
public TrajectoryDoEvent(
int waypointIndex,
double triggerTime,
int offsetCycles,
int holdCycles,
IoAddressGroup addressGroup,
IEnumerable<double>? referenceJointsDegrees = null)
{
if (waypointIndex < 0)
{
@@ -172,6 +191,7 @@ public sealed class TrajectoryDoEvent
OffsetCycles = offsetCycles;
HoldCycles = holdCycles;
AddressGroup = addressGroup ?? throw new ArgumentNullException(nameof(addressGroup));
ReferenceJointsDegrees = referenceJointsDegrees?.ToArray();
}
/// <summary>
@@ -203,6 +223,13 @@ public sealed class TrajectoryDoEvent
/// </summary>
[JsonPropertyName("addressGroup")]
public IoAddressGroup AddressGroup { get; }
/// <summary>
/// Gets the teach waypoint joints converted to degrees.
/// This is used to select the closest real send sample inside the trigger time window.
/// </summary>
[JsonPropertyName("referenceJointsDegrees")]
public IReadOnlyList<double>? ReferenceJointsDegrees { get; }
}
/// <summary>

View File

@@ -1,6 +1,7 @@
using System.Text;
using System.Text.Json;
using Flyshot.Core.Domain;
using Flyshot.Core.Planning.Sampling;
namespace Flyshot.Core.Planning.Export;
@@ -52,13 +53,51 @@ public static class TrajectoryExporter
/// </summary>
public static void WriteShotEvents(string path, IReadOnlyList<ShotEvent> events)
{
WriteShotEvents(path, events, bindings: null);
}
/// <summary>
/// 导出触发事件到 JSON 文件,并可选附带最终绑定到的实际 sample 信息。
/// </summary>
public static void WriteShotEvents(
string path,
IReadOnlyList<ShotEvent> events,
IReadOnlyList<TriggerSampleBinding>? bindings)
{
var bindingByWaypointIndex = bindings?
.GroupBy(static binding => binding.Trigger.WaypointIndex)
.ToDictionary(static group => group.Key, static group => group.First());
var payload = events.Select(e => new
{
waypoint_index = e.WaypointIndex,
trigger_time = Math.Round(e.TriggerTime, 6),
sample_index = e.SampleIndex,
sample_time = Math.Round(e.SampleTime, 6),
addrs = e.AddressGroup.Addresses.ToList()
addrs = e.AddressGroup.Addresses.ToList(),
trigger_window_seconds = bindingByWaypointIndex is not null && bindingByWaypointIndex.TryGetValue(e.WaypointIndex, out var binding)
? Math.Round(TriggerSampleBinder.TriggerBindingToleranceSeconds, 6)
: (double?)null,
selected_sample_index = bindingByWaypointIndex is not null && bindingByWaypointIndex.TryGetValue(e.WaypointIndex, out binding)
? binding.SampleIndex
: (int?)null,
selected_send_time = bindingByWaypointIndex is not null && bindingByWaypointIndex.TryGetValue(e.WaypointIndex, out binding)
? Math.Round(binding.Sample.SendTime, 6)
: (double?)null,
selected_trajectory_time = bindingByWaypointIndex is not null && bindingByWaypointIndex.TryGetValue(e.WaypointIndex, out binding)
? Math.Round(binding.Sample.TrajectoryTime, 6)
: (double?)null,
io_mask = bindingByWaypointIndex is not null && bindingByWaypointIndex.TryGetValue(e.WaypointIndex, out binding)
? ComputeIoValue(binding.Trigger.AddressGroup)
: (ushort?)null,
reference_joints_deg = bindingByWaypointIndex is not null
&& bindingByWaypointIndex.TryGetValue(e.WaypointIndex, out binding)
&& binding.Trigger.ReferenceJointsDegrees is { Count: > 0 }
? binding.Trigger.ReferenceJointsDegrees.Select(static value => Math.Round(value, 6)).ToArray()
: null,
trigger_joints_deg = bindingByWaypointIndex is not null && bindingByWaypointIndex.TryGetValue(e.WaypointIndex, out binding)
? binding.Sample.JointsDegrees.Select(static value => Math.Round(value, 6)).ToArray()
: null
}).ToList();
var json = JsonSerializer.Serialize(payload, new JsonSerializerOptions
@@ -79,4 +118,21 @@ public static class TrajectoryExporter
File.WriteAllText(path, sb.ToString(), new UTF8Encoding(false));
}
/// <summary>
/// 把 IO 地址组中的地址号映射为 writeIoValue 的位掩码,和运行时 / saveTrajectory 导出保持一致。
/// </summary>
private static ushort ComputeIoValue(IoAddressGroup group)
{
ushort value = 0;
foreach (var addr in group.Addresses)
{
if (addr is >= 1 and <= 16)
{
value |= (ushort)(1 << (addr - 1));
}
}
return value;
}
}

View File

@@ -0,0 +1,134 @@
using Flyshot.Core.Domain;
namespace Flyshot.Core.Planning.Sampling;
/// <summary>
/// 负责把理论触发事件绑定到实际 J519 发送 sample。
/// 绑定规则为:先在理论触发时间前后固定时间窗内筛候选点,再优先选择关节差最小的 sample。
/// </summary>
public static class TriggerSampleBinder
{
/// <summary>
/// 当前触发绑定使用的固定近时窗半宽,单位为秒。
/// 即:以理论触发时间为中心,在前后各 100ms 的范围内寻找最优 sample。
/// </summary>
public const double TriggerBindingToleranceSeconds = 0.1;
/// <summary>
/// 把一组触发事件绑定到采样后的 J519 sample。
/// </summary>
/// <param name="triggers">待绑定的触发事件。</param>
/// <param name="samples">J519 实发 sample。</param>
/// <param name="sampleIndexOffsetCycles">在最佳绑定 sample 基础上继续向后偏移的命令周期数。</param>
/// <returns>按最终 sampleIndex 排序的绑定结果。</returns>
public static IReadOnlyList<TriggerSampleBinding> Bind(
IReadOnlyList<TrajectoryDoEvent> triggers,
IReadOnlyList<J519SendSample> samples,
int sampleIndexOffsetCycles = 0)
{
ArgumentNullException.ThrowIfNull(triggers);
ArgumentNullException.ThrowIfNull(samples);
if (sampleIndexOffsetCycles < 0)
{
throw new ArgumentOutOfRangeException(nameof(sampleIndexOffsetCycles), "触发 sample 偏移周期不能为负数。");
}
var bindings = new List<TriggerSampleBinding>(triggers.Count);
if (triggers.Count == 0 || samples.Count == 0)
{
return bindings;
}
var lastSampleIndex = samples.Count - 1;
foreach (var trigger in triggers)
{
var fallbackIndex = FindClosestTrajectoryTimeSampleIndex(samples, trigger.TriggerTime);
var candidateStart = Math.Max(0, fallbackIndex - 1);
var candidateEnd = Math.Min(lastSampleIndex, fallbackIndex + 1);
var bestIndex = fallbackIndex;
var bestScore = double.PositiveInfinity;
var foundInWindow = false;
for (var sampleIndex = candidateStart; sampleIndex <= candidateEnd; sampleIndex++)
{
var sample = samples[sampleIndex];
if (Math.Abs(sample.TrajectoryTime - trigger.TriggerTime) > TriggerBindingToleranceSeconds)
{
continue;
}
foundInWindow = true;
var score = trigger.ReferenceJointsDegrees is { Count: > 0 }
? ComputeJointDifferenceScore(trigger.ReferenceJointsDegrees, sample.JointsDegrees)
: Math.Abs(sample.TrajectoryTime - trigger.TriggerTime);
if (score < bestScore)
{
bestScore = score;
bestIndex = sampleIndex;
}
}
var finalIndex = Math.Min(lastSampleIndex, bestIndex + sampleIndexOffsetCycles);
bindings.Add(new TriggerSampleBinding(trigger, samples[finalIndex], finalIndex, foundInWindow));
}
return bindings
.OrderBy(static binding => binding.SampleIndex)
.ThenBy(static binding => binding.Trigger.WaypointIndex)
.ToArray();
}
/// <summary>
/// 按轨迹时间找到最接近理论触发时刻的 sample。
/// </summary>
public static int FindClosestTrajectoryTimeSampleIndex(IReadOnlyList<J519SendSample> samples, double triggerTime)
{
ArgumentNullException.ThrowIfNull(samples);
var bestIndex = 0;
var bestDelta = double.PositiveInfinity;
for (var sampleIndex = 0; sampleIndex < samples.Count; sampleIndex++)
{
var delta = Math.Abs(samples[sampleIndex].TrajectoryTime - triggerTime);
if (delta < bestDelta)
{
bestDelta = delta;
bestIndex = sampleIndex;
}
}
return bestIndex;
}
/// <summary>
/// 计算参考示教点与候选 sample 的关节差评分,使用平方和即可稳定排序。
/// </summary>
public static double ComputeJointDifferenceScore(
IReadOnlyList<double>? referenceJointsDegrees,
IReadOnlyList<double> sampleJointsDegrees)
{
if (referenceJointsDegrees is null || referenceJointsDegrees.Count == 0)
{
return 0.0;
}
var jointCount = Math.Min(referenceJointsDegrees.Count, sampleJointsDegrees.Count);
var score = 0.0;
for (var index = 0; index < jointCount; index++)
{
var delta = sampleJointsDegrees[index] - referenceJointsDegrees[index];
score += delta * delta;
}
return score;
}
}
/// <summary>
/// 表示一个理论触发事件最终绑定到哪个 J519 sample 的结果。
/// </summary>
public sealed record TriggerSampleBinding(
TrajectoryDoEvent Trigger,
J519SendSample Sample,
int SampleIndex,
bool FoundInWindow);

View File

@@ -8,9 +8,22 @@ namespace Flyshot.Core.Triggering;
/// 根据规划轨迹和飞拍配置生成触发时间轴,把示教点上的 shot_flags / offset_values / addr
/// 映射成带理论时间和离散化时间的 ShotEvent以及可直接注入伺服流的 TrajectoryDoEvent。
/// </summary>
/// <remarks>
/// 本构建器只负责“时间轴映射”和“事件打包”,不负责轨迹规划与运行时发送。
/// 其中:
/// - ShotEvent 用于诊断、导出和日志观察;
/// - TrajectoryDoEvent 用于运行时伺服链路注入 DO 脉冲。
/// </remarks>
public sealed class ShotTimelineBuilder
{
/// <summary>
/// 将原始示教点索引映射到规划后时间轴上的时间戳解析器。
/// </summary>
private readonly WaypointTimestampResolver _resolver;
/// <summary>
/// 可选日志记录器,用于输出时间轴构建统计信息。
/// </summary>
private readonly ILogger<ShotTimelineBuilder>? _logger;
/// <summary>
@@ -32,6 +45,17 @@ public sealed class ShotTimelineBuilder
/// <param name="samplePeriod">稠密采样周期,用于离散化 sample_index 和 sample_time。</param>
/// <param name="useDo">是否生成可注入伺服流的 DO 事件。</param>
/// <returns>包含 ShotEvent 和 TrajectoryDoEvent 的触发时间轴。</returns>
/// <exception cref="ArgumentNullException">当 <paramref name="trajectory"/> 为 null 时抛出。</exception>
/// <exception cref="ArgumentOutOfRangeException">
/// 当 <paramref name="holdCycles"/> 小于 0或 <paramref name="samplePeriod"/> 小于等于 0 时抛出。
/// </exception>
/// <remarks>
/// 时间计算规则:
/// - 理论触发时间timestamp[i] + offset_values[i] * trigger_period
/// - 离散采样索引Round(trigger_time / sample_period)
/// - 离散采样时间sample_index * sample_period。
/// 该离散化与运行时 8ms 周期下发模型一致,可用于对齐导出与诊断。
/// </remarks>
public ShotTimeline Build(PlannedTrajectory trajectory, int holdCycles, TimeSpan samplePeriod, bool useDo = true)
{
ArgumentNullException.ThrowIfNull(trajectory);
@@ -55,6 +79,7 @@ public sealed class ShotTimelineBuilder
var shotEvents = new List<ShotEvent>();
var triggerTimeline = new List<TrajectoryDoEvent>();
// 遍历原始示教点,仅对 shot_flag=true 的点生成触发事件。
for (int i = 0; i < program.Waypoints.Count; i++)
{
if (!program.ShotFlags[i])
@@ -62,6 +87,7 @@ public sealed class ShotTimelineBuilder
continue;
}
// 先得到连续时间上的理论触发时刻,再映射到离散采样周期。
double triggerTime = timestamps[i] + program.OffsetValues[i] * triggerPeriodSeconds;
int sampleIndex = (int)Math.Round(triggerTime / samplePeriodSeconds);
double sampleTime = sampleIndex * samplePeriodSeconds;
@@ -83,7 +109,8 @@ public sealed class ShotTimelineBuilder
triggerTime: triggerTime,
offsetCycles: program.OffsetValues[i],
holdCycles: holdCycles,
addressGroup: addressGroup));
addressGroup: addressGroup,
referenceJointsDegrees: program.Waypoints[i].Positions.Select(static radians => radians * 180.0 / Math.PI)));
}
}

View File

@@ -1,6 +1,7 @@
using System.Diagnostics;
using System.Text;
using Flyshot.Core.Domain;
using Flyshot.Core.Planning.Export;
using Flyshot.Core.Planning.Sampling;
using Flyshot.Runtime.Common;
using Flyshot.Runtime.Fanuc.Protocol;
@@ -569,7 +570,6 @@ public sealed class FanucControllerRuntime : IControllerRuntime, IDisposable
var servoPeriodSeconds = _robot!.ServoPeriod.TotalSeconds;
var speedRatio = _speedRatio;
var trajectoryStepSeconds = servoPeriodSeconds * speedRatio;
var triggerToleranceSeconds = trajectoryStepSeconds / 2.0;
var durationSeconds = result.Duration.TotalSeconds;
var samples = J519SendTrajectorySampler.SampleDenseJointTrajectory(
result.DenseJointTrajectory!,
@@ -586,12 +586,18 @@ public sealed class FanucControllerRuntime : IControllerRuntime, IDisposable
"SendDenseTrajectory 开始: program={ProgramName}, 采样数={SampleCount}, 时长={Duration}s, speedRatio={SpeedRatio}, 周期={Period}ms, 触发事件数={TriggerCount}",
result.ProgramName, sampleCount, durationSeconds, speedRatio, servoPeriodSeconds * 1000, triggers.Count);
var triggerBindings = TriggerSampleBinder.Bind(
triggers,
samples,
result.TriggerSampleIndexOffsetCycles);
var stopwatch = Stopwatch.StartNew();
ushort ioValue = 0;
ushort ioMask = 0;
int holdRemaining = -1;
long logInterval = Math.Max(1, sampleCount / 10);
int triggerFiredCount = 0;
var nextBindingIndex = 0;
var commands = new List<FanucJ519Command>(sampleCount);
var sentJointRows = new List<IReadOnlyList<double>>(sampleCount);
var sentTimingRows = new List<IReadOnlyList<double>>(sampleCount);
@@ -624,19 +630,30 @@ public sealed class FanucControllerRuntime : IControllerRuntime, IDisposable
// 检查当前周期是否有新的触发事件。
if (holdRemaining < 0 && !clearMaskAfterSend)
{
foreach (var trigger in triggers)
while (nextBindingIndex < triggerBindings.Count
&& triggerBindings[nextBindingIndex].SampleIndex < sample.SampleIndex)
{
if (Math.Abs(sample.TrajectoryTime - trigger.TriggerTime) <= triggerToleranceSeconds)
{
ioMask = ComputeIoValue(trigger.AddressGroup);
ioValue = ioMask;
holdRemaining = Math.Max(trigger.HoldCycles - 1, 0);
triggerFiredCount++;
_logger?.LogInformation(
"J519 IO触发: time={Time:F4}s, addr=[{Addr}], holdCycles={HoldCycles}",
sample.TrajectoryTime, string.Join(",", trigger.AddressGroup.Addresses), trigger.HoldCycles);
break;
}
nextBindingIndex++;
}
if (nextBindingIndex < triggerBindings.Count
&& triggerBindings[nextBindingIndex].SampleIndex == sample.SampleIndex)
{
var binding = triggerBindings[nextBindingIndex];
ioMask = ComputeIoValue(binding.Trigger.AddressGroup);
ioValue = ioMask;
holdRemaining = Math.Max(binding.Trigger.HoldCycles - 1, 0);
triggerFiredCount++;
nextBindingIndex++;
_logger?.LogInformation(
"J519 IO触发: waypointIndex={WaypointIndex}, theoryTime={TheoryTime:F4}s, sampleIndex={SampleIndex}, sampleSendTime={SampleSendTime:F4}s, sampleTrajectoryTime={SampleTrajectoryTime:F4}s, addr=[{Addr}], holdCycles={HoldCycles}",
binding.Trigger.WaypointIndex,
binding.Trigger.TriggerTime,
binding.SampleIndex,
binding.Sample.SendTime,
binding.Sample.TrajectoryTime,
string.Join(",", binding.Trigger.AddressGroup.Addresses),
binding.Trigger.HoldCycles);
}
}
@@ -684,7 +701,7 @@ public sealed class FanucControllerRuntime : IControllerRuntime, IDisposable
sample.TrajectoryTime);
}
}
TryWriteDenseSendArtifacts(outputDir, sentJointRows, sentTimingRows, sentJerkRows);
TryWriteDenseSendArtifacts(result, outputDir, sentJointRows, sentTimingRows, sentJerkRows, triggerBindings);
// 上层只负责生成完整目标序列,真实出队节拍交给 J519 状态包驱动。
_j519Client.LoadCommandQueue(commands);
@@ -828,22 +845,26 @@ public sealed class FanucControllerRuntime : IControllerRuntime, IDisposable
/// 尝试把实际发送点位、时间映射和跃度统计写入纯文本文件;若落盘失败,只记录日志,不影响运动主流程。
/// </summary>
private void TryWriteDenseSendArtifacts(
TrajectoryResult result,
string outputDir,
IReadOnlyList<IReadOnlyList<double>> sentJointRows,
IReadOnlyList<IReadOnlyList<double>> sentTimingRows,
IReadOnlyList<IReadOnlyList<double>> sentJerkRows)
IReadOnlyList<IReadOnlyList<double>> sentJerkRows,
IReadOnlyList<TriggerSampleBinding> triggerBindings)
{
try
{
WriteDenseRows(Path.Combine(outputDir, "ActualSendJointTraj.txt"), sentJointRows);
WriteDenseRows(Path.Combine(outputDir, "ActualSendTiming.txt"), sentTimingRows);
WriteDenseRows(Path.Combine(outputDir, "ActualSendJerkStats.txt"), sentJerkRows);
TrajectoryExporter.WriteShotEvents(Path.Combine(outputDir, "ShotEvents.json"), result.ShotEvents, triggerBindings);
_logger?.LogInformation(
"SendDenseTrajectory 已写出实际发送记录: outputDir={OutputDir}, pointRows={PointRows}, timingRows={TimingRows}, jerkRows={JerkRows}",
"SendDenseTrajectory 已写出实际发送记录: outputDir={OutputDir}, pointRows={PointRows}, timingRows={TimingRows}, jerkRows={JerkRows}, triggerBindings={TriggerBindings}",
outputDir,
sentJointRows.Count,
sentTimingRows.Count,
sentJerkRows.Count);
sentJerkRows.Count,
triggerBindings.Count);
}
catch (Exception exception)
{
@@ -888,15 +909,16 @@ public sealed class FanucControllerRuntime : IControllerRuntime, IDisposable
/// <summary>
/// 把 IO 地址组中的地址号映射为 writeIoValue 的位掩码。
/// 手册约定 writeIoIndex=1 时LSB 对应第 1 个 IO 点,因此地址 N 对应 bit(N-1)。
/// </summary>
internal static ushort ComputeIoValue(IoAddressGroup group)
{
ushort value = 0;
foreach (var addr in group.Addresses)
{
if (addr is >= 0 and < 16)
if (addr is >= 1 and <= 16)
{
value |= (ushort)(1 << addr);
value |= (ushort)(1 << (addr - 1));
}
}

View File

@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "10.0.7",
"commands": [
"dotnet-ef"
],
"rollForward": false
}
}
}

View File

@@ -25,5 +25,12 @@
"AllowedHeaders": [
"*"
]
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://0.0.0.0:5190"
}
}
}
}

View File

@@ -30,5 +30,12 @@
"*"
]
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://0.0.0.0:5000"
}
}
},
"AllowedHosts": "*"
}

View File

@@ -21,6 +21,7 @@ public sealed class ConfigCompatibilityTests
Assert.True(loaded.Robot.UseDo);
Assert.Equal([7, 8], loaded.Robot.IoAddresses);
Assert.Equal(2, loaded.Robot.IoKeepCycles);
Assert.Equal(7, loaded.Robot.TriggerSampleIndexOffsetCycles);
Assert.Equal(1.0, loaded.Robot.AccLimitScale);
Assert.Equal(1.0, loaded.Robot.JerkLimitScale);
Assert.Equal(1.0, loaded.Robot.PlanningSpeedScale);
@@ -70,6 +71,7 @@ public sealed class ConfigCompatibilityTests
Assert.False(loaded.Robot.UseDo);
Assert.Empty(loaded.Robot.IoAddresses);
Assert.Equal(3, loaded.Robot.IoKeepCycles);
Assert.Equal(7, loaded.Robot.TriggerSampleIndexOffsetCycles);
Assert.Equal(0.5, loaded.Robot.AccLimitScale);
Assert.Equal(0.25, loaded.Robot.JerkLimitScale);
Assert.Equal(1.0, loaded.Robot.PlanningSpeedScale);
@@ -123,6 +125,46 @@ public sealed class ConfigCompatibilityTests
}
}
/// <summary>
/// 验证 RobotConfig.json 可以显式配置触发绑定后的命令 sample 后移周期数。
/// </summary>
[Fact]
public void RobotConfigLoader_LoadsTriggerSampleIndexOffsetCycles()
{
var tempRoot = CreateTempDirectory();
try
{
var configPath = Path.Combine(tempRoot, "legacy.json");
File.WriteAllText(
configPath,
"""
{
"robot": {
"use_do": true,
"io_keep_cycles": 2,
"trigger_sample_index_offset_cycles": 8,
"acc_limit": 1.0,
"jerk_limit": 1.0
},
"flying_shots": {
"demo": {
"traj_waypoints": [[0, 1], [2, 3], [4, 5], [6, 7]],
"shot_flags": [false, false, false, false]
}
}
}
""");
var loaded = new RobotConfigLoader().Load(configPath);
Assert.Equal(8, loaded.Robot.TriggerSampleIndexOffsetCycles);
}
finally
{
Directory.Delete(tempRoot, recursive: true);
}
}
/// <summary>
/// 验证 RobotConfig.json 可以关闭飞拍执行前的二次平滑起停时间重映射。
/// </summary>

View File

@@ -71,6 +71,7 @@ public sealed class ControllerClientCompatConfigRootTests
useDo: true,
ioAddresses: [7, 8],
ioKeepCycles: 2,
triggerSampleIndexOffsetCycles: 7,
accLimitScale: 1.0,
jerkLimitScale: 1.0,
adaptIcspTryNum: 5);
@@ -83,6 +84,7 @@ public sealed class ControllerClientCompatConfigRootTests
Assert.False(Directory.Exists(Path.Combine(configRoot, "TrajectoryStore")), "不应再创建独立轨迹存储目录。");
var loaded = store.LoadAll("FANUC_LR_Mate_200iD", out var loadedSettings);
Assert.NotNull(loadedSettings);
Assert.Equal(7, loadedSettings.TriggerSampleIndexOffsetCycles);
Assert.Contains(trajectory.Name, loaded);
store.Delete("FANUC_LR_Mate_200iD", trajectory.Name);

View File

@@ -1,5 +1,6 @@
using System.Text.Json;
using Flyshot.Core.Domain;
using Flyshot.Core.Planning.Sampling;
namespace Flyshot.Core.Tests;
@@ -164,7 +165,8 @@ public sealed class DomainModelTests
triggerTime: 0.5,
offsetCycles: 0,
holdCycles: 1,
addressGroup: new IoAddressGroup(new[] { 100 }))
addressGroup: new IoAddressGroup(new[] { 100 }),
referenceJointsDegrees: new[] { 12.5, -3.0 })
},
artifacts: new[]
{
@@ -176,7 +178,8 @@ public sealed class DomainModelTests
failureReason: null,
usedCache: true,
originalWaypointCount: 4,
plannedWaypointCount: 5);
plannedWaypointCount: 5,
triggerSampleIndexOffsetCycles: 7);
var json = JsonSerializer.Serialize(result);
@@ -184,6 +187,36 @@ public sealed class DomainModelTests
Assert.Contains("\"method\":\"SelfAdaptIcsp\"", json);
Assert.Contains("\"kind\":\"JointDenseTrajectory\"", json);
Assert.Contains("\"usedCache\":true", json);
Assert.Contains("\"triggerSampleIndexOffsetCycles\":7", json);
Assert.Contains("\"referenceJointsDegrees\":[12.5,-3]", json);
}
/// <summary>
/// 验证触发绑定允许在最佳 sample 基础上继续向后偏移固定命令周期。
/// </summary>
[Fact]
public void TriggerSampleBinder_Bind_AppliesConfiguredSampleIndexOffset()
{
var trigger = new TrajectoryDoEvent(
waypointIndex: 1,
triggerTime: 0.008,
offsetCycles: 0,
holdCycles: 2,
addressGroup: new IoAddressGroup([2, 4]),
referenceJointsDegrees: [10.0, 20.0]);
var samples = new[]
{
new J519SendSample(sampleIndex: 0, sendTime: 0.0, trajectoryTime: 0.0, speedRatio: 1.0, jointsDegrees: [0.0, 0.0]),
new J519SendSample(sampleIndex: 1, sendTime: 0.008, trajectoryTime: 0.008, speedRatio: 1.0, jointsDegrees: [10.0, 20.0]),
new J519SendSample(sampleIndex: 2, sendTime: 0.016, trajectoryTime: 0.016, speedRatio: 1.0, jointsDegrees: [11.0, 21.0]),
new J519SendSample(sampleIndex: 3, sendTime: 0.024, trajectoryTime: 0.024, speedRatio: 1.0, jointsDegrees: [12.0, 22.0])
};
var binding = Assert.Single(Flyshot.Core.Planning.Sampling.TriggerSampleBinder.Bind([trigger], samples, sampleIndexOffsetCycles: 2));
Assert.True(binding.FoundInWindow);
Assert.Equal(3, binding.SampleIndex);
Assert.Equal(0.024, binding.Sample.SendTime, precision: 6);
}
/// <summary>

View File

@@ -146,8 +146,8 @@ public sealed class FanucControllerRuntimeDenseTests
var denseTrajectory = new[]
{
new[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
new[] { 0.008, Math.PI / 2.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
new[] { 0.016, Math.PI, 0.0, 0.0, 0.0, 0.0, 0.0 }
new[] { 0.008, DegreesToRadians(1.0), 0.0, 0.0, 0.0, 0.0, 0.0 },
new[] { 0.016, DegreesToRadians(2.0), 0.0, 0.0, 0.0, 0.0, 0.0 }
};
var result = new TrajectoryResult(
@@ -164,7 +164,7 @@ public sealed class FanucControllerRuntimeDenseTests
plannedWaypointCount: 4,
denseJointTrajectory: denseTrajectory);
runtime.ExecuteTrajectory(result, [Math.PI, 0.0, 0.0, 0.0, 0.0, 0.0]);
runtime.ExecuteTrajectory(result, [DegreesToRadians(2.0), 0.0, 0.0, 0.0, 0.0, 0.0]);
WaitUntilIdle(runtime);
var commands = j519Client.GetCommandHistoryForTests();
@@ -172,14 +172,17 @@ public sealed class FanucControllerRuntimeDenseTests
var pointsPath = Path.Combine(runDir, "ActualSendJointTraj.txt");
var timingPath = Path.Combine(runDir, "ActualSendTiming.txt");
var jerkPath = Path.Combine(runDir, "ActualSendJerkStats.txt");
var shotEventsPath = Path.Combine(runDir, "ShotEvents.json");
Assert.True(File.Exists(pointsPath));
Assert.True(File.Exists(timingPath));
Assert.True(File.Exists(jerkPath));
Assert.True(File.Exists(shotEventsPath));
var pointLines = File.ReadAllLines(pointsPath);
var timingLines = File.ReadAllLines(timingPath);
var jerkLines = File.ReadAllLines(jerkPath);
var shotEventsJson = File.ReadAllText(shotEventsPath);
Assert.Equal(commands.Count, pointLines.Length);
Assert.Equal(commands.Count, timingLines.Length);
Assert.Equal(Math.Max(0, commands.Count - 1), jerkLines.Length);
@@ -191,7 +194,7 @@ public sealed class FanucControllerRuntimeDenseTests
Assert.Equal(9, lastColumns.Length);
Assert.Equal(0.0, firstColumns[0], precision: 6);
Assert.Equal(0.008, secondColumns[0], precision: 6);
Assert.Equal(180.0, lastColumns[1], precision: 6);
Assert.Equal(2.0, lastColumns[1], precision: 6);
var firstTimingColumns = ParseColumns(timingLines[0]);
var secondTimingColumns = ParseColumns(timingLines[1]);
@@ -211,6 +214,8 @@ public sealed class FanucControllerRuntimeDenseTests
Assert.Equal(10, firstJerkColumns.Length);
Assert.Equal(0.0, firstJerkColumns[0], precision: 6);
Assert.Equal(0.008, firstJerkColumns[2], precision: 6);
Assert.Equal("[]", shotEventsJson.Trim());
}
finally
{
@@ -561,8 +566,63 @@ public sealed class FanucControllerRuntimeDenseTests
var commands = j519Client.GetCommandHistoryForTests();
Assert.Equal(4, commands.Count);
Assert.Equal([(ushort)0, (ushort)10, (ushort)10, (ushort)10], commands.Select(static command => command.WriteIoMask));
Assert.Equal([(ushort)0, (ushort)10, (ushort)10, (ushort)0], commands.Select(static command => command.WriteIoValue));
Assert.Equal([(ushort)0, (ushort)5, (ushort)5, (ushort)5], commands.Select(static command => command.WriteIoMask));
Assert.Equal([(ushort)0, (ushort)5, (ushort)5, (ushort)0], commands.Select(static command => command.WriteIoValue));
}
/// <summary>
/// 验证同一时间窗口内存在多个候选 sample 时,会优先把 IO 挂到关节坐标最接近示教点的那一帧。
/// </summary>
[Fact]
public void ExecuteTrajectory_WithDenseWaypoints_RealMode_PrefersClosestJointSampleWithinTriggerWindow()
{
using var commandClient = new FanucCommandClient();
using var stateClient = new FanucStateClient();
using var j519Client = new FanucJ519Client();
using var runtime = new FanucControllerRuntime(commandClient, stateClient, j519Client);
var robot = TestRobotFactory.CreateRobotProfile();
runtime.ResetRobot(robot, "FANUC_LR_Mate_200iD");
j519Client.EnableCommandHistoryForTests();
ForceRealModeEnabled(runtime, speedRatio: 1.0);
var denseTrajectory = new[]
{
new[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
new[] { 0.008, DegreesToRadians(1.0), 0.0, 0.0, 0.0, 0.0, 0.0 },
new[] { 0.016, DegreesToRadians(2.0), 0.0, 0.0, 0.0, 0.0, 0.0 },
new[] { 0.024, DegreesToRadians(3.0), 0.0, 0.0, 0.0, 0.0, 0.0 }
};
var result = new TrajectoryResult(
programName: "demo",
method: PlanningMethod.Icsp,
isValid: true,
duration: TimeSpan.FromSeconds(0.024),
shotEvents: Array.Empty<ShotEvent>(),
triggerTimeline:
[
new TrajectoryDoEvent(
waypointIndex: 1,
triggerTime: 0.012,
offsetCycles: 0,
holdCycles: 1,
addressGroup: new IoAddressGroup([1]),
referenceJointsDegrees: [2.0, 0.0, 0.0, 0.0, 0.0, 0.0])
],
artifacts: Array.Empty<TrajectoryArtifact>(),
failureReason: null,
usedCache: false,
originalWaypointCount: 4,
plannedWaypointCount: 4,
denseJointTrajectory: denseTrajectory);
runtime.ExecuteTrajectory(result, [DegreesToRadians(3.0), 0.0, 0.0, 0.0, 0.0, 0.0]);
WaitUntilIdle(runtime);
var commands = j519Client.GetCommandHistoryForTests();
Assert.Equal(4, commands.Count);
Assert.Equal([(ushort)0, (ushort)0, (ushort)1, (ushort)1], commands.Select(static command => command.WriteIoMask));
Assert.Equal([(ushort)0, (ushort)0, (ushort)1, (ushort)0], commands.Select(static command => command.WriteIoValue));
}
/// <summary>
@@ -677,13 +737,16 @@ public sealed class FanucControllerRuntimeDenseTests
}
/// <summary>
/// 验证 IO 地址组中的地址号被正确映射为 writeIoValue 位掩码。
/// 验证 IO 地址组中的地址号按 writeIoIndex=1 的手册语义映射为 writeIoValue 位掩码。
/// </summary>
[Theory]
[InlineData(new[] { 0 }, (ushort)1)]
[InlineData(new[] { 7 }, (ushort)128)]
[InlineData(new[] { 7, 8 }, (ushort)384)] // 128 + 256
[InlineData(new[] { 15 }, (ushort)32768)]
[InlineData(new[] { 1 }, (ushort)1)]
[InlineData(new[] { 2, 4 }, (ushort)10)]
[InlineData(new[] { 3, 4 }, (ushort)12)]
[InlineData(new[] { 2, 3, 4 }, (ushort)14)]
[InlineData(new[] { 8 }, (ushort)128)]
[InlineData(new[] { 8, 9 }, (ushort)384)] // 128 + 256
[InlineData(new[] { 16 }, (ushort)32768)]
[InlineData(new int[] { }, (ushort)0)]
public void ComputeIoValue_MapsAddressesToBitMask(int[] addresses, ushort expected)
{
@@ -693,12 +756,12 @@ public sealed class FanucControllerRuntimeDenseTests
}
/// <summary>
/// 验证超 15 的地址号会被安全忽略,不会溢出位掩码。
/// 验证超 1..16 范围的地址号会被安全忽略,不会污染位掩码。
/// </summary>
[Fact]
public void ComputeIoValue_IgnoresOutOfRangeAddresses()
{
var group = new IoAddressGroup([0, 16, 7]);
var group = new IoAddressGroup([0, 1, 17, 8]);
var actual = FanucControllerRuntime.ComputeIoValue(group);
Assert.Equal((ushort)(1 | 128), actual);
}

View File

@@ -170,6 +170,51 @@ public sealed class PlanningCompatibilityTests
Assert.Equal(1, doEvent.WaypointIndex);
Assert.Equal(1, doEvent.OffsetCycles);
Assert.Equal(2, doEvent.HoldCycles);
Assert.NotNull(doEvent.ReferenceJointsDegrees);
Assert.Equal(RadiansToDegrees(1.0), doEvent.ReferenceJointsDegrees![0], precision: 6);
Assert.Equal(0.0, doEvent.ReferenceJointsDegrees![1], precision: 6);
}
/// <summary>
/// 验证时间轴会把示教点关节角保存到 DO 事件里,供运行时在近时窗内做最小关节差绑定。
/// </summary>
[Fact]
public void ShotTimelineBuilder_PopulatesReferenceJointsDegreesForRuntimeBinding()
{
var robot = CreateRobotProfile([1, 1], [1, 1], [1, 1]);
var program = new FlyshotProgram(
name: "demo",
waypoints:
[
new JointWaypoint([0.0, 0.0]),
new JointWaypoint([Math.PI / 6.0, -Math.PI / 4.0])
],
shotFlags: [false, true],
offsetValues: [0, 0],
addressGroups:
[
new IoAddressGroup(Array.Empty<int>()),
new IoAddressGroup([1])
]);
var trajectory = new PlannedTrajectory(
robot: robot,
originalProgram: program,
plannedWaypoints: program.Waypoints,
waypointTimes: [0.0, 0.5],
segmentDurations: [0.5],
segmentScales: [1.0],
method: PlanningMethod.Icsp,
iterations: 1,
threshold: 0.0);
var timeline = new ShotTimelineBuilder(new WaypointTimestampResolver())
.Build(trajectory, holdCycles: 1, samplePeriod: TimeSpan.FromMilliseconds(8));
var trigger = Assert.Single(timeline.TriggerTimeline);
Assert.NotNull(trigger.ReferenceJointsDegrees);
Assert.Equal(30.0, trigger.ReferenceJointsDegrees![0], precision: 6);
Assert.Equal(-45.0, trigger.ReferenceJointsDegrees![1], precision: 6);
}
/// <summary>
@@ -271,4 +316,9 @@ public sealed class PlanningCompatibilityTests
throw new DirectoryNotFoundException("Unable to locate the flyshot workspace root.");
}
private static double RadiansToDegrees(double radians)
{
return radians * 180.0 / Math.PI;
}
}

View File

@@ -189,6 +189,7 @@ public sealed class RuntimeOrchestrationTests
useDo: true,
ioAddresses: [7, 8],
ioKeepCycles: 4,
triggerSampleIndexOffsetCycles: 7,
accLimitScale: 1.0,
jerkLimitScale: 1.0,
adaptIcspTryNum: 5);
@@ -212,6 +213,7 @@ public sealed class RuntimeOrchestrationTests
useDo: false,
ioAddresses: [7, 8],
ioKeepCycles: 4,
triggerSampleIndexOffsetCycles: 7,
accLimitScale: 1.0,
jerkLimitScale: 1.0,
adaptIcspTryNum: 5);
@@ -940,11 +942,14 @@ public sealed class RuntimeOrchestrationTests
var outputDir = Path.Combine(configRoot, "Data", "demo-flyshot");
var pointsPath = Path.Combine(outputDir, "ActualSendJointTraj.txt");
var timingPath = Path.Combine(outputDir, "ActualSendTiming.txt");
var shotEventsPath = Path.Combine(outputDir, "ShotEvents.json");
Assert.True(File.Exists(pointsPath));
Assert.True(File.Exists(timingPath));
Assert.True(File.Exists(shotEventsPath));
var pointRows = File.ReadAllLines(pointsPath).Select(ParseSpaceSeparatedDoubles).ToArray();
var timingRows = File.ReadAllLines(timingPath).Select(ParseSpaceSeparatedDoubles).ToArray();
var shotEventsJson = File.ReadAllText(shotEventsPath);
var executionDuration = double.Parse(
File.ReadLines(Path.Combine(outputDir, "JointDetialTraj.txt")).Last().Split(' ')[0],
CultureInfo.InvariantCulture);
@@ -956,6 +961,8 @@ public sealed class RuntimeOrchestrationTests
Assert.Equal(0.008, pointRows[1][0], precision: 6);
Assert.Equal(0.004, timingRows[1][2], precision: 6);
Assert.Equal(0.5, timingRows[1][3], precision: 6);
Assert.Contains("\"trigger_window_seconds\": 0.1", shotEventsJson);
Assert.Contains("\"selected_sample_index\"", shotEventsJson);
}
finally
{
@@ -1127,6 +1134,7 @@ public sealed class RuntimeOrchestrationTests
useDo: settings.UseDo,
ioAddresses: settings.IoAddresses,
ioKeepCycles: settings.IoKeepCycles,
triggerSampleIndexOffsetCycles: settings.TriggerSampleIndexOffsetCycles,
accLimitScale: settings.AccLimitScale,
jerkLimitScale: settings.JerkLimitScale,
adaptIcspTryNum: settings.AdaptIcspTryNum,