diff --git a/docs/notes/接口调用履历.md b/docs/notes/接口调用履历.md index b912fa4..72c7111 100644 --- a/docs/notes/接口调用履历.md +++ b/docs/notes/接口调用履历.md @@ -444,6 +444,65 @@ func - `trajectory`:B 点整段轨迹 - `slider_trajectory`:S 点整段滑块轨迹 +### 6.3 `Cmd_FourBar_Simulate` + +用途: + +- 统一仿真 PDPS 连杆定义界面中的 `PRRR / RPRR / RRRP / RRRR` 四类结构 +- 输入机构类型、起始输入、结束输入、总时长和步长时间 +- 一次性返回逐帧点位、姿态、角度和轨迹,适合前端 Three.js 播放和 ECharts 曲线验证 + +调用履历: + +```text +func +-> dispatchCommand +-> handleFourBarCommand +-> simulateUnifiedFourBar +-> 按 mechanismType 创建或调用对应机构类 +-> validateParameters +-> for each frame: + -> calculate(currentInput) +-> 组装 frames / trajectory / parameters +``` + +类型映射: + +- `RRRP`:调用 `CrankSliderMechanism`,角度驱动曲柄滑块正解 +- `PRRR`:调用 `SliderCrankMechanism`,滑块位移驱动曲柄滑块逆解 +- `RPRR`:调用 `CrankRockingBlockMechanism_Forward`,当前按曲柄摇块正解承接 +- `RRRR`:调用 `FourBarMechanism`,角度驱动四转副四杆正解 + +主要公共入参: + +- `mechanismType`:`PRRR`、`RPRR`、`RRRP`、`RRRR` +- `startValue` / `endValue`:统一输入范围,角度驱动类型表示角度,`PRRR` 表示滑块 X +- `duration`:仿真总时长,单位秒 +- `stepTime`:仿真步长时间,单位秒 + +各类型参数: + +- `RRRP`:`L_AB`、`L_BS`、`S_OFS` +- `PRRR`:`L_AB`、`L_BS`、`S_OFS`,也可使用 `startSliderX` / `endSliderX` +- `RPRR`:`OA`、`AB`、`OC` +- `RRRR`:`L1`、`L2`、`L3`、`L4` + +主要出参: + +- `mechanismType`:实际仿真的机构类型 +- `inputName`:当前输入字段名,`angleDeg` 或 `sliderX` +- `frames[]`:逐帧仿真数据,每帧包含 `frame`、`time`、`inputValue`、`points`、`poses`、`angles` +- `trajectory`:主运动点轨迹 +- `slider_trajectory`:滑块轨迹,适用于 `RRRP / PRRR` +- `alternative_trajectory`:备选逆解轨迹,适用于 `PRRR` +- `trajectory_c`:C 点轨迹,适用于 `RRRR` +- `crank_circle`:曲柄端点轨迹,适用于 `RPRR / RRRR` +- `rocker_trajectory`:摇块轨迹,适用于 `RPRR` + +注意: + +- `RPRR` 当前先复用现有曲柄摇块正解类,PDPS 中输入/输出链节的方向、坐标系和安装约定后续如有更精确资料,可继续对齐参数语义。 + ## 7. 四足机器人接口履历 命令文件: diff --git a/public/fourbar_test.html b/public/fourbar_test.html index 08d8710..5b671b2 100644 --- a/public/fourbar_test.html +++ b/public/fourbar_test.html @@ -39,6 +39,7 @@ button, input, + select, textarea { font: inherit; } @@ -58,6 +59,7 @@ button:focus-visible, input:focus-visible, + select:focus-visible, textarea:focus-visible { outline: 3px solid rgba(15, 111, 143, 0.25); outline-offset: 2px; @@ -211,6 +213,7 @@ } input, + select, textarea { width: 100%; border: 1px solid var(--line); @@ -224,6 +227,11 @@ padding: 10px 11px; } + select { + min-height: 44px; + padding: 10px 11px; + } + textarea { min-height: 360px; resize: vertical; @@ -549,7 +557,7 @@

四连杆/曲柄滑块 WASM 验证台

