dsh-engineering-ui 0.0.0-stage → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +772 -3
- package/engineering/plugins/dsh-engineering-ui/cordis.patch.yml +5 -0
- package/engineering/plugins/dsh-engineering-ui/icon.svg +14 -0
- package/engineering/plugins/dsh-engineering-ui/lib/client.js +8259 -0
- package/engineering/plugins/dsh-engineering-ui/lib/defense-sign.js +1552 -0
- package/engineering/plugins/dsh-engineering-ui/lib/index.js +5633 -0
- package/engineering/plugins/dsh-engineering-ui/lib/job-wait-guard.js +236 -0
- package/engineering/plugins/dsh-engineering-ui/lib/mem-guard.js +331 -0
- package/engineering/plugins/dsh-engineering-ui/lib/webots.js +114 -0
- package/engineering/plugins/dsh-engineering-ui/locale/en.json +6 -0
- package/engineering/plugins/dsh-engineering-ui/locale/zh.json +6 -0
- package/engineering/plugins/dsh-engineering-ui/preset-engineering.patch.yml +601 -0
- package/engineering/skills/assembly-orchestration/SKILL.md +651 -0
- package/engineering/skills/cad-workflow/SKILL.md +132 -0
- package/engineering/skills/mode-selection/SKILL.md +660 -0
- package/engineering/skills/physics-in-loop/SKILL.md +238 -0
- package/engineering/skills/physics-in-loop/references/feadocs.md +142 -0
- package/engineering/skills/solidworks-bridge/SKILL.md +445 -0
- package/engineering/skills/sw-design/SKILL.md +112 -0
- package/engineering/skills/sw-design/references/autocad-workflow.md +81 -0
- package/engineering/skills/sw-design/references/gbt-drafting.md +71 -0
- package/engineering/skills/sw-to-cad/SKILL.md +121 -0
- package/engineering/skills/webots-simulation/SKILL.md +58 -0
- package/engineering/tools/LICENSE.Auto-SolidWorks +21 -0
- package/engineering/tools/_plugin_paths.py +93 -0
- package/engineering/tools/_root.py +330 -0
- package/engineering/tools/_store.py +446 -0
- package/engineering/tools/ac_bridge.py +459 -0
- package/engineering/tools/ac_rules.json +21 -0
- package/engineering/tools/ac_validate.py +699 -0
- package/engineering/tools/ask_user.py +887 -0
- package/engineering/tools/build_arm1.py +46 -0
- package/engineering/tools/build_assembly.py +94 -0
- package/engineering/tools/build_base.py +57 -0
- package/engineering/tools/build_housing.py +70 -0
- package/engineering/tools/build_structural.py +43 -0
- package/engineering/tools/build_transmission.py +69 -0
- package/engineering/tools/cadx.lsp +128 -0
- package/engineering/tools/choice_contract.py +61 -0
- package/engineering/tools/conn_state.py +1671 -0
- package/engineering/tools/defense_gate.py +3374 -0
- package/engineering/tools/drawing_input.py +314 -0
- package/engineering/tools/env_check.py +467 -0
- package/engineering/tools/examples/build_axis.py +142 -0
- package/engineering/tools/examples/build_cup.py +56 -0
- package/engineering/tools/examples/build_plate.py +58 -0
- package/engineering/tools/examples/build_sphere.py +30 -0
- package/engineering/tools/examples/build_transition_duct.py +381 -0
- package/engineering/tools/gate_integrity.py +401 -0
- package/engineering/tools/mode2_flow.py +3589 -0
- package/engineering/tools/mode_checker.py +77 -0
- package/engineering/tools/mode_gate.py +8013 -0
- package/engineering/tools/part_registry.py +4266 -0
- package/engineering/tools/physics/__init__.py +50 -0
- package/engineering/tools/physics/_compat.py +12 -0
- package/engineering/tools/physics/design_state.py +142 -0
- package/engineering/tools/physics/domain_validator.py +751 -0
- package/engineering/tools/physics/fatigue.py +489 -0
- package/engineering/tools/physics/fea_solver.py +1163 -0
- package/engineering/tools/physics/feapy_solver.py +314 -0
- package/engineering/tools/physics/gb_materials.json +1228 -0
- package/engineering/tools/physics/geometry_gate.py +337 -0
- package/engineering/tools/physics/load_case.py +951 -0
- package/engineering/tools/physics/material_db.py +874 -0
- package/engineering/tools/physics/mesh_adapter.py +321 -0
- package/engineering/tools/physics/refine_rules.py +272 -0
- package/engineering/tools/physics/rules/gb_base_rules.json +377 -0
- package/engineering/tools/physics/rules/gb_drafting_rules.json +57 -0
- package/engineering/tools/physics/rules/gb_electrical_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_fasteners_rules.json +73 -0
- package/engineering/tools/physics/rules/gb_housing_rules.json +41 -0
- package/engineering/tools/physics/rules/gb_manufacturing_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_material_verify_rules.json +72 -0
- package/engineering/tools/physics/rules/gb_materials_rules.json +377 -0
- package/engineering/tools/physics/rules/gb_safety_rules.json +89 -0
- package/engineering/tools/physics/rules/gb_springs_rules.json +41 -0
- package/engineering/tools/physics/rules/gb_standards_registry.json +1646 -0
- package/engineering/tools/physics/rules/gb_structural_rules.json +201 -0
- package/engineering/tools/physics/rules/gb_surface_rules.json +25 -0
- package/engineering/tools/physics/rules/gb_transmission_rules.json +233 -0
- package/engineering/tools/physics/rules/housing_rules.json +48 -0
- package/engineering/tools/physics/rules/manifest.json +54 -0
- package/engineering/tools/physics/rules/mold_rules.json +48 -0
- package/engineering/tools/physics/rules/structural_rules.json +56 -0
- package/engineering/tools/physics/rules/transmission_rules.json +48 -0
- package/engineering/tools/physics/simulation_report.py +829 -0
- package/engineering/tools/physics_bridge.py +2685 -0
- package/engineering/tools/profile-manifest.ps1 +72 -0
- package/engineering/tools/run_regression.py +109 -0
- package/engineering/tools/settings.py +419 -0
- package/engineering/tools/solidworks-modeling.md +519 -0
- package/engineering/tools/sw_bridge.py +8215 -0
- package/engineering/tools/sw_guard.py +1066 -0
- package/engineering/tools/sw_surface.py +87 -0
- package/engineering/tools/swapi.py +14766 -0
- package/engineering/tools/verify_sync.py +218 -0
- package/engineering/tools/visual_check.py +2589 -0
- package/engineering/tools/webots_env.py +121 -0
- package/engineering/tools/webots_mcp/__init__.py +3 -0
- package/engineering/tools/webots_mcp/__main__.py +3 -0
- package/engineering/tools/webots_mcp/assembly.py +391 -0
- package/engineering/tools/webots_mcp/bootstrap.py +55 -0
- package/engineering/tools/webots_mcp/controller_worker.py +124 -0
- package/engineering/tools/webots_mcp/evidence.py +288 -0
- package/engineering/tools/webots_mcp/fake_worker.py +69 -0
- package/engineering/tools/webots_mcp/fault_resources.py +121 -0
- package/engineering/tools/webots_mcp/host.py +45 -0
- package/engineering/tools/webots_mcp/ledger.py +73 -0
- package/engineering/tools/webots_mcp/owned_job.py +70 -0
- package/engineering/tools/webots_mcp/physical_gate.py +187 -0
- package/engineering/tools/webots_mcp/physics.py +152 -0
- package/engineering/tools/webots_mcp/pipeline.py +108 -0
- package/engineering/tools/webots_mcp/recipes.py +129 -0
- package/engineering/tools/webots_mcp/repair.py +132 -0
- package/engineering/tools/webots_mcp/repair_trial.py +375 -0
- package/engineering/tools/webots_mcp/runtime.py +311 -0
- package/engineering/tools/webots_mcp/server.py +217 -0
- package/engineering/tools/webots_mcp/sw_export.py +509 -0
- package/engineering/tools/webots_mcp/transport.py +156 -0
- package/engineering/tools/workflow_gate.py +6134 -0
- package/package.json +64 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
physics/ — Physics-in-the-Loop 物理验证子系统
|
|
4
|
+
==============================================
|
|
5
|
+
从 IJCAI 论文 "Physics-in-the-Loop: A Hybrid Agentic Architecture for
|
|
6
|
+
Validated CAD Engineering Design" 中提取的工程化实现。
|
|
7
|
+
|
|
8
|
+
核心能力:
|
|
9
|
+
- 载荷工况 JSON 解析与校验(load_case.py)
|
|
10
|
+
- 材料数据库与覆盖策略(material_db.py)
|
|
11
|
+
- 几何门禁检查(geometry_gate.py)
|
|
12
|
+
- STEP 导出 + 网格数据生成(mesh_adapter.py)
|
|
13
|
+
- 解析/数值 FEA 求解(fea_solver.py)
|
|
14
|
+
- 结构化仿真报告(simulation_report.py)
|
|
15
|
+
- 迭代状态管理(design_state.py)
|
|
16
|
+
- 自动修正规则引擎(refine_rules.py)
|
|
17
|
+
|
|
18
|
+
分层策略(按可用工具自动降级):
|
|
19
|
+
Level 0 解析解:悬臂梁 / 简支梁 / 轴受载 / 薄板近似
|
|
20
|
+
Level 1 杆系求解器:2D truss 框架
|
|
21
|
+
Level 2 Gmsh + CalculiX / Code_Aster 外部求解器
|
|
22
|
+
Level 3 SolidWorks Simulation API(若有授权)
|
|
23
|
+
|
|
24
|
+
命令入口:
|
|
25
|
+
python sw_bridge.py physics-validate-case <load_case.json>
|
|
26
|
+
python sw_bridge.py physics-build <part.sldprt> <load_case.json> [params.json]
|
|
27
|
+
python sw_bridge.py physics-simulate <part.sldprt> <load_case.json>
|
|
28
|
+
python sw_bridge.py physics-report <run_id>
|
|
29
|
+
python sw_bridge.py physics-recommend <report.json>
|
|
30
|
+
python sw_bridge.py physics-refine <load_case.json> [max_iter=N]
|
|
31
|
+
python sw_bridge.py physics-status
|
|
32
|
+
"""
|
|
33
|
+
import os
|
|
34
|
+
import sys
|
|
35
|
+
|
|
36
|
+
# 让本目录可被 import(无论调用方工作目录)
|
|
37
|
+
_HERE = os.path.dirname(os.path.abspath(__file__))
|
|
38
|
+
if _HERE not in sys.path:
|
|
39
|
+
sys.path.insert(0, _HERE)
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
"load_case",
|
|
43
|
+
"material_db",
|
|
44
|
+
"geometry_gate",
|
|
45
|
+
"mesh_adapter",
|
|
46
|
+
"fea_solver",
|
|
47
|
+
"simulation_report",
|
|
48
|
+
"design_state",
|
|
49
|
+
"refine_rules",
|
|
50
|
+
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
simulation_report.py — 结构化仿真报告生成
|
|
4
|
+
==========================================
|
|
5
|
+
(已在 simulation_report.py 中定义,此文件为向后兼容别名)
|
|
6
|
+
"""
|
|
7
|
+
# 保持兼容:重新导入主模块
|
|
8
|
+
from simulation_report import ( # noqa: F401
|
|
9
|
+
build_report,
|
|
10
|
+
save_report,
|
|
11
|
+
report_to_markdown,
|
|
12
|
+
)
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
design_state.py — 迭代状态管理
|
|
4
|
+
================================
|
|
5
|
+
记录每一轮迭代的参数变更、仿真结果、以及回滚点。
|
|
6
|
+
支持版本化追踪:每轮都有唯一 run_id,可通过 parent_run_id 建立链条。
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import json
|
|
12
|
+
import time
|
|
13
|
+
from typing import Any, Optional
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
STATE_DIR_NAME = "physics_runs"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DesignState:
|
|
20
|
+
"""管理一个物理闭环迭代的完整状态。"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, output_dir: str, load_case_path: str):
|
|
23
|
+
self.output_dir = output_dir
|
|
24
|
+
self.load_case_path = load_case_path
|
|
25
|
+
self.runs: list[dict] = []
|
|
26
|
+
self.current_run_id: Optional[str] = None
|
|
27
|
+
self._load_state()
|
|
28
|
+
|
|
29
|
+
def _load_state(self):
|
|
30
|
+
"""从磁盘加载已有状态(恢复中断的迭代)。"""
|
|
31
|
+
state_file = os.path.join(self.output_dir, "_state.json")
|
|
32
|
+
if os.path.exists(state_file):
|
|
33
|
+
try:
|
|
34
|
+
with open(state_file, "r", encoding="utf-8") as f:
|
|
35
|
+
data = json.load(f)
|
|
36
|
+
self.runs = data.get("runs", [])
|
|
37
|
+
self.current_run_id = data.get("current_run_id")
|
|
38
|
+
except Exception:
|
|
39
|
+
self.runs = []
|
|
40
|
+
self.current_run_id = None
|
|
41
|
+
|
|
42
|
+
def _save_state(self):
|
|
43
|
+
"""持久化状态到磁盘。"""
|
|
44
|
+
os.makedirs(self.output_dir, exist_ok=True)
|
|
45
|
+
state_file = os.path.join(self.output_dir, "_state.json")
|
|
46
|
+
with open(state_file, "w", encoding="utf-8") as f:
|
|
47
|
+
json.dump({
|
|
48
|
+
"runs": self.runs,
|
|
49
|
+
"current_run_id": self.current_run_id,
|
|
50
|
+
"load_case_path": self.load_case_path,
|
|
51
|
+
"updated_at": time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
52
|
+
}, f, ensure_ascii=False, indent=2)
|
|
53
|
+
|
|
54
|
+
def new_run(self, run_id: str) -> dict:
|
|
55
|
+
"""开始新一轮迭代,返回空状态模板。"""
|
|
56
|
+
run = {
|
|
57
|
+
"run_id": run_id,
|
|
58
|
+
"iteration": len(self.runs) + 1,
|
|
59
|
+
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
60
|
+
"design_params": {},
|
|
61
|
+
"geometry_check": {},
|
|
62
|
+
"fea_result": {},
|
|
63
|
+
"report_path": "",
|
|
64
|
+
"status": "IN_PROGRESS",
|
|
65
|
+
"parent_run_id": self.current_run_id,
|
|
66
|
+
"changes_from_parent": {},
|
|
67
|
+
}
|
|
68
|
+
self.runs.append(run)
|
|
69
|
+
self.current_run_id = run_id
|
|
70
|
+
self._save_state()
|
|
71
|
+
return run
|
|
72
|
+
|
|
73
|
+
def update_run(self, run_id: str, updates: dict) -> dict:
|
|
74
|
+
"""更新指定轮次的状态。"""
|
|
75
|
+
for run in self.runs:
|
|
76
|
+
if run["run_id"] == run_id:
|
|
77
|
+
run.update(updates)
|
|
78
|
+
self._save_state()
|
|
79
|
+
return run
|
|
80
|
+
raise KeyError(f"run_id not found: {run_id}")
|
|
81
|
+
|
|
82
|
+
def get_current(self) -> Optional[dict]:
|
|
83
|
+
"""获取当前轮次状态。"""
|
|
84
|
+
for run in reversed(self.runs):
|
|
85
|
+
if run["run_id"] == self.current_run_id:
|
|
86
|
+
return run
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
def get_history(self) -> list[dict]:
|
|
90
|
+
"""获取所有历史轮次。"""
|
|
91
|
+
return list(self.runs)
|
|
92
|
+
|
|
93
|
+
def get_last_passing(self) -> Optional[dict]:
|
|
94
|
+
"""获取最后一个通过的门禁/仿真的轮次(用于回滚)。"""
|
|
95
|
+
for run in reversed(self.runs):
|
|
96
|
+
if run.get("status") == "PASS":
|
|
97
|
+
return run
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
def add_screenshot(self, run_id: str, image_path: str):
|
|
101
|
+
"""为指定轮次添加截图记录。"""
|
|
102
|
+
for run in self.runs:
|
|
103
|
+
if run["run_id"] == run_id:
|
|
104
|
+
if "screenshots" not in run:
|
|
105
|
+
run["screenshots"] = []
|
|
106
|
+
run["screenshots"].append(image_path)
|
|
107
|
+
self._save_state()
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
def get_convergence_data(self) -> dict:
|
|
111
|
+
"""提取收敛数据(安全系数、质量、位移随迭代的变化)。"""
|
|
112
|
+
history = self.get_history()
|
|
113
|
+
if not history:
|
|
114
|
+
return {"series": [], "converged": False}
|
|
115
|
+
|
|
116
|
+
series = []
|
|
117
|
+
for run in history:
|
|
118
|
+
fr = run.get("fea_result", {})
|
|
119
|
+
series.append({
|
|
120
|
+
"iteration": run.get("iteration", 0),
|
|
121
|
+
"run_id": run.get("run_id", ""),
|
|
122
|
+
"safety_factor": fr.get("safety_factor"),
|
|
123
|
+
"max_stress_mpa": fr.get("max_von_mises_mpa"),
|
|
124
|
+
"max_displacement_mm": fr.get("max_displacement_mm"),
|
|
125
|
+
"volume_mm3": fr.get("volume_mm3"),
|
|
126
|
+
"mass_kg": fr.get("mass_kg"),
|
|
127
|
+
"status": run.get("status"),
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
# 判断是否收敛:最后3轮状态均为 PASS
|
|
131
|
+
last_3 = series[-3:] if len(series) >= 3 else series
|
|
132
|
+
converged = all(s.get("status") == "PASS" for s in last_3) if last_3 else False
|
|
133
|
+
|
|
134
|
+
return {"series": series, "converged": converged, "total_iterations": len(series)}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def get_default_output_dir(base_dir: str = None) -> str:
|
|
138
|
+
"""获取默认输出目录。"""
|
|
139
|
+
if base_dir is None:
|
|
140
|
+
tools_dir = os.path.dirname(os.path.abspath(__file__))
|
|
141
|
+
base_dir = os.path.join(tools_dir, "..", "..", "output")
|
|
142
|
+
return os.path.join(base_dir, STATE_DIR_NAME)
|