新增曲柄滑块批量仿真接口
This commit is contained in:
@@ -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_CrankSlider" ||
|
||||
req_cmd == "Cmd_FourBar_CrankSlider_Simulate")
|
||||
{
|
||||
return handleFourBarCommand(req_cmd, req_param);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,82 @@
|
||||
#include "KinematicsWebAPI.h"
|
||||
#include "FourBarMechanism/CrankSliderMechanism.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace
|
||||
{
|
||||
// 将机构点位转换为接口统一 JSON。
|
||||
json buildPointsJson(const MechanismState &state)
|
||||
{
|
||||
json points_json;
|
||||
for (const auto &point_pair : state.Points)
|
||||
{
|
||||
points_json[point_pair.first] = {
|
||||
{"x", point_pair.second.X},
|
||||
{"y", point_pair.second.Y}};
|
||||
}
|
||||
return points_json;
|
||||
}
|
||||
|
||||
// 将机构姿态转换为接口统一 JSON。
|
||||
json buildPosesJson(const MechanismState &state)
|
||||
{
|
||||
json poses_json;
|
||||
for (const auto &pose_pair : state.Poses)
|
||||
{
|
||||
poses_json[pose_pair.first] = {
|
||||
{"tx", pose_pair.second.tx},
|
||||
{"ty", pose_pair.second.ty},
|
||||
{"tz", pose_pair.second.tz},
|
||||
{"qx", pose_pair.second.qx},
|
||||
{"qy", pose_pair.second.qy},
|
||||
{"qz", pose_pair.second.qz},
|
||||
{"qw", pose_pair.second.qw}};
|
||||
}
|
||||
return poses_json;
|
||||
}
|
||||
|
||||
// 将机构角度数据转换为接口统一 JSON。
|
||||
json buildAnglesJson(const MechanismState &state)
|
||||
{
|
||||
json angles_json;
|
||||
for (const auto &angle_pair : state.Angles)
|
||||
{
|
||||
angles_json[angle_pair.first] = angle_pair.second;
|
||||
}
|
||||
return angles_json;
|
||||
}
|
||||
|
||||
// 将二维点列表转换为轨迹 JSON 数组。
|
||||
json buildTrajectoryJson(const std::vector<Vector2D> &points)
|
||||
{
|
||||
json trajectory_json = json::array();
|
||||
for (const auto &point : points)
|
||||
{
|
||||
trajectory_json.push_back({
|
||||
{"x", point.X},
|
||||
{"y", point.Y}});
|
||||
}
|
||||
return trajectory_json;
|
||||
}
|
||||
|
||||
// 组装单帧机构状态,供实时接口和批量仿真接口复用。
|
||||
json buildFrameJson(const MechanismState &state, int frame, double time, double angleDeg)
|
||||
{
|
||||
json frame_json;
|
||||
frame_json["frame"] = frame;
|
||||
frame_json["time"] = time;
|
||||
frame_json["angleDeg"] = angleDeg;
|
||||
frame_json["input_value"] = state.InputValue;
|
||||
frame_json["points"] = buildPointsJson(state);
|
||||
frame_json["poses"] = buildPosesJson(state);
|
||||
frame_json["angles"] = buildAnglesJson(state);
|
||||
if (state.hasWarning())
|
||||
{
|
||||
frame_json["warning"] = state.WarningMessage;
|
||||
}
|
||||
return frame_json;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const json &req_param)
|
||||
{
|
||||
@@ -11,11 +88,19 @@ json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const js
|
||||
double L_BS = req_param.value("L_BS", 2.0);
|
||||
double S_OFS = req_param.value("S_OFS", 0.0);
|
||||
double angleDeg = req_param.value("angleDeg", 0.0);
|
||||
double startAngleDeg = req_param.value("startAngleDeg", 0.0);
|
||||
double endAngleDeg = req_param.value("endAngleDeg", 360.0);
|
||||
double duration = req_param.value("duration", 2.0);
|
||||
double stepTime = req_param.value("stepTime", 0.02);
|
||||
|
||||
log("Parameters: L_AB=" + std::to_string(L_AB) +
|
||||
", L_BS=" + std::to_string(L_BS) +
|
||||
", S_OFS=" + std::to_string(S_OFS) +
|
||||
", angleDeg=" + std::to_string(angleDeg));
|
||||
", angleDeg=" + std::to_string(angleDeg) +
|
||||
", startAngleDeg=" + std::to_string(startAngleDeg) +
|
||||
", endAngleDeg=" + std::to_string(endAngleDeg) +
|
||||
", duration=" + std::to_string(duration) +
|
||||
", stepTime=" + std::to_string(stepTime));
|
||||
|
||||
std::unique_ptr<CrankSliderMechanism> mechanism(createCrankSliderMechanism());
|
||||
mechanism->setL_AB(L_AB);
|
||||
@@ -32,6 +117,78 @@ json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const js
|
||||
{"validation_warnings", validation.Warnings}};
|
||||
}
|
||||
|
||||
if (req_cmd == "Cmd_FourBar_CrankSlider_Simulate")
|
||||
{
|
||||
if (duration <= 0.0)
|
||||
{
|
||||
return {
|
||||
{"success", false},
|
||||
{"error", "Invalid simulation parameters"},
|
||||
{"validation_errors", json::array({"duration 必须大于 0"})},
|
||||
{"validation_warnings", json::array()}};
|
||||
}
|
||||
|
||||
if (stepTime <= 0.0 || stepTime > duration)
|
||||
{
|
||||
return {
|
||||
{"success", false},
|
||||
{"error", "Invalid simulation parameters"},
|
||||
{"validation_errors", json::array({"stepTime 必须大于 0 且不能大于 duration"})},
|
||||
{"validation_warnings", json::array()}};
|
||||
}
|
||||
|
||||
const int frameCount = static_cast<int>(std::ceil(duration / stepTime)) + 1;
|
||||
if (frameCount < 2 || frameCount > 1000)
|
||||
{
|
||||
return {
|
||||
{"success", false},
|
||||
{"error", "Invalid simulation parameters"},
|
||||
{"validation_errors", json::array({"仿真帧数必须在 2 到 1000 之间"})},
|
||||
{"validation_warnings", json::array()}};
|
||||
}
|
||||
|
||||
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 currentAngleDeg = startAngleDeg + (endAngleDeg - startAngleDeg) * progress;
|
||||
MechanismState state = mechanism->calculate(currentAngleDeg);
|
||||
if (state.hasError())
|
||||
{
|
||||
return {
|
||||
{"success", false},
|
||||
{"error", state.ErrorMessage},
|
||||
{"failed_frame", frame},
|
||||
{"failed_time", currentTime},
|
||||
{"failed_angleDeg", currentAngleDeg}};
|
||||
}
|
||||
|
||||
frames_json.push_back(buildFrameJson(state, frame, currentTime, currentAngleDeg));
|
||||
}
|
||||
|
||||
json result;
|
||||
result["success"] = true;
|
||||
result["frames"] = frames_json;
|
||||
result["frame_count"] = frameCount;
|
||||
result["duration"] = duration;
|
||||
result["stepTime"] = stepTime;
|
||||
result["startAngleDeg"] = startAngleDeg;
|
||||
result["endAngleDeg"] = endAngleDeg;
|
||||
result["trajectory"] = buildTrajectoryJson(mechanism->getTrajectoryPoints());
|
||||
result["slider_trajectory"] = buildTrajectoryJson(mechanism->getSliderTrajectory());
|
||||
result["parameters"] = {
|
||||
{"L_AB", L_AB},
|
||||
{"L_BS", L_BS},
|
||||
{"S_OFS", S_OFS},
|
||||
{"startAngleDeg", startAngleDeg},
|
||||
{"endAngleDeg", endAngleDeg},
|
||||
{"duration", duration},
|
||||
{"stepTime", stepTime}};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MechanismState state = mechanism->calculate(angleDeg);
|
||||
if (state.hasError())
|
||||
{
|
||||
@@ -43,35 +200,9 @@ json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const js
|
||||
json result;
|
||||
result["success"] = true;
|
||||
|
||||
json points_json;
|
||||
for (const auto &point_pair : state.Points)
|
||||
{
|
||||
points_json[point_pair.first] = {
|
||||
{"x", point_pair.second.X},
|
||||
{"y", point_pair.second.Y}};
|
||||
}
|
||||
result["points"] = points_json;
|
||||
|
||||
json poses_json;
|
||||
for (const auto &pose_pair : state.Poses)
|
||||
{
|
||||
poses_json[pose_pair.first] = {
|
||||
{"tx", pose_pair.second.tx},
|
||||
{"ty", pose_pair.second.ty},
|
||||
{"tz", pose_pair.second.tz},
|
||||
{"qx", pose_pair.second.qx},
|
||||
{"qy", pose_pair.second.qy},
|
||||
{"qz", pose_pair.second.qz},
|
||||
{"qw", pose_pair.second.qw}};
|
||||
}
|
||||
result["poses"] = poses_json;
|
||||
|
||||
json angles_json;
|
||||
for (const auto &angle_pair : state.Angles)
|
||||
{
|
||||
angles_json[angle_pair.first] = angle_pair.second;
|
||||
}
|
||||
result["angles"] = angles_json;
|
||||
result["points"] = buildPointsJson(state);
|
||||
result["poses"] = buildPosesJson(state);
|
||||
result["angles"] = buildAnglesJson(state);
|
||||
|
||||
result["input_value"] = state.InputValue;
|
||||
if (state.hasWarning())
|
||||
@@ -79,23 +210,8 @@ json KinematicsWebAPI::handleFourBarCommand(const std::string &req_cmd, const js
|
||||
result["warning"] = state.WarningMessage;
|
||||
}
|
||||
|
||||
json trajectory_json = json::array();
|
||||
for (const auto &point : mechanism->getTrajectoryPoints())
|
||||
{
|
||||
trajectory_json.push_back({
|
||||
{"x", point.X},
|
||||
{"y", point.Y}});
|
||||
}
|
||||
result["trajectory"] = trajectory_json;
|
||||
|
||||
json slider_trajectory_json = json::array();
|
||||
for (const auto &point : mechanism->getSliderTrajectory())
|
||||
{
|
||||
slider_trajectory_json.push_back({
|
||||
{"x", point.X},
|
||||
{"y", point.Y}});
|
||||
}
|
||||
result["slider_trajectory"] = slider_trajectory_json;
|
||||
result["trajectory"] = buildTrajectoryJson(mechanism->getTrajectoryPoints());
|
||||
result["slider_trajectory"] = buildTrajectoryJson(mechanism->getSliderTrajectory());
|
||||
|
||||
result["parameters"] = {
|
||||
{"L_AB", L_AB},
|
||||
|
||||
Reference in New Issue
Block a user