-

Cmd_FourBar_CrankSlider · 点位 / 姿态 / 轨迹

+

Cmd_FourBar_Simulate · PRRR / RPRR / RRRP / RRRR

WASM 未加载
@@ -563,19 +571,36 @@
- + + +
+
+
- +
- +
- + + +
+
+ + +
+
+
@@ -583,8 +608,8 @@
- - + +
@@ -623,8 +648,8 @@
-
-
滑块 X
-
-
+
输出 X
+
-
完整性
@@ -644,49 +669,49 @@
等待接口数据 - 调用接口后显示当前 A-B-S 姿态,角度扫描后可播放 WASM 返回的连续点位。 + 调用接口后显示当前机构姿态,仿真扫描后可播放 WASM 返回的连续点位。
3D 视图 - 使用接口返回的 A、B、S 点直接驱动模型:蓝色为曲柄 AB,金色为连杆 BS,绿色为滑块,灰色为导轨。播放扫描时不会重新计算几何,只复用多次接口调用得到的点位序列。 + 使用接口返回点位直接驱动模型:蓝色为输入杆,金色为连接杆,绿色为输出滑块或输出杆,灰色为固定机架/导轨。播放扫描时不做前端几何重算,只复用 WASM 返回的逐帧点位。
-
+
机构当前姿态 - A-B-S + 拓扑
等待执行
机构当前姿态 - 显示固定铰点 A、曲柄端点 B 和滑块 S 的二维位置。A-B 是曲柄,B-S 是连杆,S 点落在 y=S_OFS 的滑块导轨上,用于核对单角度计算结果是否符合几何关系。 + 显示接口返回关键点的二维位置,并按当前机构类型连接输入杆、连接杆、输出杆或滑块。它用于核对单帧点位、杆长和装配方向是否符合预期。
B 点圆轨迹 - Crank path + 输入端轨迹
等待扫描
B 点圆轨迹 - 由测试页按角度多次调用接口后汇总生成,理论上应接近以 A 为圆心、L_AB 为半径的圆。它适合验证曲柄长度、角度单位和旋转方向。 + 展示仿真过程中主运动点的轨迹。对于角度驱动类型可用于检查曲柄半径、角度单位和旋转方向;对于滑块驱动类型可观察逆解得到的 B 点连续性。
- 滑块位移曲线 - S.x / angle + 输出位移曲线 + output / input
等待扫描
- 滑块位移曲线 - 横轴为输入角度,纵轴为接口返回的 S 点 x 坐标。曲线可用于检查连杆长度、偏置量和极限位置处的运动连续性。 + 输出位移曲线 + 横轴为接口输入值,纵轴为输出点 x 坐标。它适合检查输出链节或滑块在扫描范围内是否连续、是否存在极限位置跳变。
@@ -724,18 +749,73 @@ diff --git a/scripts/run_wasm_tests.js b/scripts/run_wasm_tests.js index 15496fe..7bf7db5 100644 --- a/scripts/run_wasm_tests.js +++ b/scripts/run_wasm_tests.js @@ -418,6 +418,71 @@ const suite = [ { path: "res_data.slider_trajectory", lengthEquals: 5 }, ], }, + { + id: "fourbar_unified_rrrp", + type: "static", + requestFile: "tests/testdata/fourbar/simulate_rrrp.json", + assertions: [ + { path: "success", equals: true }, + { path: "res_data.success", equals: true }, + { path: "res_data.mechanismType", equals: "RRRP" }, + { path: "res_data.frame_count", equals: 5 }, + { path: "res_data.frames", lengthEquals: 5 }, + { path: "res_data.frames.0.points.B.x", exists: true }, + { path: "res_data.frames.0.points.S.x", exists: true }, + { path: "res_data.trajectory", lengthEquals: 5 }, + { path: "res_data.slider_trajectory", lengthEquals: 5 }, + ], + }, + { + id: "fourbar_unified_prrr", + type: "static", + requestFile: "tests/testdata/fourbar/simulate_prrr.json", + assertions: [ + { path: "success", equals: true }, + { path: "res_data.success", equals: true }, + { path: "res_data.mechanismType", equals: "PRRR" }, + { path: "res_data.inputName", equals: "sliderX" }, + { path: "res_data.frame_count", equals: 5 }, + { path: "res_data.frames.0.points.B.x", exists: true }, + { path: "res_data.frames.0.points.S.x", exists: true }, + { path: "res_data.trajectory", lengthEquals: 5 }, + { path: "res_data.slider_trajectory", lengthEquals: 5 }, + { path: "res_data.alternative_trajectory", lengthEquals: 5 }, + ], + }, + { + id: "fourbar_unified_rprr", + type: "static", + requestFile: "tests/testdata/fourbar/simulate_rprr.json", + assertions: [ + { path: "success", equals: true }, + { path: "res_data.success", equals: true }, + { path: "res_data.mechanismType", equals: "RPRR" }, + { path: "res_data.frame_count", equals: 5 }, + { path: "res_data.frames.0.points.O.x", exists: true }, + { path: "res_data.frames.0.points.B.x", exists: true }, + { path: "res_data.trajectory", lengthEquals: 5 }, + { path: "res_data.crank_circle", lengthEquals: 5 }, + { path: "res_data.rocker_trajectory", lengthEquals: 5 }, + ], + }, + { + id: "fourbar_unified_rrrr", + type: "static", + requestFile: "tests/testdata/fourbar/simulate_rrrr.json", + assertions: [ + { path: "success", equals: true }, + { path: "res_data.success", equals: true }, + { path: "res_data.mechanismType", equals: "RRRR" }, + { path: "res_data.frame_count", equals: 5 }, + { path: "res_data.frames.0.points.A.x", exists: true }, + { path: "res_data.frames.0.points.D.x", exists: true }, + { path: "res_data.trajectory", lengthEquals: 5 }, + { path: "res_data.trajectory_c", lengthEquals: 5 }, + { path: "res_data.crank_circle", lengthEquals: 5 }, + ], + }, { id: "quadruped_points_from_motor_angles", type: "static", diff --git a/src/api/KinematicsWebAPI.Core.cpp b/src/api/KinematicsWebAPI.Core.cpp index 12ee8ec..61685bc 100644 --- a/src/api/KinematicsWebAPI.Core.cpp +++ b/src/api/KinematicsWebAPI.Core.cpp @@ -122,7 +122,8 @@ json KinematicsWebAPI::dispatchCommand(const std::string &req_cmd, const json &r return handleSpcCommand(req_cmd, req_param); } - if (req_cmd == "Cmd_FourBar_CrankSlider" || + if (req_cmd == "Cmd_FourBar_Simulate" || + req_cmd == "Cmd_FourBar_CrankSlider" || req_cmd == "Cmd_FourBar_CrankSlider_Simulate") { return handleFourBarCommand(req_cmd, req_param); diff --git a/src/api/KinematicsWebAPI.FourBarCommands.cpp b/src/api/KinematicsWebAPI.FourBarCommands.cpp index 2f02009..90d5607 100644 --- a/src/api/KinematicsWebAPI.FourBarCommands.cpp +++ b/src/api/KinematicsWebAPI.FourBarCommands.cpp @@ -1,9 +1,45 @@ #include "KinematicsWebAPI.h" #include "FourBarMechanism/CrankSliderMechanism.h" +#include "FourBarMechanism/CrankRockingBlockMechanism_Forward.h" +#include "FourBarMechanism/FourBarMechanism.h" +#include "FourBarMechanism/SliderCrankMechanism.h" #include +#include namespace { +// 读取兼容字段,便于新统一接口沿用旧曲柄滑块参数名。 +double valueAny(const json ¶m, std::initializer_list keys, double defaultValue) +{ + for (const char *key : keys) + { + if (param.contains(key) && param[key].is_number()) + { + return param[key].get(); + } + } + return defaultValue; +} + +// 构造统一的业务失败返回,供四类连杆仿真复用。 +json buildErrorJson(const std::string &error, const json &validationErrors = json::array(), const json &validationWarnings = json::array()) +{ + json result = { + {"success", false}, + {"error", error}}; + + if (!validationErrors.empty()) + { + result["validation_errors"] = validationErrors; + } + if (!validationWarnings.empty()) + { + result["validation_warnings"] = validationWarnings; + } + + return result; +} + // 将机构点位转换为接口统一 JSON。 json buildPointsJson(const MechanismState &state) { @@ -60,12 +96,14 @@ json buildTrajectoryJson(const std::vector &points) } // 组装单帧机构状态,供实时接口和批量仿真接口复用。 -json buildFrameJson(const MechanismState &state, int frame, double time, double angleDeg) +json buildFrameJson(const MechanismState &state, int frame, double time, double inputValue, const std::string &inputName) { json frame_json; frame_json["frame"] = frame; frame_json["time"] = time; - frame_json["angleDeg"] = angleDeg; + frame_json[inputName] = inputValue; + frame_json["inputName"] = inputName; + frame_json["inputValue"] = inputValue; frame_json["input_value"] = state.InputValue; frame_json["points"] = buildPointsJson(state); frame_json["poses"] = buildPosesJson(state); @@ -76,6 +114,260 @@ json buildFrameJson(const MechanismState &state, int frame, double time, double } return frame_json; } + +// 校验仿真时间参数并返回帧数。 +json validateSimulationTimeline(double duration, double stepTime, int &frameCount) +{ + if (duration <= 0.0) + { + return buildErrorJson("Invalid simulation parameters", json::array({"duration 必须大于 0"})); + } + + if (stepTime <= 0.0 || stepTime > duration) + { + return buildErrorJson("Invalid simulation parameters", json::array({"stepTime 必须大于 0 且不能大于 duration"})); + } + + frameCount = static_cast(std::ceil(duration / stepTime)) + 1; + if (frameCount < 2 || frameCount > 1000) + { + return buildErrorJson("Invalid simulation parameters", json::array({"仿真帧数必须在 2 到 1000 之间"})); + } + + return json(); +} + +// 将 ValidationResult 转换为统一业务错误。 +json validateOrError(const ValidationResult &validation) +{ + if (validation.isValid()) + { + return json(); + } + + return buildErrorJson("Invalid parameters", validation.Errors, validation.Warnings); +} + +// 按统一格式生成逐帧仿真数据。 +template +json buildSimulationFrames(int frameCount, double duration, double stepTime, double startValue, double endValue, const std::string &inputName, CalculateFunc calculate) +{ + json frames_json = json::array(); + for (int frame = 0; frame < frameCount; ++frame) + { + const double currentTime = frame == frameCount - 1 ? duration : stepTime * frame; + const double progress = duration <= 0.0 ? 0.0 : currentTime / duration; + const double currentValue = startValue + (endValue - startValue) * progress; + MechanismState state = calculate(currentValue); + if (state.hasError()) + { + return { + {"success", false}, + {"error", state.ErrorMessage}, + {"failed_frame", frame}, + {"failed_time", currentTime}, + {"failed_input", currentValue}, + {"failed_input_name", inputName}}; + } + + frames_json.push_back(buildFrameJson(state, frame, currentTime, currentValue, inputName)); + } + + return frames_json; +} + +// 统一四连杆仿真接口,覆盖 PDPS 的 PRRR/RPRR/RRRP/RRRR 四类结构。 +json simulateUnifiedFourBar(const json &req_param) +{ + const std::string mechanismType = req_param.value("mechanismType", "RRRP"); + const double duration = req_param.value("duration", 2.0); + const double stepTime = req_param.value("stepTime", 0.02); + int frameCount = 0; + + json timelineError = validateSimulationTimeline(duration, stepTime, frameCount); + if (!timelineError.is_null()) + { + return timelineError; + } + + if (mechanismType == "RRRP") + { + const double L_AB = req_param.value("L_AB", 0.5); + const double L_BS = req_param.value("L_BS", 2.0); + const double S_OFS = req_param.value("S_OFS", 0.0); + const double startAngleDeg = valueAny(req_param, {"startAngleDeg", "startValue", "angleDeg"}, 0.0); + const double endAngleDeg = valueAny(req_param, {"endAngleDeg", "endValue"}, 360.0); + + std::unique_ptr mechanism(createCrankSliderMechanism()); + mechanism->setL_AB(L_AB); + mechanism->setL_BS(L_BS); + mechanism->setS_OFS(S_OFS); + + json validationError = validateOrError(mechanism->validateParameters()); + if (!validationError.is_null()) + { + return validationError; + } + + json frames_json = buildSimulationFrames(frameCount, duration, stepTime, startAngleDeg, endAngleDeg, "angleDeg", [&](double value) { + return mechanism->calculate(value); + }); + if (!frames_json.is_array()) + { + return frames_json; + } + + return { + {"success", true}, + {"mechanismType", mechanismType}, + {"inputName", "angleDeg"}, + {"frames", frames_json}, + {"frame_count", frameCount}, + {"duration", duration}, + {"stepTime", stepTime}, + {"startValue", startAngleDeg}, + {"endValue", endAngleDeg}, + {"startAngleDeg", startAngleDeg}, + {"endAngleDeg", endAngleDeg}, + {"trajectory", buildTrajectoryJson(mechanism->getTrajectoryPoints())}, + {"slider_trajectory", buildTrajectoryJson(mechanism->getSliderTrajectory())}, + {"parameters", {{"mechanismType", mechanismType}, {"L_AB", L_AB}, {"L_BS", L_BS}, {"S_OFS", S_OFS}, {"startAngleDeg", startAngleDeg}, {"endAngleDeg", endAngleDeg}, {"duration", duration}, {"stepTime", stepTime}}}}; + } + + if (mechanismType == "PRRR") + { + const double L_AB = req_param.value("L_AB", 0.5); + const double L_BS = req_param.value("L_BS", 2.0); + const double S_OFS = req_param.value("S_OFS", 0.0); + + std::unique_ptr mechanism(createSliderCrankMechanism()); + mechanism->setLink(L_AB, L_BS, S_OFS); + + json validationError = validateOrError(mechanism->validateParameters()); + if (!validationError.is_null()) + { + return validationError; + } + + const auto inputRange = mechanism->getInputRange(); + const double startSliderX = valueAny(req_param, {"startSliderX", "startValue", "sliderX"}, inputRange.first); + const double endSliderX = valueAny(req_param, {"endSliderX", "endValue"}, inputRange.second); + json frames_json = buildSimulationFrames(frameCount, duration, stepTime, startSliderX, endSliderX, "sliderX", [&](double value) { + return mechanism->calculate(value); + }); + if (!frames_json.is_array()) + { + return frames_json; + } + + return { + {"success", true}, + {"mechanismType", mechanismType}, + {"inputName", "sliderX"}, + {"inputRange", {{"min", inputRange.first}, {"max", inputRange.second}}}, + {"frames", frames_json}, + {"frame_count", frameCount}, + {"duration", duration}, + {"stepTime", stepTime}, + {"startValue", startSliderX}, + {"endValue", endSliderX}, + {"startSliderX", startSliderX}, + {"endSliderX", endSliderX}, + {"trajectory", buildTrajectoryJson(mechanism->getTrajectoryPoints())}, + {"slider_trajectory", buildTrajectoryJson(mechanism->getSliderTrajectory())}, + {"alternative_trajectory", buildTrajectoryJson(mechanism->getAlternativeTrajectory())}, + {"parameters", {{"mechanismType", mechanismType}, {"L_AB", L_AB}, {"L_BS", L_BS}, {"S_OFS", S_OFS}, {"startSliderX", startSliderX}, {"endSliderX", endSliderX}, {"duration", duration}, {"stepTime", stepTime}}}}; + } + + if (mechanismType == "RRRR") + { + const double L1 = valueAny(req_param, {"L1", "L_AB"}, 1.0); + const double L2 = valueAny(req_param, {"L2", "L_BS"}, 3.0); + const double L3 = req_param.value("L3", 2.5); + const double L4 = req_param.value("L4", 3.5); + const double startAngleDeg = valueAny(req_param, {"startAngleDeg", "startValue", "angleDeg"}, 0.0); + const double endAngleDeg = valueAny(req_param, {"endAngleDeg", "endValue"}, 180.0); + + std::unique_ptr mechanism(createFourBarMechanism()); + mechanism->setLink(L1, L2, L3, L4); + + json validationError = validateOrError(mechanism->validateParameters()); + if (!validationError.is_null()) + { + return validationError; + } + + json frames_json = buildSimulationFrames(frameCount, duration, stepTime, startAngleDeg, endAngleDeg, "angleDeg", [&](double value) { + return mechanism->calculate(value); + }); + if (!frames_json.is_array()) + { + return frames_json; + } + + return { + {"success", true}, + {"mechanismType", mechanismType}, + {"inputName", "angleDeg"}, + {"frames", frames_json}, + {"frame_count", frameCount}, + {"duration", duration}, + {"stepTime", stepTime}, + {"startValue", startAngleDeg}, + {"endValue", endAngleDeg}, + {"startAngleDeg", startAngleDeg}, + {"endAngleDeg", endAngleDeg}, + {"trajectory", buildTrajectoryJson(mechanism->getTrajectoryPoints())}, + {"trajectory_c", buildTrajectoryJson(mechanism->getTrajectoryC())}, + {"crank_circle", buildTrajectoryJson(mechanism->getCrankCirclePoints())}, + {"parameters", {{"mechanismType", mechanismType}, {"L1", L1}, {"L2", L2}, {"L3", L3}, {"L4", L4}, {"startAngleDeg", startAngleDeg}, {"endAngleDeg", endAngleDeg}, {"duration", duration}, {"stepTime", stepTime}}}}; + } + + if (mechanismType == "RPRR") + { + const double OA = valueAny(req_param, {"OA", "L_AB"}, 1.0); + const double AB = valueAny(req_param, {"AB", "L_BS"}, 3.0); + const double OC = valueAny(req_param, {"OC", "L4"}, 3.0); + const double startAngleDeg = valueAny(req_param, {"startAngleDeg", "startValue", "angleDeg"}, 0.0); + const double endAngleDeg = valueAny(req_param, {"endAngleDeg", "endValue"}, 180.0); + + CrankRockingBlockMechanism_Forward mechanism; + mechanism.setLink(OA, AB, OC); + + json validationError = validateOrError(mechanism.validateParameters()); + if (!validationError.is_null()) + { + return validationError; + } + + json frames_json = buildSimulationFrames(frameCount, duration, stepTime, startAngleDeg, endAngleDeg, "angleDeg", [&](double value) { + return mechanism.calculate(value); + }); + if (!frames_json.is_array()) + { + return frames_json; + } + + return { + {"success", true}, + {"mechanismType", mechanismType}, + {"inputName", "angleDeg"}, + {"frames", frames_json}, + {"frame_count", frameCount}, + {"duration", duration}, + {"stepTime", stepTime}, + {"startValue", startAngleDeg}, + {"endValue", endAngleDeg}, + {"startAngleDeg", startAngleDeg}, + {"endAngleDeg", endAngleDeg}, + {"trajectory", buildTrajectoryJson(mechanism.getTrajectoryPoints())}, + {"crank_circle", buildTrajectoryJson(mechanism.getCrankCirclePoints())}, + {"rocker_trajectory", buildTrajectoryJson(mechanism.getRockerTrajectory())}, + {"parameters", {{"mechanismType", mechanismType}, {"OA", OA}, {"AB", AB}, {"OC", OC}, {"startAngleDeg", startAngleDeg}, {"endAngleDeg", endAngleDeg}, {"duration", duration}, {"stepTime", stepTime}}}}; + } + + return buildErrorJson("Unsupported mechanismType: " + mechanismType, json::array({"mechanismType 必须是 PRRR、RPRR、RRRP、RRRR 之一"})); +} } // namespace json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const json &req_param) @@ -84,6 +376,11 @@ json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const js { log("Handling " + req_cmd + " command"); + if (req_cmd == "Cmd_FourBar_Simulate") + { + return simulateUnifiedFourBar(req_param); + } + double L_AB = req_param.value("L_AB", 0.5); double L_BS = req_param.value("L_BS", 2.0); double S_OFS = req_param.value("S_OFS", 0.0); @@ -111,10 +408,10 @@ json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const js if (!validation.isValid()) { return { - {"success", false}, - {"error", "Invalid parameters"}, - {"validation_errors", validation.Errors}, - {"validation_warnings", validation.Warnings}}; + {"success", false}, + {"error", "Invalid parameters"}, + {"validation_errors", validation.Errors}, + {"validation_warnings", validation.Warnings}}; } if (req_cmd == "Cmd_FourBar_CrankSlider_Simulate") @@ -164,7 +461,7 @@ json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const js {"failed_angleDeg", currentAngleDeg}}; } - frames_json.push_back(buildFrameJson(state, frame, currentTime, currentAngleDeg)); + frames_json.push_back(buildFrameJson(state, frame, currentTime, currentAngleDeg, "angleDeg")); } json result; diff --git a/tests/testdata/fourbar/simulate_prrr.json b/tests/testdata/fourbar/simulate_prrr.json new file mode 100644 index 0000000..6a15e13 --- /dev/null +++ b/tests/testdata/fourbar/simulate_prrr.json @@ -0,0 +1,16 @@ +{ + "msg": "fourbar unified simulate PRRR", + "req_code": "CASE_FB_UNIFIED_PRRR", + "req_from": "wasm_test", + "req_cmd": "Cmd_FourBar_Simulate", + "req_param": { + "mechanismType": "PRRR", + "L_AB": 0.5, + "L_BS": 2.0, + "S_OFS": 0.0, + "startSliderX": 1.5, + "endSliderX": 2.5, + "duration": 1.0, + "stepTime": 0.25 + } +} diff --git a/tests/testdata/fourbar/simulate_rprr.json b/tests/testdata/fourbar/simulate_rprr.json new file mode 100644 index 0000000..2110c9f --- /dev/null +++ b/tests/testdata/fourbar/simulate_rprr.json @@ -0,0 +1,16 @@ +{ + "msg": "fourbar unified simulate RPRR", + "req_code": "CASE_FB_UNIFIED_RPRR", + "req_from": "wasm_test", + "req_cmd": "Cmd_FourBar_Simulate", + "req_param": { + "mechanismType": "RPRR", + "OA": 1.0, + "AB": 3.0, + "OC": 3.0, + "startAngleDeg": 0.0, + "endAngleDeg": 180.0, + "duration": 1.0, + "stepTime": 0.25 + } +} diff --git a/tests/testdata/fourbar/simulate_rrrp.json b/tests/testdata/fourbar/simulate_rrrp.json new file mode 100644 index 0000000..8466b4f --- /dev/null +++ b/tests/testdata/fourbar/simulate_rrrp.json @@ -0,0 +1,16 @@ +{ + "msg": "fourbar unified simulate RRRP", + "req_code": "CASE_FB_UNIFIED_RRRP", + "req_from": "wasm_test", + "req_cmd": "Cmd_FourBar_Simulate", + "req_param": { + "mechanismType": "RRRP", + "L_AB": 0.5, + "L_BS": 2.0, + "S_OFS": 0.0, + "startAngleDeg": 0.0, + "endAngleDeg": 180.0, + "duration": 1.0, + "stepTime": 0.25 + } +} diff --git a/tests/testdata/fourbar/simulate_rrrr.json b/tests/testdata/fourbar/simulate_rrrr.json new file mode 100644 index 0000000..140a6df --- /dev/null +++ b/tests/testdata/fourbar/simulate_rrrr.json @@ -0,0 +1,17 @@ +{ + "msg": "fourbar unified simulate RRRR", + "req_code": "CASE_FB_UNIFIED_RRRR", + "req_from": "wasm_test", + "req_cmd": "Cmd_FourBar_Simulate", + "req_param": { + "mechanismType": "RRRR", + "L1": 1.0, + "L2": 3.0, + "L3": 2.5, + "L4": 3.5, + "startAngleDeg": 0.0, + "endAngleDeg": 180.0, + "duration": 1.0, + "stepTime": 0.25 + } +}