update 排序算法生效校验

This commit is contained in:
codeboss 2025-06-29 22:58:45 +08:00
parent f88c5f2810
commit 6769ada4b6
7 changed files with 380 additions and 133 deletions

View File

@ -122,7 +122,7 @@ LogicalNode::LogicalNode(NodeKind t /*= NodeKind::ACTIONNODE*/)
:_node_type(t) {
}
void LogicalNode::setParent(std::weak_ptr<LogicalNode> pnode)
void LogicalNode::_set_parent_node(std::weak_ptr<LogicalNode> pnode)
{
this->_parent_bind = pnode;
}
@ -153,7 +153,7 @@ int LogicalNode::getID() const
return this->_node_id;
}
QString LogicalNode::runtimeName() const
QString LogicalNode::rtName() const
{
return QString("%1(%2)").arg(this->typeName()).arg(getID());
}
@ -163,8 +163,8 @@ std::weak_ptr<LogicalNode> LogicalNode::parent() const
return this->_parent_bind;
}
BehaviorMapNode::BehaviorMapNode(std::shared_ptr<MessageLoader> core)
:LogicalNode(NodeKind::MAPNODE), MapKernal(core) {
BehaviorMapNode::BehaviorMapNode(std::shared_ptr<MapKernal> core)
:LogicalNode(NodeKind::MAPNODE), _bind_kernal(core) {
}
void BehaviorMapNode::setVariable(const QString& key, IO_TYPE t, std::shared_ptr<TopicData> ins)
@ -190,7 +190,7 @@ void BehaviorMapNode::resetName(const QString& val)
std::shared_ptr<Serializable> BehaviorMapNode::newDefault() const
{
return std::make_shared<BehaviorMapNode>(this->messageLoader());
return std::make_shared<BehaviorMapNode>(this->_bind_kernal);
}
void BehaviorMapNode::recoveryFrom(const QJsonObject& obj)
@ -340,21 +340,22 @@ void SequenceNode::reset()
this->_state_map.clear();
}
QList<std::shared_ptr<LogicalNode>> ComposeNode::children() const
QList<std::shared_ptr<LogicalNode>> LogicalNode::children() const
{
return _child_list;
}
void ComposeNode::insert(std::shared_ptr<LogicalNode> node, int index /*= -1*/)
void LogicalNode::insert(std::shared_ptr<LogicalNode> node, int index /*= -1*/)
{
for (auto it : _child_list)
if (it->getID() == node->getID())
return;
node->_set_parent_node(this->shared_from_this());
_child_list.insert(index, node);
}
void ComposeNode::remove(std::shared_ptr<LogicalNode> node)
void LogicalNode::remove(std::shared_ptr<LogicalNode> node)
{
_child_list.removeAll(node);
}
@ -531,6 +532,23 @@ LogicalResult CompareNode::execute()
return LogicalResult::FAILURE;
}
void CompareNode::insert(std::shared_ptr<LogicalNode> node, int index /*= -1*/)
{
if (this->children().size())
return;
LogicalNode::insert(node, index);
}
QList<std::shared_ptr<LogicalNode>> CompareNode::getForwards() const
{
return QList<std::shared_ptr<LogicalNode>>();
}
bool CompareNode::fallback(std::shared_ptr<LogicalNode> node, LogicalResult ste) {
return true;
}
std::shared_ptr<Serializable> CompareNode::newDefault() const
{
return std::make_shared<CompareNode>();

View File

@ -226,13 +226,20 @@ enum class NodeKind {
/// <summary>
/// 所有逻辑节点的基类
/// </summary>
class COMPONENTBASIC_EXPORT LogicalNode : virtual public Serializable {
class COMPONENTBASIC_EXPORT LogicalNode : virtual public Serializable, public std::enable_shared_from_this<LogicalNode> {
private:
int _node_id = 0;
NodeKind _node_type = NodeKind::ACTIONNODE;
std::weak_ptr<LogicalNode> _parent_bind;
QList<std::shared_ptr<LogicalNode>> _child_list;
/// <summary>
/// 重置父节点
/// </summary>
/// <param name="pnode"></param>
void _set_parent_node(std::weak_ptr<LogicalNode> pnode);
public:
LogicalNode(NodeKind t = NodeKind::ACTIONNODE);
virtual ~LogicalNode() = default;
@ -243,16 +250,6 @@ public:
/// <returns></returns>
NodeKind nodeKind() const;
/// <summary>
/// 重置父节点
/// </summary>
/// <param name="pnode"></param>
void setParent(std::weak_ptr<LogicalNode> pnode);
/// <summary>
/// 回退节点
/// </summary>
/// <returns></returns>
std::weak_ptr<LogicalNode> parent() const;
/// <summary>
/// 获取包含树图节点
/// </summary>
@ -260,62 +257,10 @@ public:
std::shared_ptr<LogicalNode> bindMap() const;
/// <summary>
/// 设置节点id
/// </summary>
/// <param name="unique_id"></param>
void setID(int unique_id);
/// <summary>
/// 提取节点id
/// 回退节点
/// </summary>
/// <returns></returns>
int getID() const;
/// <summary>
/// 实例化节点名称
/// </summary>
/// <returns></returns>
QString runtimeName() const;
/// <summary>
/// 重置内部状态
/// </summary>
virtual void reset() = 0;
/// <summary>
/// 获取节点名称
/// </summary>
/// <returns></returns>
virtual QString typeName() const = 0;
/// <summary>
/// 执行逻辑节点
/// </summary>
/// <param name="core"></param>
/// <returns></returns>
virtual LogicalResult execute() = 0;
/// <summary>
/// 声明输入变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> inputList() const = 0;
/// <summary>
/// 声明输出变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> outputList() const = 0;
/// <summary>
/// 新建默认实例
/// </summary>
/// <returns></returns>
virtual std::shared_ptr<Serializable> newDefault() const = 0;
};
/// <summary>
/// 组合节点
/// </summary>
class COMPONENTBASIC_EXPORT ComposeNode {
private:
QList<std::shared_ptr<LogicalNode>> _child_list;
public:
std::weak_ptr<LogicalNode> parent() const;
/// <summary>
/// 获取子节点列表
/// </summary>
@ -333,6 +278,46 @@ public:
/// <param name="node"></param>
virtual void remove(std::shared_ptr<LogicalNode> node);
/// <summary>
/// 设置节点id
/// </summary>
/// <param name="unique_id"></param>
void setID(int unique_id);
/// <summary>
/// 提取节点id
/// </summary>
/// <returns></returns>
int getID() const;
/// <summary>
/// 实例化节点名称
/// </summary>
/// <returns></returns>
QString rtName() const;
/// <summary>
/// 获取节点名称
/// </summary>
/// <returns></returns>
virtual QString typeName() const = 0;
/// <summary>
/// 声明输入变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> inputList() const = 0;
/// <summary>
/// 声明输出变量的内部标识和数据接口
/// </summary>
/// <returns>map{name, type-ins}</returns>
virtual QHash<QString, std::shared_ptr<TopicData>> outputList() const = 0;
/// <summary>
/// 重置内部状态
/// </summary>
virtual void reset() = 0;
/// <summary>
/// 获取执行入口节点
/// </summary>
@ -345,8 +330,22 @@ public:
/// <param name="ste"></param>
/// <returns>接续执行标志</returns>
virtual bool fallback(std::shared_ptr<LogicalNode> node, LogicalResult ste) = 0;
/// <summary>
/// 执行逻辑节点
/// </summary>
/// <param name="core"></param>
/// <returns></returns>
virtual LogicalResult execute() = 0;
/// <summary>
/// 新建默认实例
/// </summary>
/// <returns></returns>
virtual std::shared_ptr<Serializable> newDefault() const = 0;
};
/// <summary>
/// 逻辑树节点输入输出类型
/// </summary>
@ -356,18 +355,19 @@ enum class IO_TYPE {
/// <summary>
/// 自定义行为树节点根节点实例
/// </summary>
class COMPONENTBASIC_EXPORT BehaviorMapNode
: public MapKernal, public LogicalNode, public ComposeNode {
class COMPONENTBASIC_EXPORT BehaviorMapNode : public LogicalNode {
private:
std::shared_ptr<MapKernal> _bind_kernal;
QString _map_name;
/// <summary>
/// 地图变量表
/// </summary>
QHash<QString, std::pair<IO_TYPE, std::shared_ptr<TopicData>>> _variables;
QString _map_name;
LogicalResult _state_value;
public:
BehaviorMapNode(std::shared_ptr<MessageLoader> core);
BehaviorMapNode(std::shared_ptr<MapKernal> kernal);
/// <summary>
@ -443,8 +443,7 @@ public:
/// <summary>
/// 顺序节点
/// </summary>
class COMPONENTBASIC_EXPORT SequenceNode
: public ComposeNode, public LogicalNode {
class COMPONENTBASIC_EXPORT SequenceNode : public LogicalNode {
private:
QHash<int, LogicalResult> _state_map;
@ -475,8 +474,7 @@ public:
/// <summary>
/// 选择节点
/// </summary>
class COMPONENTBASIC_EXPORT SelectorNode
: public ComposeNode, public LogicalNode {
class COMPONENTBASIC_EXPORT SelectorNode : public LogicalNode {
private:
QHash<int, LogicalResult> _state_map;
@ -507,8 +505,7 @@ public:
/// <summary>
/// 并行节点
/// </summary>
class COMPONENTBASIC_EXPORT ParallelNode
: public ComposeNode, public LogicalNode {
class COMPONENTBASIC_EXPORT ParallelNode : public LogicalNode {
private:
QHash<int, LogicalResult> _state_map;
@ -532,7 +529,6 @@ public:
/// <param name="p"></param>
/// <returns></returns>
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};
@ -548,23 +544,21 @@ private:
public:
CompareNode();
/// <summary>
/// 委托名称
/// </summary>
/// <returns></returns>
QString delegateName() const;
/// <summary>
/// 绑定比较委托
/// </summary>
/// <param name="ins"></param>
void bindDelegate(std::shared_ptr<CompareKernel> ins);
QHash<QString, std::shared_ptr<TopicData>> inputList() const override;
QHash<QString, std::shared_ptr<TopicData>> outputList() const override;
QString typeName() const override;
LogicalResult execute() override;
virtual void insert(std::shared_ptr<LogicalNode> node, int index /*= -1*/) override;
QString typeName() const override;
virtual QList<std::shared_ptr<LogicalNode>> getForwards() const override;
virtual bool fallback(std::shared_ptr<LogicalNode> node, LogicalResult ste) override;
LogicalResult execute() override;
void reset() override;
/// <summary>
@ -573,7 +567,6 @@ public:
/// <param name="p"></param>
/// <returns></returns>
virtual std::shared_ptr<Serializable> newDefault() const override;
void recoveryFrom(const QJsonObject& obj) override;
void saveTo(QJsonObject& obj) const override;
};

View File

@ -1 +1,164 @@
#include "BehaviorEditor.h"
NodePresent::NodePresent(std::shared_ptr<LogicalNode> bind)
:_node_bind(bind) {
}
QRectF NodePresent::contentMeasure() const
{
return QRectF(0, 0, 200, 40);
}
QRectF NodePresent::boundingRect() const
{
return contentMeasure() + QMargins(0, 0, 20, 20);
}
void NodePresent::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
//painter->drawRect(boundingRect());
painter->translate(QPointF(10, 10));
auto rect = contentMeasure();
painter->fillRect(rect, Qt::red);
}
BehaviorsPresent::BehaviorsPresent(QWidget* parent /*= nullptr*/)
: QGraphicsView(parent) {
this->setScene(&_bind_scene);
}
void BehaviorsPresent::setRoot(std::shared_ptr<BehaviorMapNode> root)
{
qDeleteAll(_present_peers);
_present_peers.clear();
this->_bind_maproot = root;
contentRelayout();
}
void BehaviorsPresent::presentAllocate(std::shared_ptr<LogicalNode> ins)
{
switch (ins->nodeKind())
{
case NodeKind::MAPNODE:
case NodeKind::PARALLELNODE:
case NodeKind::SEQUENCENODE:
case NodeKind::SELECTORNODE:
if (ins->nodeKind() != NodeKind::MAPNODE || !ins->bindMap()) {
auto type = ins->nodeKind();
for (auto it : ins->children())
presentAllocate(it);
}
default:
if (_present_peers.contains(ins))
return;
_present_peers[ins] = new NodePresent(ins);
this->_bind_scene.addItem(_present_peers[ins]);
break;
}
}
void BehaviorsPresent::presentRelease(std::shared_ptr<LogicalNode> ins)
{
switch (ins->nodeKind())
{
case NodeKind::MAPNODE:
case NodeKind::PARALLELNODE:
case NodeKind::SELECTORNODE:
case NodeKind::SEQUENCENODE: {
for (auto item : ins->children()) {
presentRelease(item);
}
}break;
default:
if (this->_present_peers.contains(ins))
delete this->_present_peers[ins];
break;
}
}
void BehaviorsPresent::contentRelayout()
{
if (!_bind_maproot)
return;
// 初始化显示节点
presentAllocate(_bind_maproot);
QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>> results;
// 尺寸测量
outlineMeasure(_bind_maproot, results);
// 元素排布
nodeRelayout(results, _bind_maproot, QPointF());
}
QSizeF BehaviorsPresent::outlineMeasure(std::shared_ptr<LogicalNode> ins, QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy)
{
QSizeF outline_box(0, 0);
switch (ins->nodeKind()) {
case NodeKind::MAPNODE:
case NodeKind::PARALLELNODE:
case NodeKind::SELECTORNODE:
case NodeKind::SEQUENCENODE:
// 测量子节点集合尺寸,根节点必须是行为树顶部根节点
if (ins->nodeKind() != NodeKind::MAPNODE || !ins->bindMap()) {
for (auto nit : ins->children()) {
auto nit_size = outlineMeasure(nit, _outline_occupy);
outline_box.setWidth(std::max(outline_box.width(), nit_size.width() + _space_h));
outline_box += QSizeF(0, nit_size.height());
}
}
default: {
auto root_peer = _present_peers[ins];
auto root_box = root_peer->boundingRect();
outline_box += QSizeF(root_box.width(), 0);
outline_box.setHeight(std::max(outline_box.height(), root_box.height()));
_outline_occupy[ins] = std::make_pair(outline_box, root_box.size());
return outline_box;
}break;
}
}
QPointF BehaviorsPresent::nodeRelayout(QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy,
std::shared_ptr<LogicalNode> ins, const QPointF& origin_offset) {
// 提取尺寸记录
auto outline_occupy = _outline_occupy[ins];
auto node_outline = outline_occupy.first;
auto node_occupy = outline_occupy.second;
// 提取显示节点
auto present_node = _present_peers[ins];
// 设置节点位置
QPointF local_origin_offset(0, (node_outline.height() - node_occupy.height()) / 2);
present_node->setPos(origin_offset + local_origin_offset);
// 计算子节点位置
QPointF child_origin = origin_offset + QPointF(node_occupy.width() + _space_h, 0);
switch (ins->nodeKind())
{
case NodeKind::ACTIONNODE:
case NodeKind::COMPARENODE:
break;
default:
// 布局子节点集合位置,根节点必须是顶端根节点
if (ins->nodeKind() != NodeKind::MAPNODE || !ins->bindMap()) {
for (auto item : ins->children()) {
child_origin = nodeRelayout(_outline_occupy, item, child_origin);
}
}break;
}
// 计算左下角位置
return origin_offset + QPointF(0, node_outline.height());
}
uint qHash(const std::shared_ptr<LogicalNode> data, uint seed) noexcept
{
return qHash((void*)data.get(), seed);
}

View File

@ -1,12 +1,81 @@
#pragma once
#include <QMainWindow>
#include "BehaviorPerform.h"
#include <QGraphicsItem>
#include <QGraphicsView>
class NodePresent : public QGraphicsItem {
private:
std::shared_ptr<LogicalNode> _node_bind;
class BehaviorEditor : public QMainWindow
{
public:
BehaviorEditor(std::shared_ptr<BehaviorMapNode> map_ins, QWidget *parent = nullptr);
NodePresent(std::shared_ptr<LogicalNode> bind);
QRectF contentMeasure() const;
// 通过 QGraphicsItem 继承
QRectF boundingRect() const override;
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
};
uint qHash(const std::shared_ptr<LogicalNode> data, uint seed) noexcept;
/// <summary>
/// 行为树编辑展示
/// </summary>
class BehaviorsPresent : public QGraphicsView
{
private:
QGraphicsScene _bind_scene;
const double _space_h = 120;
QHash<std::shared_ptr<LogicalNode>, NodePresent*> _present_peers;
/// <summary>
/// 绑定行为树节点
/// </summary>
std::shared_ptr<BehaviorMapNode> _bind_maproot = nullptr;
public:
BehaviorsPresent(QWidget* parent = nullptr);
/// <summary>
/// 替换行为树
/// </summary>
/// <param name="root"></param>
void setRoot(std::shared_ptr<BehaviorMapNode> root);
/// <summary>
/// 显示节点分配
/// </summary>
/// <param name="_present_peers"></param>
/// <param name="ins"></param>
void presentAllocate(std::shared_ptr<LogicalNode> ins);
/// <summary>
/// 递归释放显示节点
/// </summary>
/// <param name="ins"></param>
void presentRelease(std::shared_ptr<LogicalNode> ins);
/// <summary>
/// 内容重新布局
/// </summary>
void contentRelayout();
/// <summary>
/// 尺寸测量
/// </summary>
/// <param name="ins"></param>
/// <param name="_outline_occupy"></param>
/// <returns></returns>
QSizeF outlineMeasure(std::shared_ptr<LogicalNode> ins, QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy);
/// <summary>
/// 节点布局
/// </summary>
/// <param name="_outline_occupy">尺寸记录</param>
/// <param name="ins">指定节点</param>
/// <param name="origin_offset">左上角</param>
/// <returns>左下角</returns>
QPointF nodeRelayout(QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy,
std::shared_ptr<LogicalNode> ins, const QPointF &origin_offset);
};

View File

@ -37,7 +37,7 @@
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
<QtInstall>5.12.11_msvc2017_64</QtInstall>
<QtModules>core;gui;widgets</QtModules>
<QtModules>core;gui;widgets;qml</QtModules>
<QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">

View File

@ -1,11 +1,48 @@
#include "sims_world.h"
#include "TempletAssemble.h"
#include <QtWidgets/QApplication>
#include "BehaviorEditor.h"
#include <MessageLoader.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SimsWorld w;
BehaviorsPresent w;
w.show();
auto loader = std::make_shared<MessageLoader>();
auto kernal = std::make_shared<MapKernal>(loader);
auto root = std::make_shared<BehaviorMapNode>(kernal);
root->setID(0);
auto seqs = std::make_shared<SequenceNode>();
seqs->setID(10);
root->insert(seqs);
auto seqsx = std::make_shared<SequenceNode>();
seqsx->setID(100);
seqs->insert(seqsx);
auto selex = std::make_shared<SelectorNode>();
selex->setID(101);
seqs->insert(selex);
auto parallel = std::make_shared<ParallelNode>();
parallel->setID(1000);
selex->insert(parallel);
parallel = std::make_shared<ParallelNode>();
parallel->setID(1001);
selex->insert(parallel);
auto item = std::make_shared<CompareNode>();
item->setID(10000);
parallel->insert(item);
item = std::make_shared<CompareNode>();
item->setID(10001);
parallel->insert(item);
w.setRoot(root);
return a.exec();
}

View File

@ -11,38 +11,5 @@ int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);
auto cmd = std::make_shared<HorizontalArcMotion>();
cmd->_start_time = 0;
cmd->_speed_motion = 20;
cmd->_center_point = QVector3D(200000, 0, 0);
cmd->_rotate_deg = 90;
auto enti = std::make_shared<RtWsEntity>();
auto motion = std::make_shared<SurfaceMotionPlugin>();
enti->append(motion);
auto box3d = std::make_shared<VisibleCubePlugin>();
enti->append(box3d);
auto immediate = std::make_shared<ImmediateKernel>(enti);
QList<std::shared_ptr<RespondDefault>> out;
motion->execute(immediate, cmd, out);
for (auto rst : out)
qDebug() << rst->_success_mark << rst->_reason_text;
auto total = cmd->timeExpend();
for (auto timepoint = 0; timepoint < total; timepoint += 1) {
//qDebug() << cmd->posAtTimeSpan(timepoint);
auto sync = std::make_shared<SyncRequest>();
sync->_time_current = timepoint;
motion->execute(immediate, sync, out);
qDebug() <<QString("L:%1 B:%2 H:%3").arg(box3d->_self_lla._lon_deg).arg(box3d->_self_lla._lat_deg).arg(box3d->_self_lla._alt_m);
//qDebug() << box3d->_self_posture._azimuth_deg << box3d->_self_posture._pitch_deg << box3d->_self_posture._roll_deg;
//qDebug() << timepoint << "========================";
}
return app.exec();
}