Просмотр исходного кода

test(training): verify workbench bolt picking and installation recovery

main
leiyun 7 часов назад
Родитель
Сommit
aab82abdf5
83 измененных файлов: 2258 добавлений и 1 удалений
  1. +328
    -0
      reports/bridge-bolt-pick-20260925-007/result.json
  2. Двоичные данные
     
  3. Двоичные данные
     
  4. Двоичные данные
     
  5. Двоичные данные
     
  6. Двоичные данные
     
  7. Двоичные данные
     
  8. Двоичные данные
     
  9. Двоичные данные
     
  10. Двоичные данные
     
  11. Двоичные данные
     
  12. Двоичные данные
     
  13. Двоичные данные
     
  14. Двоичные данные
     
  15. Двоичные данные
     
  16. Двоичные данные
     
  17. Двоичные данные
     
  18. +717
    -0
      reports/bridge-bolt-pick-20260925-008/result.json
  19. Двоичные данные
     
  20. Двоичные данные
     
  21. Двоичные данные
     
  22. Двоичные данные
     
  23. Двоичные данные
     
  24. Двоичные данные
     
  25. Двоичные данные
     
  26. Двоичные данные
     
  27. Двоичные данные
     
  28. Двоичные данные
     
  29. Двоичные данные
     
  30. Двоичные данные
     
  31. Двоичные данные
     
  32. Двоичные данные
     
  33. Двоичные данные
     
  34. Двоичные данные
     
  35. Двоичные данные
     
  36. Двоичные данные
     
  37. Двоичные данные
     
  38. Двоичные данные
     
  39. Двоичные данные
     
  40. Двоичные данные
     
  41. Двоичные данные
     
  42. Двоичные данные
     
  43. Двоичные данные
     
  44. Двоичные данные
     
  45. Двоичные данные
     
  46. +6
    -0
      reports/bridge-bolt-pick-20260925/index.html
  47. +394
    -0
      reports/bridge-installation-fixes-20260925-007/result.json
  48. Двоичные данные
     
  49. Двоичные данные
     
  50. Двоичные данные
     
  51. Двоичные данные
     
  52. Двоичные данные
     
  53. Двоичные данные
     
  54. Двоичные данные
     
  55. Двоичные данные
     
  56. Двоичные данные
     
  57. Двоичные данные
     
  58. Двоичные данные
     
  59. Двоичные данные
     
  60. +723
    -0
      reports/bridge-installation-fixes-20260925-008/result.json
  61. Двоичные данные
     
  62. Двоичные данные
     
  63. Двоичные данные
     
  64. Двоичные данные
     
  65. Двоичные данные
     
  66. Двоичные данные
     
  67. Двоичные данные
     
  68. Двоичные данные
     
  69. Двоичные данные
     
  70. Двоичные данные
     
  71. Двоичные данные
     
  72. Двоичные данные
     
  73. Двоичные данные
     
  74. Двоичные данные
     
  75. Двоичные данные
     
  76. Двоичные данные
     
  77. Двоичные данные
     
  78. Двоичные данные
     
  79. Двоичные данные
     
  80. +7
    -0
      reports/bridge-installation-fixes-20260925/index.html
  81. +19
    -0
      tools/bridge-bolt-pick-report.mjs
  82. +22
    -0
      tools/bridge-installation-report.mjs
  83. +42
    -1
      tools/bridge-training-safety-live.mjs

+ 328
- 0
reports/bridge-bolt-pick-20260925-007/result.json Просмотреть файл

