diff --git a/.gitignore b/.gitignore index 64cd3dc..b108561 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ node_modules/ .env.* !.env.example reports/**/build.log +reports/**/*.log +reports/**/capture.webm +**/__pycache__/ reports/**/.last-run.json artifacts/html-report/ artifacts/test-results/ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-005-original-preview.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-005-original-preview.png new file mode 100644 index 0000000..4dc5abc Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-005-original-preview.png differ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-005-reviewed.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-005-reviewed.png new file mode 100644 index 0000000..89b5735 Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-005-reviewed.png differ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-006-original-preview.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-006-original-preview.png new file mode 100644 index 0000000..1e9d74e Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-006-original-preview.png differ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-006-reviewed.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-006-reviewed.png new file mode 100644 index 0000000..edbfd82 Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-006-reviewed.png differ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-007-original-preview.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-007-original-preview.png new file mode 100644 index 0000000..1605ae4 Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-007-original-preview.png differ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-007-reviewed.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-007-reviewed.png new file mode 100644 index 0000000..7e9e618 Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-007-reviewed.png differ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-008-original-preview.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-008-original-preview.png new file mode 100644 index 0000000..5273e79 Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-008-original-preview.png differ diff --git a/reports/bridge-3d-only-20260914/TASK-VIRTUAL-008-reviewed.png b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-008-reviewed.png new file mode 100644 index 0000000..80f9755 Binary files /dev/null and b/reports/bridge-3d-only-20260914/TASK-VIRTUAL-008-reviewed.png differ diff --git a/reports/bridge-3d-only-20260914/acceptance.json b/reports/bridge-3d-only-20260914/acceptance.json new file mode 100644 index 0000000..dca263e --- /dev/null +++ b/reports/bridge-3d-only-20260914/acceptance.json @@ -0,0 +1,43 @@ +{ + "pass": true, + "checks": [ + "正式列表仅四条原任务,005 v2 三维 / 006–008 v3 三维,均为已发布普通训练", + "真实内容接口拒绝旧文字版本,返回 400", + "TASK-VIRTUAL-005 原任务 86 局域网预览加载三维模型与完整工具栏", + "TASK-VIRTUAL-006 原任务 87 局域网预览加载三维模型与完整工具栏", + "TASK-VIRTUAL-007 原任务 88 局域网预览加载三维模型与完整工具栏", + "TASK-VIRTUAL-008 原任务 89 局域网预览加载三维模型与完整工具栏", + "TASK-VIRTUAL-005 刷新恢复服务端步骤及拆装状态", + "TASK-VIRTUAL-005 5 步完成、提交、评定 85 分与统计通过", + "正式 006 保存失败不推进,重试后才保存", + "TASK-VIRTUAL-006 刷新恢复服务端步骤及拆装状态", + "TASK-VIRTUAL-006 7 步完成、提交、评定 85 分与统计通过", + "TASK-VIRTUAL-007 刷新恢复服务端步骤及拆装状态", + "TASK-VIRTUAL-007 11 步完成、提交、评定 85 分与统计通过", + "TASK-VIRTUAL-008 刷新恢复服务端步骤及拆装状态", + "TASK-VIRTUAL-008 16 步完成、提交、评定 85 分与统计通过" + ], + "errors": [], + "runs": [ + { + "taskId": "86", + "runId": "111", + "code": "TASK-VIRTUAL-005" + }, + { + "taskId": "87", + "runId": "112", + "code": "TASK-VIRTUAL-006" + }, + { + "taskId": "88", + "runId": "113", + "code": "TASK-VIRTUAL-007" + }, + { + "taskId": "89", + "runId": "114", + "code": "TASK-VIRTUAL-008" + } + ] +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/cleanup.json b/reports/bridge-3d-only-20260914/cleanup.json new file mode 100644 index 0000000..ae6529a --- /dev/null +++ b/reports/bridge-3d-only-20260914/cleanup.json @@ -0,0 +1,25 @@ +{ + "pass": true, + "removedTestRunIds": [ + 111, + 112, + 113, + 114 + ], + "removedTestMemberUserId": "175", + "keptTaskIds": [ + 86, + 87, + 88, + 89 + ], + "otherRunsUnchanged": true, + "counts": { + "ut_teaching_command_receipt": 149, + "ut_teaching_event": 153, + "ut_teaching_member": 4, + "ut_teaching_run": 4, + "ut_teaching_run_member": 4, + "ut_teaching_step_run": 39 + } +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/final-state.json b/reports/bridge-3d-only-20260914/final-state.json new file mode 100644 index 0000000..eb530df --- /dev/null +++ b/reports/bridge-3d-only-20260914/final-state.json @@ -0,0 +1,93 @@ +{ + "pass": true, + "tasks": [ + { + "id": "86", + "code": "TASK-VIRTUAL-005", + "contentVersionId": "515", + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-switch", + "scriptVersion": "2" + } + }, + { + "id": "87", + "code": "TASK-VIRTUAL-006", + "contentVersionId": "530", + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-substitute", + "scriptVersion": "3" + } + }, + { + "id": "88", + "code": "TASK-VIRTUAL-007", + "contentVersionId": "531", + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-replace", + "scriptVersion": "3" + } + }, + { + "id": "89", + "code": "TASK-VIRTUAL-008", + "contentVersionId": "526", + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-balance-valve-swap", + "scriptVersion": "3" + } + } + ], + "activeContentVersionIds": [ + "515", + "526", + "530", + "531" + ], + "activeRunIds": [ + "101" + ], + "invalidTextVersionsActive": 0, + "probeProjectRemoved": true, + "temporaryUserRemoved": true +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/index.html b/reports/bridge-3d-only-20260914/index.html new file mode 100644 index 0000000..9875a1b --- /dev/null +++ b/reports/bridge-3d-only-20260914/index.html @@ -0,0 +1 @@ +桥梁四流程三维版本生效验收

桥梁四流程 · 三维版本正式生效验收

2026-09-14 · 开发环境 · 127.0.0.1:6180 / 192.168.31.168:6180 · 通过 6100 Gateway。

PASS:文字播放器及兼容分支已移除;四条原任务均进入 HTML+JS 三维工作区。

任务原入口 ID脚本版本内容版本步骤
TASK-VIRTUAL-005 重型支援桥液压泵应急切换8625155
TASK-VIRTUAL-006 重型支援桥液压泵应急替代8735307
TASK-VIRTUAL-007 重型支援桥前泵换件修复88353111
TASK-VIRTUAL-008 重型支援桥平衡阀拆拼互换89352616

005 的 v2 是原三维版本,保留。006–008 只接受 v3,不允许文字版降级。静态 JS 仅决定内容来源,学员训练照常保存进度、提交、评定成绩与统计。

数据修复

经负责人授权,042 软删除错误运行 102、103 及关联事实。006、007 保留原任务编号,通过正式接口发布并绑定新内容版本;无活动引用的错误文字内容版本软删除。005 有效运行保留。修复前备份位于工作区本地目录,未写入此报告。

正式任务闭环验证

管理员预览 + 临时学员直接领取四条原任务。39 步、94 次三维操作,提交后由教员示例评分 85 分,核验学员可见成绩与统计。临时账号、运行、成员及关联数据已清理,四条任务不残留验收成绩。

后端 422 项测试、前端 6 项脚本/模型/路由检查与生产构建通过。

完整验收结果 · 测试数据清理 · Final database state | 正式版本映射

正式入口截图

任务列表仍为四条
TASK-VIRTUAL-005 原任务三维预览
TASK-VIRTUAL-005 学员流程完成与成绩显示(验收数据已清理)
TASK-VIRTUAL-006 原任务三维预览
TASK-VIRTUAL-006 学员流程完成与成绩显示(验收数据已清理)
TASK-VIRTUAL-007 原任务三维预览
TASK-VIRTUAL-007 学员流程完成与成绩显示(验收数据已清理)
TASK-VIRTUAL-008 原任务三维预览
TASK-VIRTUAL-008 学员流程完成与成绩显示(验收数据已清理)
\ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-after-applied.json b/reports/bridge-3d-only-20260914/migration-after-applied.json new file mode 100644 index 0000000..b681432 --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-after-applied.json @@ -0,0 +1,17 @@ +{ + "pass": true, + "phase": "after", + "mode": "applied", + "removedInvalidRunIds": [], + "preservedTaskIds": [ + 86, + 87, + 88, + 89 + ], + "protectedRunsUnchanged": true, + "file": "20260914_042_remove_bridge_text_runs.sql", + "sha256": "dc99112fc5a1a4d255ace2070f78f1fa5d22727834940eb771eb8caed25eb956", + "backupSha256": "d4682145e2c889a374e615fb0373d0044858bb371a033a72cd06f069ad05362d", + "time": "2026-09-14T14:18:50.392498+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-after-check.json b/reports/bridge-3d-only-20260914/migration-after-check.json new file mode 100644 index 0000000..7f3a2dc --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-after-check.json @@ -0,0 +1,16 @@ +{ + "pass": true, + "phase": "after", + "mode": "isolated-check", + "invalidTaskIds": [], + "invalidRunIds": [], + "checks": [ + "isolated first execution", + "full rerun", + "transaction rollback and retry" + ], + "file": "20260914_042_remove_bridge_text_runs.sql", + "sha256": "dc99112fc5a1a4d255ace2070f78f1fa5d22727834940eb771eb8caed25eb956", + "backupSha256": "d4682145e2c889a374e615fb0373d0044858bb371a033a72cd06f069ad05362d", + "time": "2026-09-14T14:18:44.736410+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-before-applied.json b/reports/bridge-3d-only-20260914/migration-before-applied.json new file mode 100644 index 0000000..4f13384 --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-before-applied.json @@ -0,0 +1,20 @@ +{ + "pass": true, + "phase": "before", + "mode": "applied", + "removedInvalidRunIds": [ + 102, + 103 + ], + "preservedTaskIds": [ + 86, + 87, + 88, + 89 + ], + "protectedRunsUnchanged": true, + "file": "20260914_042_remove_bridge_text_runs.sql", + "sha256": "dc99112fc5a1a4d255ace2070f78f1fa5d22727834940eb771eb8caed25eb956", + "backupSha256": "8ee6a6757265a1d57f94898e1b71df2b3b79ecaadbb496d3217bd75a57243889", + "time": "2026-09-14T14:15:32.943690+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-before-check.json b/reports/bridge-3d-only-20260914/migration-before-check.json new file mode 100644 index 0000000..1afba04 --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-before-check.json @@ -0,0 +1,22 @@ +{ + "pass": true, + "phase": "before", + "mode": "isolated-check", + "invalidTaskIds": [ + 87, + 88 + ], + "invalidRunIds": [ + 102, + 103 + ], + "checks": [ + "isolated first execution", + "full rerun", + "transaction rollback and retry" + ], + "file": "20260914_042_remove_bridge_text_runs.sql", + "sha256": "dc99112fc5a1a4d255ace2070f78f1fa5d22727834940eb771eb8caed25eb956", + "backupSha256": "8ee6a6757265a1d57f94898e1b71df2b3b79ecaadbb496d3217bd75a57243889", + "time": "2026-09-14T14:14:37.792217+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-legacy-v1-source-applied.json b/reports/bridge-3d-only-20260914/migration-legacy-v1-source-applied.json new file mode 100644 index 0000000..3847d0e --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-legacy-v1-source-applied.json @@ -0,0 +1,23 @@ +{ + "pass": true, + "phase": "legacy-v1-source", + "mode": "applied", + "removedInvalidRunIds": [], + "removedInvalidVersionIds": [ + 507, + 508, + 509, + 510 + ], + "preservedTaskIds": [ + 86, + 87, + 88, + 89 + ], + "protectedRunsUnchanged": true, + "file": "20260914_044_remove_legacy_bridge_v1_versions.sql", + "sha256": "8ac8b12f9dd35905fb02e5d106e05330a7f3d62adcc16b61bbfe45f8c2971061", + "backupSha256": "fc626af1b43911aad50190504e29b5b1b2694ca0c96e968bad2e776afdb5d139", + "time": "2026-09-14T14:28:55.461264+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-legacy-v1-source-check.json b/reports/bridge-3d-only-20260914/migration-legacy-v1-source-check.json new file mode 100644 index 0000000..efdfe4f --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-legacy-v1-source-check.json @@ -0,0 +1,16 @@ +{ + "pass": true, + "phase": "legacy-v1-source", + "mode": "isolated-check", + "invalidTaskIds": [], + "invalidRunIds": [], + "checks": [ + "isolated first execution", + "full rerun", + "transaction rollback and retry" + ], + "file": "20260914_044_remove_legacy_bridge_v1_versions.sql", + "sha256": "8ac8b12f9dd35905fb02e5d106e05330a7f3d62adcc16b61bbfe45f8c2971061", + "backupSha256": "fc626af1b43911aad50190504e29b5b1b2694ca0c96e968bad2e776afdb5d139", + "time": "2026-09-14T14:28:49.412219+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-v1-history-applied.json b/reports/bridge-3d-only-20260914/migration-v1-history-applied.json new file mode 100644 index 0000000..5b17490 --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-v1-history-applied.json @@ -0,0 +1,18 @@ +{ + "pass": true, + "phase": "v1-history", + "mode": "applied", + "removedInvalidRunIds": [], + "removedInvalidVersionIds": [], + "preservedTaskIds": [ + 86, + 87, + 88, + 89 + ], + "protectedRunsUnchanged": true, + "file": "20260914_043_remove_bridge_v1_text_versions.sql", + "sha256": "c3c91a1357b1e630413592009835010534549f54b174adc59ab43e247d2c5c88", + "backupSha256": "5faeb80539526b9577255487205a16d758dc9d0b9644309e7265e3e329d38c44", + "time": "2026-09-14T14:27:26.804217+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/migration-v1-history-check.json b/reports/bridge-3d-only-20260914/migration-v1-history-check.json new file mode 100644 index 0000000..1c4a3d1 --- /dev/null +++ b/reports/bridge-3d-only-20260914/migration-v1-history-check.json @@ -0,0 +1,16 @@ +{ + "pass": true, + "phase": "v1-history", + "mode": "isolated-check", + "invalidTaskIds": [], + "invalidRunIds": [], + "checks": [ + "isolated first execution", + "full rerun", + "transaction rollback and retry" + ], + "file": "20260914_043_remove_bridge_v1_text_versions.sql", + "sha256": "c3c91a1357b1e630413592009835010534549f54b174adc59ab43e247d2c5c88", + "backupSha256": "5faeb80539526b9577255487205a16d758dc9d0b9644309e7265e3e329d38c44", + "time": "2026-09-14T14:27:16.874458+00:00" +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/registered.json b/reports/bridge-3d-only-20260914/registered.json new file mode 100644 index 0000000..80e7f90 --- /dev/null +++ b/reports/bridge-3d-only-20260914/registered.json @@ -0,0 +1,50 @@ +[ + { + "code": "TASK-VIRTUAL-005", + "id": "86", + "projectId": "438", + "versionId": "515", + "name": "重型支援桥液压泵应急切换", + "scriptId": "bridge-pump-switch", + "scriptVersion": "2", + "steps": 5, + "previewUrl": "/teaching/virtual-training/preview/86", + "presentation": "original-3d" + }, + { + "code": "TASK-VIRTUAL-006", + "id": "87", + "projectId": "439", + "versionId": "530", + "name": "重型支援桥液压泵应急替代", + "scriptId": "bridge-pump-substitute", + "scriptVersion": "3", + "steps": 7, + "previewUrl": "/teaching/virtual-training/preview/87", + "presentation": "original-3d" + }, + { + "code": "TASK-VIRTUAL-007", + "id": "88", + "projectId": "440", + "versionId": "531", + "name": "重型支援桥前泵换件修复", + "scriptId": "bridge-pump-replace", + "scriptVersion": "3", + "steps": 11, + "previewUrl": "/teaching/virtual-training/preview/88", + "presentation": "original-3d" + }, + { + "code": "TASK-VIRTUAL-008", + "id": "89", + "projectId": "441", + "versionId": "526", + "name": "重型支援桥平衡阀拆拼互换", + "scriptId": "bridge-balance-valve-swap", + "scriptVersion": "3", + "steps": 16, + "previewUrl": "/teaching/virtual-training/preview/89", + "presentation": "original-3d" + } +] \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/run-fixtures.json b/reports/bridge-3d-only-20260914/run-fixtures.json new file mode 100644 index 0000000..36b2353 --- /dev/null +++ b/reports/bridge-3d-only-20260914/run-fixtures.json @@ -0,0 +1,25 @@ +{ + "userId": "175", + "runs": [ + { + "taskId": "86", + "runId": "111", + "code": "TASK-VIRTUAL-005" + }, + { + "taskId": "87", + "runId": "112", + "code": "TASK-VIRTUAL-006" + }, + { + "taskId": "88", + "runId": "113", + "code": "TASK-VIRTUAL-007" + }, + { + "taskId": "89", + "runId": "114", + "code": "TASK-VIRTUAL-008" + } + ] +} \ No newline at end of file diff --git a/reports/bridge-3d-only-20260914/task-list.png b/reports/bridge-3d-only-20260914/task-list.png new file mode 100644 index 0000000..f42e659 Binary files /dev/null and b/reports/bridge-3d-only-20260914/task-list.png differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-before.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-before.json new file mode 100644 index 0000000..507bc79 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-before.json @@ -0,0 +1,2363 @@ +{ + "task": { + "id": "86", + "code": "TASK-VIRTUAL-005", + "name": "重型支援桥液压泵应急切换", + "description": "原稿:桥梁/文件2/4.jpg", + "channel": "VIRTUAL", + "assignmentKind": "TRAINING", + "executionMode": "PRACTICE", + "audienceType": "COMMON", + "collaborationMode": "INDIVIDUAL", + "digitalHumanAllowed": false, + "digitalInstructorAgentSlug": "", + "digitalInstructorAgentName": "", + "digitalInstructorKnowledgeSource": "AGENT", + "contentProjectId": "438", + "contentVersionId": "515", + "definitionSnapshot": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥液压泵应急切换", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "架桥车前泵故障互救处置训练(虚拟仿真)", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "架桥车互救操作训练场", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "前泵故障 · 待执行互救处置", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "内置架桥车互救操作训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "架桥车前泵故障互救处置训练场景", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "架桥车前泵故障互救处置训练场景", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "真实整车步骤模型", + "前泵故障互救", + "机构顺序操作" + ], + "sensorFeeds": [] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "front-pump-step-01", + "code": "FRONT-PUMP-STEP-01", + "stepCode": "front-pump-step-01", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-01", + "number": 1, + "title": "根据故障现象确定是哪一个液压泵发生故障", + "targetId": "front-pump-hydraulic-pump", + "targetName": "液压泵", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "guidance": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "warning": "", + "destination": "液压泵", + "success": "根据故障现象确定是哪一个液压泵发生故障", + "cameraPolicy": "exterior", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-hydraulic-pump", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "exterior", + "mechanism": { + "type": "identify", + "axisSpace": "world", + "highlightColor": "#e53935", + "steps": [ + { + "targetId": "front-pump-hydraulic-pump", + "axis": [ + 0, + 1, + 0 + ], + "toleranceDegrees": 6, + "directionHint": "点击并确认发生故障的液压泵" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-hydraulic-pump", + "targetNodeName": "1液压泵", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-02", + "code": "FRONT-PUMP-STEP-02", + "stepCode": "front-pump-step-02", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-02", + "number": 2, + "title": "断开架桥车取力器", + "targetId": "front-pump-pto-switch", + "targetName": "取力器开关", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "guidance": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "warning": "", + "destination": "取力器开关", + "success": "断开架桥车取力器", + "cameraPolicy": "exterior", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-pto-switch", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "exterior", + "mechanism": { + "type": "rotate", + "axisSpace": "world", + "visualTargetIds": [ + "front-pump-power-take-off" + ], + "steps": [ + { + "targetId": "front-pump-pto-switch", + "axis": [ + 1, + 0, + 0 + ], + "deltaDegrees": -30, + "toleranceDegrees": 6, + "directionHint": "向断开方向摇动" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-pto-switch", + "targetNodeName": "2取力器开关", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-03", + "code": "FRONT-PUMP-STEP-03", + "stepCode": "front-pump-step-03", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-03", + "number": 3, + "title": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "targetId": "front-pump-ball-valve-switch", + "targetName": "球阀开关", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "guidance": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "warning": "", + "destination": "球阀开关", + "success": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-ball-valve-switch", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "focus", + "mechanism": { + "type": "rotate", + "axisSpace": "world", + "steps": [ + { + "targetId": "front-pump-ball-valve-switch", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "由垂直与官道方向旋转至平行于管道方向" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-ball-valve-switch", + "targetNodeName": "3球阀开关", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-04", + "code": "FRONT-PUMP-STEP-04", + "stepCode": "front-pump-step-04", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-04", + "number": 4, + "title": "重新联通取力器", + "targetId": "front-pump-pto-switch", + "targetName": "取力器开关", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "guidance": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "warning": "", + "destination": "取力器开关", + "success": "重新联通取力器", + "cameraPolicy": "exterior", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-pto-switch", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "exterior", + "mechanism": { + "type": "rotate", + "axisSpace": "world", + "visualTargetIds": [ + "front-pump-power-take-off" + ], + "steps": [ + { + "targetId": "front-pump-pto-switch", + "axis": [ + 1, + 0, + 0 + ], + "deltaDegrees": 30, + "toleranceDegrees": 6, + "directionHint": "按步骤2的相反方向摇回去" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-pto-switch", + "targetNodeName": "2取力器开关", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-05", + "code": "FRONT-PUMP-STEP-05", + "stepCode": "front-pump-step-05", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-05", + "number": 5, + "title": "打开辅助控制盒内的“互救”开关", + "targetId": "front-pump-aux-control-box-cover", + "targetName": "辅助控制盒盖", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "guidance": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "warning": "", + "destination": "辅助控制盒盖", + "success": "打开辅助控制盒内的“互救”开关", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-aux-control-box-cover", + "mode": "inspect", + "durationMs": 1600, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "focus", + "mechanism": { + "type": "sequence", + "axisSpace": "world", + "visualTargetIds": [ + "front-pump-aux-control-box" + ], + "steps": [ + { + "targetId": "front-pump-aux-control-box-cover", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 100, + "toleranceDegrees": 8, + "directionHint": "沿控制盒盖边缘铰链打开", + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + } + }, + { + "targetId": "front-pump-rescue-switch", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 30, + "toleranceDegrees": 6, + "directionHint": "往上搬" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-aux-control-box-cover", + "targetNodeName": "5辅助控制盒盖", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-switch", + "scriptVersion": "2" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/4.jpg" + }, + "definitionChecksum": "39f1f03c1888a80a441e7b163a7d1612525cf0d54dc222198d9c7aab2d6fecfb", + "ownerUserId": "99", + "ownerUsername": "root", + "ownerName": "内部维护", + "departmentId": "1", + "departmentName": "", + "status": "PUBLISHED", + "scheduleStartAt": null, + "dueAt": null, + "publishedAt": 1789311584, + "withdrawnAt": 1789311583, + "archivedAt": null, + "lifecycleReason": "发布教学任务", + "version": 4, + "addTime": 1789309630, + "updateTime": "2026-09-13T22:27:11", + "serverNow": 1789398484, + "members": [ + { + "id": "169", + "userId": "99", + "username": "root", + "displayName": "内部维护", + "departmentId": "1", + "departmentName": "", + "memberType": "LEARNER", + "roleCode": "LEARNER", + "teamCode": "NEUTRAL", + "groupCode": "INDIVIDUAL", + "positionCode": "LEARNER", + "stationCode": "", + "sortOrder": 0, + "version": 0 + } + ], + "runCount": 1, + "pendingReviewCount": 0 + }, + "detail": { + "project": { + "id": "438", + "type": "TRAINING", + "code": "TRAINING-691D079D73724910", + "name": "重型支援桥液压泵应急切换", + "description": "原稿:桥梁/文件2/4.jpg", + "categoryCode": "MAINTENANCE", + "trainingMode": "VIRTUAL", + "coverUri": "", + "status": "PUBLISHED", + "ownerUserId": "99", + "ownerName": "内部维护", + "departmentId": "1", + "currentVersionId": "515", + "currentVersionNo": 2, + "currentVersionCode": "V2.0.0", + "publishedVersionId": "515", + "publishedTime": 1789311583, + "usageCount": 0, + "version": 4, + "addTime": 1789309629, + "updateTime": "2026-09-13T22:59:43", + "contentSummary": { + "schema": "digital-workshop-training-project", + "trainingMode": "VIRTUAL", + "stepCount": 5 + }, + "currentVersionStatus": "PUBLISHED", + "dependencyCount": 0, + "assetCount": 0, + "readCount": 0, + "downloadCount": 0 + }, + "currentVersion": { + "id": "515", + "projectId": "438", + "versionNo": 2, + "versionCode": "V2.0.0", + "status": "PUBLISHED", + "content": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥液压泵应急切换", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "架桥车前泵故障互救处置训练(虚拟仿真)", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "架桥车互救操作训练场", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "前泵故障 · 待执行互救处置", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "内置架桥车互救操作训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "架桥车前泵故障互救处置训练场景", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "架桥车前泵故障互救处置训练场景", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "真实整车步骤模型", + "前泵故障互救", + "机构顺序操作" + ], + "sensorFeeds": [] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "front-pump-step-01", + "code": "FRONT-PUMP-STEP-01", + "stepCode": "front-pump-step-01", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-01", + "number": 1, + "title": "根据故障现象确定是哪一个液压泵发生故障", + "targetId": "front-pump-hydraulic-pump", + "targetName": "液压泵", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "guidance": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "warning": "", + "destination": "液压泵", + "success": "根据故障现象确定是哪一个液压泵发生故障", + "cameraPolicy": "exterior", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-hydraulic-pump", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "exterior", + "mechanism": { + "type": "identify", + "axisSpace": "world", + "highlightColor": "#e53935", + "steps": [ + { + "targetId": "front-pump-hydraulic-pump", + "axis": [ + 0, + 1, + 0 + ], + "toleranceDegrees": 6, + "directionHint": "点击并确认发生故障的液压泵" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-hydraulic-pump", + "targetNodeName": "1液压泵", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-02", + "code": "FRONT-PUMP-STEP-02", + "stepCode": "front-pump-step-02", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-02", + "number": 2, + "title": "断开架桥车取力器", + "targetId": "front-pump-pto-switch", + "targetName": "取力器开关", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "guidance": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "warning": "", + "destination": "取力器开关", + "success": "断开架桥车取力器", + "cameraPolicy": "exterior", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-pto-switch", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "exterior", + "mechanism": { + "type": "rotate", + "axisSpace": "world", + "visualTargetIds": [ + "front-pump-power-take-off" + ], + "steps": [ + { + "targetId": "front-pump-pto-switch", + "axis": [ + 1, + 0, + 0 + ], + "deltaDegrees": -30, + "toleranceDegrees": 6, + "directionHint": "向断开方向摇动" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-pto-switch", + "targetNodeName": "2取力器开关", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-03", + "code": "FRONT-PUMP-STEP-03", + "stepCode": "front-pump-step-03", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-03", + "number": 3, + "title": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "targetId": "front-pump-ball-valve-switch", + "targetName": "球阀开关", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "guidance": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "warning": "", + "destination": "球阀开关", + "success": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-ball-valve-switch", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "focus", + "mechanism": { + "type": "rotate", + "axisSpace": "world", + "steps": [ + { + "targetId": "front-pump-ball-valve-switch", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "由垂直与官道方向旋转至平行于管道方向" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-ball-valve-switch", + "targetNodeName": "3球阀开关", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-04", + "code": "FRONT-PUMP-STEP-04", + "stepCode": "front-pump-step-04", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-04", + "number": 4, + "title": "重新联通取力器", + "targetId": "front-pump-pto-switch", + "targetName": "取力器开关", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "guidance": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "warning": "", + "destination": "取力器开关", + "success": "重新联通取力器", + "cameraPolicy": "exterior", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-pto-switch", + "mode": "inspect", + "durationMs": 900, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "exterior", + "mechanism": { + "type": "rotate", + "axisSpace": "world", + "visualTargetIds": [ + "front-pump-power-take-off" + ], + "steps": [ + { + "targetId": "front-pump-pto-switch", + "axis": [ + 1, + 0, + 0 + ], + "deltaDegrees": 30, + "toleranceDegrees": 6, + "directionHint": "按步骤2的相反方向摇回去" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-pto-switch", + "targetNodeName": "2取力器开关", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + }, + { + "id": "front-pump-step-05", + "code": "FRONT-PUMP-STEP-05", + "stepCode": "front-pump-step-05", + "actionCode": "COMPLETE_FRONT-PUMP-STEP-05", + "number": 5, + "title": "打开辅助控制盒内的“互救”开关", + "targetId": "front-pump-aux-control-box-cover", + "targetName": "辅助控制盒盖", + "targetRef": { + "sceneId": "front-pump-rescue-vehicle", + "sceneObjectId": "front-pump-rescue-vehicle", + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "guidance": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "warning": "", + "destination": "辅助控制盒盖", + "success": "打开辅助控制盒内的“互救”开关", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-aux-control-box-cover", + "mode": "inspect", + "durationMs": 1600, + "tolerance": 0, + "requiresPlacement": false, + "cameraPolicy": "focus", + "mechanism": { + "type": "sequence", + "axisSpace": "world", + "visualTargetIds": [ + "front-pump-aux-control-box" + ], + "steps": [ + { + "targetId": "front-pump-aux-control-box-cover", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 100, + "toleranceDegrees": 8, + "directionHint": "沿控制盒盖边缘铰链打开", + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + } + }, + { + "targetId": "front-pump-rescue-switch", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 30, + "toleranceDegrees": 6, + "directionHint": "往上搬" + } + ] + } + }, + "toolId": "", + "targetNodeId": "front-pump-aux-control-box-cover", + "targetNodeName": "5辅助控制盒盖", + "measurement": "", + "audio": { + "narrationSource": "offline", + "narrationText": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "narrationUrl": "", + "safetyText": "", + "safetyUrl": "", + "successCue": "ui", + "errorCue": "collision-error" + }, + "faultIds": [], + "assessment": { + "weight": 20, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-switch", + "scriptVersion": "2" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/4.jpg" + }, + "changeSummary": "脚本来源 v2:复用正式教学运行、步骤记录与成绩评定", + "checksum": "39f1f03c1888a80a441e7b163a7d1612525cf0d54dc222198d9c7aab2d6fecfb", + "createdByUserId": "99", + "createdByName": "内部维护", + "publishedByUserId": "99", + "publishedByName": "内部维护", + "publishedTime": 1789311583, + "version": 2, + "addTime": 1789311583, + "updateTime": "2026-09-13T22:59:43", + "dependencies": [], + "assets": [] + } + }, + "runs": { + "records": [ + { + "id": "101", + "code": "RUN-5B95504E15154D1CA762", + "assignmentId": "86", + "memberId": "169", + "subjectType": "MEMBER", + "subjectCode": "169", + "attemptNo": 1, + "status": "IN_PROGRESS", + "progressPercent": 0, + "currentStepCode": "front-pump-step-01", + "checkpoint": { + "schema": "teaching-run-checkpoint/1", + "elapsedSeconds": 0, + "errors": 0, + "hints": 0, + "operations": 0, + "completedStepCodes": [], + "confirmedSafetyKeys": [], + "selectedToolId": "", + "selectedToolIds": [], + "activeStepCode": "front-pump-step-01", + "measurementNote": "", + "stepResults": [], + "processRecords": [ + { + "id": "record-1789313945735-3b15e", + "time": "2026-09-13T15:39:05.735Z", + "type": "info", + "stepCode": "front-pump-step-01", + "stepNumber": 1, + "title": "训练任务已开始", + "detail": "重型支援桥液压泵应急切换 · 训练模式" + } + ], + "updatedAt": "2026-09-13T15:39:05.639Z" + }, + "automaticResult": {}, + "submission": {}, + "score": null, + "passed": null, + "reviewFeedback": "", + "reviewRubric": {}, + "acceptedAt": 1789313944, + "startedAt": 1789313945, + "submittedAt": null, + "reviewedAt": null, + "reviewedByUserId": null, + "reviewerName": "", + "archivedAt": null, + "version": 3, + "addTime": 1789313943, + "updateTime": "2026-09-13T23:39:04", + "assignment": { + "id": "86", + "code": "TASK-VIRTUAL-005", + "name": "重型支援桥液压泵应急切换", + "channel": "VIRTUAL", + "assignmentKind": "TRAINING", + "executionMode": "PRACTICE", + "audienceType": "COMMON", + "collaborationMode": "INDIVIDUAL", + "digitalHumanAllowed": false, + "digitalInstructorAgentSlug": "", + "digitalInstructorAgentName": "", + "digitalInstructorKnowledgeSource": "AGENT", + "status": "PUBLISHED", + "scheduleStartAt": null, + "dueAt": null, + "serverNow": 1789398485 + }, + "member": { + "id": "169", + "userId": "99", + "username": "root", + "displayName": "内部维护", + "departmentId": "1", + "departmentName": "", + "memberType": "LEARNER", + "roleCode": "LEARNER", + "teamCode": "NEUTRAL", + "groupCode": "INDIVIDUAL", + "positionCode": "LEARNER", + "stationCode": "", + "sortOrder": 0, + "version": 0 + }, + "members": [ + { + "id": "169", + "userId": "99", + "username": "root", + "displayName": "内部维护", + "departmentId": "1", + "departmentName": "", + "memberType": "LEARNER", + "roleCode": "LEARNER", + "teamCode": "NEUTRAL", + "groupCode": "INDIVIDUAL", + "positionCode": "LEARNER", + "stationCode": "", + "sortOrder": 0, + "version": 0 + } + ] + } + ], + "total": 1, + "page": 1, + "size": 100 + } +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-binding.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-binding.json new file mode 100644 index 0000000..52a1305 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-binding.json @@ -0,0 +1,95 @@ +{ + "code": "TASK-VIRTUAL-005", + "taskId": "86", + "contentVersionId": "533", + "clips": [ + { + "stepCode": "front-pump-step-01", + "videoAssetCode": "DH_FF17FDE117E94B80BB30DF3E058821FD" + }, + { + "stepCode": "front-pump-step-02", + "videoAssetCode": "DH_6E75DADE9D0649DCA16A2499D1EE8776" + }, + { + "stepCode": "front-pump-step-03", + "videoAssetCode": "DH_9A4629F90E614E60835441B5D0AAE86C" + }, + { + "stepCode": "front-pump-step-04", + "videoAssetCode": "DH_DA42FE5C995F4C67A559E6E94DB1C440" + }, + { + "stepCode": "front-pump-step-05", + "videoAssetCode": "DH_D85C34259BB34E0C966C5A79569DBF10" + } + ], + "runsUnchanged": true, + "assets": [ + { + "sourceProjectId": "438", + "sourceVersionId": "533", + "assetCode": "DH_FF17FDE117E94B80BB30DF3E058821FD", + "name": "重型支援桥液压泵应急切换 · 1 根据故障现象确定是哪一个液压泵发生故障", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/f14a6784aeb6457a16f86387b4e701d2.mp4", + "mimeType": "video/mp4", + "sizeBytes": 202274, + "sha256": "d5c992479f2893d3efbe20921dab1f82fcc8ab4c4f512477fe4e0ea636e8fb7f", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/86/assets/533/DH_FF17FDE117E94B80BB30DF3E058821FD/content" + }, + { + "sourceProjectId": "438", + "sourceVersionId": "533", + "assetCode": "DH_6E75DADE9D0649DCA16A2499D1EE8776", + "name": "重型支援桥液压泵应急切换 · 2 断开架桥车取力器", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/57c38aeae43b965404d45bb45824588e.mp4", + "mimeType": "video/mp4", + "sizeBytes": 172936, + "sha256": "69ae89ec5e3d4a5ccd3efce23f33707ee4b3a236b398235ad133ee34f793a9ba", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/86/assets/533/DH_6E75DADE9D0649DCA16A2499D1EE8776/content" + }, + { + "sourceProjectId": "438", + "sourceVersionId": "533", + "assetCode": "DH_9A4629F90E614E60835441B5D0AAE86C", + "name": "重型支援桥液压泵应急切换 · 3 将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/1a7dfbfaefc3cb5859287a953de92d89.mp4", + "mimeType": "video/mp4", + "sizeBytes": 587353, + "sha256": "c9ac26a8d58e52d7dc57c28b1c6f9134de780f65b29e1eef1e8351eb51753758", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/86/assets/533/DH_9A4629F90E614E60835441B5D0AAE86C/content" + }, + { + "sourceProjectId": "438", + "sourceVersionId": "533", + "assetCode": "DH_DA42FE5C995F4C67A559E6E94DB1C440", + "name": "重型支援桥液压泵应急切换 · 4 重新联通取力器", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/024978af4939a2adbd3be834ef62e29b.mp4", + "mimeType": "video/mp4", + "sizeBytes": 162678, + "sha256": "383d1fe0a6a80112c7b8868ae1edfdbeadbc86c13ce6feec1a9721ba3d9881fe", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/86/assets/533/DH_DA42FE5C995F4C67A559E6E94DB1C440/content" + }, + { + "sourceProjectId": "438", + "sourceVersionId": "533", + "assetCode": "DH_D85C34259BB34E0C966C5A79569DBF10", + "name": "重型支援桥液压泵应急切换 · 5 打开辅助控制盒内的“互救”开关", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/2c20f201cb7c9663b751e485990de355.mp4", + "mimeType": "video/mp4", + "sizeBytes": 285991, + "sha256": "2d53c0bef4d8aa71d8b8535de676d2d8485929de06534ce3aab677805bc8eef3", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/86/assets/533/DH_D85C34259BB34E0C966C5A79569DBF10/content" + } + ] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-01.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-01.mp4 new file mode 100644 index 0000000..fe66d56 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-01.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-02.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-02.mp4 new file mode 100644 index 0000000..1909325 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-02.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-03.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-03.mp4 new file mode 100644 index 0000000..cce6315 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-03.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-04.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-04.mp4 new file mode 100644 index 0000000..bd9bcef Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-04.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-05.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-05.mp4 new file mode 100644 index 0000000..a7d1762 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-05.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-video.png b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-video.png new file mode 100644 index 0000000..906238b Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-video.png differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-before.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-before.json new file mode 100644 index 0000000..d79c094 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-before.json @@ -0,0 +1,2355 @@ +{ + "task": { + "id": "87", + "code": "TASK-VIRTUAL-006", + "name": "重型支援桥液压泵应急替代", + "description": "原稿:桥梁/文件2/5.jpg、6.jpg", + "channel": "VIRTUAL", + "assignmentKind": "TRAINING", + "executionMode": "PRACTICE", + "audienceType": "COMMON", + "collaborationMode": "INDIVIDUAL", + "digitalHumanAllowed": false, + "digitalInstructorAgentSlug": "", + "digitalInstructorAgentName": "", + "digitalInstructorKnowledgeSource": "AGENT", + "contentProjectId": "439", + "contentVersionId": "530", + "definitionSnapshot": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥液压泵应急替代", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "重型支援桥液压泵应急替代", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "重型支援桥液压泵应急替代", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "整车模型 · 补充拆装件为操作示意", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "桥梁脚本三维训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "重型支援桥液压泵应急替代", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "重型支援桥液压泵应急替代", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 11, + 8, + 16 + ], + "target": [ + 0, + 1.5, + 2 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "整车模型", + "补充操作示意", + "机构顺序操作" + ], + "sensorFeeds": [], + "name": "重型支援桥液压泵应急替代", + "title": "重型支援桥液压泵应急替代", + "operableParts": [ + "bridge-engine", + "front-pump-pto-switch", + "bridge-hose-a", + "bridge-hose-b", + "bridge-return-valve", + "front-pump-aux-control-box-cover", + "front-pump-rescue-switch", + "front-pump-ball-valve-switch", + "bridge-support-pto", + "bridge-supply", + "bridge-normal-control" + ] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "BRIDGE-STEP-1", + "stepCode": "BRIDGE-STEP-1", + "actionCode": "COMPLETE_BRIDGE-STEP-1", + "number": 1, + "title": "保持架桥车运行并断开取力器", + "targetId": "bridge-engine", + "targetName": "保持架桥车发动机运行", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "guidance": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "warning": "", + "success": "保持架桥车运行并断开取力器:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-engine", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "保持架桥车发动机运行", + "effects": [ + { + "targetId": "bridge-engine", + "color": 2209160 + } + ] + }, + { + "targetId": "front-pump-pto-switch", + "kind": "rotate", + "axis": [ + 1, + 0, + 0 + ], + "deltaDegrees": -30, + "toleranceDegrees": 8, + "directionHint": "断开架桥车取力器" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-2", + "stepCode": "BRIDGE-STEP-2", + "actionCode": "COMPLETE_BRIDGE-STEP-2", + "number": 2, + "title": "连接两车液压软管", + "targetId": "bridge-hose-a", + "targetName": "连接架桥车快速接头", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "guidance": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "warning": "", + "success": "连接两车液压软管:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-hose-a", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-hose-a", + "kind": "identify", + "directionHint": "连接架桥车快速接头", + "effects": [ + { + "targetId": "bridge-hose-a", + "offset": [ + 0, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-hose-line", + "visible": true + } + ] + }, + { + "targetId": "bridge-hose-b", + "kind": "identify", + "directionHint": "连接保障车快速接头", + "effects": [ + { + "targetId": "bridge-hose-b", + "offset": [ + 0, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-return-line", + "visible": true + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-3", + "stepCode": "BRIDGE-STEP-3", + "actionCode": "COMPLETE_BRIDGE-STEP-3", + "number": 3, + "title": "打开支援车回油截止阀", + "targetId": "bridge-return-valve", + "targetName": "打开保障车回油截止阀", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开支援车液压油箱快接接头处的回油截止阀。", + "guidance": "打开支援车液压油箱快接接头处的回油截止阀。", + "warning": "", + "success": "打开支援车回油截止阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-return-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "rotate", + "steps": [ + { + "targetId": "bridge-return-valve", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "打开保障车回油截止阀" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开支援车液压油箱快接接头处的回油截止阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-4", + "stepCode": "BRIDGE-STEP-4", + "actionCode": "COMPLETE_BRIDGE-STEP-4", + "number": 4, + "title": "打开互救作业开关", + "targetId": "front-pump-aux-control-box-cover", + "targetName": "打开辅助控制盒盖", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开辅助控制盒上的“互救作业”开关。", + "guidance": "打开辅助控制盒上的“互救作业”开关。", + "warning": "", + "success": "打开互救作业开关:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-aux-control-box-cover", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "front-pump-aux-control-box-cover", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "deltaDegrees": 100, + "toleranceDegrees": 8, + "directionHint": "打开辅助控制盒盖" + }, + { + "targetId": "front-pump-rescue-switch", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 30, + "toleranceDegrees": 8, + "directionHint": "打开互救作业开关" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开辅助控制盒上的“互救作业”开关。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-5", + "stepCode": "BRIDGE-STEP-5", + "actionCode": "COMPLETE_BRIDGE-STEP-5", + "number": 5, + "title": "打开滤油器出口连通球阀", + "targetId": "front-pump-ball-valve-switch", + "targetName": "打开滤油器出口连通球阀", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开两个输油滤油器出口处的连通球阀。", + "guidance": "打开两个输油滤油器出口处的连通球阀。", + "warning": "", + "success": "打开滤油器出口连通球阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-ball-valve-switch", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "rotate", + "steps": [ + { + "targetId": "front-pump-ball-valve-switch", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "打开滤油器出口连通球阀" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开两个输油滤油器出口处的连通球阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-6", + "stepCode": "BRIDGE-STEP-6", + "actionCode": "COMPLETE_BRIDGE-STEP-6", + "number": 6, + "title": "接通支援车液压取力器", + "targetId": "bridge-support-pto", + "targetName": "接通保障车取力器", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "接通支援车液压系统取力器,向架桥车供油。", + "guidance": "接通支援车液压系统取力器,向架桥车供油。", + "warning": "", + "success": "接通支援车液压取力器:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-support-pto", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-support-pto", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 30, + "toleranceDegrees": 8, + "directionHint": "接通保障车取力器" + }, + { + "targetId": "bridge-supply", + "kind": "identify", + "directionHint": "观察供油示意", + "effects": [ + { + "targetId": "bridge-hose-line", + "color": 15312947 + }, + { + "targetId": "bridge-return-line", + "color": 3325905 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "接通支援车液压系统取力器,向架桥车供油。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-7", + "stepCode": "BRIDGE-STEP-7", + "actionCode": "COMPLETE_BRIDGE-STEP-7", + "number": 7, + "title": "按正常步骤操作架桥车", + "targetId": "bridge-normal-control", + "targetName": "操作正常作业控制手柄", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "guidance": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "warning": "该项为原稿概括项,本预演不代表后续正常作业已经完成。", + "success": "按正常步骤操作架桥车:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-normal-control", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-normal-control", + "kind": "identify", + "directionHint": "操作正常作业控制手柄", + "effects": [ + { + "targetId": "bridge-normal-control", + "offset": [ + 0, + 0, + -0.25 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "successCue": "ui", + "errorCue": "collision-error" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-substitute", + "scriptVersion": "3" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/5.jpg、6.jpg" + }, + "definitionChecksum": "e9de65c84fde072727cca1a96dd7b25bd694129ba3f64c49f1f8dde7fe085d2e", + "ownerUserId": "99", + "ownerUsername": "root", + "ownerName": "内部维护", + "departmentId": "1", + "departmentName": "", + "status": "PUBLISHED", + "scheduleStartAt": null, + "dueAt": null, + "publishedAt": 1789395441, + "withdrawnAt": 1789395440, + "archivedAt": null, + "lifecycleReason": "发布教学任务", + "version": 7, + "addTime": 1789309631, + "updateTime": "2026-09-13T22:27:12", + "serverNow": 1789398507, + "members": [], + "runCount": 0, + "pendingReviewCount": 0 + }, + "detail": { + "project": { + "id": "439", + "type": "TRAINING", + "code": "TRAINING-439DE936E7CF4371", + "name": "重型支援桥液压泵应急替代", + "description": "原稿:桥梁/文件2/5.jpg、6.jpg", + "categoryCode": "MAINTENANCE", + "trainingMode": "VIRTUAL", + "coverUri": "", + "status": "PUBLISHED", + "ownerUserId": "99", + "ownerName": "内部维护", + "departmentId": "1", + "currentVersionId": "530", + "currentVersionNo": 3, + "currentVersionCode": "V3.0.0", + "publishedVersionId": "530", + "publishedTime": 1789395441, + "usageCount": 0, + "version": 6, + "addTime": 1789309630, + "updateTime": "2026-09-14T22:17:21", + "contentSummary": { + "schema": "digital-workshop-training-project", + "trainingMode": "VIRTUAL", + "stepCount": 7 + }, + "currentVersionStatus": "PUBLISHED", + "dependencyCount": 0, + "assetCount": 0, + "readCount": 0, + "downloadCount": 0 + }, + "currentVersion": { + "id": "530", + "projectId": "439", + "versionNo": 3, + "versionCode": "V3.0.0", + "status": "PUBLISHED", + "content": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥液压泵应急替代", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "重型支援桥液压泵应急替代", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "重型支援桥液压泵应急替代", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "整车模型 · 补充拆装件为操作示意", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "桥梁脚本三维训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "重型支援桥液压泵应急替代", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "重型支援桥液压泵应急替代", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 11, + 8, + 16 + ], + "target": [ + 0, + 1.5, + 2 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "整车模型", + "补充操作示意", + "机构顺序操作" + ], + "sensorFeeds": [], + "name": "重型支援桥液压泵应急替代", + "title": "重型支援桥液压泵应急替代", + "operableParts": [ + "bridge-engine", + "front-pump-pto-switch", + "bridge-hose-a", + "bridge-hose-b", + "bridge-return-valve", + "front-pump-aux-control-box-cover", + "front-pump-rescue-switch", + "front-pump-ball-valve-switch", + "bridge-support-pto", + "bridge-supply", + "bridge-normal-control" + ] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "BRIDGE-STEP-1", + "stepCode": "BRIDGE-STEP-1", + "actionCode": "COMPLETE_BRIDGE-STEP-1", + "number": 1, + "title": "保持架桥车运行并断开取力器", + "targetId": "bridge-engine", + "targetName": "保持架桥车发动机运行", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "guidance": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "warning": "", + "success": "保持架桥车运行并断开取力器:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-engine", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "保持架桥车发动机运行", + "effects": [ + { + "targetId": "bridge-engine", + "color": 2209160 + } + ] + }, + { + "targetId": "front-pump-pto-switch", + "kind": "rotate", + "axis": [ + 1, + 0, + 0 + ], + "deltaDegrees": -30, + "toleranceDegrees": 8, + "directionHint": "断开架桥车取力器" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-2", + "stepCode": "BRIDGE-STEP-2", + "actionCode": "COMPLETE_BRIDGE-STEP-2", + "number": 2, + "title": "连接两车液压软管", + "targetId": "bridge-hose-a", + "targetName": "连接架桥车快速接头", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "guidance": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "warning": "", + "success": "连接两车液压软管:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-hose-a", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-hose-a", + "kind": "identify", + "directionHint": "连接架桥车快速接头", + "effects": [ + { + "targetId": "bridge-hose-a", + "offset": [ + 0, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-hose-line", + "visible": true + } + ] + }, + { + "targetId": "bridge-hose-b", + "kind": "identify", + "directionHint": "连接保障车快速接头", + "effects": [ + { + "targetId": "bridge-hose-b", + "offset": [ + 0, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-return-line", + "visible": true + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-3", + "stepCode": "BRIDGE-STEP-3", + "actionCode": "COMPLETE_BRIDGE-STEP-3", + "number": 3, + "title": "打开支援车回油截止阀", + "targetId": "bridge-return-valve", + "targetName": "打开保障车回油截止阀", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开支援车液压油箱快接接头处的回油截止阀。", + "guidance": "打开支援车液压油箱快接接头处的回油截止阀。", + "warning": "", + "success": "打开支援车回油截止阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-return-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "rotate", + "steps": [ + { + "targetId": "bridge-return-valve", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "打开保障车回油截止阀" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开支援车液压油箱快接接头处的回油截止阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-4", + "stepCode": "BRIDGE-STEP-4", + "actionCode": "COMPLETE_BRIDGE-STEP-4", + "number": 4, + "title": "打开互救作业开关", + "targetId": "front-pump-aux-control-box-cover", + "targetName": "打开辅助控制盒盖", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开辅助控制盒上的“互救作业”开关。", + "guidance": "打开辅助控制盒上的“互救作业”开关。", + "warning": "", + "success": "打开互救作业开关:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-aux-control-box-cover", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "front-pump-aux-control-box-cover", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "deltaDegrees": 100, + "toleranceDegrees": 8, + "directionHint": "打开辅助控制盒盖" + }, + { + "targetId": "front-pump-rescue-switch", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 30, + "toleranceDegrees": 8, + "directionHint": "打开互救作业开关" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开辅助控制盒上的“互救作业”开关。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-5", + "stepCode": "BRIDGE-STEP-5", + "actionCode": "COMPLETE_BRIDGE-STEP-5", + "number": 5, + "title": "打开滤油器出口连通球阀", + "targetId": "front-pump-ball-valve-switch", + "targetName": "打开滤油器出口连通球阀", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开两个输油滤油器出口处的连通球阀。", + "guidance": "打开两个输油滤油器出口处的连通球阀。", + "warning": "", + "success": "打开滤油器出口连通球阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "front-pump-ball-valve-switch", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "rotate", + "steps": [ + { + "targetId": "front-pump-ball-valve-switch", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "打开滤油器出口连通球阀" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开两个输油滤油器出口处的连通球阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-6", + "stepCode": "BRIDGE-STEP-6", + "actionCode": "COMPLETE_BRIDGE-STEP-6", + "number": 6, + "title": "接通支援车液压取力器", + "targetId": "bridge-support-pto", + "targetName": "接通保障车取力器", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "接通支援车液压系统取力器,向架桥车供油。", + "guidance": "接通支援车液压系统取力器,向架桥车供油。", + "warning": "", + "success": "接通支援车液压取力器:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-support-pto", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-support-pto", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 30, + "toleranceDegrees": 8, + "directionHint": "接通保障车取力器" + }, + { + "targetId": "bridge-supply", + "kind": "identify", + "directionHint": "观察供油示意", + "effects": [ + { + "targetId": "bridge-hose-line", + "color": 15312947 + }, + { + "targetId": "bridge-return-line", + "color": 3325905 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "接通支援车液压系统取力器,向架桥车供油。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-7", + "stepCode": "BRIDGE-STEP-7", + "actionCode": "COMPLETE_BRIDGE-STEP-7", + "number": 7, + "title": "按正常步骤操作架桥车", + "targetId": "bridge-normal-control", + "targetName": "操作正常作业控制手柄", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "guidance": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "warning": "该项为原稿概括项,本预演不代表后续正常作业已经完成。", + "success": "按正常步骤操作架桥车:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-normal-control", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-normal-control", + "kind": "identify", + "directionHint": "操作正常作业控制手柄", + "effects": [ + { + "targetId": "bridge-normal-control", + "offset": [ + 0, + 0, + -0.25 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 14.285714285714286, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "successCue": "ui", + "errorCue": "collision-error" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-substitute", + "scriptVersion": "3" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/5.jpg、6.jpg" + }, + "changeSummary": "脚本来源 v3:复用三维工作区、正式教学运行、步骤记录与成绩评定", + "checksum": "e9de65c84fde072727cca1a96dd7b25bd694129ba3f64c49f1f8dde7fe085d2e", + "createdByUserId": "99", + "createdByName": "内部维护", + "publishedByUserId": "99", + "publishedByName": "内部维护", + "publishedTime": 1789395441, + "version": 2, + "addTime": 1789395441, + "updateTime": "2026-09-14T22:17:21", + "dependencies": [], + "assets": [] + } + }, + "runs": { + "records": [], + "total": 0, + "page": 1, + "size": 100 + } +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-binding.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-binding.json new file mode 100644 index 0000000..8adf128 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-binding.json @@ -0,0 +1,129 @@ +{ + "code": "TASK-VIRTUAL-006", + "taskId": "87", + "contentVersionId": "534", + "clips": [ + { + "stepCode": "BRIDGE-STEP-1", + "videoAssetCode": "DH_5AEA5274E6664D43B8C53F55859D5717" + }, + { + "stepCode": "BRIDGE-STEP-2", + "videoAssetCode": "DH_B9F2CBFE36274528825899153DB98195" + }, + { + "stepCode": "BRIDGE-STEP-3", + "videoAssetCode": "DH_983218ACA84345B5B032A5DFA8F08E4E" + }, + { + "stepCode": "BRIDGE-STEP-4", + "videoAssetCode": "DH_AC0F121CD04B44B5A373BE82D5083AE1" + }, + { + "stepCode": "BRIDGE-STEP-5", + "videoAssetCode": "DH_774F7400E0B54F4696EBDAD800A289C3" + }, + { + "stepCode": "BRIDGE-STEP-6", + "videoAssetCode": "DH_64D9ECF315DA41568D936CFEBF28E403" + }, + { + "stepCode": "BRIDGE-STEP-7", + "videoAssetCode": "DH_356ADFCC874448D28ADB2DF8067582E8" + } + ], + "runsUnchanged": true, + "assets": [ + { + "sourceProjectId": "439", + "sourceVersionId": "534", + "assetCode": "DH_5AEA5274E6664D43B8C53F55859D5717", + "name": "重型支援桥液压泵应急替代 · 1 保持架桥车运行并断开取力器", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/75748c295407bd0768e760d4593dbdee.mp4", + "mimeType": "video/mp4", + "sizeBytes": 554961, + "sha256": "d82bb8354acfca494e2ff515e5ef79887fb9d1f929a62779119d136857944ba6", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/87/assets/534/DH_5AEA5274E6664D43B8C53F55859D5717/content" + }, + { + "sourceProjectId": "439", + "sourceVersionId": "534", + "assetCode": "DH_B9F2CBFE36274528825899153DB98195", + "name": "重型支援桥液压泵应急替代 · 2 连接两车液压软管", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/d4c77791615f95ed57751597446e35c5.mp4", + "mimeType": "video/mp4", + "sizeBytes": 400318, + "sha256": "8791296620dbb4cc823bab5f24af07b8b48d510292b4baf966598b0b0351e4f9", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/87/assets/534/DH_B9F2CBFE36274528825899153DB98195/content" + }, + { + "sourceProjectId": "439", + "sourceVersionId": "534", + "assetCode": "DH_983218ACA84345B5B032A5DFA8F08E4E", + "name": "重型支援桥液压泵应急替代 · 3 打开支援车回油截止阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/0fbe417a88b14dc657256c924e8ba532.mp4", + "mimeType": "video/mp4", + "sizeBytes": 224021, + "sha256": "f78a59ebddcd35e937ce42910aed82fcaf9b49c07be4e1d460fc701e666d3d29", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/87/assets/534/DH_983218ACA84345B5B032A5DFA8F08E4E/content" + }, + { + "sourceProjectId": "439", + "sourceVersionId": "534", + "assetCode": "DH_AC0F121CD04B44B5A373BE82D5083AE1", + "name": "重型支援桥液压泵应急替代 · 4 打开互救作业开关", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/0e886b5158602172fb149cb7bb4c07cc.mp4", + "mimeType": "video/mp4", + "sizeBytes": 332829, + "sha256": "a784a79790a96f486eb6be917fa879db7071813a31f461f5d95d31c754ce3f46", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/87/assets/534/DH_AC0F121CD04B44B5A373BE82D5083AE1/content" + }, + { + "sourceProjectId": "439", + "sourceVersionId": "534", + "assetCode": "DH_774F7400E0B54F4696EBDAD800A289C3", + "name": "重型支援桥液压泵应急替代 · 5 打开滤油器出口连通球阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/3a57549a9c62a2faa19f4a9af7740193.mp4", + "mimeType": "video/mp4", + "sizeBytes": 241632, + "sha256": "db5c8f4a531e958712d309f25f9c51a145f717e4687893fcc41b65e2c8242175", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/87/assets/534/DH_774F7400E0B54F4696EBDAD800A289C3/content" + }, + { + "sourceProjectId": "439", + "sourceVersionId": "534", + "assetCode": "DH_64D9ECF315DA41568D936CFEBF28E403", + "name": "重型支援桥液压泵应急替代 · 6 接通支援车液压取力器", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/34657e7ed592e7d7a987f90e0f0188ba.mp4", + "mimeType": "video/mp4", + "sizeBytes": 401336, + "sha256": "05ffeff41d2cf4162b6e8181d4d002ba3f12531589a25d31bac76c69f5dea6bb", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/87/assets/534/DH_64D9ECF315DA41568D936CFEBF28E403/content" + }, + { + "sourceProjectId": "439", + "sourceVersionId": "534", + "assetCode": "DH_356ADFCC874448D28ADB2DF8067582E8", + "name": "重型支援桥液压泵应急替代 · 7 按正常步骤操作架桥车", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/715a4ac02abad5bf00d7a0a1bd0edb15.mp4", + "mimeType": "video/mp4", + "sizeBytes": 762615, + "sha256": "7b85bbf9c21adc74b56a26f6d92db1448f9f565101da6feba7ca9ad4cdd137f7", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/87/assets/534/DH_356ADFCC874448D28ADB2DF8067582E8/content" + } + ] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-01.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-01.mp4 new file mode 100644 index 0000000..0fd6019 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-01.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-02.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-02.mp4 new file mode 100644 index 0000000..31cf959 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-02.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-03.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-03.mp4 new file mode 100644 index 0000000..abac028 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-03.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-04.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-04.mp4 new file mode 100644 index 0000000..e6895d8 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-04.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-05.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-05.mp4 new file mode 100644 index 0000000..e28cb70 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-05.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-06.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-06.mp4 new file mode 100644 index 0000000..559f175 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-06.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-07.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-07.mp4 new file mode 100644 index 0000000..81def6e Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-07.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-video.png b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-video.png new file mode 100644 index 0000000..d46eff0 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-video.png differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-before.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-before.json new file mode 100644 index 0000000..b044593 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-before.json @@ -0,0 +1,3323 @@ +{ + "task": { + "id": "88", + "code": "TASK-VIRTUAL-007", + "name": "重型支援桥前泵换件修复", + "description": "原稿:桥梁/文件2/7.jpg、8.jpg", + "channel": "VIRTUAL", + "assignmentKind": "TRAINING", + "executionMode": "PRACTICE", + "audienceType": "COMMON", + "collaborationMode": "INDIVIDUAL", + "digitalHumanAllowed": false, + "digitalInstructorAgentSlug": "", + "digitalInstructorAgentName": "", + "digitalInstructorKnowledgeSource": "AGENT", + "contentProjectId": "440", + "contentVersionId": "531", + "definitionSnapshot": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥前泵换件修复", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "重型支援桥前泵换件修复", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "重型支援桥前泵换件修复", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "整车模型 · 补充拆装件为操作示意", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "桥梁脚本三维训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "重型支援桥前泵换件修复", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "重型支援桥前泵换件修复", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 11, + 8, + 16 + ], + "target": [ + 0, + 1.5, + 2 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "整车模型", + "补充操作示意", + "机构顺序操作" + ], + "sensorFeeds": [], + "name": "重型支援桥前泵换件修复", + "title": "重型支援桥前泵换件修复", + "operableParts": [ + "bridge-engine", + "bridge-paper", + "bridge-tank-valve", + "bridge-inlet", + "bridge-inlet-bag", + "bridge-outlet", + "bridge-outlet-bag", + "bridge-pump-bolt-1", + "bridge-pump-bolt-2", + "bridge-pump-bolt-3", + "bridge-pump-bolt-4", + "bridge-old-pump", + "bridge-gasket", + "bridge-new-pump", + "bridge-fill-cap", + "bridge-oil-can", + "bridge-test-control" + ] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "BRIDGE-STEP-1", + "stepCode": "BRIDGE-STEP-1", + "actionCode": "COMPLETE_BRIDGE-STEP-1", + "number": 1, + "title": "停机并初裁牛皮纸", + "targetId": "bridge-engine", + "targetName": "关闭架桥车发动机", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "guidance": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "warning": "", + "success": "停机并初裁牛皮纸:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-engine", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "关闭架桥车发动机", + "effects": [ + { + "targetId": "bridge-engine", + "color": 13195851 + } + ] + }, + { + "targetId": "bridge-paper", + "kind": "identify", + "directionHint": "按结合面初裁牛皮纸", + "effects": [ + { + "targetId": "bridge-paper", + "scale": [ + 0.85, + 1, + 0.85 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-2", + "stepCode": "BRIDGE-STEP-2", + "actionCode": "COMPLETE_BRIDGE-STEP-2", + "number": 2, + "title": "关闭液压油箱出油口一号球阀", + "targetId": "bridge-tank-valve", + "targetName": "关闭一号出油球阀", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将一号球阀手柄从平行管道转到垂直管道。", + "guidance": "将一号球阀手柄从平行管道转到垂直管道。", + "warning": "", + "success": "关闭液压油箱出油口一号球阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-tank-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "rotate", + "steps": [ + { + "targetId": "bridge-tank-valve", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "关闭一号出油球阀" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将一号球阀手柄从平行管道转到垂直管道。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-3", + "stepCode": "BRIDGE-STEP-3", + "actionCode": "COMPLETE_BRIDGE-STEP-3", + "number": 3, + "title": "拆开并包扎进出油管", + "targetId": "bridge-inlet", + "targetName": "拆开进油管", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "guidance": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "warning": "", + "success": "拆开并包扎进出油管:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-inlet", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-inlet", + "kind": "identify", + "directionHint": "拆开进油管", + "effects": [ + { + "targetId": "bridge-inlet", + "offset": [ + -0.6, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-inlet-bag", + "kind": "identify", + "directionHint": "包扎进油管口", + "effects": [ + { + "targetId": "bridge-inlet-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + }, + { + "targetId": "bridge-outlet", + "kind": "identify", + "directionHint": "拆开出油管", + "effects": [ + { + "targetId": "bridge-outlet", + "offset": [ + 0.6, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-outlet-bag", + "kind": "identify", + "directionHint": "包扎出油管口", + "effects": [ + { + "targetId": "bridge-outlet-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-4", + "stepCode": "BRIDGE-STEP-4", + "actionCode": "COMPLETE_BRIDGE-STEP-4", + "number": 4, + "title": "拆下四个安装螺栓", + "targetId": "bridge-pump-bolt-1", + "targetName": "拆下第 1 个安装螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "guidance": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "warning": "", + "success": "拆下四个安装螺栓:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-pump-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-pump-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 1 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-1", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 2 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-2", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 3 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-3", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 4 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-4", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-5", + "stepCode": "BRIDGE-STEP-5", + "actionCode": "COMPLETE_BRIDGE-STEP-5", + "number": 5, + "title": "取下旧前泵", + "targetId": "bridge-old-pump", + "targetName": "取下旧前泵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "取下原前泵。", + "guidance": "取下原前泵。", + "warning": "", + "success": "取下旧前泵:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-old-pump", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-old-pump", + "kind": "identify", + "directionHint": "取下旧前泵", + "effects": [ + { + "targetId": "bridge-old-pump", + "offset": [ + -2, + 0, + 0 + ] + }, + { + "targetId": "front-pump-hydraulic-pump", + "visible": false + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "取下原前泵。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-6", + "stepCode": "BRIDGE-STEP-6", + "actionCode": "COMPLETE_BRIDGE-STEP-6", + "number": 6, + "title": "修裁牛皮纸", + "targetId": "bridge-paper", + "targetName": "按安装面修裁纸垫", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "guidance": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "warning": "", + "success": "修裁牛皮纸:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-paper", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-paper", + "kind": "identify", + "directionHint": "按安装面修裁纸垫", + "effects": [ + { + "targetId": "bridge-gasket", + "visible": true + }, + { + "targetId": "bridge-paper", + "visible": false + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-7", + "stepCode": "BRIDGE-STEP-7", + "actionCode": "COMPLETE_BRIDGE-STEP-7", + "number": 7, + "title": "放置牛皮纸垫", + "targetId": "bridge-gasket", + "targetName": "将纸垫放到取力器结合面", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将裁好的牛皮纸放在取力器接口处。", + "guidance": "将裁好的牛皮纸放在取力器接口处。", + "warning": "", + "success": "放置牛皮纸垫:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-gasket", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-gasket", + "kind": "identify", + "directionHint": "将纸垫放到取力器结合面", + "effects": [ + { + "targetId": "bridge-gasket", + "offset": [ + 2.3, + 0, + -0.4 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将裁好的牛皮纸放在取力器接口处。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-8", + "stepCode": "BRIDGE-STEP-8", + "actionCode": "COMPLETE_BRIDGE-STEP-8", + "number": 8, + "title": "安装新液压泵", + "targetId": "bridge-new-pump", + "targetName": "安装新泵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "安装新的液压泵。原稿没有给出拧紧力矩。", + "guidance": "安装新的液压泵。原稿没有给出拧紧力矩。", + "warning": "", + "success": "安装新液压泵:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-new-pump", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-new-pump", + "kind": "identify", + "directionHint": "安装新泵", + "effects": [ + { + "targetId": "bridge-new-pump", + "offset": [ + -2, + 0, + 0 + ] + }, + { + "targetId": "front-pump-hydraulic-pump", + "visible": true + } + ] + }, + { + "targetId": "bridge-pump-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 1 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 2 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 3 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 4 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "安装新的液压泵。原稿没有给出拧紧力矩。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-9", + "stepCode": "BRIDGE-STEP-9", + "actionCode": "COMPLETE_BRIDGE-STEP-9", + "number": 9, + "title": "向新泵加注液压油", + "targetId": "bridge-fill-cap", + "targetName": "打开加油口", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "guidance": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "warning": "", + "success": "向新泵加注液压油:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-fill-cap", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-fill-cap", + "kind": "identify", + "directionHint": "打开加油口", + "effects": [ + { + "targetId": "bridge-fill-cap", + "offset": [ + 0, + 0.45, + 0 + ] + } + ] + }, + { + "targetId": "bridge-oil-can", + "kind": "identify", + "directionHint": "向新泵加注液压油", + "effects": [ + { + "targetId": "bridge-oil-can", + "offset": [ + -1.3, + 0.6, + -0.3 + ] + }, + { + "targetId": "bridge-oil-stream", + "visible": true + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-10", + "stepCode": "BRIDGE-STEP-10", + "actionCode": "COMPLETE_BRIDGE-STEP-10", + "number": 10, + "title": "恢复进出油管连接", + "targetId": "bridge-inlet-bag", + "targetName": "取下进油管封口袋", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用大活动扳手连接并拧紧液压泵进、出油管。", + "guidance": "用大活动扳手连接并拧紧液压泵进、出油管。", + "warning": "", + "success": "恢复进出油管连接:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-inlet-bag", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-inlet-bag", + "kind": "identify", + "directionHint": "取下进油管封口袋", + "effects": [ + { + "targetId": "bridge-inlet-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-inlet", + "kind": "identify", + "directionHint": "连接并拧紧进油管", + "effects": [ + { + "targetId": "bridge-inlet", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-outlet-bag", + "kind": "identify", + "directionHint": "取下出油管封口袋", + "effects": [ + { + "targetId": "bridge-outlet-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-outlet", + "kind": "identify", + "directionHint": "连接并拧紧出油管", + "effects": [ + { + "targetId": "bridge-outlet", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用大活动扳手连接并拧紧液压泵进、出油管。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-11", + "stepCode": "BRIDGE-STEP-11", + "actionCode": "COMPLETE_BRIDGE-STEP-11", + "number": 11, + "title": "启动设备试验", + "targetId": "bridge-engine", + "targetName": "启动设备试验", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "guidance": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "warning": "", + "success": "启动设备试验:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-engine", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "启动设备试验", + "effects": [ + { + "targetId": "bridge-engine", + "color": 2209160 + }, + { + "targetId": "bridge-oil-stream", + "visible": false + } + ] + }, + { + "targetId": "bridge-test-control", + "kind": "identify", + "directionHint": "操作试验手柄并观察", + "effects": [ + { + "targetId": "bridge-test-control", + "offset": [ + 0, + 0, + -0.25 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "successCue": "ui", + "errorCue": "collision-error" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-replace", + "scriptVersion": "3" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/7.jpg、8.jpg" + }, + "definitionChecksum": "b853206ebd130369549c955c7e3b1c574ada5de39a7c48bf136804d9dd1a2080", + "ownerUserId": "99", + "ownerUsername": "root", + "ownerName": "内部维护", + "departmentId": "1", + "departmentName": "", + "status": "PUBLISHED", + "scheduleStartAt": null, + "dueAt": null, + "publishedAt": 1789395442, + "withdrawnAt": 1789395442, + "archivedAt": null, + "lifecycleReason": "发布教学任务", + "version": 7, + "addTime": 1789309632, + "updateTime": "2026-09-13T22:27:13", + "serverNow": 1789398552, + "members": [], + "runCount": 0, + "pendingReviewCount": 0 + }, + "detail": { + "project": { + "id": "440", + "type": "TRAINING", + "code": "TRAINING-20B5F2AE722C48A5", + "name": "重型支援桥前泵换件修复", + "description": "原稿:桥梁/文件2/7.jpg、8.jpg", + "categoryCode": "MAINTENANCE", + "trainingMode": "VIRTUAL", + "coverUri": "", + "status": "PUBLISHED", + "ownerUserId": "99", + "ownerName": "内部维护", + "departmentId": "1", + "currentVersionId": "531", + "currentVersionNo": 3, + "currentVersionCode": "V3.0.0", + "publishedVersionId": "531", + "publishedTime": 1789395442, + "usageCount": 0, + "version": 6, + "addTime": 1789309631, + "updateTime": "2026-09-14T22:17:22", + "contentSummary": { + "schema": "digital-workshop-training-project", + "trainingMode": "VIRTUAL", + "stepCount": 11 + }, + "currentVersionStatus": "PUBLISHED", + "dependencyCount": 0, + "assetCount": 0, + "readCount": 0, + "downloadCount": 0 + }, + "currentVersion": { + "id": "531", + "projectId": "440", + "versionNo": 3, + "versionCode": "V3.0.0", + "status": "PUBLISHED", + "content": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥前泵换件修复", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "重型支援桥前泵换件修复", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "重型支援桥前泵换件修复", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "整车模型 · 补充拆装件为操作示意", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "桥梁脚本三维训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "重型支援桥前泵换件修复", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "重型支援桥前泵换件修复", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 11, + 8, + 16 + ], + "target": [ + 0, + 1.5, + 2 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "整车模型", + "补充操作示意", + "机构顺序操作" + ], + "sensorFeeds": [], + "name": "重型支援桥前泵换件修复", + "title": "重型支援桥前泵换件修复", + "operableParts": [ + "bridge-engine", + "bridge-paper", + "bridge-tank-valve", + "bridge-inlet", + "bridge-inlet-bag", + "bridge-outlet", + "bridge-outlet-bag", + "bridge-pump-bolt-1", + "bridge-pump-bolt-2", + "bridge-pump-bolt-3", + "bridge-pump-bolt-4", + "bridge-old-pump", + "bridge-gasket", + "bridge-new-pump", + "bridge-fill-cap", + "bridge-oil-can", + "bridge-test-control" + ] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "BRIDGE-STEP-1", + "stepCode": "BRIDGE-STEP-1", + "actionCode": "COMPLETE_BRIDGE-STEP-1", + "number": 1, + "title": "停机并初裁牛皮纸", + "targetId": "bridge-engine", + "targetName": "关闭架桥车发动机", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "guidance": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "warning": "", + "success": "停机并初裁牛皮纸:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-engine", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "关闭架桥车发动机", + "effects": [ + { + "targetId": "bridge-engine", + "color": 13195851 + } + ] + }, + { + "targetId": "bridge-paper", + "kind": "identify", + "directionHint": "按结合面初裁牛皮纸", + "effects": [ + { + "targetId": "bridge-paper", + "scale": [ + 0.85, + 1, + 0.85 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-2", + "stepCode": "BRIDGE-STEP-2", + "actionCode": "COMPLETE_BRIDGE-STEP-2", + "number": 2, + "title": "关闭液压油箱出油口一号球阀", + "targetId": "bridge-tank-valve", + "targetName": "关闭一号出油球阀", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将一号球阀手柄从平行管道转到垂直管道。", + "guidance": "将一号球阀手柄从平行管道转到垂直管道。", + "warning": "", + "success": "关闭液压油箱出油口一号球阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-tank-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "rotate", + "steps": [ + { + "targetId": "bridge-tank-valve", + "kind": "rotate", + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 90, + "toleranceDegrees": 8, + "directionHint": "关闭一号出油球阀" + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将一号球阀手柄从平行管道转到垂直管道。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-3", + "stepCode": "BRIDGE-STEP-3", + "actionCode": "COMPLETE_BRIDGE-STEP-3", + "number": 3, + "title": "拆开并包扎进出油管", + "targetId": "bridge-inlet", + "targetName": "拆开进油管", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "guidance": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "warning": "", + "success": "拆开并包扎进出油管:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-inlet", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-inlet", + "kind": "identify", + "directionHint": "拆开进油管", + "effects": [ + { + "targetId": "bridge-inlet", + "offset": [ + -0.6, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-inlet-bag", + "kind": "identify", + "directionHint": "包扎进油管口", + "effects": [ + { + "targetId": "bridge-inlet-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + }, + { + "targetId": "bridge-outlet", + "kind": "identify", + "directionHint": "拆开出油管", + "effects": [ + { + "targetId": "bridge-outlet", + "offset": [ + 0.6, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-outlet-bag", + "kind": "identify", + "directionHint": "包扎出油管口", + "effects": [ + { + "targetId": "bridge-outlet-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-4", + "stepCode": "BRIDGE-STEP-4", + "actionCode": "COMPLETE_BRIDGE-STEP-4", + "number": 4, + "title": "拆下四个安装螺栓", + "targetId": "bridge-pump-bolt-1", + "targetName": "拆下第 1 个安装螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "guidance": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "warning": "", + "success": "拆下四个安装螺栓:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-pump-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-pump-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 1 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-1", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 2 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-2", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 3 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-3", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 4 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-4", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-5", + "stepCode": "BRIDGE-STEP-5", + "actionCode": "COMPLETE_BRIDGE-STEP-5", + "number": 5, + "title": "取下旧前泵", + "targetId": "bridge-old-pump", + "targetName": "取下旧前泵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "取下原前泵。", + "guidance": "取下原前泵。", + "warning": "", + "success": "取下旧前泵:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-old-pump", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-old-pump", + "kind": "identify", + "directionHint": "取下旧前泵", + "effects": [ + { + "targetId": "bridge-old-pump", + "offset": [ + -2, + 0, + 0 + ] + }, + { + "targetId": "front-pump-hydraulic-pump", + "visible": false + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "取下原前泵。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-6", + "stepCode": "BRIDGE-STEP-6", + "actionCode": "COMPLETE_BRIDGE-STEP-6", + "number": 6, + "title": "修裁牛皮纸", + "targetId": "bridge-paper", + "targetName": "按安装面修裁纸垫", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "guidance": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "warning": "", + "success": "修裁牛皮纸:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-paper", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-paper", + "kind": "identify", + "directionHint": "按安装面修裁纸垫", + "effects": [ + { + "targetId": "bridge-gasket", + "visible": true + }, + { + "targetId": "bridge-paper", + "visible": false + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-7", + "stepCode": "BRIDGE-STEP-7", + "actionCode": "COMPLETE_BRIDGE-STEP-7", + "number": 7, + "title": "放置牛皮纸垫", + "targetId": "bridge-gasket", + "targetName": "将纸垫放到取力器结合面", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将裁好的牛皮纸放在取力器接口处。", + "guidance": "将裁好的牛皮纸放在取力器接口处。", + "warning": "", + "success": "放置牛皮纸垫:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-gasket", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-gasket", + "kind": "identify", + "directionHint": "将纸垫放到取力器结合面", + "effects": [ + { + "targetId": "bridge-gasket", + "offset": [ + 2.3, + 0, + -0.4 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将裁好的牛皮纸放在取力器接口处。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-8", + "stepCode": "BRIDGE-STEP-8", + "actionCode": "COMPLETE_BRIDGE-STEP-8", + "number": 8, + "title": "安装新液压泵", + "targetId": "bridge-new-pump", + "targetName": "安装新泵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "安装新的液压泵。原稿没有给出拧紧力矩。", + "guidance": "安装新的液压泵。原稿没有给出拧紧力矩。", + "warning": "", + "success": "安装新液压泵:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-new-pump", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-new-pump", + "kind": "identify", + "directionHint": "安装新泵", + "effects": [ + { + "targetId": "bridge-new-pump", + "offset": [ + -2, + 0, + 0 + ] + }, + { + "targetId": "front-pump-hydraulic-pump", + "visible": true + } + ] + }, + { + "targetId": "bridge-pump-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 1 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 2 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 3 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-pump-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "安装第 4 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "安装新的液压泵。原稿没有给出拧紧力矩。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-9", + "stepCode": "BRIDGE-STEP-9", + "actionCode": "COMPLETE_BRIDGE-STEP-9", + "number": 9, + "title": "向新泵加注液压油", + "targetId": "bridge-fill-cap", + "targetName": "打开加油口", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "guidance": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "warning": "", + "success": "向新泵加注液压油:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-fill-cap", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-fill-cap", + "kind": "identify", + "directionHint": "打开加油口", + "effects": [ + { + "targetId": "bridge-fill-cap", + "offset": [ + 0, + 0.45, + 0 + ] + } + ] + }, + { + "targetId": "bridge-oil-can", + "kind": "identify", + "directionHint": "向新泵加注液压油", + "effects": [ + { + "targetId": "bridge-oil-can", + "offset": [ + -1.3, + 0.6, + -0.3 + ] + }, + { + "targetId": "bridge-oil-stream", + "visible": true + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-10", + "stepCode": "BRIDGE-STEP-10", + "actionCode": "COMPLETE_BRIDGE-STEP-10", + "number": 10, + "title": "恢复进出油管连接", + "targetId": "bridge-inlet-bag", + "targetName": "取下进油管封口袋", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用大活动扳手连接并拧紧液压泵进、出油管。", + "guidance": "用大活动扳手连接并拧紧液压泵进、出油管。", + "warning": "", + "success": "恢复进出油管连接:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-inlet-bag", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-inlet-bag", + "kind": "identify", + "directionHint": "取下进油管封口袋", + "effects": [ + { + "targetId": "bridge-inlet-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-inlet", + "kind": "identify", + "directionHint": "连接并拧紧进油管", + "effects": [ + { + "targetId": "bridge-inlet", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-outlet-bag", + "kind": "identify", + "directionHint": "取下出油管封口袋", + "effects": [ + { + "targetId": "bridge-outlet-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-outlet", + "kind": "identify", + "directionHint": "连接并拧紧出油管", + "effects": [ + { + "targetId": "bridge-outlet", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用大活动扳手连接并拧紧液压泵进、出油管。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-11", + "stepCode": "BRIDGE-STEP-11", + "actionCode": "COMPLETE_BRIDGE-STEP-11", + "number": 11, + "title": "启动设备试验", + "targetId": "bridge-engine", + "targetName": "启动设备试验", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "guidance": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "warning": "", + "success": "启动设备试验:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-engine", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "启动设备试验", + "effects": [ + { + "targetId": "bridge-engine", + "color": 2209160 + }, + { + "targetId": "bridge-oil-stream", + "visible": false + } + ] + }, + { + "targetId": "bridge-test-control", + "kind": "identify", + "directionHint": "操作试验手柄并观察", + "effects": [ + { + "targetId": "bridge-test-control", + "offset": [ + 0, + 0, + -0.25 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 9.090909090909092, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "successCue": "ui", + "errorCue": "collision-error" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-pump-replace", + "scriptVersion": "3" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/7.jpg、8.jpg" + }, + "changeSummary": "脚本来源 v3:复用三维工作区、正式教学运行、步骤记录与成绩评定", + "checksum": "b853206ebd130369549c955c7e3b1c574ada5de39a7c48bf136804d9dd1a2080", + "createdByUserId": "99", + "createdByName": "内部维护", + "publishedByUserId": "99", + "publishedByName": "内部维护", + "publishedTime": 1789395442, + "version": 2, + "addTime": 1789395442, + "updateTime": "2026-09-14T22:17:22", + "dependencies": [], + "assets": [] + } + }, + "runs": { + "records": [], + "total": 0, + "page": 1, + "size": 100 + } +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-binding.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-binding.json new file mode 100644 index 0000000..ec74e81 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-binding.json @@ -0,0 +1,197 @@ +{ + "code": "TASK-VIRTUAL-007", + "taskId": "88", + "contentVersionId": "535", + "clips": [ + { + "stepCode": "BRIDGE-STEP-1", + "videoAssetCode": "DH_1CE71ECA76194F06B098A012B360BB06" + }, + { + "stepCode": "BRIDGE-STEP-2", + "videoAssetCode": "DH_34129B61FA1F4E628AF295E3EF714364" + }, + { + "stepCode": "BRIDGE-STEP-3", + "videoAssetCode": "DH_533EAE94D45D49A2BECD7E24E48835E6" + }, + { + "stepCode": "BRIDGE-STEP-4", + "videoAssetCode": "DH_787B4C212CF644AE9A3D8D49DEDCB65E" + }, + { + "stepCode": "BRIDGE-STEP-5", + "videoAssetCode": "DH_5672FD367E8F41A5A026E3C68E8C8726" + }, + { + "stepCode": "BRIDGE-STEP-6", + "videoAssetCode": "DH_C0E73EC20FD44C608A795A03DE4F7401" + }, + { + "stepCode": "BRIDGE-STEP-7", + "videoAssetCode": "DH_17FAC41643804A22A8B71A2FF8DCBC28" + }, + { + "stepCode": "BRIDGE-STEP-8", + "videoAssetCode": "DH_2284ABD91F544E2EB7799E9FA1C4BCF6" + }, + { + "stepCode": "BRIDGE-STEP-9", + "videoAssetCode": "DH_BF468C49DDCB462E8E2C75CF8C6BD172" + }, + { + "stepCode": "BRIDGE-STEP-10", + "videoAssetCode": "DH_88908FEBE6054EE99087F8653A8C5FAA" + }, + { + "stepCode": "BRIDGE-STEP-11", + "videoAssetCode": "DH_4D873387CF324AAF9C6D3BE1A72C247E" + } + ], + "runsUnchanged": true, + "assets": [ + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_1CE71ECA76194F06B098A012B360BB06", + "name": "重型支援桥前泵换件修复 · 1 停机并初裁牛皮纸", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/d8b3e011ed5bc1f41090d77dda7a8e72.mp4", + "mimeType": "video/mp4", + "sizeBytes": 448340, + "sha256": "22c92b853a9460ee67c7ae80d5bc203ff8aba07b32e148659b13f0637fb2c372", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_1CE71ECA76194F06B098A012B360BB06/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_34129B61FA1F4E628AF295E3EF714364", + "name": "重型支援桥前泵换件修复 · 2 关闭液压油箱出油口一号球阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/777c7c6f21c1108b1cf6a3e4681a7728.mp4", + "mimeType": "video/mp4", + "sizeBytes": 266042, + "sha256": "eab74c71b3be41e3c7563a4a36c75e3f61e5ad4a5ca032eab051844ca10943fe", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_34129B61FA1F4E628AF295E3EF714364/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_533EAE94D45D49A2BECD7E24E48835E6", + "name": "重型支援桥前泵换件修复 · 3 拆开并包扎进出油管", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/d974de975087ad6848689f4de8bb8597.mp4", + "mimeType": "video/mp4", + "sizeBytes": 474207, + "sha256": "63765c1da028750da4063a9d27c2211e592325165213d667c6592890cde982f0", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_533EAE94D45D49A2BECD7E24E48835E6/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_787B4C212CF644AE9A3D8D49DEDCB65E", + "name": "重型支援桥前泵换件修复 · 4 拆下四个安装螺栓", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/b8fee91715ad1fa277e03a460825ec01.mp4", + "mimeType": "video/mp4", + "sizeBytes": 275821, + "sha256": "e5b743ebe6fad8f7b614b11aea9d611fda877b02d9c31a8d67cabd41249327fe", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_787B4C212CF644AE9A3D8D49DEDCB65E/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_5672FD367E8F41A5A026E3C68E8C8726", + "name": "重型支援桥前泵换件修复 · 5 取下旧前泵", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/c3ef57b3d671acb6cfb0e7e039e86652.mp4", + "mimeType": "video/mp4", + "sizeBytes": 109215, + "sha256": "25ce8b12c5e17a2029d04a20fd53d270eed3904f50a4d7ea63bc83e33e18bd51", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_5672FD367E8F41A5A026E3C68E8C8726/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_C0E73EC20FD44C608A795A03DE4F7401", + "name": "重型支援桥前泵换件修复 · 6 修裁牛皮纸", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/7cc90bc260c6e4be30daaea3d9dfc446.mp4", + "mimeType": "video/mp4", + "sizeBytes": 246468, + "sha256": "db8bae8bfbde4f6e6dacb645eb2652f355f3b754a73012aaec3afee0e62ab9e8", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_C0E73EC20FD44C608A795A03DE4F7401/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_17FAC41643804A22A8B71A2FF8DCBC28", + "name": "重型支援桥前泵换件修复 · 7 放置牛皮纸垫", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/37e9c868094f42d56db8540f01317bf2.mp4", + "mimeType": "video/mp4", + "sizeBytes": 203299, + "sha256": "56ece26b2bab4af67bd59f88a3f4d1b08bfcdd083f423300d8d88f4ff4cae84b", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_17FAC41643804A22A8B71A2FF8DCBC28/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_2284ABD91F544E2EB7799E9FA1C4BCF6", + "name": "重型支援桥前泵换件修复 · 8 安装新液压泵", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/8f14a7af1d794cef6f9858e8244e75a5.mp4", + "mimeType": "video/mp4", + "sizeBytes": 191600, + "sha256": "1b8f68d21c2300b2bba451f5e22cbaafd6f2dcd0bf0d213c05a4caad53ce0ef0", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_2284ABD91F544E2EB7799E9FA1C4BCF6/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_BF468C49DDCB462E8E2C75CF8C6BD172", + "name": "重型支援桥前泵换件修复 · 9 向新泵加注液压油", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/363657dd4bc2b0e2809cd52faca8458c.mp4", + "mimeType": "video/mp4", + "sizeBytes": 443419, + "sha256": "095363c1f6be506fa3377330abbf88050dc9ffdd8dac07eb2c5476ea4ec32abe", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_BF468C49DDCB462E8E2C75CF8C6BD172/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_88908FEBE6054EE99087F8653A8C5FAA", + "name": "重型支援桥前泵换件修复 · 10 恢复进出油管连接", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/afe798b60bdea1f35f5b09d104205bad.mp4", + "mimeType": "video/mp4", + "sizeBytes": 219713, + "sha256": "eba4316082aa74841fe07f82c644484630efac95228a9b919b1d5348f76d06d8", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_88908FEBE6054EE99087F8653A8C5FAA/content" + }, + { + "sourceProjectId": "440", + "sourceVersionId": "535", + "assetCode": "DH_4D873387CF324AAF9C6D3BE1A72C247E", + "name": "重型支援桥前泵换件修复 · 11 启动设备试验", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/56a8a5cabf17265e7e64243e25e20dc5.mp4", + "mimeType": "video/mp4", + "sizeBytes": 246099, + "sha256": "4fed628e2847089de8882bb29da648f5aa3c00acf696123c11e5e6c3d54a48bb", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/88/assets/535/DH_4D873387CF324AAF9C6D3BE1A72C247E/content" + } + ] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-01.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-01.mp4 new file mode 100644 index 0000000..1f3e75e Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-01.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-02.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-02.mp4 new file mode 100644 index 0000000..190dbce Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-02.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-03.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-03.mp4 new file mode 100644 index 0000000..86ed0ef Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-03.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-04.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-04.mp4 new file mode 100644 index 0000000..5dc222a Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-04.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-05.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-05.mp4 new file mode 100644 index 0000000..647a22a Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-05.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-06.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-06.mp4 new file mode 100644 index 0000000..34b5087 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-06.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-07.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-07.mp4 new file mode 100644 index 0000000..dcff610 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-07.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-08.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-08.mp4 new file mode 100644 index 0000000..33f6923 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-08.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-09.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-09.mp4 new file mode 100644 index 0000000..9c6fbff Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-09.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-10.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-10.mp4 new file mode 100644 index 0000000..b0aa6ff Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-10.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-11.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-11.mp4 new file mode 100644 index 0000000..f85cbc1 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-11.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-video.png b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-video.png new file mode 100644 index 0000000..3cc61d6 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-video.png differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-before.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-before.json new file mode 100644 index 0000000..e06a786 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-before.json @@ -0,0 +1,4651 @@ +{ + "task": { + "id": "89", + "code": "TASK-VIRTUAL-008", + "name": "重型支援桥平衡阀拆拼互换", + "description": "原稿:桥梁/文件2/9.jpg、10.jpg", + "channel": "VIRTUAL", + "assignmentKind": "TRAINING", + "executionMode": "PRACTICE", + "audienceType": "COMMON", + "collaborationMode": "INDIVIDUAL", + "digitalHumanAllowed": false, + "digitalInstructorAgentSlug": "", + "digitalInstructorAgentName": "", + "digitalInstructorKnowledgeSource": "AGENT", + "contentProjectId": "441", + "contentVersionId": "526", + "definitionSnapshot": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥平衡阀拆拼互换", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "重型支援桥平衡阀拆拼互换", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "架桥车互救操作训练场", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "整车模型 · 补充拆装件为操作示意", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "内置架桥车互救操作训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "架桥车前泵故障互救处置训练场景", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "重型支援桥平衡阀拆拼互换", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 11, + 8, + 16 + ], + "target": [ + 0, + 1.5, + 2 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "真实整车步骤模型", + "前泵故障互救", + "机构顺序操作" + ], + "sensorFeeds": [], + "name": "重型支援桥平衡阀拆拼互换", + "title": "重型支援桥平衡阀拆拼互换", + "operableParts": [ + "bridge-small-cloth", + "bridge-small-pipe", + "bridge-small-bag", + "bridge-small-bolt-1", + "bridge-small-bolt-2", + "bridge-small-bolt-3", + "bridge-small-bolt-4", + "bridge-small-valve", + "bridge-small-plug-1", + "bridge-small-plug-2", + "bridge-small-seat", + "bridge-large-cloth", + "bridge-large-pipe", + "bridge-large-bag", + "bridge-large-bolt-1", + "bridge-large-bolt-2", + "bridge-large-bolt-3", + "bridge-large-bolt-4", + "bridge-large-valve", + "bridge-large-plug-1", + "bridge-large-plug-2", + "bridge-large-seat" + ] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "BRIDGE-STEP-1", + "stepCode": "BRIDGE-STEP-1", + "actionCode": "COMPLETE_BRIDGE-STEP-1", + "number": 1, + "title": "清洗小腔平衡阀", + "targetId": "bridge-small-cloth", + "targetName": "清洗并擦净阀体", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "guidance": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "warning": "", + "success": "清洗小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-cloth", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-small-cloth", + "kind": "identify", + "directionHint": "清洗并擦净阀体", + "effects": [ + { + "targetId": "bridge-small-cloth", + "offset": [ + 0.7, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-small-valve", + "color": 8492701 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-2", + "stepCode": "BRIDGE-STEP-2", + "actionCode": "COMPLETE_BRIDGE-STEP-2", + "number": 2, + "title": "拆开小腔控制油口管路", + "targetId": "bridge-small-pipe", + "targetName": "拆开控制油管", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "guidance": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "warning": "", + "success": "拆开小腔控制油口管路:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-pipe", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-pipe", + "kind": "identify", + "directionHint": "拆开控制油管", + "effects": [ + { + "targetId": "bridge-small-pipe", + "offset": [ + 0.55, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bag", + "kind": "identify", + "directionHint": "封袋包扎管口", + "effects": [ + { + "targetId": "bridge-small-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-3", + "stepCode": "BRIDGE-STEP-3", + "actionCode": "COMPLETE_BRIDGE-STEP-3", + "number": 3, + "title": "拆下小腔平衡阀", + "targetId": "bridge-small-bolt-1", + "targetName": "拆下第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "guidance": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "warning": "", + "success": "拆下小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-1", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-2", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-3", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-4", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-valve", + "kind": "identify", + "directionHint": "取下平衡阀", + "effects": [ + { + "targetId": "bridge-small-valve", + "offset": [ + 0, + 0, + 1.2 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-4", + "stepCode": "BRIDGE-STEP-4", + "actionCode": "COMPLETE_BRIDGE-STEP-4", + "number": 4, + "title": "封堵小腔油口", + "targetId": "bridge-small-plug-1", + "targetName": "封堵第 1 个油堵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "guidance": "用两个油堵封住两个油口,擦净阀座结合面。", + "warning": "", + "success": "封堵小腔油口:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-plug-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-plug-1", + "kind": "identify", + "directionHint": "封堵第 1 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-plug-2", + "kind": "identify", + "directionHint": "封堵第 2 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-seat", + "kind": "identify", + "directionHint": "擦净阀座结合面", + "effects": [ + { + "targetId": "bridge-small-seat", + "color": 12965080 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用两个油堵封住两个油口,擦净阀座结合面。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-5", + "stepCode": "BRIDGE-STEP-5", + "actionCode": "COMPLETE_BRIDGE-STEP-5", + "number": 5, + "title": "清洗大腔平衡阀", + "targetId": "bridge-large-cloth", + "targetName": "清洗并擦净阀体", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "guidance": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "warning": "", + "success": "清洗大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-cloth", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-large-cloth", + "kind": "identify", + "directionHint": "清洗并擦净阀体", + "effects": [ + { + "targetId": "bridge-large-cloth", + "offset": [ + 0.7, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-large-valve", + "color": 8492701 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-6", + "stepCode": "BRIDGE-STEP-6", + "actionCode": "COMPLETE_BRIDGE-STEP-6", + "number": 6, + "title": "拆开大腔控制油口管路", + "targetId": "bridge-large-pipe", + "targetName": "拆开控制油管", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "guidance": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "warning": "", + "success": "拆开大腔控制油口管路:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-pipe", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-pipe", + "kind": "identify", + "directionHint": "拆开控制油管", + "effects": [ + { + "targetId": "bridge-large-pipe", + "offset": [ + 0.55, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bag", + "kind": "identify", + "directionHint": "封袋包扎管口", + "effects": [ + { + "targetId": "bridge-large-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-7", + "stepCode": "BRIDGE-STEP-7", + "actionCode": "COMPLETE_BRIDGE-STEP-7", + "number": 7, + "title": "拆下大腔平衡阀", + "targetId": "bridge-large-bolt-1", + "targetName": "拆下第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "guidance": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "warning": "", + "success": "拆下大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-1", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-2", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-3", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-4", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-valve", + "kind": "identify", + "directionHint": "取下平衡阀", + "effects": [ + { + "targetId": "bridge-large-valve", + "offset": [ + 0, + 0, + 1.2 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-8", + "stepCode": "BRIDGE-STEP-8", + "actionCode": "COMPLETE_BRIDGE-STEP-8", + "number": 8, + "title": "封堵大腔油口", + "targetId": "bridge-large-plug-1", + "targetName": "封堵第 1 个油堵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "guidance": "用两个油堵封住两个油口,擦净阀座结合面。", + "warning": "", + "success": "封堵大腔油口:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-plug-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-plug-1", + "kind": "identify", + "directionHint": "封堵第 1 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-plug-2", + "kind": "identify", + "directionHint": "封堵第 2 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-seat", + "kind": "identify", + "directionHint": "擦净阀座结合面", + "effects": [ + { + "targetId": "bridge-large-seat", + "color": 12965080 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用两个油堵封住两个油口,擦净阀座结合面。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-9", + "stepCode": "BRIDGE-STEP-9", + "actionCode": "COMPLETE_BRIDGE-STEP-9", + "number": 9, + "title": "准备安装大腔平衡阀", + "targetId": "bridge-large-seat", + "targetName": "擦净安装结合面", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "guidance": "擦净平衡阀及阀座结合面,取下两个油堵。", + "warning": "", + "success": "准备安装大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-seat", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-seat", + "kind": "identify", + "directionHint": "擦净安装结合面", + "effects": [ + { + "targetId": "bridge-large-seat", + "color": 14477797 + } + ] + }, + { + "targetId": "bridge-large-plug-1", + "kind": "identify", + "directionHint": "取下第 1 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-1", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + }, + { + "targetId": "bridge-large-plug-2", + "kind": "identify", + "directionHint": "取下第 2 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-2", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "擦净平衡阀及阀座结合面,取下两个油堵。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-10", + "stepCode": "BRIDGE-STEP-10", + "actionCode": "COMPLETE_BRIDGE-STEP-10", + "number": 10, + "title": "安装大腔平衡阀", + "targetId": "bridge-small-valve", + "targetName": "将互换平衡阀装到阀座", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "guidance": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "warning": "", + "success": "安装大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-valve", + "kind": "identify", + "directionHint": "将互换平衡阀装到阀座", + "effects": [ + { + "targetId": "bridge-small-valve", + "offset": [ + 3.2, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-11", + "stepCode": "BRIDGE-STEP-11", + "actionCode": "COMPLETE_BRIDGE-STEP-11", + "number": 11, + "title": "核对大腔控制油口管路连接", + "targetId": "bridge-large-bag", + "targetName": "取下封口袋", + "mode": "measure", + "interaction": "mechanism-operation", + "instruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "guidance": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "warning": "请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "success": "核对大腔控制油口管路连接:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-bag", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-bag", + "kind": "identify", + "directionHint": "取下封口袋", + "effects": [ + { + "targetId": "bridge-large-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-pipe", + "kind": "identify", + "directionHint": "按记录的处理依据连接管路", + "effects": [ + { + "targetId": "bridge-large-pipe", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-12", + "stepCode": "BRIDGE-STEP-12", + "actionCode": "COMPLETE_BRIDGE-STEP-12", + "number": 12, + "title": "紧固大腔阀体连接螺栓", + "targetId": "bridge-large-bolt-1", + "targetName": "紧固第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "guidance": "用内六角扳手拧紧四个阀体连接螺栓。", + "warning": "", + "success": "紧固大腔阀体连接螺栓:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用内六角扳手拧紧四个阀体连接螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-13", + "stepCode": "BRIDGE-STEP-13", + "actionCode": "COMPLETE_BRIDGE-STEP-13", + "number": 13, + "title": "准备安装小腔平衡阀", + "targetId": "bridge-small-seat", + "targetName": "擦净安装结合面", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "guidance": "擦净平衡阀及阀座结合面,取下两个油堵。", + "warning": "", + "success": "准备安装小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-seat", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-seat", + "kind": "identify", + "directionHint": "擦净安装结合面", + "effects": [ + { + "targetId": "bridge-small-seat", + "color": 14477797 + } + ] + }, + { + "targetId": "bridge-small-plug-1", + "kind": "identify", + "directionHint": "取下第 1 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-1", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + }, + { + "targetId": "bridge-small-plug-2", + "kind": "identify", + "directionHint": "取下第 2 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-2", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "擦净平衡阀及阀座结合面,取下两个油堵。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-14", + "stepCode": "BRIDGE-STEP-14", + "actionCode": "COMPLETE_BRIDGE-STEP-14", + "number": 14, + "title": "安装小腔平衡阀", + "targetId": "bridge-large-valve", + "targetName": "将互换平衡阀装到阀座", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "guidance": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "warning": "", + "success": "安装小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-valve", + "kind": "identify", + "directionHint": "将互换平衡阀装到阀座", + "effects": [ + { + "targetId": "bridge-large-valve", + "offset": [ + -3.2, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-15", + "stepCode": "BRIDGE-STEP-15", + "actionCode": "COMPLETE_BRIDGE-STEP-15", + "number": 15, + "title": "核对小腔控制油口管路连接", + "targetId": "bridge-small-bag", + "targetName": "取下封口袋", + "mode": "measure", + "interaction": "mechanism-operation", + "instruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "guidance": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "warning": "请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "success": "核对小腔控制油口管路连接:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-bag", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-bag", + "kind": "identify", + "directionHint": "取下封口袋", + "effects": [ + { + "targetId": "bridge-small-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-pipe", + "kind": "identify", + "directionHint": "按记录的处理依据连接管路", + "effects": [ + { + "targetId": "bridge-small-pipe", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-16", + "stepCode": "BRIDGE-STEP-16", + "actionCode": "COMPLETE_BRIDGE-STEP-16", + "number": 16, + "title": "紧固小腔阀体连接螺栓", + "targetId": "bridge-small-bolt-1", + "targetName": "紧固第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "guidance": "用内六角扳手拧紧四个阀体连接螺栓。", + "warning": "", + "success": "紧固小腔阀体连接螺栓:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用内六角扳手拧紧四个阀体连接螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-balance-valve-swap", + "scriptVersion": "3" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/9.jpg、10.jpg" + }, + "definitionChecksum": "1fa8b28e9816770d4280fd6a129f0b180bc7c0b75ba783a98ef4df3d9f2d61f3", + "ownerUserId": "99", + "ownerUsername": "root", + "ownerName": "内部维护", + "departmentId": "1", + "departmentName": "", + "status": "PUBLISHED", + "scheduleStartAt": null, + "dueAt": null, + "publishedAt": 1789316083, + "withdrawnAt": 1789316082, + "archivedAt": null, + "lifecycleReason": "发布教学任务", + "version": 7, + "addTime": 1789309633, + "updateTime": "2026-09-13T22:27:14", + "serverNow": 1789398972, + "members": [], + "runCount": 0, + "pendingReviewCount": 0 + }, + "detail": { + "project": { + "id": "441", + "type": "TRAINING", + "code": "TRAINING-D63D50628DB64370", + "name": "重型支援桥平衡阀拆拼互换", + "description": "原稿:桥梁/文件2/9.jpg、10.jpg", + "categoryCode": "MAINTENANCE", + "trainingMode": "VIRTUAL", + "coverUri": "", + "status": "PUBLISHED", + "ownerUserId": "99", + "ownerName": "内部维护", + "departmentId": "1", + "currentVersionId": "526", + "currentVersionNo": 3, + "currentVersionCode": "V3.0.0", + "publishedVersionId": "526", + "publishedTime": 1789316083, + "usageCount": 0, + "version": 6, + "addTime": 1789309632, + "updateTime": "2026-09-14T00:14:43", + "contentSummary": { + "schema": "digital-workshop-training-project", + "trainingMode": "VIRTUAL", + "stepCount": 16 + }, + "currentVersionStatus": "PUBLISHED", + "dependencyCount": 0, + "assetCount": 0, + "readCount": 0, + "downloadCount": 0 + }, + "currentVersion": { + "id": "526", + "projectId": "441", + "versionNo": 3, + "versionCode": "V3.0.0", + "status": "PUBLISHED", + "content": { + "schema": "digital-workshop-training-project", + "version": 1, + "id": "front-pump-rescue-operation-v1", + "projectId": "front-pump-rescue-operation-v1", + "name": "重型支援桥平衡阀拆拼互换", + "status": "published", + "trainingMode": "VIRTUAL", + "resources": { + "models": [ + { + "id": "front-pump-step-vehicle", + "modelId": "front-pump-step-vehicle", + "name": "架桥车前泵互救操作整车模型", + "baseModelName": "架桥车前泵互救操作整车模型", + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "revision": 1, + "materialPreset": null, + "parts": [ + { + "editorId": "", + "interactionId": "front-pump-hydraulic-pump", + "nodeName": "1液压泵", + "sourceNodeName": "1液压泵", + "nodePath": "", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-power-take-off", + "nodeName": "2取力器", + "sourceNodeName": "2取力器", + "nodePath": "", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-pto-switch", + "nodeName": "2取力器开关", + "sourceNodeName": "2取力器开关", + "nodePath": "", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-ball-valve-switch", + "nodeName": "3球阀开关", + "sourceNodeName": "3球阀开关", + "nodePath": "", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box", + "nodeName": "5辅助控制盒", + "sourceNodeName": "5辅助控制盒", + "nodePath": "", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-aux-control-box-cover", + "nodeName": "5辅助控制盒盖", + "sourceNodeName": "5辅助控制盒盖", + "nodePath": "", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + }, + { + "editorId": "", + "interactionId": "front-pump-rescue-switch", + "nodeName": "5互救开关", + "sourceNodeName": "5互救开关", + "nodePath": "", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "visible": true + } + ] + } + ], + "animations": [] + }, + "task": { + "id": "TR-FRONT-PUMP-RESCUE-001", + "code": "TR-FRONT-PUMP-RESCUE-001", + "title": "重型支援桥平衡阀拆拼互换", + "categoryId": "minor-repair", + "difficulty": "标准", + "level": "标准", + "duration": 10, + "description": "前泵损坏的情况下如何操作。", + "image": "/models/step-model-front-pump-thumb.png", + "equipment": "架桥车", + "skills": [ + "液压泵故障识别", + "取力器断开与联通", + "球阀开启", + "互救开关操作" + ] + }, + "scenario": { + "id": "front-pump-rescue-scenario", + "publishedSceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "publishedSceneVersion": "1.0", + "baseVisualKey": "front-pump-rescue", + "visualKey": "front-pump-rescue", + "environmentName": "架桥车互救操作训练场", + "sceneLayout": "架桥车整车操作位", + "equipmentState": "整车模型 · 补充拆装件为操作示意", + "tools": [], + "faults": [], + "environment": { + "type": "outdoor", + "mode": "builtin", + "sourceName": "内置架桥车互救操作训练场", + "resourceUrl": "", + "sizeBytes": 0, + "lastModified": 0, + "embeddedDataUrl": "" + }, + "sceneResource": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "version": "1.0", + "sourceKind": "published", + "status": "已发布", + "name": "架桥车前泵故障互救处置训练场景", + "presetId": "outdoor-1", + "type": "outdoor", + "objectCount": 2, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ], + "snapshot": { + "schema": "edit3dv4.scene", + "version": "1.0", + "name": "重型支援桥平衡阀拆拼互换", + "presetId": "outdoor-1", + "type": "outdoor", + "environment": { + "presetId": "outdoor-1", + "type": "outdoor" + }, + "rendering": { + "background": 11062241, + "fog": { + "color": 11062241, + "near": 70, + "far": 240 + }, + "toneMappingExposure": 1.05, + "environment": { + "type": "room", + "sigma": 0.04 + }, + "camera": { + "fov": 45, + "near": 0.1, + "far": 800, + "position": [ + 11, + 8, + 16 + ], + "target": [ + 0, + 1.5, + 2 + ] + } + }, + "objects": [ + { + "id": "front-pump-training-yard", + "sceneId": "front-pump-training-yard", + "interactionId": "scene:front-pump-training-yard", + "type": "imported", + "name": "野外山地训练场", + "semantic": "场景地形", + "assetRole": "environment", + "operable": false, + "visible": true, + "modelId": "front-pump-field-terrain", + "modelEditorAssetId": "front-pump-field-terrain", + "modelEditorModelId": "front-pump-field-terrain", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "sourceName": "地形.glb", + "resourceUrl": "/models/地形.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 10726472, + "fitToScene": true, + "fitSize": 140, + "groundLevelY": 0, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + }, + { + "id": "front-pump-rescue-vehicle", + "sceneId": "front-pump-rescue-vehicle", + "interactionId": "scene:front-pump-rescue-vehicle", + "type": "imported", + "name": "架桥车前泵互救操作整车模型", + "semantic": "实训装备", + "assetRole": "training-content", + "operable": true, + "visible": true, + "capabilities": [ + "select", + "inspect" + ], + "modelId": "front-pump-step-vehicle", + "modelEditorAssetId": "front-pump-step-vehicle", + "modelEditorModelId": "front-pump-step-vehicle", + "modelEditorRevision": 1, + "modelOverrides": {}, + "materialPreset": null, + "modelPartTargets": [ + { + "interactionId": "front-pump-hydraulic-pump", + "sourceNodeName": "1液压泵", + "name": "液压泵", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-power-take-off", + "sourceNodeName": "2取力器", + "name": "取力器", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-pto-switch", + "sourceNodeName": "2取力器开关", + "name": "取力器开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-ball-valve-switch", + "sourceNodeName": "3球阀开关", + "name": "球阀开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box", + "sourceNodeName": "5辅助控制盒", + "name": "辅助控制盒", + "capabilities": [ + "select", + "inspect" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-aux-control-box-cover", + "sourceNodeName": "5辅助控制盒盖", + "name": "辅助控制盒盖", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "pivotEdge": { + "space": "world", + "axis": [ + 0, + 1, + 0 + ], + "edge": "nearest-vertical-edge" + }, + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + }, + { + "interactionId": "front-pump-rescue-switch", + "sourceNodeName": "5互救开关", + "name": "互救开关", + "capabilities": [ + "select", + "inspect", + "mechanism" + ], + "sceneId": "front-pump-rescue-vehicle", + "operable": true, + "visible": true + } + ], + "sourceName": "步骤模型.glb", + "resourceUrl": "/models/步骤模型.glb", + "assetKey": "", + "mimeType": "model/gltf-binary", + "sizeBytes": 32195288, + "fitToScene": true, + "fitSize": 8, + "position": [ + 0, + 0, + 0 + ], + "rotation": [ + 0, + 0, + 0 + ], + "scale": [ + 1, + 1, + 1 + ] + } + ] + }, + "assetReferences": [ + { + "resourceUrl": "/models/步骤模型.glb", + "sourceName": "步骤模型.glb", + "sizeBytes": 32195288, + "mimeType": "model/gltf-binary", + "assetRole": "training-content" + } + ] + }, + "accent": "#2d86d8", + "background": 11062241, + "fog": 11062241, + "ground": 7110499, + "camera": { + "position": [ + 10.6, + 6.4, + 13.2 + ], + "target": [ + 0, + 1.9, + 0 + ] + }, + "retainStoredParts": true, + "sceneTags": [ + "真实整车步骤模型", + "前泵故障互救", + "机构顺序操作" + ], + "sensorFeeds": [], + "name": "重型支援桥平衡阀拆拼互换", + "title": "重型支援桥平衡阀拆拼互换", + "operableParts": [ + "bridge-small-cloth", + "bridge-small-pipe", + "bridge-small-bag", + "bridge-small-bolt-1", + "bridge-small-bolt-2", + "bridge-small-bolt-3", + "bridge-small-bolt-4", + "bridge-small-valve", + "bridge-small-plug-1", + "bridge-small-plug-2", + "bridge-small-seat", + "bridge-large-cloth", + "bridge-large-pipe", + "bridge-large-bag", + "bridge-large-bolt-1", + "bridge-large-bolt-2", + "bridge-large-bolt-3", + "bridge-large-bolt-4", + "bridge-large-valve", + "bridge-large-plug-1", + "bridge-large-plug-2", + "bridge-large-seat" + ] + }, + "tools": [], + "faults": [], + "steps": [ + { + "id": "BRIDGE-STEP-1", + "stepCode": "BRIDGE-STEP-1", + "actionCode": "COMPLETE_BRIDGE-STEP-1", + "number": 1, + "title": "清洗小腔平衡阀", + "targetId": "bridge-small-cloth", + "targetName": "清洗并擦净阀体", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "guidance": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "warning": "", + "success": "清洗小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-cloth", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-small-cloth", + "kind": "identify", + "directionHint": "清洗并擦净阀体", + "effects": [ + { + "targetId": "bridge-small-cloth", + "offset": [ + 0.7, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-small-valve", + "color": 8492701 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-2", + "stepCode": "BRIDGE-STEP-2", + "actionCode": "COMPLETE_BRIDGE-STEP-2", + "number": 2, + "title": "拆开小腔控制油口管路", + "targetId": "bridge-small-pipe", + "targetName": "拆开控制油管", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "guidance": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "warning": "", + "success": "拆开小腔控制油口管路:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-pipe", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-pipe", + "kind": "identify", + "directionHint": "拆开控制油管", + "effects": [ + { + "targetId": "bridge-small-pipe", + "offset": [ + 0.55, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bag", + "kind": "identify", + "directionHint": "封袋包扎管口", + "effects": [ + { + "targetId": "bridge-small-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-3", + "stepCode": "BRIDGE-STEP-3", + "actionCode": "COMPLETE_BRIDGE-STEP-3", + "number": 3, + "title": "拆下小腔平衡阀", + "targetId": "bridge-small-bolt-1", + "targetName": "拆下第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "guidance": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "warning": "", + "success": "拆下小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-1", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-2", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-3", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-4", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-small-valve", + "kind": "identify", + "directionHint": "取下平衡阀", + "effects": [ + { + "targetId": "bridge-small-valve", + "offset": [ + 0, + 0, + 1.2 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-4", + "stepCode": "BRIDGE-STEP-4", + "actionCode": "COMPLETE_BRIDGE-STEP-4", + "number": 4, + "title": "封堵小腔油口", + "targetId": "bridge-small-plug-1", + "targetName": "封堵第 1 个油堵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "guidance": "用两个油堵封住两个油口,擦净阀座结合面。", + "warning": "", + "success": "封堵小腔油口:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-plug-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-plug-1", + "kind": "identify", + "directionHint": "封堵第 1 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-plug-2", + "kind": "identify", + "directionHint": "封堵第 2 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-seat", + "kind": "identify", + "directionHint": "擦净阀座结合面", + "effects": [ + { + "targetId": "bridge-small-seat", + "color": 12965080 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用两个油堵封住两个油口,擦净阀座结合面。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-5", + "stepCode": "BRIDGE-STEP-5", + "actionCode": "COMPLETE_BRIDGE-STEP-5", + "number": 5, + "title": "清洗大腔平衡阀", + "targetId": "bridge-large-cloth", + "targetName": "清洗并擦净阀体", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "guidance": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "warning": "", + "success": "清洗大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-cloth", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "identify", + "steps": [ + { + "targetId": "bridge-large-cloth", + "kind": "identify", + "directionHint": "清洗并擦净阀体", + "effects": [ + { + "targetId": "bridge-large-cloth", + "offset": [ + 0.7, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-large-valve", + "color": 8492701 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-6", + "stepCode": "BRIDGE-STEP-6", + "actionCode": "COMPLETE_BRIDGE-STEP-6", + "number": 6, + "title": "拆开大腔控制油口管路", + "targetId": "bridge-large-pipe", + "targetName": "拆开控制油管", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "guidance": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "warning": "", + "success": "拆开大腔控制油口管路:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-pipe", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-pipe", + "kind": "identify", + "directionHint": "拆开控制油管", + "effects": [ + { + "targetId": "bridge-large-pipe", + "offset": [ + 0.55, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bag", + "kind": "identify", + "directionHint": "封袋包扎管口", + "effects": [ + { + "targetId": "bridge-large-bag", + "offset": [ + 0, + 0, + -0.65 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-7", + "stepCode": "BRIDGE-STEP-7", + "actionCode": "COMPLETE_BRIDGE-STEP-7", + "number": 7, + "title": "拆下大腔平衡阀", + "targetId": "bridge-large-bolt-1", + "targetName": "拆下第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "guidance": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "warning": "", + "success": "拆下大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-1", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-2", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-3", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-4", + "offset": [ + 0, + 0, + 0.65 + ] + } + ] + }, + { + "targetId": "bridge-large-valve", + "kind": "identify", + "directionHint": "取下平衡阀", + "effects": [ + { + "targetId": "bridge-large-valve", + "offset": [ + 0, + 0, + 1.2 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-8", + "stepCode": "BRIDGE-STEP-8", + "actionCode": "COMPLETE_BRIDGE-STEP-8", + "number": 8, + "title": "封堵大腔油口", + "targetId": "bridge-large-plug-1", + "targetName": "封堵第 1 个油堵", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "guidance": "用两个油堵封住两个油口,擦净阀座结合面。", + "warning": "", + "success": "封堵大腔油口:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-plug-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-plug-1", + "kind": "identify", + "directionHint": "封堵第 1 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-plug-2", + "kind": "identify", + "directionHint": "封堵第 2 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-seat", + "kind": "identify", + "directionHint": "擦净阀座结合面", + "effects": [ + { + "targetId": "bridge-large-seat", + "color": 12965080 + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用两个油堵封住两个油口,擦净阀座结合面。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-9", + "stepCode": "BRIDGE-STEP-9", + "actionCode": "COMPLETE_BRIDGE-STEP-9", + "number": 9, + "title": "准备安装大腔平衡阀", + "targetId": "bridge-large-seat", + "targetName": "擦净安装结合面", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "guidance": "擦净平衡阀及阀座结合面,取下两个油堵。", + "warning": "", + "success": "准备安装大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-seat", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-seat", + "kind": "identify", + "directionHint": "擦净安装结合面", + "effects": [ + { + "targetId": "bridge-large-seat", + "color": 14477797 + } + ] + }, + { + "targetId": "bridge-large-plug-1", + "kind": "identify", + "directionHint": "取下第 1 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-1", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + }, + { + "targetId": "bridge-large-plug-2", + "kind": "identify", + "directionHint": "取下第 2 个油堵", + "effects": [ + { + "targetId": "bridge-large-plug-2", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "擦净平衡阀及阀座结合面,取下两个油堵。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-10", + "stepCode": "BRIDGE-STEP-10", + "actionCode": "COMPLETE_BRIDGE-STEP-10", + "number": 10, + "title": "安装大腔平衡阀", + "targetId": "bridge-small-valve", + "targetName": "将互换平衡阀装到阀座", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "guidance": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "warning": "", + "success": "安装大腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-valve", + "kind": "identify", + "directionHint": "将互换平衡阀装到阀座", + "effects": [ + { + "targetId": "bridge-small-valve", + "offset": [ + 3.2, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-11", + "stepCode": "BRIDGE-STEP-11", + "actionCode": "COMPLETE_BRIDGE-STEP-11", + "number": 11, + "title": "核对大腔控制油口管路连接", + "targetId": "bridge-large-bag", + "targetName": "取下封口袋", + "mode": "measure", + "interaction": "mechanism-operation", + "instruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "guidance": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "warning": "请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "success": "核对大腔控制油口管路连接:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-bag", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-bag", + "kind": "identify", + "directionHint": "取下封口袋", + "effects": [ + { + "targetId": "bridge-large-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-pipe", + "kind": "identify", + "directionHint": "按记录的处理依据连接管路", + "effects": [ + { + "targetId": "bridge-large-pipe", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-12", + "stepCode": "BRIDGE-STEP-12", + "actionCode": "COMPLETE_BRIDGE-STEP-12", + "number": 12, + "title": "紧固大腔阀体连接螺栓", + "targetId": "bridge-large-bolt-1", + "targetName": "紧固第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "guidance": "用内六角扳手拧紧四个阀体连接螺栓。", + "warning": "", + "success": "紧固大腔阀体连接螺栓:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-large-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-large-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用内六角扳手拧紧四个阀体连接螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-13", + "stepCode": "BRIDGE-STEP-13", + "actionCode": "COMPLETE_BRIDGE-STEP-13", + "number": 13, + "title": "准备安装小腔平衡阀", + "targetId": "bridge-small-seat", + "targetName": "擦净安装结合面", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "guidance": "擦净平衡阀及阀座结合面,取下两个油堵。", + "warning": "", + "success": "准备安装小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-seat", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-seat", + "kind": "identify", + "directionHint": "擦净安装结合面", + "effects": [ + { + "targetId": "bridge-small-seat", + "color": 14477797 + } + ] + }, + { + "targetId": "bridge-small-plug-1", + "kind": "identify", + "directionHint": "取下第 1 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-1", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + }, + { + "targetId": "bridge-small-plug-2", + "kind": "identify", + "directionHint": "取下第 2 个油堵", + "effects": [ + { + "targetId": "bridge-small-plug-2", + "offset": [ + 0, + 0.55, + 0.5 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "擦净平衡阀及阀座结合面,取下两个油堵。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-14", + "stepCode": "BRIDGE-STEP-14", + "actionCode": "COMPLETE_BRIDGE-STEP-14", + "number": 14, + "title": "安装小腔平衡阀", + "targetId": "bridge-large-valve", + "targetName": "将互换平衡阀装到阀座", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "guidance": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "warning": "", + "success": "安装小腔平衡阀:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-large-valve", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-large-valve", + "kind": "identify", + "directionHint": "将互换平衡阀装到阀座", + "effects": [ + { + "targetId": "bridge-large-valve", + "offset": [ + -3.2, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-15", + "stepCode": "BRIDGE-STEP-15", + "actionCode": "COMPLETE_BRIDGE-STEP-15", + "number": 15, + "title": "核对小腔控制油口管路连接", + "targetId": "bridge-small-bag", + "targetName": "取下封口袋", + "mode": "measure", + "interaction": "mechanism-operation", + "instruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "guidance": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "warning": "请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "success": "核对小腔控制油口管路连接:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-bag", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-bag", + "kind": "identify", + "directionHint": "取下封口袋", + "effects": [ + { + "targetId": "bridge-small-bag", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-pipe", + "kind": "identify", + "directionHint": "按记录的处理依据连接管路", + "effects": [ + { + "targetId": "bridge-small-pipe", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "successCue": "ui", + "errorCue": "collision-error" + } + }, + { + "id": "BRIDGE-STEP-16", + "stepCode": "BRIDGE-STEP-16", + "actionCode": "COMPLETE_BRIDGE-STEP-16", + "number": 16, + "title": "紧固小腔阀体连接螺栓", + "targetId": "bridge-small-bolt-1", + "targetName": "紧固第 1 个螺栓", + "mode": "inspect", + "interaction": "mechanism-operation", + "instruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "guidance": "用内六角扳手拧紧四个阀体连接螺栓。", + "warning": "", + "success": "紧固小腔阀体连接螺栓:三维操作已保存", + "cameraPolicy": "focus", + "action": { + "kind": "mechanism-operation", + "targetId": "bridge-small-bolt-1", + "requiresPlacement": false, + "durationMs": 700, + "mechanism": { + "type": "sequence", + "steps": [ + { + "targetId": "bridge-small-bolt-1", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 1 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-1", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 2 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-2", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-3", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 3 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-3", + "offset": [ + 0, + 0, + 0 + ] + } + ] + }, + { + "targetId": "bridge-small-bolt-4", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": 180, + "toleranceDegrees": 8, + "directionHint": "紧固第 4 个螺栓", + "effects": [ + { + "targetId": "bridge-small-bolt-4", + "offset": [ + 0, + 0, + 0 + ] + } + ] + } + ] + } + }, + "toolId": "", + "measurement": "", + "assessment": { + "weight": 6.25, + "requiredDimensions": [ + "action", + "sequence" + ], + "passPolicy": "all-required" + }, + "audio": { + "narrationSource": "offline", + "narrationText": "用内六角扳手拧紧四个阀体连接螺栓。", + "successCue": "ui", + "errorCue": "collision-error" + } + } + ], + "executionPlan": { + "schema": "digital-workshop.training-execution-plan", + "version": 1, + "entryNodeId": "front-pump-step-01", + "traversalOrder": [ + "front-pump-step-01", + "front-pump-step-02", + "front-pump-step-03", + "front-pump-step-04", + "front-pump-step-05" + ] + }, + "assessment": { + "passScore": 80, + "maxScore": 100, + "totalScore": 100, + "scoringMode": "weighted-rules", + "allowRetry": true, + "recordProcess": true + }, + "runtime": { + "startMode": "practice", + "offline": true, + "teacherEnabled": true, + "teacherVoiceEnabled": true, + "actionSoundEnabled": true, + "showStepPanel": true, + "showProgress": true, + "allowReplay": true, + "language": "zh-CN", + "definitionSource": "SCRIPT", + "scriptId": "bridge-balance-valve-swap", + "scriptVersion": "3" + }, + "schemaVersion": 1, + "source": "桥梁/文件2/9.jpg、10.jpg" + }, + "changeSummary": "脚本来源 v3:复用三维工作区、正式教学运行、步骤记录与成绩评定", + "checksum": "1fa8b28e9816770d4280fd6a129f0b180bc7c0b75ba783a98ef4df3d9f2d61f3", + "createdByUserId": "99", + "createdByName": "内部维护", + "publishedByUserId": "99", + "publishedByName": "内部维护", + "publishedTime": 1789316083, + "version": 2, + "addTime": 1789316082, + "updateTime": "2026-09-14T00:14:43", + "dependencies": [], + "assets": [] + } + }, + "runs": { + "records": [], + "total": 0, + "page": 1, + "size": 100 + } +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-binding.json b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-binding.json new file mode 100644 index 0000000..a5fa8d1 --- /dev/null +++ b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-binding.json @@ -0,0 +1,282 @@ +{ + "code": "TASK-VIRTUAL-008", + "taskId": "89", + "contentVersionId": "536", + "clips": [ + { + "stepCode": "BRIDGE-STEP-1", + "videoAssetCode": "DH_76F80444AA9C4C3183A0EEDF6E655C25" + }, + { + "stepCode": "BRIDGE-STEP-2", + "videoAssetCode": "DH_EAF5F0A89D454E6FBAFB061C93D2F760" + }, + { + "stepCode": "BRIDGE-STEP-3", + "videoAssetCode": "DH_981034D69E3047C6B9D1DAE9BBF4F7D4" + }, + { + "stepCode": "BRIDGE-STEP-4", + "videoAssetCode": "DH_60D40306A9E74E96ADD7641932934BE4" + }, + { + "stepCode": "BRIDGE-STEP-5", + "videoAssetCode": "DH_A6EFEC7D339E4BA8994C525CA3709E2E" + }, + { + "stepCode": "BRIDGE-STEP-6", + "videoAssetCode": "DH_D9E1BAFBD89D48019B9445B2A5752E68" + }, + { + "stepCode": "BRIDGE-STEP-7", + "videoAssetCode": "DH_E83DDAB19F774A418C82EBA7E8EDCF8A" + }, + { + "stepCode": "BRIDGE-STEP-8", + "videoAssetCode": "DH_4FE31068F3EB410BAC72E19F1D1BAF49" + }, + { + "stepCode": "BRIDGE-STEP-9", + "videoAssetCode": "DH_D0A3CAC5278C4A57AC9BEF13DA2690BC" + }, + { + "stepCode": "BRIDGE-STEP-10", + "videoAssetCode": "DH_0F40DAF3E28F4FA088EA943D9470CAA7" + }, + { + "stepCode": "BRIDGE-STEP-11", + "videoAssetCode": "DH_F6427532AF5F40348CEB154F031F2AED" + }, + { + "stepCode": "BRIDGE-STEP-12", + "videoAssetCode": "DH_F601DB08C8D44934AD3A1B1582E804DB" + }, + { + "stepCode": "BRIDGE-STEP-13", + "videoAssetCode": "DH_B1BBA42CE5F346228B6B39A51F190CB3" + }, + { + "stepCode": "BRIDGE-STEP-14", + "videoAssetCode": "DH_2BCD762C693242FF8DA420BD9A5D4DF9" + }, + { + "stepCode": "BRIDGE-STEP-15", + "videoAssetCode": "DH_5F8309BF74344C568C2C9EEFDD9E74BF" + }, + { + "stepCode": "BRIDGE-STEP-16", + "videoAssetCode": "DH_D525E35EDA12402DA13302C2B3874CC3" + } + ], + "runsUnchanged": true, + "assets": [ + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_76F80444AA9C4C3183A0EEDF6E655C25", + "name": "重型支援桥平衡阀拆拼互换 · 1 清洗小腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/bbb7cb4c0937594e06facdeb4265bdfb.mp4", + "mimeType": "video/mp4", + "sizeBytes": 380363, + "sha256": "2e71eb4894d380917abb95245d3299e7c0b345c76a0a1df92610ba97c9d95e91", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_76F80444AA9C4C3183A0EEDF6E655C25/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_EAF5F0A89D454E6FBAFB061C93D2F760", + "name": "重型支援桥平衡阀拆拼互换 · 2 拆开小腔控制油口管路", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/2b3185dc7f0d5cb857c3682ab7773aa1.mp4", + "mimeType": "video/mp4", + "sizeBytes": 286904, + "sha256": "a1abca193097f47595f32b71a02f4101a02005d0ff67cd4932fa728403d1235b", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_EAF5F0A89D454E6FBAFB061C93D2F760/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_981034D69E3047C6B9D1DAE9BBF4F7D4", + "name": "重型支援桥平衡阀拆拼互换 · 3 拆下小腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/a9d362f15a10a6ec05d43bfc37dfc142.mp4", + "mimeType": "video/mp4", + "sizeBytes": 386424, + "sha256": "46f07ce2308478ba60b58d4f6ec600773632193ffaa83f42ed52c71b660d4da5", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_981034D69E3047C6B9D1DAE9BBF4F7D4/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_60D40306A9E74E96ADD7641932934BE4", + "name": "重型支援桥平衡阀拆拼互换 · 4 封堵小腔油口", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/7315f5118bd573be864686aa786cf458.mp4", + "mimeType": "video/mp4", + "sizeBytes": 348426, + "sha256": "7fdab9117f713bd3e01aa1d956bfdbc4601df9f5b166b4a05488c1181ba12211", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_60D40306A9E74E96ADD7641932934BE4/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_A6EFEC7D339E4BA8994C525CA3709E2E", + "name": "重型支援桥平衡阀拆拼互换 · 5 清洗大腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/c7e7402995b868a26a11f04255624ac9.mp4", + "mimeType": "video/mp4", + "sizeBytes": 242429, + "sha256": "5a2649d18c9cef179863c09cf8179668b34f1d253d1b340b3775509bdd057433", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_A6EFEC7D339E4BA8994C525CA3709E2E/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_D9E1BAFBD89D48019B9445B2A5752E68", + "name": "重型支援桥平衡阀拆拼互换 · 6 拆开大腔控制油口管路", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/d56936153f2455950a527c7b1b193cc1.mp4", + "mimeType": "video/mp4", + "sizeBytes": 299444, + "sha256": "8c3679991ac10e63383a40c2deffb1a9fdb5b79cbb692db64fda410e2b13b923", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_D9E1BAFBD89D48019B9445B2A5752E68/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_E83DDAB19F774A418C82EBA7E8EDCF8A", + "name": "重型支援桥平衡阀拆拼互换 · 7 拆下大腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/84a9178a525514f108f353c518765957.mp4", + "mimeType": "video/mp4", + "sizeBytes": 241834, + "sha256": "d8e749aee075d99707af8b1a6b9a6700f7b0349c19e9bbd5957f55f43e9c50af", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_E83DDAB19F774A418C82EBA7E8EDCF8A/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_4FE31068F3EB410BAC72E19F1D1BAF49", + "name": "重型支援桥平衡阀拆拼互换 · 8 封堵大腔油口", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/323c01c7d4438be382e33b72c1acfdef.mp4", + "mimeType": "video/mp4", + "sizeBytes": 208428, + "sha256": "3d3c67dfa76d776bcafee0e35412de7c44190b74776f93d426e6d9947fd7bb2c", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_4FE31068F3EB410BAC72E19F1D1BAF49/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_D0A3CAC5278C4A57AC9BEF13DA2690BC", + "name": "重型支援桥平衡阀拆拼互换 · 9 准备安装大腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/f76860dcb1df69933366b58a0a4acf49.mp4", + "mimeType": "video/mp4", + "sizeBytes": 241840, + "sha256": "bd890674565a670e7994a60be84847b692a8b4820995c3063a497d8cc7eddf7e", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_D0A3CAC5278C4A57AC9BEF13DA2690BC/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_0F40DAF3E28F4FA088EA943D9470CAA7", + "name": "重型支援桥平衡阀拆拼互换 · 10 安装大腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/679a321b725c5069ff3c279bdb5d4e74.mp4", + "mimeType": "video/mp4", + "sizeBytes": 503224, + "sha256": "ed2ee749404179d67831c8f0c46cae21643c97700f431b5cb089f99644fb7d27", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_0F40DAF3E28F4FA088EA943D9470CAA7/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_F6427532AF5F40348CEB154F031F2AED", + "name": "重型支援桥平衡阀拆拼互换 · 11 核对大腔控制油口管路连接", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/ff6024de51727d348cfb8d889bea860e.mp4", + "mimeType": "video/mp4", + "sizeBytes": 689467, + "sha256": "e90845dc69d890c341d682f5d36b8880e83fe26bdad34fd8573ee0560d36d287", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_F6427532AF5F40348CEB154F031F2AED/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_F601DB08C8D44934AD3A1B1582E804DB", + "name": "重型支援桥平衡阀拆拼互换 · 12 紧固大腔阀体连接螺栓", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/bd49e1bbbbd6ad7f351cf2c6912934ff.mp4", + "mimeType": "video/mp4", + "sizeBytes": 360250, + "sha256": "133f1f65d5d88040d4ce758fdb7c0512c44d32f2affc5b0ce09f402f9fd687a5", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_F601DB08C8D44934AD3A1B1582E804DB/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_B1BBA42CE5F346228B6B39A51F190CB3", + "name": "重型支援桥平衡阀拆拼互换 · 13 准备安装小腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/f6fdebd35ca690c3d05b74f55bd65605.mp4", + "mimeType": "video/mp4", + "sizeBytes": 242849, + "sha256": "7cf538b8754ccb0ada36395919cb9653d804717ec6a4d339dc8c62572697f27a", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_B1BBA42CE5F346228B6B39A51F190CB3/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_2BCD762C693242FF8DA420BD9A5D4DF9", + "name": "重型支援桥平衡阀拆拼互换 · 14 安装小腔平衡阀", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/f7cce5ab61c4458386a86729a97637a9.mp4", + "mimeType": "video/mp4", + "sizeBytes": 318525, + "sha256": "456843aa826f489cde689a55d4ffb3e3759b7f7464cc1fbdde6d7d7d216ef31f", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_2BCD762C693242FF8DA420BD9A5D4DF9/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_5F8309BF74344C568C2C9EEFDD9E74BF", + "name": "重型支援桥平衡阀拆拼互换 · 15 核对小腔控制油口管路连接", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/c65892e63c10c2d1283cfab5c2e83481.mp4", + "mimeType": "video/mp4", + "sizeBytes": 1093064, + "sha256": "2a47835ce52868b09ecec6fe380098b412d29a8c2806519a54d15396e3473b57", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_5F8309BF74344C568C2C9EEFDD9E74BF/content" + }, + { + "sourceProjectId": "441", + "sourceVersionId": "536", + "assetCode": "DH_D525E35EDA12402DA13302C2B3874CC3", + "name": "重型支援桥平衡阀拆拼互换 · 16 紧固小腔阀体连接螺栓", + "type": "VIDEO", + "contentUri": "fsvc://unreal-tran/video/2026/09/14/f13bb21ae4e501ce3546122f2412f2aa.mp4", + "mimeType": "video/mp4", + "sizeBytes": 216175, + "sha256": "2e22f597ff2808e1b9e600c46c319f82cd91e2be0063bfc817c94d672c786213", + "downloadable": true, + "downloadUrl": "/api/tran/v1/teaching/assignments/89/assets/536/DH_D525E35EDA12402DA13302C2B3874CC3/content" + } + ] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-01.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-01.mp4 new file mode 100644 index 0000000..bdae2aa Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-01.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-02.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-02.mp4 new file mode 100644 index 0000000..8e931b2 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-02.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-03.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-03.mp4 new file mode 100644 index 0000000..1556563 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-03.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-04.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-04.mp4 new file mode 100644 index 0000000..59d7d99 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-04.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-05.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-05.mp4 new file mode 100644 index 0000000..3045e72 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-05.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-06.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-06.mp4 new file mode 100644 index 0000000..480cc75 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-06.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-07.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-07.mp4 new file mode 100644 index 0000000..ca7e10d Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-07.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-08.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-08.mp4 new file mode 100644 index 0000000..4d69330 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-08.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-09.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-09.mp4 new file mode 100644 index 0000000..b4cd800 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-09.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-10.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-10.mp4 new file mode 100644 index 0000000..db65146 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-10.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-11.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-11.mp4 new file mode 100644 index 0000000..7fc8be5 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-11.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-12.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-12.mp4 new file mode 100644 index 0000000..0534c49 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-12.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-13.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-13.mp4 new file mode 100644 index 0000000..2c3ac7c Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-13.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-14.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-14.mp4 new file mode 100644 index 0000000..ccd654d Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-14.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-15.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-15.mp4 new file mode 100644 index 0000000..313c1e0 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-15.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-16.mp4 b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-16.mp4 new file mode 100644 index 0000000..22bc896 Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-16.mp4 differ diff --git a/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-video.png b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-video.png new file mode 100644 index 0000000..6b4415a Binary files /dev/null and b/reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-video.png differ diff --git a/reports/bridge-digital-video-20260914/generation.json b/reports/bridge-digital-video-20260914/generation.json new file mode 100644 index 0000000..331a3b6 --- /dev/null +++ b/reports/bridge-digital-video-20260914/generation.json @@ -0,0 +1,671 @@ +{ + "avatarId": "55", + "avatarName": "教员1", + "voiceId": "49", + "voiceName": "温和男声", + "clips": [ + { + "key": "bridge-pump-switch:2:front-pump-step-01", + "code": "TASK-VIRTUAL-005", + "projectId": "438", + "assignmentId": "86", + "stepCode": "front-pump-step-01", + "number": 1, + "title": "重型支援桥液压泵应急切换 · 1 根据故障现象确定是哪一个液压泵发生故障", + "text": "第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。", + "jobId": "4", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "53", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-01.mp4" + }, + { + "key": "bridge-pump-switch:2:front-pump-step-02", + "code": "TASK-VIRTUAL-005", + "projectId": "438", + "assignmentId": "86", + "stepCode": "front-pump-step-02", + "number": 2, + "title": "重型支援桥液压泵应急切换 · 2 断开架桥车取力器", + "text": "第2步,断开架桥车取力器。将架桥车取力器断开。", + "jobId": "5", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "54", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-02.mp4" + }, + { + "key": "bridge-pump-switch:2:front-pump-step-03", + "code": "TASK-VIRTUAL-005", + "projectId": "438", + "assignmentId": "86", + "stepCode": "front-pump-step-03", + "number": 3, + "title": "重型支援桥液压泵应急切换 · 3 将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "text": "第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。", + "jobId": "6", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "55", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-03.mp4" + }, + { + "key": "bridge-pump-switch:2:front-pump-step-04", + "code": "TASK-VIRTUAL-005", + "projectId": "438", + "assignmentId": "86", + "stepCode": "front-pump-step-04", + "number": 4, + "title": "重型支援桥液压泵应急切换 · 4 重新联通取力器", + "text": "第4步,重新接通取力器。将架桥车取力器重新接通。", + "jobId": "7", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "56", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-04.mp4" + }, + { + "key": "bridge-pump-switch:2:front-pump-step-05", + "code": "TASK-VIRTUAL-005", + "projectId": "438", + "assignmentId": "86", + "stepCode": "front-pump-step-05", + "number": 5, + "title": "重型支援桥液压泵应急切换 · 5 打开辅助控制盒内的“互救”开关", + "text": "第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。", + "jobId": "8", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "57", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-05.mp4" + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-1", + "code": "TASK-VIRTUAL-006", + "projectId": "439", + "assignmentId": "87", + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "title": "重型支援桥液压泵应急替代 · 1 保持架桥车运行并断开取力器", + "text": "第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "jobId": "9", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "58", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-01.mp4" + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-2", + "code": "TASK-VIRTUAL-006", + "projectId": "439", + "assignmentId": "87", + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "title": "重型支援桥液压泵应急替代 · 2 连接两车液压软管", + "text": "第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "jobId": "10", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "59", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-02.mp4" + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-3", + "code": "TASK-VIRTUAL-006", + "projectId": "439", + "assignmentId": "87", + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "title": "重型支援桥液压泵应急替代 · 3 打开支援车回油截止阀", + "text": "第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。", + "jobId": "11", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "60", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-03.mp4" + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-4", + "code": "TASK-VIRTUAL-006", + "projectId": "439", + "assignmentId": "87", + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "title": "重型支援桥液压泵应急替代 · 4 打开互救作业开关", + "text": "第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。", + "jobId": "12", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "61", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-04.mp4" + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-5", + "code": "TASK-VIRTUAL-006", + "projectId": "439", + "assignmentId": "87", + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "title": "重型支援桥液压泵应急替代 · 5 打开滤油器出口连通球阀", + "text": "第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。", + "jobId": "13", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "62", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-05.mp4" + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-6", + "code": "TASK-VIRTUAL-006", + "projectId": "439", + "assignmentId": "87", + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "title": "重型支援桥液压泵应急替代 · 6 接通支援车液压取力器", + "text": "第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。", + "jobId": "14", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "63", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-06.mp4" + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-7", + "code": "TASK-VIRTUAL-006", + "projectId": "439", + "assignmentId": "87", + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "title": "重型支援桥液压泵应急替代 · 7 按正常步骤操作架桥车", + "text": "第7步,按正常步骤操作架桥车。原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。该项为原稿概括项,本预演不代表后续正常作业已经完成。", + "jobId": "15", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "64", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-006-step-07.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-1", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "title": "重型支援桥前泵换件修复 · 1 停机并初裁牛皮纸", + "text": "第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "jobId": "16", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "65", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-01.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-2", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "title": "重型支援桥前泵换件修复 · 2 关闭液压油箱出油口一号球阀", + "text": "第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。", + "jobId": "17", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "66", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-02.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-3", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "title": "重型支援桥前泵换件修复 · 3 拆开并包扎进出油管", + "text": "第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "jobId": "18", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "67", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-03.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-4", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "title": "重型支援桥前泵换件修复 · 4 拆下四个安装螺栓", + "text": "第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "jobId": "19", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "68", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-04.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-5", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "title": "重型支援桥前泵换件修复 · 5 取下旧前泵", + "text": "第5步,取下旧前泵。取下原前泵。", + "jobId": "20", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "69", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-05.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-6", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "title": "重型支援桥前泵换件修复 · 6 修裁牛皮纸", + "text": "第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "jobId": "21", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "70", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-06.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-7", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "title": "重型支援桥前泵换件修复 · 7 放置牛皮纸垫", + "text": "第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。", + "jobId": "22", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "71", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-07.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-8", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "title": "重型支援桥前泵换件修复 · 8 安装新液压泵", + "text": "第8步,安装新液压泵。安装新的液压泵。原稿没有给出拧紧力矩。", + "jobId": "23", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "72", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-08.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-9", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "title": "重型支援桥前泵换件修复 · 9 向新泵加注液压油", + "text": "第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "jobId": "24", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "73", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-09.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-10", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "title": "重型支援桥前泵换件修复 · 10 恢复进出油管连接", + "text": "第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。", + "jobId": "25", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "74", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-10.mp4" + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-11", + "code": "TASK-VIRTUAL-007", + "projectId": "440", + "assignmentId": "88", + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "title": "重型支援桥前泵换件修复 · 11 启动设备试验", + "text": "第11步,启动设备试验。启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "jobId": "26", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "75", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-007-step-11.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-1", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "title": "重型支援桥平衡阀拆拼互换 · 1 清洗小腔平衡阀", + "text": "第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "jobId": "27", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "76", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-01.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-2", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "title": "重型支援桥平衡阀拆拼互换 · 2 拆开小腔控制油口管路", + "text": "第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "jobId": "28", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "77", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-02.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-3", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "title": "重型支援桥平衡阀拆拼互换 · 3 拆下小腔平衡阀", + "text": "第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "jobId": "29", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "78", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-03.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-4", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "title": "重型支援桥平衡阀拆拼互换 · 4 封堵小腔油口", + "text": "第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "jobId": "30", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "79", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-04.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-5", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "title": "重型支援桥平衡阀拆拼互换 · 5 清洗大腔平衡阀", + "text": "第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "jobId": "31", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "80", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-05.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-6", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "title": "重型支援桥平衡阀拆拼互换 · 6 拆开大腔控制油口管路", + "text": "第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "jobId": "32", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "81", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-06.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-7", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "title": "重型支援桥平衡阀拆拼互换 · 7 拆下大腔平衡阀", + "text": "第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "jobId": "33", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "82", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-07.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-8", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "title": "重型支援桥平衡阀拆拼互换 · 8 封堵大腔油口", + "text": "第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "jobId": "34", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "83", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-08.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-9", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "title": "重型支援桥平衡阀拆拼互换 · 9 准备安装大腔平衡阀", + "text": "第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "jobId": "35", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "84", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-09.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-10", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "title": "重型支援桥平衡阀拆拼互换 · 10 安装大腔平衡阀", + "text": "第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "jobId": "36", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "85", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-10.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-11", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "title": "重型支援桥平衡阀拆拼互换 · 11 核对大腔控制油口管路连接", + "text": "第11步,核对大腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "jobId": "37", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "86", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-11.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-12", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-12", + "number": 12, + "title": "重型支援桥平衡阀拆拼互换 · 12 紧固大腔阀体连接螺栓", + "text": "第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "jobId": "38", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "87", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-12.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-13", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-13", + "number": 13, + "title": "重型支援桥平衡阀拆拼互换 · 13 准备安装小腔平衡阀", + "text": "第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "jobId": "39", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "88", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-13.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-14", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-14", + "number": 14, + "title": "重型支援桥平衡阀拆拼互换 · 14 安装小腔平衡阀", + "text": "第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "jobId": "40", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "89", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-14.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-15", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-15", + "number": 15, + "title": "重型支援桥平衡阀拆拼互换 · 15 核对小腔控制油口管路连接", + "text": "第15步,核对小腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "jobId": "41", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "90", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-15.mp4" + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-16", + "code": "TASK-VIRTUAL-008", + "projectId": "441", + "assignmentId": "89", + "stepCode": "BRIDGE-STEP-16", + "number": 16, + "title": "重型支援桥平衡阀拆拼互换 · 16 紧固小腔阀体连接螺栓", + "text": "第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "jobId": "42", + "appId": "AP_238179E0A10F97927EA49FA3", + "status": "SUCCEEDED", + "stage": "成片已保存", + "videoId": "91", + "errorMessage": "", + "previewFile": "reports/bridge-digital-video-20260914/TASK-VIRTUAL-008-step-16.mp4" + } + ] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/health.json b/reports/bridge-digital-video-20260914/health.json new file mode 100644 index 0000000..4d33f7b --- /dev/null +++ b/reports/bridge-digital-video-20260914/health.json @@ -0,0 +1,22 @@ +[ + { + "url": "http://127.0.0.1:6100/actuator/health", + "status": 200 + }, + { + "url": "http://127.0.0.1:6100/api/auth/ping", + "status": 200 + }, + { + "url": "http://127.0.0.1:6100/api/tran/ping", + "status": 200 + }, + { + "url": "http://127.0.0.1:6180/", + "status": 200 + }, + { + "url": "http://192.168.31.168:6180/", + "status": 200 + } +] \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/index.html b/reports/bridge-digital-video-20260914/index.html new file mode 100644 index 0000000..9b67fec --- /dev/null +++ b/reports/bridge-digital-video-20260914/index.html @@ -0,0 +1 @@ +四套桥梁训练数字人讲解验收

四套桥梁训练 · 数字人视频讲解

39 段竖版人物视频,合计 263.9 秒;原 39 段步骤语音和 3 段提醒完整保留。正式任务 86–89 使用发布内容版本的受控 VIDEO 资产。已核对全部视频的步骤讲解词、下载哈希及 H.264/AAC 编码。

讲解面板可切换视频/语音。切步、关闭时停止播放,视频异常自动回退原语音。历史内容版本保留,已有运行、成绩及检查点未修改。

浏览器操作验证 · 全部资源核验 · 正式运行资产/版本保护验证

TASK-VIRTUAL-005 · 5 段

步骤讲解词视频
1第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。播放
2第2步,断开架桥车取力器。将架桥车取力器断开。播放
3第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。播放
4第4步,重新接通取力器。将架桥车取力器重新接通。播放
5第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。播放

TASK-VIRTUAL-006 · 7 段

步骤讲解词视频
1第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。播放
2第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。播放
3第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。播放
4第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。播放
5第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。播放
6第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。播放
7第7步,按正常步骤操作架桥车。原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。该项为原稿概括项,本预演不代表后续正常作业已经完成。播放

TASK-VIRTUAL-007 · 11 段

步骤讲解词视频
1第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。播放
2第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。播放
3第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。播放
4第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。播放
5第5步,取下旧前泵。取下原前泵。播放
6第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。播放
7第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。播放
8第8步,安装新液压泵。安装新的液压泵。原稿没有给出拧紧力矩。播放
9第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。原稿没有给出定量值。播放
10第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。播放
11第11步,启动设备试验。启动设备进行试验。原稿没有展开具体试验项目和判定数值。播放

TASK-VIRTUAL-008 · 16 段

步骤讲解词视频
1第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。播放
2第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。播放
3第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。播放
4第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。播放
5第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。播放
6第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。播放
7第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。播放
8第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。播放
9第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。播放
10第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。播放
11第11步,核对大腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。播放
12第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。播放
13第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。播放
14第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。播放
15第15步,核对小腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。播放
16第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。播放
\ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/lan-result.json b/reports/bridge-digital-video-20260914/lan-result.json new file mode 100644 index 0000000..47df7cd --- /dev/null +++ b/reports/bridge-digital-video-20260914/lan-result.json @@ -0,0 +1,14 @@ +{ + "origin": "http://192.168.31.168:6180", + "results": [ + { + "code": "TASK-VIRTUAL-005", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/live-result.json b/reports/bridge-digital-video-20260914/live-result.json new file mode 100644 index 0000000..fb6929c --- /dev/null +++ b/reports/bridge-digital-video-20260914/live-result.json @@ -0,0 +1,38 @@ +{ + "origin": "http://127.0.0.1:6180", + "results": [ + { + "code": "TASK-VIRTUAL-005", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true + }, + { + "code": "TASK-VIRTUAL-006", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true + }, + { + "code": "TASK-VIRTUAL-007", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true + }, + { + "code": "TASK-VIRTUAL-008", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/run-assets.json b/reports/bridge-digital-video-20260914/run-assets.json new file mode 100644 index 0000000..9687964 --- /dev/null +++ b/reports/bridge-digital-video-20260914/run-assets.json @@ -0,0 +1,31 @@ +{ + "runId": "101", + "results": [ + { + "code": "DH_FF17FDE117E94B80BB30DF3E058821FD", + "status": 200, + "size": 202274 + }, + { + "code": "DH_6E75DADE9D0649DCA16A2499D1EE8776", + "status": 200, + "size": 172936 + }, + { + "code": "DH_9A4629F90E614E60835441B5D0AAE86C", + "status": 200, + "size": 587353 + }, + { + "code": "DH_DA42FE5C995F4C67A559E6E94DB1C440", + "status": 200, + "size": 162678 + }, + { + "code": "DH_D85C34259BB34E0C966C5A79569DBF10", + "status": 200, + "size": 285991 + } + ], + "staleVersionStatus": 409 +} \ No newline at end of file diff --git a/reports/bridge-digital-video-20260914/sample-frame.png b/reports/bridge-digital-video-20260914/sample-frame.png new file mode 100644 index 0000000..857d169 Binary files /dev/null and b/reports/bridge-digital-video-20260914/sample-frame.png differ diff --git a/reports/bridge-digital-video-20260914/sample-mouth-1.png b/reports/bridge-digital-video-20260914/sample-mouth-1.png new file mode 100644 index 0000000..f86520c Binary files /dev/null and b/reports/bridge-digital-video-20260914/sample-mouth-1.png differ diff --git a/reports/bridge-digital-video-20260914/sample-mouth-2.png b/reports/bridge-digital-video-20260914/sample-mouth-2.png new file mode 100644 index 0000000..09d754c Binary files /dev/null and b/reports/bridge-digital-video-20260914/sample-mouth-2.png differ diff --git a/reports/bridge-digital-video-20260914/verification.json b/reports/bridge-digital-video-20260914/verification.json new file mode 100644 index 0000000..40d4a80 --- /dev/null +++ b/reports/bridge-digital-video-20260914/verification.json @@ -0,0 +1,320 @@ +{ + "videos": 39, + "duration": 263.9451619999999, + "size": 13512813, + "preservedWavs": 42, + "verified": [ + { + "code": "TASK-VIRTUAL-005", + "step": 1, + "assetCode": "DH_FF17FDE117E94B80BB30DF3E058821FD", + "sha256": "d5c992479f2893d3efbe20921dab1f82fcc8ab4c4f512477fe4e0ea636e8fb7f", + "duration": 5.08, + "size": 202274 + }, + { + "code": "TASK-VIRTUAL-005", + "step": 2, + "assetCode": "DH_6E75DADE9D0649DCA16A2499D1EE8776", + "sha256": "69ae89ec5e3d4a5ccd3efce23f33707ee4b3a236b398235ad133ee34f793a9ba", + "duration": 4.16, + "size": 172936 + }, + { + "code": "TASK-VIRTUAL-005", + "step": 3, + "assetCode": "DH_9A4629F90E614E60835441B5D0AAE86C", + "sha256": "c9ac26a8d58e52d7dc57c28b1c6f9134de780f65b29e1eef1e8351eb51753758", + "duration": 8.48, + "size": 587353 + }, + { + "code": "TASK-VIRTUAL-005", + "step": 4, + "assetCode": "DH_DA42FE5C995F4C67A559E6E94DB1C440", + "sha256": "383d1fe0a6a80112c7b8868ae1edfdbeadbc86c13ce6feec1a9721ba3d9881fe", + "duration": 4.24, + "size": 162678 + }, + { + "code": "TASK-VIRTUAL-005", + "step": 5, + "assetCode": "DH_D85C34259BB34E0C966C5A79569DBF10", + "sha256": "2d53c0bef4d8aa71d8b8535de676d2d8485929de06534ce3aab677805bc8eef3", + "duration": 6.92, + "size": 285991 + }, + { + "code": "TASK-VIRTUAL-006", + "step": 1, + "assetCode": "DH_5AEA5274E6664D43B8C53F55859D5717", + "sha256": "d82bb8354acfca494e2ff515e5ef79887fb9d1f929a62779119d136857944ba6", + "duration": 7.92, + "size": 554961 + }, + { + "code": "TASK-VIRTUAL-006", + "step": 2, + "assetCode": "DH_B9F2CBFE36274528825899153DB98195", + "sha256": "8791296620dbb4cc823bab5f24af07b8b48d510292b4baf966598b0b0351e4f9", + "duration": 10, + "size": 400318 + }, + { + "code": "TASK-VIRTUAL-006", + "step": 3, + "assetCode": "DH_983218ACA84345B5B032A5DFA8F08E4E", + "sha256": "f78a59ebddcd35e937ce42910aed82fcaf9b49c07be4e1d460fc701e666d3d29", + "duration": 5.72, + "size": 224021 + }, + { + "code": "TASK-VIRTUAL-006", + "step": 4, + "assetCode": "DH_AC0F121CD04B44B5A373BE82D5083AE1", + "sha256": "a784a79790a96f486eb6be917fa879db7071813a31f461f5d95d31c754ce3f46", + "duration": 5.08, + "size": 332829 + }, + { + "code": "TASK-VIRTUAL-006", + "step": 5, + "assetCode": "DH_774F7400E0B54F4696EBDAD800A289C3", + "sha256": "db5c8f4a531e958712d309f25f9c51a145f717e4687893fcc41b65e2c8242175", + "duration": 5.927333, + "size": 241632 + }, + { + "code": "TASK-VIRTUAL-006", + "step": 6, + "assetCode": "DH_64D9ECF315DA41568D936CFEBF28E403", + "sha256": "05ffeff41d2cf4162b6e8181d4d002ba3f12531589a25d31bac76c69f5dea6bb", + "duration": 6.04, + "size": 401336 + }, + { + "code": "TASK-VIRTUAL-006", + "step": 7, + "assetCode": "DH_356ADFCC874448D28ADB2DF8067582E8", + "sha256": "7b85bbf9c21adc74b56a26f6d92db1448f9f565101da6feba7ca9ad4cdd137f7", + "duration": 10.88, + "size": 762615 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 1, + "assetCode": "DH_1CE71ECA76194F06B098A012B360BB06", + "sha256": "22c92b853a9460ee67c7ae80d5bc203ff8aba07b32e148659b13f0637fb2c372", + "duration": 6.68, + "size": 448340 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 2, + "assetCode": "DH_34129B61FA1F4E628AF295E3EF714364", + "sha256": "eab74c71b3be41e3c7563a4a36c75e3f61e5ad4a5ca032eab051844ca10943fe", + "duration": 6.615333, + "size": 266042 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 3, + "assetCode": "DH_533EAE94D45D49A2BECD7E24E48835E6", + "sha256": "63765c1da028750da4063a9d27c2211e592325165213d667c6592890cde982f0", + "duration": 7.04, + "size": 474207 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 4, + "assetCode": "DH_787B4C212CF644AE9A3D8D49DEDCB65E", + "sha256": "e5b743ebe6fad8f7b614b11aea9d611fda877b02d9c31a8d67cabd41249327fe", + "duration": 6.661833, + "size": 275821 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 5, + "assetCode": "DH_5672FD367E8F41A5A026E3C68E8C8726", + "sha256": "25ce8b12c5e17a2029d04a20fd53d270eed3904f50a4d7ea63bc83e33e18bd51", + "duration": 2.96, + "size": 109215 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 6, + "assetCode": "DH_C0E73EC20FD44C608A795A03DE4F7401", + "sha256": "db8bae8bfbde4f6e6dacb645eb2652f355f3b754a73012aaec3afee0e62ab9e8", + "duration": 6.738333, + "size": 246468 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 7, + "assetCode": "DH_17FAC41643804A22A8B71A2FF8DCBC28", + "sha256": "56ece26b2bab4af67bd59f88a3f4d1b08bfcdd083f423300d8d88f4ff4cae84b", + "duration": 5.04, + "size": 203299 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 8, + "assetCode": "DH_2284ABD91F544E2EB7799E9FA1C4BCF6", + "sha256": "1b8f68d21c2300b2bba451f5e22cbaafd6f2dcd0bf0d213c05a4caad53ce0ef0", + "duration": 4.8, + "size": 191600 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 9, + "assetCode": "DH_BF468C49DDCB462E8E2C75CF8C6BD172", + "sha256": "095363c1f6be506fa3377330abbf88050dc9ffdd8dac07eb2c5476ea4ec32abe", + "duration": 6.8, + "size": 443419 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 10, + "assetCode": "DH_88908FEBE6054EE99087F8653A8C5FAA", + "sha256": "eba4316082aa74841fe07f82c644484630efac95228a9b919b1d5348f76d06d8", + "duration": 5.44, + "size": 219713 + }, + { + "code": "TASK-VIRTUAL-007", + "step": 11, + "assetCode": "DH_4D873387CF324AAF9C6D3BE1A72C247E", + "sha256": "4fed628e2847089de8882bb29da648f5aa3c00acf696123c11e5e6c3d54a48bb", + "duration": 6.346333, + "size": 246099 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 1, + "assetCode": "DH_76F80444AA9C4C3183A0EEDF6E655C25", + "sha256": "2e71eb4894d380917abb95245d3299e7c0b345c76a0a1df92610ba97c9d95e91", + "duration": 5.84, + "size": 380363 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 2, + "assetCode": "DH_EAF5F0A89D454E6FBAFB061C93D2F760", + "sha256": "a1abca193097f47595f32b71a02f4101a02005d0ff67cd4932fa728403d1235b", + "duration": 7.138833, + "size": 286904 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 3, + "assetCode": "DH_981034D69E3047C6B9D1DAE9BBF4F7D4", + "sha256": "46f07ce2308478ba60b58d4f6ec600773632193ffaa83f42ed52c71b660d4da5", + "duration": 5.88, + "size": 386424 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 4, + "assetCode": "DH_60D40306A9E74E96ADD7641932934BE4", + "sha256": "7fdab9117f713bd3e01aa1d956bfdbc4601df9f5b166b4a05488c1181ba12211", + "duration": 4.92, + "size": 348426 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 5, + "assetCode": "DH_A6EFEC7D339E4BA8994C525CA3709E2E", + "sha256": "5a2649d18c9cef179863c09cf8179668b34f1d253d1b340b3775509bdd057433", + "duration": 5.946333, + "size": 242429 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 6, + "assetCode": "DH_D9E1BAFBD89D48019B9445B2A5752E68", + "sha256": "8c3679991ac10e63383a40c2deffb1a9fdb5b79cbb692db64fda410e2b13b923", + "duration": 7.273833, + "size": 299444 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 7, + "assetCode": "DH_E83DDAB19F774A418C82EBA7E8EDCF8A", + "sha256": "d8e749aee075d99707af8b1a6b9a6700f7b0349c19e9bbd5957f55f43e9c50af", + "duration": 5.870833, + "size": 241834 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 8, + "assetCode": "DH_4FE31068F3EB410BAC72E19F1D1BAF49", + "sha256": "3d3c67dfa76d776bcafee0e35412de7c44190b74776f93d426e6d9947fd7bb2c", + "duration": 5.383333, + "size": 208428 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 9, + "assetCode": "DH_D0A3CAC5278C4A57AC9BEF13DA2690BC", + "sha256": "bd890674565a670e7994a60be84847b692a8b4820995c3063a497d8cc7eddf7e", + "duration": 6.011833, + "size": 241840 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 10, + "assetCode": "DH_0F40DAF3E28F4FA088EA943D9470CAA7", + "sha256": "ed2ee749404179d67831c8f0c46cae21643c97700f431b5cb089f99644fb7d27", + "duration": 7.4, + "size": 503224 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 11, + "assetCode": "DH_F6427532AF5F40348CEB154F031F2AED", + "sha256": "e90845dc69d890c341d682f5d36b8880e83fe26bdad34fd8573ee0560d36d287", + "duration": 16.12, + "size": 689467 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 12, + "assetCode": "DH_F601DB08C8D44934AD3A1B1582E804DB", + "sha256": "133f1f65d5d88040d4ce758fdb7c0512c44d32f2affc5b0ce09f402f9fd687a5", + "duration": 5.48, + "size": 360250 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 13, + "assetCode": "DH_B1BBA42CE5F346228B6B39A51F190CB3", + "sha256": "7cf538b8754ccb0ada36395919cb9653d804717ec6a4d339dc8c62572697f27a", + "duration": 5.888333, + "size": 242849 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 14, + "assetCode": "DH_2BCD762C693242FF8DA420BD9A5D4DF9", + "sha256": "456843aa826f489cde689a55d4ffb3e3759b7f7464cc1fbdde6d7d7d216ef31f", + "duration": 7.646333, + "size": 318525 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 15, + "assetCode": "DH_5F8309BF74344C568C2C9EEFDD9E74BF", + "sha256": "2a47835ce52868b09ecec6fe380098b412d29a8c2806519a54d15396e3473b57", + "duration": 16, + "size": 1093064 + }, + { + "code": "TASK-VIRTUAL-008", + "step": 16, + "assetCode": "DH_D525E35EDA12402DA13302C2B3874CC3", + "sha256": "2e22f597ff2808e1b9e600c46c319f82cd91e2be0063bfc817c94d672c786213", + "duration": 5.576333, + "size": 216175 + } + ] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-aspect-20260915/index.html b/reports/bridge-digital-video-aspect-20260915/index.html new file mode 100644 index 0000000..9a5a411 --- /dev/null +++ b/reports/bridge-digital-video-aspect-20260915/index.html @@ -0,0 +1,15 @@ + + + + +数字教员 3:4 显示框验证 + +

数字教员显示框:3:4

+
+

2026-09-15 · 本机 127.0.0.1:6180、局域网 192.168.31.168:6180 · 内部维护账号、任务 008 教员预览。未产生测试任务或训练成绩。

+

保留原宽度适配规则,高度按 3:4 自动计算,视频使用 contain 完整显示。1920×945 下为 122×162.66;1366×768 下为 112×149.33。两个地址、两种窗口和视频/语音两种状态共 8 项尺寸检查通过,页面脚本错误为 0。

+

pnpm run buildnode scripts/virtual-training-formal-route.contract.test.mjs 均通过;浏览器验证使用一次性 Playwright 检查。尺寸与环境记录

+
+

桌面窗口

桌面窗口 3:4 数字教员视频框
+

小屏窗口

小屏窗口 3:4 数字教员视频框
+ diff --git a/reports/bridge-digital-video-aspect-20260915/lan-1366-audio.png b/reports/bridge-digital-video-aspect-20260915/lan-1366-audio.png new file mode 100644 index 0000000..4b65c71 Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/lan-1366-audio.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/lan-1366-video.png b/reports/bridge-digital-video-aspect-20260915/lan-1366-video.png new file mode 100644 index 0000000..152fe34 Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/lan-1366-video.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/lan-1920-audio.png b/reports/bridge-digital-video-aspect-20260915/lan-1920-audio.png new file mode 100644 index 0000000..f3a5672 Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/lan-1920-audio.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/lan-1920-video.png b/reports/bridge-digital-video-aspect-20260915/lan-1920-video.png new file mode 100644 index 0000000..56bcb27 Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/lan-1920-video.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/local-1366-audio.png b/reports/bridge-digital-video-aspect-20260915/local-1366-audio.png new file mode 100644 index 0000000..1f87d32 Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/local-1366-audio.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/local-1366-video.png b/reports/bridge-digital-video-aspect-20260915/local-1366-video.png new file mode 100644 index 0000000..7423fe6 Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/local-1366-video.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/local-1920-audio.png b/reports/bridge-digital-video-aspect-20260915/local-1920-audio.png new file mode 100644 index 0000000..a6bdec2 Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/local-1920-audio.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/local-1920-video.png b/reports/bridge-digital-video-aspect-20260915/local-1920-video.png new file mode 100644 index 0000000..47a288f Binary files /dev/null and b/reports/bridge-digital-video-aspect-20260915/local-1920-video.png differ diff --git a/reports/bridge-digital-video-aspect-20260915/result.json b/reports/bridge-digital-video-aspect-20260915/result.json new file mode 100644 index 0000000..c434fab --- /dev/null +++ b/reports/bridge-digital-video-aspect-20260915/result.json @@ -0,0 +1,125 @@ +{ + "results": [ + { + "origin": "http://127.0.0.1:6180", + "viewport": { + "width": 1920, + "height": 945 + }, + "mode": "video", + "width": 122, + "height": 162.65625, + "actorWidth": 122, + "actorHeight": 162.65625, + "videoFit": "contain", + "bottom": 824, + "viewportHeight": 945 + }, + { + "origin": "http://127.0.0.1:6180", + "viewport": { + "width": 1920, + "height": 945 + }, + "mode": "audio", + "width": 122, + "height": 162.65625, + "actorWidth": 122, + "actorHeight": 162.65625, + "videoFit": "contain", + "bottom": 824, + "viewportHeight": 945 + }, + { + "origin": "http://127.0.0.1:6180", + "viewport": { + "width": 1366, + "height": 768 + }, + "mode": "video", + "width": 112, + "height": 149.328125, + "actorWidth": 112, + "actorHeight": 149.328125, + "videoFit": "contain", + "bottom": 647, + "viewportHeight": 768 + }, + { + "origin": "http://127.0.0.1:6180", + "viewport": { + "width": 1366, + "height": 768 + }, + "mode": "audio", + "width": 112, + "height": 149.328125, + "actorWidth": 112, + "actorHeight": 149.328125, + "videoFit": "contain", + "bottom": 647, + "viewportHeight": 768 + }, + { + "origin": "http://192.168.31.168:6180", + "viewport": { + "width": 1920, + "height": 945 + }, + "mode": "video", + "width": 122, + "height": 162.65625, + "actorWidth": 122, + "actorHeight": 162.65625, + "videoFit": "contain", + "bottom": 824, + "viewportHeight": 945 + }, + { + "origin": "http://192.168.31.168:6180", + "viewport": { + "width": 1920, + "height": 945 + }, + "mode": "audio", + "width": 122, + "height": 162.65625, + "actorWidth": 122, + "actorHeight": 162.65625, + "videoFit": "contain", + "bottom": 824, + "viewportHeight": 945 + }, + { + "origin": "http://192.168.31.168:6180", + "viewport": { + "width": 1366, + "height": 768 + }, + "mode": "video", + "width": 112, + "height": 149.328125, + "actorWidth": 112, + "actorHeight": 149.328125, + "videoFit": "contain", + "bottom": 647, + "viewportHeight": 768 + }, + { + "origin": "http://192.168.31.168:6180", + "viewport": { + "width": 1366, + "height": 768 + }, + "mode": "audio", + "width": 112, + "height": 149.328125, + "actorWidth": 112, + "actorHeight": 149.328125, + "videoFit": "contain", + "bottom": 647, + "viewportHeight": 768 + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-label-20260915/index.html b/reports/bridge-digital-video-label-20260915/index.html new file mode 100644 index 0000000..f8604d5 --- /dev/null +++ b/reports/bridge-digital-video-label-20260915/index.html @@ -0,0 +1 @@ +Digital instructor label removal

Digital instructor label removed

Local and LAN preview verified; video playback works. No training records created.

Verification dataLocal previewLAN preview \ No newline at end of file diff --git a/reports/bridge-digital-video-label-20260915/lan.png b/reports/bridge-digital-video-label-20260915/lan.png new file mode 100644 index 0000000..bec27e8 Binary files /dev/null and b/reports/bridge-digital-video-label-20260915/lan.png differ diff --git a/reports/bridge-digital-video-label-20260915/local.png b/reports/bridge-digital-video-label-20260915/local.png new file mode 100644 index 0000000..a8792b4 Binary files /dev/null and b/reports/bridge-digital-video-label-20260915/local.png differ diff --git a/reports/bridge-digital-video-label-20260915/result.json b/reports/bridge-digital-video-label-20260915/result.json new file mode 100644 index 0000000..6b84105 --- /dev/null +++ b/reports/bridge-digital-video-label-20260915/result.json @@ -0,0 +1,17 @@ +{ + "checks": [ + { + "origin": "http://127.0.0.1:6180", + "labelRemoved": true, + "videoPlaying": true, + "file": "local.png" + }, + { + "origin": "http://192.168.31.168:6180", + "labelRemoved": true, + "videoPlaying": true, + "file": "lan.png" + } + ], + "testDataCreated": false +} \ No newline at end of file diff --git a/reports/bridge-digital-video-static-20260915/ACCEPTANCE.md b/reports/bridge-digital-video-static-20260915/ACCEPTANCE.md new file mode 100644 index 0000000..fd1add5 --- /dev/null +++ b/reports/bridge-digital-video-static-20260915/ACCEPTANCE.md @@ -0,0 +1,59 @@ +# 四套桥梁流程 v2 数字人讲解验收 + +2026-09-15;本机 Windows,教员1 v2;使用负责人已确认的 005 第一步样片参数。 + +## 交付 + +- TASK-VIRTUAL-005:5 段;006:7 段;007:11 段;008:16 段,共 39 段。 +- MP4 位于 `unreal_tran_web/public/legacy/virtual-training/videos/narration/`,已进入前端 `dist`,采用静态地址播放。 +- 总时长 264.24 秒,总大小 17,727,827 字节;480×640、25 FPS、H.264/AAC。 +- 005 第一步与已确认样片逐字节相同。其余步骤复用各自原讲解音轨,以同一教员1 v2 和捕获方法生成。 +- 任务 86–89 的发布版本 533–536 保留;39 个服务端步骤与讲解清单匹配。本次未创建或改写任务、版本、运行或成绩。 +- 原 39 个视频与 42 个 WAV 的 SHA-256 均保持一致。讲解可切回语音,视频失败自动使用保留的语音。 + +## 验证结果 + +- 所有 39 段完整解码通过,编码、尺寸、帧率和时长检查通过。 +- 39 段均存在有效声音,见 `delivery-validation.json` 中音量记录。 +- `public`、`dist`、本机 HTTP 下载、局域网 HTTP 下载的全部文件摘要一致;视频 Range 请求返回 206。 +- 逐段预览页包含 39 个有效视频链接;每套流程抽帧检查,画面正常。 +- 本机 `http://127.0.0.1:6180` 与局域网 `http://192.168.31.168:6180` 各测试四个真实任务的教员预览。页面用现有登录及教学 API,经同源 `/api` 访问配置的 Gateway 6100。 +- 每套检查第一、第二步实际静态视频播放,切换语音/视频,三维操作后切步停止旧视频,损坏视频时回退 WAV,刷新后播放和关闭教员停止。两个环境均通过,页面脚本错误为 0,旧讲解资产下载为 0。 +- 预览验证使用内部维护账号;未生成测试任务、学员运行或测试成绩。 + +## 已执行命令 + +在数字人 API 目录,使用既有 Python 环境: + +```powershell +python ../../unreal_tran/ute2e/tools/bridge-digital-video-static-generate.py +``` + +在 `unreal_tran_web`: + +```powershell +pnpm run build +node --test scripts/bridge-digital-video.contract.test.mjs scripts/bridge-script-narration.test.mjs +node --test scripts/bridge-scripts-3d-only.test.mjs +node scripts/virtual-training-formal-route.contract.test.mjs +``` + +构建成功,11 项视频/语音测试及 2 项三维脚本测试通过,正式入口契约通过。Vite 仍提示部分既有包超过 500 kB,不影响构建。 + +在 `ute2e`: + +```powershell +node tools/bridge-digital-video-static-live.mjs +$env:BASE_URL = 'http://192.168.31.168:6180' +node tools/bridge-digital-video-static-live.mjs +node tools/bridge-digital-video-static-delivery.mjs +``` + +## 证据 + +- `index.html`:39 段视频集中预览。 +- `generation.json`、`manifest.json`:素材来源、逐步对应及文件摘要。 +- `delivery-validation.json`:全部视频、保留文件、构建输出和两处 HTTP 地址的验证。 +- `live-result.json`、`lan-result.json`:实际页面交互结果。 +- `TASK-VIRTUAL-005-video.png` 至 `TASK-VIRTUAL-008-video.png`:项目内播放截图。 +- 各任务 `*-frame.jpg`:生成视频抽帧。 diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-005-frame.jpg b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-005-frame.jpg new file mode 100644 index 0000000..9cb2cd6 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-005-frame.jpg differ diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-005-video.png b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-005-video.png new file mode 100644 index 0000000..b58d958 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-005-video.png differ diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-006-frame.jpg b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-006-frame.jpg new file mode 100644 index 0000000..e8e84fe Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-006-frame.jpg differ diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-006-video.png b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-006-video.png new file mode 100644 index 0000000..94798e2 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-006-video.png differ diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-007-frame.jpg b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-007-frame.jpg new file mode 100644 index 0000000..cadb1e8 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-007-frame.jpg differ diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-007-video.png b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-007-video.png new file mode 100644 index 0000000..45cafc8 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-007-video.png differ diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-008-frame.jpg b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-008-frame.jpg new file mode 100644 index 0000000..b34ea39 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-008-frame.jpg differ diff --git a/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-008-video.png b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-008-video.png new file mode 100644 index 0000000..a592901 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/TASK-VIRTUAL-008-video.png differ diff --git a/reports/bridge-digital-video-static-20260915/capture/narration.wav b/reports/bridge-digital-video-static-20260915/capture/narration.wav new file mode 100644 index 0000000..7906139 Binary files /dev/null and b/reports/bridge-digital-video-static-20260915/capture/narration.wav differ diff --git a/reports/bridge-digital-video-static-20260915/delivery-validation.json b/reports/bridge-digital-video-static-20260915/delivery-validation.json new file mode 100644 index 0000000..9480c36 --- /dev/null +++ b/reports/bridge-digital-video-static-20260915/delivery-validation.json @@ -0,0 +1,181 @@ +{ + "clips": 39, + "checks": [ + { + "origin": "http://127.0.0.1:6180", + "playableUrls": 39, + "exactFiles": true, + "rangeRequests": true + }, + { + "origin": "http://192.168.31.168:6180", + "playableUrls": 39, + "exactFiles": true, + "rangeRequests": true + } + ], + "buildFilesVerified": 39, + "audibleNarrations": [ + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "meanVolumeDb": -24.7 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4", + "meanVolumeDb": -25.9 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-03-81ea8dc0e23da76d.mp4", + "meanVolumeDb": -25.6 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-04-aa6bbd5769344dc0.mp4", + "meanVolumeDb": -26.1 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-05-422f9e85bb468fd5.mp4", + "meanVolumeDb": -25.7 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "meanVolumeDb": -25.6 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4", + "meanVolumeDb": -25.9 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-03-d0d26b774e96a981.mp4", + "meanVolumeDb": -26.5 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-04-a7cafe4130983380.mp4", + "meanVolumeDb": -26 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-05-ef62a148cdeb4c73.mp4", + "meanVolumeDb": -25.1 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-06-f4bb8c70dc263869.mp4", + "meanVolumeDb": -25.7 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-07-84f943a4e5a9bbc8.mp4", + "meanVolumeDb": -25.5 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "meanVolumeDb": -25.3 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4", + "meanVolumeDb": -25.5 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-03-9e2b426e945678f0.mp4", + "meanVolumeDb": -25.5 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-04-fe998d3697e1a463.mp4", + "meanVolumeDb": -25.9 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-05-e0348b0ea0055779.mp4", + "meanVolumeDb": -25.2 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-06-488750524bd2c0a8.mp4", + "meanVolumeDb": -25.4 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-07-5dbddd64c54251a5.mp4", + "meanVolumeDb": -26.1 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-08-5ca9062502638806.mp4", + "meanVolumeDb": -24.7 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-09-e8782919d61b49b9.mp4", + "meanVolumeDb": -25.4 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-10-c14fe764c6a78575.mp4", + "meanVolumeDb": -25.8 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-11-c06a4be476669d7f.mp4", + "meanVolumeDb": -25.2 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "meanVolumeDb": -26.5 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4", + "meanVolumeDb": -25.7 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-03-8dba240adff9be00.mp4", + "meanVolumeDb": -26.4 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-04-24da11990de8e484.mp4", + "meanVolumeDb": -25.7 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-05-714a15e72dfa2832.mp4", + "meanVolumeDb": -26 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-06-5478cc2211086156.mp4", + "meanVolumeDb": -25.6 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-07-98bf30b8947911aa.mp4", + "meanVolumeDb": -26 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-08-2101b2ebb4bf1783.mp4", + "meanVolumeDb": -25.5 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-09-74cedc700826b5d5.mp4", + "meanVolumeDb": -26.2 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-10-32f16dc6b235d2d6.mp4", + "meanVolumeDb": -26.6 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-11-41511d4a555dca5e.mp4", + "meanVolumeDb": -25 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-12-81396098754fccab.mp4", + "meanVolumeDb": -25.9 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-13-672e69748f537f2f.mp4", + "meanVolumeDb": -26.7 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-14-0eaebfde856428f8.mp4", + "meanVolumeDb": -26.6 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-15-31ab069954b685be.mp4", + "meanVolumeDb": -25.4 + }, + { + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-16-ab6b316a229cd837.mp4", + "meanVolumeDb": -26.2 + } + ], + "originalVideosPreserved": 39, + "originalWavsPreserved": 42, + "totalDuration": 264.24, + "totalBytes": 17727827, + "taskDataMutated": false +} \ No newline at end of file diff --git a/reports/bridge-digital-video-static-20260915/generation.json b/reports/bridge-digital-video-static-20260915/generation.json new file mode 100644 index 0000000..2b56a39 --- /dev/null +++ b/reports/bridge-digital-video-static-20260915/generation.json @@ -0,0 +1,525 @@ +{ + "profile": { + "avatarName": "教员1", + "materialVersion": "v2", + "providerAvatarId": "a1000000000000000000000000000005", + "avatarManifestSha256": "8155a21af68b60ea024c7591c8ad454aa9884a2c7d22cb069c16bb192bc4e122", + "renderer": "OpenGenerationWorker.capture", + "width": 480, + "height": 640, + "fps": 25, + "videoCodec": "h264", + "audioCodec": "aac", + "encoding": "libx264 veryfast crf20 yuv420p / aac 128k faststart", + "audioSource": "existing step narration, unchanged" + }, + "clips": [ + { + "key": "bridge-pump-switch:2:front-pump-step-01", + "code": "TASK-VIRTUAL-005", + "number": 1, + "stepCode": "front-pump-step-01", + "text": "第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "duration": 4.96, + "sha256": "7db0b2653aa8719268764ff4fb4f1ede92c947b9f4603308ce2ad7d0903ac45c", + "sourceVideoSha256": "d5c992479f2893d3efbe20921dab1f82fcc8ab4c4f512477fe4e0ea636e8fb7f", + "audioSha256": "8aa3cc38efd5d6f68fd49226f933c7821434f35f4f022e241b7827f87c4fbcae", + "reused": "approved sample" + }, + { + "key": "bridge-pump-switch:2:front-pump-step-02", + "code": "TASK-VIRTUAL-005", + "number": 2, + "stepCode": "front-pump-step-02", + "text": "第2步,断开架桥车取力器。将架桥车取力器断开。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4", + "duration": 4.16, + "sha256": "421922b32e5a9cb84c2fef6d1b026918044af2ce1ce0b725a89b60900d2052ef", + "sourceVideoSha256": "69ae89ec5e3d4a5ccd3efce23f33707ee4b3a236b398235ad133ee34f793a9ba", + "audioSha256": "e9ecb259431a08c4a5790d1d62527740a13b3a4395accc096abaf2520c31b7db", + "reused": false + }, + { + "key": "bridge-pump-switch:2:front-pump-step-03", + "code": "TASK-VIRTUAL-005", + "number": 3, + "stepCode": "front-pump-step-03", + "text": "第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-03-81ea8dc0e23da76d.mp4", + "duration": 8.36, + "sha256": "4ff18d5fa228f6c040d39ec4f435fcac9eb9bfe768f108a27f57577ebcada362", + "sourceVideoSha256": "c9ac26a8d58e52d7dc57c28b1c6f9134de780f65b29e1eef1e8351eb51753758", + "audioSha256": "418622b7eeb0d5e8f292dff4c97f7b968711f706b373fdc3b483602452fd19cd", + "reused": false + }, + { + "key": "bridge-pump-switch:2:front-pump-step-04", + "code": "TASK-VIRTUAL-005", + "number": 4, + "stepCode": "front-pump-step-04", + "text": "第4步,重新接通取力器。将架桥车取力器重新接通。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-04-aa6bbd5769344dc0.mp4", + "duration": 4.2, + "sha256": "e841b61cf522ed5f1633b8569eba04bc17ee77d777f811ddbb2334abb856f2cb", + "sourceVideoSha256": "383d1fe0a6a80112c7b8868ae1edfdbeadbc86c13ce6feec1a9721ba3d9881fe", + "audioSha256": "32a8e79992d73c93d1e180ba2c815452834eff978e409ae1b37db8462ab870a1", + "reused": false + }, + { + "key": "bridge-pump-switch:2:front-pump-step-05", + "code": "TASK-VIRTUAL-005", + "number": 5, + "stepCode": "front-pump-step-05", + "text": "第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-05-422f9e85bb468fd5.mp4", + "duration": 6.8, + "sha256": "6def38648367bbd7475e7bcba40d407d8530e9bbbdda128121c320ccd252275c", + "sourceVideoSha256": "2d53c0bef4d8aa71d8b8535de676d2d8485929de06534ce3aab677805bc8eef3", + "audioSha256": "dce992c07154e02e13aeb3e841e5e288201f33523258ed007934738a30d2f28b", + "reused": false + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-1", + "code": "TASK-VIRTUAL-006", + "number": 1, + "stepCode": "BRIDGE-STEP-1", + "text": "第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "duration": 7.84, + "sha256": "87b2c3c11e2170f6be3e11c35d353e19a9772101d881b06d827912a97623ca18", + "sourceVideoSha256": "d82bb8354acfca494e2ff515e5ef79887fb9d1f929a62779119d136857944ba6", + "audioSha256": "96b1207fd760747646da5bbdd5ef37a298cf42e5fe3b154d686b1420b9ad768d", + "reused": false + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-2", + "code": "TASK-VIRTUAL-006", + "number": 2, + "stepCode": "BRIDGE-STEP-2", + "text": "第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4", + "duration": 9.72, + "sha256": "19ecd4d56bd96f6c513f43abc2f5baaf8d0f53dae3edfaceda51dc82a9014f05", + "sourceVideoSha256": "8791296620dbb4cc823bab5f24af07b8b48d510292b4baf966598b0b0351e4f9", + "audioSha256": "7c6ae05db51fed139ffeed56daff1467311eb8aaca85cb58b1bc17923f0fc177", + "reused": false + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-3", + "code": "TASK-VIRTUAL-006", + "number": 3, + "stepCode": "BRIDGE-STEP-3", + "text": "第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-03-d0d26b774e96a981.mp4", + "duration": 5.76, + "sha256": "216e6300b28fcf5b34bb9afe8bf1339870d2d31dc8d2780f66bd4a338622878c", + "sourceVideoSha256": "f78a59ebddcd35e937ce42910aed82fcaf9b49c07be4e1d460fc701e666d3d29", + "audioSha256": "5ef12fcdec4faef5231329fecfcd143da326041451cf3346a5f5a13c1034f5df", + "reused": false + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-4", + "code": "TASK-VIRTUAL-006", + "number": 4, + "stepCode": "BRIDGE-STEP-4", + "text": "第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-04-a7cafe4130983380.mp4", + "duration": 5.16, + "sha256": "1c22bb9066f42642903038fd2c6272603a5e758d95edf5f7f2447c9be82eb8a1", + "sourceVideoSha256": "a784a79790a96f486eb6be917fa879db7071813a31f461f5d95d31c754ce3f46", + "audioSha256": "e4391d76106266b79fe58b7f2eeb30f1da0842770d821af5df0957c37e3803e3", + "reused": false + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-5", + "code": "TASK-VIRTUAL-006", + "number": 5, + "stepCode": "BRIDGE-STEP-5", + "text": "第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-05-ef62a148cdeb4c73.mp4", + "duration": 5.96, + "sha256": "6aa84f6c7ed9017ec1789b70357d4163364512951568a028658a76b2a4566a72", + "sourceVideoSha256": "db5c8f4a531e958712d309f25f9c51a145f717e4687893fcc41b65e2c8242175", + "audioSha256": "4555e828a1c485bc2cb96e2c30b3fdc2c98d6821e53cd742c5fa811e435197ad", + "reused": false + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-6", + "code": "TASK-VIRTUAL-006", + "number": 6, + "stepCode": "BRIDGE-STEP-6", + "text": "第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-06-f4bb8c70dc263869.mp4", + "duration": 6.0, + "sha256": "b4f70d76acf8bfc50952c2d981f8910d0da865a32639bb972508409e19404b1f", + "sourceVideoSha256": "05ffeff41d2cf4162b6e8181d4d002ba3f12531589a25d31bac76c69f5dea6bb", + "audioSha256": "eb3367b25e89f4624c692ece93f7af9000e6a38f210061adab485646552f6243", + "reused": false + }, + { + "key": "bridge-pump-substitute:3:BRIDGE-STEP-7", + "code": "TASK-VIRTUAL-006", + "number": 7, + "stepCode": "BRIDGE-STEP-7", + "text": "第7步,按正常步骤操作架桥车。原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。该项为原稿概括项,本预演不代表后续正常作业已经完成。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-07-84f943a4e5a9bbc8.mp4", + "duration": 10.88, + "sha256": "27d1c3c9666a176028bad6892d318082b6a85ca729e36f7f4e8920738b3f95d1", + "sourceVideoSha256": "7b85bbf9c21adc74b56a26f6d92db1448f9f565101da6feba7ca9ad4cdd137f7", + "audioSha256": "95918b6e90dc79a278ec106fadc46538368a8d6994f0aa381df6b6fded8bf896", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-1", + "code": "TASK-VIRTUAL-007", + "number": 1, + "stepCode": "BRIDGE-STEP-1", + "text": "第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "duration": 6.64, + "sha256": "cbaf3a71793502c3f08262bba414c78c1565ba68e32f0dd51b82efaf35070ca7", + "sourceVideoSha256": "22c92b853a9460ee67c7ae80d5bc203ff8aba07b32e148659b13f0637fb2c372", + "audioSha256": "26993cf0832f20dc91a58a131de53e9a79121b11890644ae3bd603005c394618", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-2", + "code": "TASK-VIRTUAL-007", + "number": 2, + "stepCode": "BRIDGE-STEP-2", + "text": "第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4", + "duration": 6.56, + "sha256": "1f1b83d60763eb2d71fd06654c6ace25cb73bd69bd7f31a72f930bbd75f6f72b", + "sourceVideoSha256": "eab74c71b3be41e3c7563a4a36c75e3f61e5ad4a5ca032eab051844ca10943fe", + "audioSha256": "5d0f9abfa1931f872b02c7b70fc3a8502c195c05b4dda5b0f8ec3b6c7e86bc8e", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-3", + "code": "TASK-VIRTUAL-007", + "number": 3, + "stepCode": "BRIDGE-STEP-3", + "text": "第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-03-9e2b426e945678f0.mp4", + "duration": 7.0, + "sha256": "2b81b7b187f3445c2c72b1135ccc6a82b131635ff1de9fd2c42da7b70ceb95ce", + "sourceVideoSha256": "63765c1da028750da4063a9d27c2211e592325165213d667c6592890cde982f0", + "audioSha256": "083bb86399ecdf712a11f16071efb676f3276d6a506afb181aa8a5e8554ebd08", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-4", + "code": "TASK-VIRTUAL-007", + "number": 4, + "stepCode": "BRIDGE-STEP-4", + "text": "第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-04-fe998d3697e1a463.mp4", + "duration": 6.92, + "sha256": "6f49c2a6cdf334ef439ca1dd5b31ea8c31a6b0c39e5820bd821fe6f001cb7a3e", + "sourceVideoSha256": "e5b743ebe6fad8f7b614b11aea9d611fda877b02d9c31a8d67cabd41249327fe", + "audioSha256": "d553905b72fa82fef067c4d15bd383c8e147ee702bfa5d70fa9235330f808fb1", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-5", + "code": "TASK-VIRTUAL-007", + "number": 5, + "stepCode": "BRIDGE-STEP-5", + "text": "第5步,取下旧前泵。取下原前泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-05-e0348b0ea0055779.mp4", + "duration": 3.08, + "sha256": "4ed2cee9a68503af9951909cf0162c03e978ff9fc5665a918bb3e634952547e1", + "sourceVideoSha256": "25ce8b12c5e17a2029d04a20fd53d270eed3904f50a4d7ea63bc83e33e18bd51", + "audioSha256": "0637951703cd4280bfd078dbda997679f8d18faea7a7aaccdbb68b8fc922e215", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-6", + "code": "TASK-VIRTUAL-007", + "number": 6, + "stepCode": "BRIDGE-STEP-6", + "text": "第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-06-488750524bd2c0a8.mp4", + "duration": 6.76, + "sha256": "be089ff024fb7166a408613a5f0afc1a19b4a33672f8be5d07b4347824900e48", + "sourceVideoSha256": "db8bae8bfbde4f6e6dacb645eb2652f355f3b754a73012aaec3afee0e62ab9e8", + "audioSha256": "11804f763bcd9c5a43cfc0e447bc71bdd34ca64754be1b27ff4adf43317beb09", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-7", + "code": "TASK-VIRTUAL-007", + "number": 7, + "stepCode": "BRIDGE-STEP-7", + "text": "第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-07-5dbddd64c54251a5.mp4", + "duration": 5.0, + "sha256": "513e55b9110879d17d7bf45cc726b6642646731a657c0a276cc3c749ca768637", + "sourceVideoSha256": "56ece26b2bab4af67bd59f88a3f4d1b08bfcdd083f423300d8d88f4ff4cae84b", + "audioSha256": "2def2464a750a8c348c64154de2f17e341541187366a3957c781cd14df37c7b9", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-8", + "code": "TASK-VIRTUAL-007", + "number": 8, + "stepCode": "BRIDGE-STEP-8", + "text": "第8步,安装新液压泵。安装新的液压泵。原稿没有给出拧紧力矩。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-08-5ca9062502638806.mp4", + "duration": 4.84, + "sha256": "bcd805461e072ce4ddad0ab0ba4dd6b442feed395bac3a16694224237a8ef550", + "sourceVideoSha256": "1b8f68d21c2300b2bba451f5e22cbaafd6f2dcd0bf0d213c05a4caad53ce0ef0", + "audioSha256": "ba95019b136540567cca0eaaf3a21e14b81f5320ff77fe5127455153665662bd", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-9", + "code": "TASK-VIRTUAL-007", + "number": 9, + "stepCode": "BRIDGE-STEP-9", + "text": "第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-09-e8782919d61b49b9.mp4", + "duration": 6.84, + "sha256": "946b6a086fc885b47a956717d378d7e8e061b7dde9e473478ebeb084dfb21d08", + "sourceVideoSha256": "095363c1f6be506fa3377330abbf88050dc9ffdd8dac07eb2c5476ea4ec32abe", + "audioSha256": "8e77bc7290a4563644a914cb8607052a6f8c4288946a764e8fa8e269b08eaf0c", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-10", + "code": "TASK-VIRTUAL-007", + "number": 10, + "stepCode": "BRIDGE-STEP-10", + "text": "第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-10-c14fe764c6a78575.mp4", + "duration": 5.36, + "sha256": "7f51d9ff1ce26c7a29ed6de1543a49883c0a46cad20e262c87aec79eb9a3afec", + "sourceVideoSha256": "eba4316082aa74841fe07f82c644484630efac95228a9b919b1d5348f76d06d8", + "audioSha256": "ebfd250f2910887894f60882475e8a94dcd47a9759c9132b3d37678827a6827d", + "reused": false + }, + { + "key": "bridge-pump-replace:3:BRIDGE-STEP-11", + "code": "TASK-VIRTUAL-007", + "number": 11, + "stepCode": "BRIDGE-STEP-11", + "text": "第11步,启动设备试验。启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-11-c06a4be476669d7f.mp4", + "duration": 6.08, + "sha256": "f48cc129f98b980130fc9616fdbfb5d8e9750c3c4fc687bb9da32ccf373158ef", + "sourceVideoSha256": "4fed628e2847089de8882bb29da648f5aa3c00acf696123c11e5e6c3d54a48bb", + "audioSha256": "d33510951c6e52d5f0a579f6797ce1c8fab9e850be4a68e4ef52a22a7ab80d91", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-1", + "code": "TASK-VIRTUAL-008", + "number": 1, + "stepCode": "BRIDGE-STEP-1", + "text": "第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "duration": 5.96, + "sha256": "e9f87d4d2f08b827e66a769344493c8475ff51a974c37283b2bfb3edfcaf60d4", + "sourceVideoSha256": "2e71eb4894d380917abb95245d3299e7c0b345c76a0a1df92610ba97c9d95e91", + "audioSha256": "72bdceefbec5d60d46f515cf4d5d74298e40b33b7b1b1f9ead69199b02bde179", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-2", + "code": "TASK-VIRTUAL-008", + "number": 2, + "stepCode": "BRIDGE-STEP-2", + "text": "第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4", + "duration": 7.2, + "sha256": "b8b4468ce061596ba616d6449c870627f5cc0d659786f0104a48406079990f4a", + "sourceVideoSha256": "a1abca193097f47595f32b71a02f4101a02005d0ff67cd4932fa728403d1235b", + "audioSha256": "5370895cf85adf9bceeb0603f51fb0208e2ffaee316ee33b51176230a18e49ca", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-3", + "code": "TASK-VIRTUAL-008", + "number": 3, + "stepCode": "BRIDGE-STEP-3", + "text": "第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-03-8dba240adff9be00.mp4", + "duration": 5.96, + "sha256": "63b2c9dd87654c9795d81c4dfa8149512dc0980b63e07990c0d0af3ad4515dba", + "sourceVideoSha256": "46f07ce2308478ba60b58d4f6ec600773632193ffaa83f42ed52c71b660d4da5", + "audioSha256": "4874f5b680c2a1b67732dac44592ac57c7942afc2f72a5710d544710fa50d177", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-4", + "code": "TASK-VIRTUAL-008", + "number": 4, + "stepCode": "BRIDGE-STEP-4", + "text": "第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-04-24da11990de8e484.mp4", + "duration": 4.96, + "sha256": "c70d5879a4261e52ff84dc70ad4916cf553136307819144c9f8dc42ac43eb023", + "sourceVideoSha256": "7fdab9117f713bd3e01aa1d956bfdbc4601df9f5b166b4a05488c1181ba12211", + "audioSha256": "2b04e68c50d7c67b6e9ec48208cc193bccf8fbf213c97b5b776f817e617affa3", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-5", + "code": "TASK-VIRTUAL-008", + "number": 5, + "stepCode": "BRIDGE-STEP-5", + "text": "第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-05-714a15e72dfa2832.mp4", + "duration": 6.0, + "sha256": "16cbea74ac0717dc600522796538740113c6c7018ff2ba7c341c2c90607e9a8b", + "sourceVideoSha256": "5a2649d18c9cef179863c09cf8179668b34f1d253d1b340b3775509bdd057433", + "audioSha256": "f9a51ee91040ad6953a52db950fe4679cc512fedae7f599529ba07eebfbd71e2", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-6", + "code": "TASK-VIRTUAL-008", + "number": 6, + "stepCode": "BRIDGE-STEP-6", + "text": "第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-06-5478cc2211086156.mp4", + "duration": 7.32, + "sha256": "3064f526e6a887cd892628420b0860240044f5bff9ab6b1431ab289f78d30fc2", + "sourceVideoSha256": "8c3679991ac10e63383a40c2deffb1a9fdb5b79cbb692db64fda410e2b13b923", + "audioSha256": "e3123023bf92ee63500d5f8b39f6711e953d56fdd2bd732f419348fc8b97f281", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-7", + "code": "TASK-VIRTUAL-008", + "number": 7, + "stepCode": "BRIDGE-STEP-7", + "text": "第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-07-98bf30b8947911aa.mp4", + "duration": 6.0, + "sha256": "098359d57fcd11fb7fcaaeff0d237373462674b7fe6fafcce03bbf6f5cb1a722", + "sourceVideoSha256": "d8e749aee075d99707af8b1a6b9a6700f7b0349c19e9bbd5957f55f43e9c50af", + "audioSha256": "27f556b276bd0fff214421d5f4fbeaf4a997ed639b17f4a0cc95872edebcce65", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-8", + "code": "TASK-VIRTUAL-008", + "number": 8, + "stepCode": "BRIDGE-STEP-8", + "text": "第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-08-2101b2ebb4bf1783.mp4", + "duration": 5.4, + "sha256": "93c9f6c1ce727c7363b04b7f2ff359cb2b9509363ef597a1f20c30e5bac371d0", + "sourceVideoSha256": "3d3c67dfa76d776bcafee0e35412de7c44190b74776f93d426e6d9947fd7bb2c", + "audioSha256": "041ea29b89f5539d6b85e2c4716abee135cd30983b639b76c744379e16d963e4", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-9", + "code": "TASK-VIRTUAL-008", + "number": 9, + "stepCode": "BRIDGE-STEP-9", + "text": "第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-09-74cedc700826b5d5.mp4", + "duration": 6.0, + "sha256": "eab74396df9583d53a0262ca9440d3469fbdd33b1278fa8cda2f5902b137e70e", + "sourceVideoSha256": "bd890674565a670e7994a60be84847b692a8b4820995c3063a497d8cc7eddf7e", + "audioSha256": "3173a6cbd597f668ef3ec9dff6577a50327a44b2a95c1ad649968cf6236c8b62", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-10", + "code": "TASK-VIRTUAL-008", + "number": 10, + "stepCode": "BRIDGE-STEP-10", + "text": "第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-10-32f16dc6b235d2d6.mp4", + "duration": 7.36, + "sha256": "e600a45218921a3e06a3af53b6575858e641c294ac3913a9ffb4e68d0a4d2d5a", + "sourceVideoSha256": "ed2ee749404179d67831c8f0c46cae21643c97700f431b5cb089f99644fb7d27", + "audioSha256": "7baf9850efb63bf3a003f07fd6c292179d34580608e743c327a1e9faf0696a52", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-11", + "code": "TASK-VIRTUAL-008", + "number": 11, + "stepCode": "BRIDGE-STEP-11", + "text": "第11步,核对大腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-11-41511d4a555dca5e.mp4", + "duration": 16.12, + "sha256": "879d72ebcbe9fdbb2c070add12cef9e837fe147e12de56a4d602a4fac78515c1", + "sourceVideoSha256": "e90845dc69d890c341d682f5d36b8880e83fe26bdad34fd8573ee0560d36d287", + "audioSha256": "b4eaf33eee4046620aa2737a2d4bbfe8b5508b37e3fb657eb1963f6b3ac0a968", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-12", + "code": "TASK-VIRTUAL-008", + "number": 12, + "stepCode": "BRIDGE-STEP-12", + "text": "第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-12-81396098754fccab.mp4", + "duration": 5.44, + "sha256": "355bf751999942f0e330115315ae31019b56a8263c237f041f7e54c5c4b1b81d", + "sourceVideoSha256": "133f1f65d5d88040d4ce758fdb7c0512c44d32f2affc5b0ce09f402f9fd687a5", + "audioSha256": "a9cb31535d85237c95cb7312ee1b18b866b41072199745ea97ea64d590fcc6a4", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-13", + "code": "TASK-VIRTUAL-008", + "number": 13, + "stepCode": "BRIDGE-STEP-13", + "text": "第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-13-672e69748f537f2f.mp4", + "duration": 6.0, + "sha256": "0023ab39f3a28981c8819d1f6492c486f64cab9c850bf510749fef58adb7bd2f", + "sourceVideoSha256": "7cf538b8754ccb0ada36395919cb9653d804717ec6a4d339dc8c62572697f27a", + "audioSha256": "24ed5b3eaac3f650ea221f4b76eee582bc368e057c29909599b18a499cac1116", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-14", + "code": "TASK-VIRTUAL-008", + "number": 14, + "stepCode": "BRIDGE-STEP-14", + "text": "第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-14-0eaebfde856428f8.mp4", + "duration": 7.76, + "sha256": "14ea83fb883f2657d38a3851ebbfd608bc975027c8ba9ebc54883a2543f3bbb8", + "sourceVideoSha256": "456843aa826f489cde689a55d4ffb3e3759b7f7464cc1fbdde6d7d7d216ef31f", + "audioSha256": "22e386e5efdd0ae1b316a70b12984ff281317636e549b7d99fdb855e9885d594", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-15", + "code": "TASK-VIRTUAL-008", + "number": 15, + "stepCode": "BRIDGE-STEP-15", + "text": "第15步,核对小腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-15-31ab069954b685be.mp4", + "duration": 16.24, + "sha256": "790d9617261add255912538c8dfff81a3ddc3acd5a8aff3d6efb6ac9931803ac", + "sourceVideoSha256": "2a47835ce52868b09ecec6fe380098b412d29a8c2806519a54d15396e3473b57", + "audioSha256": "d658535364dd2c1265acbddabbb3ebf57768fcf1f040c45c8a866da35bf87029", + "reused": false + }, + { + "key": "bridge-balance-valve-swap:3:BRIDGE-STEP-16", + "code": "TASK-VIRTUAL-008", + "number": 16, + "stepCode": "BRIDGE-STEP-16", + "text": "第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-16-ab6b316a229cd837.mp4", + "duration": 5.64, + "sha256": "ea676012e2a34aa57bcbc616042d71f9bd4e56e7d29cc4958cd2e973de72ff30", + "sourceVideoSha256": "2e22f597ff2808e1b9e600c46c319f82cd91e2be0063bfc817c94d672c786213", + "audioSha256": "0edfb8d70abece780b793e4afbeebe64a20b95ec45868bdf5bc3e35c541e2c8d", + "reused": false + } + ] +} diff --git a/reports/bridge-digital-video-static-20260915/index.html b/reports/bridge-digital-video-static-20260915/index.html new file mode 100644 index 0000000..5e78813 --- /dev/null +++ b/reports/bridge-digital-video-static-20260915/index.html @@ -0,0 +1 @@ +桥梁讲解 · 教员1 v2

四套桥梁流程 · 教员1 v2 讲解

39 段视频已生成到前端 public 目录。点击播放;原语音与上一版视频保留。

TASK-VIRTUAL-005 · 重型支援桥液压泵应急切换

第 1 步

第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。

4.96 秒 · 打开视频

第 2 步

第2步,断开架桥车取力器。将架桥车取力器断开。

4.16 秒 · 打开视频

第 3 步

第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。

8.36 秒 · 打开视频

第 4 步

第4步,重新接通取力器。将架桥车取力器重新接通。

4.20 秒 · 打开视频

第 5 步

第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。

6.80 秒 · 打开视频

TASK-VIRTUAL-006 · 重型支援桥液压泵应急替代

第 1 步

第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。

7.84 秒 · 打开视频

第 2 步

第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。

9.72 秒 · 打开视频

第 3 步

第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。

5.76 秒 · 打开视频

第 4 步

第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。

5.16 秒 · 打开视频

第 5 步

第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。

5.96 秒 · 打开视频

第 6 步

第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。

6.00 秒 · 打开视频

第 7 步

第7步,按正常步骤操作架桥车。原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。该项为原稿概括项,本预演不代表后续正常作业已经完成。

10.88 秒 · 打开视频

TASK-VIRTUAL-007 · 重型支援桥前泵换件修复

第 1 步

第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。

6.64 秒 · 打开视频

第 2 步

第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。

6.56 秒 · 打开视频

第 3 步

第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。

7.00 秒 · 打开视频

第 4 步

第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。

6.92 秒 · 打开视频

第 5 步

第5步,取下旧前泵。取下原前泵。

3.08 秒 · 打开视频

第 6 步

第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。

6.76 秒 · 打开视频

第 7 步

第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。

5.00 秒 · 打开视频

第 8 步

第8步,安装新液压泵。安装新的液压泵。原稿没有给出拧紧力矩。

4.84 秒 · 打开视频

第 9 步

第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。原稿没有给出定量值。

6.84 秒 · 打开视频

第 10 步

第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。

5.36 秒 · 打开视频

第 11 步

第11步,启动设备试验。启动设备进行试验。原稿没有展开具体试验项目和判定数值。

6.08 秒 · 打开视频

TASK-VIRTUAL-008 · 重型支援桥平衡阀拆拼互换

第 1 步

第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。

5.96 秒 · 打开视频

第 2 步

第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。

7.20 秒 · 打开视频

第 3 步

第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。

5.96 秒 · 打开视频

第 4 步

第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。

4.96 秒 · 打开视频

第 5 步

第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。

6.00 秒 · 打开视频

第 6 步

第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。

7.32 秒 · 打开视频

第 7 步

第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。

6.00 秒 · 打开视频

第 8 步

第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。

5.40 秒 · 打开视频

第 9 步

第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。

6.00 秒 · 打开视频

第 10 步

第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。

7.36 秒 · 打开视频

第 11 步

第11步,核对大腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。

16.12 秒 · 打开视频

第 12 步

第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。

5.44 秒 · 打开视频

第 13 步

第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。

6.00 秒 · 打开视频

第 14 步

第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。

7.76 秒 · 打开视频

第 15 步

第15步,核对小腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。

16.24 秒 · 打开视频

第 16 步

第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。

5.64 秒 · 打开视频

\ No newline at end of file diff --git a/reports/bridge-digital-video-static-20260915/lan-result.json b/reports/bridge-digital-video-static-20260915/lan-result.json new file mode 100644 index 0000000..b1fe3c3 --- /dev/null +++ b/reports/bridge-digital-video-static-20260915/lan-result.json @@ -0,0 +1,58 @@ +{ + "origin": "http://192.168.31.168:6180", + "results": [ + { + "code": "TASK-VIRTUAL-005", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-006", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-007", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-008", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4" + ], + "obsoleteAssetDownloads": 0 + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-static-20260915/live-result.json b/reports/bridge-digital-video-static-20260915/live-result.json new file mode 100644 index 0000000..09d5e5c --- /dev/null +++ b/reports/bridge-digital-video-static-20260915/live-result.json @@ -0,0 +1,58 @@ +{ + "origin": "http://127.0.0.1:6180", + "results": [ + { + "code": "TASK-VIRTUAL-005", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-006", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-007", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-008", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4" + ], + "obsoleteAssetDownloads": 0 + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-static-20260915/manifest.json b/reports/bridge-digital-video-static-20260915/manifest.json new file mode 100644 index 0000000..0e71b92 --- /dev/null +++ b/reports/bridge-digital-video-static-20260915/manifest.json @@ -0,0 +1,440 @@ +{ + "profile": { + "avatarName": "教员1", + "materialVersion": "v2", + "providerAvatarId": "a1000000000000000000000000000005", + "avatarManifestSha256": "8155a21af68b60ea024c7591c8ad454aa9884a2c7d22cb069c16bb192bc4e122", + "renderer": "OpenGenerationWorker.capture", + "width": 480, + "height": 640, + "fps": 25, + "videoCodec": "h264", + "audioCodec": "aac", + "encoding": "libx264 veryfast crf20 yuv420p / aac 128k faststart", + "audioSource": "existing step narration, unchanged" + }, + "scripts": [ + { + "id": "bridge-pump-switch", + "version": "2", + "code": "TASK-VIRTUAL-005", + "title": "重型支援桥液压泵应急切换", + "steps": [ + { + "stepCode": "front-pump-step-01", + "number": 1, + "expectedTitle": "根据故障现象确定是哪一个液压泵发生故障", + "expectedInstruction": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "text": "第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "duration": 4.96, + "sha256": "7db0b2653aa8719268764ff4fb4f1ede92c947b9f4603308ce2ad7d0903ac45c" + }, + { + "stepCode": "front-pump-step-02", + "number": 2, + "expectedTitle": "断开架桥车取力器", + "expectedInstruction": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "text": "第2步,断开架桥车取力器。将架桥车取力器断开。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4", + "duration": 4.16, + "sha256": "421922b32e5a9cb84c2fef6d1b026918044af2ce1ce0b725a89b60900d2052ef" + }, + { + "stepCode": "front-pump-step-03", + "number": 3, + "expectedTitle": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "expectedInstruction": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "text": "第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-03-81ea8dc0e23da76d.mp4", + "duration": 8.36, + "sha256": "4ff18d5fa228f6c040d39ec4f435fcac9eb9bfe768f108a27f57577ebcada362" + }, + { + "stepCode": "front-pump-step-04", + "number": 4, + "expectedTitle": "重新联通取力器", + "expectedInstruction": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "text": "第4步,重新接通取力器。将架桥车取力器重新接通。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-04-aa6bbd5769344dc0.mp4", + "duration": 4.2, + "sha256": "e841b61cf522ed5f1633b8569eba04bc17ee77d777f811ddbb2334abb856f2cb" + }, + { + "stepCode": "front-pump-step-05", + "number": 5, + "expectedTitle": "打开辅助控制盒内的“互救”开关", + "expectedInstruction": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "text": "第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-05-422f9e85bb468fd5.mp4", + "duration": 6.8, + "sha256": "6def38648367bbd7475e7bcba40d407d8530e9bbbdda128121c320ccd252275c" + } + ] + }, + { + "id": "bridge-pump-substitute", + "version": "3", + "code": "TASK-VIRTUAL-006", + "title": "重型支援桥液压泵应急替代", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "保持架桥车运行并断开取力器", + "expectedInstruction": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "text": "第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "duration": 7.84, + "sha256": "87b2c3c11e2170f6be3e11c35d353e19a9772101d881b06d827912a97623ca18" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "连接两车液压软管", + "expectedInstruction": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "text": "第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4", + "duration": 9.72, + "sha256": "19ecd4d56bd96f6c513f43abc2f5baaf8d0f53dae3edfaceda51dc82a9014f05" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "打开支援车回油截止阀", + "expectedInstruction": "打开支援车液压油箱快接接头处的回油截止阀。", + "text": "第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-03-d0d26b774e96a981.mp4", + "duration": 5.76, + "sha256": "216e6300b28fcf5b34bb9afe8bf1339870d2d31dc8d2780f66bd4a338622878c" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "打开互救作业开关", + "expectedInstruction": "打开辅助控制盒上的“互救作业”开关。", + "text": "第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-04-a7cafe4130983380.mp4", + "duration": 5.16, + "sha256": "1c22bb9066f42642903038fd2c6272603a5e758d95edf5f7f2447c9be82eb8a1" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "打开滤油器出口连通球阀", + "expectedInstruction": "打开两个输油滤油器出口处的连通球阀。", + "text": "第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-05-ef62a148cdeb4c73.mp4", + "duration": 5.96, + "sha256": "6aa84f6c7ed9017ec1789b70357d4163364512951568a028658a76b2a4566a72" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "接通支援车液压取力器", + "expectedInstruction": "接通支援车液压系统取力器,向架桥车供油。", + "text": "第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-06-f4bb8c70dc263869.mp4", + "duration": 6.0, + "sha256": "b4f70d76acf8bfc50952c2d981f8910d0da865a32639bb972508409e19404b1f" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "按正常步骤操作架桥车", + "expectedInstruction": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "text": "第7步,按正常步骤操作架桥车。原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。该项为原稿概括项,本预演不代表后续正常作业已经完成。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-07-84f943a4e5a9bbc8.mp4", + "duration": 10.88, + "sha256": "27d1c3c9666a176028bad6892d318082b6a85ca729e36f7f4e8920738b3f95d1" + } + ] + }, + { + "id": "bridge-pump-replace", + "version": "3", + "code": "TASK-VIRTUAL-007", + "title": "重型支援桥前泵换件修复", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "停机并初裁牛皮纸", + "expectedInstruction": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "text": "第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "duration": 6.64, + "sha256": "cbaf3a71793502c3f08262bba414c78c1565ba68e32f0dd51b82efaf35070ca7" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "关闭液压油箱出油口一号球阀", + "expectedInstruction": "将一号球阀手柄从平行管道转到垂直管道。", + "text": "第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4", + "duration": 6.56, + "sha256": "1f1b83d60763eb2d71fd06654c6ace25cb73bd69bd7f31a72f930bbd75f6f72b" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆开并包扎进出油管", + "expectedInstruction": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "text": "第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-03-9e2b426e945678f0.mp4", + "duration": 7.0, + "sha256": "2b81b7b187f3445c2c72b1135ccc6a82b131635ff1de9fd2c42da7b70ceb95ce" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "拆下四个安装螺栓", + "expectedInstruction": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "text": "第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-04-fe998d3697e1a463.mp4", + "duration": 6.92, + "sha256": "6f49c2a6cdf334ef439ca1dd5b31ea8c31a6b0c39e5820bd821fe6f001cb7a3e" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "取下旧前泵", + "expectedInstruction": "取下原前泵。", + "text": "第5步,取下旧前泵。取下原前泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-05-e0348b0ea0055779.mp4", + "duration": 3.08, + "sha256": "4ed2cee9a68503af9951909cf0162c03e978ff9fc5665a918bb3e634952547e1" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "修裁牛皮纸", + "expectedInstruction": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "text": "第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-06-488750524bd2c0a8.mp4", + "duration": 6.76, + "sha256": "be089ff024fb7166a408613a5f0afc1a19b4a33672f8be5d07b4347824900e48" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "放置牛皮纸垫", + "expectedInstruction": "将裁好的牛皮纸放在取力器接口处。", + "text": "第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-07-5dbddd64c54251a5.mp4", + "duration": 5.0, + "sha256": "513e55b9110879d17d7bf45cc726b6642646731a657c0a276cc3c749ca768637" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "安装新液压泵", + "expectedInstruction": "安装新的液压泵。原稿没有给出拧紧力矩。", + "text": "第8步,安装新液压泵。安装新的液压泵。原稿没有给出拧紧力矩。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-08-5ca9062502638806.mp4", + "duration": 4.84, + "sha256": "bcd805461e072ce4ddad0ab0ba4dd6b442feed395bac3a16694224237a8ef550" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "向新泵加注液压油", + "expectedInstruction": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "text": "第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-09-e8782919d61b49b9.mp4", + "duration": 6.84, + "sha256": "946b6a086fc885b47a956717d378d7e8e061b7dde9e473478ebeb084dfb21d08" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "恢复进出油管连接", + "expectedInstruction": "用大活动扳手连接并拧紧液压泵进、出油管。", + "text": "第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-10-c14fe764c6a78575.mp4", + "duration": 5.36, + "sha256": "7f51d9ff1ce26c7a29ed6de1543a49883c0a46cad20e262c87aec79eb9a3afec" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "启动设备试验", + "expectedInstruction": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "text": "第11步,启动设备试验。启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-11-c06a4be476669d7f.mp4", + "duration": 6.08, + "sha256": "f48cc129f98b980130fc9616fdbfb5d8e9750c3c4fc687bb9da32ccf373158ef" + } + ] + }, + { + "id": "bridge-balance-valve-swap", + "version": "3", + "code": "TASK-VIRTUAL-008", + "title": "重型支援桥平衡阀拆拼互换", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "清洗小腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "duration": 5.96, + "sha256": "e9f87d4d2f08b827e66a769344493c8475ff51a974c37283b2bfb3edfcaf60d4" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "拆开小腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4", + "duration": 7.2, + "sha256": "b8b4468ce061596ba616d6449c870627f5cc0d659786f0104a48406079990f4a" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆下小腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-03-8dba240adff9be00.mp4", + "duration": 5.96, + "sha256": "63b2c9dd87654c9795d81c4dfa8149512dc0980b63e07990c0d0af3ad4515dba" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "封堵小腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-04-24da11990de8e484.mp4", + "duration": 4.96, + "sha256": "c70d5879a4261e52ff84dc70ad4916cf553136307819144c9f8dc42ac43eb023" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "清洗大腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-05-714a15e72dfa2832.mp4", + "duration": 6.0, + "sha256": "16cbea74ac0717dc600522796538740113c6c7018ff2ba7c341c2c90607e9a8b" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "拆开大腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-06-5478cc2211086156.mp4", + "duration": 7.32, + "sha256": "3064f526e6a887cd892628420b0860240044f5bff9ab6b1431ab289f78d30fc2" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "拆下大腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-07-98bf30b8947911aa.mp4", + "duration": 6.0, + "sha256": "098359d57fcd11fb7fcaaeff0d237373462674b7fe6fafcce03bbf6f5cb1a722" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "封堵大腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-08-2101b2ebb4bf1783.mp4", + "duration": 5.4, + "sha256": "93c9f6c1ce727c7363b04b7f2ff359cb2b9509363ef597a1f20c30e5bac371d0" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "准备安装大腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-09-74cedc700826b5d5.mp4", + "duration": 6.0, + "sha256": "eab74396df9583d53a0262ca9440d3469fbdd33b1278fa8cda2f5902b137e70e" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "安装大腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-10-32f16dc6b235d2d6.mp4", + "duration": 7.36, + "sha256": "e600a45218921a3e06a3af53b6575858e641c294ac3913a9ffb4e68d0a4d2d5a" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "核对大腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第11步,核对大腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-11-41511d4a555dca5e.mp4", + "duration": 16.12, + "sha256": "879d72ebcbe9fdbb2c070add12cef9e837fe147e12de56a4d602a4fac78515c1" + }, + { + "stepCode": "BRIDGE-STEP-12", + "number": 12, + "expectedTitle": "紧固大腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-12-81396098754fccab.mp4", + "duration": 5.44, + "sha256": "355bf751999942f0e330115315ae31019b56a8263c237f041f7e54c5c4b1b81d" + }, + { + "stepCode": "BRIDGE-STEP-13", + "number": 13, + "expectedTitle": "准备安装小腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-13-672e69748f537f2f.mp4", + "duration": 6.0, + "sha256": "0023ab39f3a28981c8819d1f6492c486f64cab9c850bf510749fef58adb7bd2f" + }, + { + "stepCode": "BRIDGE-STEP-14", + "number": 14, + "expectedTitle": "安装小腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-14-0eaebfde856428f8.mp4", + "duration": 7.76, + "sha256": "14ea83fb883f2657d38a3851ebbfd608bc975027c8ba9ebc54883a2543f3bbb8" + }, + { + "stepCode": "BRIDGE-STEP-15", + "number": 15, + "expectedTitle": "核对小腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第15步,核对小腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-15-31ab069954b685be.mp4", + "duration": 16.24, + "sha256": "790d9617261add255912538c8dfff81a3ddc3acd5a8aff3d6efb6ac9931803ac" + }, + { + "stepCode": "BRIDGE-STEP-16", + "number": 16, + "expectedTitle": "紧固小腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-16-ab6b316a229cd837.mp4", + "duration": 5.64, + "sha256": "ea676012e2a34aa57bcbc616042d71f9bd4e56e7d29cc4958cd2e973de72ff30" + } + ] + } + ] +} diff --git a/reports/bridge-digital-video-v2-sample-20260915/TASK-VIRTUAL-005-step-01-v2.mp4 b/reports/bridge-digital-video-v2-sample-20260915/TASK-VIRTUAL-005-step-01-v2.mp4 new file mode 100644 index 0000000..f627c15 Binary files /dev/null and b/reports/bridge-digital-video-v2-sample-20260915/TASK-VIRTUAL-005-step-01-v2.mp4 differ diff --git a/reports/bridge-digital-video-v2-sample-20260915/comparison.png b/reports/bridge-digital-video-v2-sample-20260915/comparison.png new file mode 100644 index 0000000..431c84f Binary files /dev/null and b/reports/bridge-digital-video-v2-sample-20260915/comparison.png differ diff --git a/reports/bridge-digital-video-v2-sample-20260915/frame-0.8.jpg b/reports/bridge-digital-video-v2-sample-20260915/frame-0.8.jpg new file mode 100644 index 0000000..c97ddab Binary files /dev/null and b/reports/bridge-digital-video-v2-sample-20260915/frame-0.8.jpg differ diff --git a/reports/bridge-digital-video-v2-sample-20260915/frame-2.0.jpg b/reports/bridge-digital-video-v2-sample-20260915/frame-2.0.jpg new file mode 100644 index 0000000..daab848 Binary files /dev/null and b/reports/bridge-digital-video-v2-sample-20260915/frame-2.0.jpg differ diff --git a/reports/bridge-digital-video-v2-sample-20260915/frame-3.2.jpg b/reports/bridge-digital-video-v2-sample-20260915/frame-3.2.jpg new file mode 100644 index 0000000..ba67bea Binary files /dev/null and b/reports/bridge-digital-video-v2-sample-20260915/frame-3.2.jpg differ diff --git a/reports/bridge-digital-video-v2-sample-20260915/index.html b/reports/bridge-digital-video-v2-sample-20260915/index.html new file mode 100644 index 0000000..410ae41 --- /dev/null +++ b/reports/bridge-digital-video-v2-sample-20260915/index.html @@ -0,0 +1,20 @@ + + + + +005 液压泵应急切换 · 教员1 v2 对比 + +
+

005:液压泵应急切换 · 第1步

讲解:第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。

2026-09-15 · 教员1 · 沿用旧片讲解音频 · 480 × 640 · 25 FPS

下载 v2 新片
+
+

原素材 旧片保留

+

v2 新素材 本次生成 · 4.96 秒

+
+ +
diff --git a/reports/bridge-digital-video-v2-sample-20260915/original-audio.wav b/reports/bridge-digital-video-v2-sample-20260915/original-audio.wav new file mode 100644 index 0000000..29f63c4 Binary files /dev/null and b/reports/bridge-digital-video-v2-sample-20260915/original-audio.wav differ diff --git a/reports/bridge-digital-video-v2-sample-20260915/playback-validation.json b/reports/bridge-digital-video-v2-sample-20260915/playback-validation.json new file mode 100644 index 0000000..f71401b --- /dev/null +++ b/reports/bridge-digital-video-v2-sample-20260915/playback-validation.json @@ -0,0 +1,21 @@ +{ + "errors": [], + "result": [ + { + "id": "old", + "duration": 5.08, + "width": 480, + "height": 640, + "error": null, + "muted": true + }, + { + "id": "fresh", + "duration": 4.96, + "width": 480, + "height": 640, + "error": null, + "muted": false + } + ] +} \ No newline at end of file diff --git a/reports/bridge-digital-video-v2-sample-20260915/result.json b/reports/bridge-digital-video-v2-sample-20260915/result.json new file mode 100644 index 0000000..90498d0 --- /dev/null +++ b/reports/bridge-digital-video-v2-sample-20260915/result.json @@ -0,0 +1,171 @@ +{ + "avatarName": "教员1", + "materialVersion": "v2", + "providerAvatarId": "a1000000000000000000000000000005", + "text": "第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。", + "audioSource": "E:\\work\\edit_3d\\unreal_tran\\ute2e\\reports\\bridge-digital-video-20260914\\TASK-VIRTUAL-005-step-01.mp4", + "audioSha256": "8aa3cc38efd5d6f68fd49226f933c7821434f35f4f022e241b7827f87c4fbcae", + "originalSha256": "d5c992479f2893d3efbe20921dab1f82fcc8ab4c4f512477fe4e0ea636e8fb7f", + "outputSha256": "7db0b2653aa8719268764ff4fb4f1ede92c947b9f4603308ce2ad7d0903ac45c", + "output": "E:\\work\\edit_3d\\unreal_tran\\ute2e\\reports\\bridge-digital-video-v2-sample-20260915\\TASK-VIRTUAL-005-step-01-v2.mp4", + "renderEngine": "OpenGenerationWorker.capture / open_render_capture.js (unchanged)", + "liveAvatarManifest": { + "version": 1, + "created_at": "2026-09-14T15:57:38.109202+00:00", + "device": "cpu", + "matting_mode": "off", + "resize": true, + "source_frame_count": 251, + "width": 720, + "height": 960, + "fps": 25.0, + "frame_count": 502, + "duration": 20.08, + "files": { + "01.mp4": 3959109, + "combined_data.json.gz": 147484, + "thumbnail.jpg": 31865 + } + }, + "metadata": { + "streams": [ + { + "index": 0, + "codec_name": "h264", + "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", + "profile": "High", + "codec_type": "video", + "codec_tag_string": "avc1", + "codec_tag": "0x31637661", + "width": 480, + "height": 640, + "coded_width": 480, + "coded_height": 640, + "closed_captions": 0, + "film_grain": 0, + "has_b_frames": 2, + "sample_aspect_ratio": "1:1", + "display_aspect_ratio": "3:4", + "pix_fmt": "yuv420p", + "level": 30, + "color_range": "tv", + "color_space": "bt470bg", + "chroma_location": "left", + "field_order": "progressive", + "refs": 1, + "is_avc": "true", + "nal_length_size": "4", + "id": "0x1", + "r_frame_rate": "25/1", + "avg_frame_rate": "25/1", + "time_base": "1/12800", + "start_pts": 0, + "start_time": "0.000000", + "duration_ts": 63488, + "duration": "4.960000", + "bit_rate": "420335", + "bits_per_raw_sample": "8", + "nb_frames": "124", + "extradata_size": 49, + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "non_diegetic": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "handler_name": "VideoHandler", + "vendor_id": "[0][0][0][0]", + "encoder": "Lavc61.3.100 libx264" + } + }, + { + "index": 1, + "codec_name": "aac", + "codec_long_name": "AAC (Advanced Audio Coding)", + "profile": "LC", + "codec_type": "audio", + "codec_tag_string": "mp4a", + "codec_tag": "0x6134706d", + "sample_fmt": "fltp", + "sample_rate": "48000", + "channels": 2, + "channel_layout": "stereo", + "bits_per_sample": 0, + "initial_padding": 0, + "id": "0x2", + "r_frame_rate": "0/0", + "avg_frame_rate": "0/0", + "time_base": "1/48000", + "start_pts": 3408, + "start_time": "0.071000", + "duration_ts": 225640, + "duration": "4.700833", + "bit_rate": "126787", + "nb_frames": "221", + "extradata_size": 5, + "disposition": { + "default": 1, + "dub": 0, + "original": 0, + "comment": 0, + "lyrics": 0, + "karaoke": 0, + "forced": 0, + "hearing_impaired": 0, + "visual_impaired": 0, + "clean_effects": 0, + "attached_pic": 0, + "timed_thumbnails": 0, + "non_diegetic": 0, + "captions": 0, + "descriptions": 0, + "metadata": 0, + "dependent": 0, + "still_image": 0 + }, + "tags": { + "language": "eng", + "handler_name": "SoundHandler", + "vendor_id": "[0][0][0][0]" + } + } + ], + "format": { + "filename": "E:\\work\\edit_3d\\unreal_tran\\ute2e\\reports\\bridge-digital-video-v2-sample-20260915\\TASK-VIRTUAL-005-step-01-v2.mp4", + "nb_streams": 2, + "nb_programs": 0, + "nb_stream_groups": 0, + "format_name": "mov,mp4,m4a,3gp,3g2,mj2", + "format_long_name": "QuickTime / MOV", + "start_time": "0.000000", + "duration": "4.960000", + "size": "340847", + "bit_rate": "549753", + "probe_score": 100, + "tags": { + "major_brand": "isom", + "minor_version": "512", + "compatible_brands": "isomiso2avc1mp41", + "encoder": "Lavf61.1.100" + } + } + }, + "originalPreserved": true, + "publishedTaskBindingsChanged": false +} \ No newline at end of file diff --git a/reports/bridge-lecture-polish-20260915/before-video-manifest.json b/reports/bridge-lecture-polish-20260915/before-video-manifest.json new file mode 100644 index 0000000..a9d3edc --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/before-video-manifest.json @@ -0,0 +1,440 @@ +{ + "profile": { + "avatarName": "教员1", + "materialVersion": "v2", + "providerAvatarId": "a1000000000000000000000000000005", + "avatarManifestSha256": "8155a21af68b60ea024c7591c8ad454aa9884a2c7d22cb069c16bb192bc4e122", + "renderer": "OpenGenerationWorker.capture", + "width": 480, + "height": 640, + "fps": 25, + "videoCodec": "h264", + "audioCodec": "aac", + "encoding": "libx264 veryfast crf20 yuv420p / aac 128k faststart", + "audioSource": "existing step narration, unchanged" + }, + "scripts": [ + { + "id": "bridge-pump-switch", + "version": "2", + "code": "TASK-VIRTUAL-005", + "title": "重型支援桥液压泵应急切换", + "steps": [ + { + "stepCode": "front-pump-step-01", + "number": 1, + "expectedTitle": "根据故障现象确定是哪一个液压泵发生故障", + "expectedInstruction": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "text": "第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "duration": 4.96, + "sha256": "7db0b2653aa8719268764ff4fb4f1ede92c947b9f4603308ce2ad7d0903ac45c" + }, + { + "stepCode": "front-pump-step-02", + "number": 2, + "expectedTitle": "断开架桥车取力器", + "expectedInstruction": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "text": "第2步,断开架桥车取力器。将架桥车取力器断开。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4", + "duration": 4.16, + "sha256": "421922b32e5a9cb84c2fef6d1b026918044af2ce1ce0b725a89b60900d2052ef" + }, + { + "stepCode": "front-pump-step-03", + "number": 3, + "expectedTitle": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "expectedInstruction": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "text": "第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-03-81ea8dc0e23da76d.mp4", + "duration": 8.36, + "sha256": "4ff18d5fa228f6c040d39ec4f435fcac9eb9bfe768f108a27f57577ebcada362" + }, + { + "stepCode": "front-pump-step-04", + "number": 4, + "expectedTitle": "重新联通取力器", + "expectedInstruction": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "text": "第4步,重新接通取力器。将架桥车取力器重新接通。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-04-aa6bbd5769344dc0.mp4", + "duration": 4.2, + "sha256": "e841b61cf522ed5f1633b8569eba04bc17ee77d777f811ddbb2334abb856f2cb" + }, + { + "stepCode": "front-pump-step-05", + "number": 5, + "expectedTitle": "打开辅助控制盒内的“互救”开关", + "expectedInstruction": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "text": "第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-05-422f9e85bb468fd5.mp4", + "duration": 6.8, + "sha256": "6def38648367bbd7475e7bcba40d407d8530e9bbbdda128121c320ccd252275c" + } + ] + }, + { + "id": "bridge-pump-substitute", + "version": "3", + "code": "TASK-VIRTUAL-006", + "title": "重型支援桥液压泵应急替代", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "保持架桥车运行并断开取力器", + "expectedInstruction": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "text": "第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "duration": 7.84, + "sha256": "87b2c3c11e2170f6be3e11c35d353e19a9772101d881b06d827912a97623ca18" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "连接两车液压软管", + "expectedInstruction": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "text": "第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4", + "duration": 9.72, + "sha256": "19ecd4d56bd96f6c513f43abc2f5baaf8d0f53dae3edfaceda51dc82a9014f05" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "打开支援车回油截止阀", + "expectedInstruction": "打开支援车液压油箱快接接头处的回油截止阀。", + "text": "第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-03-d0d26b774e96a981.mp4", + "duration": 5.76, + "sha256": "216e6300b28fcf5b34bb9afe8bf1339870d2d31dc8d2780f66bd4a338622878c" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "打开互救作业开关", + "expectedInstruction": "打开辅助控制盒上的“互救作业”开关。", + "text": "第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-04-a7cafe4130983380.mp4", + "duration": 5.16, + "sha256": "1c22bb9066f42642903038fd2c6272603a5e758d95edf5f7f2447c9be82eb8a1" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "打开滤油器出口连通球阀", + "expectedInstruction": "打开两个输油滤油器出口处的连通球阀。", + "text": "第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-05-ef62a148cdeb4c73.mp4", + "duration": 5.96, + "sha256": "6aa84f6c7ed9017ec1789b70357d4163364512951568a028658a76b2a4566a72" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "接通支援车液压取力器", + "expectedInstruction": "接通支援车液压系统取力器,向架桥车供油。", + "text": "第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-06-f4bb8c70dc263869.mp4", + "duration": 6, + "sha256": "b4f70d76acf8bfc50952c2d981f8910d0da865a32639bb972508409e19404b1f" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "按正常步骤操作架桥车", + "expectedInstruction": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "text": "第7步,按正常步骤操作架桥车。原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。该项为原稿概括项,本预演不代表后续正常作业已经完成。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-07-84f943a4e5a9bbc8.mp4", + "duration": 10.88, + "sha256": "27d1c3c9666a176028bad6892d318082b6a85ca729e36f7f4e8920738b3f95d1" + } + ] + }, + { + "id": "bridge-pump-replace", + "version": "3", + "code": "TASK-VIRTUAL-007", + "title": "重型支援桥前泵换件修复", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "停机并初裁牛皮纸", + "expectedInstruction": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "text": "第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "duration": 6.64, + "sha256": "cbaf3a71793502c3f08262bba414c78c1565ba68e32f0dd51b82efaf35070ca7" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "关闭液压油箱出油口一号球阀", + "expectedInstruction": "将一号球阀手柄从平行管道转到垂直管道。", + "text": "第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4", + "duration": 6.56, + "sha256": "1f1b83d60763eb2d71fd06654c6ace25cb73bd69bd7f31a72f930bbd75f6f72b" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆开并包扎进出油管", + "expectedInstruction": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "text": "第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-03-9e2b426e945678f0.mp4", + "duration": 7, + "sha256": "2b81b7b187f3445c2c72b1135ccc6a82b131635ff1de9fd2c42da7b70ceb95ce" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "拆下四个安装螺栓", + "expectedInstruction": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "text": "第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-04-fe998d3697e1a463.mp4", + "duration": 6.92, + "sha256": "6f49c2a6cdf334ef439ca1dd5b31ea8c31a6b0c39e5820bd821fe6f001cb7a3e" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "取下旧前泵", + "expectedInstruction": "取下原前泵。", + "text": "第5步,取下旧前泵。取下原前泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-05-e0348b0ea0055779.mp4", + "duration": 3.08, + "sha256": "4ed2cee9a68503af9951909cf0162c03e978ff9fc5665a918bb3e634952547e1" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "修裁牛皮纸", + "expectedInstruction": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "text": "第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-06-488750524bd2c0a8.mp4", + "duration": 6.76, + "sha256": "be089ff024fb7166a408613a5f0afc1a19b4a33672f8be5d07b4347824900e48" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "放置牛皮纸垫", + "expectedInstruction": "将裁好的牛皮纸放在取力器接口处。", + "text": "第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-07-5dbddd64c54251a5.mp4", + "duration": 5, + "sha256": "513e55b9110879d17d7bf45cc726b6642646731a657c0a276cc3c749ca768637" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "安装新液压泵", + "expectedInstruction": "安装新的液压泵。原稿没有给出拧紧力矩。", + "text": "第8步,安装新液压泵。安装新的液压泵。原稿没有给出拧紧力矩。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-08-5ca9062502638806.mp4", + "duration": 4.84, + "sha256": "bcd805461e072ce4ddad0ab0ba4dd6b442feed395bac3a16694224237a8ef550" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "向新泵加注液压油", + "expectedInstruction": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "text": "第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-09-e8782919d61b49b9.mp4", + "duration": 6.84, + "sha256": "946b6a086fc885b47a956717d378d7e8e061b7dde9e473478ebeb084dfb21d08" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "恢复进出油管连接", + "expectedInstruction": "用大活动扳手连接并拧紧液压泵进、出油管。", + "text": "第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-10-c14fe764c6a78575.mp4", + "duration": 5.36, + "sha256": "7f51d9ff1ce26c7a29ed6de1543a49883c0a46cad20e262c87aec79eb9a3afec" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "启动设备试验", + "expectedInstruction": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "text": "第11步,启动设备试验。启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-11-c06a4be476669d7f.mp4", + "duration": 6.08, + "sha256": "f48cc129f98b980130fc9616fdbfb5d8e9750c3c4fc687bb9da32ccf373158ef" + } + ] + }, + { + "id": "bridge-balance-valve-swap", + "version": "3", + "code": "TASK-VIRTUAL-008", + "title": "重型支援桥平衡阀拆拼互换", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "清洗小腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "duration": 5.96, + "sha256": "e9f87d4d2f08b827e66a769344493c8475ff51a974c37283b2bfb3edfcaf60d4" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "拆开小腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4", + "duration": 7.2, + "sha256": "b8b4468ce061596ba616d6449c870627f5cc0d659786f0104a48406079990f4a" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆下小腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-03-8dba240adff9be00.mp4", + "duration": 5.96, + "sha256": "63b2c9dd87654c9795d81c4dfa8149512dc0980b63e07990c0d0af3ad4515dba" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "封堵小腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-04-24da11990de8e484.mp4", + "duration": 4.96, + "sha256": "c70d5879a4261e52ff84dc70ad4916cf553136307819144c9f8dc42ac43eb023" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "清洗大腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-05-714a15e72dfa2832.mp4", + "duration": 6, + "sha256": "16cbea74ac0717dc600522796538740113c6c7018ff2ba7c341c2c90607e9a8b" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "拆开大腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-06-5478cc2211086156.mp4", + "duration": 7.32, + "sha256": "3064f526e6a887cd892628420b0860240044f5bff9ab6b1431ab289f78d30fc2" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "拆下大腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-07-98bf30b8947911aa.mp4", + "duration": 6, + "sha256": "098359d57fcd11fb7fcaaeff0d237373462674b7fe6fafcce03bbf6f5cb1a722" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "封堵大腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-08-2101b2ebb4bf1783.mp4", + "duration": 5.4, + "sha256": "93c9f6c1ce727c7363b04b7f2ff359cb2b9509363ef597a1f20c30e5bac371d0" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "准备安装大腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-09-74cedc700826b5d5.mp4", + "duration": 6, + "sha256": "eab74396df9583d53a0262ca9440d3469fbdd33b1278fa8cda2f5902b137e70e" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "安装大腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-10-32f16dc6b235d2d6.mp4", + "duration": 7.36, + "sha256": "e600a45218921a3e06a3af53b6575858e641c294ac3913a9ffb4e68d0a4d2d5a" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "核对大腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第11步,核对大腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-11-41511d4a555dca5e.mp4", + "duration": 16.12, + "sha256": "879d72ebcbe9fdbb2c070add12cef9e837fe147e12de56a4d602a4fac78515c1" + }, + { + "stepCode": "BRIDGE-STEP-12", + "number": 12, + "expectedTitle": "紧固大腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-12-81396098754fccab.mp4", + "duration": 5.44, + "sha256": "355bf751999942f0e330115315ae31019b56a8263c237f041f7e54c5c4b1b81d" + }, + { + "stepCode": "BRIDGE-STEP-13", + "number": 13, + "expectedTitle": "准备安装小腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-13-672e69748f537f2f.mp4", + "duration": 6, + "sha256": "0023ab39f3a28981c8819d1f6492c486f64cab9c850bf510749fef58adb7bd2f" + }, + { + "stepCode": "BRIDGE-STEP-14", + "number": 14, + "expectedTitle": "安装小腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-14-0eaebfde856428f8.mp4", + "duration": 7.76, + "sha256": "14ea83fb883f2657d38a3851ebbfd608bc975027c8ba9ebc54883a2543f3bbb8" + }, + { + "stepCode": "BRIDGE-STEP-15", + "number": 15, + "expectedTitle": "核对小腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第15步,核对小腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-15-31ab069954b685be.mp4", + "duration": 16.24, + "sha256": "790d9617261add255912538c8dfff81a3ddc3acd5a8aff3d6efb6ac9931803ac" + }, + { + "stepCode": "BRIDGE-STEP-16", + "number": 16, + "expectedTitle": "紧固小腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-16-ab6b316a229cd837.mp4", + "duration": 5.64, + "sha256": "ea676012e2a34aa57bcbc616042d71f9bd4e56e7d29cc4958cd2e973de72ff30" + } + ] + } + ] +} diff --git a/reports/bridge-lecture-polish-20260915/deployment.json b/reports/bridge-lecture-polish-20260915/deployment.json new file mode 100644 index 0000000..aa88ce3 --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/deployment.json @@ -0,0 +1,11 @@ +{ + "verifiedAt": "2026-09-15T01:35:29+08:00", + "testServer": "1.14.103.234", + "webUrls": {"training": "http://1.14.103.234:6180", "digitalHuman": "http://1.14.103.234:7180"}, + "commits": {"unreal_tran_api": "40d2557b8c9843da4d96181faa96e9dbddfadb25", "unreal_tran_web": "af6b89dbfd56dc85eedca459186cb4e12996a86a", "ai_person_api": "093595e8423cdf74955d1baad49965ae9d95f3ab", "ai_person_web": "6635c82114cd336d0b5f8fabd34b14b13dccb86c", "ai_person_service": "ec0dbd499af0f11bda7c37bf4c985d080964ea1a"}, + "image": {"tag": "digital-human-service:lecture-v2-20260915", "runningId": "sha256:6d66dd620303ea162047d7a9713b30f0f36575750f1a9a03c4f44aaf58f7659d", "health": "healthy", "dataMount": "/home/digital-human-service/data"}, + "apiReleases": {"training": "/home/unreal_tran/releases/api/20260915_013113", "digitalHuman": "/home/ai_person/releases/api/20260915_013258"}, + "backups": ["/home/unreal_tran/backups/test-release-20260915_012848", "/home/ai_person/backups/test-release-20260915_012848"], + "checks": {"gateway": "UP", "digitalHumanApi": "ok", "digitalHumanService": "ok", "avatarBundles": "All 3 avatars: manifest, video, blend data and thumbnail HTTP SHA-256 equal source files", "pendingAiMigrations": 0}, + "serviceVerification": "/home/digital-human-service/releases/lecture-v2-20260915/final-verification.json" +} diff --git a/reports/bridge-lecture-polish-20260915/index.html b/reports/bridge-lecture-polish-20260915/index.html new file mode 100644 index 0000000..4e6d847 --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/index.html @@ -0,0 +1 @@ +桥梁数字教员讲解修正验收

桥梁数字教员讲解修正验收 · 2026-09-15

四套任务共39段讲解,6段重新生成。默认视频模式,等待场景加载完成后播放;保留语音切换与旧文件。右上角按内容自动排列,移除“三维实时交互”角标。公开浮窗显示真实教员头像,移除阴影和头像绿点。

验证:local 浏览器回归 文件校验 · lan 浏览器回归 文件校验。另通过前端构建、14项脚本契约测试、562项Java测试、2项公开头像接口测试。

本次重新生成的6段

TASK-VIRTUAL-006 · 第7步

第7步,按正常步骤操作架桥车。按正常操作步骤操作架桥车。

4.88s · 已替换 · 原文件保留
TASK-VIRTUAL-007 · 第8步

第8步,安装新液压泵。安装新的液压泵。

3.36s · 已替换 · 原文件保留
TASK-VIRTUAL-007 · 第9步

第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。

4.96s · 已替换 · 原文件保留
TASK-VIRTUAL-007 · 第11步

第11步,启动设备试验。启动设备进行试验。

3.28s · 已替换 · 原文件保留
TASK-VIRTUAL-008 · 第11步

第11步,核对大腔控制油口管路连接。核对大腔控制油口管路连接,记录处理方式及依据,并提交教员核对。

8.48s · 已替换 · 原文件保留
TASK-VIRTUAL-008 · 第15步

第15步,核对小腔控制油口管路连接。核对小腔控制油口管路连接,记录处理方式及依据,并提交教员核对。

8.24s · 已替换 · 原文件保留

当前39段讲解清单

TASK-VIRTUAL-005 · 重型支援桥液压泵应急切换

  1. 根据故障现象确定是哪一个液压泵发生故障:第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。
  2. 断开架桥车取力器:第2步,断开架桥车取力器。将架桥车取力器断开。
  3. 将架桥车备胎斜上方链接两个红色滤油器的球阀打开:第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。
  4. 重新联通取力器:第4步,重新接通取力器。将架桥车取力器重新接通。
  5. 打开辅助控制盒内的“互救”开关:第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。

TASK-VIRTUAL-006 · 重型支援桥液压泵应急替代

  1. 保持架桥车运行并断开取力器:第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。
  2. 连接两车液压软管:第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。
  3. 打开支援车回油截止阀:第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。
  4. 打开互救作业开关:第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。
  5. 打开滤油器出口连通球阀:第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。
  6. 接通支援车液压取力器:第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。
  7. 按正常步骤操作架桥车:第7步,按正常步骤操作架桥车。按正常操作步骤操作架桥车。

TASK-VIRTUAL-007 · 重型支援桥前泵换件修复

  1. 停机并初裁牛皮纸:第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。
  2. 关闭液压油箱出油口一号球阀:第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。
  3. 拆开并包扎进出油管:第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。
  4. 拆下四个安装螺栓:第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。
  5. 取下旧前泵:第5步,取下旧前泵。取下原前泵。
  6. 修裁牛皮纸:第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。
  7. 放置牛皮纸垫:第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。
  8. 安装新液压泵:第8步,安装新液压泵。安装新的液压泵。
  9. 向新泵加注液压油:第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。
  10. 恢复进出油管连接:第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。
  11. 启动设备试验:第11步,启动设备试验。启动设备进行试验。

TASK-VIRTUAL-008 · 重型支援桥平衡阀拆拼互换

  1. 清洗小腔平衡阀:第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。
  2. 拆开小腔控制油口管路:第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。
  3. 拆下小腔平衡阀:第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。
  4. 封堵小腔油口:第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。
  5. 清洗大腔平衡阀:第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。
  6. 拆开大腔控制油口管路:第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。
  7. 拆下大腔平衡阀:第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。
  8. 封堵大腔油口:第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。
  9. 准备安装大腔平衡阀:第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。
  10. 安装大腔平衡阀:第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。
  11. 核对大腔控制油口管路连接:第11步,核对大腔控制油口管路连接。核对大腔控制油口管路连接,记录处理方式及依据,并提交教员核对。
  12. 紧固大腔阀体连接螺栓:第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。
  13. 准备安装小腔平衡阀:第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。
  14. 安装小腔平衡阀:第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。
  15. 核对小腔控制油口管路连接:第15步,核对小腔控制油口管路连接。核对小腔控制油口管路连接,记录处理方式及依据,并提交教员核对。
  16. 紧固小腔阀体连接螺栓:第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。
\ No newline at end of file diff --git a/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-005.png b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-005.png new file mode 100644 index 0000000..b259895 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-005.png differ diff --git a/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-006.png b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-006.png new file mode 100644 index 0000000..f4ca66c Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-006.png differ diff --git a/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-007.png b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-007.png new file mode 100644 index 0000000..b357742 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-007.png differ diff --git a/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-008.png b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-008.png new file mode 100644 index 0000000..39b3989 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/lan/TASK-VIRTUAL-008.png differ diff --git a/reports/bridge-lecture-polish-20260915/lan/result.json b/reports/bridge-lecture-polish-20260915/lan/result.json new file mode 100644 index 0000000..70d43a2 --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/lan/result.json @@ -0,0 +1,82 @@ +{ + "origin": "http://192.168.31.168:6180", + "delayed": 8, + "checks": [ + { + "task": "TASK-VIRTUAL-005", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-006", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-007", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-008", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4" + } + ] + }, + { + "widget": "http://192.168.31.168:8003", + "avatarLoaded": true, + "avatar": "/avatars/builtin/equipment-instructor-1.png", + "greenDotRemoved": true, + "launcherAndPanelShadows": "none" + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-lecture-polish-20260915/lan/widget.png b/reports/bridge-lecture-polish-20260915/lan/widget.png new file mode 100644 index 0000000..e7212ac Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/lan/widget.png differ diff --git a/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-005.png b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-005.png new file mode 100644 index 0000000..864cc66 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-005.png differ diff --git a/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-006.png b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-006.png new file mode 100644 index 0000000..f65ee5b Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-006.png differ diff --git a/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-007.png b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-007.png new file mode 100644 index 0000000..9c32037 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-007.png differ diff --git a/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-008.png b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-008.png new file mode 100644 index 0000000..39b3989 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/local/TASK-VIRTUAL-008.png differ diff --git a/reports/bridge-lecture-polish-20260915/local/delivery.json b/reports/bridge-lecture-polish-20260915/local/delivery.json new file mode 100644 index 0000000..64b2ec6 --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/local/delivery.json @@ -0,0 +1,9 @@ +{ + "origin": "http://127.0.0.1:6180", + "videos": 39, + "audio": 41, + "allTextsClean": true, + "exactFiles": true, + "buildCopiesMatch": true, + "rangeRequests": true +} \ No newline at end of file diff --git a/reports/bridge-lecture-polish-20260915/local/failure.json b/reports/bridge-lecture-polish-20260915/local/failure.json new file mode 100644 index 0000000..18b759b --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/local/failure.json @@ -0,0 +1,74 @@ +{ + "message": "locator.getAttribute: Timeout 30000ms exceeded.\nCall log:\n\u001b[2m - waiting for locator('[data-testid=\"global-digital-human-widget\"]')\u001b[22m\n", + "checks": [ + { + "task": "TASK-VIRTUAL-005", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-006", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-007", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-008", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4" + } + ] + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-lecture-polish-20260915/local/failure.png b/reports/bridge-lecture-polish-20260915/local/failure.png new file mode 100644 index 0000000..cf9c3d6 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/local/failure.png differ diff --git a/reports/bridge-lecture-polish-20260915/local/result.json b/reports/bridge-lecture-polish-20260915/local/result.json new file mode 100644 index 0000000..d8ab21e --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/local/result.json @@ -0,0 +1,82 @@ +{ + "origin": "http://127.0.0.1:6180", + "delayed": 0, + "checks": [ + { + "task": "TASK-VIRTUAL-005", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-006", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-007", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4" + } + ] + }, + { + "task": "TASK-VIRTUAL-008", + "videoDefault": true, + "noPlaybackWhileLoading": true, + "autoplayRestrictionRetainsVideo": true, + "noHudOverlap": [ + 1920, + 1600, + 1366 + ], + "plays": [ + { + "loading": false, + "src": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4" + } + ] + }, + { + "widget": "http://127.0.0.1:8003", + "avatarLoaded": true, + "avatar": "/avatars/builtin/equipment-instructor-1.png", + "greenDotRemoved": true, + "launcherAndPanelShadows": "none" + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-lecture-polish-20260915/local/widget.png b/reports/bridge-lecture-polish-20260915/local/widget.png new file mode 100644 index 0000000..709b982 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/local/widget.png differ diff --git a/reports/bridge-lecture-polish-20260915/narration-manifest.json b/reports/bridge-lecture-polish-20260915/narration-manifest.json new file mode 100644 index 0000000..5eced91 --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/narration-manifest.json @@ -0,0 +1,481 @@ +{ + "voice": { + "engine": "sherpa-onnx-vits-zh-ll", + "modelSha256": "6c349bdd73dc928234dd7bc86929748bba32cd5264d32d915bf7b7aa0595965b", + "speaker": 1, + "speed": 0.85 + }, + "scripts": [ + { + "id": "bridge-pump-switch", + "version": "2", + "code": "TASK-VIRTUAL-005", + "title": "重型支援桥液压泵应急切换", + "source": "桥梁/文件2/4.jpg", + "steps": [ + { + "stepCode": "front-pump-step-01", + "number": 1, + "expectedTitle": "根据故障现象确定是哪一个液压泵发生故障", + "expectedInstruction": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "text": "第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-01-4b0be5be669cfeaf.wav", + "stepDuration": 4.863, + "stepSha256": "3b29f93a367e7f8738500a2adeb56dc4752ce91f17e3b5bf671d3ee0f7f080eb" + }, + { + "stepCode": "front-pump-step-02", + "number": 2, + "expectedTitle": "断开架桥车取力器", + "expectedInstruction": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "text": "第2步,断开架桥车取力器。将架桥车取力器断开。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-02-2e6be19cade105be.wav", + "stepDuration": 3.773, + "stepSha256": "6483f2df65230985db961bef38b3c55684bc623058fc8c0589e66f816d62dc29" + }, + { + "stepCode": "front-pump-step-03", + "number": 3, + "expectedTitle": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "expectedInstruction": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "text": "第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-03-b2401eb08aa0a8e8.wav", + "stepDuration": 8.262, + "stepSha256": "96f5889aa3ba307d05572b3912ebc5ac756b87957fddb2838e77a6b6f314296b" + }, + { + "stepCode": "front-pump-step-04", + "number": 4, + "expectedTitle": "重新联通取力器", + "expectedInstruction": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "text": "第4步,重新接通取力器。将架桥车取力器重新接通。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-04-98693ab8c5150fd5.wav", + "stepDuration": 4.158, + "stepSha256": "1cf2f643138ceddaf4c0cf5b751abe2e9f74437f68efb20e6acc5263311f1bc0" + }, + { + "stepCode": "front-pump-step-05", + "number": 5, + "expectedTitle": "打开辅助控制盒内的“互救”开关", + "expectedInstruction": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "text": "第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-05-a21afc5ebe5af2ee.wav", + "stepDuration": 6.7, + "stepSha256": "a6baf1bc2900f1daecbe77be41aeecc8914cc5ae3f170bbf7c7c7ded86f8a4a2" + } + ] + }, + { + "id": "bridge-pump-substitute", + "version": "3", + "code": "TASK-VIRTUAL-006", + "title": "重型支援桥液压泵应急替代", + "source": "桥梁/文件2/5.jpg、6.jpg", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "保持架桥车运行并断开取力器", + "expectedInstruction": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "text": "第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-01-7584e4158566d224.wav", + "stepDuration": 7.289, + "stepSha256": "7bd2bc0bab9f5009cb9bdae4d0b201e089cb18b7c2a5a5c5dee3fc8f215b0aa0" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "连接两车液压软管", + "expectedInstruction": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "text": "第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-02-63419c9269e953d9.wav", + "stepDuration": 9.548, + "stepSha256": "980996376e1eac8713b14fc6316e0ed1c611dce783341a45e85b6e6cc9d87d12" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "打开支援车回油截止阀", + "expectedInstruction": "打开支援车液压油箱快接接头处的回油截止阀。", + "text": "第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-03-0ae0974737dbd97d.wav", + "stepDuration": 5.583, + "stepSha256": "e07a1ae6033c7adca8b43a9eeedd8e69ae2d7d44613661ae6c93728276738dd7" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "打开互救作业开关", + "expectedInstruction": "打开辅助控制盒上的“互救作业”开关。", + "text": "第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-04-12baddb3a8f3bc1b.wav", + "stepDuration": 4.534, + "stepSha256": "916268d72d860334f7ca70c02c2611ee7a3ae407bba3293deb51068c9e727feb" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "打开滤油器出口连通球阀", + "expectedInstruction": "打开两个输油滤油器出口处的连通球阀。", + "text": "第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-05-0a5c8ac984f02d75.wav", + "stepDuration": 5.851, + "stepSha256": "01f49e5a2f42288e6fd52f19633637d17164d23c16c7dea0e9aa95e6808a8838" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "接通支援车液压取力器", + "expectedInstruction": "接通支援车液压系统取力器,向架桥车供油。", + "text": "第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-06-9a08c1ab2cc3229b.wav", + "stepDuration": 5.921, + "stepSha256": "4963fd312b6b021fbda36c1a96eef634b2ae7d8b5d72a76e01c5139502c9f40b" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "按正常步骤操作架桥车", + "expectedInstruction": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "text": "第7步,按正常步骤操作架桥车。按正常操作步骤操作架桥车。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-07-9fa9d42953215bdd.wav", + "stepDuration": 4.725, + "stepSha256": "2abb993085e1ad3a7ea7b4103d836cceab8a4d3821fcfaacf8799716882a16a2" + } + ] + }, + { + "id": "bridge-pump-replace", + "version": "3", + "code": "TASK-VIRTUAL-007", + "title": "重型支援桥前泵换件修复", + "source": "桥梁/文件2/7.jpg、8.jpg", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "停机并初裁牛皮纸", + "expectedInstruction": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "text": "第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-01-2de2b12cc45b7893.wav", + "stepDuration": 6.332, + "stepSha256": "2723f8e8db47cc3101bd88c1e5d0c57db1de676eeb10360e9c5ffaeafd483431" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "关闭液压油箱出油口一号球阀", + "expectedInstruction": "将一号球阀手柄从平行管道转到垂直管道。", + "text": "第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-02-7144daf79c235d5e.wav", + "stepDuration": 6.248, + "stepSha256": "b5a26f072f31dd75f813ef17f736eee0c1c5f3c49af87e9869f56d69714b7be9" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆开并包扎进出油管", + "expectedInstruction": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "text": "第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-03-005e99b68d7d893e.wav", + "stepDuration": 6.673, + "stepSha256": "f92e26bc1e413ef3511841511ad1b40b39a6f608d4d5439a28ddef996444825c" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "拆下四个安装螺栓", + "expectedInstruction": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "text": "第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-04-26852f94d435cfca.wav", + "stepDuration": 6.653, + "stepSha256": "599f8df6b367d3a1d846896ebb9d667059390f56d4fb9376756c685d1f47d98f" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "取下旧前泵", + "expectedInstruction": "取下原前泵。", + "text": "第5步,取下旧前泵。取下原前泵。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-05-ddb3fcb704bf7442.wav", + "stepDuration": 2.873, + "stepSha256": "ad5c7bbe9e306e758a650e6c6c58cfb6d918c2760634e64b8f97f7791ede8457" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "修裁牛皮纸", + "expectedInstruction": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "text": "第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-06-6f9c954385802ccc.wav", + "stepDuration": 6.481, + "stepSha256": "714bdd7183c866bfb1543d44bd3da7dd2fd5063dfadfba468bafe9b38dd6080f" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "放置牛皮纸垫", + "expectedInstruction": "将裁好的牛皮纸放在取力器接口处。", + "text": "第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-07-32e6e350e9bdf86c.wav", + "stepDuration": 4.54, + "stepSha256": "47d92fb06b17c9cdf32cc1e6d35551f4759ec2a157bf8f2a19c1a3bd3046973a" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "安装新液压泵", + "expectedInstruction": "安装新的液压泵。原稿没有给出拧紧力矩。", + "text": "第8步,安装新液压泵。安装新的液压泵。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-08-3ceca5450b18c4ba.wav", + "stepDuration": 3.13, + "stepSha256": "5dd1afc550ea20c1f728543dc01f6c4ce82af82c7cec216ee2452bc67d8291db" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "向新泵加注液压油", + "expectedInstruction": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "text": "第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-09-0bf9c5e7979deec8.wav", + "stepDuration": 4.805, + "stepSha256": "14cdc8dae461a998f820fc2e4fc8739a061b69e83ce0f6b9d6155c80c49d1b02" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "恢复进出油管连接", + "expectedInstruction": "用大活动扳手连接并拧紧液压泵进、出油管。", + "text": "第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-10-d8d77b3072c93264.wav", + "stepDuration": 5.074, + "stepSha256": "8107a88cadfc4d9d7e9d8d3887a1d521bf5606cb1e707e7b1fce6f37dd945477" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "启动设备试验", + "expectedInstruction": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "text": "第11步,启动设备试验。启动设备进行试验。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-11-7617879d42c2d4e2.wav", + "stepDuration": 3.056, + "stepSha256": "368b4ca3f55e9f20f2128d82db7b34283da0b53ef3fb8ffb7dc582e57fda7427" + } + ] + }, + { + "id": "bridge-balance-valve-swap", + "version": "3", + "code": "TASK-VIRTUAL-008", + "title": "重型支援桥平衡阀拆拼互换", + "source": "桥梁/文件2/9.jpg、10.jpg", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "清洗小腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-01-ea1da2456af43dba.wav", + "stepDuration": 5.631, + "stepSha256": "ac012c8fb98f2bec6306f9191370db056dae1fa149a503b0935ed2693682ff04" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "拆开小腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-02-ce4a4236a649cdaa.wav", + "stepDuration": 6.874, + "stepSha256": "ee5a36959dc40a2b6add9867b9fb8133952e6631984d42a326737e86d8c59a04" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆下小腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-03-10e99ab9d685c071.wav", + "stepDuration": 5.736, + "stepSha256": "8916862dc0b935dc72b8c173d5454423b3d71f7d605f225236d4014c5352276e" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "封堵小腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-04-637a9a4953c95518.wav", + "stepDuration": 5.231, + "stepSha256": "fa373eae3647d10a3309f537ccc303ec23ada62600d922ebef6078d724d80842" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "清洗大腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-05-3ec2faf63a53606b.wav", + "stepDuration": 5.537, + "stepSha256": "2cf2bcb15e99e30fede366d563b566664abbe02373d2db06518701e8dc879d08" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "拆开大腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-06-d799ca1e85de6dc1.wav", + "stepDuration": 7.171, + "stepSha256": "5b5997cff09a9b8b5d0abf9c8ca42f9690ebcf3d1a14af5016a7d3e65aedb62c" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "拆下大腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-07-e869fb72d97cc851.wav", + "stepDuration": 5.644, + "stepSha256": "cac1312389c9bd08aebade4bc430a698610141785fb6ff3c7e1cb766a001c89b" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "封堵大腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-08-cb20f78a2b88ab3d.wav", + "stepDuration": 5.083, + "stepSha256": "1a6c29b60980f7e7e562008bd67893033fcb03ddf48750bbd7868af9c9363ec4" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "准备安装大腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-09-16254636cfc9d0c7.wav", + "stepDuration": 5.769, + "stepSha256": "adb4d0d6341d324f7d90b55de072ad7820170a6dd456d2fe8a4adade4384e5b5" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "安装大腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-10-44988514081776bc.wav", + "stepDuration": 7.09, + "stepSha256": "155824ee57251f1217a455a2e8d233a0d23daef7b74f5ff447409b903503895d" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "核对大腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第11步,核对大腔控制油口管路连接。核对大腔控制油口管路连接,记录处理方式及依据,并提交教员核对。", + "safetyText": "请记录控制油口管路的处理方式及依据,提交教员核对。", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-11-74165e700ea1b9a1.wav", + "stepDuration": 8.291, + "stepSha256": "e27f07e1aa08e7436cb5956ff7207050df35ff3a72c95cec32c9ac546d66cdde", + "safetyUrl": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/safety-11-cd17b636a027797c.wav", + "safetyDuration": 3.864, + "safetySha256": "5851d9f87954894e8da970e54eeb6c9a62b0bd109e35a7b7018ba2912c9cf8eb" + }, + { + "stepCode": "BRIDGE-STEP-12", + "number": 12, + "expectedTitle": "紧固大腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-12-990b9ddf6e1b0ced.wav", + "stepDuration": 5.226, + "stepSha256": "e8ca6a606f3e18f82317211b0bbe4463c21743314ed1e7c67346d7d53fb3cb39" + }, + { + "stepCode": "BRIDGE-STEP-13", + "number": 13, + "expectedTitle": "准备安装小腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-13-46556532f15bf882.wav", + "stepDuration": 5.853, + "stepSha256": "af96100a06b9ef2faf41f8e4372c163e924b86163e7e41e65703dcf451a9154e" + }, + { + "stepCode": "BRIDGE-STEP-14", + "number": 14, + "expectedTitle": "安装小腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-14-b6791d3d51bd7892.wav", + "stepDuration": 7.461, + "stepSha256": "2f8020d015e761de746c4dd148eb90048e95dedf267d80dd454c3ce874d06487" + }, + { + "stepCode": "BRIDGE-STEP-15", + "number": 15, + "expectedTitle": "核对小腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第15步,核对小腔控制油口管路连接。核对小腔控制油口管路连接,记录处理方式及依据,并提交教员核对。", + "safetyText": "请记录控制油口管路的处理方式及依据,提交教员核对。", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-15-f9d2e3b55442209e.wav", + "stepDuration": 8.026, + "stepSha256": "e48c2d2ab65996db7106528bef5dbdd03ceea1b4fa961b9aee96ad581fd47ac5", + "safetyUrl": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/safety-15-cd17b636a027797c.wav", + "safetyDuration": 4.116, + "safetySha256": "3e92f88eb2d9a4366926100e1fd386a8ad4072fbd551fdf471c2bcf24f772963" + }, + { + "stepCode": "BRIDGE-STEP-16", + "number": 16, + "expectedTitle": "紧固小腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "safetyText": "", + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-16-20ecc40d88e8c4e0.wav", + "stepDuration": 5.229, + "stepSha256": "c943039c9c52878772f3b1bae62f3f03d4e633ea186578ed4aacb0fa08338bdf" + } + ] + } + ] +} diff --git a/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-005-video.png b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-005-video.png new file mode 100644 index 0000000..ece23c2 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-005-video.png differ diff --git a/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-006-video.png b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-006-video.png new file mode 100644 index 0000000..4ad72f1 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-006-video.png differ diff --git a/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-007-video.png b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-007-video.png new file mode 100644 index 0000000..a32c13f Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-007-video.png differ diff --git a/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-008-video.png b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-008-video.png new file mode 100644 index 0000000..63cf319 Binary files /dev/null and b/reports/bridge-lecture-polish-20260915/playback/TASK-VIRTUAL-008-video.png differ diff --git a/reports/bridge-lecture-polish-20260915/playback/live-result.json b/reports/bridge-lecture-polish-20260915/playback/live-result.json new file mode 100644 index 0000000..09d5e5c --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/playback/live-result.json @@ -0,0 +1,58 @@ +{ + "origin": "http://127.0.0.1:6180", + "results": [ + { + "code": "TASK-VIRTUAL-005", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-006", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-007", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4" + ], + "obsoleteAssetDownloads": 0 + }, + { + "code": "TASK-VIRTUAL-008", + "firstAndSecondVideo": true, + "audioToggle": true, + "stopOnStepChange": true, + "errorFallback": true, + "reloadAndClose": true, + "staticVideoUrls": [ + "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4" + ], + "obsoleteAssetDownloads": 0 + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-lecture-polish-20260915/regenerated.json b/reports/bridge-lecture-polish-20260915/regenerated.json new file mode 100644 index 0000000..54e9723 --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/regenerated.json @@ -0,0 +1,74 @@ +[ + { + "code": "TASK-VIRTUAL-006", + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "text": "第7步,按正常步骤操作架桥车。按正常操作步骤操作架桥车。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-07-4c2f4821d77d37d6.mp4", + "sha256": "936edea840e0e1a08ebeb3033541afd8da7857109cb6935c95d33ba4feb35c80", + "duration": 4.88, + "audioSha256": "2abb993085e1ad3a7ea7b4103d836cceab8a4d3821fcfaacf8799716882a16a2", + "previousUrl": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-07-84f943a4e5a9bbc8.mp4", + "previousSha256": "27d1c3c9666a176028bad6892d318082b6a85ca729e36f7f4e8920738b3f95d1" + }, + { + "code": "TASK-VIRTUAL-007", + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "text": "第8步,安装新液压泵。安装新的液压泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-08-112b34220df76ad2.mp4", + "sha256": "a3407af6e75ccd86db414b7d4acd98f4c8782b617c4533bc9cc8e8c76b0d13ff", + "duration": 3.36, + "audioSha256": "5dd1afc550ea20c1f728543dc01f6c4ce82af82c7cec216ee2452bc67d8291db", + "previousUrl": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-08-5ca9062502638806.mp4", + "previousSha256": "bcd805461e072ce4ddad0ab0ba4dd6b442feed395bac3a16694224237a8ef550" + }, + { + "code": "TASK-VIRTUAL-007", + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "text": "第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-09-87051eca2269dcec.mp4", + "sha256": "e146ad861a508f8679eff1768c8a0d94e88dbf9d6807ca78923bb49f073df045", + "duration": 4.96, + "audioSha256": "14cdc8dae461a998f820fc2e4fc8739a061b69e83ce0f6b9d6155c80c49d1b02", + "previousUrl": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-09-e8782919d61b49b9.mp4", + "previousSha256": "946b6a086fc885b47a956717d378d7e8e061b7dde9e473478ebeb084dfb21d08" + }, + { + "code": "TASK-VIRTUAL-007", + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "text": "第11步,启动设备试验。启动设备进行试验。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-11-e3328d50b4700fb4.mp4", + "sha256": "af2151f73318dc03389466af1be454bda3e2ab3d719f590a8df038572819d612", + "duration": 3.28, + "audioSha256": "368b4ca3f55e9f20f2128d82db7b34283da0b53ef3fb8ffb7dc582e57fda7427", + "previousUrl": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-11-c06a4be476669d7f.mp4", + "previousSha256": "f48cc129f98b980130fc9616fdbfb5d8e9750c3c4fc687bb9da32ccf373158ef" + }, + { + "code": "TASK-VIRTUAL-008", + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "text": "第11步,核对大腔控制油口管路连接。核对大腔控制油口管路连接,记录处理方式及依据,并提交教员核对。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-11-f5b91f1736b72a17.mp4", + "sha256": "f6c5140f910d0ded60194e2ecd2e07127bdb7cdd4f4e2eb4689f5a7bd97d317e", + "duration": 8.48, + "audioSha256": "e27f07e1aa08e7436cb5956ff7207050df35ff3a72c95cec32c9ac546d66cdde", + "previousUrl": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-11-41511d4a555dca5e.mp4", + "previousSha256": "879d72ebcbe9fdbb2c070add12cef9e837fe147e12de56a4d602a4fac78515c1" + }, + { + "code": "TASK-VIRTUAL-008", + "stepCode": "BRIDGE-STEP-15", + "number": 15, + "text": "第15步,核对小腔控制油口管路连接。核对小腔控制油口管路连接,记录处理方式及依据,并提交教员核对。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-15-4469fbd3dc5cbb84.mp4", + "sha256": "9ed868f9c933e9cb21f898f99eb4833eb0f561d2dcd42da1173dc725a7fbcbfa", + "duration": 8.24, + "audioSha256": "e48c2d2ab65996db7106528bef5dbdd03ceea1b4fa961b9aee96ad581fd47ac5", + "previousUrl": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-15-31ab069954b685be.mp4", + "previousSha256": "790d9617261add255912538c8dfff81a3ddc3acd5a8aff3d6efb6ac9931803ac" + } +] diff --git a/reports/bridge-lecture-polish-20260915/video-manifest.json b/reports/bridge-lecture-polish-20260915/video-manifest.json new file mode 100644 index 0000000..2a4fd82 --- /dev/null +++ b/reports/bridge-lecture-polish-20260915/video-manifest.json @@ -0,0 +1,440 @@ +{ + "profile": { + "avatarName": "教员1", + "materialVersion": "v2", + "providerAvatarId": "a1000000000000000000000000000005", + "avatarManifestSha256": "8155a21af68b60ea024c7591c8ad454aa9884a2c7d22cb069c16bb192bc4e122", + "renderer": "OpenGenerationWorker.capture", + "width": 480, + "height": 640, + "fps": 25, + "videoCodec": "h264", + "audioCodec": "aac", + "encoding": "libx264 veryfast crf20 yuv420p / aac 128k faststart", + "audioSource": "existing step narration, unchanged" + }, + "scripts": [ + { + "id": "bridge-pump-switch", + "version": "2", + "code": "TASK-VIRTUAL-005", + "title": "重型支援桥液压泵应急切换", + "steps": [ + { + "stepCode": "front-pump-step-01", + "number": 1, + "expectedTitle": "根据故障现象确定是哪一个液压泵发生故障", + "expectedInstruction": "根据故障现象确定是哪一个液压泵发生故障(注:模型_1液压泵标记出来。例如显红色)", + "text": "第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-01-bd17dc16621458c4.mp4", + "duration": 4.96, + "sha256": "7db0b2653aa8719268764ff4fb4f1ede92c947b9f4603308ce2ad7d0903ac45c" + }, + { + "stepCode": "front-pump-step-02", + "number": 2, + "expectedTitle": "断开架桥车取力器", + "expectedInstruction": "断开架桥车取力器。(注:显示模型2取力器和2取力器开关,摇动模型2取力器开关。特别说明这个这边是早上随手补的不准确,车外看就行,不要拉近)", + "text": "第2步,断开架桥车取力器。将架桥车取力器断开。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-02-f485ff03a609c910.mp4", + "duration": 4.16, + "sha256": "421922b32e5a9cb84c2fef6d1b026918044af2ce1ce0b725a89b60900d2052ef" + }, + { + "stepCode": "front-pump-step-03", + "number": 3, + "expectedTitle": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开", + "expectedInstruction": "将架桥车备胎斜上方链接两个红色滤油器的球阀打开。(注;把模型3球阀开关由垂直与官道方向旋转至平行于管道方向)", + "text": "第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-03-81ea8dc0e23da76d.mp4", + "duration": 8.36, + "sha256": "4ff18d5fa228f6c040d39ec4f435fcac9eb9bfe768f108a27f57577ebcada362" + }, + { + "stepCode": "front-pump-step-04", + "number": 4, + "expectedTitle": "重新联通取力器", + "expectedInstruction": "重新联通取力器(注:把步骤2的2取力器开关摇回去:还是不要拉近)", + "text": "第4步,重新接通取力器。将架桥车取力器重新接通。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-04-aa6bbd5769344dc0.mp4", + "duration": 4.2, + "sha256": "e841b61cf522ed5f1633b8569eba04bc17ee77d777f811ddbb2334abb856f2cb" + }, + { + "stepCode": "front-pump-step-05", + "number": 5, + "expectedTitle": "打开辅助控制盒内的“互救”开关", + "expectedInstruction": "打开辅助控制盒内的“互救”开关(注:打开5辅助控制盒盖在5辅助控制盒面板上,把5互救开关往上搬)", + "text": "第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-switch/v2/instructor-1-v2/step-05-422f9e85bb468fd5.mp4", + "duration": 6.8, + "sha256": "6def38648367bbd7475e7bcba40d407d8530e9bbbdda128121c320ccd252275c" + } + ] + }, + { + "id": "bridge-pump-substitute", + "version": "3", + "code": "TASK-VIRTUAL-006", + "title": "重型支援桥液压泵应急替代", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "保持架桥车运行并断开取力器", + "expectedInstruction": "保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "text": "第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-01-053bd89d013ca8c2.mp4", + "duration": 7.84, + "sha256": "87b2c3c11e2170f6be3e11c35d353e19a9772101d881b06d827912a97623ca18" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "连接两车液压软管", + "expectedInstruction": "连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "text": "第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-02-7e103c9898230504.mp4", + "duration": 9.72, + "sha256": "19ecd4d56bd96f6c513f43abc2f5baaf8d0f53dae3edfaceda51dc82a9014f05" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "打开支援车回油截止阀", + "expectedInstruction": "打开支援车液压油箱快接接头处的回油截止阀。", + "text": "第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-03-d0d26b774e96a981.mp4", + "duration": 5.76, + "sha256": "216e6300b28fcf5b34bb9afe8bf1339870d2d31dc8d2780f66bd4a338622878c" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "打开互救作业开关", + "expectedInstruction": "打开辅助控制盒上的“互救作业”开关。", + "text": "第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-04-a7cafe4130983380.mp4", + "duration": 5.16, + "sha256": "1c22bb9066f42642903038fd2c6272603a5e758d95edf5f7f2447c9be82eb8a1" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "打开滤油器出口连通球阀", + "expectedInstruction": "打开两个输油滤油器出口处的连通球阀。", + "text": "第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-05-ef62a148cdeb4c73.mp4", + "duration": 5.96, + "sha256": "6aa84f6c7ed9017ec1789b70357d4163364512951568a028658a76b2a4566a72" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "接通支援车液压取力器", + "expectedInstruction": "接通支援车液压系统取力器,向架桥车供油。", + "text": "第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-06-f4bb8c70dc263869.mp4", + "duration": 6, + "sha256": "b4f70d76acf8bfc50952c2d981f8910d0da865a32639bb972508409e19404b1f" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "按正常步骤操作架桥车", + "expectedInstruction": "原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。", + "text": "第7步,按正常步骤操作架桥车。按正常操作步骤操作架桥车。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-substitute/v3/instructor-1-v2/step-07-4c2f4821d77d37d6.mp4", + "duration": 4.88, + "sha256": "936edea840e0e1a08ebeb3033541afd8da7857109cb6935c95d33ba4feb35c80" + } + ] + }, + { + "id": "bridge-pump-replace", + "version": "3", + "code": "TASK-VIRTUAL-007", + "title": "重型支援桥前泵换件修复", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "停机并初裁牛皮纸", + "expectedInstruction": "架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "text": "第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-01-071874b4ec4b9e19.mp4", + "duration": 6.64, + "sha256": "cbaf3a71793502c3f08262bba414c78c1565ba68e32f0dd51b82efaf35070ca7" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "关闭液压油箱出油口一号球阀", + "expectedInstruction": "将一号球阀手柄从平行管道转到垂直管道。", + "text": "第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-02-26d142b67538ea4d.mp4", + "duration": 6.56, + "sha256": "1f1b83d60763eb2d71fd06654c6ace25cb73bd69bd7f31a72f930bbd75f6f72b" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆开并包扎进出油管", + "expectedInstruction": "用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "text": "第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-03-9e2b426e945678f0.mp4", + "duration": 7, + "sha256": "2b81b7b187f3445c2c72b1135ccc6a82b131635ff1de9fd2c42da7b70ceb95ce" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "拆下四个安装螺栓", + "expectedInstruction": "用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "text": "第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-04-fe998d3697e1a463.mp4", + "duration": 6.92, + "sha256": "6f49c2a6cdf334ef439ca1dd5b31ea8c31a6b0c39e5820bd821fe6f001cb7a3e" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "取下旧前泵", + "expectedInstruction": "取下原前泵。", + "text": "第5步,取下旧前泵。取下原前泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-05-e0348b0ea0055779.mp4", + "duration": 3.08, + "sha256": "4ed2cee9a68503af9951909cf0162c03e978ff9fc5665a918bb3e634952547e1" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "修裁牛皮纸", + "expectedInstruction": "进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "text": "第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-06-488750524bd2c0a8.mp4", + "duration": 6.76, + "sha256": "be089ff024fb7166a408613a5f0afc1a19b4a33672f8be5d07b4347824900e48" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "放置牛皮纸垫", + "expectedInstruction": "将裁好的牛皮纸放在取力器接口处。", + "text": "第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-07-5dbddd64c54251a5.mp4", + "duration": 5, + "sha256": "513e55b9110879d17d7bf45cc726b6642646731a657c0a276cc3c749ca768637" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "安装新液压泵", + "expectedInstruction": "安装新的液压泵。原稿没有给出拧紧力矩。", + "text": "第8步,安装新液压泵。安装新的液压泵。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-08-112b34220df76ad2.mp4", + "duration": 3.36, + "sha256": "a3407af6e75ccd86db414b7d4acd98f4c8782b617c4533bc9cc8e8c76b0d13ff" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "向新泵加注液压油", + "expectedInstruction": "打开新液压泵加油口,加注液压油。原稿没有给出定量值。", + "text": "第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-09-87051eca2269dcec.mp4", + "duration": 4.96, + "sha256": "e146ad861a508f8679eff1768c8a0d94e88dbf9d6807ca78923bb49f073df045" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "恢复进出油管连接", + "expectedInstruction": "用大活动扳手连接并拧紧液压泵进、出油管。", + "text": "第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-10-c14fe764c6a78575.mp4", + "duration": 5.36, + "sha256": "7f51d9ff1ce26c7a29ed6de1543a49883c0a46cad20e262c87aec79eb9a3afec" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "启动设备试验", + "expectedInstruction": "启动设备进行试验。原稿没有展开具体试验项目和判定数值。", + "text": "第11步,启动设备试验。启动设备进行试验。", + "url": "/legacy/virtual-training/videos/narration/bridge-pump-replace/v3/instructor-1-v2/step-11-e3328d50b4700fb4.mp4", + "duration": 3.28, + "sha256": "af2151f73318dc03389466af1be454bda3e2ab3d719f590a8df038572819d612" + } + ] + }, + { + "id": "bridge-balance-valve-swap", + "version": "3", + "code": "TASK-VIRTUAL-008", + "title": "重型支援桥平衡阀拆拼互换", + "steps": [ + { + "stepCode": "BRIDGE-STEP-1", + "number": 1, + "expectedTitle": "清洗小腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-01-8540f64d275cd500.mp4", + "duration": 5.96, + "sha256": "e9f87d4d2f08b827e66a769344493c8475ff51a974c37283b2bfb3edfcaf60d4" + }, + { + "stepCode": "BRIDGE-STEP-2", + "number": 2, + "expectedTitle": "拆开小腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-02-3ed7b91337a0c00e.mp4", + "duration": 7.2, + "sha256": "b8b4468ce061596ba616d6449c870627f5cc0d659786f0104a48406079990f4a" + }, + { + "stepCode": "BRIDGE-STEP-3", + "number": 3, + "expectedTitle": "拆下小腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-03-8dba240adff9be00.mp4", + "duration": 5.96, + "sha256": "63b2c9dd87654c9795d81c4dfa8149512dc0980b63e07990c0d0af3ad4515dba" + }, + { + "stepCode": "BRIDGE-STEP-4", + "number": 4, + "expectedTitle": "封堵小腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-04-24da11990de8e484.mp4", + "duration": 4.96, + "sha256": "c70d5879a4261e52ff84dc70ad4916cf553136307819144c9f8dc42ac43eb023" + }, + { + "stepCode": "BRIDGE-STEP-5", + "number": 5, + "expectedTitle": "清洗大腔平衡阀", + "expectedInstruction": "用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "text": "第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-05-714a15e72dfa2832.mp4", + "duration": 6, + "sha256": "16cbea74ac0717dc600522796538740113c6c7018ff2ba7c341c2c90607e9a8b" + }, + { + "stepCode": "BRIDGE-STEP-6", + "number": 6, + "expectedTitle": "拆开大腔控制油口管路", + "expectedInstruction": "用19开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "text": "第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-06-5478cc2211086156.mp4", + "duration": 7.32, + "sha256": "3064f526e6a887cd892628420b0860240044f5bff9ab6b1431ab289f78d30fc2" + }, + { + "stepCode": "BRIDGE-STEP-7", + "number": 7, + "expectedTitle": "拆下大腔平衡阀", + "expectedInstruction": "用8内六角扳手拆下安装螺栓,取下平衡阀。", + "text": "第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-07-98bf30b8947911aa.mp4", + "duration": 6, + "sha256": "098359d57fcd11fb7fcaaeff0d237373462674b7fe6fafcce03bbf6f5cb1a722" + }, + { + "stepCode": "BRIDGE-STEP-8", + "number": 8, + "expectedTitle": "封堵大腔油口", + "expectedInstruction": "用两个油堵封住两个油口,擦净阀座结合面。", + "text": "第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-08-2101b2ebb4bf1783.mp4", + "duration": 5.4, + "sha256": "93c9f6c1ce727c7363b04b7f2ff359cb2b9509363ef597a1f20c30e5bac371d0" + }, + { + "stepCode": "BRIDGE-STEP-9", + "number": 9, + "expectedTitle": "准备安装大腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-09-74cedc700826b5d5.mp4", + "duration": 6, + "sha256": "eab74396df9583d53a0262ca9440d3469fbdd33b1278fa8cda2f5902b137e70e" + }, + { + "stepCode": "BRIDGE-STEP-10", + "number": 10, + "expectedTitle": "安装大腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-10-32f16dc6b235d2d6.mp4", + "duration": 7.36, + "sha256": "e600a45218921a3e06a3af53b6575858e641c294ac3913a9ffb4e68d0a4d2d5a" + }, + { + "stepCode": "BRIDGE-STEP-11", + "number": 11, + "expectedTitle": "核对大腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第11步,核对大腔控制油口管路连接。核对大腔控制油口管路连接,记录处理方式及依据,并提交教员核对。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-11-f5b91f1736b72a17.mp4", + "duration": 8.48, + "sha256": "f6c5140f910d0ded60194e2ecd2e07127bdb7cdd4f4e2eb4689f5a7bd97d317e" + }, + { + "stepCode": "BRIDGE-STEP-12", + "number": 12, + "expectedTitle": "紧固大腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-12-81396098754fccab.mp4", + "duration": 5.44, + "sha256": "355bf751999942f0e330115315ae31019b56a8263c237f041f7e54c5c4b1b81d" + }, + { + "stepCode": "BRIDGE-STEP-13", + "number": 13, + "expectedTitle": "准备安装小腔平衡阀", + "expectedInstruction": "擦净平衡阀及阀座结合面,取下两个油堵。", + "text": "第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-13-672e69748f537f2f.mp4", + "duration": 6, + "sha256": "0023ab39f3a28981c8819d1f6492c486f64cab9c850bf510749fef58adb7bd2f" + }, + { + "stepCode": "BRIDGE-STEP-14", + "number": 14, + "expectedTitle": "安装小腔平衡阀", + "expectedInstruction": "将平衡阀放置于阀座上,用8内六角扳手安装四个安装螺栓。", + "text": "第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-14-0eaebfde856428f8.mp4", + "duration": 7.76, + "sha256": "14ea83fb883f2657d38a3851ebbfd608bc975027c8ba9ebc54883a2543f3bbb8" + }, + { + "stepCode": "BRIDGE-STEP-15", + "number": 15, + "expectedTitle": "核对小腔控制油口管路连接", + "expectedInstruction": "原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用19开口扳手拆开管路并包扎”的相反描述。", + "text": "第15步,核对小腔控制油口管路连接。核对小腔控制油口管路连接,记录处理方式及依据,并提交教员核对。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-15-4469fbd3dc5cbb84.mp4", + "duration": 8.24, + "sha256": "9ed868f9c933e9cb21f898f99eb4833eb0f561d2dcd42da1173dc725a7fbcbfa" + }, + { + "stepCode": "BRIDGE-STEP-16", + "number": 16, + "expectedTitle": "紧固小腔阀体连接螺栓", + "expectedInstruction": "用内六角扳手拧紧四个阀体连接螺栓。", + "text": "第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。", + "url": "/legacy/virtual-training/videos/narration/bridge-balance-valve-swap/v3/instructor-1-v2/step-16-ab6b316a229cd837.mp4", + "duration": 5.64, + "sha256": "ea676012e2a34aa57bcbc616042d71f9bd4e56e7d29cc4958cd2e973de72ff30" + } + ] + } + ] +} diff --git a/reports/bridge-lipsync-diagnosis-20260914-silence/diagnostic.webm b/reports/bridge-lipsync-diagnosis-20260914-silence/diagnostic.webm new file mode 100644 index 0000000..d5629cb Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914-silence/diagnostic.webm differ diff --git a/reports/bridge-lipsync-diagnosis-20260914-silence/runtime.json b/reports/bridge-lipsync-diagnosis-20260914-silence/runtime.json new file mode 100644 index 0000000..73f4ed0 --- /dev/null +++ b/reports/bridge-lipsync-diagnosis-20260914-silence/runtime.json @@ -0,0 +1,3535 @@ +{ + "frames": [ + { + "t": 13.800000190734863, + "ms": 2, + "values": [ + -7.333581924438477, + -1.3326692581176758, + -0.4915201663970947, + -1.0617811679840088, + 1.1403899192810059, + -1.4151867628097534, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 74.60000038146973, + "ms": 2.3999996185302734, + "values": [ + -10.414820671081543, + -2.5791680812835693, + -2.9664151668548584, + -1.4958993196487427, + 1.6885420083999634, + -2.3302152156829834, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 138.80000019073486, + "ms": 1.1999998092651367, + "values": [ + -11.187210083007812, + -2.4062650203704834, + -3.008010149002075, + -1.6241434812545776, + 1.7497658729553223, + -2.3635599613189697, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 201.2000002861023, + "ms": 1, + "values": [ + -11.41242790222168, + -2.291626214981079, + -3.0029213428497314, + -1.7169710397720337, + 1.8058910369873047, + -2.4175188541412354, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 248.90000009536743, + "ms": 1.5999999046325684, + "values": [ + -11.405503273010254, + -2.158625841140747, + -2.987684488296509, + -1.7998685836791992, + 1.8586337566375732, + -2.4592525959014893, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 381.7000002861023, + "ms": 1.5999999046325684, + "values": [ + -11.234643936157227, + -1.9874532222747803, + -2.9421188831329346, + -1.8663241863250732, + 1.9030104875564575, + -2.502091646194458, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 427.1000003814697, + "ms": 0.5, + "values": [ + -11.000639915466309, + -1.804243803024292, + -2.8916399478912354, + -1.9170767068862915, + 1.9341318607330322, + -2.5452568531036377, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 606.9000000953674, + "ms": 1.3000001907348633, + "values": [ + -2.336031913757324, + 0.9111114740371704, + -1.660916805267334, + -1.2925432920455933, + 2.158233165740967, + -2.7378103733062744, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 659, + "ms": 1.1000003814697266, + "values": [ + -2.5100879669189453, + 1.2606303691864014, + -1.5769522190093994, + -1.4401308298110962, + 1.9707541465759277, + -2.8980352878570557, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 696.1000003814697, + "ms": 1.5, + "values": [ + -3.8079700469970703, + 0.7090802192687988, + -1.886613130569458, + -1.4971195459365845, + 1.9132698774337769, + -2.9397776126861572, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 739.5, + "ms": 2.200000286102295, + "values": [ + -5.238895416259766, + -0.03506612777709961, + -2.269681692123413, + -1.5166850090026855, + 1.9472532272338867, + -2.927692174911499, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 776.3000001907349, + "ms": 0.9000000953674316, + "values": [ + -6.281012058258057, + -0.5720365047454834, + -2.526323080062866, + -1.566057801246643, + 1.989891529083252, + -2.898470640182495, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 836.9000000953674, + "ms": 0.7000002861022949, + "values": [ + -6.955916404724121, + -0.8298282623291016, + -2.6348559856414795, + -1.6271644830703735, + 2.0408143997192383, + -2.855090379714966, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 892.3000001907349, + "ms": 0.8000001907348633, + "values": [ + -7.329530239105225, + -0.897369384765625, + -2.646117925643921, + -1.6802036762237549, + 2.0856475830078125, + -2.825312852859497, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 931.1000003814697, + "ms": 1.3999996185302734, + "values": [ + -7.511922836303711, + -0.8788375854492188, + -2.611745595932007, + -1.722036361694336, + 2.1158533096313477, + -2.80830454826355, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 967.2000002861023, + "ms": 1.4000000953674316, + "values": [ + -7.568079948425293, + -0.8221957683563232, + -2.5511834621429443, + -1.7545664310455322, + 2.1316800117492676, + -2.803727388381958, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1002, + "ms": 0.6000003814697266, + "values": [ + -7.55587100982666, + -0.7599747180938721, + -2.4894354343414307, + -1.781198263168335, + 2.1438517570495605, + -2.8102614879608154, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1051.8000001907349, + "ms": 0.5, + "values": [ + -7.516407012939453, + -0.7106215953826904, + -2.4359328746795654, + -1.8037023544311523, + 2.155478000640869, + -2.819267511367798, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1089.3000001907349, + "ms": 1.1999998092651367, + "values": [ + -7.473262786865234, + -0.6800124645233154, + -2.3955771923065186, + -1.8227543830871582, + 2.166684865951538, + -2.8285515308380127, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1136.1000003814697, + "ms": 0.8999996185302734, + "values": [ + -7.4381632804870605, + -0.6690840721130371, + -2.370967149734497, + -1.8382632732391357, + 2.177997589111328, + -2.836473226547241, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1173.2000002861023, + "ms": 1.299999713897705, + "values": [ + -7.417008876800537, + -0.6751260757446289, + -2.3612120151519775, + -1.8505619764328003, + 2.1895575523376465, + -2.842628240585327, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1220.6000003814697, + "ms": 0.6999998092651367, + "values": [ + -7.4115777015686035, + -0.6937251091003418, + -2.3611810207366943, + -1.8628087043762207, + 2.2006402015686035, + -2.84869647026062, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1268.7000002861023, + "ms": 0.9000000953674316, + "values": [ + -7.421533584594727, + -0.7216439247131348, + -2.3688290119171143, + -1.8752310276031494, + 2.211124897003174, + -2.8547041416168213, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1310.8000001907349, + "ms": 1, + "values": [ + -7.445448875427246, + -0.756065845489502, + -2.382403612136841, + -1.887822151184082, + 2.2209222316741943, + -2.8607194423675537, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1353.9000000953674, + "ms": 1.0999999046325684, + "values": [ + -7.48036003112793, + -0.7943053245544434, + -2.400161027908325, + -1.9007099866867065, + 2.229837656021118, + -2.8669331073760986, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1389.8000001907349, + "ms": 0.9000000953674316, + "values": [ + -7.52350378036499, + -0.8341877460479736, + -2.4206740856170654, + -1.913840889930725, + 2.2376961708068848, + -2.8736021518707275, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1468.2000002861023, + "ms": 1.1999998092651367, + "values": [ + -7.574014663696289, + -0.873939037322998, + -2.4432685375213623, + -1.9274810552597046, + 2.2453200817108154, + -2.8805363178253174, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1502.2000002861023, + "ms": 0.6999998092651367, + "values": [ + -7.62986946105957, + -0.9109725952148438, + -2.466412305831909, + -1.9411133527755737, + 2.253194808959961, + -2.8886067867279053, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1537.1000003814697, + "ms": 0.5999999046325684, + "values": [ + -7.685938835144043, + -0.9433369636535645, + -2.4876716136932373, + -1.95352303981781, + 2.2598116397857666, + -2.8980062007904053, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1575.8000001907349, + "ms": 0.6999998092651367, + "values": [ + -7.743061542510986, + -0.9736847877502441, + -2.50874924659729, + -1.9658688306808472, + 2.2655282020568848, + -2.9075005054473877, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1609.8000001907349, + "ms": 0.5999999046325684, + "values": [ + -7.800034523010254, + -1.0019900798797607, + -2.529517889022827, + -1.978139042854309, + 2.2703652381896973, + -2.917083501815796, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1652.7000002861023, + "ms": 0.7999997138977051, + "values": [ + -7.855790615081787, + -1.0278980731964111, + -2.5496528148651123, + -1.990319848060608, + 2.2743606567382812, + -2.926737070083618, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1691.5, + "ms": 1.1000003814697266, + "values": [ + -7.909539222717285, + -1.0513205528259277, + -2.5689899921417236, + -2.002392053604126, + 2.2775869369506836, + -2.9364092350006104, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1734.8000001907349, + "ms": 0.9000000953674316, + "values": [ + -7.959151268005371, + -1.0706758499145508, + -2.5864150524139404, + -2.014275312423706, + 2.280033588409424, + -2.9459855556488037, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1782.5, + "ms": 1.6000003814697266, + "values": [ + -8.00632381439209, + -1.0876424312591553, + -2.6037142276763916, + -2.0275866985321045, + 2.2818915843963623, + -2.954989194869995, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1820.3000001907349, + "ms": 0.9000000953674316, + "values": [ + -8.051715850830078, + -1.101423978805542, + -2.619922399520874, + -2.040851593017578, + 2.2833144664764404, + -2.96399188041687, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1869.4000000953674, + "ms": 1, + "values": [ + -8.096063613891602, + -1.1134471893310547, + -2.635333776473999, + -2.054072141647339, + 2.283973217010498, + -2.972947835922241, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1909.4000000953674, + "ms": 1, + "values": [ + -8.136604309082031, + -1.1233711242675781, + -2.649726629257202, + -2.0670928955078125, + 2.284241199493408, + -2.9816548824310303, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1947.4000000953674, + "ms": 1.8000001907348633, + "values": [ + -8.17174243927002, + -1.1305832862854004, + -2.6623952388763428, + -2.079981565475464, + 2.283735990524292, + -2.990316152572632, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1984.7000002861023, + "ms": 1.1999998092651367, + "values": [ + -8.20079517364502, + -1.1343107223510742, + -2.672781229019165, + -2.0926220417022705, + 2.2828402519226074, + -2.998548746109009, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2043.5, + "ms": 1.8000001907348633, + "values": [ + -8.226497650146484, + -1.1364645957946777, + -2.6823055744171143, + -2.105053186416626, + 2.281743288040161, + -3.0064094066619873, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2104.7000002861023, + "ms": 1.299999713897705, + "values": [ + -8.248403549194336, + -1.1375646591186523, + -2.690951108932495, + -2.116741418838501, + 2.2809720039367676, + -3.0136139392852783, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2167, + "ms": 1.4000000953674316, + "values": [ + -8.266782760620117, + -1.1377549171447754, + -2.698674440383911, + -2.12768292427063, + 2.280613422393799, + -3.020265817642212, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2219.6000003814697, + "ms": 2.0999999046325684, + "values": [ + -8.282645225524902, + -1.1375761032104492, + -2.705871343612671, + -2.1385724544525146, + 2.280154228210449, + -3.0265443325042725, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2268.6000003814697, + "ms": 1.8999996185302734, + "values": [ + -8.296346664428711, + -1.1364777088165283, + -2.712444543838501, + -2.1493184566497803, + 2.279592275619507, + -3.0324132442474365, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2313.6000003814697, + "ms": 1.3999996185302734, + "values": [ + -8.308205604553223, + -1.1345767974853516, + -2.7184512615203857, + -2.1599106788635254, + 2.27895450592041, + -3.0378644466400146, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2359.1000003814697, + "ms": 1.3999996185302734, + "values": [ + -8.31800651550293, + -1.1309216022491455, + -2.7243287563323975, + -2.170646905899048, + 2.278667449951172, + -3.04266619682312, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2410.7000002861023, + "ms": 1.1999998092651367, + "values": [ + -8.326621055603027, + -1.1267919540405273, + -2.7297136783599854, + -2.1811137199401855, + 2.2783422470092773, + -3.047100305557251, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2449.1000003814697, + "ms": 1.6999998092651367, + "values": [ + -8.333999633789062, + -1.1235458850860596, + -2.7348792552948, + -2.1903493404388428, + 2.277949810028076, + -3.0505049228668213, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2487.4000000953674, + "ms": 0.7000002861022949, + "values": [ + -8.340616226196289, + -1.120199203491211, + -2.739793539047241, + -2.1993281841278076, + 2.2775745391845703, + -3.0533950328826904, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2536.5, + "ms": 1.1000003814697266, + "values": [ + -8.34682559967041, + -1.116729974746704, + -2.7444212436676025, + -2.2081735134124756, + 2.2771968841552734, + -3.0559470653533936, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2577.800000190735, + "ms": 2.0999999046325684, + "values": [ + -8.352825164794922, + -1.1132397651672363, + -2.7488114833831787, + -2.2168824672698975, + 2.276826858520508, + -3.058173418045044, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2630.1000003814697, + "ms": 1.299999713897705, + "values": [ + -8.358880996704102, + -1.1094341278076172, + -2.7528421878814697, + -2.2255313396453857, + 2.276463747024536, + -3.0601489543914795, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2671.1000003814697, + "ms": 0.7999997138977051, + "values": [ + -8.364421844482422, + -1.106550693511963, + -2.7567455768585205, + -2.2332634925842285, + 2.276538848876953, + -3.0622336864471436, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2710.5, + "ms": 1, + "values": [ + -8.369481086730957, + -1.1047396659851074, + -2.7606112957000732, + -2.240032434463501, + 2.27706241607666, + -3.064446210861206, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2750.800000190735, + "ms": 1.3000001907348633, + "values": [ + -8.37492561340332, + -1.1030874252319336, + -2.764366388320923, + -2.2467267513275146, + 2.277574062347412, + -3.0663564205169678, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2791, + "ms": 0.9000000953674316, + "values": [ + -8.380794525146484, + -1.101487159729004, + -2.7677667140960693, + -2.2532918453216553, + 2.2779605388641357, + -3.0681498050689697, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2836.2000002861023, + "ms": 0.9000000953674316, + "values": [ + -8.387134552001953, + -1.0999844074249268, + -2.7708709239959717, + -2.259730815887451, + 2.278243064880371, + -3.0698230266571045, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2881.800000190735, + "ms": 1.6999998092651367, + "values": [ + -8.394002914428711, + -1.098721981048584, + -2.7739274501800537, + -2.266084909439087, + 2.27852725982666, + -3.071242570877075, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2923.4000000953674, + "ms": 1.4000000953674316, + "values": [ + -8.400712013244629, + -1.0983362197875977, + -2.777043104171753, + -2.2724521160125732, + 2.2789981365203857, + -3.0724542140960693, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2967.1000003814697, + "ms": 1.5, + "values": [ + -8.407042503356934, + -1.099194049835205, + -2.7799265384674072, + -2.2794713973999023, + 2.2786221504211426, + -3.0745904445648193, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3008.4000000953674, + "ms": 1.0999999046325684, + "values": [ + -8.414018630981445, + -1.1001925468444824, + -2.78275990486145, + -2.2863876819610596, + 2.278208017349243, + -3.07653546333313, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3047.1000003814697, + "ms": 1, + "values": [ + -8.421599388122559, + -1.1013374328613281, + -2.7855589389801025, + -2.2931735515594482, + 2.277810573577881, + -3.078260660171509, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3085.800000190735, + "ms": 0.9000000953674316, + "values": [ + -8.429762840270996, + -1.1026220321655273, + -2.788325071334839, + -2.299830675125122, + 2.277430534362793, + -3.0797855854034424, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3124.6000003814697, + "ms": 1.5999999046325684, + "values": [ + -8.439671516418457, + -1.1022584438323975, + -2.791351556777954, + -2.306915521621704, + 2.276888132095337, + -3.0810630321502686, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3173.7000002861023, + "ms": 1.1999998092651367, + "values": [ + -8.450725555419922, + -1.1014151573181152, + -2.7945382595062256, + -2.314030408859253, + 2.2763407230377197, + -3.082223653793335, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3221.9000000953674, + "ms": 1.700000286102295, + "values": [ + -8.462211608886719, + -1.1007452011108398, + -2.797663450241089, + -2.320995569229126, + 2.275820255279541, + -3.083244562149048, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3288.6000003814697, + "ms": 1.8999996185302734, + "values": [ + -8.474090576171875, + -1.100233554840088, + -2.800727128982544, + -2.3278138637542725, + 2.2753241062164307, + -3.084141969680786, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3333, + "ms": 1.6000003814697266, + "values": [ + -8.48498249053955, + -1.1003193855285645, + -2.803823232650757, + -2.334451913833618, + 2.27500057220459, + -3.0847957134246826, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3386.7000002861023, + "ms": 0.9000000953674316, + "values": [ + -8.495755195617676, + -1.1001300811767578, + -2.8059980869293213, + -2.3410696983337402, + 2.2745418548583984, + -3.0856211185455322, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3432.800000190735, + "ms": 0.8000001907348633, + "values": [ + -8.506749153137207, + -1.099945306777954, + -2.807910203933716, + -2.347580671310425, + 2.2740631103515625, + -3.0864312648773193, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3485.2000002861023, + "ms": 0.9000000953674316, + "values": [ + -8.518050193786621, + -1.0998644828796387, + -2.809796094894409, + -2.353955030441284, + 2.273606300354004, + -3.0871622562408447, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3533.9000000953674, + "ms": 2.0999999046325684, + "values": [ + -8.529613494873047, + -1.099867820739746, + -2.8116519451141357, + -2.360199213027954, + 2.273169755935669, + -3.087827444076538, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3583.300000190735, + "ms": 1.1999998092651367, + "values": [ + -8.541400909423828, + -1.0999398231506348, + -2.8134734630584717, + -2.366316556930542, + 2.2727508544921875, + -3.088435411453247, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3642.300000190735, + "ms": 1.4000000953674316, + "values": [ + -8.553380966186523, + -1.1000678539276123, + -2.815260648727417, + -2.3723108768463135, + 2.272348165512085, + -3.0889971256256104, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3695, + "ms": 1.6000003814697266, + "values": [ + -8.565530776977539, + -1.100311040878296, + -2.8170230388641357, + -2.378154754638672, + 2.2719943523406982, + -3.0894992351531982, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3748.7000002861023, + "ms": 0.9000000953674316, + "values": [ + -8.577816009521484, + -1.1006474494934082, + -2.8187568187713623, + -2.383854389190674, + 2.271681785583496, + -3.0899527072906494, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3792, + "ms": 1.8000001907348633, + "values": [ + -8.590188980102539, + -1.1009881496429443, + -2.820449113845825, + -2.389450788497925, + 2.2713780403137207, + -3.0903866291046143, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3836.9000000953674, + "ms": 1.700000286102295, + "values": [ + -8.602614402770996, + -1.101318359375, + -2.822094678878784, + -2.3949482440948486, + 2.2710819244384766, + -3.0908076763153076, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3879, + "ms": 1.200000286102295, + "values": [ + -8.61506462097168, + -1.1016297340393066, + -2.8236958980560303, + -2.4003512859344482, + 2.270791530609131, + -3.091221570968628, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3922.4000000953674, + "ms": 0.7000002861022949, + "values": [ + -8.627516746520996, + -1.1019089221954346, + -2.8252522945404053, + -2.4056637287139893, + 2.2705068588256836, + -3.091632604598999, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3973.7000002861023, + "ms": 1.299999713897705, + "values": [ + -8.639937400817871, + -1.102144718170166, + -2.8267605304718018, + -2.4108903408050537, + 2.2702245712280273, + -3.0920464992523193, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4011.6000003814697, + "ms": 1, + "values": [ + -8.65230941772461, + -1.102332353591919, + -2.8282229900360107, + -2.416033983230591, + 2.269946336746216, + -3.09246563911438, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4072.300000190735, + "ms": 1.1999998092651367, + "values": [ + -8.664525985717773, + -1.1026101112365723, + -2.8297011852264404, + -2.421119213104248, + 2.26957368850708, + -3.0929782390594482, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4114.700000286102, + "ms": 1.799999713897705, + "values": [ + -8.6765775680542, + -1.1029410362243652, + -2.831184148788452, + -2.426145553588867, + 2.269127607345581, + -3.093566656112671, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4161.5, + "ms": 2.6000003814697266, + "values": [ + -8.688516616821289, + -1.1031980514526367, + -2.8326199054718018, + -2.4310991764068604, + 2.2686820030212402, + -3.094170331954956, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4210.300000190735, + "ms": 1.6999998092651367, + "values": [ + -8.700333595275879, + -1.1033751964569092, + -2.8340089321136475, + -2.435986280441284, + 2.268235445022583, + -3.09479022026062, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4263.900000095367, + "ms": 2, + "values": [ + -8.712005615234375, + -1.1034667491912842, + -2.8353536128997803, + -2.4408082962036133, + 2.267789363861084, + -3.0954296588897705, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4332.60000038147, + "ms": 2, + "values": [ + -8.723518371582031, + -1.1034674644470215, + -2.836655378341675, + -2.445568799972534, + 2.267343044281006, + -3.096087694168091, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4383.10000038147, + "ms": 1.6999998092651367, + "values": [ + -8.734862327575684, + -1.1033694744110107, + -2.837909460067749, + -2.450270414352417, + 2.266896963119507, + -3.096766233444214, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4440.10000038147, + "ms": 1.299999713897705, + "values": [ + -8.746026039123535, + -1.1031737327575684, + -2.839123010635376, + -2.4549152851104736, + 2.2664501667022705, + -3.0974667072296143, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4494.800000190735, + "ms": 2.3000001907348633, + "values": [ + -8.756996154785156, + -1.102874755859375, + -2.8402936458587646, + -2.4595067501068115, + 2.266002893447876, + -3.0981876850128174, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4543.10000038147, + "ms": 0.7999997138977051, + "values": [ + -8.767721176147461, + -1.1025032997131348, + -2.841412305831909, + -2.464054822921753, + 2.2655675411224365, + -3.0989139080047607, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4593, + "ms": 1.1000003814697266, + "values": [ + -8.77801513671875, + -1.1022162437438965, + -2.842418909072876, + -2.468594789505005, + 2.265197277069092, + -3.0995657444000244, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4640.300000190735, + "ms": 0.8000001907348633, + "values": [ + -8.788091659545898, + -1.1018195152282715, + -2.8433878421783447, + -2.4730899333953857, + 2.264826774597168, + -3.100240468978882, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4690.300000190735, + "ms": 1.4000000953674316, + "values": [ + -8.79794979095459, + -1.101311445236206, + -2.8443186283111572, + -2.47753643989563, + 2.2644553184509277, + -3.1009342670440674, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4732, + "ms": 1, + "values": [ + -8.807580947875977, + -1.1006884574890137, + -2.8452155590057373, + -2.4819400310516357, + 2.2640838623046875, + -3.1016499996185303, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4777.5, + "ms": 2.6000003814697266, + "values": [ + -8.816980361938477, + -1.0999555587768555, + -2.846078634262085, + -2.486299753189087, + 2.263711929321289, + -3.1023848056793213, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4815.800000190735, + "ms": 0.5999999046325684, + "values": [ + -8.826162338256836, + -1.0991201400756836, + -2.8469245433807373, + -2.4906177520751953, + 2.2633302211761475, + -3.103144884109497, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4870.400000095367, + "ms": 0.7000002861022949, + "values": [ + -8.835123062133789, + -1.098191738128662, + -2.8477561473846436, + -2.4948928356170654, + 2.262937545776367, + -3.1039297580718994, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4906.60000038147, + "ms": 0.5, + "values": [ + -8.843846321105957, + -1.0971441268920898, + -2.848557710647583, + -2.4991295337677, + 2.2625467777252197, + -3.1047298908233643, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4954.900000095367, + "ms": 1, + "values": [ + -8.852326393127441, + -1.0959820747375488, + -2.8493235111236572, + -2.5033280849456787, + 2.2621588706970215, + -3.10554575920105, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4988.700000286102, + "ms": 0.7999997138977051, + "values": [ + -8.860560417175293, + -1.0947062969207764, + -2.8500592708587646, + -2.507490396499634, + 2.2617735862731934, + -3.1063787937164307, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5035.800000190735, + "ms": 0.9000000953674316, + "values": [ + -8.868556022644043, + -1.093320369720459, + -2.850766897201538, + -2.511615514755249, + 2.26138973236084, + -3.107222318649292, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5083.10000038147, + "ms": 2.0999999046325684, + "values": [ + -8.876309394836426, + -1.0918242931365967, + -2.8514468669891357, + -2.5157063007354736, + 2.2610087394714355, + -3.108081102371216, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5133.700000286102, + "ms": 1.1999998092651367, + "values": [ + -8.883820533752441, + -1.090221643447876, + -2.8521010875701904, + -2.519763231277466, + 2.2606306076049805, + -3.1089508533477783, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5184.900000095367, + "ms": 1.9000000953674316, + "values": [ + -8.891092300415039, + -1.088515043258667, + -2.8527305126190186, + -2.523784875869751, + 2.2602546215057373, + -3.1098320484161377, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5234.400000095367, + "ms": 1.200000286102295, + "values": [ + -8.898126602172852, + -1.086704969406128, + -2.853337049484253, + -2.527773141860962, + 2.2598817348480225, + -3.1107232570648193, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5275.800000190735, + "ms": 0.9000000953674316, + "values": [ + -8.904927253723145, + -1.0847954750061035, + -2.85392165184021, + -2.5317280292510986, + 2.259512186050415, + -3.111623525619507, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5311.700000286102, + "ms": 2.0999999046325684, + "values": [ + -8.911490440368652, + -1.0827884674072266, + -2.8544843196868896, + -2.5356504917144775, + 2.2591443061828613, + -3.1125314235687256, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5358.900000095367, + "ms": 1, + "values": [ + -8.917827606201172, + -1.0806899070739746, + -2.855029821395874, + -2.539538621902466, + 2.2587804794311523, + -3.113447904586792, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5395.700000286102, + "ms": 1.5999999046325684, + "values": [ + -8.923938751220703, + -1.0784993171691895, + -2.855555772781372, + -2.543395519256592, + 2.2584190368652344, + -3.114370584487915, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5431.800000190735, + "ms": 1.6999998092651367, + "values": [ + -8.92982292175293, + -1.0762214660644531, + -2.8560664653778076, + -2.5472214221954346, + 2.2580604553222656, + -3.1152989864349365, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5468.5, + "ms": 0.7000002861022949, + "values": [ + -8.9354887008667, + -1.073859691619873, + -2.8565609455108643, + -2.551013946533203, + 2.2577056884765625, + -3.116231679916382, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5504.800000190735, + "ms": 0.8000001907348633, + "values": [ + -8.940938949584961, + -1.0714168548583984, + -2.8570406436920166, + -2.5547752380371094, + 2.2573537826538086, + -3.1171696186065674, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5553.300000190735, + "ms": 1.5, + "values": [ + -8.946176528930664, + -1.0688960552215576, + -2.8575074672698975, + -2.558504819869995, + 2.257004737854004, + -3.118109941482544, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5593, + "ms": 1.700000286102295, + "values": [ + -8.951204299926758, + -1.0663022994995117, + -2.8579604625701904, + -2.562201976776123, + 2.256660223007202, + -3.119051694869995, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5634.800000190735, + "ms": 1.0999999046325684, + "values": [ + -8.956029891967773, + -1.063636302947998, + -2.8584024906158447, + -2.5658676624298096, + 2.256317377090454, + -3.119997262954712, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5675.200000286102, + "ms": 0.9000000953674316, + "values": [ + -8.960747718811035, + -1.0609667301177979, + -2.858668565750122, + -2.569445848464966, + 2.2559638023376465, + -3.1209356784820557, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5713.800000190735, + "ms": 2.0999999046325684, + "values": [ + -8.965335845947266, + -1.0582749843597412, + -2.8588082790374756, + -2.572951555252075, + 2.2556018829345703, + -3.1218698024749756, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5755.400000095367, + "ms": 0.9000000953674316, + "values": [ + -8.969732284545898, + -1.0555229187011719, + -2.858940839767456, + -2.5764267444610596, + 2.2552437782287598, + -3.1228039264678955, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5794.900000095367, + "ms": 1.8000001907348633, + "values": [ + -8.973938941955566, + -1.0527138710021973, + -2.8590667247772217, + -2.5798707008361816, + 2.2548885345458984, + -3.123737096786499, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5848.200000286102, + "ms": 1.5999999046325684, + "values": [ + -8.977983474731445, + -1.0498661994934082, + -2.8592031002044678, + -2.5832815170288086, + 2.2545270919799805, + -3.1246755123138428, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5904.5, + "ms": 1.200000286102295, + "values": [ + -8.981855392456055, + -1.0469775199890137, + -2.8593480587005615, + -2.5866611003875732, + 2.2541627883911133, + -3.1256158351898193, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5956.60000038147, + "ms": 0.7999997138977051, + "values": [ + -8.985557556152344, + -1.044044017791748, + -2.859489679336548, + -2.5900075435638428, + 2.2537999153137207, + -3.126554250717163, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5998.900000095367, + "ms": 1, + "values": [ + -8.989091873168945, + -1.041067123413086, + -2.8596279621124268, + -2.59332275390625, + 2.2534403800964355, + -3.1274898052215576, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6045, + "ms": 2, + "values": [ + -8.992462158203125, + -1.038050651550293, + -2.859764337539673, + -2.5966053009033203, + 2.2530839443206787, + -3.128422975540161, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6093, + "ms": 0.8000001907348633, + "values": [ + -8.995674133300781, + -1.0349969863891602, + -2.8598992824554443, + -2.5998568534851074, + 2.25273060798645, + -3.129352331161499, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6133.200000286102, + "ms": 1, + "values": [ + -8.998730659484863, + -1.0319104194641113, + -2.860032796859741, + -2.6030771732330322, + 2.2523791790008545, + -3.1302783489227295, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6183.200000286102, + "ms": 1.6999998092651367, + "values": [ + -9.001638412475586, + -1.028791904449463, + -2.860166311264038, + -2.6062653064727783, + 2.252030849456787, + -3.1311986446380615, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6231, + "ms": 2.1000003814697266, + "values": [ + -9.00439739227295, + -1.025644302368164, + -2.860297918319702, + -2.6094210147857666, + 2.2516865730285645, + -3.1321160793304443, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6273.300000190735, + "ms": 1.0999999046325684, + "values": [ + -9.007017135620117, + -1.022474765777588, + -2.8604323863983154, + -2.612545967102051, + 2.2513442039489746, + -3.1330268383026123, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6310.400000095367, + "ms": 0.5, + "values": [ + -9.009502410888672, + -1.0192818641662598, + -2.8605644702911377, + -2.6156375408172607, + 2.251004219055176, + -3.1339333057403564, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6347, + "ms": 0.6000003814697266, + "values": [ + -9.011849403381348, + -1.0160670280456543, + -2.8606984615325928, + -2.61869740486145, + 2.250666856765747, + -3.134834051132202, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6397, + "ms": 2.4000000953674316, + "values": [ + -9.01407241821289, + -1.0128376483917236, + -2.860832452774048, + -2.621724843978882, + 2.250333070755005, + -3.135727643966675, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6457.5, + "ms": 1.5, + "values": [ + -9.016168594360352, + -1.0095906257629395, + -2.8609678745269775, + -2.624720811843872, + 2.250002384185791, + -3.1366164684295654, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6503, + "ms": 0.5, + "values": [ + -9.018144607543945, + -1.0063340663909912, + -2.8611042499542236, + -2.6276838779449463, + 2.2496743202209473, + -3.137497663497925, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6560.60000038147, + "ms": 1.8999996185302734, + "values": [ + -9.020005226135254, + -1.003065586090088, + -2.8612430095672607, + -2.6306159496307373, + 2.2493491172790527, + -3.1383721828460693, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6612.300000190735, + "ms": 2.3000001907348633, + "values": [ + -9.021753311157227, + -0.9997894763946533, + -2.8613831996917725, + -2.633514642715454, + 2.249026298522949, + -3.139240026473999, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6664, + "ms": 1.200000286102295, + "values": [ + -9.023391723632812, + -0.996509313583374, + -2.861525774002075, + -2.636382579803467, + 2.248706579208374, + -3.140101671218872, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6707.400000095367, + "ms": 0.8000001907348633, + "values": [ + -9.024927139282227, + -0.9932258129119873, + -2.8616693019866943, + -2.639216661453247, + 2.2483890056610107, + -3.1409542560577393, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6759.5, + "ms": 0.7000002861022949, + "values": [ + -9.026358604431152, + -0.9899404048919678, + -2.861816167831421, + -2.6420199871063232, + 2.2480740547180176, + -3.14180064201355, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6812.800000190735, + "ms": 1.6999998092651367, + "values": [ + -9.027493476867676, + -0.986379861831665, + -2.861802816390991, + -2.6447508335113525, + 2.2477357387542725, + -3.142631769180298, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6857.10000038147, + "ms": 0.7999997138977051, + "values": [ + -9.028521537780762, + -0.9828000068664551, + -2.8617799282073975, + -2.6474454402923584, + 2.2473978996276855, + -3.1434552669525146, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6901.700000286102, + "ms": 1.0999999046325684, + "values": [ + -9.029458045959473, + -0.9792323112487793, + -2.8617637157440186, + -2.6501100063323975, + 2.2470622062683105, + -3.1442711353302, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6944.5, + "ms": 1.6000003814697266, + "values": [ + -9.030315399169922, + -0.9756765365600586, + -2.861753225326538, + -2.6527435779571533, + 2.2467312812805176, + -3.1450788974761963, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6992.400000095367, + "ms": 0.7000002861022949, + "values": [ + -9.031095504760742, + -0.9721372127532959, + -2.861750364303589, + -2.655345916748047, + 2.246403217315674, + -3.1458795070648193, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7037.60000038147, + "ms": 1, + "values": [ + -9.03179931640625, + -0.9686143398284912, + -2.8617546558380127, + -2.6579179763793945, + 2.2460777759552, + -3.1466715335845947, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7084.900000095367, + "ms": 1.200000286102295, + "values": [ + -9.032430648803711, + -0.9651062488555908, + -2.861765146255493, + -2.660459041595459, + 2.245755672454834, + -3.1474554538726807, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7130, + "ms": 1, + "values": [ + -9.032991409301758, + -0.9616179466247559, + -2.861780881881714, + -2.6629698276519775, + 2.245436668395996, + -3.1482322216033936, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7181.400000095367, + "ms": 1.700000286102295, + "values": [ + -9.033483505249023, + -0.9581513404846191, + -2.861802816390991, + -2.665450096130371, + 2.2451210021972656, + -3.1489994525909424, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7231.200000286102, + "ms": 1.6999998092651367, + "values": [ + -9.033914566040039, + -0.9547040462493896, + -2.8618319034576416, + -2.667900323867798, + 2.2448089122772217, + -3.14975905418396, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7276.5, + "ms": 1.8000001907348633, + "values": [ + -9.034281730651855, + -0.951277494430542, + -2.8618648052215576, + -2.670320510864258, + 2.2444980144500732, + -3.150510549545288, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7324.900000095367, + "ms": 1, + "values": [ + -9.034591674804688, + -0.9478769302368164, + -2.861905336380005, + -2.6727092266082764, + 2.2441916465759277, + -3.1512529850006104, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7370.60000038147, + "ms": 1.1999998092651367, + "values": [ + -9.034843444824219, + -0.9444973468780518, + -2.861952543258667, + -2.6750686168670654, + 2.243887424468994, + -3.1519877910614014, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7421.200000286102, + "ms": 1.4000000953674316, + "values": [ + -9.035040855407715, + -0.9411439895629883, + -2.8620049953460693, + -2.677398204803467, + 2.243586301803589, + -3.152714967727661, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7471.900000095367, + "ms": 0.7000002861022949, + "values": [ + -9.035188674926758, + -0.9378170967102051, + -2.8620622158050537, + -2.6796977519989014, + 2.2432875633239746, + -3.153433084487915, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7528.300000190735, + "ms": 2.0999999046325684, + "values": [ + -9.035221099853516, + -0.934457540512085, + -2.8620994091033936, + -2.6819727420806885, + 2.2429962158203125, + -3.15415358543396, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7580.5, + "ms": 1.5, + "values": [ + -9.03514289855957, + -0.9310731887817383, + -2.8621222972869873, + -2.684222459793091, + 2.2427103519439697, + -3.154876470565796, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7623.700000286102, + "ms": 1, + "values": [ + -9.035025596618652, + -0.9277210235595703, + -2.862151861190796, + -2.6864421367645264, + 2.242427349090576, + -3.1555869579315186, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7668.10000038147, + "ms": 1.5999999046325684, + "values": [ + -9.034865379333496, + -0.9243984222412109, + -2.862187623977661, + -2.688633680343628, + 2.2421467304229736, + -3.1562931537628174, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7727.60000038147, + "ms": 1.5999999046325684, + "values": [ + -9.034669876098633, + -0.9211053848266602, + -2.8622281551361084, + -2.6907949447631836, + 2.241868019104004, + -3.156987428665161, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7771.200000286102, + "ms": 1.299999713897705, + "values": [ + -9.034433364868164, + -0.9178459644317627, + -2.862274408340454, + -2.6929280757904053, + 2.2415919303894043, + -3.1576755046844482, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7815, + "ms": 1.9000000953674316, + "values": [ + -9.034164428710938, + -0.9146156311035156, + -2.8623239994049072, + -2.695032835006714, + 2.2413179874420166, + -3.158353090286255, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7860.60000038147, + "ms": 1.5999999046325684, + "values": [ + -9.033863067626953, + -0.9114203453063965, + -2.86238169670105, + -2.697108745574951, + 2.241046905517578, + -3.1590235233306885, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7907.200000286102, + "ms": 4.5, + "values": [ + -9.033529281616211, + -0.9082539081573486, + -2.8624417781829834, + -2.6991560459136963, + 2.2407774925231934, + -3.159684419631958, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7984.5, + "ms": 2.1000003814697266, + "values": [ + -9.033161163330078, + -0.9051215648651123, + -2.8625071048736572, + -2.701176881790161, + 2.2405102252960205, + -3.160339117050171, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8044.60000038147, + "ms": 1.5, + "values": [ + -9.032767295837402, + -0.9020214080810547, + -2.862576723098755, + -2.7031686305999756, + 2.2402453422546387, + -3.1609833240509033, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8102.60000038147, + "ms": 1.5999999046325684, + "values": [ + -9.032346725463867, + -0.8989553451538086, + -2.8626511096954346, + -2.705132246017456, + 2.2399816513061523, + -3.1616194248199463, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8154.60000038147, + "ms": 0.8999996185302734, + "values": [ + -9.031901359558105, + -0.8959217071533203, + -2.8627302646636963, + -2.7070693969726562, + 2.2397212982177734, + -3.162247896194458, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8206.5, + "ms": 1.200000286102295, + "values": [ + -9.031431198120117, + -0.8929204940795898, + -2.8628127574920654, + -2.7089805603027344, + 2.239462375640869, + -3.1628692150115967, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8257.300000190735, + "ms": 0.8000001907348633, + "values": [ + -9.030950546264648, + -0.8899533748626709, + -2.8628947734832764, + -2.7108633518218994, + 2.239206314086914, + -3.1634819507598877, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8308.60000038147, + "ms": 1.1999998092651367, + "values": [ + -9.030900001525879, + -0.8870029449462891, + -2.86289381980896, + -2.712749481201172, + 2.2390098571777344, + -3.164116621017456, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8348.10000038147, + "ms": 1.3999996185302734, + "values": [ + -9.0308198928833, + -0.8840851783752441, + -2.862896203994751, + -2.714609146118164, + 2.2388134002685547, + -3.1647427082061768, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8386.900000095367, + "ms": 0.9000000953674316, + "values": [ + -9.03071403503418, + -0.8812012672424316, + -2.862903356552124, + -2.7164406776428223, + 2.238616943359375, + -3.165360689163208, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8427.200000286102, + "ms": 1.0999999046325684, + "values": [ + -9.0305814743042, + -0.8783531188964844, + -2.862915277481079, + -2.7182466983795166, + 2.2384228706359863, + -3.1659696102142334, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8469.10000038147, + "ms": 0.6999998092651367, + "values": [ + -9.030426979064941, + -0.8755362033843994, + -2.862929582595825, + -2.7200262546539307, + 2.238229274749756, + -3.1665709018707275, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8508, + "ms": 1.1000003814697266, + "values": [ + -9.03024673461914, + -0.8727526664733887, + -2.8629491329193115, + -2.72178053855896, + 2.238037109375, + -3.1671640872955322, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8552, + "ms": 0.9000000953674316, + "values": [ + -9.030047416687012, + -0.8700025081634521, + -2.86297345161438, + -2.7235090732574463, + 2.2378451824188232, + -3.167750120162964, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8590.60000038147, + "ms": 1.299999713897705, + "values": [ + -9.029827117919922, + -0.86728835105896, + -2.8630001544952393, + -2.725212812423706, + 2.237654209136963, + -3.1683270931243896, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8627.400000095367, + "ms": 1.4000000953674316, + "values": [ + -9.029584884643555, + -0.86460280418396, + -2.8630306720733643, + -2.7268917560577393, + 2.23746395111084, + -3.1688973903656006, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8665.900000095367, + "ms": 1.5, + "values": [ + -9.029325485229492, + -0.8619537353515625, + -2.8630659580230713, + -2.7285468578338623, + 2.2372756004333496, + -3.1694600582122803, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8702.10000038147, + "ms": 0.5, + "values": [ + -9.029045104980469, + -0.8593356609344482, + -2.863103151321411, + -2.730177402496338, + 2.2370879650115967, + -3.1700146198272705, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8755.300000190735, + "ms": 0.9000000953674316, + "values": [ + -9.028751373291016, + -0.85675048828125, + -2.863144636154175, + -2.731783151626587, + 2.236900806427002, + -3.1705615520477295, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8796.900000095367, + "ms": 1.4000000953674316, + "values": [ + -9.028440475463867, + -0.8541982173919678, + -2.8631865978240967, + -2.7333645820617676, + 2.2367148399353027, + -3.1711008548736572, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8834.900000095367, + "ms": 1, + "values": [ + -9.028112411499023, + -0.8516783714294434, + -2.863232374191284, + -2.7349236011505127, + 2.2365293502807617, + -3.171633005142212, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8883.10000038147, + "ms": 0.8999996185302734, + "values": [ + -9.027771949768066, + -0.849189043045044, + -2.8632819652557373, + -2.736459970474243, + 2.2363436222076416, + -3.1721580028533936, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8938.300000190735, + "ms": 1.8000001907348633, + "values": [ + -9.02741527557373, + -0.8467340469360352, + -2.8633315563201904, + -2.7379722595214844, + 2.2361602783203125, + -3.172675371170044, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8986.900000095367, + "ms": 1.5999999046325684, + "values": [ + -9.027007102966309, + -0.8444328308105469, + -2.863410711288452, + -2.739436388015747, + 2.236006021499634, + -3.1731669902801514, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9042.200000286102, + "ms": 1.299999713897705, + "values": [ + -9.026576042175293, + -0.8422024250030518, + -2.863499402999878, + -2.7408690452575684, + 2.2358617782592773, + -3.173644781112671, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9086.700000286102, + "ms": 1.299999713897705, + "values": [ + -9.02613639831543, + -0.8400025367736816, + -2.8635895252227783, + -2.742279291152954, + 2.235718250274658, + -3.174114942550659, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9140.800000190735, + "ms": 4.099999904632568, + "values": [ + -9.025683403015137, + -0.8378288745880127, + -2.863682508468628, + -2.7436702251434326, + 2.2355732917785645, + -3.1745803356170654, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9202.5, + "ms": 0.9000000953674316, + "values": [ + -9.025242805480957, + -0.8356921672821045, + -2.863823652267456, + -2.745002031326294, + 2.235431671142578, + -3.175016164779663, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9249.60000038147, + "ms": 1.1999998092651367, + "values": [ + -9.02479362487793, + -0.8335843086242676, + -2.8639719486236572, + -2.7463152408599854, + 2.235290288925171, + -3.175445795059204, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9301.900000095367, + "ms": 1.0999999046325684, + "values": [ + -9.024337768554688, + -0.8315043449401855, + -2.8641207218170166, + -2.747606039047241, + 2.235149383544922, + -3.1758687496185303, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + ], + "start": 3927.8999996185303, + "events": [ + { + "type": "setAudio", + "t": 499.90000009536743, + "n": 263790 + } + ], + "capture": { + "status": "done", + "elapsed": 8.549400000095368, + "url": "blob:http://1.14.103.234:8123/7fc43ae1-8a41-4c4d-9768-0e31e6e8c992" + }, + "errors": [], + "summary": { + "frameCount": 188, + "elapsedMs": 8695, + "fps": 21.62162162162162, + "maxBlend": 9.035221099853516, + "nonZeroFrames": 188 + } +} \ No newline at end of file diff --git a/reports/bridge-lipsync-diagnosis-20260914-silence/sample.wav b/reports/bridge-lipsync-diagnosis-20260914-silence/sample.wav new file mode 100644 index 0000000..982147e Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914-silence/sample.wav differ diff --git a/reports/bridge-lipsync-diagnosis-20260914/diagnosis.md b/reports/bridge-lipsync-diagnosis-20260914/diagnosis.md new file mode 100644 index 0000000..e57b84c --- /dev/null +++ b/reports/bridge-lipsync-diagnosis-20260914/diagnosis.md @@ -0,0 +1,24 @@ +# 桥梁讲解视频口型问题复查 + +本次是问题诊断,不是口型质量通过报告。上一轮仅验证了媒体编码、资源绑定、播放及回退,不能据此认定嘴型同步合格。 + +## 项目接入 + +TASK-VIRTUAL-005~008 保留任务 ID 86~89,分别使用已发布内容版本 533~536。39 段 MP4 通过数字人视频导入接口进入受控文件存储,步骤 audio.narrationVideoAssetCode 引用 VIDEO 资产。任务预览和正式运行分别从教学 assignment/run 资产接口下载,转为 Blob URL 交给同一个 video 元素播放。原 WAV 仅在选择语音模式或视频失败时播放,不与视频音轨并行播放。报告目录中的 MP4 是复核副本,不是项目运行时依赖的文件地址。 + +## 已验证的事实 + +- 取 TASK-VIRTUAL-005 第3步为样本:MP4 画面 8.480 秒,音轨 8.241333 秒,音轨 start_time=0.064 秒。单凭 64ms 起点差异不能解释严重口型不符。 +- 共享服务当前 MiniLive2.js、control-bridge.js 与本地源文件内容一致(忽略换行)。 +- 用样本语音重新驱动同一人物,口型参数确实随语音变化;静音对照的变化幅度明显不同。语音驱动并未完全失效。 +- 同配置本地无头浏览器测试,口型更新约 24.96fps,而录制 WebM 样本只有 113 个视频帧(约8秒)。说明推理更新频率和录制帧率不是一回事。原 MP4 212 帧中,固定嘴部区域有40次相邻帧平均像素差小于0.1。此像素统计只能反映近重复画面,不能直接量化发音准确率。 +- open_render_capture.js 给 Viewer 发送同一语音驱动口型,同时使用另一个 AudioContext 播放录制音轨;以 speaking-start 通知开始录制。Viewer 在 WASM 设置音频后才解码并启动声音。两个路径没有共同的逐帧音频位置校验。 +- 捕获使用实时时钟、setInterval和canvas.captureStream;FFmpeg最终转25fps。现有成功条件检查编码、音轨存在和时长,不检查口型与发音是否对应,也未记录录制过程的同步偏差。 + +## 结论及边界 + +问题应继续沿成片生成链路排查,项目资源绑定本身没有发现把视频和旧语音混播的问题。已确认录制存在独立时钟与录制帧率不稳定的风险;还不能把严重错位唯一归因于这两点,也不能据当前实验排除人物/底层WASM口型模型质量问题。 + +应先用同一音轨、统一时间轴制作一段对照样片,记录口型和音频位置,再逐字检查起句、停顿、收尾及闭口音。样片合格后再重做并发布39段;现有视频暂不作口型质量合格交付。现有任务、成绩及旧语音不作修改。 + +证据:runtime.json(语音驱动)、../bridge-lipsync-diagnosis-20260914-silence/runtime.json(静音对照)、frame-comparison.json、原成片与复现帧截图。 diff --git a/reports/bridge-lipsync-diagnosis-20260914/diagnostic.webm b/reports/bridge-lipsync-diagnosis-20260914/diagnostic.webm new file mode 100644 index 0000000..f5f7413 Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914/diagnostic.webm differ diff --git a/reports/bridge-lipsync-diagnosis-20260914/frame-comparison.json b/reports/bridge-lipsync-diagnosis-20260914/frame-comparison.json new file mode 100644 index 0000000..79fed02 --- /dev/null +++ b/reports/bridge-lipsync-diagnosis-20260914/frame-comparison.json @@ -0,0 +1,30 @@ +[ + { + "name": "original", + "frames": 212, + "nearRepeated": 40, + "quantiles": [ + 0, + 0, + 0.18763020833333333, + 0.7575520833333333, + 4.136979166666666, + 9.123046875, + 14.172981770833333 + ] + }, + { + "name": "reproduced", + "frames": 113, + "nearRepeated": 8, + "quantiles": [ + 0, + 2.0314453125, + 2.828255208333333, + 4.585611979166667, + 7.561393229166667, + 10.342122395833334, + 17.634635416666665 + ] + } +] \ No newline at end of file diff --git a/reports/bridge-lipsync-diagnosis-20260914/original-frame.png b/reports/bridge-lipsync-diagnosis-20260914/original-frame.png new file mode 100644 index 0000000..3749a75 Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914/original-frame.png differ diff --git a/reports/bridge-lipsync-diagnosis-20260914/original.rgb b/reports/bridge-lipsync-diagnosis-20260914/original.rgb new file mode 100644 index 0000000..2e46f73 Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914/original.rgb differ diff --git a/reports/bridge-lipsync-diagnosis-20260914/remote-MiniLive2.js b/reports/bridge-lipsync-diagnosis-20260914/remote-MiniLive2.js new file mode 100644 index 0000000..40919c5 --- /dev/null +++ b/reports/bridge-lipsync-diagnosis-20260914/remote-MiniLive2.js @@ -0,0 +1,986 @@ +// ==================== 重要配置项 ==================== +const externalViewerConfig = window.DH_VIEWER_CONFIG || {}; +const defaultChromaKey = { + keyColor: { r: 0.0, g: 1.0, b: 0.0 }, + similarity: 0.4, + smoothness: 0.1, + spill: 0.5 +}; +let CONFIG = { + showFPS: false, // 是否显示 FPS + chromaKeyEnabled: true, // 是否开启绿幕扣除 + removeWatermark: true, // 对 WASM 水印笔画像素做局部修补,不覆盖下巴/口型 + backgroundVideoSrc: "background/bg.mp4", // 背景视频路径(开启绿幕扣除时使用) + videoSrc: "assets/01.mp4", // 默认视频文件路径 + dataSrc: "assets/combined_data.json.gz", // 默认数据文件路径 + // 绿幕抠图参数配置 + chromaKey: defaultChromaKey, + ...externalViewerConfig, + chromaKey: { ...defaultChromaKey, ...(externalViewerConfig.chromaKey || {}) } +}; +// ================================================== +const model_size = 184; +let frameTimes = []; +const VIDEO_FPS = 25; +const FRAME_INTERVAL = 1000 / VIDEO_FPS; +const MODULO_N = 16; +const THRESHOLD = 128; +const DEBUG_RUNTIME = externalViewerConfig.debug === true; +const debugLog = (...args) => { + if (DEBUG_RUNTIME) console.log(...args); +}; +const debugWarn = (...args) => { + if (DEBUG_RUNTIME) console.warn(...args); +}; + +let chromaKeyCanvas = null; +let chromaKeyGl = null; +let chromaKeyProgram = null; +let chromaKeyTextures = { foreground: null }; + +let frameIndexCanvas = null; +let frameIndexCtx = null; + +class VideoProcessor { + constructor() { + this.video = null; + this.combinedData = null; + this.lastFrameTime = 0; + } + + async init(videoUrl, gzipUrl) { + if (this.video) { + this.video.pause(); + this.video.src = ''; + this.video = null; + } + + this.video = document.createElement('video'); + // 允许合法 CORS 资源进入 canvas/WebGL;同源部署时该属性同样安全。 + this.video.crossOrigin = 'anonymous'; + this.video.preload = 'auto'; + this.video.loop = true; + this.video.muted = true; + this.video.playsInline = true; + + await new Promise((resolve, reject) => { + this.video.onloadeddata = () => { + const videoW = this.video.videoWidth; + const videoH = this.video.videoHeight; + + canvas_video.width = videoW; + canvas_video.height = videoH; + canvasEl.width = videoW; + canvasEl.height = videoH; + + resolve(); + }; + this.video.onerror = reject; + this.video.src = videoUrl; + this.video.load(); + }); + + await this.fetchVideoUtilData(gzipUrl); + } + + async fetchVideoUtilData(gzipUrl) { + const response = await fetch(gzipUrl); + const compressedData = await response.arrayBuffer(); + const decompressedData = pako.inflate(new Uint8Array(compressedData), { to: 'string' }); + this.combinedData = JSON.parse(decompressedData); + } + + decodeModuloFromPixels(pixelData) { + let detected = 0; + + for (let i = 0; i < 4; i++) { + let r = pixelData[i * 4]; + let bitValue = (r > THRESHOLD) ? 1 : 0; + + switch(i) { + case 0: + if (bitValue) detected |= (1 << 1); + break; + case 1: + if (bitValue) detected |= (1 << 0); + break; + case 2: + if (bitValue) detected |= (1 << 3); + break; + case 3: + if (bitValue) detected |= (1 << 2); + break; + } + } + + return detected; + } + + getAccurateFrameIndex(pixelData) { + return this.decodeModuloFromPixels(pixelData); + } + + findRealFrame(roughFrame, exactModulo) { + let candidateFrame = roughFrame; + if (candidateFrame % MODULO_N !== exactModulo) { + for (let offset = -7; offset <= 7; offset++) { + let candidate = candidateFrame + offset; + if (candidate >= 0 && candidate % MODULO_N === exactModulo) { + return candidate; + } + } + debugWarn("未找到匹配帧号,返回修正值:", candidateFrame); + return candidateFrame; + } + return candidateFrame; + } + + getCurrentFrameIndex(pixelData) { + if (!this.video) return 0; + + const roughFrameByTime = Math.floor(this.video.currentTime * VIDEO_FPS); + const moduloFromPixel = this.getAccurateFrameIndex(pixelData); + // console.log("roughFrameByTime", roughFrameByTime, "moduloFromPixel", moduloFromPixel); + return this.findRealFrame(roughFrameByTime, moduloFromPixel); + } + + play() { + if (this.video) { + this.video.play().catch(error => { + console.error('数字人视频播放失败:', error); + window.dispatchEvent(new CustomEvent('digital-human-runtime-error', { + detail: { message: error.message || String(error) } + })); + }); + } + } + + pause() { + if (this.video) { + this.video.pause(); + } + } +} + +let backgroundVideoPlayToken = 0; + +function setupBackgroundVideo() { + const bgVideo = document.getElementById('background_video'); + if (bgVideo) { + const playToken = ++backgroundVideoPlayToken; + hideBackgroundImage(); + bgVideo.crossOrigin = 'anonymous'; + bgVideo.muted = true; + bgVideo.playsInline = true; + bgVideo.src = CONFIG.backgroundVideoSrc; + bgVideo.style.display = 'block'; + bgVideo.load(); + const playWhenReady = () => { + if (playToken !== backgroundVideoPlayToken || bgVideo.style.display === 'none') return; + bgVideo.play().catch(error => { + if (error?.name !== 'AbortError') { + console.warn('背景视频播放失败:', error); + } + }); + }; + if (bgVideo.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) { + playWhenReady(); + } else { + bgVideo.addEventListener('canplay', playWhenReady, { once: true }); + } + } +} + +function hideBackgroundVideo() { + backgroundVideoPlayToken += 1; + const bgVideo = document.getElementById('background_video'); + if (bgVideo) { + bgVideo.pause(); + bgVideo.removeAttribute('src'); + bgVideo.load(); + bgVideo.style.display = 'none'; + } +} + +function setupBackgroundImage(url) { + const bgImage = document.getElementById('background_image'); + if (!bgImage) return; + hideBackgroundVideo(); + bgImage.crossOrigin = 'anonymous'; + bgImage.src = url; + bgImage.style.display = 'block'; +} + +function hideBackgroundImage() { + const bgImage = document.getElementById('background_image'); + if (!bgImage) return; + bgImage.removeAttribute('src'); + bgImage.style.display = 'none'; +} + +function hideBackgroundMedia() { + hideBackgroundImage(); + hideBackgroundVideo(); +} + +function initChromaKeyGL() { + chromaKeyCanvas = document.createElement('canvas'); + chromaKeyCanvas.width = canvas_video.width; + chromaKeyCanvas.height = canvas_video.height; + + debugLog('初始化绿幕抠图 WebGL, 画布尺寸:', chromaKeyCanvas.width, 'x', chromaKeyCanvas.height); + debugLog('绿幕抠图参数:', CONFIG.chromaKey); + + chromaKeyGl = chromaKeyCanvas.getContext('webgl2', { + antialias: false, + alpha: true, + premultipliedAlpha: false, + // 抠图结果会立即作为 2D canvas 的图像源,必须保留 WebGL 后备缓冲区。 + preserveDrawingBuffer: true + }); + + const vertexShaderSource = `#version 300 es + in vec2 a_position; + in vec2 a_texCoord; + out vec2 v_texCoord; + + void main() { + gl_Position = vec4(a_position, 0.0, 1.0); + v_texCoord = a_texCoord; + } + `; + + const fragmentShaderSource = `#version 300 es + precision highp float; + + in vec2 v_texCoord; + uniform sampler2D u_foreground; + uniform vec3 u_keyColor; + uniform float u_similarity; + uniform float u_smoothness; + uniform float u_spill; + out vec4 outColor; + + void main() { + vec4 fg = texture(u_foreground, v_texCoord); + + vec3 keyColor = u_keyColor; + + float diff = distance(fg.rgb, keyColor); + float mask = smoothstep(u_similarity, u_similarity + u_smoothness, diff); + + float spill = max(0.0, fg.g - max(fg.r, fg.b)) * u_spill; + vec3 color = fg.rgb - spill * keyColor; + + float edgeMask = smoothstep(u_similarity * 0.5, u_similarity, diff); + color = mix(color, fg.rgb, edgeMask * 0.5); + + outColor = vec4(color, mask); + } + `; + + const vertexShader = chromaKeyGl.createShader(chromaKeyGl.VERTEX_SHADER); + chromaKeyGl.shaderSource(vertexShader, vertexShaderSource); + chromaKeyGl.compileShader(vertexShader); + if (!chromaKeyGl.getShaderParameter(vertexShader, chromaKeyGl.COMPILE_STATUS)) { + console.error('顶点着色器编译失败:', chromaKeyGl.getShaderInfoLog(vertexShader)); + } + + const fragmentShader = chromaKeyGl.createShader(chromaKeyGl.FRAGMENT_SHADER); + chromaKeyGl.shaderSource(fragmentShader, fragmentShaderSource); + chromaKeyGl.compileShader(fragmentShader); + if (!chromaKeyGl.getShaderParameter(fragmentShader, chromaKeyGl.COMPILE_STATUS)) { + console.error('片段着色器编译失败:', chromaKeyGl.getShaderInfoLog(fragmentShader)); + } + + chromaKeyProgram = chromaKeyGl.createProgram(); + chromaKeyGl.attachShader(chromaKeyProgram, vertexShader); + chromaKeyGl.attachShader(chromaKeyProgram, fragmentShader); + chromaKeyGl.linkProgram(chromaKeyProgram); + if (!chromaKeyGl.getProgramParameter(chromaKeyProgram, chromaKeyGl.LINK_STATUS)) { + console.error('着色器程序链接失败:', chromaKeyGl.getProgramInfoLog(chromaKeyProgram)); + } else { + debugLog('绿幕抠图着色器初始化成功'); + } + + const positions = new Float32Array([ + -1, -1, 0, 1, + 1, -1, 1, 1, + -1, 1, 0, 0, + 1, 1, 1, 0, + ]); + + const buffer = chromaKeyGl.createBuffer(); + chromaKeyGl.bindBuffer(chromaKeyGl.ARRAY_BUFFER, buffer); + chromaKeyGl.bufferData(chromaKeyGl.ARRAY_BUFFER, positions, chromaKeyGl.STATIC_DRAW); + + const posLoc = chromaKeyGl.getAttribLocation(chromaKeyProgram, 'a_position'); + const texLoc = chromaKeyGl.getAttribLocation(chromaKeyProgram, 'a_texCoord'); + + chromaKeyGl.enableVertexAttribArray(posLoc); + chromaKeyGl.vertexAttribPointer(posLoc, 2, chromaKeyGl.FLOAT, false, 16, 0); + chromaKeyGl.enableVertexAttribArray(texLoc); + chromaKeyGl.vertexAttribPointer(texLoc, 2, chromaKeyGl.FLOAT, false, 16, 8); + + chromaKeyTextures.foreground = chromaKeyGl.createTexture(); + + chromaKeyGl.bindTexture(chromaKeyGl.TEXTURE_2D, chromaKeyTextures.foreground); + chromaKeyGl.texParameteri(chromaKeyGl.TEXTURE_2D, chromaKeyGl.TEXTURE_WRAP_S, chromaKeyGl.CLAMP_TO_EDGE); + chromaKeyGl.texParameteri(chromaKeyGl.TEXTURE_2D, chromaKeyGl.TEXTURE_WRAP_T, chromaKeyGl.CLAMP_TO_EDGE); + chromaKeyGl.texParameteri(chromaKeyGl.TEXTURE_2D, chromaKeyGl.TEXTURE_MIN_FILTER, chromaKeyGl.LINEAR); + chromaKeyGl.texParameteri(chromaKeyGl.TEXTURE_2D, chromaKeyGl.TEXTURE_MAG_FILTER, chromaKeyGl.LINEAR); +} + +function processChromaKey(foregroundSource) { + if (!chromaKeyGl || !chromaKeyProgram) { + return foregroundSource; + } + + chromaKeyGl.viewport(0, 0, chromaKeyCanvas.width, chromaKeyCanvas.height); + chromaKeyGl.clearColor(0, 0, 0, 0); + chromaKeyGl.clear(chromaKeyGl.COLOR_BUFFER_BIT); + + chromaKeyGl.useProgram(chromaKeyProgram); + + chromaKeyGl.activeTexture(chromaKeyGl.TEXTURE0); + chromaKeyGl.bindTexture(chromaKeyGl.TEXTURE_2D, chromaKeyTextures.foreground); + chromaKeyGl.texImage2D(chromaKeyGl.TEXTURE_2D, 0, chromaKeyGl.RGBA, chromaKeyGl.RGBA, chromaKeyGl.UNSIGNED_BYTE, foregroundSource); + + chromaKeyGl.uniform1i(chromaKeyGl.getUniformLocation(chromaKeyProgram, 'u_foreground'), 0); + + // 使用 CONFIG 中的绿幕参数 + chromaKeyGl.uniform3f( + chromaKeyGl.getUniformLocation(chromaKeyProgram, 'u_keyColor'), + CONFIG.chromaKey.keyColor.r, + CONFIG.chromaKey.keyColor.g, + CONFIG.chromaKey.keyColor.b + ); + chromaKeyGl.uniform1f( + chromaKeyGl.getUniformLocation(chromaKeyProgram, 'u_similarity'), + CONFIG.chromaKey.similarity + ); + chromaKeyGl.uniform1f( + chromaKeyGl.getUniformLocation(chromaKeyProgram, 'u_smoothness'), + CONFIG.chromaKey.smoothness + ); + chromaKeyGl.uniform1f( + chromaKeyGl.getUniformLocation(chromaKeyProgram, 'u_spill'), + CONFIG.chromaKey.spill + ); + + chromaKeyGl.drawArrays(chromaKeyGl.TRIANGLE_STRIP, 0, 4); + + return chromaKeyCanvas; +} + +let asset_dir = "assets"; +let isPaused = false; // 标志位,控制是否暂停处理 +// 获取 characterDropdown 元素 +const characterDropdown = document.getElementById('characterDropdown'); + +// 检查元素是否存在 +if (characterDropdown) { + characterDropdown.addEventListener('change', async function() { + isPaused = true; + document.getElementById('startMessage').style.display = 'block'; + asset_dir = this.value; + debugLog('Selected character:', asset_dir); + await videoProcessor.init(asset_dir + "/01.mp4", asset_dir + "/combined_data.json.gz"); + await loadCombinedData(); + await setupVertsBuffers(); + + if (chromaKeyCanvas) { + chromaKeyCanvas.width = canvas_video.width; + chromaKeyCanvas.height = canvas_video.height; + } + + isPaused = false; + videoProcessor.play(); + processVideoFrames(); + }); +} else { + console.warn("characterDropdown 元素未找到,无法绑定事件监听器"); +} +// 初始化处理器 +const videoProcessor = new VideoProcessor(); + +const canvas_gl = document.getElementById('canvas_gl'); +const gl = canvas_gl.getContext('webgl2', { antialias: false }); + +// 最终显示的画布 +const canvas_video = document.getElementById('canvas_video'); +// const ctx_video = canvas_video.getContext('2d'); +const ctx_video = canvas_video.getContext('2d', { + alpha: true, + willReadFrequently: false +}); + +// 缩放到model_size +const resizedCanvas = document.createElement('canvas'); +// const resizedCtx = resizedCanvas.getContext('2d', { willReadFrequently: true }); +const resizedCtx = resizedCanvas.getContext('2d', { + alpha: true, + willReadFrequently: true +}); +resizedCanvas.width = model_size; +resizedCanvas.height = model_size; + +// 创建一个像素缓冲区来存储读取的像素数据 +const pixels_fbo = new Uint8Array(model_size * model_size * 4); + +// 预创建离屏 canvas,用于锁定当前视频帧,避免处理过程中视频继续播放导致不同步 +const lockedFrameCanvas = document.createElement('canvas'); +const lockedFrameCtx = lockedFrameCanvas.getContext('2d', { willReadFrequently: true }); + +let objData; +let dataSets = []; + +let program; +let indexBuffer; +let positionBuffer; +const texture_bs = gl.createTexture(); +var bs_array = new Float32Array(12); + +let currentDataSetIndex; +let lastDataSetIndex = -1; + +let imageDataPtr = null; +let imageDataGlPtr = null; +let bsPtr = null; + +// 解析OBJ文件 +function parseObjFile(text) { + const vertices = []; + const vt = []; + const faces = []; + const lines = text.split('\n'); + + lines.forEach(line => { + const parts = line.trim().split(/\s+/); + if (parts[0] === 'v') { + vertices.push(parseFloat(parts[1]), parseFloat(parts[2]), parseFloat(parts[3]), + parseFloat(parts[4]), parseFloat(parts[5])); + } else if (parts[0] === 'f') { + const face = parts.slice(1).map(part => { + const indices = part.split('/').map(index => parseInt(index, 10) - 1); + return indices[0]; + }); + faces.push(...face); + } + }); + + return { vertices, faces }; +} + +async function loadCombinedData() { + try { + let { json_data, ...WasmInputJson } = videoProcessor.combinedData; + + let jsonString = JSON.stringify(WasmInputJson); + // 分配内存 + // 使用 TextEncoder 计算 UTF-8 字节长度 + function getUTF8Length(str) { + const encoder = new TextEncoder(); + const encoded = encoder.encode(str); + return encoded.length + 1; // +1 是为了包含 null 终止符 + } + let lengthBytes = getUTF8Length(jsonString); + + let stringPointer = Module._malloc(lengthBytes); + Module.stringToUTF8(jsonString, stringPointer, lengthBytes); +// Module["asm"]["stringToUTF8"](jsonString, stringPointer, lengthBytes); + debugLog("Module._processJson", { lengthBytes }); + const version_valid = Module._processJson(stringPointer); + + // 释放内存 + Module._free(stringPointer); + + // 旧资源仍可由当前渲染器兼容读取;不要用原生 alert 阻塞嵌入页和自动录制。 + // 保留诊断警告,后续可根据资源 manifest 做离线迁移。 + if (version_valid === 0) { + console.warn("DH_live 前端与数字人资源版本标识不一致,已按兼容模式继续加载") + } + + // 提取 jsonData + dataSets = videoProcessor.combinedData.json_data; + debugLog('JSON data loaded successfully:', dataSets.length, 'sets.'); + + // 将 dataSets 的内容逆序并加到原列表后面 + dataSets = dataSets.concat(dataSets.slice().reverse()); + debugLog('DataSets after adding reversed content:', dataSets.length, 'sets.'); + + // 提取 objData + objData = parseObjFile(videoProcessor.combinedData.face3D_obj.join('\n')); + debugLog('OBJ data loaded successfully:', objData.vertices.length, 'vertices,', objData.faces.length, 'faces.'); + } catch (error) { + console.error('Error loading the combined data:', error); + throw error; + } +} + + +async function init_gl() { + // WebGL Shaders + const vertexShaderSource = `#version 300 es + layout(location = 0) in vec3 a_position; + layout(location = 1) in vec2 a_texture; + uniform float bsVec[12]; + uniform mat4 gProjection; + uniform mat4 gWorld0; + uniform sampler2D texture_bs; + uniform vec2 vertBuffer[209]; + out vec2 v_texture; + out vec2 v_bias; + + vec4 calculateMorphPosition(vec3 position, vec2 textureCoord) { + vec4 tmp_Position2 = vec4(position, 1.0); + if (textureCoord.x < 3.0 && textureCoord.x >= 0.0) { + vec3 morphSum = vec3(0.0); + for (int i = 0; i < 6; i++) { + ivec2 coord = ivec2(int(textureCoord.y), i); + vec3 morph = texelFetch(texture_bs, coord, 0).xyz * 2.0 - 1.0; + morphSum += bsVec[i] * morph; + } + tmp_Position2.xyz += morphSum; + } + else if (textureCoord.x == 4.0) { + float z_ = (bsVec[0] + bsVec[1])/ 3.9; + z_ = max(z_, 0.0); + vec3 morphSum = vec3(0.0, (bsVec[0] + bsVec[1]) / 3.0 + 6.0, z_); + tmp_Position2.xyz += morphSum; + } + return tmp_Position2; + } + + void main() { + mat4 gWorld = gWorld0; + + vec4 tmp_Position2 = calculateMorphPosition(a_position, a_texture); + vec4 tmp_Position = gWorld * tmp_Position2; + + v_bias = vec2(0.0, 0.0); + if (a_texture.x == -1.0f) { + v_bias = vec2(0.0, 0.0); + } + else if (a_texture.y < 209.0f) { + vec4 vert_new = gProjection * vec4(tmp_Position.x, tmp_Position.y, tmp_Position.z, 1.0); + v_bias = vert_new.xy - (vertBuffer[int(a_texture.y)].xy / 184.0 * 2.0 - 1.0); + } + gl_Position = gProjection * vec4(tmp_Position.xyz, 1.0); + v_texture = a_texture; + } + `; + + const fragmentShaderSource = `#version 300 es + precision mediump float; + in mediump vec2 v_texture; + in mediump vec2 v_bias; + out vec4 out_color; + + void main() { + if (v_texture.x == 2.0f) { + out_color = vec4(1.0, 0.0, 0.0, 1.0); + } + else if (v_texture.x > 2.0f && v_texture.x < 2.1f) { + out_color = vec4(0.5f, 0.0, 0.0, 1.0); + } + else if (v_texture.x == 3.0f) { + out_color = vec4(0.0, 1.0, 0.0, 1.0); + } + else if (v_texture.x == 4.0f) { + out_color = vec4(0.0, 0.0, 1.0, 1.0); + } + else if (v_texture.x > 3.0f && v_texture.x < 4.0f) { + out_color = vec4(0.0, 0.0, 0.0, 1.0); + } + else if (v_texture.x == -2.0f) { + out_color = vec4(0.0, 0.0, 0.0, 1.0); + } + else { + vec2 wrap = (v_bias.xy + 1.0) / 2.0; + out_color = vec4(wrap.xy, 0.5, 1.0); + } + } + `; + + // Compile shaders and link program + const vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexShaderSource); + gl.compileShader(vertexShader); + + const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentShaderSource); + gl.compileShader(fragmentShader); + + program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.useProgram(program); + + // Set up vertex data + positionBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(objData.vertices), gl.STATIC_DRAW); + gl.enableVertexAttribArray(0); + gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 20, 0); + + gl.enableVertexAttribArray(1); + gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 20, 12); + + indexBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(objData.faces), gl.STATIC_DRAW); + + var image = new Image(); + image.crossOrigin = 'anonymous'; + image.onload = function () { + gl.bindTexture(gl.TEXTURE_2D, texture_bs); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); +// gl.bindTexture(gl.TEXTURE_2D, null); + + gl.activeTexture(gl.TEXTURE0); + gl.uniform1i(gl.getUniformLocation(program, 'texture_bs'), 0); + }; + image.src = CONFIG.blendshapeTextureSrc || '/viewer-static/common/bs_texture_halfFace.png'; +} +async function setupVertsBuffers() { + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(objData.vertices), gl.STATIC_DRAW); +} + +async function newVideoTask() { + await videoProcessor.init(CONFIG.videoSrc, CONFIG.dataSrc); + await loadCombinedData(); + await init_gl(); + await setupVertsBuffers(); + initMemory(); + + if (CONFIG.chromaKeyEnabled) { + initChromaKeyGL(); + setupBackgroundVideo(); + } else { + hideBackgroundVideo(); + } + + videoProcessor.play(); + processVideoFrames(); + document.getElementById('startMessage').style.display = 'none'; + window.DH_RUNTIME_READY = true; + window.dispatchEvent(new CustomEvent('digital-human-runtime-ready')); +} + +function cerateOrthoMatrix() +{ + const orthoMatrix = new Float32Array(16); + +// 定义正交投影参数 +const left = 0; +const right = model_size; +const bottom = 0; +const top = model_size; +const near = 1000; +const far = -1000; + +// 计算各轴跨度 +const rl = right - left; +const tb = top - bottom; +const fn = far - near; + +// 列主序填充正交投影矩阵 +// 第一列 (x) +orthoMatrix[0] = 2 / rl; +orthoMatrix[1] = 0; +orthoMatrix[2] = 0; +orthoMatrix[3] = 0; + +// 第二列 (y) +orthoMatrix[4] = 0; +orthoMatrix[5] = 2 / tb; +orthoMatrix[6] = 0; +orthoMatrix[7] = 0; + +// 第三列 (z) +orthoMatrix[8] = 0; +orthoMatrix[9] = 0; +orthoMatrix[10] = -2 / fn; +orthoMatrix[11] = 0; + +// 第四列 (平移) +orthoMatrix[12] = -(right + left) / rl; +orthoMatrix[13] = -(top + bottom) / tb; +orthoMatrix[14] = -(far + near) / fn; +orthoMatrix[15] = 1; +return orthoMatrix; +} + +function render(mat_world, subPoints, bsArray) { + if (isPaused) { + // 如果暂停,直接返回,不处理帧 + return; + } + gl.useProgram(program); + const worldMatUniformLocation = gl.getUniformLocation(program, "gWorld0"); + gl.uniformMatrix4fv(worldMatUniformLocation, false, mat_world); + + gl.uniform2fv(gl.getUniformLocation(program, "vertBuffer"), subPoints); + gl.uniform1fv(gl.getUniformLocation(program, "bsVec"), bsArray); + + const projectionUniformLocation = gl.getUniformLocation(program, "gProjection"); + const orthoMatrix = cerateOrthoMatrix(); + gl.uniformMatrix4fv(projectionUniformLocation, false, orthoMatrix); + + gl.enable(gl.DEPTH_TEST); + // gl.enable(gl.BLEND); + // gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + gl.enable(gl.CULL_FACE); + gl.cullFace(gl.BACK); + gl.frontFace(gl.CW); + gl.clearColor(0.5, 0.5, 0.5, 0); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + const width = gl.drawingBufferWidth; + const height = gl.drawingBufferHeight; + gl.drawElements(gl.TRIANGLES, objData.faces.length, gl.UNSIGNED_SHORT, 0); + + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels_fbo); +} + + + +async function processVideoFrames() { + if (isPaused) { + return; + } + + const currentTime = performance.now(); + const deltaTime = currentTime - videoProcessor.lastFrameTime; + + if (deltaTime >= FRAME_INTERVAL) { + videoProcessor.lastFrameTime = currentTime - (deltaTime % FRAME_INTERVAL); + + // 一次性将当前视频帧绘制到离屏 canvas,锁定当前帧,避免后续处理中视频继续播放导致不同步 + if (lockedFrameCanvas.width !== canvas_video.width || + lockedFrameCanvas.height !== canvas_video.height) { + lockedFrameCanvas.width = canvas_video.width; + lockedFrameCanvas.height = canvas_video.height; + } + lockedFrameCtx.drawImage(videoProcessor.video, 0, 0, canvas_video.width, canvas_video.height); + + if (!frameIndexCanvas) { + frameIndexCanvas = document.createElement('canvas'); + frameIndexCanvas.width = 2; + frameIndexCanvas.height = 2; + frameIndexCtx = frameIndexCanvas.getContext('2d', { willReadFrequently: true }); + } + + // 从锁定的帧 canvas 读取帧序号像素 + frameIndexCtx.clearRect(0, 0, 2, 2); + frameIndexCtx.drawImage(lockedFrameCanvas, + canvas_video.width - 2, 0, 2, 2, + 0, 0, 2, 2); + const pixelData = frameIndexCtx.getImageData(0, 0, 2, 2); + const currentFrameIndex = videoProcessor.getCurrentFrameIndex(pixelData.data); + + ctx_video.clearRect(0, 0, canvas_video.width, canvas_video.height); + + if (CONFIG.chromaKeyEnabled && chromaKeyGl) { + const chromaKeyResult = processChromaKey(lockedFrameCanvas); + ctx_video.drawImage(chromaKeyResult, 0, 0, canvas_video.width, canvas_video.height); + } else { + ctx_video.drawImage(lockedFrameCanvas, 0, 0, canvas_video.width, canvas_video.height); + } + + // console.log("currentFrameIndex", currentFrameIndex, videoProcessor.video.currentTime); + + processDataSet(currentFrameIndex); + + if (CONFIG.showFPS) { + frameTimes.push(currentTime); + + while (frameTimes.length > 0 && currentTime - frameTimes[0] > 1000) { + frameTimes.shift(); + } + + const fps = frameTimes.length; + ctx_video.fillStyle = 'white'; + ctx_video.font = '16px Arial'; + ctx_video.textAlign = 'right'; + ctx_video.fillText(`FPS: ${fps}`, canvas_video.width - 10, 20); + } + } + + requestAnimationFrame(processVideoFrames); +} + +async function initMemory() { + const imageDataSize = model_size * model_size * 4; // RGBA + imageDataPtr = Module._malloc(imageDataSize); + imageDataGlPtr = Module._malloc(imageDataSize); + bsPtr = Module._malloc(12 * 4); // 12 floats for blend shape +} +async function processDataSet(currentDataSetIndex) { + if (isPaused) { + // 如果暂停,直接返回,不处理帧 + return; + } + const dataSet = dataSets[currentDataSetIndex]; + const rect = dataSet.rect; + + const currentpoints = dataSets[currentDataSetIndex].points; + + const matrix = new Float32Array(16); + matrix.set(currentpoints.slice(0, 16)); + + const subPoints = currentpoints.slice(16); + Module._updateBlendShape(bsPtr, 12 * 4); + const bsArray = new Float32Array(Module.HEAPU8.buffer, bsPtr, 12); + + render(matrix, subPoints, bsArray); + // console.log("bsArray", bsArray); + resizedCtx.clearRect(0, 0, model_size, model_size); + resizedCtx.drawImage(canvas_video, rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1], 0, 0, model_size, model_size); + + const imageData = resizedCtx.getImageData(0, 0, model_size, model_size); + const originalImageData = CONFIG.removeWatermark + ? new Uint8ClampedArray(imageData.data) + : null; + Module.HEAPU8.set(imageData.data, imageDataPtr); + + Module.HEAPU8.set(pixels_fbo, imageDataGlPtr); + + Module._processImage(imageDataPtr, model_size, model_size, imageDataGlPtr, currentDataSetIndex); + const result = Module.HEAPU8.subarray(imageDataPtr, imageDataPtr + imageData.data.length); + imageData.data.set(result); + + // 未授权 WASM 会在 184x184 人脸块的右下区域叠加红色 MatesX。 + // 只修补水印笔画,不再整块恢复原视频,避免说话时下巴位置不一致。 + if (originalImageData) { + restoreWasmWatermarkPixels(imageData.data, originalImageData, model_size); + } + + resizedCtx.putImageData(imageData, 0, 0); + ctx_video.drawImage(resizedCanvas, 0, 0, model_size, model_size, rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]); +} + +function restoreWasmWatermarkPixels(processedPixels, originalPixels, size) { + // 水印在模型人脸块内的位置固定;检测区位于嘴部下方。 + const xStart = Math.floor(size * 0.51); + const xEnd = Math.ceil(size * 0.95); + const yStart = Math.floor(size * 0.73); + const yEnd = Math.ceil(size * 0.90); + const coreMask = new Uint8Array(size * size); + let detectedPixels = 0; + + for (let y = yStart; y < yEnd; y++) { + for (let x = xStart; x < xEnd; x++) { + const pixelIndex = y * size + x; + const offset = pixelIndex * 4; + const r = processedPixels[offset]; + const g = processedPixels[offset + 1]; + const b = processedPixels[offset + 2]; + const colorDelta = Math.abs(r - originalPixels[offset]) + + Math.abs(g - originalPixels[offset + 1]) + + Math.abs(b - originalPixels[offset + 2]); + + // MatesX 的核心笔画是高饱和深红色。严格限制 G/B 可排除肤色。 + if (r > 115 && g < 110 && b < 130 + && r - g > 45 && r - b > 35 && colorDelta > 55) { + coreMask[pixelIndex] = 1; + detectedPixels++; + } + } + } + + if (detectedPixels < 6) { + return; + } + + // 1、2 分别表示水印核心和两级抗锯齿边缘。 + const restoreMask = new Uint8Array(coreMask); + for (let radius = 1; radius <= 2; radius++) { + for (let y = yStart; y < yEnd; y++) { + for (let x = xStart; x < xEnd; x++) { + const pixelIndex = y * size + x; + if (!coreMask[pixelIndex]) { + continue; + } + for (let dy = -radius; dy <= radius; dy++) { + for (let dx = -radius; dx <= radius; dx++) { + if (Math.max(Math.abs(dx), Math.abs(dy)) !== radius) { + continue; + } + const nx = x + dx; + const ny = y + dy; + if (nx >= xStart && nx < xEnd && ny >= yStart && ny < yEnd) { + const neighborIndex = ny * size + nx; + if (!restoreMask[neighborIndex]) { + restoreMask[neighborIndex] = radius + 1; + } + } + } + } + } + } + } + + // 只在文字形状内混回同一帧原像素;下巴其余区域完全保留 WASM 输出。 + for (let y = yStart; y < yEnd; y++) { + for (let x = xStart; x < xEnd; x++) { + const pixelIndex = y * size + x; + const maskValue = restoreMask[pixelIndex]; + if (!maskValue) { + continue; + } + const offset = pixelIndex * 4; + const blend = maskValue === 1 ? 1.0 : (maskValue === 2 ? 0.72 : 0.28); + for (let channel = 0; channel < 4; channel++) { + processedPixels[offset + channel] = processedPixels[offset + channel] * (1 - blend) + + originalPixels[offset + channel] * blend; + } + } + } +} + +window.DigitalHumanRuntime = { + pause() { + isPaused = true; + videoProcessor.pause(); + }, + resume() { + if (!isPaused) return; + isPaused = false; + videoProcessor.play(); + processVideoFrames(); + }, + setBackground(url, type = 'video') { + // 无背景表示让抠图后的数字人画布保持透明,供宿主页面自行叠加网页背景。 + // 不能关闭 chroma key,否则 CPU 抠图生成的绿幕会重新显示出来。 + CONFIG.chromaKeyEnabled = true; + if (!chromaKeyGl) initChromaKeyGL(); + if (!url) { + hideBackgroundMedia(); + return; + } + if (type === 'image') { + setupBackgroundImage(url); + return; + } + if (type !== 'video') { + throw new Error('backgroundType must be image or video'); + } + CONFIG.backgroundVideoSrc = url; + setupBackgroundVideo(); + }, + isPaused() { + return isPaused; + } +}; diff --git a/reports/bridge-lipsync-diagnosis-20260914/remote-control-bridge.js b/reports/bridge-lipsync-diagnosis-20260914/remote-control-bridge.js new file mode 100644 index 0000000..780d37f --- /dev/null +++ b/reports/bridge-lipsync-diagnosis-20260914/remote-control-bridge.js @@ -0,0 +1,206 @@ +(function installControlBridge() { + const allowedOrigins = window.DH_ALLOWED_PARENT_ORIGINS || ["*"]; + const statusElement = document.getElementById("status"); + let audioContext = null; + let currentSource = null; + let currentRequestId = null; + let ready = false; + let volume = 1; + + function isAllowedOrigin(origin) { + return allowedOrigins.includes("*") || allowedOrigins.includes(origin); + } + + function send(target, targetOrigin, type, payload = {}) { + if (!target || typeof target.postMessage !== "function") return; + target.postMessage({ type, avatarId: window.DH_BOOTSTRAP.avatarId, ...payload }, targetOrigin); + } + + function notifyParent(type, payload = {}) { + if (window.parent === window) return; + if (allowedOrigins.includes("*")) { + send(window.parent, "*", type, payload); + return; + } + for (const origin of allowedOrigins) { + send(window.parent, origin, type, payload); + } + } + + function requireReady() { + if (!ready || !window.Module || !window.DigitalHumanRuntime) { + throw new Error("digital human runtime is not ready"); + } + } + + function markReady() { + ready = true; + if (statusElement) statusElement.style.display = "none"; + notifyParent("digital-human.ready", {}); + } + + function clearWasmAudio() { + if (window.Module && typeof window.Module._clearAudio === "function") { + window.Module._clearAudio(); + } + } + + function stopAudio(emitEvent = true) { + if (currentSource) { + currentSource.onended = null; + try { currentSource.stop(); } catch (_) { /* already stopped */ } + currentSource.disconnect(); + currentSource = null; + } + clearWasmAudio(); + if (emitEvent && currentRequestId) { + notifyParent("digital-human.speaking-end", { + requestId: currentRequestId, + reason: "stopped", + }); + } + currentRequestId = null; + } + + async function resolveAudioBuffer(message) { + if (message.audioBuffer instanceof ArrayBuffer) { + return message.audioBuffer; + } + if (ArrayBuffer.isView(message.audioBuffer)) { + return message.audioBuffer.buffer.slice( + message.audioBuffer.byteOffset, + message.audioBuffer.byteOffset + message.audioBuffer.byteLength + ); + } + if (message.audioBase64) { + const binary = atob(message.audioBase64); + const bytes = new Uint8Array(binary.length); + for (let index = 0; index < binary.length; index++) { + bytes[index] = binary.charCodeAt(index); + } + return bytes.buffer; + } + if (message.audioUrl) { + const response = await fetch(message.audioUrl); + if (!response.ok) { + throw new Error(`audio download failed with HTTP ${response.status}`); + } + return await response.arrayBuffer(); + } + throw new Error("audioBuffer, audioBase64, or audioUrl is required"); + } + + async function playAudio(message) { + requireReady(); + const compressedAudio = await resolveAudioBuffer(message); + stopAudio(false); + + const wasmBytes = new Uint8Array(compressedAudio); + const pointer = window.Module._malloc(wasmBytes.byteLength); + try { + window.Module.HEAPU8.set(wasmBytes, pointer); + window.Module._setAudioBuffer(pointer, wasmBytes.byteLength); + } finally { + window.Module._free(pointer); + } + + audioContext = audioContext || new (window.AudioContext || window.webkitAudioContext)(); + if (audioContext.state === "suspended") { + await audioContext.resume(); + } + const decoded = await audioContext.decodeAudioData(compressedAudio.slice(0)); + const gain = audioContext.createGain(); + gain.gain.value = volume; + gain.connect(audioContext.destination); + currentSource = audioContext.createBufferSource(); + currentSource.buffer = decoded; + currentSource.connect(gain); + currentRequestId = message.requestId || crypto.randomUUID(); + currentSource.onended = () => { + const requestId = currentRequestId; + currentSource = null; + currentRequestId = null; + // Natural playback completion must release the same WASM buffer as + // an explicit stop. Otherwise the browser audio is silent while the + // lip-sync runtime keeps consuming stale samples. + clearWasmAudio(); + notifyParent("digital-human.speaking-end", { + requestId, + reason: "ended", + }); + }; + currentSource.start(0); + notifyParent("digital-human.speaking-start", { + requestId: currentRequestId, + duration: decoded.duration, + }); + } + + async function handleCommand(event) { + if (!isAllowedOrigin(event.origin)) return; + const message = event.data || {}; + if (typeof message.type !== "string" || !message.type.startsWith("digital-human.")) { + return; + } + try { + switch (message.type) { + case "digital-human.play-audio": + await playAudio(message); + break; + case "digital-human.stop": + stopAudio(true); + break; + case "digital-human.pause": + requireReady(); + window.DigitalHumanRuntime.pause(); + if (audioContext) await audioContext.suspend(); + break; + case "digital-human.resume": + requireReady(); + window.DigitalHumanRuntime.resume(); + if (audioContext) await audioContext.resume(); + break; + case "digital-human.set-background": + requireReady(); + window.DigitalHumanRuntime.setBackground( + message.backgroundUrl || null, + message.backgroundType || "video" + ); + break; + case "digital-human.set-volume": + volume = Math.max(0, Math.min(1, Number(message.volume))); + break; + case "digital-human.get-state": + send(event.source, event.origin, "digital-human.state", { + requestId: message.requestId, + ready, + speaking: Boolean(currentSource), + paused: window.DigitalHumanRuntime?.isPaused() ?? false, + }); + return; + default: + return; + } + send(event.source, event.origin, "digital-human.command-accepted", { + requestId: message.requestId, + command: message.type, + }); + } catch (error) { + send(event.source, event.origin, "digital-human.error", { + requestId: message.requestId, + message: error instanceof Error ? error.message : String(error), + }); + } + } + + window.addEventListener("message", handleCommand); + window.addEventListener("digital-human-runtime-ready", markReady); + // The runtime can finish between the preceding script tag and bridge + // installation. Preserve the ready state so fast local bundles cannot lose + // the only handshake event. + if (window.DH_RUNTIME_READY) queueMicrotask(markReady); + window.addEventListener("error", (event) => { + if (statusElement) statusElement.textContent = "数字人加载失败"; + notifyParent("digital-human.error", { message: event.message || "viewer error" }); + }); +})(); diff --git a/reports/bridge-lipsync-diagnosis-20260914/reproduced-frame.png b/reports/bridge-lipsync-diagnosis-20260914/reproduced-frame.png new file mode 100644 index 0000000..f1fecee Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914/reproduced-frame.png differ diff --git a/reports/bridge-lipsync-diagnosis-20260914/reproduced.rgb b/reports/bridge-lipsync-diagnosis-20260914/reproduced.rgb new file mode 100644 index 0000000..5934de4 Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914/reproduced.rgb differ diff --git a/reports/bridge-lipsync-diagnosis-20260914/runtime.json b/reports/bridge-lipsync-diagnosis-20260914/runtime.json new file mode 100644 index 0000000..5c3a96e --- /dev/null +++ b/reports/bridge-lipsync-diagnosis-20260914/runtime.json @@ -0,0 +1,4075 @@ +{ + "frames": [ + { + "t": 10.799999713897705, + "ms": 1.5, + "values": [ + -7.333581924438477, + -1.3326692581176758, + -0.4915201663970947, + -1.0617811679840088, + 1.1403899192810059, + -1.4151867628097534, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 62.799999713897705, + "ms": 1.4000000953674316, + "values": [ + -10.414820671081543, + -2.5791680812835693, + -2.9664151668548584, + -1.4958993196487427, + 1.6885420083999634, + -2.3302152156829834, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 114.5, + "ms": 1.1999998092651367, + "values": [ + -11.187210083007812, + -2.4062650203704834, + -3.008010149002075, + -1.6241434812545776, + 1.7497658729553223, + -2.3635599613189697, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 162.59999990463257, + "ms": 1.6999998092651367, + "values": [ + -11.41242790222168, + -2.291626214981079, + -3.0029213428497314, + -1.7169710397720337, + 1.8058910369873047, + -2.4175188541412354, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 204.2999997138977, + "ms": 0.7000002861022949, + "values": [ + -11.405503273010254, + -2.158625841140747, + -2.987684488296509, + -1.7998685836791992, + 1.8586337566375732, + -2.4592525959014893, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 235.19999980926514, + "ms": 1.0999999046325684, + "values": [ + -11.234643936157227, + -1.9874532222747803, + -2.9421188831329346, + -1.8663241863250732, + 1.9030104875564575, + -2.502091646194458, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 353, + "ms": 1.5999999046325684, + "values": [ + -11.000639915466309, + -1.804243803024292, + -2.8916399478912354, + -1.9170767068862915, + 1.9341318607330322, + -2.5452568531036377, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 391.40000009536743, + "ms": 0.5999999046325684, + "values": [ + -10.71794319152832, + -1.636136531829834, + -2.8416473865509033, + -1.9587112665176392, + 1.9675533771514893, + -2.5838072299957275, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 547.1999998092651, + "ms": 1.5, + "values": [ + 1.405081033706665, + -10.04085922241211, + 4.504970550537109, + -2.0723888874053955, + 3.738966941833496, + -1.308504343032837, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 589, + "ms": 1.5, + "values": [ + -2.5699405670166016, + -12.367692947387695, + 6.7443037033081055, + -1.5549615621566772, + 4.258182525634766, + -1.4520602226257324, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 625.1999998092651, + "ms": 0.8000001907348633, + "values": [ + -2.828125, + -16.07012367248535, + 7.532029151916504, + -2.3541605472564697, + 4.504526615142822, + -1.523911476135254, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 662.5999999046326, + "ms": 0.8000001907348633, + "values": [ + 6.852521896362305, + -10.746471405029297, + 7.38546085357666, + -1.7370903491973877, + 3.70324444770813, + -1.0641447305679321, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 730.1999998092651, + "ms": 0.9000000953674316, + "values": [ + 19.386816024780273, + -0.9064590930938721, + 3.380399227142334, + -1.7421300411224365, + 3.240464687347412, + 0.039005160331726074, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 765.1999998092651, + "ms": 0.40000009536743164, + "values": [ + 11.988037109375, + -4.038861274719238, + -1.7676773071289062, + -2.422168493270874, + 2.9285049438476562, + 0.13217683136463165, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 797.7999997138977, + "ms": 0.7000002861022949, + "values": [ + -3.9641103744506836, + -6.1270904541015625, + -4.378006935119629, + -1.0393428802490234, + 3.6242282390594482, + 1.2251720428466797, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 833.0999999046326, + "ms": 0.6999998092651367, + "values": [ + -9.626608848571777, + -3.8484878540039062, + -3.03684401512146, + -0.10024029016494751, + 3.691019296646118, + 2.2176899909973145, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 867.5, + "ms": 1.0999999046325684, + "values": [ + -10.776272773742676, + 1.7973796129226685, + -0.7483789920806885, + 0.7960360050201416, + 3.889455556869507, + 2.3845324516296387, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 900.7999997138977, + "ms": 1.200000286102295, + "values": [ + -11.495360374450684, + 7.704944133758545, + -0.03116607666015625, + 0.9048638343811035, + 3.6937100887298584, + 1.9758758544921875, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 941.9000000953674, + "ms": 1.0999999046325684, + "values": [ + -11.672282218933105, + 8.085990905761719, + -0.524709939956665, + 0.6705906391143799, + 3.2107372283935547, + 1.3782856464385986, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 992.5999999046326, + "ms": 1.6999998092651367, + "values": [ + -11.631510734558105, + 7.220142364501953, + -1.9030439853668213, + 0.3304102420806885, + 2.372007369995117, + 0.8421545624732971, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1030, + "ms": 1.5999999046325684, + "values": [ + -9.958861351013184, + 3.3963136672973633, + -3.936389207839966, + -1.2671735286712646, + 2.2093112468719482, + 1.398576259613037, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1075.4000000953674, + "ms": 1.1999998092651367, + "values": [ + -4.954394340515137, + -0.7305753231048584, + -6.545392990112305, + -3.0057616233825684, + 2.1796882152557373, + 2.1463990211486816, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1130.9000000953674, + "ms": 1.6999998092651367, + "values": [ + 5.180577754974365, + -1.5265878438949585, + -5.886059761047363, + -2.985342025756836, + 2.868682861328125, + 2.341963291168213, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1166.9000000953674, + "ms": 0.5999999046325684, + "values": [ + 23.004352569580078, + 3.748051166534424, + -3.043851137161255, + -1.5742658376693726, + 4.3539886474609375, + 2.1068406105041504, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1203.4000000953674, + "ms": 1.3999996185302734, + "values": [ + 45.127723693847656, + 13.009882926940918, + -3.8401896953582764, + 2.840515375137329, + 6.823270797729492, + 1.7617861032485962, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1240.2999997138977, + "ms": 1, + "values": [ + 47.522159576416016, + 8.68051815032959, + -1.8436079025268555, + 4.532628059387207, + 5.481573581695557, + -0.8211276531219482, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1279.0999999046326, + "ms": 0.8000001907348633, + "values": [ + 47.238914489746094, + 8.010187149047852, + -2.750443696975708, + 5.709020614624023, + 4.778693675994873, + -1.578502893447876, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1313.5, + "ms": 0.40000009536743164, + "values": [ + 46.17533493041992, + 7.08312463760376, + -2.214508056640625, + 5.085385322570801, + 4.9773640632629395, + -1.1927706003189087, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1347.5, + "ms": 0.7999997138977051, + "values": [ + 34.10588455200195, + 13.2170991897583, + -2.747413158416748, + 5.305959224700928, + 3.7947309017181396, + -1.163221001625061, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1378.5999999046326, + "ms": 1.3000001907348633, + "values": [ + 6.377496719360352, + 20.728971481323242, + -4.3419599533081055, + 7.667971611022949, + 3.0104784965515137, + -0.3076810836791992, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1423.5999999046326, + "ms": 0.6999998092651367, + "values": [ + -9.109881401062012, + 22.246265411376953, + -5.712993144989014, + 6.831658363342285, + 2.679291248321533, + 0.346419095993042, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1460.6999998092651, + "ms": 0.5, + "values": [ + -12.302227973937988, + 17.778223037719727, + -5.430683135986328, + 5.67387056350708, + 3.1260838508605957, + 0.42355096340179443, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1508.9000000953674, + "ms": 1.1999998092651367, + "values": [ + -15.643010139465332, + 15.087658882141113, + -2.7888355255126953, + 5.949488162994385, + 3.5413308143615723, + 0.40715503692626953, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1545.5, + "ms": 0.5999999046325684, + "values": [ + -17.244525909423828, + 13.116340637207031, + -0.334753155708313, + 6.358853340148926, + 4.081623077392578, + 0.08156415820121765, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1584.6999998092651, + "ms": 1.5999999046325684, + "values": [ + -16.852203369140625, + 12.191290855407715, + -0.39444780349731445, + 6.108586311340332, + 4.106612205505371, + -0.2646039128303528, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1625.1999998092651, + "ms": 0.8000001907348633, + "values": [ + -15.169610023498535, + 12.316083908081055, + -1.41782808303833, + 5.451694488525391, + 4.429863452911377, + -0.05795924365520477, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1661.0999999046326, + "ms": 0.9000000953674316, + "values": [ + -14.383404731750488, + 13.170860290527344, + -0.5148999691009521, + 5.636154651641846, + 4.638479232788086, + 0.05197364091873169, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1707.6999998092651, + "ms": 0.7000002861022949, + "values": [ + -16.984088897705078, + 13.966556549072266, + 2.2365942001342773, + 5.802814483642578, + 5.047005653381348, + 0.024337098002433777, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1744.6999998092651, + "ms": 1.5, + "values": [ + -18.8660888671875, + 14.659078598022461, + 1.0794949531555176, + 5.168883800506592, + 4.859053611755371, + -0.22195173799991608, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1782.4000000953674, + "ms": 0.5, + "values": [ + -17.762920379638672, + 14.754554748535156, + -2.1386849880218506, + 4.46995735168457, + 3.7449839115142822, + -0.7805148959159851, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1826.6999998092651, + "ms": 0.9000000953674316, + "values": [ + -14.04312801361084, + 14.607677459716797, + -3.937012195587158, + 4.600213527679443, + 3.0591235160827637, + -1.152369737625122, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1865.4000000953674, + "ms": 0.7999997138977051, + "values": [ + -10.855976104736328, + 12.63978099822998, + -5.631303787231445, + 5.263982772827148, + 3.008049964904785, + -1.983312726020813, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1906.7999997138977, + "ms": 1, + "values": [ + -10.633963584899902, + 5.799996376037598, + -7.404681205749512, + 7.608638763427734, + 3.7478108406066895, + -2.453716278076172, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1945.7999997138977, + "ms": 0.6000003814697266, + "values": [ + -6.54232120513916, + 1.6812419891357422, + -6.905872821807861, + 8.386180877685547, + 4.181448936462402, + -2.532014846801758, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 1989.0999999046326, + "ms": 1.3000001907348633, + "values": [ + 3.394083261489868, + 5.280542850494385, + -5.819310665130615, + 7.751677513122559, + 4.097428798675537, + -2.351985454559326, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2029.7999997138977, + "ms": 0.7000002861022949, + "values": [ + 25.189495086669922, + 4.528913497924805, + -4.615684509277344, + 5.211656093597412, + 4.299961090087891, + -2.9121458530426025, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2083.7999997138977, + "ms": 1.6000003814697266, + "values": [ + 35.67892837524414, + 11.364232063293457, + -2.786463737487793, + 3.9713079929351807, + 3.770238161087036, + -2.3063228130340576, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2137.199999809265, + "ms": 1.200000286102295, + "values": [ + 32.48588180541992, + 11.073118209838867, + -2.2249884605407715, + 3.3339240550994873, + 2.9182114601135254, + -2.6282992362976074, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2175.7999997138977, + "ms": 2.4000000953674316, + "values": [ + 23.448562622070312, + 7.4625163078308105, + -2.640291690826416, + 2.0042121410369873, + 1.4932266473770142, + -3.415408134460449, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2217.199999809265, + "ms": 0.9000000953674316, + "values": [ + 14.179403305053711, + 2.673830032348633, + -1.9936761856079102, + 0.8258535861968994, + 0.8296573758125305, + -4.321136474609375, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2251.699999809265, + "ms": 1.700000286102295, + "values": [ + 14.829519271850586, + -1.8155677318572998, + -0.727868378162384, + 0.6897602081298828, + 0.23330828547477722, + -5.119823455810547, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2297.199999809265, + "ms": 0.7000002861022949, + "values": [ + 10.241984367370605, + -6.587217807769775, + 1.6387263536453247, + -0.2942531108856201, + -0.6639268398284912, + -3.787496328353882, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2338.9000000953674, + "ms": 1.1999998092651367, + "values": [ + 18.795671463012695, + -0.8421332240104675, + 1.290588617324829, + 0.12070503830909729, + 0.7749068140983582, + -2.722313642501831, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2374.2999997138977, + "ms": 0.3000001907348633, + "values": [ + 29.106239318847656, + 8.637682914733887, + 0.5522529482841492, + 1.5388041734695435, + 1.1043201684951782, + -3.3703153133392334, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2409.9000000953674, + "ms": 1.299999713897705, + "values": [ + 39.79912185668945, + 11.156234741210938, + -0.4867596924304962, + 3.945452928543091, + 2.1703479290008545, + -3.4286906719207764, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2448.5999999046326, + "ms": 0.6999998092651367, + "values": [ + 46.29541015625, + 12.53666877746582, + -1.4804795980453491, + 4.917768955230713, + 3.1461985111236572, + -2.8023345470428467, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2481, + "ms": 1.799999713897705, + "values": [ + 48.215579986572266, + 9.940902709960938, + -1.149629831314087, + 5.842483043670654, + 4.709728240966797, + -1.7848483324050903, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2525.0999999046326, + "ms": 1.3000001907348633, + "values": [ + 42.24689865112305, + 4.877431869506836, + -0.5340486764907837, + 5.912855625152588, + 5.313474655151367, + -1.6629164218902588, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2559.5999999046326, + "ms": 0.6999998092651367, + "values": [ + 28.92166519165039, + -2.12764835357666, + -5.178244590759277, + 3.4987363815307617, + 5.133848190307617, + -0.34786170721054077, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2593.5999999046326, + "ms": 1.1999998092651367, + "values": [ + 18.660991668701172, + -5.043009281158447, + -7.668257236480713, + 2.583420753479004, + 4.831768989562988, + 0.6142326593399048, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2633.9000000953674, + "ms": 1.6999998092651367, + "values": [ + 19.867700576782227, + -1.9973244667053223, + -5.0466814041137695, + 2.2058284282684326, + 4.934624671936035, + 1.4534672498703003, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2680, + "ms": 0.6999998092651367, + "values": [ + 23.905536651611328, + 0.18410468101501465, + -0.7218185663223267, + 3.395782709121704, + 5.349031925201416, + 1.2469977140426636, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2717.199999809265, + "ms": 1, + "values": [ + 7.418901443481445, + -5.164750576019287, + 3.370976209640503, + 1.5435657501220703, + 4.51046085357666, + 1.5548746585845947, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2756.5, + "ms": 1.0999999046325684, + "values": [ + 9.099308967590332, + -6.625756740570068, + 3.896385908126831, + 1.4947855472564697, + 4.052497386932373, + 0.34605133533477783, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2790.5999999046326, + "ms": 0.6999998092651367, + "values": [ + 24.89267921447754, + -0.4589727222919464, + 5.008519649505615, + 1.5865917205810547, + 5.178462982177734, + 0.569853663444519, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2826.4000000953674, + "ms": 0.7999997138977051, + "values": [ + 21.518386840820312, + -1.3559319972991943, + 7.264543533325195, + 2.917613983154297, + 5.783586502075195, + 1.0494965314865112, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2860.0999999046326, + "ms": 0.6999998092651367, + "values": [ + -7.011378765106201, + -1.8959617614746094, + 15.074334144592285, + 4.998197555541992, + 5.446478843688965, + 2.4856865406036377, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2907.5, + "ms": 0.40000009536743164, + "values": [ + -17.12105369567871, + 0.6644372344017029, + 16.738935470581055, + 4.6373090744018555, + 4.497582912445068, + 2.862213373184204, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2942.199999809265, + "ms": 0.5999999046325684, + "values": [ + -10.036805152893066, + 4.547932147979736, + 10.198807716369629, + 3.51548433303833, + 3.4132533073425293, + 1.3135766983032227, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 2993.4000000953674, + "ms": 1, + "values": [ + -10.527900695800781, + -0.7198257446289062, + 3.918792963027954, + 3.3892669677734375, + 3.36521053314209, + -0.7882927656173706, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3024.9000000953674, + "ms": 0.5999999046325684, + "values": [ + -14.903278350830078, + -7.464247703552246, + 1.0656404495239258, + 5.855109214782715, + 4.321291923522949, + -1.7634592056274414, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3059.5999999046326, + "ms": 0.5, + "values": [ + -14.259941101074219, + -8.14258861541748, + 1.4000468254089355, + 6.179186820983887, + 4.3505449295043945, + -1.7881889343261719, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3107.9000000953674, + "ms": 0.8999996185302734, + "values": [ + -10.471424102783203, + -2.732942819595337, + 2.55348539352417, + 5.5422868728637695, + 3.9513766765594482, + -1.3953561782836914, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3146.7999997138977, + "ms": 0.8000001907348633, + "values": [ + -5.725350379943848, + 7.137985706329346, + -3.392643928527832, + 6.779603004455566, + 3.166912794113159, + -2.3539297580718994, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3181.199999809265, + "ms": 0.5, + "values": [ + -9.634522438049316, + 8.960269927978516, + -3.459900379180908, + 5.597231864929199, + 2.514676809310913, + -2.198863983154297, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3224.699999809265, + "ms": 0.8000001907348633, + "values": [ + -9.50095272064209, + 5.922221660614014, + -3.109445571899414, + 4.799992561340332, + 1.9865044355392456, + -2.0310983657836914, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3259.2999997138977, + "ms": 1.1000003814697266, + "values": [ + -3.9623055458068848, + 4.691370487213135, + -2.2094802856445312, + 4.289284706115723, + 2.1679766178131104, + -1.3756368160247803, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3307.199999809265, + "ms": 0.5999999046325684, + "values": [ + 12.910332679748535, + 6.290950298309326, + 0.27942952513694763, + 1.404541254043579, + 1.701088547706604, + -0.65235835313797, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3341.2999997138977, + "ms": 1.3000001907348633, + "values": [ + 19.964008331298828, + 11.8035888671875, + 0.5527111887931824, + 1.0059030055999756, + 1.3617981672286987, + -0.973593533039093, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3390.4000000953674, + "ms": 0.6999998092651367, + "values": [ + 14.014010429382324, + 9.768118858337402, + -1.7779545783996582, + 0.41630178689956665, + 0.034823380410671234, + -1.461780071258545, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3428.199999809265, + "ms": 0.7000002861022949, + "values": [ + 9.628210067749023, + 7.371962070465088, + -3.443636417388916, + -0.3684406578540802, + -0.29581770300865173, + -1.4091408252716064, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3474.199999809265, + "ms": 1, + "values": [ + 5.443136215209961, + 4.849061489105225, + -5.078926086425781, + -0.8087950944900513, + -0.20426985621452332, + -1.2534153461456299, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3507.5999999046326, + "ms": 0.5, + "values": [ + 4.077988624572754, + 3.1420414447784424, + -5.5780744552612305, + -0.8647352457046509, + -0.2453169971704483, + -1.2186589241027832, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3545.0999999046326, + "ms": 0.6999998092651367, + "values": [ + 6.442591667175293, + 7.063014984130859, + -2.8647780418395996, + 1.0574564933776855, + -0.829940915107727, + -2.3037362098693848, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3590.699999809265, + "ms": 0.7000002861022949, + "values": [ + -4.903164863586426, + 7.048542499542236, + -1.6042747497558594, + 2.968357801437378, + -1.7466216087341309, + -3.13098406791687, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3622.9000000953674, + "ms": 0.5999999046325684, + "values": [ + -7.393880367279053, + 9.974995613098145, + -0.739132285118103, + 4.267623424530029, + -1.94276762008667, + -2.8457517623901367, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3658.5999999046326, + "ms": 1.1999998092651367, + "values": [ + -8.846354484558105, + 13.592846870422363, + -0.048818040639162064, + 5.239814758300781, + -1.489319086074829, + -2.146296501159668, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3707.4000000953674, + "ms": 0.39999961853027344, + "values": [ + -12.09565258026123, + 23.299943923950195, + -1.266870141029358, + 7.045947074890137, + -1.262683629989624, + -1.386162519454956, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3743.2999997138977, + "ms": 0.7000002861022949, + "values": [ + -21.244277954101562, + 29.565996170043945, + -3.814847469329834, + 6.883934497833252, + -0.8370362520217896, + -1.4822019338607788, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3786.0999999046326, + "ms": 1.1999998092651367, + "values": [ + -24.47845458984375, + 26.265674591064453, + -5.439520835876465, + 5.431215763092041, + -0.5037409067153931, + -0.9939021468162537, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3823, + "ms": 0.5, + "values": [ + -28.391162872314453, + 21.303306579589844, + -4.34710693359375, + 4.802043914794922, + 0.23179882764816284, + -0.915385365486145, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3862.699999809265, + "ms": 0.9000000953674316, + "values": [ + -33.8393669128418, + 18.169784545898438, + -1.1426388025283813, + 5.092304706573486, + 0.6931689381599426, + -0.6744562983512878, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3899.0999999046326, + "ms": 1.0999999046325684, + "values": [ + -23.655181884765625, + 11.496641159057617, + -0.6166239976882935, + 3.7022430896759033, + -0.09804487228393555, + -0.9372649192810059, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3942.5999999046326, + "ms": 0.8000001907348633, + "values": [ + -20.510770797729492, + 11.198214530944824, + -0.16836214065551758, + 4.231844425201416, + 0.2826947569847107, + -1.1535742282867432, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 3993.2999997138977, + "ms": 0.7000002861022949, + "values": [ + -19.425437927246094, + 11.385119438171387, + -2.0793027877807617, + 4.125753402709961, + 0.3929756283760071, + -0.6132134199142456, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4024.4000000953674, + "ms": 1.0999999046325684, + "values": [ + -23.042057037353516, + 12.371115684509277, + -2.2022016048431396, + 5.229942321777344, + 0.9276755452156067, + -0.7497968673706055, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4074.199999809265, + "ms": 1.3000001907348633, + "values": [ + -24.90914535522461, + 13.302112579345703, + -2.507147789001465, + 5.928067207336426, + 1.1331877708435059, + -0.5351829528808594, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4110.099999904633, + "ms": 1.0999999046325684, + "values": [ + -23.931570053100586, + 15.401019096374512, + -2.011467695236206, + 6.052706718444824, + 1.378749132156372, + -0.27933794260025024, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4144.400000095367, + "ms": 0.7999997138977051, + "values": [ + -26.586761474609375, + 16.747140884399414, + -2.1831867694854736, + 6.085460662841797, + 1.2325189113616943, + -0.29514944553375244, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4183.900000095367, + "ms": 0.6999998092651367, + "values": [ + -28.12339210510254, + 17.543560028076172, + -2.9592983722686768, + 4.474210262298584, + 1.1934521198272705, + -0.19009941816329956, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4231.299999713898, + "ms": 0.9000000953674316, + "values": [ + -26.96727752685547, + 15.296974182128906, + -2.91489839553833, + 4.368298530578613, + 0.5364521145820618, + -0.2417425513267517, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4272.5, + "ms": 1.299999713897705, + "values": [ + -23.311634063720703, + 12.86449146270752, + -1.5391215085983276, + 4.107986927032471, + 0.8505465388298035, + -0.4434660077095032, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4309.599999904633, + "ms": 0.8000001907348633, + "values": [ + -20.288925170898438, + 11.208775520324707, + 0.39712977409362793, + 3.8728830814361572, + 1.151885747909546, + -0.6861923336982727, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4350.5, + "ms": 1.1999998092651367, + "values": [ + -17.947450637817383, + 12.384154319763184, + 0.5006492137908936, + 3.8034565448760986, + 1.2674338817596436, + -1.021314263343811, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4384.900000095367, + "ms": 1.8999996185302734, + "values": [ + -18.618083953857422, + 13.012343406677246, + -0.3639099597930908, + 3.9480061531066895, + 1.1716687679290771, + -1.096616268157959, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4422.299999713898, + "ms": 0.7000002861022949, + "values": [ + -32.794979095458984, + 1.3232089281082153, + 7.821144104003906, + 6.393223762512207, + 3.1855270862579346, + -2.474717855453491, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4475.400000095367, + "ms": 0.8999996185302734, + "values": [ + -36.13392639160156, + -0.6111320853233337, + 6.935393333435059, + 6.498803615570068, + 3.547457695007324, + -2.535979747772217, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4510.699999809265, + "ms": 0.7000002861022949, + "values": [ + -37.26600646972656, + -1.2680084705352783, + 6.214326858520508, + 6.524359226226807, + 3.8266677856445312, + -2.2051358222961426, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4554.599999904633, + "ms": 0.8000001907348633, + "values": [ + -33.69902801513672, + -2.6829490661621094, + 5.905307769775391, + 5.002154350280762, + 3.8162360191345215, + -2.083198070526123, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4599, + "ms": 2.799999713897705, + "values": [ + -29.264366149902344, + -4.190082550048828, + 5.657395839691162, + 4.4468770027160645, + 3.80257511138916, + -2.278900623321533, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4643.299999713898, + "ms": 0.40000009536743164, + "values": [ + -23.251731872558594, + -5.812807083129883, + 6.252974510192871, + 3.4671072959899902, + 3.7577357292175293, + -1.994126558303833, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4683.299999713898, + "ms": 1, + "values": [ + -2.532999038696289, + -11.708344459533691, + 5.3431525230407715, + 0.06748497486114502, + 5.004839897155762, + -1.3342516422271729, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4723.900000095367, + "ms": 1.1999998092651367, + "values": [ + 9.715556144714355, + -7.412163734436035, + 4.281386375427246, + 0.6305595636367798, + 4.249697685241699, + -1.5728005170822144, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4766.5, + "ms": 0.6999998092651367, + "values": [ + 10.144518852233887, + -11.380349159240723, + 2.119192600250244, + 1.808896541595459, + 2.922896146774292, + -2.578998565673828, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4809.799999713898, + "ms": 1.1000003814697266, + "values": [ + 5.079522132873535, + -11.782465934753418, + 2.37961483001709, + 1.2137622833251953, + 2.300004720687866, + -2.892035961151123, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4845.599999904633, + "ms": 0.9000000953674316, + "values": [ + 5.985903739929199, + -9.2538480758667, + 2.1025760173797607, + 1.3130109310150146, + 2.1654951572418213, + -2.7800862789154053, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4879.400000095367, + "ms": 0.2999997138977051, + "values": [ + 9.979491233825684, + -8.401815414428711, + 1.6968975067138672, + 1.8904101848602295, + 2.21185040473938, + -2.209764242172241, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4917, + "ms": 1, + "values": [ + 13.997363090515137, + -10.401144981384277, + 1.6304033994674683, + 2.2998363971710205, + 2.5593206882476807, + -2.3942339420318604, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4955.599999904633, + "ms": 1.0999999046325684, + "values": [ + 18.01095199584961, + -8.279013633728027, + 1.3117586374282837, + 2.2433269023895264, + 2.880934476852417, + -2.1639881134033203, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 4992.400000095367, + "ms": 0.8999996185302734, + "values": [ + 17.253767013549805, + -5.037794589996338, + 1.6525548696517944, + 2.284512758255005, + 2.7369515895843506, + -2.1178057193756104, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5028.400000095367, + "ms": 1.1999998092651367, + "values": [ + 7.728093147277832, + -2.16225004196167, + 1.1885161399841309, + 2.8583920001983643, + 0.37814512848854065, + -2.254047155380249, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5067.799999713898, + "ms": 1.1000003814697266, + "values": [ + -4.829283714294434, + -1.2473454475402832, + 0.7092276811599731, + 2.607895612716675, + -0.2491319477558136, + -2.353444814682007, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5105.5, + "ms": 1.299999713897705, + "values": [ + -12.474334716796875, + -0.3819344639778137, + -0.7489814162254333, + 2.5401289463043213, + -0.385407030582428, + -1.6055357456207275, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5142.400000095367, + "ms": 0.8999996185302734, + "values": [ + -15.81019401550293, + -2.487074136734009, + -0.9927021861076355, + 1.4541860818862915, + -0.014217376708984375, + -1.1292036771774292, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5193.199999809265, + "ms": 0.5999999046325684, + "values": [ + -15.512857437133789, + -3.4052183628082275, + 0.4584061801433563, + 1.8073375225067139, + 0.39692914485931396, + -0.6007537245750427, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5223.5, + "ms": 0.7999997138977051, + "values": [ + -13.729034423828125, + -2.3748397827148438, + 3.7381861209869385, + 2.881505012512207, + 1.3527876138687134, + -0.49823153018951416, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5259.699999809265, + "ms": 1, + "values": [ + -32.34999465942383, + 0.7144597172737122, + 9.54293155670166, + 4.363951683044434, + 3.7934319972991943, + 0.6898875832557678, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5307.199999809265, + "ms": 1.3000001907348633, + "values": [ + -32.02696228027344, + 2.1820759773254395, + 8.004731178283691, + 4.289327144622803, + 3.509308338165283, + 0.1146603375673294, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5342, + "ms": 0.7999997138977051, + "values": [ + -31.380685806274414, + 0.613736093044281, + 5.234629154205322, + 4.073022842407227, + 3.0818300247192383, + -0.5021584033966064, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5391.599999904633, + "ms": 0.8000001907348633, + "values": [ + -30.482528686523438, + -0.3595082461833954, + 2.646430015563965, + 4.608903884887695, + 3.361715793609619, + -1.2319029569625854, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5429.799999713898, + "ms": 0.8000001907348633, + "values": [ + -29.572978973388672, + -4.177766799926758, + 0.5757055282592773, + 5.403255462646484, + 3.786638021469116, + -1.8924753665924072, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5466.199999809265, + "ms": 0.40000009536743164, + "values": [ + -29.217296600341797, + -9.124862670898438, + 0.7633762359619141, + 6.937750339508057, + 4.190334320068359, + -2.1841371059417725, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5498.599999904633, + "ms": 0.5, + "values": [ + -25.55074119567871, + -10.087533950805664, + 1.064046859741211, + 7.292147159576416, + 4.189195156097412, + -2.229198694229126, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5541.699999809265, + "ms": 0.7000002861022949, + "values": [ + -14.69289779663086, + -4.671184539794922, + 2.129159927368164, + 6.182745456695557, + 3.9232521057128906, + -2.0199759006500244, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5594.299999713898, + "ms": 0.7000002861022949, + "values": [ + 22.526065826416016, + 4.220155715942383, + -2.736884117126465, + 5.1000566482543945, + 2.9703571796417236, + -3.0771243572235107, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5630, + "ms": 1.0999999046325684, + "values": [ + 33.8766975402832, + 11.414834976196289, + -1.1404914855957031, + 3.9421374797821045, + 2.4092986583709717, + -2.0849738121032715, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5664, + "ms": 0.5, + "values": [ + 30.201824188232422, + 10.310654640197754, + -1.603166103363037, + 2.6484215259552, + 1.1958227157592773, + -2.191904306411743, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5709.900000095367, + "ms": 0.7999997138977051, + "values": [ + 21.6502628326416, + 6.700460433959961, + -1.6657506227493286, + 1.872132420539856, + -0.707599401473999, + -3.704667329788208, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5744.699999809265, + "ms": 0.40000009536743164, + "values": [ + 19.401988983154297, + 4.152242183685303, + -1.8333185911178589, + 1.7220494747161865, + -2.1209802627563477, + -4.462690353393555, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5793.299999713898, + "ms": 1, + "values": [ + 16.651905059814453, + 4.882608413696289, + -1.0686821937561035, + 2.016522169113159, + -3.0989322662353516, + -4.4683427810668945, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5825.599999904633, + "ms": 0.5, + "values": [ + 16.041854858398438, + 7.076114654541016, + -0.02063613012433052, + 2.4768893718719482, + -3.803551435470581, + -4.603030204772949, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5865.099999904633, + "ms": 0.8000001907348633, + "values": [ + 15.774680137634277, + 8.66187572479248, + 0.5024136304855347, + 2.536863327026367, + -4.307717323303223, + -4.8979597091674805, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5899.199999809265, + "ms": 0.8000001907348633, + "values": [ + 14.322529792785645, + 9.25537395477295, + 0.2596225142478943, + 1.8828108310699463, + -4.527651786804199, + -5.467596054077148, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5942.900000095367, + "ms": 0.6999998092651367, + "values": [ + 14.197481155395508, + 9.082780838012695, + -0.3510420620441437, + 1.5077717304229736, + -4.274723529815674, + -5.748845100402832, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 5996.400000095367, + "ms": 0.6999998092651367, + "values": [ + 14.206999778747559, + 9.535420417785645, + -0.8830007314682007, + 1.709773063659668, + -4.014988422393799, + -5.969700813293457, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6032, + "ms": 1.0999999046325684, + "values": [ + 13.390412330627441, + 8.560873031616211, + -1.2100167274475098, + 2.313275098800659, + -3.22416615486145, + -5.873724937438965, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6074.5, + "ms": 1.0999999046325684, + "values": [ + -0.48926329612731934, + 10.490918159484863, + 4.031308174133301, + 6.254397392272949, + -1.6811845302581787, + -5.031075477600098, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6112.400000095367, + "ms": 1.3999996185302734, + "values": [ + -16.122577667236328, + 14.347744941711426, + 8.899755477905273, + 8.026581764221191, + -1.1693336963653564, + -3.3943960666656494, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6153.099999904633, + "ms": 1.3000001907348633, + "values": [ + -30.643360137939453, + 11.773896217346191, + 12.0282564163208, + 8.289443016052246, + 0.6247557997703552, + -2.6216976642608643, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6200.900000095367, + "ms": 1.1999998092651367, + "values": [ + -50.81394577026367, + 10.841862678527832, + 13.479429244995117, + 7.89386510848999, + 2.3540303707122803, + -2.532292604446411, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6233.5, + "ms": 0.9000000953674316, + "values": [ + -53.52585983276367, + 9.706185340881348, + 10.2843599319458, + 6.505681991577148, + 3.2168326377868652, + -2.570312738418579, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6271.199999809265, + "ms": 1.3000001907348633, + "values": [ + -51.17578887939453, + 9.469877243041992, + 7.079144477844238, + 5.711472988128662, + 3.0256240367889404, + -2.6482763290405273, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6306.099999904633, + "ms": 0.5999999046325684, + "values": [ + -46.690773010253906, + 9.181392669677734, + 3.686859130859375, + 4.770251274108887, + 2.8277406692504883, + -2.5489449501037598, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6341.099999904633, + "ms": 0.5, + "values": [ + -43.412471771240234, + 8.898212432861328, + -0.20798969268798828, + 2.8823633193969727, + 2.5691771507263184, + -1.447481393814087, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6395.400000095367, + "ms": 0.7999997138977051, + "values": [ + -41.219303131103516, + 4.78723669052124, + -2.2208385467529297, + 0.9402635097503662, + 2.843503475189209, + -0.015484213829040527, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6430.900000095367, + "ms": 0.5999999046325684, + "values": [ + -36.88801574707031, + 2.58790922164917, + -1.2496113777160645, + 0.7863378524780273, + 3.7979815006256104, + 0.7914875745773315, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6470.900000095367, + "ms": 1.5999999046325684, + "values": [ + -26.096736907958984, + 4.4406280517578125, + 1.8131799697875977, + 1.4639220237731934, + 4.550527572631836, + 0.4538428783416748, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6503.900000095367, + "ms": 2.1999998092651367, + "values": [ + -21.15359878540039, + 5.970063209533691, + 3.5273325443267822, + 2.4317827224731445, + 4.492465019226074, + -0.4794601798057556, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6548.799999713898, + "ms": 0.9000000953674316, + "values": [ + 13.301284790039062, + 2.703555107116699, + -2.261461019515991, + -1.0068159103393555, + 4.491020679473877, + -0.06508427858352661, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6587.900000095367, + "ms": 2.0999999046325684, + "values": [ + 14.311988830566406, + 2.9267005920410156, + -2.603273868560791, + -1.1472563743591309, + 3.385662794113159, + -1.4873030185699463, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6629.299999713898, + "ms": 0.8000001907348633, + "values": [ + 12.488852500915527, + 2.7965354919433594, + -3.176602840423584, + -1.6720507144927979, + 2.4615724086761475, + -2.6770710945129395, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6673.599999904633, + "ms": 1.5, + "values": [ + 10.17236042022705, + 2.658870220184326, + -3.5764267444610596, + -1.6564418077468872, + 1.8611087799072266, + -3.0296804904937744, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6710.400000095367, + "ms": 0.6999998092651367, + "values": [ + 9.350656509399414, + 2.3263304233551025, + -3.804638385772705, + -1.5641255378723145, + 1.6752498149871826, + -3.0569839477539062, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6749.099999904633, + "ms": 0.5999999046325684, + "values": [ + 5.53863000869751, + 2.7958505153656006, + -2.8691916465759277, + 0.17205366492271423, + 1.0137183666229248, + -3.0442447662353516, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6787.299999713898, + "ms": 1.1000003814697266, + "values": [ + -6.623910903930664, + 5.4051127433776855, + 0.619429349899292, + 2.8198983669281006, + 0.931010365486145, + -3.496868371963501, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6834.699999809265, + "ms": 1.700000286102295, + "values": [ + -11.261462211608887, + 5.850034236907959, + 0.15462754666805267, + 2.3395283222198486, + 1.3023681640625, + -3.230984687805176, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6882.5, + "ms": 0.9000000953674316, + "values": [ + -16.069896697998047, + 6.795828819274902, + -0.8122683763504028, + 2.4503402709960938, + 2.1822588443756104, + -2.213819742202759, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6924.900000095367, + "ms": 1.3999996185302734, + "values": [ + -21.568504333496094, + 9.022791862487793, + 0.2524142563343048, + 2.815845489501953, + 2.729161262512207, + -1.7453298568725586, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 6969.299999713898, + "ms": 2.9000000953674316, + "values": [ + -27.275508880615234, + 7.671746253967285, + 2.8259925842285156, + 3.799891948699951, + 2.9229226112365723, + -1.5866756439208984, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7026.599999904633, + "ms": 1.1999998092651367, + "values": [ + -26.085681915283203, + 5.710488319396973, + 3.5771851539611816, + 4.233034610748291, + 2.922788619995117, + -1.7668914794921875, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7078.900000095367, + "ms": 1.3999996185302734, + "values": [ + -18.203697204589844, + 4.225621223449707, + 2.7816672325134277, + 3.50612735748291, + 3.064764976501465, + -2.164121627807617, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7123, + "ms": 1.0999999046325684, + "values": [ + -11.56640338897705, + 2.918555974960327, + 5.231761932373047, + 2.4849956035614014, + 6.86042594909668, + -1.0052794218063354, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7162.699999809265, + "ms": 0.8000001907348633, + "values": [ + -12.261153221130371, + 3.0063891410827637, + 6.828045845031738, + 4.264076232910156, + 7.544426918029785, + -1.712418794631958, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7199, + "ms": 0.5999999046325684, + "values": [ + -25.178098678588867, + -1.9341604709625244, + 9.063502311706543, + 7.0695672035217285, + 8.265101432800293, + -1.9155681133270264, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7233, + "ms": 0.6999998092651367, + "values": [ + -35.720703125, + 0.17395518720149994, + 10.40718936920166, + 7.841708660125732, + 8.059473991394043, + -1.3073970079421997, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7268.900000095367, + "ms": 2.0999999046325684, + "values": [ + -36.561988830566406, + 0.7507902383804321, + 8.527780532836914, + 6.853759765625, + 7.6085591316223145, + -1.1363749504089355, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7306.599999904633, + "ms": 0.8000001907348633, + "values": [ + -35.56404495239258, + 0.8950953483581543, + 5.622134208679199, + 6.211966514587402, + 6.460933685302734, + -1.5645546913146973, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7340.699999809265, + "ms": 0.40000009536743164, + "values": [ + -35.96611785888672, + 2.284970760345459, + 3.2008447647094727, + 4.924874305725098, + 5.764821529388428, + -1.0052855014801025, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7391.900000095367, + "ms": 0.7999997138977051, + "values": [ + -26.345359802246094, + 3.3656814098358154, + 1.975954294204712, + 3.9768564701080322, + 5.871219158172607, + -1.0167782306671143, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7424, + "ms": 0.5999999046325684, + "values": [ + -15.567323684692383, + 3.6650025844573975, + 3.4099955558776855, + 3.7795042991638184, + 5.8175201416015625, + -1.3081351518630981, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7477.5, + "ms": 0.5999999046325684, + "values": [ + 6.227669715881348, + 2.602263927459717, + 0.05360419675707817, + 0.03537294641137123, + 3.8088834285736084, + -2.4097392559051514, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7514, + "ms": 0.7999997138977051, + "values": [ + -2.5800111293792725, + -3.4828941822052, + 2.1235923767089844, + -0.40175768733024597, + 2.594738483428955, + -2.9930779933929443, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7555.400000095367, + "ms": 1.299999713897705, + "values": [ + -8.05845832824707, + -1.5781877040863037, + 2.8810386657714844, + 0.30352166295051575, + 0.966284990310669, + -3.6551454067230225, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7596.400000095367, + "ms": 0.8999996185302734, + "values": [ + -3.0487537384033203, + 5.030720233917236, + 2.733035087585449, + 0.3929472267627716, + 0.05088409036397934, + -3.5839571952819824, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7633.900000095367, + "ms": 0.5999999046325684, + "values": [ + -3.2401862144470215, + 12.952961921691895, + 0.18846099078655243, + 2.3167874813079834, + -0.20446380972862244, + -3.8215835094451904, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7676.299999713898, + "ms": 0.7000002861022949, + "values": [ + -10.434473991394043, + 10.73208999633789, + 2.6335256099700928, + 3.4308955669403076, + 1.8278000354766846, + -3.3644731044769287, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7711.199999809265, + "ms": 0.9000000953674316, + "values": [ + -24.049392700195312, + 6.7465362548828125, + 3.974799633026123, + 4.387029647827148, + 2.9598636627197266, + -3.3965845108032227, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7746.900000095367, + "ms": 0.5999999046325684, + "values": [ + -31.94753646850586, + 6.49761962890625, + 5.409801959991455, + 5.778480529785156, + 3.258812427520752, + -3.164924144744873, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7792.099999904633, + "ms": 0.8000001907348633, + "values": [ + -35.903385162353516, + 6.006303787231445, + 6.925891399383545, + 3.976205348968506, + 2.8209524154663086, + -2.4734482765197754, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7825, + "ms": 0.5, + "values": [ + -8.976631164550781, + 14.625836372375488, + 4.330262660980225, + 1.2694565057754517, + 2.3481078147888184, + -2.2930281162261963, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7862.400000095367, + "ms": 0.7999997138977051, + "values": [ + -5.021747589111328, + 11.664031982421875, + 0.7236764430999756, + 0.00918799638748169, + 2.241964817047119, + -2.0537679195404053, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7911.099999904633, + "ms": 0.8000001907348633, + "values": [ + -11.272377014160156, + 5.8942999839782715, + -4.800360679626465, + -1.1349267959594727, + 2.4841551780700684, + -1.2838903665542603, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7946.299999713898, + "ms": 0.7000002861022949, + "values": [ + -13.440125465393066, + 2.7492756843566895, + -4.558774948120117, + -0.633268415927887, + 2.7986323833465576, + -0.5638381838798523, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 7993.699999809265, + "ms": 0.7000002861022949, + "values": [ + -10.503755569458008, + 4.603376388549805, + -2.0019748210906982, + -0.22866421937942505, + 3.5621016025543213, + 0.49787843227386475, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8029.799999713898, + "ms": 0.7000002861022949, + "values": [ + -10.51417350769043, + 7.961134910583496, + 2.8445518016815186, + 1.302581787109375, + 4.370325088500977, + 0.014503002166748047, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8065.400000095367, + "ms": 1, + "values": [ + -7.25847053527832, + 3.562786102294922, + 0.006754636764526367, + 1.1200505495071411, + 4.251446723937988, + -0.15052688121795654, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8113.5, + "ms": 0.7999997138977051, + "values": [ + -4.730093479156494, + 2.698568344116211, + 2.3032174110412598, + 1.659325361251831, + 3.984747886657715, + -0.811644971370697, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8156.199999809265, + "ms": 1.3000001907348633, + "values": [ + 3.9011385440826416, + -9.708113670349121, + 3.2331247329711914, + 1.7279119491577148, + 5.819105625152588, + -0.1557999849319458, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8195.5, + "ms": 0.7999997138977051, + "values": [ + 5.213095664978027, + -12.774744987487793, + 5.81633186340332, + 1.1541721820831299, + 5.583709239959717, + -0.16394975781440735, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8228.900000095367, + "ms": 0.6999998092651367, + "values": [ + -0.8084649443626404, + -13.762500762939453, + 6.954435348510742, + 0.8522472381591797, + 4.483011722564697, + -0.1796126365661621, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8260.799999713898, + "ms": 0.7000002861022949, + "values": [ + -6.7794508934021, + -13.12187385559082, + 7.649224281311035, + 0.811181902885437, + 3.3757476806640625, + -0.32386916875839233, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8308.400000095367, + "ms": 0.6999998092651367, + "values": [ + -6.390361785888672, + -12.021974563598633, + 6.178391456604004, + 0.9637323617935181, + 3.031646251678467, + -0.4584554135799408, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8342.699999809265, + "ms": 0.5999999046325684, + "values": [ + -10.268893241882324, + -9.638364791870117, + 4.603377342224121, + 1.9148292541503906, + 2.6018712520599365, + -0.6035040616989136, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8391.699999809265, + "ms": 0.7000002861022949, + "values": [ + -15.76949691772461, + -7.8211517333984375, + 1.6720085144042969, + 1.8153364658355713, + 2.3766541481018066, + -0.2036055326461792, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8424.599999904633, + "ms": 1, + "values": [ + -14.34726619720459, + -4.240779876708984, + 0.2548942565917969, + 0.7548326849937439, + 2.2324540615081787, + 0.743243932723999, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8462.199999809265, + "ms": 0.8000001907348633, + "values": [ + -4.440877914428711, + -4.056642532348633, + 1.0771594047546387, + 0.8087905645370483, + 2.223642110824585, + 0.19133898615837097, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8508.199999809265, + "ms": 0.8000001907348633, + "values": [ + 2.057441234588623, + 1.6846425533294678, + -0.4061950743198395, + 1.0504474639892578, + 1.4215338230133057, + -0.3168410658836365, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8542.099999904633, + "ms": 1.1999998092651367, + "values": [ + -2.2450664043426514, + -4.701574802398682, + 1.578120470046997, + -0.22732067108154297, + 0.49939271807670593, + -2.135554790496826, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8592.199999809265, + "ms": 1.3000001907348633, + "values": [ + -0.7099403738975525, + -2.9188263416290283, + 2.845872402191162, + -0.3758317530155182, + -0.9867148399353027, + -2.43542218208313, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8630.699999809265, + "ms": 0.8000001907348633, + "values": [ + 11.428804397583008, + 7.174230098724365, + 3.0946803092956543, + -0.5866274237632751, + -2.255856513977051, + -2.4723105430603027, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8671.699999809265, + "ms": 1, + "values": [ + 17.057437896728516, + 15.102141380310059, + 1.7119390964508057, + 0.35698190331459045, + -2.7073137760162354, + -2.1635875701904297, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8710.900000095367, + "ms": 1.3999996185302734, + "values": [ + 12.595614433288574, + 13.50704574584961, + -0.6105338335037231, + -0.15174786746501923, + -3.040919065475464, + -2.220855951309204, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8748.699999809265, + "ms": 0.5, + "values": [ + 7.8760085105896, + 10.571850776672363, + -2.576935291290283, + -0.8030305504798889, + -2.9313552379608154, + -2.1803250312805176, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8790.5, + "ms": 1.5999999046325684, + "values": [ + 5.348376274108887, + 8.901150703430176, + -3.9661340713500977, + -0.7458317875862122, + -2.5256431102752686, + -2.0001959800720215, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8827.900000095367, + "ms": 1.1999998092651367, + "values": [ + 3.7819552421569824, + 6.938417911529541, + -4.904252529144287, + -0.7253883481025696, + -2.206754207611084, + -1.9103690385818481, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8868.799999713898, + "ms": 2.1000003814697266, + "values": [ + 2.661128282546997, + 5.457953929901123, + -5.540745735168457, + -0.594207763671875, + -1.9598013162612915, + -1.9195917844772339, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8907.699999809265, + "ms": 0.5, + "values": [ + 1.6261272430419922, + 4.339597702026367, + -5.853689193725586, + -0.46712350845336914, + -1.750910997390747, + -2.01916241645813, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8945, + "ms": 1, + "values": [ + 0.4950075149536133, + 3.334221601486206, + -5.999077320098877, + -0.40602734684944153, + -1.51939857006073, + -2.1653947830200195, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 8983, + "ms": 0.5, + "values": [ + -0.5043578147888184, + 2.638533115386963, + -6.045931339263916, + -0.413872092962265, + -1.3294521570205688, + -2.3049373626708984, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9027, + "ms": 0.7999997138977051, + "values": [ + -1.346761703491211, + 2.221341609954834, + -6.013335227966309, + -0.4503161609172821, + -1.2013479471206665, + -2.4583144187927246, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9062, + "ms": 1, + "values": [ + -1.9936232566833496, + 1.9005427360534668, + -5.974276542663574, + -0.5047236084938049, + -1.0782053470611572, + -2.606442451477051, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9109.5, + "ms": 0.7999997138977051, + "values": [ + -2.4918665885925293, + 1.6391100883483887, + -5.930579662322998, + -0.5639653205871582, + -0.9475992918014526, + -2.730454444885254, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9149.5, + "ms": 0.7999997138977051, + "values": [ + -2.8550925254821777, + 1.4134511947631836, + -5.878252029418945, + -0.6353188157081604, + -0.8180866241455078, + -2.8438212871551514, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9201.900000095367, + "ms": 1.299999713897705, + "values": [ + -3.0997300148010254, + 1.2344260215759277, + -5.817983627319336, + -0.6971996426582336, + -0.694791316986084, + -2.9392642974853516, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "t": 9240.299999713898, + "ms": 0.8000001907348633, + "values": [ + -3.230106830596924, + 1.0968451499938965, + -5.762261390686035, + -0.764464795589447, + -0.5845882892608643, + -3.032961368560791, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + ], + "start": 3867.5999999046326, + "events": [ + { + "type": "setAudio", + "t": 442, + "n": 264270 + } + ], + "capture": { + "status": "done", + "elapsed": 8.565299999713897, + "url": "blob:http://1.14.103.234:8123/c8d8e7ca-0931-49ed-a7eb-68a210e5a145" + }, + "errors": [], + "summary": { + "frameCount": 217, + "elapsedMs": 8693.099999904633, + "fps": 24.962326443084816, + "maxBlend": 53.52585983276367, + "nonZeroFrames": 217 + } +} \ No newline at end of file diff --git a/reports/bridge-lipsync-diagnosis-20260914/sample.wav b/reports/bridge-lipsync-diagnosis-20260914/sample.wav new file mode 100644 index 0000000..64accea Binary files /dev/null and b/reports/bridge-lipsync-diagnosis-20260914/sample.wav differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-005-original.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-005-original.png new file mode 100644 index 0000000..94ff39e Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-005-original.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-diagnostic.json b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-diagnostic.json new file mode 100644 index 0000000..c0f2c62 --- /dev/null +++ b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-diagnostic.json @@ -0,0 +1,1451 @@ +{ + "mounted": true, + "hasEnvironment": true, + "hasEnvironmentTarget": true, + "toneMappingExposure": 1.05, + "background": "a8cbe1", + "meshCount": 75, + "materials": [ + { + "name": "M_3dfreehub_mat_2", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_3", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_4", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_5", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__85", + "color": "695c5b", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "BaiSe", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Cai1", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "HeiSe", + "color": "4f4f4f", + "metalness": 0.3, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "JinShu", + "color": "929292", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LanSe", + "color": "3b76d0", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LvSe", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_black", + "color": "322e2e", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_01", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_02", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1676", + "color": "d96e6e", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "MoShaJinShu", + "color": "cbcbcb", + "metalness": 0.8, + "roughness": 0.35, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "__", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__579", + "color": "404040", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1673", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "QianlvSe2", + "color": "749f62", + "metalness": 0, + "roughness": 0.6, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "WaiQiang", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "254b50", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "a6b9c3", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "4d95b6", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "a6b9c3", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "4d95b6", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a149", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "4d95b6", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a149", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "4d95b6", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "34474b", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "34474b", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "dd4545", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + } + ], + "server": { + "stepId": "BRIDGE-STEP-1", + "completed": [], + "registeredTargets": [ + "scene:front-pump-rescue-vehicle", + "front-pump-hydraulic-pump", + "front-pump-power-take-off", + "front-pump-pto-switch", + "front-pump-ball-valve-switch", + "front-pump-aux-control-box", + "front-pump-aux-control-box-cover", + "front-pump-rescue-switch", + "bridge-engine", + "bridge-port-a", + "bridge-port-b", + "bridge-hose-a", + "bridge-hose-b", + "bridge-hose-line", + "bridge-return-line", + "bridge-return-valve", + "bridge-support-pto", + "bridge-supply", + "bridge-normal-control" + ], + "readOnly": false, + "animations": [ + { + "modelId": "front-pump-field-terrain", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + }, + { + "modelId": "front-pump-step-vehicle", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + } + ] + }, + "bridgeWorkshop": { + "modelBinding": null, + "pending": false, + "operation": { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "保持架桥车发动机运行", + "effects": [ + { + "targetId": "bridge-engine", + "color": 2209160 + } + ], + "index": 0, + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 0, + "toleranceDegrees": 6 + }, + "operationIndex": 0, + "targets": [ + { + "id": "front-pump-hydraulic-pump", + "visible": true, + "position": [ + 0, + 0, + 0 + ], + "scale": [ + 0.01, + 0.01, + 0.01 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 0, + 0 + ], + "homeScale": [ + 0.01, + 0.01, + 0.01 + ], + "worldBounds": { + "min": [ + -0.1828516818917321, + 0.5470110749761624, + 1.5480637042583223 + ], + "max": [ + -0.07350143670700486, + 0.6823860012265373, + 1.7452996392749651 + ] + }, + "sourceNode": "1液压泵" + }, + { + "id": "bridge-engine", + "visible": true, + "position": [ + -3, + 1.1, + 1.2 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -3, + 1.1, + 1.2 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -3.1744597940157613, + 0.9977008716087504, + 6.0763115451708565 + ], + "max": [ + -2.824339676310247, + 1.2881462221520208, + 6.831686504293038 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-port-a", + "visible": true, + "position": [ + -1.8, + 1.1, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.8, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.979688718853388, + 0.5786910329922862, + 5.026213141470239 + ], + "max": [ + -1.6193012164038165, + 1.2892821195627557, + 5.3766873800293284 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-port-b", + "visible": true, + "position": [ + 1.8, + 1.1, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.8, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.6203107451633934, + 0.5767265795792963, + 5.0262118470612736 + ], + "max": [ + 1.9806982476129649, + 1.2873176661497658, + 5.376686085620363 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-hose-a", + "visible": true, + "position": [ + -1.8, + 1.1, + 0.85 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.8, + 1.1, + 0.85 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.9396671966128642, + 0.6175926702022128, + 5.9258038439221545 + ], + "max": [ + -1.65932336787092, + 1.2480742789892327, + 6.176633960727525 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-hose-b", + "visible": true, + "position": [ + 1.8, + 1.1, + 0.85 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.8, + 1.1, + 0.85 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.6603322674039172, + 0.6156282167892229, + 5.925802549513189 + ], + "max": [ + 1.9406760961458613, + 1.2461098255762428, + 6.176632666318559 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-hose-line", + "visible": false, + "position": [ + -1.8, + 1.1, + 0.2 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.8, + 1.1, + 0.2 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.8427780460984118, + 0.7489938128273822, + 5.357804753531997 + ], + "max": [ + 1.8438155965345846, + 1.1673566580929169, + 6.409232122960655 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-return-line", + "visible": false, + "position": [ + -1.8, + 0.75, + 0.2 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.8, + 0.75, + 0.2 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.8471076810901101, + 0.6947915760640372, + 5.36926182739268 + ], + "max": [ + 1.8479254921067865, + 0.8187577960750975, + 6.8491772563030295 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-return-valve", + "visible": true, + "position": [ + 2.7, + 1.1, + 0.1 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 2.7, + 1.1, + 0.1 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 2.5255397528579935, + 0.9960401005834839, + 4.976310450862948 + ], + "max": [ + 2.8756598705635077, + 1.2864854511267543, + 5.731685409985129 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-support-pto", + "visible": true, + "position": [ + 2.7, + 1.1, + 1.1 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 2.7, + 1.1, + 1.1 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 2.5255393932999475, + 0.9947222700877559, + 5.976309582523898 + ], + "max": [ + 2.8756595110054617, + 1.2851676206310263, + 6.7316845416460795 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-supply", + "visible": true, + "position": [ + 0, + 1, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.1745143773491488, + 0.897645325415127, + 4.876179725454005 + ], + "max": [ + 0.17560574035636536, + 1.1880906759583973, + 5.631554684576186 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-normal-control", + "visible": true, + "position": [ + -2.7, + 1.1, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.7, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -2.8744594072113743, + 0.9991185637525416, + 4.876312479310302 + ], + "max": [ + -2.52433928950586, + 1.289563914295812, + 5.6316874384324835 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + } + ] + }, + "bridgeGrounding": [ + { + "id": "front-pump-rescue-vehicle", + "adjustment": -2.6725065689598313e-9, + "contacts": 22, + "minGap": 0, + "maxGap": 0.01902815385345835, + "position": [ + 0, + -2.6725065689598313e-9, + 0 + ], + "quaternion": [ + 1.5432791624149142e-17, + 0, + -1.284056869900529e-16, + 1 + ] + }, + { + "id": "bridge-workshop", + "adjustment": 0.007972344742127626, + "contacts": 16, + "minGap": 0, + "maxGap": 0.007419605491776459, + "position": [ + 0, + 0.007972344742127626, + 5.2 + ], + "quaternion": [ + 0.0006589154154300379, + 0, + -0.00027284082118916614, + 0.9999997456941484 + ] + } + ], + "publishedContentMounted": true, + "publishedContentName": "重型支援桥液压泵应急替代", + "publishedTrainingContent": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "objectCount": 2 + }, + "proceduralMachineVisible": false, + "publishedModelRootCount": 2, + "framing": { + "cameraPosition": [ + -4.08, + 7.56, + 17.74 + ], + "controlsTarget": [ + -4.08, + 1.31, + 6.36 + ], + "distance": 12.98, + "minDistance": 0.25, + "maxDistance": 800, + "fov": 45, + "near": 0.1, + "far": 800, + "fogNear": 70, + "fogFar": 240, + "modelSize": [ + 140, + 28.34, + 116.19 + ], + "modelCenter": [ + -8.4, + 7.33, + -34.86 + ], + "stepCameraPolicy": "focus", + "explosionItemCount": 36, + "structureNodeCount": 44, + "enablePan": true, + "outlineActive": false, + "labelsVisible": false, + "hideOthers": false, + "hiddenMeshCount": 0, + "keptTargets": [], + "targetOnScreen": { + "targetId": "bridge-engine", + "localX": 628, + "localY": 395, + "insideCanvas": true, + "visible": true, + "coveredBy": [] + }, + "keptOpacity": [], + "environmentAlignment": { + "pickedAt": [ + 8.4, + -10.31, + 34.86 + ], + "localRelief": 0.265, + "samples": 115, + "workArea": { + "changedVertices": 1354, + "floorY": 0, + "bounds": [ + -5, + 5, + -6, + 8 + ] + } + }, + "sceneObjects": [ + { + "name": "野外山地训练场", + "min": [ + -78.4, + -6.84, + -92.96 + ], + "max": [ + 61.6, + 21.5, + 23.24 + ] + }, + { + "name": "架桥车前泵互救操作整车模型", + "min": [ + -0.92, + 0, + -4 + ], + "max": [ + 0.92, + 1.97, + 4 + ] + }, + { + "name": "补充操作示意 · 非实车尺寸", + "min": [ + -3.6, + 0, + 4.4 + ], + "max": [ + 3.6, + 3.06, + 7 + ] + } + ], + "labelSamples": [ + { + "targetId": "scene:front-pump-rescue-vehicle", + "targetName": "", + "partName": "架桥车前泵互救操作整车模型" + }, + { + "targetId": "front-pump-hydraulic-pump", + "targetName": "", + "partName": "液压泵" + }, + { + "targetId": "front-pump-power-take-off", + "targetName": "", + "partName": "取力器" + }, + { + "targetId": "front-pump-pto-switch", + "targetName": "", + "partName": "取力器开关" + } + ] + } +} \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-start.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-start.png new file mode 100644 index 0000000..4b04e60 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-start.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-2.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-2.png new file mode 100644 index 0000000..e750e54 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-2.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-4.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-4.png new file mode 100644 index 0000000..6f06f24 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-4.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-5.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-5.png new file mode 100644 index 0000000..0b1374b Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-006-step-5.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-context.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-context.png new file mode 100644 index 0000000..843bd05 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-context.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-diagnostic.json b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-diagnostic.json new file mode 100644 index 0000000..a9855f1 --- /dev/null +++ b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-diagnostic.json @@ -0,0 +1,2219 @@ +{ + "mounted": true, + "hasEnvironment": true, + "hasEnvironmentTarget": true, + "toneMappingExposure": 1.05, + "background": "a8cbe1", + "meshCount": 82, + "materials": [ + { + "name": "M_3dfreehub_mat_2", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_3", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_4", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_5", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__85", + "color": "695c5b", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "BaiSe", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Cai1", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "HeiSe", + "color": "4f4f4f", + "metalness": 0.3, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "JinShu", + "color": "929292", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LanSe", + "color": "3b76d0", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LvSe", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_black", + "color": "322e2e", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_01", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_02", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1676", + "color": "d96e6e", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "MoShaJinShu", + "color": "cbcbcb", + "metalness": 0.8, + "roughness": 0.35, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "__", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__579", + "color": "404040", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1673", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "QianlvSe2", + "color": "749f62", + "metalness": 0, + "roughness": 0.6, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "WaiQiang", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "627980", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a543", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "b89455", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "b89455", + "metalness": 0, + "roughness": 1, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "465963", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "465963", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d1eaf1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d1eaf1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ddab4a", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d5a945", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "e4b243", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + } + ], + "server": { + "stepId": "BRIDGE-STEP-1", + "completed": [], + "registeredTargets": [ + "scene:front-pump-rescue-vehicle", + "front-pump-hydraulic-pump", + "front-pump-power-take-off", + "front-pump-pto-switch", + "front-pump-ball-valve-switch", + "front-pump-aux-control-box", + "front-pump-aux-control-box-cover", + "front-pump-rescue-switch", + "bridge-engine", + "bridge-old-pump", + "bridge-new-pump", + "bridge-pump-seat", + "bridge-pump-bolt-1", + "bridge-pump-bolt-2", + "bridge-pump-bolt-3", + "bridge-pump-bolt-4", + "bridge-tank-valve", + "bridge-paper", + "bridge-gasket", + "bridge-inlet", + "bridge-outlet", + "bridge-inlet-bag", + "bridge-outlet-bag", + "bridge-fill-cap", + "bridge-oil-can", + "bridge-oil-stream", + "bridge-test-control" + ], + "readOnly": false, + "animations": [ + { + "modelId": "front-pump-field-terrain", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + }, + { + "modelId": "front-pump-step-vehicle", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + } + ] + }, + "bridgeWorkshop": { + "modelBinding": { + "sourceNode": "1液压泵", + "boltSource": "关键螺丝", + "boltCount": 4, + "sourceBounds": { + "min": [ + -0.1828516818917321, + 0.5470110749761624, + 1.5480637042583223 + ], + "max": [ + -0.07350143670700486, + 0.6823860012265373, + 1.7452996392749651 + ] + }, + "scale": 0.17930539546967528, + "mountedOnVehicle": true + }, + "pending": false, + "operation": { + "targetId": "bridge-engine", + "kind": "identify", + "directionHint": "关闭架桥车发动机", + "effects": [ + { + "targetId": "bridge-engine", + "color": 13195851 + } + ], + "index": 0, + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 0, + "toleranceDegrees": 6 + }, + "operationIndex": 0, + "targets": [ + { + "id": "front-pump-hydraulic-pump", + "visible": false, + "position": [ + 0, + 0, + 0 + ], + "scale": [ + 0.01, + 0.01, + 0.01 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 0, + 0 + ], + "homeScale": [ + 0.01, + 0.01, + 0.01 + ], + "worldBounds": { + "min": [ + -0.1828516818917321, + 0.5470110749761624, + 1.5480637042583223 + ], + "max": [ + -0.07350143670700486, + 0.6823860012265373, + 1.7452996392749651 + ] + }, + "sourceNode": "1液压泵" + }, + { + "id": "bridge-engine", + "visible": true, + "position": [ + -3, + 1.1, + 1.2 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -3, + 1.1, + 1.2 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6974711893812158, + 0.5411833260656574, + 1.8035738949400966 + ], + "max": [ + -0.6347143020355728, + 0.5931818905247553, + 1.9389494663822144 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-old-pump", + "visible": true, + "position": [ + 0, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18285168890500836, + 0.5470110777057942, + 1.5480637555580075 + ], + "max": [ + -0.07350144038116299, + 0.682385982465754, + 1.745299694849624 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-new-pump", + "visible": true, + "position": [ + 2, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 2, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.1757591020343422, + 0.5470110777057942, + 1.5480637555580075 + ], + "max": [ + 0.2851093505581876, + 0.682385982465754, + 1.745299694849624 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-pump-seat", + "visible": true, + "position": [ + 0, + 1.4, + 0.62 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 1.4, + 0.62 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18555428456717243, + 0.5698721892339311, + 1.7524718552139857 + ], + "max": [ + -0.0707988340315645, + 0.6595248869687687, + 1.7632301787016988 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-pump-bolt-1", + "visible": true, + "position": [ + -0.22726086527109146, + 1.4364657248137518, + 0.5203916877508163 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -0.22726086527109146, + 1.4364657248137518, + 0.5203916877508163 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18129260597425773, + 0.6088700919574924, + 1.7276237617852601 + ], + "max": [ + -0.15655871126890647, + 0.6336039866628437, + 1.7523576564906111 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-pump-bolt-2", + "visible": true, + "position": [ + 0.22531712800264359, + 1.4364657248137518, + 0.5203923434019089 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.22531712800264359, + 1.4364657248137518, + 0.5203923434019089 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.10014292990943864, + 0.6088700919574924, + 1.7276238793470384 + ], + "max": [ + -0.07540903520408739, + 0.6336039866628437, + 1.7523577740523895 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-pump-bolt-3", + "visible": true, + "position": [ + -0.22726086527109146, + 1.1014159262180327, + 0.5203910171985626 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -0.22726086527109146, + 1.1014159262180327, + 0.5203910171985626 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18129260998204563, + 0.548793851310464, + 1.727623637543835 + ], + "max": [ + -0.15655870726111856, + 0.573527754031391, + 1.7523575402647622 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-pump-bolt-4", + "visible": true, + "position": [ + 0.22531712800264359, + 1.1014159262180327, + 0.5203916877508163 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.22531712800264359, + 1.1014159262180327, + 0.5203916877508163 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.10014292990943864, + 0.5487938553182519, + 1.7276237617852601 + ], + "max": [ + -0.07540903520408739, + 0.5735277500236031, + 1.7523576564906111 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-tank-valve", + "visible": true, + "position": [ + -2.7, + 1.1, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.7, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6436795707403132, + 0.5411833260656574, + 1.5884074203764862 + ], + "max": [ + -0.5809226833946702, + 0.5931818905247553, + 1.723782991818604 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-paper", + "visible": true, + "position": [ + -2.3, + 0.8, + 0.4 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.3, + 0.8, + 0.4 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6212663947034885, + 0.5048739833427757, + 1.637716404130647 + ], + "max": [ + -0.4598915430557545, + 0.509356618296314, + 1.799091255778381 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-gasket", + "visible": false, + "position": [ + -2.3, + 1.4, + -0.75 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.3, + 1.4, + -0.75 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6158872326256496, + 0.5393902743553218, + 1.5122026251643872 + ], + "max": [ + -0.4652707051335935, + 0.690006801847378, + 1.5122026251643872 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-inlet", + "visible": true, + "position": [ + -0.65, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -0.65, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.35295371138761605, + 0.5363196942955012, + 1.6334456796932533 + ], + "max": [ + -0.24472401430169025, + 0.6288944167519539, + 1.7004538734767225 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-outlet", + "visible": true, + "position": [ + 0.65, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.65, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.011629104297046704, + 0.5363196942955012, + 1.6334456796932533 + ], + "max": [ + 0.09660059278887913, + 0.6288944167519539, + 1.7004538734767225 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-inlet-bag", + "visible": true, + "position": [ + -1.25, + 1.4, + 0.65 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.25, + 1.4, + 0.65 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.37741105910909145, + 0.5833200944285284, + 1.7417135318465062 + ], + "max": [ + -0.32720554816383374, + 0.6460769817741714, + 1.784746825797359 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-outlet-bag", + "visible": true, + "position": [ + 1.25, + 1.4, + 0.65 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.25, + 1.4, + 0.65 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.07085242956509674, + 0.5833200944285284, + 1.7417135318465062 + ], + "max": [ + 0.12105794051035451, + 0.6460769817741714, + 1.784746825797359 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-fill-cap", + "visible": true, + "position": [ + 0, + 2, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 2, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.15148625985543152, + 0.698972074827092, + 1.637716401859567 + ], + "max": [ + -0.10486685874330544, + 0.7455914759392182, + 1.6556469416737205 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-oil-can", + "visible": true, + "position": [ + 1.4, + 1.8, + 0.5 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.4, + 1.8, + 0.5 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.09147255068535545, + 0.6415943474218013, + 1.7094385591122865 + ], + "max": [ + 0.15422943803099834, + 0.7312470451566389, + 1.763230179890676 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-oil-stream", + "visible": false, + "position": [ + 0.1, + 2.1, + 0.15 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.1, + 2.1, + 0.15 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.13835291417702386, + 0.6891968621123294, + 1.6373530580795213 + ], + "max": [ + -0.10006966447396676, + 0.746401420884391, + 1.6829060957093678 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-test-control", + "visible": true, + "position": [ + 3, + 1.1, + 1 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 3, + 1.1, + 1 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.37836118343683595, + 0.5411833260656574, + 1.7677128158461615 + ], + "max": [ + 0.44111807078247883, + 0.5931818905247553, + 1.9030883872882793 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + } + ] + }, + "bridgeGrounding": [ + { + "id": "front-pump-rescue-vehicle", + "adjustment": -2.6725065689598313e-9, + "contacts": 22, + "minGap": 0, + "maxGap": 0.01902815385345835, + "position": [ + 0, + -2.6725065689598313e-9, + 0 + ], + "quaternion": [ + 1.5432791624149142e-17, + 0, + -1.284056869900529e-16, + 1 + ] + } + ], + "publishedContentMounted": true, + "publishedContentName": "重型支援桥前泵换件修复", + "publishedTrainingContent": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "objectCount": 2 + }, + "proceduralMachineVisible": false, + "publishedModelRootCount": 2, + "framing": { + "cameraPosition": [ + -0.13, + 1.56, + 3.58 + ], + "controlsTarget": [ + -0.13, + 0.57, + 1.76 + ], + "distance": 2.07, + "minDistance": 0.25, + "maxDistance": 800, + "fov": 45, + "near": 0.1, + "far": 800, + "fogNear": 70, + "fogFar": 240, + "modelSize": [ + 140, + 28.34, + 116.19 + ], + "modelCenter": [ + -8.4, + 7.33, + -34.86 + ], + "stepCameraPolicy": "focus", + "explosionItemCount": 36, + "structureNodeCount": 44, + "enablePan": true, + "outlineActive": false, + "labelsVisible": false, + "hideOthers": false, + "hiddenMeshCount": 0, + "keptTargets": [ + "bridge-engine", + "bridge-old-pump", + "bridge-new-pump", + "bridge-pump-seat", + "bridge-pump-bolt-1", + "bridge-pump-bolt-2", + "bridge-pump-bolt-3", + "bridge-pump-bolt-4", + "bridge-tank-valve", + "bridge-paper", + "bridge-gasket", + "bridge-inlet", + "bridge-outlet", + "bridge-inlet-bag", + "bridge-outlet-bag", + "bridge-fill-cap", + "bridge-oil-can", + "bridge-oil-stream", + "bridge-test-control" + ], + "targetOnScreen": { + "targetId": "bridge-engine", + "localX": 299, + "localY": 407, + "insideCanvas": true, + "visible": true, + "coveredBy": [] + }, + "keptOpacity": [ + { + "targetId": "bridge-engine", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.04, + 0.06 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.02, + 0.01, + 0.09 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.03, + 0.03, + 0.12 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-old-pump", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.14, + 0.2 + ], + "verts": 1963, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-new-pump", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.14, + 0.2 + ], + "verts": 1963, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-pump-seat", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.09, + 0.01 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-pump-bolt-1", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-1", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-pump-bolt-2", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-2", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-pump-bolt-3", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-3", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-pump-bolt-4", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-4", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-tank-valve", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.04, + 0.06 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.02, + 0.01, + 0.09 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.03, + 0.03, + 0.12 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-paper", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.16, + 0, + 0.16 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-gasket", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.15, + 0.15, + 0 + ], + "verts": 66, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-inlet", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.09, + 0.07 + ], + "verts": 451, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-outlet", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.09, + 0.07 + ], + "verts": 451, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-inlet-bag", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.05, + 0.06, + 0.04 + ], + "verts": 24, + "baseOpacity": 0.65 + } + ] + }, + { + "targetId": "bridge-outlet-bag", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.05, + 0.06, + 0.04 + ], + "verts": 24, + "baseOpacity": 0.65 + } + ] + }, + { + "targetId": "bridge-fill-cap", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.05, + 0.05, + 0.02 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-oil-can", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.09, + 0.05 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-oil-stream", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.04, + 0.06, + 0.05 + ], + "verts": 451, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-test-control", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.04, + 0.06 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.02, + 0.01, + 0.09 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.03, + 0.03, + 0.12 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + } + ], + "environmentAlignment": { + "pickedAt": [ + 8.4, + -10.31, + 34.86 + ], + "localRelief": 0.265, + "samples": 115, + "workArea": { + "changedVertices": 1354, + "floorY": 0, + "bounds": [ + -5, + 5, + -6, + 8 + ] + } + }, + "sceneObjects": [ + { + "name": "野外山地训练场", + "min": [ + -78.4, + -6.84, + -92.96 + ], + "max": [ + 61.6, + 21.5, + 23.24 + ] + }, + { + "name": "架桥车前泵互救操作整车模型", + "min": [ + -0.92, + 0, + -4 + ], + "max": [ + 0.92, + 1.97, + 4 + ] + }, + { + "name": "前泵原位检修 · 原模型泵体与四颗安装螺栓", + "min": [ + -0.7, + 0.5, + 1.51 + ], + "max": [ + 0.44, + 0.91, + 1.94 + ] + } + ], + "labelSamples": [ + { + "targetId": "scene:front-pump-rescue-vehicle", + "targetName": "", + "partName": "架桥车前泵互救操作整车模型" + }, + { + "targetId": "front-pump-hydraulic-pump", + "targetName": "", + "partName": "液压泵" + }, + { + "targetId": "front-pump-power-take-off", + "targetName": "", + "partName": "取力器" + }, + { + "targetId": "front-pump-pto-switch", + "targetName": "", + "partName": "取力器开关" + } + ] + } +} \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-start.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-start.png new file mode 100644 index 0000000..9f8e1f4 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-start.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-11.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-11.png new file mode 100644 index 0000000..052ced7 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-11.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-2.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-2.png new file mode 100644 index 0000000..1c1e979 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-2.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-4.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-4.png new file mode 100644 index 0000000..6be595c Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-4.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-5.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-5.png new file mode 100644 index 0000000..0f7c0da Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-5.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-8.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-8.png new file mode 100644 index 0000000..12ed08c Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-007-step-8.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-diagnostic.json b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-diagnostic.json new file mode 100644 index 0000000..1e90ec0 --- /dev/null +++ b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-diagnostic.json @@ -0,0 +1,2029 @@ +{ + "mounted": true, + "hasEnvironment": true, + "hasEnvironmentTarget": true, + "toneMappingExposure": 1.05, + "background": "a8cbe1", + "meshCount": 81, + "materials": [ + { + "name": "M_3dfreehub_mat_2", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_3", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_4", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_5", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__85", + "color": "695c5b", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "BaiSe", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Cai1", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "HeiSe", + "color": "4f4f4f", + "metalness": 0.3, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "JinShu", + "color": "929292", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LanSe", + "color": "3b76d0", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LvSe", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_black", + "color": "322e2e", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_01", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_02", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1676", + "color": "d96e6e", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "MoShaJinShu", + "color": "cbcbcb", + "metalness": 0.8, + "roughness": 0.35, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "__", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__579", + "color": "404040", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1673", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "QianlvSe2", + "color": "749f62", + "metalness": 0, + "roughness": 0.6, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "WaiQiang", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "254b50", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "456068", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "6e8992", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "c0ced2", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "526767", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "172a32", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "172a32", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "3c6c86", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "607985", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d1eaf1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "e4ece7", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a441", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a441", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "526767", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "172a32", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "172a32", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "8b783d", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "bdcbd1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "607985", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d1eaf1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "e4ece7", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a441", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a441", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + } + ], + "server": { + "stepId": "BRIDGE-STEP-1", + "completed": [], + "registeredTargets": [ + "scene:front-pump-rescue-vehicle", + "front-pump-hydraulic-pump", + "front-pump-power-take-off", + "front-pump-pto-switch", + "front-pump-ball-valve-switch", + "front-pump-aux-control-box", + "front-pump-aux-control-box-cover", + "front-pump-rescue-switch", + "bridge-engine", + "bridge-small-seat", + "bridge-small-valve", + "bridge-small-bolt-1", + "bridge-small-bolt-2", + "bridge-small-bolt-3", + "bridge-small-bolt-4", + "bridge-small-pipe", + "bridge-small-bag", + "bridge-small-cloth", + "bridge-small-plug-1", + "bridge-small-plug-2", + "bridge-large-seat", + "bridge-large-valve", + "bridge-large-bolt-1", + "bridge-large-bolt-2", + "bridge-large-bolt-3", + "bridge-large-bolt-4", + "bridge-large-pipe", + "bridge-large-bag", + "bridge-large-cloth", + "bridge-large-plug-1", + "bridge-large-plug-2" + ], + "readOnly": false, + "animations": [ + { + "modelId": "front-pump-field-terrain", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + }, + { + "modelId": "front-pump-step-vehicle", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + } + ] + }, + "bridgeWorkshop": { + "modelBinding": null, + "pending": false, + "operation": { + "targetId": "bridge-small-cloth", + "kind": "identify", + "directionHint": "清洗并擦净阀体", + "effects": [ + { + "targetId": "bridge-small-cloth", + "offset": [ + 0.7, + 0, + -0.7 + ] + }, + { + "targetId": "bridge-small-valve", + "color": 8492701 + } + ], + "index": 0, + "axis": [ + 0, + 1, + 0 + ], + "deltaDegrees": 0, + "toleranceDegrees": 6 + }, + "operationIndex": 0, + "targets": [ + { + "id": "front-pump-hydraulic-pump", + "visible": true, + "position": [ + 0, + 0, + 0 + ], + "scale": [ + 0.01, + 0.01, + 0.01 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 0, + 0 + ], + "homeScale": [ + 0.01, + 0.01, + 0.01 + ], + "worldBounds": { + "min": [ + -0.1828516818917321, + 0.5470110749761624, + 1.5480637042583223 + ], + "max": [ + -0.07350143670700486, + 0.6823860012265373, + 1.7452996392749651 + ] + }, + "sourceNode": "1液压泵" + }, + { + "id": "bridge-engine", + "visible": true, + "position": [ + -3, + 1.1, + 1.2 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -3, + 1.1, + 1.2 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -3.1744597940157613, + 0.9977008716087504, + 6.0763115451708565 + ], + "max": [ + -2.824339676310247, + 1.2881462221520208, + 6.831686504293038 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-small-seat", + "visible": true, + "position": [ + -1.6, + 1.1, + -0.15 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.6, + 1.1, + -0.15 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -2.0995631331577895, + 0.8086047144589517, + 4.926054898687963 + ], + "max": [ + -1.0992357832373305, + 1.4094792670943594, + 5.216608437271742 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-valve", + "visible": true, + "position": [ + -1.6, + 1.1, + 0.15 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.6, + 1.1, + 0.15 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -2.024549640049506, + 0.8331843804255162, + 5.176087657320527 + ], + "max": [ + -1.1742494920804414, + 1.384108902830358, + 5.526812459854107 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-bolt-1", + "visible": true, + "position": [ + -1.9200000000000002, + 1.29, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.9200000000000002, + 1.29, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.975623083869019, + 1.233302820342235, + 5.521614733113131 + ], + "max": [ + -1.8629687881649977, + 1.3636276840634107, + 5.721785920863944 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-bolt-2", + "visible": true, + "position": [ + -1.28, + 1.29, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.28, + 1.29, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.3356231791549245, + 1.2329535841799255, + 5.521614502995981 + ], + "max": [ + -1.2229688834509032, + 1.3632784479011013, + 5.7217856907467946 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-bolt-3", + "visible": true, + "position": [ + -1.9200000000000002, + 0.9100000000000001, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.9200000000000002, + 0.9100000000000001, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.97583044284039, + 0.8533032068870802, + 5.521113957524753 + ], + "max": [ + -1.8631761471363688, + 0.983628070608256, + 5.721285145275567 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-bolt-4", + "visible": true, + "position": [ + -1.28, + 0.9100000000000001, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.28, + 0.9100000000000001, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.3358305381262956, + 0.8529539707247709, + 5.521113727407604 + ], + "max": [ + -1.2231762424222743, + 0.9832788344459467, + 5.721284915158417 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-pipe", + "visible": true, + "position": [ + -1.2000000000000002, + 1.1, + 0.1 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.2000000000000002, + 1.1, + 0.1 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.1995372633259738, + 0.8670490005055358, + 5.058073455360458 + ], + "max": [ + -0.8410036815160429, + 1.179190675198913, + 5.374853877871689 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-bag", + "visible": true, + "position": [ + -0.6500000000000001, + 1.1, + 0.75 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -0.6500000000000001, + 1.1, + 0.75 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.7894954404005422, + 0.932103191829592, + 5.831218632215685 + ], + "max": [ + -0.5093044060790936, + 1.2825718999745528, + 6.071679759791803 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-cloth", + "visible": true, + "position": [ + -2.3, + 1.1, + 1.05 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.3, + 1.1, + 1.05 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -2.449454341721735, + 1.0077443463562852, + 6.238817702455533 + ], + "max": [ + -2.1493452291747768, + 1.2079407961123305, + 6.264081355090077 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-plug-1", + "visible": true, + "position": [ + -1.82, + 1.6500000000000001, + 0.5 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.82, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.9291595710851788, + 1.548139552500657, + 5.622029710894203 + ], + "max": [ + -1.7090394975723722, + 1.7684702303241913, + 5.7823195701939385 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-small-plug-2", + "visible": true, + "position": [ + -1.3800000000000001, + 1.6500000000000001, + 0.5 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.3800000000000001, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -1.489159636594239, + 1.5478994526390693, + 5.622029552688662 + ], + "max": [ + -1.2690395630814324, + 1.7682301304626036, + 5.782319411988398 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-seat", + "visible": true, + "position": [ + 1.6, + 1.1, + -0.15 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.6, + 1.1, + -0.15 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.1004363904126826, + 0.8068585336474052, + 4.926053748102215 + ], + "max": [ + 2.100763740333142, + 1.407733086282813, + 5.216607286685995 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-valve", + "visible": true, + "position": [ + 1.6, + 1.1, + 0.15 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.6, + 1.1, + 0.15 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.1754498835209661, + 0.8314381996139698, + 5.176086506734779 + ], + "max": [ + 2.025750031490031, + 1.3823627220188115, + 5.52681130926836 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-bolt-1", + "visible": true, + "position": [ + 1.28, + 1.29, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.28, + 1.29, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.2243764397014536, + 1.2315566395306883, + 5.521613582527383 + ], + "max": [ + 1.337030735405475, + 1.361881503251864, + 5.721784770278196 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-bolt-2", + "visible": true, + "position": [ + 1.9200000000000002, + 1.29, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.9200000000000002, + 1.29, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.8643763444155481, + 1.2312074033683789, + 5.521613352410234 + ], + "max": [ + 1.9770306401195694, + 1.3615322670895547, + 5.721784540161047 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-bolt-3", + "visible": true, + "position": [ + 1.28, + 0.9100000000000001, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.28, + 0.9100000000000001, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.2241690807300825, + 0.8515570260755336, + 5.521112806939006 + ], + "max": [ + 1.3368233764341038, + 0.9818818897967094, + 5.721283994689819 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-bolt-4", + "visible": true, + "position": [ + 1.9200000000000002, + 0.9100000000000001, + 0.42 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.9200000000000002, + 0.9100000000000001, + 0.42 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.864168985444177, + 0.8512077899132243, + 5.5211125768218565 + ], + "max": [ + 1.9768232811481983, + 0.9815326536344001, + 5.72128376457267 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-pipe", + "visible": true, + "position": [ + 2, + 1.1, + 0.1 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 2, + 1.1, + 0.1 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 2.0004622602444986, + 0.8653028196939891, + 5.0580723047747105 + ], + "max": [ + 2.3589958420544295, + 1.1774444943873663, + 5.374852727285941 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-bag", + "visible": true, + "position": [ + 2.55, + 1.1, + 0.75 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 2.55, + 1.1, + 0.75 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 2.41050408316993, + 0.9303570110180454, + 5.831217481629937 + ], + "max": [ + 2.6906951174913782, + 1.2808257191630061, + 6.071678609206056 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-cloth", + "visible": true, + "position": [ + 0.9000000000000001, + 1.1, + 1.05 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.9000000000000001, + 1.1, + 1.05 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.7505451818487371, + 1.0059981655447385, + 6.238816551869785 + ], + "max": [ + 1.0506542943956954, + 1.2061946153007839, + 6.26408020450433 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-plug-1", + "visible": true, + "position": [ + 1.3800000000000001, + 1.6500000000000001, + 0.5 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.3800000000000001, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.2708399524852938, + 1.5463933716891105, + 5.622028560308455 + ], + "max": [ + 1.4909600259981004, + 1.7667240495126448, + 5.782318419608191 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-large-plug-2", + "visible": true, + "position": [ + 1.82, + 1.6500000000000001, + 0.5 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.82, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 1.7108398869762336, + 1.5461532718275228, + 5.622028402102915 + ], + "max": [ + 1.9309599604890402, + 1.7664839496510572, + 5.782318261402651 + ] + }, + "sourceNode": "" + } + ] + }, + "bridgeGrounding": [ + { + "id": "front-pump-rescue-vehicle", + "adjustment": -2.6725065689598313e-9, + "contacts": 22, + "minGap": 0, + "maxGap": 0.01902815385345835, + "position": [ + 0, + -2.6725065689598313e-9, + 0 + ], + "quaternion": [ + 1.5432791624149142e-17, + 0, + -1.284056869900529e-16, + 1 + ] + }, + { + "id": "bridge-workshop", + "adjustment": 0.007972344742127626, + "contacts": 16, + "minGap": 0, + "maxGap": 0.007419605491776459, + "position": [ + 0, + 0.007972344742127626, + 5.2 + ], + "quaternion": [ + 0.0006589154154300379, + 0, + -0.00027284082118916614, + 0.9999997456941484 + ] + } + ], + "publishedContentMounted": true, + "publishedContentName": "重型支援桥平衡阀拆拼互换", + "publishedTrainingContent": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "objectCount": 2 + }, + "proceduralMachineVisible": false, + "publishedModelRootCount": 2, + "framing": { + "cameraPosition": [ + -3.4, + 7.62, + 17.7 + ], + "controlsTarget": [ + -3.4, + 1.27, + 6.16 + ], + "distance": 13.17, + "minDistance": 0.25, + "maxDistance": 800, + "fov": 45, + "near": 0.1, + "far": 800, + "fogNear": 70, + "fogFar": 240, + "modelSize": [ + 140, + 28.34, + 116.19 + ], + "modelCenter": [ + -8.4, + 7.33, + -34.86 + ], + "stepCameraPolicy": "focus", + "explosionItemCount": 36, + "structureNodeCount": 44, + "enablePan": true, + "outlineActive": false, + "labelsVisible": false, + "hideOthers": false, + "hiddenMeshCount": 0, + "keptTargets": [], + "targetOnScreen": { + "targetId": "bridge-small-cloth", + "localX": 628, + "localY": 395, + "insideCanvas": true, + "visible": true, + "coveredBy": [] + }, + "keptOpacity": [], + "environmentAlignment": { + "pickedAt": [ + 8.4, + -10.31, + 34.86 + ], + "localRelief": 0.265, + "samples": 115, + "workArea": { + "changedVertices": 1354, + "floorY": 0, + "bounds": [ + -5, + 5, + -6, + 8 + ] + } + }, + "sceneObjects": [ + { + "name": "野外山地训练场", + "min": [ + -78.4, + -6.84, + -92.96 + ], + "max": [ + 61.6, + 21.5, + 23.24 + ] + }, + { + "name": "架桥车前泵互救操作整车模型", + "min": [ + -0.92, + 0, + -4 + ], + "max": [ + 0.92, + 1.97, + 4 + ] + }, + { + "name": "补充操作示意 · 非实车尺寸", + "min": [ + -3.6, + 0, + 4.34 + ], + "max": [ + 3.6, + 3.06, + 7 + ] + } + ], + "labelSamples": [ + { + "targetId": "scene:front-pump-rescue-vehicle", + "targetName": "", + "partName": "架桥车前泵互救操作整车模型" + }, + { + "targetId": "front-pump-hydraulic-pump", + "targetName": "", + "partName": "液压泵" + }, + { + "targetId": "front-pump-power-take-off", + "targetName": "", + "partName": "取力器" + }, + { + "targetId": "front-pump-pto-switch", + "targetName": "", + "partName": "取力器开关" + } + ] + } +} \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-original.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-original.png new file mode 100644 index 0000000..3c3f594 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-original.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-start.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-start.png new file mode 100644 index 0000000..30253d8 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-start.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-11.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-11.png new file mode 100644 index 0000000..94dd11d Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-11.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-16.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-16.png new file mode 100644 index 0000000..4f50ce1 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-16.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-2.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-2.png new file mode 100644 index 0000000..116e5aa Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-2.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-4.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-4.png new file mode 100644 index 0000000..8af18fe Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-4.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-5.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-5.png new file mode 100644 index 0000000..0e3069f Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-5.png differ diff --git a/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-8.png b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-8.png new file mode 100644 index 0000000..a7942d9 Binary files /dev/null and b/reports/bridge-model-match-20260914/TASK-VIRTUAL-008-step-8.png differ diff --git a/reports/bridge-model-match-20260914/acceptance.json b/reports/bridge-model-match-20260914/acceptance.json new file mode 100644 index 0000000..f78f4bf --- /dev/null +++ b/reports/bridge-model-match-20260914/acceptance.json @@ -0,0 +1,9 @@ +{ + "pass": true, + "checks": [ + "TASK-VIRTUAL-006: 7 steps, 11 3D operations; preview server validation passed", + "TASK-VIRTUAL-007: 11 steps, 27 3D operations; preview server validation passed", + "TASK-VIRTUAL-008: 16 steps, 50 3D operations; preview server validation passed" + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/cleanup.json b/reports/bridge-model-match-20260914/cleanup.json new file mode 100644 index 0000000..e959a21 --- /dev/null +++ b/reports/bridge-model-match-20260914/cleanup.json @@ -0,0 +1,20 @@ +{ + "result": "PASS", + "softDeletedTasks": 3, + "keptTaskIds": [ + 86, + 87, + 88, + 89 + ], + "counts": { + "ut_teaching_assignment": 3, + "ut_teaching_event": 6 + }, + "backupSha256": "6e1fcc710804b170c9b876c54a8470b17f51d34fa838a8d24c683d78b996e2d8", + "softDeletedContentProjects": [ + 453, + 454, + 455 + ] +} \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/fixtures-1789393430060.json b/reports/bridge-model-match-20260914/fixtures-1789393430060.json new file mode 100644 index 0000000..59087e9 --- /dev/null +++ b/reports/bridge-model-match-20260914/fixtures-1789393430060.json @@ -0,0 +1,8 @@ +[ + { + "code": "TASK-VIRTUAL-007", + "projectId": "453", + "taskId": "113", + "passed": true + } +] \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/fixtures-1789393666850.json b/reports/bridge-model-match-20260914/fixtures-1789393666850.json new file mode 100644 index 0000000..59087e9 --- /dev/null +++ b/reports/bridge-model-match-20260914/fixtures-1789393666850.json @@ -0,0 +1,8 @@ +[ + { + "code": "TASK-VIRTUAL-007", + "projectId": "453", + "taskId": "113", + "passed": true + } +] \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/fixtures-1789393834396.json b/reports/bridge-model-match-20260914/fixtures-1789393834396.json new file mode 100644 index 0000000..4376c64 --- /dev/null +++ b/reports/bridge-model-match-20260914/fixtures-1789393834396.json @@ -0,0 +1,20 @@ +[ + { + "code": "TASK-VIRTUAL-006", + "projectId": "454", + "taskId": "114", + "passed": true + }, + { + "code": "TASK-VIRTUAL-007", + "projectId": "453", + "taskId": "113", + "passed": true + }, + { + "code": "TASK-VIRTUAL-008", + "projectId": "455", + "taskId": "115", + "passed": true + } +] \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/fixtures-1789394583363.json b/reports/bridge-model-match-20260914/fixtures-1789394583363.json new file mode 100644 index 0000000..4376c64 --- /dev/null +++ b/reports/bridge-model-match-20260914/fixtures-1789394583363.json @@ -0,0 +1,20 @@ +[ + { + "code": "TASK-VIRTUAL-006", + "projectId": "454", + "taskId": "114", + "passed": true + }, + { + "code": "TASK-VIRTUAL-007", + "projectId": "453", + "taskId": "113", + "passed": true + }, + { + "code": "TASK-VIRTUAL-008", + "projectId": "455", + "taskId": "115", + "passed": true + } +] \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/index.html b/reports/bridge-model-match-20260914/index.html new file mode 100644 index 0000000..9108194 --- /dev/null +++ b/reports/bridge-model-match-20260914/index.html @@ -0,0 +1 @@ +桥梁四套脚本模型匹配验收

桥梁四套脚本 · 模型匹配验收

2026-09-14 · 对照桥梁文件夹图片 4–10,以及实际 GLB 网格、节点、变换和运行结果。

结论:005 原模型对应最完整;007 已改为原位拆装;006、008 仍有实车模型缺失,不能声称四套已完全匹配。

任务匹配程度核对与修正
005 应急切换原模型对应最完整5 步、6 次操作;7 个登记节点均唯一存在,沿用原转轴。开关精度及故障物理仿真仍有限。
006 应急替代部分匹配4 次操作复用原车开关;双管接头与软管联动、阀体固定只转手柄。保障车和接口仍为补充示意。
007 换件修复原位泵体、螺栓已匹配复用原泵网格和世界姿态,拆出原有 4 颗螺栓;安装位置复原,增加细节视角和直接拾取。管路、纸垫等仍为补充件。
008 平衡阀互换仍为补充装配模型补齐油缸与两腔关系;擦拭贴面、阀座保留油口、封堵与换位对应。原整车缺少可确认的两腔平衡阀节点。

验证范围

原 005 完整 5 步和后加三套 34 步,共 39 步、94 次操作,经真实教学预览校验;未创建学员成绩。附加 8 项单元/路由检查与生产构建通过。

acceptance · PASS

原始结果

originals · PASS

原始结果

picking · PASS

原始结果

39 步逐项核对及模型缺项说明 · 临时验收数据清理结果

运行截图

005 原始流程回归
005 原始流程回归
006 两端接头与双管连接
006 两端接头与双管连接
007 原模型四颗安装螺栓拆卸
007 原模型四颗安装螺栓拆卸
007 新泵原位安装
007 新泵原位安装
007 复位视角保留拆卸状态
007 复位视角保留拆卸状态
008 小腔拆阀后封堵油口
008 小腔拆阀后封堵油口
008 完成两腔互换
008 完成两腔互换
\ No newline at end of file diff --git a/reports/bridge-model-match-20260914/originals.json b/reports/bridge-model-match-20260914/originals.json new file mode 100644 index 0000000..48c09fe --- /dev/null +++ b/reports/bridge-model-match-20260914/originals.json @@ -0,0 +1,7 @@ +{ + "pass": true, + "checks": [ + "TASK-VIRTUAL-005 原任务入口通过,原运行与成绩未变化", + "TASK-VIRTUAL-008 原任务入口通过,原运行与成绩未变化" + ] +} \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/picking-diagnostic.json b/reports/bridge-model-match-20260914/picking-diagnostic.json new file mode 100644 index 0000000..0c19299 --- /dev/null +++ b/reports/bridge-model-match-20260914/picking-diagnostic.json @@ -0,0 +1,2227 @@ +{ + "mounted": true, + "hasEnvironment": true, + "hasEnvironmentTarget": true, + "toneMappingExposure": 1.05, + "background": "a8cbe1", + "meshCount": 82, + "materials": [ + { + "name": "M_3dfreehub_mat_2", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_3", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_4", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "M_3dfreehub_mat_5", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__85", + "color": "695c5b", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "BaiSe", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Cai1", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "HeiSe", + "color": "4f4f4f", + "metalness": 0.3, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "JinShu", + "color": "929292", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LanSe", + "color": "3b76d0", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "LvSe", + "color": "3d4b3b", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_black", + "color": "322e2e", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_01", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridgeBridge_02", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Mat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1676", + "color": "d96e6e", + "metalness": 0.6, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "MoShaJinShu", + "color": "cbcbcb", + "metalness": 0.8, + "roughness": 0.35, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "__", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_supportBridge_05", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "adskMatMat_white", + "color": "9da3a4", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__579", + "color": "404040", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "Material__1673", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": true, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "QianlvSe2", + "color": "749f62", + "metalness": 0, + "roughness": 0.6, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "WaiQiang", + "color": "ffffff", + "metalness": 0, + "roughness": 0.5, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "c95a4b", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "c95a4b", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "c95a4b", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "627980", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ffffff", + "metalness": null, + "roughness": null, + "envMapIntensity": null, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d9a543", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "b89455", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "b89455", + "metalness": 0, + "roughness": 1, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "465963", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "465963", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d1eaf1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d1eaf1", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "ddab4a", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "d5a945", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "e4b243", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "31464f", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "21b588", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + }, + { + "name": "(未命名)", + "color": "7e979e", + "metalness": 0.55, + "roughness": 0.45, + "envMapIntensity": 1, + "hasMap": false, + "preset": null, + "rule": null, + "authored": null + } + ], + "server": { + "stepId": "BRIDGE-STEP-4", + "completed": [ + 0, + 1, + 2 + ], + "registeredTargets": [ + "scene:front-pump-rescue-vehicle", + "front-pump-hydraulic-pump", + "front-pump-power-take-off", + "front-pump-pto-switch", + "front-pump-ball-valve-switch", + "front-pump-aux-control-box", + "front-pump-aux-control-box-cover", + "front-pump-rescue-switch", + "bridge-engine", + "bridge-old-pump", + "bridge-new-pump", + "bridge-pump-seat", + "bridge-pump-bolt-1", + "bridge-pump-bolt-2", + "bridge-pump-bolt-3", + "bridge-pump-bolt-4", + "bridge-tank-valve", + "bridge-paper", + "bridge-gasket", + "bridge-inlet", + "bridge-outlet", + "bridge-inlet-bag", + "bridge-outlet-bag", + "bridge-fill-cap", + "bridge-oil-can", + "bridge-oil-stream", + "bridge-test-control" + ], + "readOnly": false, + "animations": [ + { + "modelId": "front-pump-field-terrain", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + }, + { + "modelId": "front-pump-step-vehicle", + "versionId": "", + "bindings": 0, + "unresolved": 0, + "flowVisible": false, + "native": [] + } + ] + }, + "bridgeWorkshop": { + "modelBinding": { + "sourceNode": "1液压泵", + "boltSource": "关键螺丝", + "boltCount": 4, + "sourceBounds": { + "min": [ + -0.1828516818917321, + 0.5470110749761624, + 1.5480637042583223 + ], + "max": [ + -0.07350143670700486, + 0.6823860012265373, + 1.7452996392749651 + ] + }, + "scale": 0.17930539546967528, + "mountedOnVehicle": true + }, + "pending": false, + "operation": { + "targetId": "bridge-pump-bolt-2", + "kind": "rotate", + "axis": [ + 0, + 0, + 1 + ], + "deltaDegrees": -180, + "toleranceDegrees": 8, + "directionHint": "拆下第 2 个安装螺栓", + "effects": [ + { + "targetId": "bridge-pump-bolt-2", + "offset": [ + 0, + 0, + 0.65 + ] + } + ], + "index": 1 + }, + "operationIndex": 1, + "targets": [ + { + "id": "front-pump-hydraulic-pump", + "visible": false, + "position": [ + 0, + 0, + 0 + ], + "scale": [ + 0.01, + 0.01, + 0.01 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 0, + 0 + ], + "homeScale": [ + 0.01, + 0.01, + 0.01 + ], + "worldBounds": { + "min": [ + -0.1828516818917321, + 0.5470110749761624, + 1.5480637042583223 + ], + "max": [ + -0.07350143670700486, + 0.6823860012265373, + 1.7452996392749651 + ] + }, + "sourceNode": "1液压泵" + }, + { + "id": "bridge-engine", + "visible": true, + "position": [ + -3, + 1.1, + 1.2 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -3, + 1.1, + 1.2 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6974711893812158, + 0.5411833260656574, + 1.8035738949400966 + ], + "max": [ + -0.6347143020355728, + 0.5931818905247553, + 1.9389494663822144 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + }, + { + "id": "bridge-old-pump", + "visible": true, + "position": [ + 0, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18285168890500836, + 0.5470110777057942, + 1.5480637555580075 + ], + "max": [ + -0.07350144038116299, + 0.682385982465754, + 1.745299694849624 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-new-pump", + "visible": true, + "position": [ + 2, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 2, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.1757591020343422, + 0.5470110777057942, + 1.5480637555580075 + ], + "max": [ + 0.2851093505581876, + 0.682385982465754, + 1.745299694849624 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-pump-seat", + "visible": true, + "position": [ + 0, + 1.4, + 0.62 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 1.4, + 0.62 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18555428456717243, + 0.5698721892339311, + 1.7524718552139857 + ], + "max": [ + -0.0707988340315645, + 0.6595248869687687, + 1.7632301787016988 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-pump-bolt-1", + "visible": true, + "position": [ + -0.22726086527109146, + 1.4364657248137518, + 1.1703916877508163 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + -1, + 6.123233995736766e-17 + ], + "home": [ + -0.22726086527109146, + 1.4364657248137518, + 0.5203916877508163 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18129260597425778, + 0.6088700919574924, + 1.844172268840549 + ], + "max": [ + -0.15655871126890653, + 0.6336039866628437, + 1.8689061635459001 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-pump-bolt-2", + "visible": true, + "position": [ + 0.22531712800264359, + 1.4364657248137518, + 0.5203923434019089 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.22531712800264359, + 1.4364657248137518, + 0.5203923434019089 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.10014292990943864, + 0.6088700919574924, + 1.7276238793470384 + ], + "max": [ + -0.07540903520408739, + 0.6336039866628437, + 1.7523577740523895 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-pump-bolt-3", + "visible": true, + "position": [ + -0.22726086527109146, + 1.1014159262180327, + 0.5203910171985626 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -0.22726086527109146, + 1.1014159262180327, + 0.5203910171985626 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.18129260998204563, + 0.548793851310464, + 1.727623637543835 + ], + "max": [ + -0.15655870726111856, + 0.573527754031391, + 1.7523575402647622 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-pump-bolt-4", + "visible": true, + "position": [ + 0.22531712800264359, + 1.1014159262180327, + 0.5203916877508163 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.22531712800264359, + 1.1014159262180327, + 0.5203916877508163 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.10014292990943864, + 0.5487938553182519, + 1.7276237617852601 + ], + "max": [ + -0.07540903520408739, + 0.5735277500236031, + 1.7523576564906111 + ] + }, + "sourceNode": "关键螺丝" + }, + { + "id": "bridge-tank-valve", + "visible": true, + "position": [ + -2.7, + 1.1, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.7, + 1.1, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6436795707403132, + 0.5411833260656574, + 1.5884074203764862 + ], + "max": [ + -0.5351998070155313, + 0.5931818905247548, + 1.7049559231568012 + ] + }, + "rotatingQuaternion": [ + 0, + 0.7071067811865475, + 0, + 0.7071067811865476 + ], + "sourceNode": "" + }, + { + "id": "bridge-paper", + "visible": true, + "position": [ + -2.3, + 0.8, + 0.4 + ], + "scale": [ + 0.85, + 1, + 0.85 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.3, + 0.8, + 0.4 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6091632808299084, + 0.5048739833427757, + 1.649819518004227 + ], + "max": [ + -0.4719946569293346, + 0.509356618296314, + 1.7869881419048008 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-gasket", + "visible": false, + "position": [ + -2.3, + 1.4, + -0.75 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -2.3, + 1.4, + -0.75 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.6158872326256496, + 0.5393902743553218, + 1.5122026251643872 + ], + "max": [ + -0.4652707051335935, + 0.690006801847378, + 1.5122026251643872 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-inlet", + "visible": true, + "position": [ + -1.25, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -0.65, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.46053694866942124, + 0.5363196942955012, + 1.6334456796932533 + ], + "max": [ + -0.3523072515834954, + 0.6288944167519539, + 1.7004538734767225 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-outlet", + "visible": true, + "position": [ + 1.25, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.65, + 1.4, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.09595413298475845, + 0.5363196942955012, + 1.6334456796932533 + ], + "max": [ + 0.2041838300706843, + 0.6288944167519539, + 1.7004538734767225 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-inlet-bag", + "visible": true, + "position": [ + -1.25, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + -1.25, + 1.4, + 0.65 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.37741105910909145, + 0.5833200944285284, + 1.6251650247912173 + ], + "max": [ + -0.32720554816383374, + 0.6460769817741714, + 1.6681983187420701 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-outlet-bag", + "visible": true, + "position": [ + 1.25, + 1.4, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.25, + 1.4, + 0.65 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.07085242956509674, + 0.5833200944285284, + 1.6251650247912173 + ], + "max": [ + 0.12105794051035451, + 0.6460769817741714, + 1.6681983187420701 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-fill-cap", + "visible": true, + "position": [ + 0, + 2, + 0 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0, + 2, + 0 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.15148625985543152, + 0.698972074827092, + 1.637716401859567 + ], + "max": [ + -0.10486685874330544, + 0.7455914759392182, + 1.6556469416737205 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-oil-can", + "visible": true, + "position": [ + 1.4, + 1.8, + 0.5 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 1.4, + 1.8, + 0.5 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.09147255068535545, + 0.6415943474218013, + 1.7094385591122865 + ], + "max": [ + 0.15422943803099834, + 0.7312470451566389, + 1.763230179890676 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-oil-stream", + "visible": false, + "position": [ + 0.1, + 2.1, + 0.15 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 0.1, + 2.1, + 0.15 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + -0.13835291417702386, + 0.6891968621123294, + 1.6373530580795213 + ], + "max": [ + -0.10006966447396676, + 0.746401420884391, + 1.6829060957093678 + ] + }, + "sourceNode": "" + }, + { + "id": "bridge-test-control", + "visible": true, + "position": [ + 3, + 1.1, + 1 + ], + "scale": [ + 1, + 1, + 1 + ], + "quaternion": [ + 0, + 0, + 0, + 1 + ], + "home": [ + 3, + 1.1, + 1 + ], + "homeScale": [ + 1, + 1, + 1 + ], + "worldBounds": { + "min": [ + 0.37836118343683595, + 0.5411833260656574, + 1.7677128158461615 + ], + "max": [ + 0.44111807078247883, + 0.5931818905247553, + 1.9030883872882793 + ] + }, + "rotatingQuaternion": [ + 0, + 0, + 0, + 1 + ], + "sourceNode": "" + } + ] + }, + "bridgeGrounding": [ + { + "id": "front-pump-rescue-vehicle", + "adjustment": -2.6725065689598313e-9, + "contacts": 22, + "minGap": 0, + "maxGap": 0.01902815385345835, + "position": [ + 0, + -2.6725065689598313e-9, + 0 + ], + "quaternion": [ + 1.5432791624149142e-17, + 0, + -1.284056869900529e-16, + 1 + ] + } + ], + "publishedContentMounted": true, + "publishedContentName": "重型支援桥前泵换件修复", + "publishedTrainingContent": { + "sceneId": "SCENE-FRONT-PUMP-RESCUE-01", + "objectCount": 2 + }, + "proceduralMachineVisible": false, + "publishedModelRootCount": 2, + "framing": { + "cameraPosition": [ + -0.13, + 0.89, + 2.19 + ], + "controlsTarget": [ + -0.13, + 0.6, + 1.66 + ], + "distance": 0.6, + "minDistance": 0.25, + "maxDistance": 800, + "fov": 45, + "near": 0.1, + "far": 800, + "fogNear": 70, + "fogFar": 240, + "modelSize": [ + 140, + 28.34, + 116.19 + ], + "modelCenter": [ + -8.4, + 7.33, + -34.86 + ], + "stepCameraPolicy": "focus", + "explosionItemCount": 36, + "structureNodeCount": 44, + "enablePan": true, + "outlineActive": false, + "labelsVisible": false, + "hideOthers": false, + "hiddenMeshCount": 0, + "keptTargets": [ + "bridge-engine", + "bridge-old-pump", + "bridge-new-pump", + "bridge-pump-seat", + "bridge-pump-bolt-1", + "bridge-pump-bolt-2", + "bridge-pump-bolt-3", + "bridge-pump-bolt-4", + "bridge-tank-valve", + "bridge-paper", + "bridge-gasket", + "bridge-inlet", + "bridge-outlet", + "bridge-inlet-bag", + "bridge-outlet-bag", + "bridge-fill-cap", + "bridge-oil-can", + "bridge-oil-stream", + "bridge-test-control" + ], + "targetOnScreen": { + "targetId": "bridge-pump-bolt-1", + "localX": 461, + "localY": 548, + "insideCanvas": true, + "visible": true, + "coveredBy": [] + }, + "keptOpacity": [ + { + "targetId": "bridge-engine", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.04, + 0.06 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.02, + 0.01, + 0.09 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.03, + 0.03, + 0.12 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-old-pump", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.14, + 0.2 + ], + "verts": 1963, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-new-pump", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.14, + 0.2 + ], + "verts": 1963, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.01 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.02, + 0.02 + ], + "verts": 480, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-pump-seat", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.09, + 0.01 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-pump-bolt-1", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-1", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-pump-bolt-2", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-2", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-pump-bolt-3", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-3", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-pump-bolt-4", + "minOpacity": 0, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.01, + 0.01, + 0.02 + ], + "verts": 240, + "baseOpacity": 1 + }, + { + "name": "training-pick-proxy:bridge-pump-bolt-4", + "size": [ + 0.02, + 0.02, + 0.02 + ], + "verts": 117, + "baseOpacity": 0 + } + ] + }, + { + "targetId": "bridge-tank-valve", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.04, + 0.06 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.09, + 0.01, + 0.02 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.03, + 0.03, + 0.12 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-paper", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.14, + 0, + 0.14 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-gasket", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.15, + 0.15, + 0 + ], + "verts": 66, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-inlet", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.09, + 0.07 + ], + "verts": 451, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-outlet", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.11, + 0.09, + 0.07 + ], + "verts": 451, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-inlet-bag", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.05, + 0.06, + 0.04 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-outlet-bag", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.05, + 0.06, + 0.04 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-fill-cap", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.05, + 0.05, + 0.02 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-oil-can", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.09, + 0.05 + ], + "verts": 24, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-oil-stream", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.04, + 0.06, + 0.05 + ], + "verts": 451, + "baseOpacity": 1 + } + ] + }, + { + "targetId": "bridge-test-control", + "minOpacity": 1, + "meshes": [ + { + "name": "Mesh", + "size": [ + 0.06, + 0.04, + 0.06 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.02, + 0.01, + 0.09 + ], + "verts": 24, + "baseOpacity": 1 + }, + { + "name": "Mesh", + "size": [ + 0.03, + 0.03, + 0.12 + ], + "verts": 148, + "baseOpacity": 1 + } + ] + } + ], + "environmentAlignment": { + "pickedAt": [ + 8.4, + -10.31, + 34.86 + ], + "localRelief": 0.265, + "samples": 115, + "workArea": { + "changedVertices": 1354, + "floorY": 0, + "bounds": [ + -5, + 5, + -6, + 8 + ] + } + }, + "sceneObjects": [ + { + "name": "野外山地训练场", + "min": [ + -78.4, + -6.84, + -92.96 + ], + "max": [ + 61.6, + 21.5, + 23.24 + ] + }, + { + "name": "架桥车前泵互救操作整车模型", + "min": [ + -0.92, + 0, + -4 + ], + "max": [ + 0.92, + 1.97, + 4 + ] + }, + { + "name": "前泵原位检修 · 原模型泵体与四颗安装螺栓", + "min": [ + -0.7, + 0.5, + 1.51 + ], + "max": [ + 0.44, + 0.91, + 1.94 + ] + } + ], + "labelSamples": [ + { + "targetId": "scene:front-pump-rescue-vehicle", + "targetName": "", + "partName": "架桥车前泵互救操作整车模型" + }, + { + "targetId": "front-pump-hydraulic-pump", + "targetName": "", + "partName": "液压泵" + }, + { + "targetId": "front-pump-power-take-off", + "targetName": "", + "partName": "取力器" + }, + { + "targetId": "front-pump-pto-switch", + "targetName": "", + "partName": "取力器开关" + } + ] + } +} \ No newline at end of file diff --git a/reports/bridge-model-match-20260914/picking-failure.png b/reports/bridge-model-match-20260914/picking-failure.png new file mode 100644 index 0000000..7f6e83a Binary files /dev/null and b/reports/bridge-model-match-20260914/picking-failure.png differ diff --git a/reports/bridge-model-match-20260914/picking.json b/reports/bridge-model-match-20260914/picking.json new file mode 100644 index 0000000..101aa23 --- /dev/null +++ b/reports/bridge-model-match-20260914/picking.json @@ -0,0 +1,12 @@ +{ + "pass": true, + "checks": [ + "Canvas picking bridge-pump-bolt-1", + "Canvas picking bridge-pump-bolt-2", + "Canvas picking bridge-pump-bolt-3", + "Canvas picking bridge-pump-bolt-4", + "camera reset preserves actual pump/bolt state", + "reload preserves source placement" + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-narration-20260914/TASK-VIRTUAL-005-step-2.png b/reports/bridge-narration-20260914/TASK-VIRTUAL-005-step-2.png new file mode 100644 index 0000000..c2e3ffb Binary files /dev/null and b/reports/bridge-narration-20260914/TASK-VIRTUAL-005-step-2.png differ diff --git a/reports/bridge-narration-20260914/TASK-VIRTUAL-006-step-2.png b/reports/bridge-narration-20260914/TASK-VIRTUAL-006-step-2.png new file mode 100644 index 0000000..f1b5205 Binary files /dev/null and b/reports/bridge-narration-20260914/TASK-VIRTUAL-006-step-2.png differ diff --git a/reports/bridge-narration-20260914/TASK-VIRTUAL-007-step-2.png b/reports/bridge-narration-20260914/TASK-VIRTUAL-007-step-2.png new file mode 100644 index 0000000..5a31be1 Binary files /dev/null and b/reports/bridge-narration-20260914/TASK-VIRTUAL-007-step-2.png differ diff --git a/reports/bridge-narration-20260914/TASK-VIRTUAL-008-step-2.png b/reports/bridge-narration-20260914/TASK-VIRTUAL-008-step-2.png new file mode 100644 index 0000000..ec96d0d Binary files /dev/null and b/reports/bridge-narration-20260914/TASK-VIRTUAL-008-step-2.png differ diff --git a/reports/bridge-narration-20260914/index.html b/reports/bridge-narration-20260914/index.html new file mode 100644 index 0000000..4cbe953 --- /dev/null +++ b/reports/bridge-narration-20260914/index.html @@ -0,0 +1 @@ +桥梁脚本语音验收

四套桥梁脚本语音验收

39段步骤讲解、3段核对提醒,全部真实下载和浏览器解码通过。四个原任务前两步实际播放、切步停止、刷新重播、关闭停止通过。教员预览未写入成绩。

TASK-VIRTUAL-005 重型支援桥液压泵应急切换

桥梁/文件2/4.jpg · 5步

第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。

第2步,断开架桥车取力器。将架桥车取力器断开。

第3步,打开互救球阀。打开备胎上方两个红色滤油器之间的连通球阀,手柄由垂直管道转为平行管道。

第4步,重新接通取力器。将架桥车取力器重新接通。

第5步,打开辅助控制盒互救开关。打开辅助控制盒盖,再打开互救开关,进入单泵作业状态。

TASK-VIRTUAL-006 重型支援桥液压泵应急替代

桥梁/文件2/5.jpg、6.jpg · 7步

第1步,保持架桥车运行并断开取力器。保持架桥车发动机运转,确保架桥车取力器处于断开状态。

第2步,连接两车液压软管。连接支援车与架桥车液压软管。架桥车快接接头位于液压油箱右侧;支援车快接接头位于驾驶室外右下方。

第3步,打开支援车回油截止阀。打开支援车液压油箱快接接头处的回油截止阀。

第4步,打开互救作业开关。打开辅助控制盒上的“互救作业”开关。

第5步,打开滤油器出口连通球阀。打开两个输油滤油器出口处的连通球阀。

第6步,接通支援车液压取力器。接通支援车液压系统取力器,向架桥车供油。

第7步,按正常步骤操作架桥车。原图只概括“按正常操作步骤操作架桥车”,没有展开后续作业。该项为原稿概括项,本预演不代表后续正常作业已经完成。

TASK-VIRTUAL-007 重型支援桥前泵换件修复

桥梁/文件2/7.jpg、8.jpg · 11步

第1步,停机并初裁牛皮纸。架桥车熄火;按液压泵与取力器结合面形状初步裁剪牛皮纸。

第2步,关闭液压油箱出油口一号球阀。将一号球阀手柄从平行管道转到垂直管道。

第3步,拆开并包扎进出油管。用大活动扳手拆开液压泵进、出油管接头,用塑料袋包扎管口。

第4步,拆下四个安装螺栓。用开口扳手拆下液压泵与取力器之间的四个安装螺栓。

第5步,取下旧前泵。取下原前泵。

第6步,修裁牛皮纸。进一步裁剪牛皮纸,使其与液压泵安装面及取力器结合面吻合。

第7步,放置牛皮纸垫。将裁好的牛皮纸放在取力器接口处。

第8步,安装新液压泵。安装新的液压泵。原稿没有给出拧紧力矩。

第9步,向新泵加注液压油。打开新液压泵加油口,加注液压油。原稿没有给出定量值。

第10步,恢复进出油管连接。用大活动扳手连接并拧紧液压泵进、出油管。

第11步,启动设备试验。启动设备进行试验。原稿没有展开具体试验项目和判定数值。

TASK-VIRTUAL-008 重型支援桥平衡阀拆拼互换

桥梁/文件2/9.jpg、10.jpg · 16步

第1步,清洗小腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。

第2步,拆开小腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。

第3步,拆下小腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。

第4步,封堵小腔油口。用两个油堵封住两个油口,擦净阀座结合面。

第5步,清洗大腔平衡阀。用清洗剂清洗平衡阀和管接头,并用抹布擦净。

第6步,拆开大腔控制油口管路。用十九号开口扳手拆开控制油口管路,用塑料袋包扎管口。

第7步,拆下大腔平衡阀。用八号内六角扳手拆下安装螺栓,取下平衡阀。

第8步,封堵大腔油口。用两个油堵封住两个油口,擦净阀座结合面。

第9步,准备安装大腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。

第10步,安装大腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。

第11步,核对大腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。

第12步,紧固大腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。

第13步,准备安装小腔平衡阀。擦净平衡阀及阀座结合面,取下两个油堵。

第14步,安装小腔平衡阀。将平衡阀放置于阀座上,用八号内六角扳手安装四个安装螺栓。

第15步,核对小腔控制油口管路连接。原稿先写“拆下包扎袋,连接并拧紧管路”,随后又出现“用十九号开口扳手拆开管路并包扎”的相反描述。请记录采用的处理方式及依据,随训练记录提交教员核对;系统不自动判定该项操作正确。

第16步,紧固小腔阀体连接螺栓。用内六角扳手拧紧四个阀体连接螺栓。

\ No newline at end of file diff --git a/reports/bridge-narration-20260914/result.json b/reports/bridge-narration-20260914/result.json new file mode 100644 index 0000000..1a7af1d --- /dev/null +++ b/reports/bridge-narration-20260914/result.json @@ -0,0 +1,245 @@ +{ + "results": [ + { + "code": "TASK-VIRTUAL-005", + "stepsBound": 5, + "firstAndSecondPlayed": true, + "stopOnStepChange": true, + "reloadPlayed": true + }, + { + "code": "TASK-VIRTUAL-006", + "stepsBound": 7, + "firstAndSecondPlayed": true, + "stopOnStepChange": true, + "reloadPlayed": true + }, + { + "code": "TASK-VIRTUAL-007", + "stepsBound": 11, + "firstAndSecondPlayed": true, + "stopOnStepChange": true, + "reloadPlayed": true + }, + { + "code": "TASK-VIRTUAL-008", + "stepsBound": 16, + "firstAndSecondPlayed": true, + "stopOnStepChange": true, + "reloadPlayed": true + } + ], + "decoded": [ + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-01-4b0be5be669cfeaf.wav", + "duration": 4.862625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-02-2e6be19cade105be.wav", + "duration": 3.7735, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-03-b2401eb08aa0a8e8.wav", + "duration": 8.262125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-04-98693ab8c5150fd5.wav", + "duration": 4.158375, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-switch/v2/step-05-a21afc5ebe5af2ee.wav", + "duration": 6.700125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-01-7584e4158566d224.wav", + "duration": 7.2891875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-02-63419c9269e953d9.wav", + "duration": 9.54775, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-03-0ae0974737dbd97d.wav", + "duration": 5.5828125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-04-12baddb3a8f3bc1b.wav", + "duration": 4.5341875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-05-0a5c8ac984f02d75.wav", + "duration": 5.8506875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-06-9a08c1ab2cc3229b.wav", + "duration": 5.9210625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/step-07-35815b60bc24b4e0.wav", + "duration": 10.8363125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-substitute/v3/safety-07-fc1a6a725f992f1a.wav", + "duration": 4.1635625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-01-2de2b12cc45b7893.wav", + "duration": 6.332, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-02-7144daf79c235d5e.wav", + "duration": 6.248, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-03-005e99b68d7d893e.wav", + "duration": 6.6730625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-04-26852f94d435cfca.wav", + "duration": 6.6531875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-05-ddb3fcb704bf7442.wav", + "duration": 2.8734375, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-06-6f9c954385802ccc.wav", + "duration": 6.4815, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-07-32e6e350e9bdf86c.wav", + "duration": 4.5395, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-08-7c3ab1dcf3d277c5.wav", + "duration": 4.7276875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-09-12db6e161d8d1636.wav", + "duration": 6.296875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-10-d8d77b3072c93264.wav", + "duration": 5.0744375, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-pump-replace/v3/step-11-1839ce82fc3e7430.wav", + "duration": 6.130875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-01-ea1da2456af43dba.wav", + "duration": 5.63125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-02-ce4a4236a649cdaa.wav", + "duration": 6.8740625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-03-10e99ab9d685c071.wav", + "duration": 5.735625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-04-637a9a4953c95518.wav", + "duration": 5.2313125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-05-3ec2faf63a53606b.wav", + "duration": 5.5365, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-06-d799ca1e85de6dc1.wav", + "duration": 7.171125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-07-e869fb72d97cc851.wav", + "duration": 5.643875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-08-cb20f78a2b88ab3d.wav", + "duration": 5.082875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-09-16254636cfc9d0c7.wav", + "duration": 5.7695, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-10-44988514081776bc.wav", + "duration": 7.0896875, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-11-c6f8c4d608bf1fa9.wav", + "duration": 16.11125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/safety-11-1cee2dea0fe6a2b9.wav", + "duration": 5.9148125, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-12-990b9ddf6e1b0ced.wav", + "duration": 5.225625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-13-46556532f15bf882.wav", + "duration": 5.853, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-14-b6791d3d51bd7892.wav", + "duration": 7.461, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-15-b22f9eb5e583f7b6.wav", + "duration": 16.2405625, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/safety-15-1cee2dea0fe6a2b9.wav", + "duration": 6.11825, + "sampleRate": 48000 + }, + { + "url": "/legacy/virtual-training/audio/narration/bridge-balance-valve-swap/v3/step-16-20ecc40d88e8c4e0.wav", + "duration": 5.228875, + "sampleRate": 48000 + } + ], + "errors": [] +} \ No newline at end of file diff --git a/reports/bridge-scripted-tasks-20260913/registered.json b/reports/bridge-scripted-tasks-20260913/registered.json index 81fe560..80e7f90 100644 --- a/reports/bridge-scripted-tasks-20260913/registered.json +++ b/reports/bridge-scripted-tasks-20260913/registered.json @@ -15,25 +15,25 @@ "code": "TASK-VIRTUAL-006", "id": "87", "projectId": "439", - "versionId": "516", + "versionId": "530", "name": "重型支援桥液压泵应急替代", "scriptId": "bridge-pump-substitute", - "scriptVersion": "2", + "scriptVersion": "3", "steps": 7, "previewUrl": "/teaching/virtual-training/preview/87", - "presentation": "procedure" + "presentation": "original-3d" }, { "code": "TASK-VIRTUAL-007", "id": "88", "projectId": "440", - "versionId": "517", + "versionId": "531", "name": "重型支援桥前泵换件修复", "scriptId": "bridge-pump-replace", - "scriptVersion": "2", + "scriptVersion": "3", "steps": 11, "previewUrl": "/teaching/virtual-training/preview/88", - "presentation": "procedure" + "presentation": "original-3d" }, { "code": "TASK-VIRTUAL-008", diff --git a/tools/bridge-3d-only-live.mjs b/tools/bridge-3d-only-live.mjs new file mode 100644 index 0000000..9ba873c --- /dev/null +++ b/tools/bridge-3d-only-live.mjs @@ -0,0 +1,98 @@ +import {chromium,expect} from '@playwright/test'; +import assert from 'node:assert/strict'; +import crypto from 'node:crypto'; +import fs from 'node:fs'; +import {login,call} from './role-permissions-live.mjs'; +import {scripts,scriptDefinition} from '../../unreal_tran_web/src/features/virtual-training-scripts/definition.js'; +import {verifyVisualEffects} from './bridge-model-match-assertions.mjs'; + +const dir='reports/bridge-3d-only-20260914';fs.mkdirSync(dir,{recursive:true}); +const root=await login('root'),checks=[],runs=[],errors=[]; +const api=async(path,data,method)=>{const r=await call(path,root.accessToken,data,method);assert.equal(r.status,200,`${path}: ${r.message}`);return r.data;}; +const listed=await api('tran/v1/teaching/assignments?channel=VIRTUAL&assignmentKind=TRAINING&size=100'); +assert.deepEqual(listed.records.map(t=>t.code).sort(),scripts.map(s=>s.code).sort()); +const tasks=scripts.map(script=>listed.records.find(t=>t.code===script.code)); +for(const [i,task] of tasks.entries()){ + assert.equal(task.definitionSnapshot.runtime.scriptVersion,scripts[i].version); + assert.equal(task.executionMode,'PRACTICE');assert.equal(task.status,'PUBLISHED'); + assert.deepEqual(task.definitionSnapshot.steps.map(s=>s.action.mechanism.steps),scriptDefinition(scripts[i]).steps.map(s=>s.action.mechanism.steps)); +} +checks.push('正式列表仅四条原任务,005 v2 三维 / 006–008 v3 三维,均为已发布普通训练'); +const invalid=scriptDefinition(scripts[1]);invalid.runtime.scriptVersion='2'; +const rejected=await call('tran/v1/content/projects',root.accessToken,{type:'TRAINING',name:'拒绝文字版验收',categoryCode:'MAINTENANCE',trainingMode:'VIRTUAL',content:invalid,dependencies:[],assets:[]}); +assert.equal(rejected.status,400,'Backend must reject obsolete text version');checks.push('真实内容接口拒绝旧文字版本,返回 400'); +const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']}); +let userId,page; +const ready=async()=>{await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});await page.waitForTimeout(1500);await expect(page.locator('.bridge-procedure')).toHaveCount(0);}; +const diag=()=>page.evaluate(()=>globalThis.__trainingSceneDiagnostics()); +const saveRuns=()=>fs.writeFileSync(`${dir}/run-fixtures.json`,JSON.stringify({userId,runs},null,2)); +try{ + page=await browser.newPage({viewport:{width:1600,height:1000}}); + await page.addInitScript(s=>sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken),root); + page.on('pageerror',e=>errors.push(e.message)); + await page.goto('http://127.0.0.1:6180/teaching/virtual-training'); + await expect(page.getByPlaceholder('请输入任务名称或编码')).toBeVisible(); + await page.screenshot({path:`${dir}/task-list.png`}); + for(const task of tasks){ + await page.goto(`http://192.168.31.168:6180/teaching/virtual-training/preview/${task.id}`);await ready(); + const bar=page.locator('[data-role="model-commandbar"]'); + for(const action of ['toggle-structure-tree','focus-selected-part','viewer-reset-view','toggle-part-labels','toggle-issue-highlight','toggle-hide-others','toggle-explosion'])await expect(bar.locator(`[data-action="${action}"]`)).toBeVisible(); + await page.screenshot({path:`${dir}/${task.code}-original-preview.png`}); + checks.push(`${task.code} 原任务 ${task.id} 局域网预览加载三维模型与完整工具栏`); + } + await page.close(); + const roles=await api('auth/v1/roles/all'),role=(roles.records||roles).find(r=>r.code==='student'); + const password='Br!'+crypto.randomBytes(8).toString('hex'); + const created=await api('auth/v1/users',{username:'bridge_final_'+Date.now().toString(36),password,displayName:'桥梁三维迁移验收',departmentId:'5',roleIds:[role.id],defaultRoleId:role.id,enabled:true,remark:'临时验收账号'}); + userId=(created.user||created).id;saveRuns(); + const signed=await call('auth/v1/auth/login',null,{userId,password,roleCode:'student',rememberMe:false});assert.equal(signed.status,200); + const learner=async(path,data)=>{const r=await call('tran/v1/'+path,signed.data.accessToken,data);assert.equal(r.status,200,`${path}: ${r.message}`);return r.data;}; + page=await browser.newPage({viewport:{width:1600,height:1000}}); + await page.addInitScript(s=>sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken),signed.data); + page.on('pageerror',e=>errors.push(e.message)); + for(const task of tasks){ + let run=await learner(`teaching/assignments/${task.id}/accept`,{assignmentVersion:task.version,teamCode:'NEUTRAL',positionCode:'LEARNER'}); + runs.push({taskId:task.id,runId:run.id,code:task.code});saveRuns(); + await page.goto(`http://127.0.0.1:6180/teaching/virtual-training/runs/${run.id}`);await ready(); + const workshop=task.code!=='TASK-VIRTUAL-005'; + for(let i=0;i(await diag()).bridgeWorkshop.operation.targetId).toBe(ops[k].targetId); + if(i===0&&k===ops.length-1&&task.code==='TASK-VIRTUAL-006'){ + await page.route(`**/teaching/runs/${run.id}/progress`,r=>r.fulfill({status:503,contentType:'application/json',body:JSON.stringify({code:'SERVICE_UNAVAILABLE',message:'验收模拟保存失败'})}),{times:1}); + const response=page.waitForResponse(r=>r.url().includes(`/runs/${run.id}/progress`));await page.locator('[data-role="part-label"]').click();assert.equal((await response).status(),503); + await expect.poll(async()=>(await diag()).bridgeWorkshop.pending).toBe(false);assert.equal((await learner(`teaching/runs/${run.id}`)).progressPercent,0); + await expect(page.locator('[data-action="next"]')).toBeDisabled();checks.push('正式 006 保存失败不推进,重试后才保存'); + } + if(k===ops.length-1){const response=page.waitForResponse(r=>r.url().includes(`/runs/${run.id}/progress`));await page.locator('[data-role="part-label"]').click();assert.equal((await response).status(),200);} + else {await page.locator('[data-role="part-label"]').click();if(workshop)await expect.poll(async()=>(await diag()).bridgeWorkshop.operationIndex).toBe(k+1);else await page.waitForTimeout(1200);} + if(workshop)await verifyVisualEffects(page,ops[k]); + } + await expect(page.locator('[data-action="next"]')).toBeEnabled(); + assert.equal((await learner(`teaching/runs/${run.id}/steps`)).filter(s=>s.statusCode==='COMPLETED').length,i+1); + if(i===3){ + const before=workshop?(await diag()).bridgeWorkshop.targets:null; + await page.reload();await ready(); + if(before){const after=(await diag()).bridgeWorkshop.targets;for(const b of before){const a=after.find(t=>t.id===b.id);assert.equal(a.visible,b.visible);assert.ok(a.position.every((v,k)=>Math.abs(v-b.position[k])<.001),`Restore ${b.id}`);}} + checks.push(`${task.code} 刷新恢复服务端步骤及拆装状态`); + }else if(i(await learner(`teaching/runs/${run.id}`)).status).toBe('SUBMITTED'); + run=await learner(`teaching/runs/${run.id}`);assert.equal(run.score,null); + run=await api(`tran/v1/teaching/runs/${run.id}/review`,{version:run.version,commandId:crypto.randomUUID(),score:85,passed:true,feedback:'临时自动化验收评分',rubric:{testFixture:true}}); + assert.equal((await learner(`teaching/runs/${run.id}`)).score,85); + const records=await api(`tran/v1/teaching/analytics/records?userId=${userId}&channel=VIRTUAL&assignmentKind=TRAINING&size=100`); + assert.ok(records.records.some(r=>String(r.runId||r.id)===run.id)); + await page.reload();await ready();await expect(page.locator('.virtual-server-status')).toContainText('85');await page.screenshot({path:`${dir}/${task.code}-reviewed.png`}); + checks.push(`${task.code} ${task.definitionSnapshot.steps.length} 步完成、提交、评定 85 分与统计通过`); + } + assert.deepEqual(errors,[]);fs.writeFileSync(`${dir}/acceptance.json`,JSON.stringify({pass:true,checks,errors,runs},null,2)); +}catch(e){await page?.screenshot({path:`${dir}/failure.png`}).catch(()=>{});fs.writeFileSync(`${dir}/acceptance.json`,JSON.stringify({pass:false,error:e.message,checks,errors,runs},null,2));throw e;} +finally{await browser.close();saveRuns();if(userId){const user=await api(`auth/v1/users/${userId}`);await api(`auth/v1/users/${userId}`,{version:user.version},'DELETE');}} diff --git a/tools/bridge-digital-video-bind.mjs b/tools/bridge-digital-video-bind.mjs new file mode 100644 index 0000000..351e5ca --- /dev/null +++ b/tools/bridge-digital-video-bind.mjs @@ -0,0 +1,59 @@ +import fs from 'node:fs'; +import assert from 'node:assert/strict'; +import { login, call } from './role-permissions-live.mjs'; +import manifest from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-manifest.js'; +const dir = 'reports/bridge-digital-video-20260914'; +const generated = JSON.parse(fs.readFileSync(`${dir}/generation.json`, 'utf8')); +const session = await login('root'); +const api = async (path, body, method) => { + const r = await call(`tran/v1/${path}`, session.accessToken, body, method); + assert.equal(r.status, 200, `${path}: ${r.message}`); return r.data; +}; +const assignments = (await api('teaching/assignments?channel=VIRTUAL&assignmentKind=TRAINING&size=100')).records; +const codes = process.argv.slice(2); +for (const pack of manifest.scripts.filter(p => !codes.length || codes.includes(p.code))) { + const clips = generated.clips.filter(c => c.code === pack.code); + assert.equal(clips.length, pack.steps.length); assert.ok(clips.every(c => c.status === 'SUCCEEDED')); + let task = assignments.find(t => t.code === pack.code); + let detail = await api(`content/projects/${task.contentProjectId}`); + const backup = `${dir}/${pack.code}-before.json`; + if (!fs.existsSync(backup)) fs.writeFileSync(backup, JSON.stringify({ task, detail, + runs: await api(`teaching/runs?assignmentId=${task.id}&size=100`) }, null, 2)); + const content = structuredClone(detail.currentVersion.content), assets = [...detail.currentVersion.assets]; + let changed = false; + for (const step of content.steps) { + const clip = clips.find(c => c.stepCode === (step.stepCode || step.id)); assert.ok(clip); + const existing = assets.find(a => a.code === step.audio?.narrationVideoAssetCode && String(a.metadata?.sourceVideoId) === clip.videoId); + if (existing) continue; + const asset = await api(`content/projects/${task.contentProjectId}/digital-human/videos/${clip.videoId}/import`, + { version: detail.project.version, name: clip.title, appId: clip.appId }); + assets.push(asset); + step.audio = { ...step.audio, narrationSource: 'digital-generate', narrationText: clip.text, + narrationUrl: '', narrationAssetCode: '', narrationVideoAssetCode: asset.code, + digitalHuman: { enabled: true, mode: 'video', videoSource: 'library', videoId: clip.videoId, + videoName: clip.title, appId: clip.appId, videoUrl: '', generatedVideoUrl: '', generationStatus: 'generated' } }; + changed = true; + console.log('IMPORTED', pack.code, clip.number, asset.code); + } + if (changed) { + detail = await api(`content/projects/${task.contentProjectId}`, { ...detail.project, content, + dependencies: detail.currentVersion.dependencies, assets, changeSummary: '39段数字人视频讲解;原语音保留可切换' }, 'PUT'); + } + if (detail.project.currentVersionStatus !== 'PUBLISHED') { + await api(`content/projects/${task.contentProjectId}/publish`, { version: detail.project.version }); + detail = await api(`content/projects/${task.contentProjectId}`); + } + if (task.contentVersionId !== detail.project.publishedVersionId) { + task = await api(`teaching/assignments/${task.id}/narration`, { version: task.version, + contentVersionId: detail.project.publishedVersionId, reason: '补充逐步数字人讲解视频,保留原语音,训练操作和评分不变' }, 'PUT'); + } + const original = JSON.parse(fs.readFileSync(backup, 'utf8')); + const runs = await api(`teaching/runs?assignmentId=${task.id}&size=100`); + const stableRuns = value => JSON.parse(JSON.stringify(value, (key, item) => key === 'serverNow' ? undefined : item)); + assert.deepEqual(stableRuns(runs), stableRuns(original.runs), 'Existing training runs must not change'); + const result = { code: pack.code, taskId: task.id, contentVersionId: task.contentVersionId, + clips: task.definitionSnapshot.steps.map(s => ({ stepCode: s.stepCode, videoAssetCode: s.audio.narrationVideoAssetCode })), + runsUnchanged: true, assets: await api(`teaching/assignments/${task.id}/assets`) }; + fs.writeFileSync(`${dir}/${pack.code}-binding.json`, JSON.stringify(result, null, 2)); + console.log('BOUND', pack.code, task.contentVersionId, result.clips.length); +} diff --git a/tools/bridge-digital-video-generate.mjs b/tools/bridge-digital-video-generate.mjs new file mode 100644 index 0000000..b9f582d --- /dev/null +++ b/tools/bridge-digital-video-generate.mjs @@ -0,0 +1,55 @@ +import fs from 'node:fs'; +import assert from 'node:assert/strict'; +import { login, call } from './role-permissions-live.mjs'; +import narration from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-manifest.js'; + +const dir = 'reports/bridge-digital-video-20260914'; fs.mkdirSync(dir, { recursive: true }); +const manifestPath = `${dir}/generation.json`; +const progress = fs.existsSync(manifestPath) ? JSON.parse(fs.readFileSync(manifestPath, 'utf8')) : { avatarId: '55', avatarName: '教员1', voiceId: '49', voiceName: '温和男声', clips: [] }; +const save = () => fs.writeFileSync(manifestPath, JSON.stringify(progress, null, 2)); +let session = await login('root'); +const api = async (path, data, method) => { + let r = await call(`tran/v1/${path}`, session.accessToken, data, method); + if (r.status === 401) { session = await login('root'); r = await call(`tran/v1/${path}`, session.accessToken, data, method); } + assert.equal(r.status, 200, `${path}: ${r.message}`); return r.data; +}; +const assignments = (await api('teaching/assignments?channel=VIRTUAL&assignmentKind=TRAINING&size=100')).records; +const limit = process.argv.includes('--all') ? 39 : 1; +let count = 0; +for (const script of narration.scripts) { + const task = assignments.find(t => t.code === script.code); assert.ok(task); + for (const step of script.steps) { + if (count++ >= limit) break; + const key = `${script.id}:${script.version}:${step.stepCode}`; + let clip = progress.clips.find(c => c.key === key); + if (!clip) { + const detail = await api(`content/projects/${task.contentProjectId}`); + const generation = { title: `${script.title} · ${step.number} ${step.expectedTitle}`.slice(0, 120), text: step.text, + avatarId: progress.avatarId, voiceId: progress.voiceId, backgroundId: null, speed: .85, width: 480, height: 640, subtitles: false }; + const job = await api(`content/projects/${task.contentProjectId}/digital-human/jobs`, { version: detail.project.version, stepId: step.stepCode, + requestKey: `bridge-video-20260914-${script.code}-${step.number}`, generation }); + clip = { key, code: script.code, projectId: task.contentProjectId, assignmentId: task.id, stepCode: step.stepCode, + number: step.number, title: generation.title, text: step.text, jobId: job.id, appId: job.appId, status: job.status }; + progress.clips.push(clip); save(); + } + if (clip.status !== 'SUCCEEDED') { + const deadline = Date.now() + 15 * 60000; + while (Date.now() < deadline) { + const job = await api(`content/projects/${clip.projectId}/digital-human/jobs/${clip.jobId}`); + Object.assign(clip, { status: job.status, stage: job.stage, videoId: job.videoId, errorMessage: job.errorMessage }); save(); + if (job.status === 'SUCCEEDED') break; + if (['FAILED', 'CANCELLED'].includes(job.status)) throw new Error(`${clip.code} ${clip.number}: ${job.errorMessage}`); + console.log(clip.code, clip.number, job.status, job.stage); + await new Promise(resolve => setTimeout(resolve, 5000)); + } + assert.equal(clip.status, 'SUCCEEDED', 'Generation timeout'); + } + const output = `${dir}/${clip.code}-step-${String(clip.number).padStart(2, '0')}.mp4`; + if (!fs.existsSync(output)) { + const r = await fetch(`http://127.0.0.1:6180/api/tran/v1/content/digital-human/videos/${clip.videoId}/preview`, + { headers: { Authorization: `Bearer ${session.accessToken}` }, signal: AbortSignal.timeout(180000) }); + assert.equal(r.status, 200); fs.writeFileSync(output, Buffer.from(await r.arrayBuffer())); + } + clip.previewFile = output; save(); console.log('READY', clip.code, clip.number, clip.videoId); + } +} diff --git a/tools/bridge-digital-video-live.mjs b/tools/bridge-digital-video-live.mjs new file mode 100644 index 0000000..7331b7e --- /dev/null +++ b/tools/bridge-digital-video-live.mjs @@ -0,0 +1,97 @@ +import { chromium, expect } from '@playwright/test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import { login, call } from './role-permissions-live.mjs'; +import manifest from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-manifest.js'; +import videos from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-video-manifest.js'; +const staticMode = process.env.NARRATION_STATIC === '1'; +const dir = process.env.REPORT_DIR || 'reports/bridge-digital-video-20260914'; +fs.mkdirSync(dir, { recursive: true }); +const origin = process.env.BASE_URL || 'http://127.0.0.1:6180'; +const root = await login('root'); +const response = await call('tran/v1/teaching/assignments?channel=VIRTUAL&assignmentKind=TRAINING&size=100', root.accessToken); +assert.equal(response.status, 200); +const codes = process.argv.slice(2); +const packs = manifest.scripts.filter(p => !codes.length || codes.includes(p.code)); +const browser = await chromium.launch({ channel: 'msedge', headless: true, args: ['--enable-unsafe-swiftshader'] }); +const results = [], errors = [], requests = []; +let page; +try { + page = await browser.newPage({ viewport: { width: 1600, height: 1000 } }); + await page.addInitScript(token => { + sessionStorage.setItem('unreal-tran:web:access-token:v1', token); + localStorage.setItem('unreal-tran:web:preferences:v1', JSON.stringify({ themeMode: 'military' })); + }, root.accessToken); + page.on('pageerror', e => errors.push(e.message)); + page.on('request', request => requests.push(new URL(request.url()).pathname)); + const ready = async () => { + await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/, { timeout: 120000 }); + await expect(page.locator('[data-role="step-count"]')).toBeVisible(); + }; + const media = page.locator('.training-server-video'); + const play = async () => { + if (await page.locator('[data-role="teacher-launch"]').isVisible()) await page.locator('[data-role="teacher-launch"]').click(); + await page.locator('[data-action="teacher-speak"]').click(); + await expect(media).toBeVisible(); + await expect.poll(() => media.evaluate(v => v.currentTime), { timeout: 15000 }).toBeGreaterThan(.1); + assert.equal(await media.evaluate(v => v.error), null); + assert.ok(await media.evaluate(v => v.videoWidth === 480 && v.videoHeight === 640)); + }; + for (const pack of packs) { + const task = response.data.records.find(t => t.code === pack.code); assert.ok(task); + const videoPack = staticMode ? videos.scripts.find(item => item.id === pack.id && item.version === pack.version) : null; + const obsoleteDownloads = []; + if (staticMode) { + assert.equal(videoPack.steps.length, pack.steps.length); + const assets = await call(`tran/v1/teaching/assignments/${task.id}/assets`, root.accessToken); + assert.equal(assets.status, 200); + const replaced = new Set(task.definitionSnapshot.steps.map(step => step.audio?.narrationVideoAssetCode?.toUpperCase()).filter(Boolean)); + for (const asset of assets.data) if (asset.sourceVersionId === task.contentVersionId && replaced.has(asset.assetCode.toUpperCase())) { + obsoleteDownloads.push(new URL(asset.downloadUrl, origin).pathname); + } + requests.length = 0; + } + await page.goto(`${origin}/teaching/virtual-training/preview/${task.id}`); + await ready(); await play(); + if (staticMode) assert.equal(await media.evaluate(v => new URL(v.currentSrc).pathname), videoPack.steps[0].url); + assert.equal(await page.locator('[data-role="teacher-image"]').evaluate(e => getComputedStyle(e).visibility), 'hidden'); + await page.screenshot({ path: `${dir}/${task.code}-video.png` }); + const button = page.locator('[data-action="toggle-teacher-media"]'); + await button.click(); + await expect(media).toBeHidden(); + await expect.poll(() => media.evaluate(v => new URL(v.currentSrc || v.src, location.href).pathname)).toBe(pack.steps[0].url); + await expect.poll(() => media.evaluate(v => v.currentTime)).toBeGreaterThan(.1); + await button.click(); await expect(media).toBeVisible(); + const voice = page.locator('[data-action="toggle-teacher-voice"]'); + if (await voice.getAttribute('aria-pressed') === 'true') await voice.click(); + for (let op = 0; op < task.definitionSnapshot.steps[0].action.mechanism.steps.length; op++) { + await page.locator('[data-role="part-label"]').click(); + if (pack.code !== 'TASK-VIRTUAL-005') await expect.poll(() => page.evaluate(() => globalThis.__trainingSceneDiagnostics().bridgeWorkshop.pending)).toBe(false); + else await page.waitForTimeout(1800); + } + await expect(page.locator('[data-action="next"]')).toBeEnabled({ timeout: 20000 }); + await play(); const first = await media.getAttribute('src'); + await page.locator('[data-action="next"]').click(); + await expect(page.locator('[data-role="step-count"]')).toHaveText(`2 / ${pack.steps.length}`); + assert.equal(await media.evaluate(v => v.paused), true); + await play(); assert.notEqual(await media.getAttribute('src'), first); + if (staticMode) assert.equal(await media.evaluate(v => new URL(v.currentSrc).pathname), videoPack.steps[1].url); + await media.evaluate(v => { v.src = 'data:video/mp4;base64,AA=='; v.load(); }); + await expect(media).toBeHidden(); + await expect.poll(() => media.evaluate(v => new URL(v.currentSrc || v.src, location.href).pathname)).toBe(pack.steps[1].url); + await expect.poll(() => media.evaluate(v => v.currentTime)).toBeGreaterThan(.1); + await page.reload(); await ready(); await play(); + await page.locator('.training-teacher-bubble [data-action="toggle-teacher"]').click(); + assert.equal(await media.evaluate(v => v.paused), true); + if (staticMode) assert.deepEqual(requests.filter(url => obsoleteDownloads.includes(url)), [], 'Static narration must not download obsolete video assets'); + results.push({ code: pack.code, firstAndSecondVideo: true, audioToggle: true, stopOnStepChange: true, errorFallback: true, reloadAndClose: true, + ...(staticMode ? { staticVideoUrls: videoPack.steps.slice(0, 2).map(clip => clip.url), obsoleteAssetDownloads: 0 } : {}) }); + console.log('PASS', pack.code); + } + assert.deepEqual(errors, []); + fs.writeFileSync(`${dir}/${origin.includes('127.0.0.1') ? 'live' : 'lan'}-result.json`, JSON.stringify({ origin, results, errors }, null, 2)); +} catch (error) { + if (page) await page.screenshot({ path: `${dir}/failure.png` }).catch(() => {}); + fs.writeFileSync(`${dir}/failure.json`, JSON.stringify({ message: error.message, results, errors }, null, 2)); + throw error; +} finally { await browser.close(); } diff --git a/tools/bridge-digital-video-refresh.py b/tools/bridge-digital-video-refresh.py new file mode 100644 index 0000000..96e5ba9 --- /dev/null +++ b/tools/bridge-digital-video-refresh.py @@ -0,0 +1,77 @@ +"""Regenerate revised lecture text with the approved v2 avatar; retain prior media.""" +from pathlib import Path +import hashlib +import importlib.util +import json +import subprocess +import threading + +import requests + +spec = importlib.util.spec_from_file_location('render_static', Path(__file__).with_name('bridge-digital-video-static-generate.py')) +render = importlib.util.module_from_spec(spec) +spec.loader.exec_module(render) +ROOT, WEB = render.ROOT, render.WEB +REPORT = ROOT / 'unreal_tran/ute2e/reports/bridge-lecture-polish-20260915' + + +def read_manifest(name): + command = f"import m from './src/features/virtual-training-scripts/{name}.js';console.log(JSON.stringify(m))" + return json.loads(subprocess.check_output(['node', '--input-type=module', '-e', command], cwd=WEB, encoding='utf-8')) + + +def main(): + REPORT.mkdir(parents=True, exist_ok=True) + speech, videos = read_manifest('narration-manifest'), read_manifest('narration-video-manifest') + backup = REPORT / 'before-video-manifest.json' + if not backup.exists(): render.write_json(backup, videos) + settings = render.get_settings() + avatar = videos['profile']['providerAvatarId'] + http = requests.Session(); http.trust_env = False + response = http.get(str(settings.service_base_url).rstrip('/') + f'/api/v1/avatars/{avatar}/assets/manifest.json', timeout=30) + response.raise_for_status() + assert hashlib.sha256(response.content).hexdigest() == videos['profile']['avatarManifestSha256'] + progress_file = REPORT / 'regenerated.json' + progress = json.loads(progress_file.read_text('utf-8')) if progress_file.exists() else [] + worker = render.OpenGenerationWorker(None, settings, None, None) + for pack in speech['scripts']: + target = next(p for p in videos['scripts'] if p['id'] == pack['id'] and p['version'] == pack['version']) + for clip in pack['steps']: + previous = next(c for c in target['steps'] if c['stepCode'] == clip['stepCode']) + assert previous['expectedTitle'] == clip['expectedTitle'] and previous['expectedInstruction'] == clip['expectedInstruction'] + if previous['text'] == clip['text']: + assert render.digest(WEB / 'public' / previous['url'].lstrip('/')) == previous['sha256'] + continue + audio = WEB / 'public' / clip['url'].lstrip('/') + assert render.digest(audio) == clip['stepSha256'] + signature = hashlib.sha256(json.dumps([videos['profile'], clip['stepSha256'], clip['text']], sort_keys=True, ensure_ascii=False).encode()).hexdigest()[:16] + url = f"/legacy/virtual-training/videos/narration/{pack['id']}/v{pack['version']}/instructor-1-v2/step-{clip['number']:02}-{signature}.mp4" + output = WEB / 'public' / url.lstrip('/') + entry = next((p for p in progress if p['url'] == url), None) + if not entry or not output.exists() or render.digest(output) != entry['sha256']: + print(f"Rendering {pack['code']} step {clip['number']}: {clip['text']}", flush=True) + captured = REPORT / 'capture.webm' + command = render.GenerationCommand(title=f"{pack['title']} · 第{clip['number']}步", text=clip['text'], + avatarId='55', voiceId='49', speed=.85, width=480, height=640, subtitles=False) + worker.capture(command, avatar, audio, None, captured, threading.Event()) + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', '-y', '-i', str(captured), + '-r', '25', '-c:v', 'libx264', '-preset', 'veryfast', '-crf', '20', '-pix_fmt', 'yuv420p', + '-c:a', 'aac', '-b:a', '128k', '-movflags', '+faststart', str(output)], check=True) + duration = render.validate(settings, output, clip['stepDuration']) + entry = {'code': pack['code'], 'stepCode': clip['stepCode'], 'number': clip['number'], 'text': clip['text'], + 'url': url, 'sha256': render.digest(output), 'duration': duration, 'audioSha256': clip['stepSha256'], + 'previousUrl': previous['url'], 'previousSha256': previous['sha256']} + progress.append(entry); render.write_json(progress_file, progress) + else: render.validate(settings, output, clip['stepDuration']) + previous.update({key: entry[key] for key in ('text', 'url', 'sha256', 'duration')}) + print(f"Verified {pack['code']} step {clip['number']}", flush=True) + target = WEB / 'src/features/virtual-training-scripts/narration-video-manifest.js' + temporary = target.with_suffix('.js.tmp') + temporary.write_text('// Generated by bridge-digital-video-static-generate.py; revised by bridge-digital-video-refresh.py.\nexport default ' + json.dumps(videos, ensure_ascii=False, indent=2) + ';\n', encoding='utf-8') + temporary.replace(target) + render.write_json(REPORT / 'video-manifest.json', videos) + render.write_json(REPORT / 'narration-manifest.json', speech) + print(json.dumps({'regenerated': len(progress), 'total': sum(len(p['steps']) for p in videos['scripts']), 'previousFilesPreserved': True}), flush=True) + + +if __name__ == '__main__': main() diff --git a/tools/bridge-digital-video-report.mjs b/tools/bridge-digital-video-report.mjs new file mode 100644 index 0000000..6decb0a --- /dev/null +++ b/tools/bridge-digital-video-report.mjs @@ -0,0 +1,34 @@ +import fs from 'node:fs'; +import crypto from 'node:crypto'; +import { execFileSync } from 'node:child_process'; +import assert from 'node:assert/strict'; +import { login, call } from './role-permissions-live.mjs'; +const dir = 'reports/bridge-digital-video-20260914'; +const generation = JSON.parse(fs.readFileSync(`${dir}/generation.json`, 'utf8')); +assert.equal(generation.clips.length, 39); assert.ok(generation.clips.every(c => c.status === 'SUCCEEDED')); +const root = await login('root'), verified = []; +for (const code of ['TASK-VIRTUAL-005', 'TASK-VIRTUAL-006', 'TASK-VIRTUAL-007', 'TASK-VIRTUAL-008']) { + const binding = JSON.parse(fs.readFileSync(`${dir}/${code}-binding.json`, 'utf8')); + const task = (await call(`tran/v1/teaching/assignments/${binding.taskId}`, root.accessToken)).data; + for (const clip of generation.clips.filter(c => c.code === code)) { + const step = task.definitionSnapshot.steps.find(s => s.stepCode === clip.stepCode); + assert.equal(step.audio.narrationText, clip.text); + const asset = binding.assets.find(a => a.assetCode === step.audio.narrationVideoAssetCode); assert.ok(asset); + const response = await fetch(`http://127.0.0.1:6180${asset.downloadUrl}`, { headers: { Authorization: `Bearer ${root.accessToken}` } }); + assert.equal(response.status, 200); + const bytes = Buffer.from(await response.arrayBuffer()); + const sha = value => crypto.createHash('sha256').update(value).digest('hex'); + assert.equal(sha(bytes), asset.sha256); assert.equal(sha(bytes), sha(fs.readFileSync(clip.previewFile))); + const probe = JSON.parse(execFileSync('ffprobe', ['-v', 'error', '-show_streams', '-show_format', '-of', 'json', clip.previewFile], { encoding: 'utf8' })); + const video = probe.streams.find(s => s.codec_type === 'video'), audio = probe.streams.find(s => s.codec_type === 'audio'); + assert.equal(video.codec_name, 'h264'); assert.equal(video.width, 480); assert.equal(video.height, 640); + assert.equal(audio.codec_name, 'aac'); assert.ok(Number(probe.format.duration) > 1); + verified.push({ code, step: clip.number, assetCode: asset.assetCode, sha256: asset.sha256, duration: Number(probe.format.duration), size: bytes.length }); + } + console.log('VERIFIED', code); +} +const summary = { videos: verified.length, duration: verified.reduce((n, v) => n + v.duration, 0), size: verified.reduce((n, v) => n + v.size, 0), preservedWavs: 42, verified }; +fs.writeFileSync(`${dir}/verification.json`, JSON.stringify(summary, null, 2)); +const escape = s => String(s).replace(/[&<>"']/g, c => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c])); +fs.writeFileSync(`${dir}/index.html`, `四套桥梁训练数字人讲解验收

四套桥梁训练 · 数字人视频讲解

39 段竖版人物视频,合计 ${summary.duration.toFixed(1)} 秒;原 39 段步骤语音和 3 段提醒完整保留。正式任务 86–89 使用发布内容版本的受控 VIDEO 资产。已核对全部视频的步骤讲解词、下载哈希及 H.264/AAC 编码。

讲解面板可切换视频/语音。切步、关闭时停止播放,视频异常自动回退原语音。历史内容版本保留,已有运行、成绩及检查点未修改。

浏览器操作验证 · 全部资源核验 · 正式运行资产/版本保护验证

${['TASK-VIRTUAL-005','TASK-VIRTUAL-006','TASK-VIRTUAL-007','TASK-VIRTUAL-008'].map(code => { const clips = generation.clips.filter(c=>c.code===code); return `

${code} · ${clips.length} 段

${clips.map(c=>``).join('')}
步骤讲解词视频
${c.number}${escape(c.text)}播放
`; }).join('')}
`); +console.log('PASS', summary.videos, 'videos', summary.duration.toFixed(1), 'seconds'); diff --git a/tools/bridge-digital-video-static-delivery.mjs b/tools/bridge-digital-video-static-delivery.mjs new file mode 100644 index 0000000..f3259b6 --- /dev/null +++ b/tools/bridge-digital-video-static-delivery.mjs @@ -0,0 +1,66 @@ +// Verify project/build copies and browser delivery without requiring avatar services. +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import { createHash } from 'node:crypto'; +import { fileURLToPath } from 'node:url'; +import { spawnSync } from 'node:child_process'; +import videos from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-video-manifest.js'; +import speech from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-manifest.js'; + +const root = new URL('../../', import.meta.url); +const report = new URL('ute2e/reports/bridge-digital-video-static-20260915/', root); +const sha = data => createHash('sha256').update(data).digest('hex'); +const generated = JSON.parse(fs.readFileSync(new URL('generation.json', report), 'utf8')); +const original = JSON.parse(fs.readFileSync(new URL('ute2e/reports/bridge-digital-video-20260914/generation.json', root), 'utf8')); +const clips = videos.scripts.flatMap(script => script.steps); +assert.equal(clips.length, 39); +const preview = new URL('index.html', report); +const previewLinks = [...fs.readFileSync(preview, 'utf8').matchAll(/]+src="([^"]+)"/g)]; +assert.equal(previewLinks.length, 39); +for (const [, link] of previewLinks) assert.ok(fs.existsSync(new URL(link, preview)), `Broken preview ${link}`); +const origins = ['http://127.0.0.1:6180', process.env.LAN_URL || 'http://192.168.31.168:6180']; +const checks = []; +for (const origin of origins) { + for (const clip of clips) { + const response = await fetch(origin + clip.url, { signal: AbortSignal.timeout(30000) }); + assert.equal(response.status, 200, `${origin} ${clip.url}`); + assert.match(response.headers.get('content-type'), /video\/mp4/); + assert.equal(sha(Buffer.from(await response.arrayBuffer())), clip.sha256); + } + const range = await fetch(origin + clips[0].url, { headers: { Range: 'bytes=0-1023' }, signal: AbortSignal.timeout(30000) }); + assert.equal(range.status, 206); + assert.equal((await range.arrayBuffer()).byteLength, 1024); + checks.push({ origin, playableUrls: clips.length, exactFiles: true, rangeRequests: true }); +} +const audioChecks = []; +for (const clip of clips) { + const file = fs.readFileSync(new URL(`unreal_tran_web/dist${clip.url}`, root)); + assert.equal(sha(file), clip.sha256, `Missing or stale build file ${clip.url}`); + const volume = spawnSync(process.env.FFMPEG_BINARY || 'ffmpeg', ['-hide_banner', '-nostdin', + '-i', fileURLToPath(new URL(`unreal_tran_web/public${clip.url}`, root)), '-map', '0:a:0', + '-af', 'volumedetect', '-f', 'null', '-'], { encoding: 'utf8', windowsHide: true, timeout: 30000 }); + assert.equal(volume.status, 0); + const mean = Number(volume.stderr.match(/mean_volume:\s*(-?\d+(?:\.\d+)?)\s*dB/)?.[1]); + assert.ok(Number.isFinite(mean) && mean > -70, `Silent narration ${clip.url}`); + audioChecks.push({ url: clip.url, meanVolumeDb: mean }); +} +for (const source of original.clips) { + const record = generated.clips.find(clip => clip.key === source.key); + assert.equal(sha(fs.readFileSync(new URL(`ute2e/${source.previewFile}`, root))), record.sourceVideoSha256); +} +let preservedWavs = 0; +for (const script of speech.scripts) for (const clip of script.steps) { + for (const [url, hash] of [[clip.url, clip.stepSha256], [clip.safetyUrl, clip.safetySha256]]) { + if (!url) continue; + assert.equal(sha(fs.readFileSync(new URL(`unreal_tran_web/public${url}`, root))), hash); + preservedWavs++; + } +} +const result = { clips: clips.length, checks, buildFilesVerified: clips.length, + audibleNarrations: audioChecks, + originalVideosPreserved: original.clips.length, originalWavsPreserved: preservedWavs, + totalDuration: Number(clips.reduce((sum, clip) => sum + clip.duration, 0).toFixed(2)), + totalBytes: clips.reduce((sum, clip) => sum + fs.statSync(new URL(`unreal_tran_web/public${clip.url}`, root)).size, 0), + taskDataMutated: false }; +fs.writeFileSync(new URL('delivery-validation.json', report), JSON.stringify(result, null, 2)); +console.log(JSON.stringify({ ...result, audibleNarrations: audioChecks.length, report: fileURLToPath(new URL('delivery-validation.json', report)) })); diff --git a/tools/bridge-digital-video-static-generate.py b/tools/bridge-digital-video-static-generate.py new file mode 100644 index 0000000..bb24f00 --- /dev/null +++ b/tools/bridge-digital-video-static-generate.py @@ -0,0 +1,162 @@ +"""Render the 39 approved bridge narrations into the web project's public directory. + +Run with the digital-human API's Python environment and working directory. Uses +the same capture/encoding as the approved v2 sample, without creating DB assets. +Completed clips are checksum-verified on resume. Original videos/WAVs stay intact. +""" +from pathlib import Path +import hashlib +import html +import json +import shutil +import subprocess +import sys +import threading + +import requests + +ROOT = Path(__file__).resolve().parents[3] +WEB = ROOT / 'unreal_tran/unreal_tran_web' +REPORT = ROOT / 'unreal_tran/ute2e/reports/bridge-digital-video-static-20260915' +SAMPLE = REPORT.parent / 'bridge-digital-video-v2-sample-20260915' +sys.path.insert(0, str(ROOT / 'ai_person/ai_person_api')) +from app.config import get_settings +from app.schemas.open_platform import GenerationCommand +from app.services.open_generation_worker import OpenGenerationWorker + + +def digest(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def write_json(path, value): + temporary = path.with_suffix(path.suffix + '.tmp') + temporary.write_text(json.dumps(value, ensure_ascii=False, indent=2) + '\n', encoding='utf-8') + temporary.replace(path) + + +def probe(settings, path): + result = subprocess.run([settings.ffprobe_binary, '-v', 'error', '-show_format', + '-show_streams', '-of', 'json', str(path)], check=True, + capture_output=True, encoding='utf-8') + return json.loads(result.stdout) + + +def validate(settings, path, source_duration): + info = probe(settings, path) + video = next(s for s in info['streams'] if s['codec_type'] == 'video') + audio = next(s for s in info['streams'] if s['codec_type'] == 'audio') + assert (video['codec_name'], video['width'], video['height'], video['r_frame_rate']) == ('h264', 480, 640, '25/1') + assert audio['codec_name'] == 'aac' + duration = float(info['format']['duration']) + assert abs(duration - source_duration) < .5, (path, duration, source_duration) + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', + '-i', str(path), '-f', 'null', '-'], check=True, capture_output=True) + return duration + + +def main(): + REPORT.mkdir(parents=True, exist_ok=True) + settings = get_settings() + voice = json.loads(subprocess.run(['node', '--input-type=module', '-e', + "import m from './src/features/virtual-training-scripts/narration-manifest.js';console.log(JSON.stringify(m))"], + cwd=WEB, check=True, capture_output=True, encoding='utf-8').stdout) + old = json.loads((REPORT.parent / 'bridge-digital-video-20260914/generation.json').read_text('utf-8')) + old_by_key = {clip['key']: clip for clip in old['clips']} + avatar = 'a1000000000000000000000000000005' + http = requests.Session() + http.trust_env = False + response = http.get(str(settings.service_base_url).rstrip('/') + f'/api/v1/avatars/{avatar}/assets/manifest.json', timeout=30) + response.raise_for_status() + bundle = json.loads((ROOT / 'ai_person/ai_person_service/builtin_avatars/instructors-v2.json').read_text('utf-8'))['instructors'][0] + avatar_hash = hashlib.sha256(response.content).hexdigest() + assert avatar_hash == bundle['bundle_sha256']['manifest.json'], 'Live avatar does not match approved v2' + sample = json.loads((SAMPLE / 'result.json').read_text('utf-8')) + assert sample['providerAvatarId'] == avatar and sample['materialVersion'] == 'v2' + profile = {'avatarName': '教员1', 'materialVersion': 'v2', 'providerAvatarId': avatar, + 'avatarManifestSha256': avatar_hash, 'renderer': 'OpenGenerationWorker.capture', + 'width': 480, 'height': 640, 'fps': 25, 'videoCodec': 'h264', 'audioCodec': 'aac', + 'encoding': 'libx264 veryfast crf20 yuv420p / aac 128k faststart', + 'audioSource': 'existing step narration, unchanged'} + manifest = {'profile': profile, 'scripts': []} + progress_file = REPORT / 'generation.json' + progress = json.loads(progress_file.read_text('utf-8')) if progress_file.exists() else {'profile': profile, 'clips': []} + assert progress['profile'] == profile, 'Generation profile changed; use a separate output report' + done = {item['key']: item for item in progress['clips']} + plan = [] + for pack in voice['scripts']: + target_pack = {key: pack[key] for key in ('id', 'version', 'code', 'title')} + target_pack['steps'] = [] + manifest['scripts'].append(target_pack) + for clip in pack['steps']: + key = f"{pack['id']}:{pack['version']}:{clip['stepCode']}" + original = old_by_key[key] + assert original['text'] == clip['text'] and original['number'] == clip['number'] and original['code'] == pack['code'], key + source = REPORT.parent.parent / original['previewFile'] + source_hash = digest(source) + content_hash = hashlib.sha256(json.dumps([profile, source_hash, clip['text']], sort_keys=True, ensure_ascii=False).encode()).hexdigest()[:16] + url = f"/legacy/virtual-training/videos/narration/{pack['id']}/v{pack['version']}/instructor-1-v2/step-{clip['number']:02}-{content_hash}.mp4" + destination = WEB / 'public' / url.lstrip('/') + audio = WEB / 'public' / clip['url'].lstrip('/') + assert digest(audio) == clip['stepSha256'], f'Original WAV changed: {key}' + plan.append((key, pack, clip, target_pack, source, source_hash, destination, url)) + assert len(plan) == 39 + worker = OpenGenerationWorker(None, settings, None, None) + work = REPORT / 'capture' + work.mkdir(exist_ok=True) + for index, (key, pack, clip, target_pack, source, source_hash, destination, url) in enumerate(plan, 1): + destination.parent.mkdir(parents=True, exist_ok=True) + source_duration = float(probe(settings, source)['format']['duration']) + entry = done.get(key) + if entry and entry['url'] == url and destination.exists() and digest(destination) == entry['sha256']: + duration = validate(settings, destination, source_duration) + reused = 'resume' + else: + audio = work / 'narration.wav' + captured = work / 'capture.webm' + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', '-y', + '-i', str(source), '-vn', '-ac', '1', '-ar', '16000', '-c:a', 'pcm_s16le', str(audio)], check=True) + if pack['code'] == 'TASK-VIRTUAL-005' and clip['number'] == 1: + approved = SAMPLE / 'TASK-VIRTUAL-005-step-01-v2.mp4' + assert sample['originalSha256'] == source_hash and sample['text'] == clip['text'] + assert digest(approved) == sample['outputSha256'] and digest(audio) == sample['audioSha256'] + shutil.copy2(approved, destination) + reused = 'approved sample' + else: + command = GenerationCommand(title=f"{pack['title']} · 第{clip['number']}步 · 教员1 v2", + text=clip['text'], avatarId='55', voiceId='49', speed=.85, width=480, height=640, subtitles=False) + print(f"[{index}/39] Rendering {pack['code']} step {clip['number']:02}", flush=True) + worker.capture(command, avatar, audio, None, captured, threading.Event()) + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', '-y', + '-i', str(captured), '-r', '25', '-c:v', 'libx264', '-preset', 'veryfast', '-crf', '20', + '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-b:a', '128k', '-movflags', '+faststart', str(destination)], check=True) + reused = False + duration = validate(settings, destination, source_duration) + entry = {'key': key, 'code': pack['code'], 'number': clip['number'], 'stepCode': clip['stepCode'], + 'text': clip['text'], 'url': url, 'duration': duration, 'sha256': digest(destination), + 'sourceVideoSha256': source_hash, 'audioSha256': digest(audio), 'reused': reused} + done[key] = entry + progress['clips'] = list(done.values()) + write_json(progress_file, progress) + assert digest(source) == source_hash, 'Original video changed' + target_pack['steps'].append({name: clip[name] for name in ('stepCode', 'number', 'expectedTitle', 'expectedInstruction', 'text')} | + {name: entry[name] for name in ('url', 'duration', 'sha256')}) + print(f"[{index}/39] Verified {pack['code']} step {clip['number']:02}: {duration:.2f}s ({reused or 'rendered'})", flush=True) + target = WEB / 'src/features/virtual-training-scripts/narration-video-manifest.js' + temporary = target.with_suffix('.js.tmp') + temporary.write_text('// Generated by ute2e/tools/bridge-digital-video-static-generate.py.\nexport default ' + json.dumps(manifest, ensure_ascii=False, indent=2) + ';\n', encoding='utf-8') + temporary.replace(target) + write_json(REPORT / 'manifest.json', manifest) + groups = [] + for pack in manifest['scripts']: + cards = [] + for clip in pack['steps']: + relative = '../../..' + '/unreal_tran_web/public' + clip['url'] + cards.append(f'

第 {clip["number"]} 步

{html.escape(clip["text"])}

{clip["duration"]:.2f} 秒 · 打开视频

') + groups.append(f'

{html.escape(pack["code"] + " · " + pack["title"])}

{"".join(cards)}
') + (REPORT / 'index.html').write_text('桥梁讲解 · 教员1 v2

四套桥梁流程 · 教员1 v2 讲解

39 段视频已生成到前端 public 目录。点击播放;原语音与上一版视频保留。

' + ''.join(groups) + '', encoding='utf-8') + print(json.dumps({'complete': True, 'clips': len(plan), 'manifest': str(target), 'report': str(REPORT / 'index.html')}, ensure_ascii=False), flush=True) + + +if __name__ == '__main__': + main() diff --git a/tools/bridge-digital-video-static-live.mjs b/tools/bridge-digital-video-static-live.mjs new file mode 100644 index 0000000..d04528c --- /dev/null +++ b/tools/bridge-digital-video-static-live.mjs @@ -0,0 +1,4 @@ +// Same playback/fallback checks, with strict project-static URL assertions. +process.env.NARRATION_STATIC = '1'; +process.env.REPORT_DIR = 'reports/bridge-digital-video-static-20260915'; +await import('./bridge-digital-video-live.mjs'); diff --git a/tools/bridge-digital-video-v2-sample.py b/tools/bridge-digital-video-v2-sample.py new file mode 100644 index 0000000..c2a39e9 --- /dev/null +++ b/tools/bridge-digital-video-v2-sample.py @@ -0,0 +1,71 @@ +"""Render one v2 sample with the existing server renderer and the old clip's audio.""" +from pathlib import Path +import hashlib +import json +import subprocess +import sys +import threading + +import requests + +ROOT = Path(__file__).resolve().parents[3] +API_ROOT = ROOT / 'ai_person/ai_person_api' +sys.path.insert(0, str(API_ROOT)) +from app.config import get_settings +from app.schemas.open_platform import GenerationCommand +from app.services.open_generation_worker import OpenGenerationWorker + + +def digest(path): + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def main(): + original = ROOT / 'unreal_tran/ute2e/reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-01.mp4' + report = ROOT / 'unreal_tran/ute2e/reports/bridge-digital-video-v2-sample-20260915' + report.mkdir(parents=True, exist_ok=True) + output = report / 'TASK-VIRTUAL-005-step-01-v2.mp4' + if output.exists(): + raise RuntimeError('Sample already exists; refusing to overwrite it') + audio, captured = report / 'original-audio.wav', report / 'capture.webm' + settings = get_settings() + avatar = 'a1000000000000000000000000000005' + session = requests.Session() + session.trust_env = False + manifest_response = session.get(str(settings.service_base_url).rstrip('/') + f'/api/v1/avatars/{avatar}/assets/manifest.json', timeout=30) + manifest_response.raise_for_status() + expected = json.loads((ROOT / 'ai_person/ai_person_service/builtin_avatars/instructors-v2.json').read_text('utf-8'))['instructors'][0] + assert hashlib.sha256(manifest_response.content).hexdigest() == expected['bundle_sha256']['manifest.json'], 'Live avatar is not the validated v2 bundle' + original_digest = digest(original) + command = GenerationCommand(title='005:液压泵应急切换 · 第1步 · v2素材对比', + text='第1步,确定故障液压泵。根据故障现象确定发生故障的液压泵。', + avatarId='55', voiceId='49', speed=.85, width=480, height=640, subtitles=False) + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', '-y', '-i', str(original), + '-vn', '-ac', '1', '-ar', '16000', '-c:a', 'pcm_s16le', str(audio)], check=True) + print('Rendering validated instructor 1 v2 with the original narration audio', flush=True) + worker = OpenGenerationWorker(None, settings, None, None) + worker.capture(command, avatar, audio, None, captured, threading.Event()) + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', '-y', '-i', str(captured), + '-r', '25', '-c:v', 'libx264', '-preset', 'veryfast', '-crf', '20', '-pix_fmt', 'yuv420p', + '-c:a', 'aac', '-b:a', '128k', '-movflags', '+faststart', str(output)], check=True) + probe = subprocess.run([settings.ffprobe_binary, '-v', 'error', '-show_format', '-show_streams', '-of', 'json', str(output)], check=True, capture_output=True, text=True) + metadata = json.loads(probe.stdout) + assert any(stream['codec_type'] == 'video' and stream['codec_name'] == 'h264' for stream in metadata['streams']) + assert any(stream['codec_type'] == 'audio' for stream in metadata['streams']) + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', '-i', str(output), '-f', 'null', '-'], check=True) + for second in (.8, 2.0, 3.2): + subprocess.run([settings.ffmpeg_binary, '-hide_banner', '-loglevel', 'error', '-y', '-ss', str(second), + '-i', str(output), '-frames:v', '1', str(report / f'frame-{second}.jpg')], check=True) + assert digest(original) == original_digest, 'Original comparison clip changed' + result = {'avatarName': '教员1', 'materialVersion': 'v2', 'providerAvatarId': avatar, + 'text': command.text, 'audioSource': str(original), 'audioSha256': digest(audio), + 'originalSha256': original_digest, 'outputSha256': digest(output), 'output': str(output), + 'renderEngine': 'OpenGenerationWorker.capture / open_render_capture.js (unchanged)', + 'liveAvatarManifest': manifest_response.json(), 'metadata': metadata, + 'originalPreserved': True, 'publishedTaskBindingsChanged': False} + (report / 'result.json').write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding='utf-8') + print(json.dumps({'output': str(output), 'duration': metadata['format']['duration'], 'originalPreserved': True}), flush=True) + + +if __name__ == '__main__': + main() diff --git a/tools/bridge-lecture-delivery.mjs b/tools/bridge-lecture-delivery.mjs new file mode 100644 index 0000000..fc65319 --- /dev/null +++ b/tools/bridge-lecture-delivery.mjs @@ -0,0 +1,25 @@ +import fs from 'node:fs'; +import assert from 'node:assert/strict'; +import {createHash} from 'node:crypto'; +import videos from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-video-manifest.js'; +import speech from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-manifest.js'; +const origin=process.env.BASE_URL || 'http://127.0.0.1:6180'; +const directory=process.env.REPORT_DIR || 'reports/bridge-lecture-polish-20260915/local'; +const sha=b=>createHash('sha256').update(b).digest('hex'); +const clips=videos.scripts.flatMap(s=>s.steps); +const sounds=speech.scripts.flatMap(s=>s.steps.flatMap(c=>[{url:c.url,sha256:c.stepSha256},...(c.safetyUrl?[{url:c.safetyUrl,sha256:c.safetySha256}]:[])])); +assert.equal(clips.length,39); +for(const pack of speech.scripts)for(const clip of pack.steps)assert.doesNotMatch(clip.text+' '+clip.safetyText,/原稿|原图|没有展开|未展开|没有给出|概括项|本预演|相反描述/); +for(const group of [clips,sounds]) { + for(let start=0;start{ + const r=await fetch(origin+clip.url,{signal:AbortSignal.timeout(60000)}); + assert.equal(r.status,200,clip.url); + assert.equal(sha(Buffer.from(await r.arrayBuffer())),clip.sha256,clip.url); + assert.equal(sha(fs.readFileSync(new URL('../../unreal_tran_web/dist'+clip.url,import.meta.url))),clip.sha256); + })); +} +const range=await fetch(origin+clips[0].url,{headers:{Range:'bytes=0-1023'}}); +assert.equal(range.status,206);assert.equal((await range.arrayBuffer()).byteLength,1024); +fs.mkdirSync(directory,{recursive:true}); +const result={origin,videos:clips.length,audio:sounds.length,allTextsClean:true,exactFiles:true,buildCopiesMatch:true,rangeRequests:true}; +fs.writeFileSync(directory+'/delivery.json',JSON.stringify(result,null,2));console.log(JSON.stringify(result)); diff --git a/tools/bridge-lecture-polish-live.mjs b/tools/bridge-lecture-polish-live.mjs new file mode 100644 index 0000000..8c0bc76 --- /dev/null +++ b/tools/bridge-lecture-polish-live.mjs @@ -0,0 +1,102 @@ +import { chromium, expect } from '@playwright/test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import { credentials } from './role-permissions-live.mjs'; +import videos from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-video-manifest.js'; +const origin=process.env.BASE_URL || 'http://127.0.0.1:6180'; +const widgetOrigin=process.env.WIDGET_URL || 'http://127.0.0.1:8003'; +const dir=process.env.REPORT_DIR || 'reports/bridge-lecture-polish-20260915/local'; +fs.mkdirSync(dir,{recursive:true}); +const auth=await fetch(`${origin}/api/auth/v1/auth/login`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({...credentials('root'),roleCode:'admin',rememberMe:false})}).then(r=>r.json()); +assert.ok(auth.data?.accessToken,'Login'); +const listing=await fetch(`${origin}/api/tran/v1/teaching/assignments?channel=VIRTUAL&assignmentKind=TRAINING&size=100`,{headers:{Authorization:`Bearer ${auth.data.accessToken}`}}).then(r=>r.json()); +const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader','--autoplay-policy=no-user-gesture-required']}); +const previous=process.env.WIDGET_ONLY === '1' ? JSON.parse(fs.readFileSync(fs.existsSync(`${dir}/result.json`)?`${dir}/result.json`:`${dir}/failure.json`)) : null; +const checks=previous?.checks.filter(c=>c.task) || [], errors=[]; +let page; +try { + page=await browser.newPage({viewport:{width:1920,height:945}}); + await page.addInitScript(token=>{ + sessionStorage.setItem('unreal-tran:web:access-token:v1',token); + localStorage.setItem('unreal-tran:web:preferences:v1',JSON.stringify({themeMode:'military'})); + window.__lecturePlays=[]; + const play=HTMLMediaElement.prototype.play; + HTMLMediaElement.prototype.play=function(){ + if(this.classList.contains('training-server-video')) { + const visible=e=>{const s=getComputedStyle(e);return e.getClientRects().length>0&&s.visibility!=='hidden'&&s.display!=='none'&&s.opacity!=='0'}; + window.__lecturePlays.push({loading:[...document.querySelectorAll('.training-loading:not(.is-hidden), .el-loading-mask')].some(visible),src:new URL(this.currentSrc||this.src,location.href).pathname}); + if(window.__blockNextLecture){window.__blockNextLecture=false;return Promise.reject(new DOMException('User gesture required','NotAllowedError'))} + } + return play.apply(this,arguments); + }; + },auth.data.accessToken); + page.on('pageerror',e=>errors.push(e.message)); + // Deliberately delay model and decoder responses without replacing their data. + let delayed=previous?.delayed || 0; + await page.route(/(?:\.glb(?:\?|$)|draco.*\.(?:wasm|js)(?:\?|$)|\/assets\/[^/]+\/download)/,async route=>{ + delayed++; + await new Promise(resolve=>setTimeout(resolve,1500)); + await route.continue(); + }); + for(const pack of process.env.WIDGET_ONLY === '1' ? [] : videos.scripts){ + const task=listing.data.records.find(t=>t.code===pack.code);assert.ok(task,pack.code); + await page.goto(`${origin}/teaching/virtual-training/preview/${task.id}`); + await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:150000}); + const media=page.locator('.training-server-video'); + await expect(media).toBeVisible(); + await expect(page.locator('[data-action="toggle-teacher-media"]')).toHaveText('切换语音'); + await expect.poll(()=>media.evaluate(v=>v.currentTime),{timeout:20000}).toBeGreaterThan(.1); + const attempts=await page.evaluate(()=>window.__lecturePlays); + assert.ok(attempts.length>0);assert.ok(attempts.every(p=>!p.loading),'Narration must wait for visible loading overlays to finish'); + assert.equal(attempts[0].src,pack.steps[0].url); + assert.equal(await page.locator('.training-scene-badge').count(),0); + for(const width of [1920,1600,1366]) { + await page.setViewportSize({width,height:945}); + const hud=page.locator('[data-role="scenario-hud"]'),tools=page.locator('[data-role="model-commandbar"]'); + await expect(tools).toBeVisible(); + if(await hud.isVisible()){ + const h=await hud.boundingBox(),t=await tools.boundingBox(); + assert.ok(t.y>=h.y+h.height+7,`${pack.code} HUD/tool overlap at ${width}`); + } + if(width===1920)await page.screenshot({path:`${dir}/${pack.code}.png`}); + } + await page.setViewportSize({width:1920,height:945}); + await page.evaluate(()=>window.__blockNextLecture=true); + await page.locator('[data-action="teacher-speak"]').click(); + await expect(page.locator('[data-role="teacher-voice-status"]')).toHaveText('点击播放讲解'); + await expect(media).toBeVisible(); + await expect(page.locator('[data-action="toggle-teacher-media"]')).toHaveText('切换语音'); + await page.locator('[data-action="teacher-speak"]').click(); + await expect.poll(()=>media.evaluate(v=>v.currentTime)).toBeGreaterThan(.1); + checks.push({task:pack.code,videoDefault:true,noPlaybackWhileLoading:true,autoplayRestrictionRetainsVideo:true,noHudOverlap:[1920,1600,1366],plays:attempts}); + console.log('PASS',pack.code); + } + await page.goto(`${origin}/teaching/virtual-training`); + const publicWidget=await page.locator('[data-testid="global-digital-human-widget"]').getAttribute('src'); + const slug=new URL(publicWidget).pathname.split('/').at(-1); + const publicProfile=await fetch(`${widgetOrigin}/open/v1/realtime/${slug}`).then(r=>r.json()); + const expectedCover=publicProfile.data.avatars[0].coverUrl; + assert.match(expectedCover,/^\/avatars\/builtin\/.+\.png$/); + await page.goto(`${widgetOrigin}/embed/${slug}?label=${encodeURIComponent('问数字教员')}`); + const image=page.locator('.embed-launcher-avatar img'); + await expect(image).toBeVisible(); + await expect(image).toHaveAttribute('src',expectedCover,{timeout:30000}); + await expect.poll(()=>image.evaluate(e=>e.naturalWidth)).toBeGreaterThan(0); + assert.equal(await page.locator('.embed-launcher-avatar i').count(),0); + const launcher=page.locator('.embed-launcher'); + assert.equal(await launcher.evaluate(e=>getComputedStyle(e).boxShadow),'none'); + await launcher.hover(); + assert.equal(await launcher.evaluate(e=>getComputedStyle(e).boxShadow),'none'); + await page.screenshot({path:`${dir}/widget.png`}); + await launcher.click(); + await expect(page.locator('.embed-panel')).toBeVisible(); + assert.equal(await page.locator('.embed-panel').evaluate(e=>getComputedStyle(e).boxShadow),'none'); + checks.push({widget:widgetOrigin,avatarLoaded:true,avatar:expectedCover,greenDotRemoved:true,launcherAndPanelShadows:'none'}); + assert.deepEqual(errors,[]); + fs.writeFileSync(`${dir}/result.json`,JSON.stringify({origin,delayed,checks,errors},null,2)); + console.log(JSON.stringify({passed:checks.length,delayed,errors})); +}catch(error){ + await page?.screenshot({path:`${dir}/failure.png`}).catch(()=>{}); + fs.writeFileSync(`${dir}/failure.json`,JSON.stringify({message:error.message,checks,errors},null,2)); + throw error; +}finally{await browser.close()} diff --git a/tools/bridge-lecture-polish-report.mjs b/tools/bridge-lecture-polish-report.mjs new file mode 100644 index 0000000..ded08da --- /dev/null +++ b/tools/bridge-lecture-polish-report.mjs @@ -0,0 +1,14 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import videos from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-video-manifest.js'; +const dir=path.resolve('reports/bridge-lecture-polish-20260915'); +const changed=JSON.parse(fs.readFileSync(path.join(dir,'regenerated.json'),'utf8')); +const esc=s=>String(s).replaceAll('&','&').replaceAll('<','<').replaceAll('"','"'); +const tests=['local','lan','test'].filter(name=>fs.existsSync(path.join(dir,name,'result.json'))); +let html=`桥梁数字教员讲解修正验收

桥梁数字教员讲解修正验收 · 2026-09-15

四套任务共39段讲解,6段重新生成。默认视频模式,等待场景加载完成后播放;保留语音切换与旧文件。右上角按内容自动排列,移除“三维实时交互”角标。公开浮窗显示真实教员头像,移除阴影和头像绿点。

验证:${tests.map(t=>`${t} 浏览器回归 文件校验`).join(' · ')}。另通过前端构建、14项脚本契约测试、562项Java测试、2项公开头像接口测试。

本次重新生成的6段

`; +for(const item of changed){const src=path.relative(dir,path.resolve('../unreal_tran_web/public'+item.url)).replaceAll('\\','/');html+=`
${esc(item.code)} · 第${item.number}步

${esc(item.text)}

${item.duration}s · 已替换 · 原文件保留
`} +html+='

当前39段讲解清单

'; +for(const script of videos.scripts){html+=`

${esc(script.code)} · ${esc(script.title||script.id)}

    `;for(const clip of script.steps){const src=path.relative(dir,path.resolve('../unreal_tran_web/public'+clip.url)).replaceAll('\\','/');html+=`
  1. ${esc(clip.expectedTitle)}:${esc(clip.text)}
  2. `}html+='
'} +if(fs.existsSync(path.join(dir,'test/TASK-VIRTUAL-008.png')))html+='

测试环境

'; +html+='
';fs.writeFileSync(path.join(dir,'index.html'),html); +console.log('Report updated'); diff --git a/tools/bridge-lipsync-diagnose.mjs b/tools/bridge-lipsync-diagnose.mjs new file mode 100644 index 0000000..7d9107f --- /dev/null +++ b/tools/bridge-lipsync-diagnose.mjs @@ -0,0 +1,37 @@ +import fs from 'node:fs'; +import { execFileSync } from 'node:child_process'; +import { chromium } from '@playwright/test'; +const silence = process.argv.includes('--silence'); +const dir = `reports/bridge-lipsync-diagnosis-20260914${silence ? '-silence' : ''}`; fs.mkdirSync(dir, { recursive: true }); +const input = 'reports/bridge-digital-video-20260914/TASK-VIRTUAL-005-step-03.mp4'; +execFileSync('ffmpeg', ['-hide_banner','-loglevel','error','-y','-i',input,'-vn','-ar','16000','-ac','1','-c:a','pcm_s16le',`${dir}/sample.wav`]); +if (silence) execFileSync('ffmpeg', ['-hide_banner','-loglevel','error','-y','-f','lavfi','-i','anullsrc=r=16000:cl=mono','-t','8.241','-c:a','pcm_s16le',`${dir}/sample.wav`]); +const origin = 'http://1.14.103.234:8123'; +const browser = await chromium.launch({ channel:'msedge', headless:true, args:['--autoplay-policy=no-user-gesture-required','--use-gl=angle','--use-angle=swiftshader','--enable-unsafe-swiftshader',`--unsafely-treat-insecure-origin-as-secure=${origin}`] }); +try { + const context=await browser.newContext({ viewport:{width:480,height:640},acceptDownloads:true }); + await context.route(`${origin}/__open-render__`,r=>r.fulfill({contentType:'text/html',body:''})); + const page=await context.newPage(), errors=[];page.on('pageerror',e=>errors.push(e.message)); + await page.goto(`${origin}/__open-render__`); + const frame=page.frames().find(f=>f.url().includes('/viewer/')); + await frame.waitForFunction(()=>window.DH_RUNTIME_READY,{},{timeout:120000}); + await frame.evaluate(()=>{ + window.lipDiagnostic={frames:[],start:performance.now(),events:[]}; + const bs=Module._updateBlendShape, set=Module._setAudioBuffer; + Module._updateBlendShape=function(p,n){const t=performance.now(),r=bs(p,n);window.lipDiagnostic.frames.push({t:t-window.lipDiagnostic.start,ms:performance.now()-t,values:Array.from(new Float32Array(Module.HEAPU8.buffer,p,12))});return r;}; + Module._setAudioBuffer=function(p,n){const r=set(p,n);window.lipDiagnostic.events.push({type:'setAudio',t:performance.now()-window.lipDiagnostic.start,n,result:r});return r;}; + }); + const capture=fs.readFileSync('../../ai_person/ai_person_api/app/services/open_render_capture.js','utf8'); + await page.evaluate(({ script, args }) => eval(`(${script}\n)`)(args), { script: capture, args: {audio:fs.readFileSync(`${dir}/sample.wav`).toString('base64'),background:null,backgroundVideo:false,width:480,height:640,text:'口型同步诊断',subtitles:false,maxSeconds:120} }); + await page.waitForFunction(()=>['done','error'].includes(window.openCapture?.status),{},{timeout:120000}); + const result=await frame.evaluate(()=>window.lipDiagnostic); + result.capture=await page.evaluate(()=>window.openCapture);result.errors=errors; + if (result.capture.status === 'done') { + const downloadPromise = page.waitForEvent('download'); + await page.evaluate(()=>{const a=document.createElement('a');a.href=window.openCapture.url;a.download='diagnostic.webm';a.click();}); + await (await downloadPromise).saveAs(`${dir}/diagnostic.webm`); + } + const active=result.frames.filter(f=>f.t>=result.events[0]?.t); + result.summary={frameCount:active.length,elapsedMs:active.at(-1)?.t-active[0]?.t,fps:active.length/((active.at(-1)?.t-active[0]?.t)/1000),maxBlend:Math.max(...active.flatMap(f=>f.values.map(Math.abs))),nonZeroFrames:active.filter(f=>f.values.some(v=>Math.abs(v)>.001)).length}; + fs.writeFileSync(`${dir}/runtime.json`,JSON.stringify(result,null,2));console.log(JSON.stringify({summary:result.summary,events:result.events,capture:result.capture.status,errors})); +} finally {await browser.close();} diff --git a/tools/bridge-model-match-assertions.mjs b/tools/bridge-model-match-assertions.mjs new file mode 100644 index 0000000..b2d59b8 --- /dev/null +++ b/tools/bridge-model-match-assertions.mjs @@ -0,0 +1,26 @@ +import assert from 'node:assert/strict'; +import { expect } from '@playwright/test'; + +export async function verifyVisualEffects(page, operation) { + await expect.poll(async()=>page.evaluate(()=>globalThis.__trainingSceneDiagnostics().bridgeWorkshop.pending)).toBe(false); + const d=await page.evaluate(()=>globalThis.__trainingSceneDiagnostics().bridgeWorkshop), targets=d.targets; + for (const effect of operation.effects || []) { + const t=targets.find(t=>t.id===effect.targetId); assert.ok(t,effect.targetId); + if(d.modelBinding && t.id==='front-pump-hydraulic-pump'){assert.equal(t.visible,false);continue;} + if(typeof effect.visible==='boolean')assert.equal(t.visible,effect.visible,t.id); + const offset=effect.targetId==='bridge-gasket' && effect.offset?.[0] ? [2.3,0,1.31] : effect.offset; + if(offset)assert.ok(t.position.every((v,i)=>Math.abs(v-t.home[i]-offset[i])<1e-5),t.id+' position'); + } + if(operation.kind==='rotate'){ + const t=targets.find(t=>t.id===operation.targetId); + if(t?.rotatingQuaternion){assert.deepEqual(t.quaternion,[0,0,0,1],'valve housing must stay fixed');assert.ok(Math.abs(t.rotatingQuaternion[3])<0.999,'handle must visibly turn');} + } + if(d.modelBinding){ + assert.equal(d.modelBinding.boltCount,4);assert.equal(d.modelBinding.mountedOnVehicle,true); + const installed=targets.find(t=>t.id==='bridge-new-pump'); + if(operation.targetId==='bridge-new-pump'){ + const expected=d.modelBinding.sourceBounds; + for(const key of ['min','max'])assert.ok(installed.worldBounds[key].every((v,i)=>Math.abs(v-expected[key][i])<0.001),'new pump must occupy original source bounds'); + } + } +} diff --git a/tools/bridge-model-match-cleanup.mjs b/tools/bridge-model-match-cleanup.mjs new file mode 100644 index 0000000..89bf7f6 --- /dev/null +++ b/tools/bridge-model-match-cleanup.mjs @@ -0,0 +1,19 @@ +import fs from 'node:fs'; +import assert from 'node:assert/strict'; +import {login,call} from './role-permissions-live.mjs'; +const dir='reports/bridge-model-match-20260914',s=await login('root'); +const api=async(p,data,method)=>{const r=await call('tran/v1/'+p,s.accessToken,data,method);assert.equal(r.status,200,`${p}: ${r.message}`);return r.data;}; +const cleanup=JSON.parse(fs.readFileSync('E:/work/edit_3d/.codex-tmp/bridge-model-match-cleanup-20260914/result.json','utf8')); +assert.equal(cleanup.result,'PASS'); +const fixtures=fs.readdirSync(dir).filter(f=>f.startsWith('fixtures-')).flatMap(f=>JSON.parse(fs.readFileSync(dir+'/'+f))); +const ids=[...new Set(fixtures.map(f=>Number(f.projectId)))].sort((a,b)=>a-b); +assert.deepEqual(ids,[453,454,455]); +for(const id of ids){ + let detail=await api('content/projects/'+id); + assert.ok(detail.project.name.startsWith('三维验收·')); + detail=await api(`content/projects/${id}/review`,{version:detail.project.version,action:'REVOKE',comment:'模型匹配验收完成,清理本次临时项目'}); + await api(`content/projects/${id}?version=${detail.project.version}`,undefined,'DELETE'); +} +cleanup.softDeletedContentProjects=ids; +fs.writeFileSync(dir+'/cleanup.json',JSON.stringify(cleanup,null,2)); +console.log(JSON.stringify(cleanup)); diff --git a/tools/bridge-model-match-live.mjs b/tools/bridge-model-match-live.mjs new file mode 100644 index 0000000..a60523f --- /dev/null +++ b/tools/bridge-model-match-live.mjs @@ -0,0 +1,74 @@ +import { chromium, expect } from '@playwright/test'; +import fs from 'node:fs'; +import assert from 'node:assert/strict'; +import crypto from 'node:crypto'; +import { login, call } from './role-permissions-live.mjs'; +import { scripts, scriptDefinition } from '../../unreal_tran_web/src/features/virtual-training-scripts/definition.js'; +import { verifyVisualEffects } from './bridge-model-match-assertions.mjs'; + +const dir='reports/bridge-model-match-20260914';fs.mkdirSync(dir,{recursive:true}); +const session=await login('root'), fixtures=[], checks=[], errors=[]; +const api=async(path,data,method)=>{const r=await call(path,session.accessToken,data,method);assert.equal(r.status,200,`${path}: ${r.message}`);return r.data;}; +const fixtureFile=`${dir}/fixtures-${Date.now()}.json`; +const saveFixtures=()=>fs.writeFileSync(fixtureFile,JSON.stringify(fixtures,null,2)); +const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']}); +const page=await browser.newPage({viewport:{width:1600,height:1000}}); +await page.addInitScript(s=>sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken),session); +page.on('pageerror',e=>errors.push(e.message)); +const waitReady=async()=>{await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});await page.waitForFunction(()=>globalThis.__trainingSceneDiagnostics()?.bridgeWorkshop?.targets.length>0);await page.waitForTimeout(1800);}; +try { + for(const script of scripts.filter(s=>s.version==='3' && (!process.env.BRIDGE_CODE || process.env.BRIDGE_CODE===s.code))) { + const existing=fs.readdirSync(dir).filter(f=>f.startsWith('fixtures-')).flatMap(f=>JSON.parse(fs.readFileSync(dir+'/'+f,'utf8'))).find(f=>f.code===script.code && f.taskId); + let task,fixture; + if(existing){fixture={...existing};task=await api('tran/v1/teaching/assignments/'+fixture.taskId);fixtures.push(fixture);saveFixtures();} + else { + const content=await api('tran/v1/content/projects',{type:'TRAINING',name:`三维验收·${script.title}`,description:'Temporary 3D acceptance fixture',categoryCode:'MAINTENANCE',trainingMode:'VIRTUAL',content:scriptDefinition(script),dependencies:[],assets:[]}); + fixture={code:script.code,projectId:content.project.id};fixtures.push(fixture);saveFixtures(); + const project=(await api(`tran/v1/content/projects/${fixture.projectId}/publish`,{version:content.project.version})).project; + task=await api('tran/v1/teaching/assignments',{code:`CHECK-3D-${Date.now()}-${script.code}`,name:`三维验收·${script.title}`,description:'Temporary acceptance fixture',channel:'VIRTUAL',assignmentKind:'TRAINING',executionMode:'PRACTICE',audienceType:'COMMON',collaborationMode:'INDIVIDUAL',digitalHumanAllowed:false,contentProjectId:project.id,contentVersionId:project.publishedVersionId,members:[]}); + fixture.taskId=task.id;saveFixtures(); + task=await api(`tran/v1/teaching/assignments/${task.id}/publish`,{version:task.version}); + } + await page.goto(`http://127.0.0.1:6180/teaching/virtual-training/preview/${task.id}`);await waitReady(); + await expect(page.locator('.bridge-procedure')).toHaveCount(0); + const bar=page.locator('[data-role="model-commandbar"]'); + for(const action of ['toggle-structure-tree','focus-selected-part','viewer-reset-view','toggle-part-labels','toggle-issue-highlight','toggle-hide-others','toggle-explosion'])await expect(bar.locator(`[data-action="${action}"]`)).toBeVisible(); + await page.screenshot({path:`${dir}/${script.code}-start.png`}); + fs.writeFileSync(`${dir}/${script.code}-diagnostic.json`,JSON.stringify(await page.evaluate(()=>globalThis.__trainingSceneDiagnostics()),null,2)); + for(let index=0;indexpage.evaluate(()=>globalThis.__trainingSceneDiagnostics().bridgeWorkshop.operationIndex)).toBe(k); + if(k===step.action.mechanism.steps.length-1){ + const response=page.waitForResponse(r=>r.url().includes(`/assignments/${task.id}/preview/validate`)); + await page.locator('[data-role="part-label"]').click(); + assert.equal((await response).status(),200); + }else{ + await page.locator('[data-role="part-label"]').click(); + await expect.poll(async()=>page.evaluate(()=>globalThis.__trainingSceneDiagnostics().bridgeWorkshop.operationIndex)).toBe(k+1); + } + await verifyVisualEffects(page,op); + console.log(script.code,index+1,k+1,op.targetId); + } + await expect(page.locator('[data-action="next"]')).toBeEnabled(); + if([1,3,4,7,10,15].includes(index))await page.screenshot({path:`${dir}/${script.code}-step-${index+1}.png`}); + if(indexs.action.mechanism.steps).length} 3D operations; preview server validation passed`); + fixture.passed=true;saveFixtures(); + } + assert.deepEqual(errors,[]); + fs.writeFileSync(`${dir}/acceptance.json`,JSON.stringify({pass:true,checks,errors},null,2)); +} catch(error){ + console.log('Feedback',await page.locator('.el-message').allTextContents()); + await page.screenshot({path:`${dir}/failure.png`}).catch(()=>{}); + fs.writeFileSync(`${dir}/acceptance.json`,JSON.stringify({pass:false,error:error.message,checks,errors},null,2));throw error; +}finally{await browser.close();saveFixtures();} diff --git a/tools/bridge-model-match-originals.mjs b/tools/bridge-model-match-originals.mjs new file mode 100644 index 0000000..e21a675 --- /dev/null +++ b/tools/bridge-model-match-originals.mjs @@ -0,0 +1,30 @@ +import {chromium,expect} from '@playwright/test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import {login,call} from './role-permissions-live.mjs'; +const dir='reports/bridge-model-match-20260914', s=await login('root'),checks=[]; +const api=async p=>{const r=await call('tran/v1/'+p,s.accessToken);assert.equal(r.status,200);return r.data;}; +const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']}); +try { + const page=await browser.newPage({viewport:{width:1600,height:1000}}); + await page.addInitScript(s=>{sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken);localStorage.setItem('unreal-tran:web:preferences:v1',JSON.stringify({themeMode:'military'}));},s); + for(const id of [86,89]) { + const task=await api('teaching/assignments/'+id), before=await api('teaching/runs?assignmentId='+id+'&size=100'); + await page.goto('http://127.0.0.1:6180/teaching/virtual-training/preview/'+id); + await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});await page.waitForTimeout(1500); + const steps=id===86?task.definitionSnapshot.steps:task.definitionSnapshot.steps.slice(0,1); + for(let i=0;ir.url().includes('/preview/validate'));await page.locator('[data-role="part-label"]').click();assert.equal((await response).status(),200);} + else{await page.locator('[data-role="part-label"]').click();await page.waitForTimeout(1000);} + } + await expect(page.locator('[data-action="next"]')).toBeEnabled(); + if(iJSON.parse(JSON.stringify(value,(key,item)=>key==='serverNow'?undefined:item)); + assert.deepEqual(stable((await api('teaching/runs?assignmentId='+id+'&size=100')).records),stable(before.records)); + checks.push(`${task.code} 原任务入口通过,原运行与成绩未变化`); + } + fs.writeFileSync(`${dir}/originals.json`,JSON.stringify({pass:true,checks},null,2)); +}finally{await browser.close();} diff --git a/tools/bridge-model-match-picking.mjs b/tools/bridge-model-match-picking.mjs new file mode 100644 index 0000000..a423f47 --- /dev/null +++ b/tools/bridge-model-match-picking.mjs @@ -0,0 +1,50 @@ +import {chromium,expect} from '@playwright/test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import {login,call} from './role-permissions-live.mjs'; +const dir='reports/bridge-model-match-20260914',session=await login('root'); +const fixture=fs.readdirSync(dir).filter(f=>f.startsWith('fixtures-')).flatMap(f=>JSON.parse(fs.readFileSync(dir+'/'+f))).find(f=>f.code==='TASK-VIRTUAL-007'); +const result=await call('tran/v1/teaching/assignments/'+fixture.taskId,session.accessToken);assert.equal(result.status,200); +const browser=await chromium.launch({channel:'msedge',headless:true,args:['--enable-unsafe-swiftshader']}); +const page=await browser.newPage({viewport:{width:1600,height:1000}}),checks=[],errors=[]; +await page.addInitScript(s=>sessionStorage.setItem('unreal-tran:web:access-token:v1',s.accessToken),session); +page.on('pageerror',e=>errors.push(e.message)); +const diag=()=>page.evaluate(()=>globalThis.__trainingSceneDiagnostics()); +try{ + // LAN entry exercises the same Gateway-backed preview as localhost. + await page.goto(`http://192.168.31.168:6180/teaching/virtual-training/preview/${fixture.taskId}`); + await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});await page.waitForTimeout(1500); + const teacher=page.locator('[aria-label="关闭数字教员"]');if(await teacher.isVisible())await teacher.click(); + const initial=await diag(); + const old=initial.bridgeWorkshop.targets.find(t=>t.id==='bridge-old-pump'); + for(const key of ['min','max'])assert.ok(old.worldBounds[key].every((v,i)=>Math.abs(v-initial.bridgeWorkshop.modelBinding.sourceBounds[key][i])<1e-6)); + for(let i=0;i<4;i++){ + const ops=result.data.definitionSnapshot.steps[i].action.mechanism.steps; + for(let j=0;jr.url().includes('/preview/validate')):null; + if(i===3){ + const d=await diag(),t=d.framing.targetOnScreen; + assert.ok(t.insideCanvas);assert.deepEqual(t.coveredBy,[]); + const rect=await page.locator('[data-role="canvas"]').boundingBox(); + await page.mouse.click(rect.x+t.localX,rect.y+t.localY); + checks.push(`Canvas picking ${ops[j].targetId}`); + }else await page.locator('[data-role="part-label"]').click(); + if(response)assert.equal((await response).status(),200); + else await expect.poll(async()=>(await diag()).bridgeWorkshop.operationIndex).toBe(j+1); + } + await expect(page.locator('[data-action="next"]')).toBeEnabled(); + if(i<3)await page.locator('[data-action="next"]').click(); + } + const positions=()=>diag().then(d=>d.bridgeWorkshop.targets.map(t=>[t.id,t.position,t.visible])); + const before=await positions(); + await page.locator('[data-action="viewer-reset-view"]').click();await page.waitForTimeout(800); + assert.deepEqual(await positions(),before,'camera reset must preserve dismantled state'); + await page.screenshot({path:`${dir}/TASK-VIRTUAL-007-context.png`}); + checks.push('camera reset preserves actual pump/bolt state'); + await page.reload();await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/,{timeout:120000});await page.waitForTimeout(1000); + const reloaded=await diag();assert.deepEqual(reloaded.bridgeWorkshop.modelBinding.sourceBounds,initial.bridgeWorkshop.modelBinding.sourceBounds); + checks.push('reload preserves source placement');assert.deepEqual(errors,[]); + fs.writeFileSync(`${dir}/picking.json`,JSON.stringify({pass:true,checks,errors},null,2)); +}catch(e){await page.screenshot({path:`${dir}/picking-failure.png`});fs.writeFileSync(`${dir}/picking-diagnostic.json`,JSON.stringify(await diag(),null,2));fs.writeFileSync(`${dir}/picking.json`,JSON.stringify({pass:false,error:e.message,checks,errors,feedback:await page.locator('.el-message').allTextContents()},null,2));throw e;} +finally{await browser.close();} diff --git a/tools/bridge-model-match-report.mjs b/tools/bridge-model-match-report.mjs new file mode 100644 index 0000000..51646b0 --- /dev/null +++ b/tools/bridge-model-match-report.mjs @@ -0,0 +1,14 @@ +import fs from 'node:fs'; +const dir='reports/bridge-model-match-20260914'; +const read=name=>JSON.parse(fs.readFileSync(`${dir}/${name}.json`,'utf8')); +const results=['acceptance','originals','picking'].map(name=>({name,...read(name)})); +if(results.some(r=>!r.pass))throw new Error('Acceptance incomplete'); +const esc=s=>String(s).replaceAll('&','&').replaceAll('<','<').replaceAll('"','"'); +const rows=[ + ['005 应急切换','原模型对应最完整','5 步、6 次操作;7 个登记节点均唯一存在,沿用原转轴。开关精度及故障物理仿真仍有限。'], + ['006 应急替代','部分匹配','4 次操作复用原车开关;双管接头与软管联动、阀体固定只转手柄。保障车和接口仍为补充示意。'], + ['007 换件修复','原位泵体、螺栓已匹配','复用原泵网格和世界姿态,拆出原有 4 颗螺栓;安装位置复原,增加细节视角和直接拾取。管路、纸垫等仍为补充件。'], + ['008 平衡阀互换','仍为补充装配模型','补齐油缸与两腔关系;擦拭贴面、阀座保留油口、封堵与换位对应。原整车缺少可确认的两腔平衡阀节点。'], +]; +const images=[['TASK-VIRTUAL-005-original.png','005 原始流程回归'],['TASK-VIRTUAL-006-step-2.png','006 两端接头与双管连接'],['TASK-VIRTUAL-007-step-4.png','007 原模型四颗安装螺栓拆卸'],['TASK-VIRTUAL-007-step-8.png','007 新泵原位安装'],['TASK-VIRTUAL-007-context.png','007 复位视角保留拆卸状态'],['TASK-VIRTUAL-008-step-4.png','008 小腔拆阀后封堵油口'],['TASK-VIRTUAL-008-step-16.png','008 完成两腔互换']]; +fs.writeFileSync(`${dir}/index.html`,`桥梁四套脚本模型匹配验收

桥梁四套脚本 · 模型匹配验收

2026-09-14 · 对照桥梁文件夹图片 4–10,以及实际 GLB 网格、节点、变换和运行结果。

结论:005 原模型对应最完整;007 已改为原位拆装;006、008 仍有实车模型缺失,不能声称四套已完全匹配。

${rows.map(r=>`${r.map(c=>``).join('')}`).join('')}
任务匹配程度核对与修正
${esc(c)}

验证范围

原 005 完整 5 步和后加三套 34 步,共 39 步、94 次操作,经真实教学预览校验;未创建学员成绩。附加 8 项单元/路由检查与生产构建通过。

${results.map(r=>`

${esc(r.name)} · PASS

    ${r.checks.map(c=>`
  • ${esc(c)}
  • `).join('')}
原始结果`).join('')}

39 步逐项核对及模型缺项说明 · 临时验收数据清理结果

运行截图

${images.filter(([file])=>fs.existsSync(`${dir}/${file}`)).map(([file,title])=>`
${esc(title)}
${esc(title)}
`).join('')}
`); diff --git a/tools/bridge-narration-live.mjs b/tools/bridge-narration-live.mjs new file mode 100644 index 0000000..3f2388e --- /dev/null +++ b/tools/bridge-narration-live.mjs @@ -0,0 +1,78 @@ +import { chromium, expect } from '@playwright/test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import { login, call } from './role-permissions-live.mjs'; +import manifest from '../../unreal_tran_web/src/features/virtual-training-scripts/narration-manifest.js'; +import { scriptTrainingDefinition } from '../../unreal_tran_web/src/features/virtual-training-scripts/registry.js'; + +const dir = 'reports/bridge-narration-20260914'; fs.mkdirSync(dir, { recursive: true }); +const root = await login('root'); +const response = await call('tran/v1/teaching/assignments?channel=VIRTUAL&assignmentKind=TRAINING&size=100', root.accessToken); +assert.equal(response.status, 200); +const tasks = manifest.scripts.map(s => response.data.records.find(t => t.code === s.code)); +const browser = await chromium.launch({ channel: 'msedge', headless: true, args: ['--enable-unsafe-swiftshader'] }); +const results = [], errors = []; +try { + const page = await browser.newPage({ viewport: { width: 1600, height: 1000 } }); + await page.addInitScript(token => sessionStorage.setItem('unreal-tran:web:access-token:v1', token), root.accessToken); + page.on('pageerror', e => errors.push(e.message)); + const ready = async () => { + await expect(page.locator('[data-role="loading"]')).toHaveClass(/is-hidden/, { timeout: 120000 }); + await expect(page.locator('[data-role="step-count"]')).toBeVisible(); + }; + const audioState = () => page.locator('.training-server-video').evaluate(a => ({ src: new URL(a.currentSrc || a.src, location.href).pathname, paused: a.paused, time: a.currentTime, error: a.error?.message })); + const play = async expected => { + const launch = page.locator('[data-role="teacher-launch"]'); + if (await launch.isVisible()) await launch.click(); + await page.locator('[data-action="teacher-speak"]').click(); + await expect.poll(async () => (await audioState()).src).toBe(expected); + await expect.poll(async () => (await audioState()).time, { timeout: 15000 }).toBeGreaterThan(.1); + assert.equal((await audioState()).error, undefined); + }; + for (const [index, task] of tasks.entries()) { + assert.ok(task, manifest.scripts[index].code); + const pack = manifest.scripts[index], bound = scriptTrainingDefinition(task); + assert.deepEqual(bound.steps.map(s => s.audio.narrationUrl), pack.steps.map(s => s.url)); + await page.goto(`http://127.0.0.1:6180/teaching/virtual-training/preview/${task.id}`); + await ready(); await play(pack.steps[0].url); + const toggle = page.locator('[data-action="toggle-teacher-voice"]'); + if (await toggle.getAttribute('aria-pressed') === 'true') await toggle.click(); + // Complete the real first-step model actions in preview, then change step. + for (let op = 0; op < task.definitionSnapshot.steps[0].action.mechanism.steps.length; op++) { + await page.locator('[data-role="part-label"]').click(); + if (index > 0) await expect.poll(() => page.evaluate(() => globalThis.__trainingSceneDiagnostics().bridgeWorkshop.pending)).toBe(false); + else await page.waitForTimeout(1800); + } + await expect(page.locator('[data-action="next"]')).toBeEnabled({ timeout: 20000 }); + await play(pack.steps[0].url); + await page.locator('[data-action="next"]').click(); + await expect(page.locator('[data-role="step-count"]')).toHaveText(`2 / ${pack.steps.length}`); + assert.equal((await audioState()).paused, true, 'Old narration stops on step change'); + await play(pack.steps[1].url); + await page.screenshot({ path: `${dir}/${task.code}-step-2.png` }); + await page.reload(); await ready(); await play(pack.steps[0].url); + await page.locator('.training-teacher-bubble [data-action="toggle-teacher"]').click(); + assert.equal((await audioState()).paused, true, 'Closing instructor stops narration'); + results.push({ code: task.code, stepsBound: pack.steps.length, firstAndSecondPlayed: true, stopOnStepChange: true, reloadPlayed: true }); + console.log(task.code, 'play / step change / reload passed'); + } + // Download and decode every published clip with the browser's actual codec. + const clips = manifest.scripts.flatMap(s => s.steps.flatMap(step => [{ url: step.url, duration: step.stepDuration }, ...(step.safetyUrl ? [{ url: step.safetyUrl, duration: step.safetyDuration }] : [])])); + const decoded = await page.evaluate(async clips => { + const context = new AudioContext(), results = []; + try { + for (const clip of clips) { + const response = await fetch(clip.url); + if (!response.ok) throw new Error(`Audio HTTP ${response.status}: ${clip.url}`); + const buffer = await context.decodeAudioData(await response.arrayBuffer()); + if (Math.abs(buffer.duration - clip.duration) > .02) throw new Error(`Duration mismatch: ${clip.url}`); + results.push({ url: clip.url, duration: buffer.duration, sampleRate: buffer.sampleRate }); + } + } finally { await context.close(); } + return results; + }, clips); + assert.equal(decoded.length, 42); assert.deepEqual(errors, []); + fs.writeFileSync(`${dir}/result.json`, JSON.stringify({ results, decoded, errors }, null, 2)); + fs.writeFileSync(`${dir}/index.html`, `桥梁脚本语音验收

四套桥梁脚本语音验收

39段步骤讲解、3段核对提醒,全部真实下载和浏览器解码通过。四个原任务前两步实际播放、切步停止、刷新重播、关闭停止通过。教员预览未写入成绩。

${manifest.scripts.map(s => `

${s.code} ${s.title}

${s.source} · ${s.steps.length}步

${s.steps.map(step => `

${step.text}

`).join('')}
`).join('')}`); + console.log('PASS', decoded.length, 'WAVs decoded'); +} finally { await browser.close(); } diff --git a/tools/bridge-widget-inspect.mjs b/tools/bridge-widget-inspect.mjs new file mode 100644 index 0000000..4d54e76 --- /dev/null +++ b/tools/bridge-widget-inspect.mjs @@ -0,0 +1,26 @@ +import { chromium } from '@playwright/test'; +import { login } from './role-permissions-live.mjs'; +const {accessToken}=await login('root'); +const browser=await chromium.launch({channel:'msedge',headless:true}); +try { + const page=await browser.newPage(); + await page.addInitScript(t=>sessionStorage.setItem('unreal-tran:web:access-token:v1',t),accessToken); + await page.goto('http://127.0.0.1:6180/teaching/virtual-training'); + await page.locator('[data-testid="global-digital-human-widget"]').waitFor(); + const src=await page.locator('[data-testid="global-digital-human-widget"]').getAttribute('src'); + console.log('widget',src); + const frame=await page.locator('[data-testid="global-digital-human-widget"]').contentFrame(); + await frame.locator('.embed-launcher').waitFor(); + const url=new URL(src); + const slug=url.pathname.split('/').filter(Boolean).at(-1); + for(const origin of [url.origin,'http://127.0.0.1:8003']) { + const r=await fetch(`${origin}/open/v1/realtime/${slug}`); + const data=await r.json(); + const agent=data.data||data; + for (const avatar of agent.avatars || []) { + const cover=await fetch(new URL(avatar.coverUrl,origin),{headers:{Range:'bytes=0-0'}}); + console.log(JSON.stringify({origin,status:r.status,avatar:avatar.name,coverPath:avatar.coverUrl.split('?')[0],coverStatus:cover.status,type:cover.headers.get('content-type'),error:cover.ok?null:await cover.text()})); + } + } + console.log(await frame.locator('.embed-launcher-avatar').evaluate(e=>({tag:e.firstElementChild?.tagName,greenDot:!!e.querySelector('i')}))); +} finally {await browser.close();} diff --git a/tools/render-bridge-3d-only-report.mjs b/tools/render-bridge-3d-only-report.mjs new file mode 100644 index 0000000..d8e94ef --- /dev/null +++ b/tools/render-bridge-3d-only-report.mjs @@ -0,0 +1,11 @@ +import fs from 'node:fs'; +import assert from 'node:assert/strict'; +const dir='reports/bridge-3d-only-20260914'; +const acceptance=JSON.parse(fs.readFileSync(dir+'/acceptance.json','utf8')); +const cleanup=JSON.parse(fs.readFileSync(dir+'/cleanup.json','utf8')); +assert.equal(acceptance.pass,true);assert.equal(cleanup.pass,true); +for(const stage of ['before-check','before-applied','after-check','after-applied','v1-history-check','v1-history-applied','legacy-v1-source-check','legacy-v1-source-applied'])fs.copyFileSync(`E:/work/edit_3d/.codex-tmp/bridge-3d-only-migration/${stage}.json`,`${dir}/migration-${stage}.json`); +fs.copyFileSync('reports/bridge-scripted-tasks-20260913/registered.json',dir+'/registered.json'); +const registered=JSON.parse(fs.readFileSync(dir+'/registered.json','utf8')); +const esc=s=>String(s).replaceAll('&','&').replaceAll('<','<').replaceAll('"','"'); +fs.writeFileSync(dir+'/index.html',`桥梁四流程三维版本生效验收

桥梁四流程 · 三维版本正式生效验收

2026-09-14 · 开发环境 · 127.0.0.1:6180 / 192.168.31.168:6180 · 通过 6100 Gateway。

PASS:文字播放器及兼容分支已移除;四条原任务均进入 HTML+JS 三维工作区。

${registered.map(t=>``).join('')}
任务原入口 ID脚本版本内容版本步骤
${esc(t.code)} ${esc(t.name)}${esc(t.id)}${esc(t.scriptVersion)}${esc(t.versionId)}${t.steps}

005 的 v2 是原三维版本,保留。006–008 只接受 v3,不允许文字版降级。静态 JS 仅决定内容来源,学员训练照常保存进度、提交、评定成绩与统计。

数据修复

经负责人授权,042 软删除错误运行 102、103 及关联事实。006、007 保留原任务编号,通过正式接口发布并绑定新内容版本;无活动引用的错误文字内容版本软删除。005 有效运行保留。修复前备份位于工作区本地目录,未写入此报告。

    ${['before-check','before-applied','after-check','after-applied','v1-history-applied','legacy-v1-source-applied'].map(s=>`
  • ${s} 执行证据
  • `).join('')}

正式任务闭环验证

管理员预览 + 临时学员直接领取四条原任务。39 步、94 次三维操作,提交后由教员示例评分 85 分,核验学员可见成绩与统计。临时账号、运行、成员及关联数据已清理,四条任务不残留验收成绩。

    ${acceptance.checks.map(c=>`
  • ${esc(c)}
  • `).join('')}

后端 422 项测试、前端 6 项脚本/模型/路由检查与生产构建通过。

完整验收结果 · 测试数据清理 · Final database state | 正式版本映射

正式入口截图

任务列表仍为四条
${registered.map(t=>`
${esc(t.code)} 原任务三维预览
${esc(t.code)} 学员流程完成与成绩显示(验收数据已清理)
`).join('')}
`);