- 本教程来自:Nav2中文网
- Nav2交流社区:https://fishros.org.cn/forum
- ROS2/Nav2千人交流群:(QQ)139707339
- 更多精彩教程请关注微信公众号:鱼香ROS
- 欢迎添加机器人小伊微信,解锁机器人学习特殊服务
- 概述
- 必要条件
- 教程步骤
本教程演示如何创建你自己行为树 (BT) 插件。BT插件作为节点行为树XML处理BT导航仪导航逻辑。 [待校准@1993]
必要条件- ROS 2 (二进制或从源代码构建)
- Nav2 (包括依赖项) [待校准@1996]
- Gazebo [待校准@1997]
- Turtlebot3 [待校准@1998]
我们将创建一个简单的BT插件节点来在另一个服务器上执行操作。在这个例子中,我们将分析 nav2_behavior_tree
包中最简单的行为树动作节点, wait
节点。除了操作BT节点的示例之外,您还可以创建自定义装饰器、条件和控制节点。每个节点类型在行为树中都具有独特的作用,以执行诸如规划、控制BT流、检查条件状态或修改其他BT节点的输出之类的操作。 [待校准@2001]
本教程中的代码可以在 nav2_behavior_tree 包中找到,作为 wait_action
节点。可以将此操作节点视为编写其他操作节点插件的参考。 [待校准@2002]
我们的示例插件继承自基类 “nav2 _ 行为 _ 树::BtAction节点 . The base class is a wrapper on the BehaviorTree.CPP `` ::Action节点基本”,简化了利用ROS 2动作客户端的BT动作节点。 ``BTActionNode
既是BT动作,也是使用ROS 2动作网络接口调用远程服务器进行一些工作。 [待校准@2003]
与其它类型BT节点 (e。g.装饰、控制、状态) 使用相应BT节点,‘‘BT: DecoratorNode’’,‘‘BT: ControlNode’’,或 ‘‘BT: ConditionNode’’。BT动作节点 * 不 * 利用ROS 2动作接口,使用 ‘‘BT: ActionNodeBase’’ 基类本身。 [待校准@2004]
的 BTActionNode
类提供虚拟方法使用,除了信息提供构造函数。让学习更方法需要写BT动作插件。 [待校准@2005]
在本教程中,我们将仅使用 on_tick()
方法。 [待校准@2025]
在构造函数中,我们需要获取应用于行为树节点的任何非变量参数。在此示例中,我们需要从行为树XML的输入端口获取睡眠时间的值。 [待校准@2026]
WaitAction::WaitAction(
const std::string & xml_tag_name,
const std::string & action_name,
const BT::NodeConfiguration & conf)
: BtActionNode(xml_tag_name, action_name, conf)
{
int duration;
getInput("wait_duration", duration);
if (duration get_logger(), "Wait duration is negative or zero "
"(%i). Setting to positive.", duration);
duration *= -1;
}
goal_.time.sec = duration;
}
这里给出输入的 xml_tag_name
告诉BT节点插件stringXML中对应节点。这将看到后我们登记这BT节点插件。它也在string名称动作服务器将调用执行一些行为。最后,配置,我们可以忽略的最节点插件。 [待校准@2027]
然后我们调用 BTActionNode
构造函数。可以看出,它是由ROS 2操作类型模板化的,所以我们给它 “nav2_msgs::action:: wait” 操作消息类型,并转发我们的其他输入。 BTActionNode
作为 tick()
方法,当从树中调用该节点时,行为树直接调用该方法。然后, on_tick()
与行动客户目标一起被调用。 [待校准@2028]
在构造函数的主体,我们输入端口 getInput
参数 wait_duration
可独立配置的每个例证 wait
节点树。它是在 duration
参数插入 goal_
。的 goal_
类变量目标ROS 2行动客户端将发送到操作服务器。所以在这个例子,我们设置时间我们想等使动作服务器知道细节的请求。 [待校准@2029]
的 providedPorts()
方法给我们机会定义输入或输出端口。端口可以认为参数行为树节点访问行为树本身。例如,只有一个输入端口, wait_duration
可以把它BT XML每个实例 wait
恢复。我们设置类型, int
,默认 1
, wait_duration
,描述港口 Wait time
。 [待校准@2030]
static BT::PortsList providedPorts()
{
return providedBasicPorts(
{
BT::InputPort("wait_duration", 1, "Wait time")
});
}
当行为树勾选特定节点时,将调用 on_tick()
方法。对于等待BT节点,我们只想通知黑板上的计数器,勾选了与恢复相对应的操作插件。这对于保持特定导航运行期间执行的恢复数量的度量很有用。如果是可变输入,您也可以记录或更新 goal_
的等待时间。 [待校准@2031]
void WaitAction::on_tick()
{
increment_recovery_count();
}
不使用其余方法,也不强制重写它们。只有一些BT节点插件需要覆盖 on_wait_for_result()
来检查抢占或检查超时。如果不重叠,成功、中止和取消的方法将分别默认为 SUCCESS
、 FAILURE
、 SUCCESS
。 [待校准@2032]
现在我们创建定制BT节点,我们需要导出插件也能见的行为树时加载定制BT XML。插件加载运行时如果不可见,然后我们BT导航仪服务器将无法加载或使用它。在BehaviorTree.CPP,导出和加载插件由 BT_REGISTER_NODES
微距。 [待校准@2034]
BT_REGISTER_NODES(factory)
{
BT::NodeBuilder builder =
[](const std::string & name, const BT::NodeConfiguration & config)
{
return std::make_unique(name, "wait", config);
};
factory.registerBuilder("Wait", builder);
}
在此宏中,我们必须创建一个 NodeBuilder
,以便我们的自定义操作节点可以具有非默认构造函数签名 (用于操作和xml名称)。此lambda将返回指向我们创建的行为树节点的唯一指针。用相关信息填充构造函数,在函数参数中给出 name
和 config
。然后定义这个BT节点将调用的ROS 2动作服务器的名称,在这种情况下,是 wWait 的动作。 [待校准@2035]
我们最后给生成器工厂登记。 Wait
给工厂名称在行为树XML文件对应BT节点插件。可以看到一个示例下面, Wait
BT XML节点指定非变量输入端口 wait_duration
5秒。 [待校准@2036]
3-将插件库名称添加到配置 [待校准@2037]
为了使BT Navigator节点发现我们刚刚注册的插件,我们需要在configuration YAML文件的bt_navigator节点下列出插件库名称。配置应类似于下面显示的配置。请注意plugin_lib_names下列出的nav2_wait_action_bt_node。 [待校准@2038]
bt_navigator:
ros__parameters:
use_sim_time: True
global_frame: map
robot_base_frame: base_link
odom_topic: /odom
default_bt_xml_filename: "navigate_w_replanning_and_recovery.xml"
plugin_lib_names:
- nav2_back_up_action_bt_node # other plugin
- nav2_wait_action_bt_node # our new plugin
4运行定制插件 [待校准@2039]
现在,您可以在自定义BT节点上使用行为树。例如, navigate_w_replanning_and_recovery.xml
文件如下所示。 [待校准@2040]
选择此BT XML文件特定导航请求 NavigateToPose
或默认行为树BT导航仪配置yaml文件。 [待校准@2041]
- 本文遵循知识共享协议,禁止未授权商用转载