348 lines
9.0 KiB
C++
348 lines
9.0 KiB
C++
// 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
|