新增曲柄滑块批量仿真接口
This commit is contained in:
@@ -579,20 +579,24 @@
|
||||
<input id="angleInput" type="number" step="1" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="stepInput">扫描步长</label>
|
||||
<input id="stepInput" type="number" min="1" max="90" step="1" />
|
||||
<label for="stepInput">stepTime 步长时间</label>
|
||||
<input id="stepInput" type="number" min="0.01" max="1" step="0.01" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="scanEndInput">扫描终止角</label>
|
||||
<input id="scanEndInput" type="number" min="1" max="720" step="1" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="durationInput">duration 总时长</label>
|
||||
<input id="durationInput" type="number" min="0.02" max="60" step="0.01" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="secondary" id="validButton" type="button">有效样例</button>
|
||||
<button class="secondary" id="invalidButton" type="button">异常样例</button>
|
||||
<button class="primary" id="runButton" type="button">调用接口</button>
|
||||
<button class="primary" id="scanButton" type="button">角度扫描</button>
|
||||
<button class="primary" id="scanButton" type="button">仿真扫描</button>
|
||||
</div>
|
||||
<div class="message" id="inputMessage" aria-live="polite"></div>
|
||||
|
||||
@@ -756,6 +760,7 @@
|
||||
const angleInput = document.getElementById("angleInput");
|
||||
const stepInput = document.getElementById("stepInput");
|
||||
const scanEndInput = document.getElementById("scanEndInput");
|
||||
const durationInput = document.getElementById("durationInput");
|
||||
const requestOutput = document.getElementById("requestOutput");
|
||||
const topSuccess = document.getElementById("topSuccess");
|
||||
const businessSuccess = document.getElementById("businessSuccess");
|
||||
@@ -813,6 +818,25 @@
|
||||
};
|
||||
}
|
||||
|
||||
// 按批量仿真接口格式组装曲柄滑块请求。
|
||||
function buildSimulationRequest(input, sim, reqCode = `FOURBAR_SIM_${Date.now()}`) {
|
||||
return {
|
||||
msg: "fourbar crank slider simulate",
|
||||
req_code: reqCode,
|
||||
req_from: "fourbar_test_page",
|
||||
req_cmd: "Cmd_FourBar_CrankSlider_Simulate",
|
||||
req_param: {
|
||||
L_AB: input.L_AB,
|
||||
L_BS: input.L_BS,
|
||||
S_OFS: input.S_OFS,
|
||||
startAngleDeg: input.angleDeg,
|
||||
endAngleDeg: sim.endAngleDeg,
|
||||
duration: sim.duration,
|
||||
stepTime: sim.stepTime,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 将当前表单同步到请求 JSON 文本框。
|
||||
function refreshRequestPreview() {
|
||||
try {
|
||||
@@ -828,8 +852,9 @@
|
||||
lBsInput.value = sample.L_BS;
|
||||
sOfsInput.value = sample.S_OFS;
|
||||
angleInput.value = sample.angleDeg;
|
||||
stepInput.value = stepInput.value || "10";
|
||||
stepInput.value = stepInput.value || "0.02";
|
||||
scanEndInput.value = scanEndInput.value || "360";
|
||||
durationInput.value = durationInput.value || "2";
|
||||
refreshRequestPreview();
|
||||
}
|
||||
|
||||
@@ -1116,6 +1141,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 调用曲柄滑块批量仿真接口并解析 JSON 响应。
|
||||
async function callFourBarSimulation(input, sim) {
|
||||
const module = await ensureWasm();
|
||||
const payload = JSON.stringify(buildSimulationRequest(input, sim));
|
||||
let requestPtr = 0;
|
||||
let responsePtr = 0;
|
||||
try {
|
||||
requestPtr = allocString(module, payload);
|
||||
responsePtr = module._func(requestPtr);
|
||||
return JSON.parse(module.UTF8ToString(responsePtr));
|
||||
} finally {
|
||||
if (responsePtr) module._smart_free_string(responsePtr);
|
||||
if (requestPtr) module._free(requestPtr);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算前端几何校验值,用于和 WASM 返回点位对照。
|
||||
function calculateLocalGeometry(input) {
|
||||
const angle = (input.angleDeg * Math.PI) / 180;
|
||||
@@ -1419,43 +1460,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 多角度调用接口,生成轨迹和位移曲线。
|
||||
// 调用批量仿真接口,生成轨迹和位移曲线。
|
||||
async function runScan() {
|
||||
try {
|
||||
setMessage("");
|
||||
const baseInput = readInput();
|
||||
const step = Number(stepInput.value);
|
||||
const stepTime = Number(stepInput.value);
|
||||
const scanEnd = Number(scanEndInput.value);
|
||||
if (!Number.isInteger(step) || step < 1 || step > 90) {
|
||||
throw new Error("扫描步长必须是 1 到 90 之间的整数");
|
||||
const duration = Number(durationInput.value);
|
||||
if (!Number.isFinite(stepTime) || stepTime <= 0 || stepTime > 1) {
|
||||
throw new Error("stepTime 必须是 0 到 1 秒之间的有效数字");
|
||||
}
|
||||
if (!Number.isFinite(scanEnd) || scanEnd <= 0 || scanEnd > 720) {
|
||||
throw new Error("扫描终止角必须在 1 到 720 之间");
|
||||
}
|
||||
if (!Number.isFinite(duration) || duration <= 0 || duration > 60) {
|
||||
throw new Error("duration 必须在 0 到 60 秒之间");
|
||||
}
|
||||
|
||||
requestStatus.textContent = "扫描中";
|
||||
requestStatus.className = "badge warn";
|
||||
const rows = [];
|
||||
for (let angle = 0; angle <= scanEnd + 0.000001; angle += step) {
|
||||
const input = { ...baseInput, angleDeg: angle };
|
||||
const response = await callFourBar(input, `FOURBAR_SCAN_${angle}`);
|
||||
const data = response.res_data || {};
|
||||
rows.push({
|
||||
angle,
|
||||
ok: response.success === true && data.success === true && !data.error,
|
||||
B: data.points?.B,
|
||||
S: data.points?.S,
|
||||
error: data.error || response.msg || "",
|
||||
});
|
||||
const response = await callFourBarSimulation(baseInput, {
|
||||
endAngleDeg: scanEnd,
|
||||
duration,
|
||||
stepTime,
|
||||
});
|
||||
const data = response.res_data || {};
|
||||
if (response.success !== true || data.success !== true || data.error) {
|
||||
throw new Error(data.error || response.msg || "批量仿真接口返回失败");
|
||||
}
|
||||
const rows = (data.frames || []).map((frame) => ({
|
||||
frame: frame.frame,
|
||||
time: frame.time,
|
||||
angle: frame.angleDeg,
|
||||
ok: Boolean(frame.points?.B && frame.points?.S),
|
||||
B: frame.points?.B,
|
||||
S: frame.points?.S,
|
||||
error: "",
|
||||
}));
|
||||
|
||||
latestScan = rows;
|
||||
scanOutput.textContent = JSON.stringify(rows, null, 2);
|
||||
scanOutput.textContent = JSON.stringify(response, null, 2);
|
||||
renderScanCharts(rows);
|
||||
scanAnimation.frame = 0;
|
||||
requestStatus.textContent = "扫描完成";
|
||||
requestStatus.className = "badge ok";
|
||||
setMessage(`扫描完成:${rows.filter((row) => row.ok).length}/${rows.length} 个角度有效`, "is-ok");
|
||||
setMessage(`仿真完成:${rows.filter((row) => row.ok).length}/${rows.length} 帧有效`, "is-ok");
|
||||
} catch (error) {
|
||||
requestStatus.textContent = "扫描失败";
|
||||
requestStatus.className = "badge error";
|
||||
@@ -1472,7 +1522,7 @@
|
||||
scanOutput.classList.toggle("hidden", isResponse);
|
||||
}
|
||||
|
||||
[lAbInput, lBsInput, sOfsInput, angleInput].forEach((input) => {
|
||||
[lAbInput, lBsInput, sOfsInput, angleInput, stepInput, scanEndInput, durationInput].forEach((input) => {
|
||||
input.addEventListener("input", refreshRequestPreview);
|
||||
});
|
||||
|
||||
@@ -1495,8 +1545,9 @@
|
||||
scanTab.addEventListener("click", () => setActiveTab("scan"));
|
||||
|
||||
loadSample(validSample);
|
||||
stepInput.value = "10";
|
||||
stepInput.value = "0.02";
|
||||
scanEndInput.value = "360";
|
||||
durationInput.value = "2";
|
||||
refreshRequestPreview();
|
||||
renderThreeMechanism(calculateLocalGeometry(validSample), validSample, {
|
||||
title: "有效样例预览",
|
||||
|
||||
Reference in New Issue
Block a user