2025-04-28 12:25:20 +08:00
|
|
|
/**
|
|
|
|
* @file XNModelObject.cpp
|
|
|
|
* @author jinchao
|
|
|
|
* @brief 模型基类源文件
|
|
|
|
* @version 1.0
|
|
|
|
* @date 2024-11-07
|
|
|
|
*
|
|
|
|
* @copyright Copyright (c) 2024 XN
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include "XNModelObject.h"
|
|
|
|
#include "XNModelObject_p.h"
|
|
|
|
#include "XNFramework.h"
|
|
|
|
#include "XNThreadManager.h"
|
|
|
|
#include "XNModelManager.h"
|
|
|
|
#include "XNDDSManager.h"
|
|
|
|
#include "XNIDL/XNSimStatusPubSubTypes.hpp"
|
|
|
|
|
|
|
|
// 默认构造函数
|
2025-05-20 15:39:40 +08:00
|
|
|
XNModelObject::XNModelObject() : XNObject(new XNModelObjectPrivate())
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// 默认析构函数
|
|
|
|
XNModelObject::~XNModelObject()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
XNModelObject::XNModelObject(PrivateType *p) : XNObject(p)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2025-05-20 16:41:46 +08:00
|
|
|
void XNModelObject::SetFramework(XNFrameworkPtr framework)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_framework = framework;
|
|
|
|
}
|
|
|
|
|
|
|
|
XNFrameworkPtr XNModelObject::GetFramework() const
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
return d->_framework;
|
|
|
|
}
|
|
|
|
|
2025-04-28 12:25:20 +08:00
|
|
|
// 获取模型描述
|
2025-05-20 15:39:40 +08:00
|
|
|
const std::string &XNModelObject::GetDescription()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
return d->_sDescription;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置模型描述
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::SetDescription(const std::string &sDescription)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_sDescription = sDescription;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取作者
|
2025-05-20 15:39:40 +08:00
|
|
|
const std::string &XNModelObject::GetAuthor()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
return d->_sAuthor;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置作者
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::SetAuthor(const std::string &sAuthor)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_sAuthor = sAuthor;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取模型配置文件路径
|
2025-05-20 15:39:40 +08:00
|
|
|
const std::string &XNModelObject::GetXmlPath()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
return d->_sXmlPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置模型配置文件路径
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::SetXmlPath(const std::string &sXmlPath)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_sXmlPath = sXmlPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取模型创建时间
|
2025-05-20 15:39:40 +08:00
|
|
|
const XNTimePoint &XNModelObject::GetCreateTime()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
return d->_cCreatTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置模型创建时间
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::SetCreateTime(const XNTimePoint &cTime)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_cCreatTime = cTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取模型修改时间
|
2025-05-20 15:39:40 +08:00
|
|
|
const XNTimePoint &XNModelObject::GetChangeTime()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
return d->_cChangeTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置模型修改时间
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::SetChangeTime(const XNTimePoint &cTime)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_cChangeTime = cTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取模型版本号
|
2025-05-20 15:39:40 +08:00
|
|
|
const std::string &XNModelObject::GetVersion()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
return d->_sVersion;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置模型版本号
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::SetVersion(const std::string &sVersion)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_sVersion = sVersion;
|
|
|
|
}
|
|
|
|
|
2025-05-21 12:17:50 +08:00
|
|
|
void XNModelObject::SetInitializeType(uint32_t initialType)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_initialType = initialType;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::SetThreadID(uint32_t threadID)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_threadID = threadID;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XNModelObject::GetThreadID() const
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
return d->_threadID;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XNModelObject::GetRunFreq() const
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
return d->_runFreq;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::SetRunFreq(uint32_t runFreq)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_runFreq = runFreq;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XNModelObject::GetRunNode() const
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
return d->_runNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::SetRunNode(uint32_t runNode)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_runNode = runNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XNModelObject::GetRunPriority() const
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
return d->_runPriority;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::SetRunPriority(uint32_t runPriority)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_runPriority = runPriority;
|
|
|
|
}
|
|
|
|
|
|
|
|
double XNModelObject::GetSetFreq() const
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
return d->_setFreq;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::SetSetFreq(double setFreq)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_setFreq = setFreq;
|
|
|
|
}
|
|
|
|
|
2025-06-04 14:00:46 +08:00
|
|
|
const std::string &XNModelObject::GetLibPath()
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
return d->_sLibPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::SetLibPath(const std::string &sLibPath)
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
d->_sLibPath = sLibPath;
|
|
|
|
}
|
|
|
|
|
2025-04-28 12:25:20 +08:00
|
|
|
// 初始化函数
|
2025-05-21 12:17:50 +08:00
|
|
|
void XNModelObject::Initialize()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-05-21 12:17:50 +08:00
|
|
|
if (d->_initialType == 0) {
|
2025-05-27 15:16:11 +08:00
|
|
|
ParseXml();
|
|
|
|
} else {
|
|
|
|
ParseConfig();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::ParseXml()
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
// 读取配置文件,设置循环执行函数
|
|
|
|
std::ifstream file(GetXmlPath());
|
|
|
|
if (!file.is_open()) {
|
|
|
|
LOG_WARNING("0x2161 Failed to open the model configuration file: %1!", GetXmlPath());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
tinyxml2::XMLDocument doc;
|
|
|
|
doc.LoadFile(GetXmlPath().c_str());
|
|
|
|
tinyxml2::XMLElement *rootNode = doc.FirstChildElement("Model");
|
|
|
|
if (!rootNode) {
|
|
|
|
LOG_WARNING("0x2161 Failed to parse model configuration file: %1!", GetXmlPath());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// 读取配置文件的模型参数
|
|
|
|
const char *modelName = rootNode->FirstChildElement("Name")->GetText();
|
|
|
|
if (!modelName || std::string(modelName) != GetObjectName()) {
|
|
|
|
LOG_WARNING("0x2162 The model name in the configuration file of model %1 is not consistent "
|
|
|
|
"with the model name in the configuration file of model %2!",
|
|
|
|
GetObjectName(), modelName ? modelName : "null");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
d->_sDescription = rootNode->FirstChildElement("Description")->GetText();
|
|
|
|
d->_sAuthor = rootNode->FirstChildElement("Author")->GetText();
|
|
|
|
d->_sVersion = rootNode->FirstChildElement("Version")->GetText();
|
|
|
|
|
|
|
|
// 使用标准C++时间处理
|
|
|
|
std::string createTimeStr = rootNode->FirstChildElement("CreateTime")->GetText();
|
|
|
|
std::string changeTimeStr = rootNode->FirstChildElement("ChangeTime")->GetText();
|
|
|
|
d->_cCreatTime = XNSim::parseISOTime(createTimeStr);
|
|
|
|
d->_cChangeTime = XNSim::parseISOTime(changeTimeStr);
|
|
|
|
|
|
|
|
std::string funcNode = rootNode->FirstChildElement("Node")->GetText();
|
|
|
|
d->_runPriority = XNSim::safe_stoi(rootNode->FirstChildElement("Priority")->GetText());
|
|
|
|
|
|
|
|
// 检查运行节点是否是 "x-x" 形式
|
|
|
|
size_t tmp = funcNode.find('-');
|
|
|
|
if (tmp == std::string::npos || tmp == 0) {
|
|
|
|
LOG_WARNING("0x2162 The value of the run node attribute in the configuration file of model "
|
|
|
|
"%1 is not in the x-x format, registration not executed!",
|
|
|
|
GetObjectName());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 使用标准C++字符串处理
|
|
|
|
d->_runFreq = XNSim::safe_stoi(funcNode.substr(0, tmp));
|
|
|
|
d->_runNode = XNSim::safe_stoi(funcNode.substr(tmp + 1));
|
|
|
|
|
|
|
|
// 注册周期性函数
|
|
|
|
auto framework = GetFramework();
|
|
|
|
if (framework) {
|
|
|
|
auto threadManager = framework->GetThreadManager();
|
|
|
|
if (threadManager) {
|
|
|
|
threadManager->RegisterFunction(
|
|
|
|
GetUniqueId(), std::bind(&XNModelObject::StepUpdate, this), d->_threadID,
|
|
|
|
d->_runFreq, d->_runNode, d->_runPriority);
|
2025-05-20 15:39:40 +08:00
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 加载动态库
|
|
|
|
const char *mathlib = rootNode->FirstChildElement("MathLib")->GetText();
|
|
|
|
if (mathlib && strlen(mathlib) > 0) {
|
|
|
|
// 使用标准C++文件路径处理
|
|
|
|
std::filesystem::path xmlPath(GetXmlPath());
|
|
|
|
d->_sLibPath = xmlPath.parent_path().string() + "/" + mathlib;
|
|
|
|
|
|
|
|
// 使用标准C++动态库加载
|
|
|
|
d->_dynamicLib = dlopen(d->_sLibPath.c_str(), RTLD_LAZY);
|
|
|
|
if (d->_dynamicLib) { // 动态库加载成功
|
|
|
|
LOG_INFO("0x2163 Model %1 loaded algorithm dynamic library %2 successfully!",
|
|
|
|
GetObjectName(), d->_sLibPath);
|
|
|
|
} else {
|
2025-05-20 15:39:40 +08:00
|
|
|
LOG_WARNING(
|
2025-05-27 15:16:11 +08:00
|
|
|
"0x2160 Model %1 failed to find algorithm dynamic library %2, will not call "
|
|
|
|
"algorithm!",
|
|
|
|
GetObjectName(), d->_sLibPath);
|
|
|
|
d->_dynamicLib = nullptr;
|
2025-05-20 15:39:40 +08:00
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
2025-05-27 15:16:11 +08:00
|
|
|
// 处理指令列表
|
|
|
|
tinyxml2::XMLElement *nodeCmds = rootNode->FirstChildElement("CommandList");
|
|
|
|
if (nodeCmds) {
|
|
|
|
for (tinyxml2::XMLElement *nodeCmd = nodeCmds->FirstChildElement("Command");
|
|
|
|
nodeCmd != nullptr; nodeCmd = nodeCmd->NextSiblingElement("Command")) {
|
|
|
|
const char *cmdName = nodeCmd->Attribute("Name");
|
|
|
|
const char *cmdDescription = nodeCmd->Attribute("Description");
|
|
|
|
const char *cmdCall = nodeCmd->Attribute("Call");
|
|
|
|
// TODO: 处理命令列表
|
2025-05-20 15:39:40 +08:00
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::ParseConfig()
|
|
|
|
{
|
|
|
|
T_D();
|
|
|
|
std::vector<std::string> nameAndVersion = XNSim::split(GetXmlPath(), ",");
|
|
|
|
std::string planeName = nameAndVersion[0];
|
|
|
|
std::string modelName = nameAndVersion[1];
|
|
|
|
std::string modelVersion = nameAndVersion[2];
|
|
|
|
// 获取数据库路径
|
|
|
|
std::string dbPath = std::getenv("XNCore");
|
|
|
|
if (dbPath.empty()) {
|
|
|
|
LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dbPath += "/database/XNSim.db";
|
|
|
|
|
|
|
|
// 打开数据库
|
|
|
|
sqlite3 *db;
|
|
|
|
if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
|
|
|
|
LOG_ERROR("0x1016 打开数据库失败: %1", sqlite3_errmsg(db));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 准备SQL语句
|
|
|
|
std::string sql =
|
|
|
|
"SELECT * FROM XNModelsVersion WHERE PlaneName = ? AND ClassName = ? AND Version = ?";
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
|
|
|
|
LOG_ERROR("0x1017 准备SQL语句失败: %1", sqlite3_errmsg(db));
|
|
|
|
sqlite3_close(db);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 绑定参数
|
|
|
|
if (sqlite3_bind_text(stmt, 1, planeName.c_str(), planeName.length(), nullptr) != SQLITE_OK
|
|
|
|
|| sqlite3_bind_text(stmt, 2, modelName.c_str(), modelName.length(), nullptr) != SQLITE_OK
|
|
|
|
|| sqlite3_bind_text(stmt, 3, modelVersion.c_str(), modelVersion.length(), nullptr)
|
|
|
|
!= SQLITE_OK) {
|
|
|
|
LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db));
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
sqlite3_close(db);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 执行查询
|
|
|
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
|
|
|
LOG_ERROR("0x1019 未找到机型为%1,模型名称为%2,版本号%3的记录", planeName.c_str(),
|
|
|
|
modelName.c_str(), modelVersion.c_str());
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
sqlite3_close(db);
|
|
|
|
return;
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
2025-05-27 15:16:11 +08:00
|
|
|
d->_sDescription = XNSim::getStringFromSqlite3(stmt, 7);
|
|
|
|
d->_sAuthor = XNSim::getStringFromSqlite3(stmt, 6);
|
|
|
|
d->_sVersion = XNSim::getStringFromSqlite3(stmt, 2);
|
|
|
|
|
|
|
|
// 解析时间
|
|
|
|
std::string createTimeStr = XNSim::getStringFromSqlite3(stmt, 8);
|
|
|
|
std::string changeTimeStr = XNSim::getStringFromSqlite3(stmt, 9);
|
|
|
|
d->_cCreatTime = XNSim::parseISOTime(createTimeStr);
|
|
|
|
d->_cChangeTime = XNSim::parseISOTime(changeTimeStr);
|
|
|
|
d->_runFreq = XNSim::safe_stoi(XNSim::getStringFromSqlite3(stmt, 10));
|
|
|
|
d->_runNode = XNSim::safe_stoi(XNSim::getStringFromSqlite3(stmt, 11));
|
|
|
|
d->_runPriority = XNSim::safe_stoi(XNSim::getStringFromSqlite3(stmt, 12));
|
|
|
|
|
|
|
|
// 注册周期性函数
|
|
|
|
auto framework = GetFramework();
|
|
|
|
if (framework) {
|
|
|
|
auto threadManager = framework->GetThreadManager();
|
|
|
|
if (threadManager) {
|
|
|
|
threadManager->RegisterFunction(
|
|
|
|
GetUniqueId(), std::bind(&XNModelObject::StepUpdate, this), d->_threadID,
|
|
|
|
d->_runFreq, d->_runNode, d->_runPriority);
|
2025-05-20 15:39:40 +08:00
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
2025-05-27 15:16:11 +08:00
|
|
|
// 加载动态库
|
|
|
|
std::string mathlib = XNSim::getStringFromSqlite3(stmt, 13);
|
|
|
|
if (mathlib.length() > 0) {
|
|
|
|
// 使用标准C++文件路径处理
|
2025-06-04 15:26:50 +08:00
|
|
|
//std::filesystem::path xmlPath(GetXmlPath());
|
|
|
|
//d->_sLibPath = xmlPath.parent_path().string() + "/" + mathlib;
|
|
|
|
std::string libPath = d->_sLibPath + "/" + mathlib;
|
2025-05-27 15:16:11 +08:00
|
|
|
// 使用标准C++动态库加载
|
2025-06-04 15:26:50 +08:00
|
|
|
d->_dynamicLib = dlopen(libPath.c_str(), RTLD_LAZY);
|
2025-05-27 15:16:11 +08:00
|
|
|
if (d->_dynamicLib) { // 动态库加载成功
|
2025-06-04 15:26:50 +08:00
|
|
|
LOG_INFO("0x2163 模型 %1 加载数据包模型动态库 %2 成功!", GetObjectName(), libPath);
|
2025-05-27 15:16:11 +08:00
|
|
|
} else {
|
2025-06-04 15:26:50 +08:00
|
|
|
LOG_WARNING("0x2160 模型 %1 未找到数据包模型动态库 %2, 将不调用数据包模型!",
|
|
|
|
GetObjectName(), libPath);
|
2025-05-27 15:16:11 +08:00
|
|
|
d->_dynamicLib = nullptr;
|
2025-04-28 12:25:20 +08:00
|
|
|
}
|
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
|
|
|
|
// TODO: 读取模型命令列表
|
|
|
|
// 清理资源
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
sqlite3_close(db);
|
2025-04-28 12:25:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 单步执行函数
|
|
|
|
void XNModelObject::StepUpdate()
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
|
|
|
uint32_t setFreq = d->_setFreq < 1.0 ? 1 : (uint32_t)d->_setFreq;
|
2025-05-22 16:22:48 +08:00
|
|
|
if (d->_dataWriter != nullptr && d->_runCnt > 0 && d->_runCnt % setFreq == 0) {
|
2025-04-28 12:25:20 +08:00
|
|
|
XNSim::XNSimStatus::XNModelStatus modelStatus;
|
2025-05-20 15:39:40 +08:00
|
|
|
modelStatus.XNModelName(GetObjectName());
|
|
|
|
modelStatus.XNModelID(GetUniqueId());
|
2025-04-28 12:25:20 +08:00
|
|
|
modelStatus.XNModelSt(1);
|
2025-05-20 15:39:40 +08:00
|
|
|
modelStatus.XNModelThID(d->_threadID);
|
2025-04-28 12:25:20 +08:00
|
|
|
modelStatus.XNModelNode(d->_runNode);
|
|
|
|
modelStatus.XNModelPro(d->_runPriority);
|
|
|
|
modelStatus.XNModelRunCnt(d->_runCnt);
|
|
|
|
timespec now;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
|
|
double time_diff =
|
|
|
|
(now.tv_sec - d->_lastRunTime.tv_sec) + (now.tv_nsec - d->_lastRunTime.tv_nsec) / 1.0E9;
|
|
|
|
modelStatus.XNMdlCurFreq(d->_setFreq / time_diff);
|
|
|
|
modelStatus.XNMdlSetFreq(d->_setFreq);
|
2025-05-22 16:22:48 +08:00
|
|
|
d->_dataWriter->write(&modelStatus);
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_lastRunTime = now;
|
2025-05-20 15:39:40 +08:00
|
|
|
LOG_DEBUG("Model: %1 Write DDS!", GetObjectName());
|
2025-04-28 12:25:20 +08:00
|
|
|
}
|
|
|
|
d->_runCnt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 运行前最后准备函数
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::PrepareForExecute()
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
d->_runCnt = 0;
|
|
|
|
// 注册DDS
|
|
|
|
RegisterDDSParticipant();
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &d->_lastRunTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
void XNModelObject::RegisterDDSParticipant()
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
|
|
|
auto framework = GetFramework();
|
|
|
|
if (framework == nullptr) {
|
|
|
|
LOG_WARNING("Failed to get Framework!");
|
2025-04-28 12:25:20 +08:00
|
|
|
return;
|
2025-05-20 15:39:40 +08:00
|
|
|
}
|
|
|
|
auto ddsManager = framework->GetDDSManager();
|
|
|
|
if (ddsManager == nullptr) {
|
|
|
|
LOG_WARNING("Failed to get DDSManager!");
|
2025-04-28 12:25:20 +08:00
|
|
|
return;
|
2025-05-20 15:39:40 +08:00
|
|
|
}
|
2025-05-22 16:22:48 +08:00
|
|
|
uint32_t MyID = GetUniqueId();
|
|
|
|
d->_dataWriter = ddsManager->RegisterPublisher<XNSim::XNSimStatus::XNModelStatusPubSubType>(
|
|
|
|
"XNSim::XNSimStatus::XNModelStatus", MyID);
|
2025-04-28 12:25:20 +08:00
|
|
|
}
|
|
|
|
|
2025-05-21 12:17:50 +08:00
|
|
|
int XNModelObject::RegisterEventHandler(const std::string &eventName, XNEventCallback callback,
|
|
|
|
bool async, XNEvent::Priority priority)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
|
|
|
// 获取事件管理器
|
2025-05-20 15:39:40 +08:00
|
|
|
auto framework = GetFramework();
|
|
|
|
if (framework == nullptr) {
|
|
|
|
LOG_WARNING("Failed to get Framework!");
|
2025-04-28 12:25:20 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
XNEventManagerPtr eventManager = framework->GetEventManager();
|
2025-04-28 12:25:20 +08:00
|
|
|
if (eventManager == nullptr) {
|
|
|
|
LOG_WARNING("Failed to get EventManager!");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 注册事件处理器
|
2025-05-20 15:39:40 +08:00
|
|
|
return eventManager->RegisterEventHandler(eventName, callback, GetUniqueId(), async, priority);
|
2025-04-28 12:25:20 +08:00
|
|
|
}
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
void XNModelObject::TriggerEvent(const std::string &eventName, const std::any &eventData,
|
2025-04-28 12:25:20 +08:00
|
|
|
bool forceAsync, XNEvent::Priority priority)
|
|
|
|
{
|
|
|
|
// 获取事件管理器
|
2025-05-20 15:39:40 +08:00
|
|
|
auto framework = GetFramework();
|
|
|
|
if (framework == nullptr) {
|
|
|
|
LOG_WARNING("Failed to get Framework!");
|
2025-04-28 12:25:20 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
XNEventManagerPtr eventManager = framework->GetEventManager();
|
2025-04-28 12:25:20 +08:00
|
|
|
if (eventManager == nullptr) {
|
|
|
|
LOG_WARNING("Failed to get EventManager!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 触发事件
|
|
|
|
eventManager->TriggerEvent(eventName, eventData, forceAsync, priority);
|
|
|
|
}
|