行为树(BT)笔记(五):如何使用NodeParameters

NodeParameters就像传递给函数的参数一样。

它们是通常从文件中读取的键/值对(两个字符串)的映射。

要创建接受NodeParameters的TreeNode,您必须遵循以下规则:

  • 从ActionNode,ConditionNode或DecoratorNode继承。

  • 您必须提供具有以下特征的构造函数:

MyAction (const  std :: string & name , const  BT :: NodeParameters & params ) 
  • 必须定义以下静态成员函数:
static const BT::NodeParameters& requiredNodeParameters()

示例:需要参数“message”的Action

SaySomething 是一个简单的SyncActionNode,它将打印在NodeParameter中传递的名为“message”的字符串。

请注意:

  • 构造函数形式。

  • 静态方法requiredNodeParameters()包含单个键/值对。字符串“default message”是默认值。

  • 必须使用该方法访问参数getParam(),最好在tick()方法内部 。

class SaySomething: public SyncActionNode
{
public:
    // There must be a constructor with this signature
    SaySomething(const std::string& name, const NodeParameters& params):
        SyncActionNode(name, params) {}

    // It is mandatory to define this static method.
    static const NodeParameters& requiredNodeParameters()
    {
        static NodeParameters params = {{"message","default message"}};
        return params;
    }

    virtual NodeStatus tick() override
    {
        std::string msg;
        if( getParam("message", msg) == false )
        {
            // if getParam failed, use the default value
            msg = requiredNodeParameters().at("message");
        }
        std::cout << "Robot says: " << msg << std::endl;
        return BT::NodeStatus::SUCCESS;
    }
};

示例:转换为用户定义的C ++类型

在下一个示例中,我们有一个用户定义的类型Pose2D

struct Pose2D
{
    double x,y,theta;
};

如果我们希望方法getParam()能够解析字符串并将其值存储到a中Pose2D,我们必须提供自己的模板特化convertFromString<T>()

在这种情况下,a的文本表示Pose2D是由分号分隔的三个实数,如下所示:

“1.1; -2.32; 0.4”

由于这是一种常见模式,因此库提供了辅助函数BT::splitString

// use this namespace
namespace BT{

// This template specialization is needed if you want
// to AUTOMATICALLY convert a NodeParameter into a Pose2D
template <> Pose2D BT::convertFromString(const StringView& key)
{
    // Three real numbers separated by semicolons.
    // You may use <boost/algorithm/string/split.hpp>  if you prefer
    auto parts = BT::splitString(key, ';');
    if( parts.size() != 3)
    {
        throw std::runtime_error("invalid input)");
    }
    else{
        Pose2D output;
        output.x     = convertFromString<double>( parts[0] );
        output.y     = convertFromString<double>( parts[1] );
        output.theta = convertFromString<double>( parts[2] );
        return output;
    }
}

} // end namespace

我们现在定义一个名为MoveBaseAction异步ActionNode

方法tick()AsynActionNode在其自己的线程中执行。

该方法getParam()将调用convertFromString<Pose2D>()引擎下的功能; 或者,我们可以直接使用后者的功能,例如将默认字符串“0; 0; 0”转换为Pose2D。

// This is an asynchronous operation that will run in a separate thread.
// It requires the NodeParameter "goal". 
// If the key is not provided, the default value "0;0;0" is used instead.
class MoveBaseAction: public AsynActionNode
{
public:

    MoveBaseAction(const std::string& name, const NodeParameters& params):
        AsynActionNode(name, params) {}

    static const BT::NodeParameters& requiredNodeParameters()
    {
        static BT::NodeParameters params = {{"goal","0;0;0"}};
        return params;
    }

    virtual NodeStatus tick() override
    {
        Pose2D goal;
        if( getParam<Pose2D>("goal", goal) == false )
        {
            auto default_goal =  requiredNodeParameters().at("goal");
            goal = BT::convertFromString<Pose2D>( default_goal_value );
        }

        printf("[ MoveBase: STARTED ]. goal: x=%.f y=%.1f theta=%.2f\n",
                goal.x, goal.y, goal.theta);

        halt_requested_ = false;

        int count = 0;
        // "compute" for 250 milliseconds or until halt_requested_
        while( !halt_requested_ && count++ < 25)
        {
            SleepMilliseconds(10);
        }

        std::cout << "[ MoveBase: FINISHED ]" << std::endl;
        return halt_requested_ ? NodeStatus::FAILURE :
                                 NodeStatus::SUCCESS;
    }

    virtual void halt() override
    {
        halt_requested_ = true;
    }
private:
    bool halt_requested_;
};

XML中的NodeParameters

要从XML传递参数,请使用以下属性:

<Sequence> 
    <MoveBaseAction  goal = “41.2; 13.5; 0.7” /> 
    <SaySomething    message = “Destination reach ” /> 
    <SaySomething />  <! - 没有参数传递 - >  
</ Sequence> 

预期输出:

[ MoveBase: STARTED ]: goal: x=41.2 y=13.5 theta=0.7
[ MoveBase: FINISHED ]
Robot says: Destination reached
Robot says: default message

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值