@@ -0,0 +1,328 @@
{
"pass": true,
"checks": [
{
"task": "88",
"step": 1,
"target": "bridge-engine",
"picked": {
"x": 1015.0000000000001,
"y": 535.7640349787625
}
},
{
"task": "88",
"step": 1,
"check": "wrong tool rejected; Escape leaves poses and progress unchanged"
},
{
"task": "88",
"step": 1,
"target": "bridge-paper",
"picked": {
"x": 1189.9941977014037,
"y": 630.8778892474477
}
},
{
"task": "88",
"step": 1,
"check": "physical tray occupancy",
"stored": [
"bridge-new-pump"
]
},
{
"task": "88",
"step": 2,
"target": "bridge-tank-valve",
"picked": {
"x": 1224.3398889114299,
"y": 630.9457721389707
}
},
{
"task": "88",
"step": 2,
"check": "physical tray occupancy",
"stored": [
"bridge-new-pump"
]
},
{
"task": "88",
"step": 3,
"target": "bridge-inlet",
"picked": {
"x": 1307.2770099242337,
"y": 594.3731653154827
}
},
{
"task": "88",
"step": 3,
"target": "bridge-inlet-bag",
"picked": {
"x": 1249.5,
"y": 631.1324163541328
}
},
{
"task": "88",
"step": 3,
"target": "bridge-outlet",
"picked": {
"x": 1249.5000000000002,
"y": 588.3872583739098
}
},
{
"task": "88",
"step": 3,
"target": "bridge-outlet-bag",
"picked": {
"x": 1249.5,
"y": 631.0649704261706
}
},
{
"task": "88",
"step": 3,
"check": "physical tray occupancy",
"stored": [
"bridge-new-pump"
]
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-1",
"picked": {
"x": 1249.5,
"y": 630.9749404882067
}
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-2",
"picked": {
"x": 1249.5,
"y": 630.9749397374121
}
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-3",
"picked": {
"x": 1249.5,
"y": 630.9749397019398
}
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-4",
"picked": {
"x": 1249.5,
"y": 630.9749404527312
}
},
{
"task": "88",
"step": 4,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 5,
"target": "bridge-old-pump",
"picked": {
"x": 1249.5,
"y": 632.3471269406336
}
},
{
"task": "88",
"step": 5,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-old-pump",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 6,
"target": "bridge-paper",
"picked": {
"x": 1194.435173166285,
"y": 630.874411952604
}
},
{
"task": "88",
"step": 6,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-old-pump",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 7,
"target": "bridge-gasket",
"picked": {
"x": 1249.4999999999995,
"y": 630.8883671945545
}
},
{
"task": "88",
"step": 7,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-old-pump",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 8,
"target": "bridge-new-pump",
"picked": {
"x": 1248.2392765221184,
"y": 632.0568816050143
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-1",
"check": "preparation save preserves placed but untightened bolt"
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-1",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-1",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-1",
"picked": {
"x": 1249.5,
"y": 630.9749404882067
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-2",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-2",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-2",
"picked": {
"x": 1249.5,
"y": 630.9749397374128
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-3",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-3",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-3",
"picked": {
"x": 1249.4999999999998,
"y": 630.97493970194
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-4",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-4",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"check": "503 preserves operation and retry succeeds"
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-4",
"picked": {
"x": 1249.5,
"y": 630.9749404527312
}
},
{
"task": "88",
"step": 8,
"check": "physical tray occupancy",
"stored": [
"bridge-old-pump"
]
}
],
"errors": []
}

Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


+ 717
- 0
reports/bridge-bolt-pick-20260925-008/result.json Просмотреть файл

@@ -0,0 +1,717 @@
{
"pass": true,
"checks": [
{
"task": "89",
"step": 1,
"check": "wrong tool rejected; Escape leaves poses and progress unchanged"
},
{
"task": "89",
"step": 1,
"target": "bridge-small-valve",
"picked": {
"x": 1249.5002412712608,
"y": 630.5777537222049
}
},
{
"task": "89",
"step": 1,
"check": "physical tray occupancy",
"stored": []
},
{
"task": "89",
"step": 2,
"target": "bridge-small-pipe",
"picked": {
"x": 1249.511343546854,
"y": 630.9243461613266
}
},
{
"task": "89",
"step": 2,
"target": "bridge-small-bag",
"picked": {
"x": 1249.5237608216112,
"y": 630.9337561143501
}
},
{
"task": "89",
"step": 2,
"check": "physical tray occupancy",
"stored": []
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-1",
"picked": {
"x": 1249.5001445871621,
"y": 630.411293349843
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-2",
"picked": {
"x": 1249.5001445868954,
"y": 630.4112923318257
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-3",
"picked": {
"x": 1249.5001445869875,
"y": 630.4112922081891
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-4",
"picked": {
"x": 1249.5001445868954,
"y": 630.411292331826
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-valve",
"picked": {
"x": 1231.7693228292756,
"y": 630.5777537222052
}
},
{
"task": "89",
"step": 3,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 4,
"target": "bridge-small-plug-1",
"picked": {
"x": 1249.5225682175646,
"y": 630.8977809163484
}
},
{
"task": "89",
"step": 4,
"target": "bridge-small-plug-2",
"picked": {
"x": 1249.5225682614525,
"y": 630.8977809578514
}
},
{
"task": "89",
"step": 4,
"target": "bridge-small-seat",
"picked": {
"x": 1249.500207959537,
"y": 631.1276696400746
}
},
{
"task": "89",
"step": 4,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 5,
"target": "bridge-large-valve",
"picked": {
"x": 1249.7245792955082,
"y": 630.4104969399293
}
},
{
"task": "89",
"step": 5,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 6,
"target": "bridge-large-pipe",
"picked": {
"x": 1249.512111228889,
"y": 630.9254237627724
}
},
{
"task": "89",
"step": 6,
"target": "bridge-large-bag",
"picked": {
"x": 1249.5238251595379,
"y": 630.9335875212079
}
},
{
"task": "89",
"step": 6,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-1",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530943
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-2",
"picked": {
"x": 1249.5150587486603,
"y": 630.4224337647446
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-3",
"picked": {
"x": 1249.5150587601102,
"y": 630.4224337725875
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-4",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530957
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-valve",
"picked": {
"x": 1249.7245792955082,
"y": 630.4104969399293
}
},
{
"task": "89",
"step": 7,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve",
"bridge-large-bolt-1",
"bridge-large-bolt-2",
"bridge-large-bolt-3",
"bridge-large-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 8,
"target": "bridge-large-plug-1",
"picked": {
"x": 1249.5186577262555,
"y": 630.9003322145043
}
},
{
"task": "89",
"step": 8,
"target": "bridge-large-plug-2",
"picked": {
"x": 1249.5186577469094,
"y": 630.9003322338912
}
},
{
"task": "89",
"step": 8,
"target": "bridge-large-seat",
"picked": {
"x": 1211.9594824120277,
"y": 631.0309038609222
}
},
{
"task": "89",
"step": 8,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve",
"bridge-large-bolt-1",
"bridge-large-bolt-2",
"bridge-large-bolt-3",
"bridge-large-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 9,
"target": "bridge-large-seat",
"picked": {
"x": 1211.9594824120277,
"y": 631.0309038609222
}
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-1",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-1",
"picked": {
"x": 1249.5186577262557,
"y": 630.9003322145035
}
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-2",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-2",
"picked": {
"x": 1249.5186577469103,
"y": 630.9003322338904
}
},
{
"task": "89",
"step": 9,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve",
"bridge-large-bolt-1",
"bridge-large-bolt-2",
"bridge-large-bolt-3",
"bridge-large-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 10,
"target": "bridge-small-valve",
"picked": {
"x": 1249.4145040500296,
"y": 631.0747989773504
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-1",
"check": "preparation save preserves placed but untightened bolt"
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-1",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-1",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-1",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530952
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-2",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-2",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-2",
"picked": {
"x": 1249.5150587486603,
"y": 630.4224337647445
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-3",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-3",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-3",
"picked": {
"x": 1249.5150587601102,
"y": 630.4224337725873
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-4",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-4",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-4",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530957
}
},
{
"task": "89",
"step": 10,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 11,
"target": "bridge-large-bag",
"picked": {
"x": 1249.5238251595379,
"y": 630.9335875212089
}
},
{
"task": "89",
"step": 11,
"target": "bridge-large-pipe",
"picked": {
"x": 1249.5121112288894,
"y": 630.9254237627831
}
},
{
"task": "89",
"step": 11,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-1",
"picked": {
"x": 1249.5278116770771,
"y": 630.2882305760778
}
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-2",
"picked": {
"x": 1249.5278116646073,
"y": 630.2882295301911
}
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-3",
"picked": {
"x": 1249.5278116846418,
"y": 630.2882295365889
}
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-4",
"picked": {
"x": 1249.527811677077,
"y": 630.288230576079
}
},
{
"task": "89",
"step": 12,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 13,
"target": "bridge-small-seat",
"picked": {
"x": 1249.500207959537,
"y": 631.1276696400746
}
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-1",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-1",
"picked": {
"x": 1249.5225682175662,
"y": 630.8977809163456
}
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-2",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-2",
"picked": {
"x": 1249.5225682614544,
"y": 630.8977809578479
}
},
{
"task": "89",
"step": 13,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 14,
"target": "bridge-large-valve",
"picked": {
"x": 1248.6202008477849,
"y": 631.9159210458049
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-1",
"check": "preparation save preserves placed but untightened bolt"
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-1",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-1",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-1",
"picked": {
"x": 1249.5001445871621,
"y": 630.4112933498424
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-2",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-2",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-2",
"picked": {
"x": 1249.5001445868954,
"y": 630.4112923318257
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-3",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-3",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-3",
"picked": {
"x": 1249.500144586988,
"y": 630.4112922081893
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-4",
"check": "bolt remains on workbench until clicked; click places only; tools unlock at hole"
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-4",
"check": "bolt placed by click; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"check": "503 preserves operation and retry succeeds"
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-4",
"picked": {
"x": 1249.500144586895,
"y": 630.4112923318269
}
},
{
"task": "89",
"step": 14,
"check": "physical tray occupancy",
"stored": []
}
],
"errors": []
}

Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


+ 6
- 0
reports/bridge-bolt-pick-20260925/index.html Просмотреть файл

@@ -0,0 +1,6 @@
<!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>螺栓:工作台取件 → 孔位就位 → 扳手紧固</title>
<style>body{margin:0;background:#eef5f2;color:#173f37;font:16px/1.7 system-ui,"Microsoft YaHei",sans-serif}main{max-width:1380px;margin:auto;padding:24px}section,figure{background:white;border:1px solid #ccdfd7;border-radius:12px;padding:20px;margin:18px 0}img{width:100%;height:auto}.pair{display:grid;grid-template-columns:1fr 1fr;gap:14px}h1{line-height:1.4}a{color:#087b65}@media(max-width:900px){.pair{grid-template-columns:1fr}}</style>
<main><h1>螺栓:工作台取件 → 孔位就位 → 扳手紧固</h1><p>2026-09-25 · 本地 6180 / 6100 Gateway · 管理员教员预览 · 1440×900</p>
<section><p>进入回装子操作时,螺栓留在工作台,视角聚焦待取件。点击原螺栓后播放就位动画,随后使用扳手完成紧固。查看标签只聚焦,不移动零件;就位不计为紧固完成。每颗螺栓分别执行这三个阶段。</p><p>保存准备记录、紧固提交失败时保留已就位的状态;允许再次拖入扳手重试。油堵直接拆卸和第 14 步安装面的正面视角继续保留。</p></section>
<section><h2>验证结果</h2><p>007 从第 1 步走到第 8 步,008 从第 1 步走到第 14 步,覆盖全部 12 颗回装螺栓。使用真实模型点击、工具拖放及预览校验接口。检查取件前工具禁用、点击后仍未紧固、保存准备记录后位置保持、最后一颗螺栓提交失败后重试。相关 Node 测试及 pnpm run build 通过。没有创建学员成绩或测试任务。</p><ul><li>007:38 条检查通过,0 个页面脚本错误。<a href="../bridge-bolt-pick-20260925-007/result.json">JSON 记录</a></li><li>008:82 条检查通过,0 个页面脚本错误。<a href="../bridge-bolt-pick-20260925-008/result.json">JSON 记录</a></li></ul></section>
<section><h2>007 第 8 步 · 螺栓 1</h2><div class="pair"><figure><img src="../bridge-bolt-pick-20260925-007/task-88-pick-step-8-bolt-1.png" alt="点击前:工作台取件,工具暂不可用"><figcaption>点击前:工作台取件,工具暂不可用</figcaption></figure><figure><img src="../bridge-bolt-pick-20260925-007/task-88-mount-step-8-bolt-1.png" alt="点击后:安装孔位就位,等待扳手紧固"><figcaption>点击后:安装孔位就位,等待扳手紧固</figcaption></figure></div></section><section><h2>008 第 10 步 · 螺栓 2</h2><div class="pair"><figure><img src="../bridge-bolt-pick-20260925-008/task-89-pick-step-10-bolt-2.png" alt="点击前:工作台取件,工具暂不可用"><figcaption>点击前:工作台取件,工具暂不可用</figcaption></figure><figure><img src="../bridge-bolt-pick-20260925-008/task-89-mount-step-10-bolt-2.png" alt="点击后:安装孔位就位,等待扳手紧固"><figcaption>点击后:安装孔位就位,等待扳手紧固</figcaption></figure></div></section><section><h2>008 第 14 步 · 螺栓 3</h2><div class="pair"><figure><img src="../bridge-bolt-pick-20260925-008/task-89-pick-step-14-bolt-3.png" alt="点击前:工作台取件,工具暂不可用"><figcaption>点击前:工作台取件,工具暂不可用</figcaption></figure><figure><img src="../bridge-bolt-pick-20260925-008/task-89-mount-step-14-bolt-3.png" alt="点击后:安装孔位就位,等待扳手紧固"><figcaption>点击后:安装孔位就位,等待扳手紧固</figcaption></figure></div></section></main></html>

+ 394
- 0
reports/bridge-installation-fixes-20260925-007/result.json Просмотреть файл

@@ -0,0 +1,394 @@
{
"pass": true,
"checks": [
{
"task": "88",
"step": 1,
"target": "bridge-engine",
"picked": {
"x": 1015.0000000000001,
"y": 535.7640349787625
}
},
{
"task": "88",
"step": 1,
"check": "wrong tool rejected; Escape leaves poses and progress unchanged"
},
{
"task": "88",
"step": 1,
"target": "bridge-paper",
"picked": {
"x": 1189.9941977014037,
"y": 630.8778892474477
}
},
{
"task": "88",
"step": 1,
"check": "physical tray occupancy",
"stored": [
"bridge-new-pump"
]
},
{
"task": "88",
"step": 2,
"target": "bridge-tank-valve",
"picked": {
"x": 1224.3398889114299,
"y": 630.9457721389707
}
},
{
"task": "88",
"step": 2,
"check": "physical tray occupancy",
"stored": [
"bridge-new-pump"
]
},
{
"task": "88",
"step": 3,
"target": "bridge-inlet",
"picked": {
"x": 1307.2770099242337,
"y": 594.3731653154827
}
},
{
"task": "88",
"step": 3,
"target": "bridge-inlet-bag",
"picked": {
"x": 1249.5,
"y": 631.1324163541328
}
},
{
"task": "88",
"step": 3,
"target": "bridge-outlet",
"picked": {
"x": 1249.5000000000002,
"y": 588.3872583739098
}
},
{
"task": "88",
"step": 3,
"target": "bridge-outlet-bag",
"picked": {
"x": 1249.5,
"y": 631.0649704261706
}
},
{
"task": "88",
"step": 3,
"check": "physical tray occupancy",
"stored": [
"bridge-new-pump"
]
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-1",
"picked": {
"x": 1249.5,
"y": 630.9749404882067
}
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-2",
"picked": {
"x": 1249.5,
"y": 630.9749397374121
}
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-3",
"picked": {
"x": 1249.5,
"y": 630.9749397019398
}
},
{
"task": "88",
"step": 4,
"target": "bridge-pump-bolt-4",
"picked": {
"x": 1249.5,
"y": 630.9749404527312
}
},
{
"task": "88",
"step": 4,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 5,
"target": "bridge-old-pump",
"picked": {
"x": 1249.5,
"y": 632.3471269406336
}
},
{
"task": "88",
"step": 5,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-old-pump",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 6,
"target": "bridge-paper",
"picked": {
"x": 1194.435173166285,
"y": 630.874411952604
}
},
{
"task": "88",
"step": 6,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-old-pump",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 7,
"target": "bridge-gasket",
"picked": {
"x": 1249.4999999999995,
"y": 630.8883671945545
}
},
{
"task": "88",
"step": 7,
"check": "physical tray occupancy",
"stored": [
"bridge-pump-bolt-1",
"bridge-pump-bolt-2",
"bridge-pump-bolt-3",
"bridge-pump-bolt-4",
"bridge-old-pump",
"bridge-new-pump"
]
},
{
"task": "88",
"step": 8,
"target": "bridge-new-pump",
"picked": {
"x": 1248.2392765221184,
"y": 632.0568816050143
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-1",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-1",
"picked": {
"x": 1249.5,
"y": 630.9749404882067
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-2",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-2",
"picked": {
"x": 1249.5,
"y": 630.9749397374128
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-3",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-3",
"picked": {
"x": 1249.4999999999998,
"y": 630.97493970194
}
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-4",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.008000000000000007
},
{
"task": "88",
"step": 8,
"check": "503 preserves operation and retry succeeds"
},
{
"task": "88",
"step": 8,
"target": "bridge-pump-bolt-4",
"picked": {
"x": 1249.5,
"y": 630.9749404527312
}
},
{
"task": "88",
"step": 8,
"check": "physical tray occupancy",
"stored": [
"bridge-old-pump"
]
},
{
"task": "88",
"step": 9,
"target": "bridge-fill-cap",
"picked": {
"x": 1249.5,
"y": 630.9172747235208
}
},
{
"task": "88",
"step": 9,
"target": "bridge-fill-port",
"picked": {
"x": 1212.4431336221521,
"y": 630.9401402415141
}
},
{
"task": "88",
"step": 9,
"check": "physical tray occupancy",
"stored": [
"bridge-old-pump"
]
},
{
"task": "88",
"step": 10,
"target": "bridge-inlet-bag",
"picked": {
"x": 1249.5,
"y": 631.132416354133
}
},
{
"task": "88",
"step": 10,
"target": "bridge-inlet",
"picked": {
"x": 1307.2770099242337,
"y": 594.3731653154824
}
},
{
"task": "88",
"step": 10,
"target": "bridge-outlet-bag",
"picked": {
"x": 1249.5,
"y": 631.0649704261702
}
},
{
"task": "88",
"step": 10,
"target": "bridge-outlet",
"picked": {
"x": 1249.5,
"y": 588.3872583739098
}
},
{
"task": "88",
"step": 10,
"check": "physical tray occupancy",
"stored": [
"bridge-old-pump"
]
},
{
"task": "88",
"step": 11,
"target": "bridge-engine",
"picked": {
"x": 1249.5,
"y": 631.745172863328
}
},
{
"task": "88",
"step": 11,
"target": "bridge-test-control",
"picked": {
"x": 1249.5,
"y": 631.148312317676
}
},
{
"task": "88",
"step": 11,
"check": "physical tray occupancy",
"stored": [
"bridge-old-pump"
]
}
],
"errors": []
}

Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


+ 723
- 0
reports/bridge-installation-fixes-20260925-008/result.json Просмотреть файл

@@ -0,0 +1,723 @@
{
"pass": true,
"checks": [
{
"task": "89",
"step": 1,
"check": "wrong tool rejected; Escape leaves poses and progress unchanged"
},
{
"task": "89",
"step": 1,
"target": "bridge-small-valve",
"picked": {
"x": 1249.5002412712608,
"y": 630.5777537222049
}
},
{
"task": "89",
"step": 1,
"check": "physical tray occupancy",
"stored": []
},
{
"task": "89",
"step": 2,
"target": "bridge-small-pipe",
"picked": {
"x": 1249.511343546854,
"y": 630.9243461613266
}
},
{
"task": "89",
"step": 2,
"target": "bridge-small-bag",
"picked": {
"x": 1249.5237608216112,
"y": 630.9337561143501
}
},
{
"task": "89",
"step": 2,
"check": "physical tray occupancy",
"stored": []
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-1",
"picked": {
"x": 1249.5001445871621,
"y": 630.411293349843
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-2",
"picked": {
"x": 1249.5001445868954,
"y": 630.4112923318257
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-3",
"picked": {
"x": 1249.5001445869875,
"y": 630.4112922081891
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-bolt-4",
"picked": {
"x": 1249.5001445868954,
"y": 630.411292331826
}
},
{
"task": "89",
"step": 3,
"target": "bridge-small-valve",
"picked": {
"x": 1231.7693228292756,
"y": 630.5777537222052
}
},
{
"task": "89",
"step": 3,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 4,
"target": "bridge-small-plug-1",
"picked": {
"x": 1249.5225682175646,
"y": 630.8977809163484
}
},
{
"task": "89",
"step": 4,
"target": "bridge-small-plug-2",
"picked": {
"x": 1249.5225682614525,
"y": 630.8977809578514
}
},
{
"task": "89",
"step": 4,
"target": "bridge-small-seat",
"picked": {
"x": 1249.500207959537,
"y": 631.1276696400746
}
},
{
"task": "89",
"step": 4,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 5,
"target": "bridge-large-valve",
"picked": {
"x": 1249.7245792955082,
"y": 630.4104969399293
}
},
{
"task": "89",
"step": 5,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 6,
"target": "bridge-large-pipe",
"picked": {
"x": 1249.512111228889,
"y": 630.9254237627724
}
},
{
"task": "89",
"step": 6,
"target": "bridge-large-bag",
"picked": {
"x": 1249.5238251595379,
"y": 630.9335875212079
}
},
{
"task": "89",
"step": 6,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve"
]
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-1",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530943
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-2",
"picked": {
"x": 1249.5150587486603,
"y": 630.4224337647446
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-3",
"picked": {
"x": 1249.5150587601102,
"y": 630.4224337725875
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-bolt-4",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530957
}
},
{
"task": "89",
"step": 7,
"target": "bridge-large-valve",
"picked": {
"x": 1249.7245792955082,
"y": 630.4104969399293
}
},
{
"task": "89",
"step": 7,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve",
"bridge-large-bolt-1",
"bridge-large-bolt-2",
"bridge-large-bolt-3",
"bridge-large-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 8,
"target": "bridge-large-plug-1",
"picked": {
"x": 1249.5186577262555,
"y": 630.9003322145043
}
},
{
"task": "89",
"step": 8,
"target": "bridge-large-plug-2",
"picked": {
"x": 1249.5186577469094,
"y": 630.9003322338912
}
},
{
"task": "89",
"step": 8,
"target": "bridge-large-seat",
"picked": {
"x": 1211.9594824120277,
"y": 631.0309038609222
}
},
{
"task": "89",
"step": 8,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve",
"bridge-large-bolt-1",
"bridge-large-bolt-2",
"bridge-large-bolt-3",
"bridge-large-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 9,
"target": "bridge-large-seat",
"picked": {
"x": 1211.9594824120277,
"y": 631.0309038609222
}
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-1",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-1",
"picked": {
"x": 1249.5186577262557,
"y": 630.9003322145035
}
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-2",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 9,
"target": "bridge-large-plug-2",
"picked": {
"x": 1249.5186577469103,
"y": 630.9003322338904
}
},
{
"task": "89",
"step": 9,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-small-valve",
"bridge-large-bolt-1",
"bridge-large-bolt-2",
"bridge-large-bolt-3",
"bridge-large-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 10,
"target": "bridge-small-valve",
"picked": {
"x": 1249.4145040500296,
"y": 631.0747989773504
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-1",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-1",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530952
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-2",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-2",
"picked": {
"x": 1249.5150587486603,
"y": 630.4224337647445
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-3",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-3",
"picked": {
"x": 1249.5150587601102,
"y": 630.4224337725873
}
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-4",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999936
},
{
"task": "89",
"step": 10,
"target": "bridge-large-bolt-4",
"picked": {
"x": 1249.5150587800808,
"y": 630.4224344530957
}
},
{
"task": "89",
"step": 10,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 11,
"target": "bridge-large-bag",
"picked": {
"x": 1249.5238251595379,
"y": 630.9335875212089
}
},
{
"task": "89",
"step": 11,
"target": "bridge-large-pipe",
"picked": {
"x": 1249.5121112288894,
"y": 630.9254237627831
}
},
{
"task": "89",
"step": 11,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-1",
"picked": {
"x": 1249.5278116770771,
"y": 630.2882305760778
}
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-2",
"picked": {
"x": 1249.5278116646073,
"y": 630.2882295301911
}
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-3",
"picked": {
"x": 1249.5278116846418,
"y": 630.2882295365889
}
},
{
"task": "89",
"step": 12,
"target": "bridge-large-bolt-4",
"picked": {
"x": 1249.527811677077,
"y": 630.288230576079
}
},
{
"task": "89",
"step": 12,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 13,
"target": "bridge-small-seat",
"picked": {
"x": 1249.500207959537,
"y": 631.1276696400746
}
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-1",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-1",
"picked": {
"x": 1249.5225682175662,
"y": 630.8977809163456
}
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-2",
"check": "installed oil plug removed directly"
},
{
"task": "89",
"step": 13,
"target": "bridge-small-plug-2",
"picked": {
"x": 1249.5225682614544,
"y": 630.8977809578479
}
},
{
"task": "89",
"step": 13,
"check": "physical tray occupancy",
"stored": [
"bridge-small-bolt-1",
"bridge-small-bolt-2",
"bridge-small-bolt-3",
"bridge-small-bolt-4",
"bridge-large-valve"
]
},
{
"task": "89",
"step": 14,
"target": "bridge-large-valve",
"picked": {
"x": 1248.6202008477849,
"y": 631.9159210458049
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-1",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-1",
"picked": {
"x": 1249.5001445871621,
"y": 630.4112933498424
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-2",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-2",
"picked": {
"x": 1249.5001445868954,
"y": 630.4112923318257
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-3",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-3",
"picked": {
"x": 1249.500144586988,
"y": 630.4112922081893
}
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-4",
"check": "bolt pre-positioned; tightening unconfirmed; front-facing camera",
"mountingDistance": 0.007999999999999912
},
{
"task": "89",
"step": 14,
"check": "503 preserves operation and retry succeeds"
},
{
"task": "89",
"step": 14,
"target": "bridge-small-bolt-4",
"picked": {
"x": 1249.500144586895,
"y": 630.4112923318269
}
},
{
"task": "89",
"step": 14,
"check": "physical tray occupancy",
"stored": []
},
{
"task": "89",
"step": 15,
"target": "bridge-small-bag",
"picked": {
"x": 1249.5237608216166,
"y": 630.9337561143498
}
},
{
"task": "89",
"step": 15,
"target": "bridge-small-pipe",
"picked": {
"x": 1249.511343546855,
"y": 630.9243461613277
}
},
{
"task": "89",
"step": 15,
"check": "physical tray occupancy",
"stored": []
},
{
"task": "89",
"step": 16,
"target": "bridge-small-bolt-1",
"picked": {
"x": 1249.500215349077,
"y": 630.4769337608634
}
},
{
"task": "89",
"step": 16,
"target": "bridge-small-bolt-2",
"picked": {
"x": 1249.5002153490705,
"y": 630.4769333144791
}
},
{
"task": "89",
"step": 16,
"target": "bridge-small-bolt-3",
"picked": {
"x": 1249.5002153490998,
"y": 630.4769331522325
}
},
{
"task": "89",
"step": 16,
"target": "bridge-small-bolt-4",
"picked": {
"x": 1249.5002153490705,
"y": 630.4769333144793
}
},
{
"task": "89",
"step": 16,
"check": "physical tray occupancy",
"stored": []
}
],
"errors": []
}

Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


+ 7
- 0
reports/bridge-installation-fixes-20260925/index.html Просмотреть файл

@@ -0,0 +1,7 @@
<!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>螺栓安装、油堵拆卸与平衡阀视角修正</title>
<style>body{margin:0;background:#eef5f2;color:#173f37;font:16px/1.75 system-ui,"Microsoft YaHei",sans-serif}main{max-width:1160px;margin:auto;padding:32px 24px}section,figure{background:white;border:1px solid #ccdfd7;border-radius:12px;padding:24px;margin:18px 0}img{width:100%;height:auto}a{color:#087b65}h1{line-height:1.4}figcaption{margin-top:12px}</style>
<main><h1>螺栓安装、油堵拆卸与平衡阀视角修正</h1><p>2026-09-25 · 本地 6180 → 6100 Gateway · 维护账号教员预览 · 真实鼠标点击、工具拖放和服务端预览校验。</p>
<section><h2>完成内容</h2><ul><li>007、008 回装螺栓时,先把当前螺栓从暂存台送到安装孔,再等待学员用扳手紧固。搬运不完成子操作,不生成紧固证据。</li><li>008 第 9、13 步的油堵直接点击或拖动取下;第 4、8 步封堵仍使用工具箱油堵。</li><li>008 两侧螺栓按真实安装面法线设置视角,互换后的阀体跟随目的安装面。被交换阀体遮住的螺栓仍可见、可拾取。</li><li>保存失败恢复到待紧固位置,允许再次使用工具;不改写已发布任务、步骤数量或评分规则。</li></ul></section>
<section><h2>验证</h2><p>相关 Node 自动测试、正式路由契约和前端生产构建通过。007、008 全流程使用正式页面与预览接口;模拟最后一颗安装螺栓保存失败并重试。未创建学员成绩或测试教学任务。</p><ul><li><a href="../bridge-installation-fixes-20260925-007/result.json">bridge-installation-fixes-20260925-007</a>:通过,44 条检查,0 个页面脚本错误。</li><li><a href="../bridge-installation-fixes-20260925-008/result.json">bridge-installation-fixes-20260925-008</a>:通过,80 条检查,0 个页面脚本错误。</li></ul></section>
<figure><img src="../bridge-installation-fixes-20260925-007/task-88-mount-step-8-bolt-1.png" alt="007:新泵安装后的第一颗螺栓,已到孔位,等待拖入扳手。"><figcaption>007:新泵安装后的第一颗螺栓,已到孔位,等待拖入扳手。</figcaption></figure><figure><img src="../bridge-installation-fixes-20260925-008/task-89-mount-step-10-bolt-2.png" alt="008 第 10 步:大腔螺栓在安装位置等待工具,暂存台上的其余零件保持原位。"><figcaption>008 第 10 步:大腔螺栓在安装位置等待工具,暂存台上的其余零件保持原位。</figcaption></figure><figure><img src="../bridge-installation-fixes-20260925-008/task-89-mount-step-14-bolt-3.png" alt="008 第 14 步:第 3 颗小腔螺栓,从安装面正面观察。"><figcaption>008 第 14 步:第 3 颗小腔螺栓,从安装面正面观察。</figcaption></figure>
</main></html>

+ 19
- 0
tools/bridge-bolt-pick-report.mjs Просмотреть файл

@@ -0,0 +1,19 @@
import fs from 'node:fs';
import assert from 'node:assert/strict';

const dir='reports/bridge-bolt-pick-20260925';
const results=['007','008'].map(script=>{
const result=JSON.parse(fs.readFileSync(`${dir}-${script}/result.json`,'utf8'));
assert.equal(result.pass,true,script);
return {script,...result};
});
const figures=[['007','88',8,1],['008','89',10,2],['008','89',14,3]];
for(const [script,id,step,bolt] of figures)for(const phase of ['pick','mount'])assert.ok(fs.existsSync(`${dir}-${script}/task-${id}-${phase}-step-${step}-bolt-${bolt}.png`));
fs.mkdirSync(dir,{recursive:true});
fs.writeFileSync(`${dir}/index.html`,`<!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>螺栓:工作台取件 → 孔位就位 → 扳手紧固</title>
<style>body{margin:0;background:#eef5f2;color:#173f37;font:16px/1.7 system-ui,"Microsoft YaHei",sans-serif}main{max-width:1380px;margin:auto;padding:24px}section,figure{background:white;border:1px solid #ccdfd7;border-radius:12px;padding:20px;margin:18px 0}img{width:100%;height:auto}.pair{display:grid;grid-template-columns:1fr 1fr;gap:14px}h1{line-height:1.4}a{color:#087b65}@media(max-width:900px){.pair{grid-template-columns:1fr}}</style>
<main><h1>螺栓:工作台取件 → 孔位就位 → 扳手紧固</h1><p>2026-09-25 · 本地 6180 / 6100 Gateway · 管理员教员预览 · 1440×900</p>
<section><p>进入回装子操作时,螺栓留在工作台,视角聚焦待取件。点击原螺栓后播放就位动画,随后使用扳手完成紧固。查看标签只聚焦,不移动零件;就位不计为紧固完成。每颗螺栓分别执行这三个阶段。</p><p>保存准备记录、紧固提交失败时保留已就位的状态;允许再次拖入扳手重试。油堵直接拆卸和第 14 步安装面的正面视角继续保留。</p></section>
<section><h2>验证结果</h2><p>007 从第 1 步走到第 8 步,008 从第 1 步走到第 14 步,覆盖全部 12 颗回装螺栓。使用真实模型点击、工具拖放及预览校验接口。检查取件前工具禁用、点击后仍未紧固、保存准备记录后位置保持、最后一颗螺栓提交失败后重试。相关 Node 测试及 pnpm run build 通过。没有创建学员成绩或测试任务。</p><ul>${results.map(r=>`<li>${r.script}:${r.checks.length} 条检查通过,${r.errors.length} 个页面脚本错误。<a href="../bridge-bolt-pick-20260925-${r.script}/result.json">JSON 记录</a></li>`).join('')}</ul></section>
${figures.map(([script,id,step,bolt])=>`<section><h2>${script} 第 ${step} 步 · 螺栓 ${bolt}</h2><div class="pair">${[['pick','点击前:工作台取件,工具暂不可用'],['mount','点击后:安装孔位就位,等待扳手紧固']].map(([phase,title])=>`<figure><img src="../bridge-bolt-pick-20260925-${script}/task-${id}-${phase}-step-${step}-bolt-${bolt}.png" alt="${title}"><figcaption>${title}</figcaption></figure>`).join('')}</div></section>`).join('')}</main></html>`);
console.log(`${dir}/index.html`);

+ 22
- 0
tools/bridge-installation-report.mjs Просмотреть файл

@@ -0,0 +1,22 @@
import fs from 'node:fs';
import assert from 'node:assert/strict';

const dir='reports/bridge-installation-fixes-20260925';
const reports=['bridge-installation-fixes-20260925-007','bridge-installation-fixes-20260925-008'];
const results=reports.map(name=>({name,result:JSON.parse(fs.readFileSync(`reports/${name}/result.json`,'utf8'))}));
for(const {name,result} of results)assert.equal(result.pass,true,name);
fs.mkdirSync(dir,{recursive:true});
const figures=[
['007','88',8,1,'007:新泵安装后的第一颗螺栓,已到孔位,等待拖入扳手。'],
['008','89',10,2,'008 第 10 步:大腔螺栓在安装位置等待工具,暂存台上的其余零件保持原位。'],
['008','89',14,3,'008 第 14 步:第 3 颗小腔螺栓,从安装面正面观察。'],
];
for(const [suffix,id,step,bolt] of figures)assert.ok(fs.existsSync(`reports/bridge-installation-fixes-20260925-${suffix}/task-${id}-mount-step-${step}-bolt-${bolt}.png`));
fs.writeFileSync(`${dir}/index.html`,`<!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>螺栓安装、油堵拆卸与平衡阀视角修正</title>
<style>body{margin:0;background:#eef5f2;color:#173f37;font:16px/1.75 system-ui,"Microsoft YaHei",sans-serif}main{max-width:1160px;margin:auto;padding:32px 24px}section,figure{background:white;border:1px solid #ccdfd7;border-radius:12px;padding:24px;margin:18px 0}img{width:100%;height:auto}a{color:#087b65}h1{line-height:1.4}figcaption{margin-top:12px}</style>
<main><h1>螺栓安装、油堵拆卸与平衡阀视角修正</h1><p>2026-09-25 · 本地 6180 → 6100 Gateway · 维护账号教员预览 · 真实鼠标点击、工具拖放和服务端预览校验。</p>
<section><h2>完成内容</h2><ul><li>007、008 回装螺栓时,先把当前螺栓从暂存台送到安装孔,再等待学员用扳手紧固。搬运不完成子操作,不生成紧固证据。</li><li>008 第 9、13 步的油堵直接点击或拖动取下;第 4、8 步封堵仍使用工具箱油堵。</li><li>008 两侧螺栓按真实安装面法线设置视角,互换后的阀体跟随目的安装面。被交换阀体遮住的螺栓仍可见、可拾取。</li><li>保存失败恢复到待紧固位置,允许再次使用工具;不改写已发布任务、步骤数量或评分规则。</li></ul></section>
<section><h2>验证</h2><p>相关 Node 自动测试、正式路由契约和前端生产构建通过。007、008 全流程使用正式页面与预览接口;模拟最后一颗安装螺栓保存失败并重试。未创建学员成绩或测试教学任务。</p><ul>${results.map(({name,result})=>`<li><a href="../${name}/result.json">${name}</a>:通过,${result.checks.length} 条检查,${result.errors.length} 个页面脚本错误。</li>`).join('')}</ul></section>
${figures.map(([suffix,id,step,bolt,caption])=>`<figure><img src="../bridge-installation-fixes-20260925-${suffix}/task-${id}-mount-step-${step}-bolt-${bolt}.png" alt="${caption}"><figcaption>${caption}</figcaption></figure>`).join('')}
</main></html>`);
console.log(`${dir}/index.html`);

+ 42
- 1
tools/bridge-training-safety-live.mjs Просмотреть файл

@@ -5,7 +5,7 @@ import {login,call} from './role-permissions-live.mjs';
import {finalAcceptance} from './bridge-final-acceptance.mjs';

const fullFlow=process.env.FULL_FLOW==='1';
const dir=(fullFlow?'reports/bridge-final-acceptance-20260924':'reports/bridge-training-safety-20260924')+(process.env.REPORT_SUFFIX||'');fs.mkdirSync(dir,{recursive:true});
const dir=process.env.REPORT_DIR||((fullFlow?'reports/bridge-final-acceptance-20260924':'reports/bridge-training-safety-20260924')+(process.env.REPORT_SUFFIX||''));fs.mkdirSync(dir,{recursive:true});
const session=await login('root'),checks=[],errors=[];
const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']});
const page=await browser.newPage({viewport:{width:Number(process.env.WIDTH)||1440,height:Number(process.env.HEIGHT)||900}});
@@ -24,8 +24,12 @@ await page.route(/\/src\/features\/virtual-training-legacy\/upstream\/views\/tra
}
const roots=(e.publishedContentRoot?.children||[]).map(root=>{let faded=0,opaque=0,changed=0;root.traverse(m=>{if(!m.isMesh||m.userData.trainingPickProxy)return;for(const mat of Array.isArray(m.material)?m.material:[m.material]){if(mat.opacity<.4)faded++;else opaque++;if(mat.opacity!==e.viewerMaterialBaseline.get(mat)?.opacity)changed++;}});return {name:root.name,environment:e.viewerEnvironmentRoots?.has(root),faded,opaque,changed};});
const pose=[...e.parts].map(([id,o])=>({id,p:o.position.toArray(),q:o.quaternion.toArray(),visible:o.visible}));
const activeFront=obj?.userData.trainingInspectionFront,viewDirection=e.camera.position.clone().sub(e.controls.target).normalize();
return {id,tool:e.bridgeTools?.profile,canonicalId:e.getActiveMechanismOperation()?.operation.targetId,step:e.session.stepIndex,operation:e.getActiveMechanismOperation()?.state.index,operationData:e.getActiveMechanismOperation()?.operation,
points,freePoints,box,complete:e.session.currentComplete,pending:e.bridgeOperationPending||e.serverCommitPending,tween:!!e.viewerCameraTween,
mountingDistance:obj?.userData.home?obj.getWorldPosition(new THREE.Vector3()).distanceTo(obj.parent.localToWorld(obj.userData.home.position.clone())):null,
frontAlignment:activeFront?activeFront.dot(viewDirection):null,
needsPlacement:e.bridgePartsWorkbench?.needsPlacement(),
completed:[...e.session.completed],introductionActive:!!e.introductionActive,
camera:e.camera.position.toArray(),target:e.controls.target.toArray(),floor:e.viewerTerrainSurface?.heightAt(e.camera.position.x,e.camera.position.z),roots,pose,
tray:e.bridgePartsWorkbench?.root?{position:e.bridgePartsWorkbench.root.position.toArray(),items:[...e.bridgePartsWorkbench.items.values()].map(item=>{const bounds=new THREE.Box3().setFromObject(item.part,true);return {id:item.id,stored:item.stored,number:item.number,uuid:item.part.uuid,position:item.part.position.toArray(),slot:item.position.toArray(),bottom:bounds.min.y,top:e.bridgePartsWorkbench.layout.position.y};})}:null,
@@ -87,6 +91,42 @@ try{
const ops=step.action.mechanism.steps;
for(let j=0;j<ops.length;j++){
await settle();let d=await snap();assert.equal(d.canonicalId,ops[j].targetId);
if(d.needsPlacement){
const stored=d.tray.items.find(item=>item.id===d.id);
assert.equal(stored.stored,true,'installation starts with the bolt on the workbench');
assert.ok(Math.hypot(...stored.position.map((v,k)=>v-stored.slot[k]))<.00001);
assert.equal(d.tool.trigger,'direct','first phase is picking the bolt, not using a wrench');
await page.locator('[data-role="part-label"]').click();await settle();d=await snap();
assert.equal(d.needsPlacement,true,'focusing alone must not move the bolt');
assert.ok(d.points.length,'workbench bolt is clickable');
if(process.env.CHECK_INSTALLATION==='1'){
assert.equal(await page.locator('[data-bridge-tool]:enabled').count(),0,'tools unavailable until the bolt is placed');
await page.screenshot({path:dir+'/task-'+id+'-pick-step-'+(i+1)+'-bolt-'+j+'.png'});
}
await page.mouse.click(d.points[0].x,d.points[0].y);await settle();d=await snap();
assert.equal(d.needsPlacement,false);assert.equal(d.operation,j,'picking never completes tightening');
assert.equal(d.tool.trigger,'tool-drop','wrench is required after placing the bolt');
if(process.env.CHECK_INSTALLATION==='1'&&j===1){
await page.locator('[data-open-preparation]').click();await page.locator('[data-save-preparation]').click();await page.locator('[data-close-preparation]').click();await settle();d=await snap();
assert.equal(d.needsPlacement,false,'preparation save retains picked placement');
checks.push({task:id,step:i+1,target:d.id,check:'preparation save preserves placed but untightened bolt'});
}
checks.push({task:id,step:i+1,target:d.id,check:'bolt remains on workbench until clicked; click places only; tools unlock at hole'});
}
if(process.env.CHECK_INSTALLATION==='1'){
const installation=(id==='88'&&i===7)||(id==='89'&&[9,13].includes(i));
if(installation&&d.id.includes('-bolt-')){
assert.equal(d.tray.items.find(item=>item.id===d.id).stored,false,'bolt leaves storage before tool use');
assert.ok(Math.abs(d.mountingDistance-.008)<.00001,'bolt is staged at mounting hole before tool use');
assert.equal(d.operation,j,'click placement never completes tightening');assert.ok(!d.complete);
assert.ok(d.frontAlignment>.95,'automatic camera faces mounting plane');
checks.push({task:id,step:i+1,target:d.id,check:'bolt placed by click; tightening unconfirmed; front-facing camera',mountingDistance:d.mountingDistance});
}
if(id==='89'&&[8,12].includes(i)&&d.id.includes('-plug-')){
assert.equal(d.tool.trigger,'direct','plug removal must not require another plug');
checks.push({task:id,step:i+1,target:d.id,check:'installed oil plug removed directly'});
}
}
if(d.tool?.trigger==='tool-drop'){
if(await page.locator('[data-toolbox-toggle]').getAttribute('aria-expanded')==='false')await page.locator('[data-toolbox-toggle]').click();
if(process.env.KEEP_TEACHER==='1'){
@@ -96,6 +136,7 @@ try{
}
await page.locator('[data-role="part-label"]').click();await settle();d=await snap();
assert.ok(d.points.length,'no visible pick point '+id+' step '+(i+1)+' '+d.id);
if(process.env.CHECK_INSTALLATION==='1'&&((id==='89'&&[9,13].includes(i))||(id==='88'&&i===7))&&d.id.includes('-bolt-'))await page.screenshot({path:dir+'/task-'+id+'-mount-step-'+(i+1)+'-bolt-'+j+'.png'});
if(d.tool?.trigger==='tool-drop'&&!testedToolFailure){
testedToolFailure=true;
const wrongId=(await page.locator('[data-bridge-tool]').evaluateAll(nodes=>nodes.map(n=>n.dataset.bridgeTool))).find(key=>key!==d.tool.toolId);


Загрузка…
Отмена
Сохранить