Files
smart_wasm/include/QuadrupedRobotSimulation/OPERATION.h
2026-06-01 16:57:39 +08:00

348 lines
9.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// OPERATION.h
#ifndef OPERATION_H
#define OPERATION_H
#include <string>
#include <vector>
#include <cmath>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
// 毫米转米函数
inline double MMToM(double MM)
{
return std::round(MM / 1000.0 * 100000.0) / 100000.0; // 保留5位小数
}
// 帧内容类
class C_ObjStates
{
public:
std::string i = ""; // 模型代码
std::string tx = ""; // tx
std::string ty = ""; // ty
std::string tz = ""; // tz
std::string qx = ""; // qx
std::string qy = ""; // qy
std::string qz = ""; // qz
std::string qw = ""; // qw
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_ObjStates, i, tx, ty, tz, qx, qy, qz, qw)
// 工艺类
class C_Craft
{
public:
std::string CraftCode;
std::string CraftValue;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Craft, CraftCode, CraftValue)
// 帧信号类
class C_Signalwrite
{
public:
std::string TagID;
std::string TagValue;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Signalwrite, TagID, TagValue)
// 可见性类
class C_Visible
{
public:
std::string ModelCode;
std::string Visible;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Visible, ModelCode, Visible)
// 旋转类
class C_Rotation
{
public:
std::string ModelCode;
std::string Axis;
int Rate = 0;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Rotation, ModelCode, Axis, Rate)
// 等待类
class C_Wait
{
public:
std::string WaitStr;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Wait, WaitStr)
// 附加类
class C_Attach
{
public:
std::string AttachToModelCode = "";
std::string AttachToModelName = "";
bool IsTwoWay = false;
bool IsAttach = false;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Attach, AttachToModelCode, AttachToModelName, IsTwoWay, IsAttach)
// 帧类
class C_Frames
{
public:
std::string time = "0.01"; // 帧时间
std::vector<C_ObjStates> objStates;
std::vector<C_Craft> crafts;
std::vector<C_Signalwrite> signalwrites;
std::vector<C_Visible> visibles;
std::vector<C_Rotation> rotations;
std::vector<C_Wait> waits;
std::vector<C_Attach> attachs;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Frames, time, objStates, crafts, signalwrites,
visibles, rotations, waits, attachs)
// 操作类(帧集合)
class C_OPERATION
{
public:
std::vector<C_Frames> frames;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_OPERATION, frames)
// 项目操作类
class P_OPERATION
{
public:
C_OPERATION OPERATION;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(P_OPERATION, OPERATION)
// 功能类
class P_OPERATION_Func
{
public:
/**
* 生成线框播放数据
* @param PP_FrameValue 帧率值
* @param modelCode 模型代码
* @param ptQList 点位置和四元数列表 [x, y, z, qx, qy, qz, qw]
* @return 帧列表
*/
static std::vector<C_Frames> _MakeCraftPlayData_Line_Frame(
int PP_FrameValue,
const std::string &modelCode,
const std::vector<std::vector<double>> &ptQList)
{
std::vector<C_Frames> frames;
for (size_t i = 0; i < ptQList.size(); i++)
{
const auto &currQ = ptQList[i];
if (currQ.size() < 7)
{
// 数据不足,跳过
continue;
}
// 创建对象状态
C_ObjStates objState;
objState.i = modelCode;
objState.tx = std::to_string(MMToM(currQ[0]));
objState.ty = std::to_string(MMToM(currQ[1]));
objState.tz = std::to_string(MMToM(currQ[2]));
objState.qx = std::to_string(currQ[3]);
objState.qy = std::to_string(currQ[4]);
objState.qz = std::to_string(currQ[5]);
objState.qw = std::to_string(currQ[6]);
// 创建帧
C_Frames frame;
frame.time = std::to_string(PP_FrameValue * i / 1000.0);
frame.objStates.push_back(objState);
frames.push_back(frame);
}
return frames;
}
/**
* 生成线框播放数据(简化版本)
* @param frameRate 帧率
* @param modelCode 模型代码
* @param positions 位置数组 [x, y, z] (毫米)
* @param quaternions 四元数数组 [qx, qy, qz, qw]
* @return 帧列表
*/
static std::vector<C_Frames> MakeCraftPlayData_Simple(
int frameRate,
const std::string &modelCode,
const std::vector<std::vector<double>> &positions,
const std::vector<std::vector<double>> &quaternions)
{
if (positions.size() != quaternions.size())
{
// 数据长度不匹配,返回空列表
return {};
}
std::vector<C_Frames> frames;
for (size_t i = 0; i < positions.size(); i++)
{
if (positions[i].size() < 3 || quaternions[i].size() < 4)
{
continue;
}
// 创建对象状态
C_ObjStates objState;
objState.i = modelCode;
objState.tx = std::to_string(MMToM(positions[i][0]));
objState.ty = std::to_string(MMToM(positions[i][1]));
objState.tz = std::to_string(MMToM(positions[i][2]));
objState.qx = std::to_string(quaternions[i][0]);
objState.qy = std::to_string(quaternions[i][1]);
objState.qz = std::to_string(quaternions[i][2]);
objState.qw = std::to_string(quaternions[i][3]);
// 创建帧
C_Frames frame;
frame.time = std::to_string(i / static_cast<double>(frameRate));
frame.objStates.push_back(objState);
frames.push_back(frame);
}
return frames;
}
/**
* 生成完整的操作对象
* @param frameRate 帧率
* @param modelCode 模型代码
* @param positions 位置数组
* @param quaternions 四元数数组
* @return P_OPERATION对象
*/
static P_OPERATION MakeOperation(
int frameRate,
const std::string &modelCode,
const std::vector<std::vector<double>> &positions,
const std::vector<std::vector<double>> &quaternions)
{
auto frames = MakeCraftPlayData_Simple(frameRate, modelCode, positions, quaternions);
P_OPERATION operation;
operation.OPERATION.frames = frames;
return operation;
}
/**
* 添加信号写入到帧
* @param frame 目标帧
* @param tagID 标签ID
* @param tagValue 标签值
*/
static void AddSignalWrite(C_Frames &frame, const std::string &tagID, const std::string &tagValue)
{
C_Signalwrite signal;
signal.TagID = tagID;
signal.TagValue = tagValue;
frame.signalwrites.push_back(signal);
}
/**
* 添加工艺命令到帧
* @param frame 目标帧
* @param craftCode 工艺代码
* @param craftValue 工艺值
*/
static void AddCraft(C_Frames &frame, const std::string &craftCode, const std::string &craftValue)
{
C_Craft craft;
craft.CraftCode = craftCode;
craft.CraftValue = craftValue;
frame.crafts.push_back(craft);
}
/**
* 添加可见性控制到帧
* @param frame 目标帧
* @param modelCode 模型代码
* @param visible 是否可见 ("true" 或 "false")
*/
static void AddVisible(C_Frames &frame, const std::string &modelCode, const std::string &visible)
{
C_Visible visibleCmd;
visibleCmd.ModelCode = modelCode;
visibleCmd.Visible = visible;
frame.visibles.push_back(visibleCmd);
}
/**
* 添加旋转控制到帧
* @param frame 目标帧
* @param modelCode 模型代码
* @param axis 旋转轴 ("x", "y", "z")
* @param rate 旋转速率
*/
static void AddRotation(C_Frames &frame, const std::string &modelCode,
const std::string &axis, int rate)
{
C_Rotation rotation;
rotation.ModelCode = modelCode;
rotation.Axis = axis;
rotation.Rate = rate;
frame.rotations.push_back(rotation);
}
/**
* 添加等待命令到帧
* @param frame 目标帧
* @param waitStr 等待字符串
*/
static void AddWait(C_Frames &frame, const std::string &waitStr)
{
C_Wait wait;
wait.WaitStr = waitStr;
frame.waits.push_back(wait);
}
/**
* 添加附加命令到帧
* @param frame 目标帧
* @param attachToModelCode 附加目标模型代码
* @param attachToModelName 附加目标模型名称
* @param isTwoWay 是否双向附加
* @param isAttach 是否附加true=附加false=分离)
*/
static void AddAttach(C_Frames &frame, const std::string &attachToModelCode,
const std::string &attachToModelName,
bool isTwoWay, bool isAttach)
{
C_Attach attach;
attach.AttachToModelCode = attachToModelCode;
attach.AttachToModelName = attachToModelName;
attach.IsTwoWay = isTwoWay;
attach.IsAttach = isAttach;
frame.attachs.push_back(attach);
}
};
#endif // OPERATION_H