Initial commit: step2urdf tool with handtuned JSON import.
Includes FastAPI backend, vendored step2urdf frontend, and A7 handtuned arm JSON for URDF generation.
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
const state = {
|
||||
jobId: null,
|
||||
draft: null,
|
||||
};
|
||||
|
||||
const $ = (id) => document.getElementById(id);
|
||||
|
||||
function pretty(obj) {
|
||||
return JSON.stringify(obj, null, 2);
|
||||
}
|
||||
|
||||
async function refreshHealth() {
|
||||
const el = $("health");
|
||||
try {
|
||||
const res = await fetch("/api/health");
|
||||
const data = await res.json();
|
||||
const z = data.zhipu_configured ? `智谱 OK (${data.zhipu_model})` : "智谱未配置";
|
||||
const g = data.geometry?.available ? "几何后端可用" : "几何后端未装(占位 mesh)";
|
||||
el.textContent = `${z} · ${g}`;
|
||||
el.className = "pill " + (data.zhipu_configured ? "ok" : "warn");
|
||||
} catch (e) {
|
||||
el.textContent = "后端未连接";
|
||||
el.className = "pill warn";
|
||||
}
|
||||
}
|
||||
|
||||
$("btnParse").addEventListener("click", async () => {
|
||||
const file = $("file").files?.[0];
|
||||
if (!file) {
|
||||
$("parseOut").textContent = "请先选择 STEP 文件";
|
||||
$("parseOut").classList.add("error");
|
||||
return;
|
||||
}
|
||||
$("parseOut").classList.remove("error");
|
||||
$("parseOut").textContent = "解析中…";
|
||||
const fd = new FormData();
|
||||
fd.append("file", file);
|
||||
try {
|
||||
const res = await fetch("/api/parse", { method: "POST", body: fd });
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
const data = await res.json();
|
||||
state.jobId = data.job_id;
|
||||
$("btnPropose").disabled = false;
|
||||
$("parseOut").textContent = pretty({
|
||||
job_id: data.job_id,
|
||||
root_name: data.root_name,
|
||||
product_count: data.product_names?.length,
|
||||
product_names: data.product_names,
|
||||
stats: data.stats,
|
||||
});
|
||||
} catch (e) {
|
||||
$("parseOut").textContent = String(e);
|
||||
$("parseOut").classList.add("error");
|
||||
}
|
||||
});
|
||||
|
||||
$("btnPropose").addEventListener("click", async () => {
|
||||
if (!state.jobId) return;
|
||||
$("proposeOut").classList.remove("error");
|
||||
$("proposeOut").textContent = "调用智谱中(可能需要几十秒)…";
|
||||
try {
|
||||
const res = await fetch("/api/propose", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
job_id: state.jobId,
|
||||
profile: $("profile").value,
|
||||
robot_name: $("robotName").value || "A7",
|
||||
extra_hint: $("hint").value || "",
|
||||
}),
|
||||
});
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
const draft = await res.json();
|
||||
state.draft = draft;
|
||||
$("draftEditor").value = pretty(draft);
|
||||
$("btnExport").disabled = false;
|
||||
$("proposeOut").textContent = `links=${draft.links?.length || 0}, joints=${draft.joints?.length || 0}\n` +
|
||||
(draft.notes || []).map((n) => `- ${n}`).join("\n");
|
||||
} catch (e) {
|
||||
$("proposeOut").textContent = String(e);
|
||||
$("proposeOut").classList.add("error");
|
||||
}
|
||||
});
|
||||
|
||||
$("btnExport").addEventListener("click", async () => {
|
||||
if (!state.jobId) return;
|
||||
$("exportOut").classList.remove("error");
|
||||
try {
|
||||
const draft = JSON.parse($("draftEditor").value);
|
||||
state.draft = draft;
|
||||
const res = await fetch("/api/export", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
job_id: state.jobId,
|
||||
draft,
|
||||
include_meshes: true,
|
||||
}),
|
||||
});
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
const meta = await res.json();
|
||||
$("exportOut").textContent = pretty(meta);
|
||||
const name = draft.name || "robot";
|
||||
const a = $("dlLink");
|
||||
a.hidden = false;
|
||||
a.href = `/api/jobs/${state.jobId}/download/${encodeURIComponent(name)}`;
|
||||
a.textContent = `下载 ${name}.urdf`;
|
||||
} catch (e) {
|
||||
$("exportOut").textContent = String(e);
|
||||
$("exportOut").classList.add("error");
|
||||
}
|
||||
});
|
||||
|
||||
refreshHealth();
|
||||
Reference in New Issue
Block a user