Sequences and AsyncActionNode

网友投稿 225 2022-11-01


Sequences and AsyncActionNode

下面例子将展示SequenceNode和ReactiveSequence的不同

一个异步行为有它自己的线程;允许用户使用阻塞函数,但是要将执行流返回给到树;

//Custom typestruct Pose2D{ double x, y, theta;};class MoveBaseAction : public AsyncActionNode{ public: MoveBaseAction(const std::string& name, const NodeConfiguration& config) : AsyncActionNode(name, config) { } static PortsList providedPorts() { return{ InputPort("goal") }; } NodeStatus tick() override; // This overloaded method is used to stop the execution of this node. void halt() override { _halt_requested.store(true); }private: std::atomic_bool_halt_requested;};//-------------------------NodeStatus MoveBaseAction::tick(){ Pose2D goal; if ( !getInput("goal", goal)) { throw RuntimeError("missing required input [goal]"); } printf("[ MoveBase: STARTED ]. goal: x=%.f y=%.1f theta=%.2f\n", goal.x, goal.y, goal.theta); _halt_requested.store(false); int count = 0; // Pretend that "computing" takes 250 milliseconds. // It is up to you to check periodicall _halt_requested and interrupt // this tick() if it is true. while (!_halt_requested && count++ < 25) { SleepMS(10); } std::cout << "[ MoveBase: FINISHED ]" << std::endl; return _halt_requested ? NodeStatus::FAILURE : NodeStatus::SUCCESS;}

方法​​MoveBaseAction::tick()​​​在不主线程不同的线程中执行,主线程唤醒的​​MoveBaseAction::executeTick()​​.

自己需要实现一个有效的halt()函数;

也需要实现一个函数​​convertFromString(StringView)​​;

Sequence与ReactiveSequence比较

下面是一个简单的SequenceNode

"mission started..." />

int main(){ using namespace DummyNodes; BehaviorTreeFactory factory; factory.registerSimpleCondition("BatteryOK", std::bind(CheckBattery)); factory.registerNodeType("MoveBase"); factory.registerNodeType("SaySomething"); auto tree = factory.createTreeFromText(xml_text); NodeStatus status; std::cout << "\n--- 1st executeTick() ---" << std::endl; status = tree.tickRoot(); SleepMS(150); std::cout << "\n--- 2nd executeTick() ---" << std::endl; status = tree.tickRoot(); SleepMS(150); std::cout << "\n--- 3rd executeTick() ---" << std::endl; status = tree.tickRoot(); std::cout << std::endl; return 0;}

Expected output: --- 1st executeTick() --- [ Battery: OK ] Robot says: "mission started..." [ MoveBase: STARTED ]. goal: x=1 y=2.0 theta=3.00 --- 2nd executeTick() --- [ MoveBase: FINISHED ] --- 3rd executeTick() --- Robot says: "mission completed!"

注意到当executeTick()被执行的时候,MoveBase返回RUNNING,在第一次和第二次,第三次最后成功;

BatteryOK只执行了一次;

如果使用ReactiveSequence,MoveBase返回RUNNING,序列sequence重新开始从BatteryOK开始执行,这样比较合理

"mission started..." />

Expected output: --- 1st executeTick() --- [ Battery: OK ] Robot says: "mission started..." [ MoveBase: STARTED ]. goal: x=1 y=2.0 theta=3.00 --- 2nd executeTick() --- [ Battery: OK ] [ MoveBase: FINISHED ] --- 3rd executeTick() --- [ Battery: OK ] Robot says: "mission completed!"


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java CAS操作与Unsafe类详解
下一篇:9、流类库与输入/输出2.3输出文件流成员函数
相关文章

 发表评论

暂时没有评论,来抢沙发吧~