标签:some count print reac inter -- str rup success
下面例子将展示SequenceNode和ReactiveSequence的不同
一个异步行为有它自己的线程;允许用户使用阻塞函数,但是要将执行流返回给到树;
//Custom type struct 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<Pose2D>("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<Pose2D>("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<Pose2D>(StringView)
;
Sequence与ReactiveSequence比较
下面是一个简单的SequenceNode
<root> <BehaviorTree> <Sequence> <BatteryOK/> <SaySomething message="mission started..." /> <MoveBase goal="1;2;3"/> <SaySomething message="mission completed!" /> </Sequence> </BehaviorTree> </root>
int main() { using namespace DummyNodes; BehaviorTreeFactory factory; factory.registerSimpleCondition("BatteryOK", std::bind(CheckBattery)); factory.registerNodeType<MoveBaseAction>("MoveBase"); factory.registerNodeType<SaySomething>("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开始执行,这样比较合理
<root> <BehaviorTree> <ReactiveSequence> <BatteryOK/> <Sequence> <SaySomething message="mission started..." /> <MoveBase goal="1;2;3"/> <SaySomething message="mission completed!" /> </Sequence> </ReactiveSequence> </BehaviorTree> </root>
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!"
标签:some count print reac inter -- str rup success
原文地址:https://www.cnblogs.com/gary-guo/p/14700313.html