[{"data":1,"prerenderedAt":5220},["ShallowReactive",2],{"wiki-page-\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0600-zu-he-shi-ji-ren-wu":3,"wiki-doc-items-2023-12-30-ros2-tutorial":4803,"wiki:author-members":5208},{"id":4,"title":5,"authors":6,"body":8,"chapterDepth":567,"chapterOrder":4791,"date":4792,"description":75,"docKey":4793,"docRoot":4794,"docTitle":4795,"extension":4796,"isWikiDoc":563,"isWikiIndex":4797,"meta":4798,"navigation":563,"path":4799,"seo":4800,"stem":4801,"wikiDepth":135,"__hash__":4802},"wiki\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0600-组合实际任务.md","组合实际任务",[7],"董佳辉",{"type":9,"value":10,"toc":4774},"minimark",[11,15,58,65,68,79,89,92,95,109,115,124,173,193,269,291,304,306,309,320,323,362,370,377,399,416,422,431,437,439,442,445,537,543,3559,3592,3597,3602,3617,3740,3767,3769,3773,3776,3782,4096,4112,4116,4121,4230,4245,4257,4268,4270,4274,4292,4298,4306,4315,4402,4405,4407,4410,4427,4440,4456,4462,4468,4481,4487,4493,4504,4506,4510,4519,4621,4636,4644,4647,4649,4652,4670,4686,4689,4703,4714,4716,4719,4722,4765,4770],[12,13,14],"h2",{"id":14},"把已有节点组合成移动机器人任务",[16,17,18],"blockquote",{},[19,20,21,22,29,30,35,36,41,42,29,47,35,52,57],"p",{},"对应 BehaviorTree.CPP 3.8 官方文档：",[23,24,28],"a",{"href":25,"rel":26},"https:\u002F\u002Fwww.behaviortree.dev\u002Fdocs\u002F3.8\u002Ftutorial-basics\u002Ftutorial_05_subtrees\u002F",[27],"nofollow","Using SubTrees","、",[23,31,34],{"href":32,"rel":33},"https:\u002F\u002Fwww.behaviortree.dev\u002Fdocs\u002F3.8\u002Ftutorial-basics\u002Ftutorial_06_subtree_ports\u002F",[27],"Port Remapping"," 和 ",[23,37,40],{"href":38,"rel":39},"https:\u002F\u002Fwww.behaviortree.dev\u002Fdocs\u002F3.8\u002Ftutorial-basics\u002Ftutorial_07_multiple_xml\u002F",[27],"Use multiple XML files","。实现细节参考 3.8.7 的 ",[23,43,46],{"href":44,"rel":45},"https:\u002F\u002Fgithub.com\u002FBehaviorTree\u002FBehaviorTree.CPP\u002Fblob\u002F3.8.7\u002Fsrc\u002Fxml_parsing.cpp",[27],"xml_parsing.cpp",[23,48,51],{"href":49,"rel":50},"https:\u002F\u002Fgithub.com\u002FBehaviorTree\u002FBehaviorTree.CPP\u002Fblob\u002F3.8.7\u002Finclude\u002Fbehaviortree_cpp_v3\u002Fblackboard.h",[27],"blackboard.h",[23,53,56],{"href":54,"rel":55},"https:\u002F\u002Fgithub.com\u002FBehaviorTree\u002FBehaviorTree.CPP\u002Fblob\u002F3.8.7\u002Fsrc\u002Fdecorators\u002Fretry_node.cpp",[27],"retry_node.cpp","。",[19,59,60,61],{},"前面的实践已经分别给出了端口、Blackboard 和持续动作。\n本篇把它们组合成一个完整主题：",[62,63,64],"strong",{},"机器人先确保电量足够，再依次前往取货点和放货点；每段导航允许有限次尝试，成功后报告结果，尝试耗尽后报告任务失败。",[19,66,67],{},"本篇的导航仍用回调计数模拟，充电简化为一次电量更新，全部运行都不需要连接机器人。\n先完成前面几篇的实践，再运行本篇，便于把注意力集中在任务组织与子树边界上。",[69,70,76],"pre",{"className":71,"code":73,"language":74,"meta":75},[72],"language-text","MainTree\n└── Sequence：一次运输任务\n    ├── Fallback：确保电量(如果电量不OK，则充电)\n    │   ├── BatteryOK\n    │   └── ChargeBattery\n    └── Fallback：执行任务，或报告失败（如果任务执行失败，则报Failure）\n        ├── Sequence\n        │   ├── SubTree：NavigateLeg，前往取货点\n        │   ├── SubTree：NavigateLeg，前往放货点\n        │   └── ReportMission\n        └── ForceFailure\n            └── ReportFailure\n\nNavigateLeg：每次调用都创建自己的节点和局部 Blackboard\n└── RetryUntilSuccessful：最多尝试两次\n    └── NavigateToGoal：跨多次 tick 检查本次导航\n","text","",[77,78,73],"code",{"__ignoreMap":75},[19,80,81,82,85,86,88],{},"电量检查失败时，Fallback 继续执行模拟充电；充电成功后，外层 Sequence 才进入导航。\n导航序列返回 ",[77,83,84],{},"RUNNING"," 时，任务 Fallback 也返回 ",[77,87,84],{},"，不会提前执行失败报告。",[90,91],"hr",{},[12,93,94],{"id":94},"复用子树时明确数据边界",[19,96,97,98,101,102,29,105,108],{},"两段导航执行规则相同，只是目标和结果条目不同，因此可以共用 ",[77,99,100],{},"NavigateLeg"," 这份 XML 定义。\n它在每次调用时创建不同的节点对象和局部 Blackboard，内部的 ",[77,103,104],{},"target",[77,106,107],{},"reached"," 名称可以相同，再分别连接到主树的不同条目。",[69,110,113],{"className":111,"code":112,"language":74,"meta":75},[72],"主树 Blackboard                         第一次 NavigateLeg 的局部 Blackboard\npickup_goal = loading_area   ──映射──→   target\npickup_reached               ←─映射──   reached\n\n主树 Blackboard                         第二次 NavigateLeg 的局部 Blackboard\ndropoff_goal = unloading_area ─映射──→   target\ndropoff_reached              ←─映射──   reached\n",[77,114,112],{"__ignoreMap":75},[19,116,117,118,123],{},"本篇使用官方 3.8 端口映射教程中的普通 ",[62,119,120],{},[77,121,122],{},"SubTree"," 写法：",[69,125,129],{"className":126,"code":127,"language":128,"meta":75,"style":75},"language-xml shiki shiki-themes github-light github-dark","\u003CSubTree ID=\"NavigateLeg\" target=\"pickup_goal\" reached=\"pickup_reached\"\u002F>\n","xml",[77,130,131],{"__ignoreMap":75},[132,133,136,140,143,147,150,154,157,159,162,165,167,170],"span",{"class":134,"line":135},"line",1,[132,137,139],{"class":138},"sVt8B","\u003C",[132,141,122],{"class":142},"s9eBZ",[132,144,146],{"class":145},"sScJk"," ID",[132,148,149],{"class":138},"=",[132,151,153],{"class":152},"sZZnC","\"NavigateLeg\"",[132,155,156],{"class":145}," target",[132,158,149],{"class":138},[132,160,161],{"class":152},"\"pickup_goal\"",[132,163,164],{"class":145}," reached",[132,166,149],{"class":138},[132,168,169],{"class":152},"\"pickup_reached\"",[132,171,172],{"class":138},"\u002F>\n",[19,174,175,176,29,178,180,181,29,184,187,188,190,191,57],{},"这里属性名 ",[77,177,104],{},[77,179,107],{}," 是子树局部 Blackboard 的键，属性值 ",[77,182,183],{},"pickup_goal",[77,185,186],{},"pickup_reached"," 是父 Blackboard 的键名。\n它们建立映射关系，子树对 ",[77,189,107],{}," 的写入会反映到主树的 ",[77,192,186],{},[194,195,196,212],"table",{},[197,198,199],"thead",{},[200,201,202,206,209],"tr",{},[203,204,205],"th",{},"所在位置",[203,207,208],{},"写法",[203,210,211],{},"含义",[213,214,215,232,253],"tbody",{},[200,216,217,221,226],{},[218,219,220],"td",{},"普通节点端口",[218,222,223],{},[77,224,225],{},"goal=\"{target}\"",[218,227,228,229,231],{},"从当前 Blackboard 的 ",[77,230,104],{}," 读取输入",[200,233,234,240,245],{},[218,235,236,237,239],{},"3.8 的普通 ",[77,238,122],{}," 边界",[218,241,242],{},[77,243,244],{},"target=\"pickup_goal\"",[218,246,247,248,250,251],{},"将子树的 ",[77,249,104],{}," 映射到父树的 ",[77,252,183],{},[200,254,255,258,263],{},[218,256,257],{},"普通节点的输出端口",[218,259,260],{},[77,261,262],{},"reached_goal=\"{reached}\"",[218,264,265,266,268],{},"写入当前 Blackboard 的 ",[77,267,107],{},"，再由映射连接到父树",[19,270,271,280,281,283,284,287,288,290],{},[62,272,273,274,276,277,57],{},"不要把本篇 ",[77,275,122],{}," 的映射值改成 ",[77,278,279],{},"{pickup_goal}","\n3.8.7 的普通 ",[77,282,122],{}," 分支直接把属性值当作父键名，不会替你去掉花括号，之后就可能找不到正确输入。\n源码中还提供了使用不同映射语义的 ",[77,285,286],{},"SubTreePlus","，本篇统一使用普通 ",[77,289,122],{},"，按表中的边界规则填写。",[19,292,293,294,297,298,300,301,303],{},"子树边界的键名也不等于 C++ 叶节点的端口名。\n本例经过的是：",[77,295,296],{},"goal"," 端口 → 局部 ",[77,299,104],{}," → 父树 ",[77,302,183],{},"，每一层分别声明自己的接口。",[90,305],{},[12,307,308],{"id":308},"建立组合任务工程",[19,310,311,312,315,316,319],{},"本篇直接复制整个 ",[77,313,314],{},"bt_running"," 文件夹，再把副本重命名为 ",[77,317,318],{},"bt_mission","，保留原来的持续任务工程供后续对照。",[19,321,322],{},"在系统文件管理器中完成下面几步：",[324,325,326,336,349],"ol",{},[327,328,329,330,332,333,335],"li",{},"打开 ",[77,331,314],{}," 所在的父目录，复制并粘贴整个文件夹，将副本重命名为 ",[77,334,318],{},"，让两个工程位于同一层目录。",[327,337,338,339,341,342,35,345,348],{},"在新副本 ",[77,340,318],{}," 中，删除复制过来的 ",[77,343,344],{},"build",[77,346,347],{},"install"," 文件夹（如果存在）。其中的构建缓存和安装结果属于旧工程，新工程稍后会重新生成。",[327,350,351,352,355,356,359,360,57],{},"在 VSCode 中选择 ",[62,353,354],{},"文件 → 新建窗口","，再选择 ",[62,357,358],{},"文件 → 打开文件夹","，打开新的 ",[77,361,318],{},[19,363,364,365,369],{},"框架继续来自 ",[23,366,368],{"href":367},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-cmake-gong-cheng-mu-ban","CMake工程模板","，保留 C++20、CMake 3.22、预设格式版本 3，以及优先查找 BehaviorTree.CPP 3.8.7 的依赖配置。\nUbuntu 22.04 的 CMake 3.22.1 可以继续使用。复用 Humble 安装包时，VSCode 的配置、运行和调试进程仍需继承 ROS 2 环境。",[19,371,372,373,376],{},"在顶层 ",[77,374,375],{},"CMakeLists.txt"," 中，将项目声明改为：",[69,378,382],{"className":379,"code":380,"language":381,"meta":75,"style":75},"language-cmake shiki shiki-themes github-light github-dark","project(bt_mission VERSION 1.0.0 LANGUAGES C CXX)\n","cmake",[77,383,384],{"__ignoreMap":75},[132,385,386,390,393,396],{"class":134,"line":135},[132,387,389],{"class":388},"szBVR","project",[132,391,392],{"class":138},"(bt_mission ",[132,394,395],{"class":145},"VERSION",[132,397,398],{"class":138}," 1.0.0 LANGUAGES C CXX)\n",[19,400,401,35,404,407,408,411,412,415],{},[77,402,403],{},"src\u002Fmain.cpp",[77,405,406],{},"trees\u002Fmission.xml"," 已经随工程复制过来，稍后用本篇内容替换。\n在左侧资源管理器的 ",[77,409,410],{},"trees"," 目录中新建 ",[77,413,414],{},"navigation.xml","，用于保存导航子树。参与本篇构建的目录为：",[69,417,420],{"className":418,"code":419,"language":74,"meta":75},[72],"bt_mission\u002F\n├── CMakeLists.txt\n├── CMakePresets.json\n├── cmake\u002F\n│   ├── ProjectOptions.cmake\n│   └── BehaviorTree.cmake\n├── src\u002F\n│   ├── CMakeLists.txt\n│   └── main.cpp\n└── trees\u002F\n    ├── mission.xml          任务入口，引用导航子树\n    └── navigation.xml       可复用的 NavigateLeg 定义\n",[77,421,419],{"__ignoreMap":75},[19,423,424,427,428,430],{},[77,425,426],{},"BT_XML_PATH"," 仍指向 ",[77,429,406],{},"，不需要因为增加了第二个 XML 而修改 CMake。",[19,432,433],{},[434,435],"img",{"alt":75,"src":436},"https:\u002F\u002Fcdn.tungchiahui.cn\u002Ftungwebsite\u002Fassets\u002Fimages\u002F2023\u002F12\u002F30\u002F1792420155633-d652f6a5.webp",[90,438],{},[12,440,441],{"id":441},"实现任务所需的节点",[19,443,444],{},"导航节点沿用上一篇的生命周期，在此基础上增加“前几次尝试失败”的模拟参数，以及成功后写出到达目标的输出端口。",[194,446,447,460],{},[197,448,449],{},[200,450,451,454,457],{},[203,452,453],{},"节点",[203,455,456],{},"类型",[203,458,459],{},"主要职责",[213,461,462,477,492,510,524],{},[200,463,464,469,474],{},[218,465,466],{},[77,467,468],{},"BatteryOK",[218,470,471],{},[77,472,473],{},"ConditionNode",[218,475,476],{},"读取电量，a达到 30 时返回成功",[200,478,479,484,489],{},[218,480,481],{},[77,482,483],{},"ChargeBattery",[218,485,486],{},[77,487,488],{},"SyncActionNode",[218,490,491],{},"将模拟电量更新为 80",[200,493,494,499,504],{},[218,495,496],{},[77,497,498],{},"NavigateToGoal",[218,500,501],{},[77,502,503],{},"StatefulActionNode",[218,505,506,507],{},"分多次检查导航，成功时写出 ",[77,508,509],{},"reached_goal",[200,511,512,517,521],{},[218,513,514],{},[77,515,516],{},"ReportMission",[218,518,519],{},[77,520,488],{},[218,522,523],{},"读取两段导航的结果并报告完成",[200,525,526,531,534],{},[218,527,528],{},[77,529,530],{},"ReportFailure",[218,532,533],{},"简单同步动作",[218,535,536],{},"输出失败信息，表示报告动作已执行",[19,538,539,540,542],{},"用以下完整程序替换 ",[77,541,403],{}," 的原有内容，再保存。四个节点类和一个简单动作都在这个文件中，方便先把组合任务跑通。",[69,544,548],{"className":545,"code":546,"language":547,"meta":75,"style":75},"language-cpp shiki shiki-themes github-light github-dark","#include \"behaviortree_cpp_v3\u002Fbt_factory.h\"\n\n#include \u003Cchrono>\n#include \u003Ccmath>\n#include \u003Ciostream>\n#include \u003Cstdexcept>\n#include \u003Cstring>\n\nclass BatteryOK : public BT::ConditionNode\n{\npublic:\n    BatteryOK(const std::string& name, const BT::NodeConfiguration& config)\n        : BT::ConditionNode(name, config)\n    {}\n\n    static BT::PortsList providedPorts()\n    {\n        return {BT::InputPort\u003Cdouble>(\"level\")};\n    }\n\n    BT::NodeStatus tick() override\n    {\n        auto level = getInput\u003Cdouble>(\"level\");\n        if (!level)\n        {\n            throw BT::RuntimeError(\"Cannot read input [level]: \", level.error());\n        }\n        if (!std::isfinite(level.value()) || level.value() \u003C 0.0 || level.value() > 100.0)\n        {\n            throw std::runtime_error(\"battery level must be between 0 and 100\");\n        }\n        const auto result = level.value() >= 30.0\n                                ? BT::NodeStatus::SUCCESS : BT::NodeStatus::FAILURE;\n        std::cout \u003C\u003C \"[BatteryOK] level=\" \u003C\u003C level.value()\n                  \u003C\u003C \" -> \" \u003C\u003C BT::toStr(result) \u003C\u003C '\\n';\n        return result;\n    }\n};\n\nclass ChargeBattery : public BT::SyncActionNode\n{\npublic:\n    ChargeBattery(const std::string& name, const BT::NodeConfiguration& config)\n        : BT::SyncActionNode(name, config)\n    {}\n\n    static BT::PortsList providedPorts()\n    {\n        return {BT::OutputPort\u003Cdouble>(\"level\")};\n    }\n\n    BT::NodeStatus tick() override\n    {\n        \u002F\u002F 本例把充电简化为一次数据更新，真实充电应实现为持续任务。\n        auto written = setOutput(\"level\", 80.0);\n        if (!written)\n        {\n            throw BT::RuntimeError(\"Cannot write output [level]: \", written.error());\n        }\n        std::cout \u003C\u003C \"[ChargeBattery] level=80\\n\";\n        return BT::NodeStatus::SUCCESS;\n    }\n};\n\nclass NavigateToGoal : public BT::StatefulActionNode\n{\npublic:\n    NavigateToGoal(const std::string& name, const BT::NodeConfiguration& config)\n        : BT::StatefulActionNode(name, config)\n    {}\n\n    static BT::PortsList providedPorts()\n    {\n        return {BT::InputPort\u003Cstd::string>(\"goal\"),\n                BT::InputPort\u003Cint>(\"ticks\", 2, \"每次导航尝试的检查次数\"),\n                BT::InputPort\u003Cint>(\"fail_attempts\", 1, \"模拟前几次尝试失败\"),\n                BT::OutputPort\u003Cstd::string>(\"reached_goal\")};\n    }\n\n    BT::NodeStatus onStart() override\n    {\n        auto goal = getInput\u003Cstd::string>(\"goal\");\n        auto ticks = getInput\u003Cint>(\"ticks\");\n        auto failures = getInput\u003Cint>(\"fail_attempts\");\n        if (!goal)\n        {\n            throw BT::RuntimeError(\"Cannot read input [goal]: \", goal.error());\n        }\n        if (!ticks)\n        {\n            throw BT::RuntimeError(\"Cannot read input [ticks]: \", ticks.error());\n        }\n        if (!failures)\n        {\n            throw BT::RuntimeError(\"Cannot read input [fail_attempts]: \", failures.error());\n        }\n        if (goal.value().empty() || ticks.value() \u003C 1 || failures.value() \u003C 0)\n        {\n            throw std::runtime_error(\"invalid navigation simulation parameters\");\n        }\n\n        goal_ = goal.value();\n        required_ticks_ = ticks.value();\n        failed_attempts_ = failures.value();\n        completed_ticks_ = 0;\n        \u002F\u002F 每个节点实例分别保留尝试次数，用于模拟先失败、后成功。\n        ++attempt_;\n        std::cout \u003C\u003C \"[NavigateToGoal] start goal=\" \u003C\u003C goal_\n                  \u003C\u003C \", attempt=\" \u003C\u003C attempt_ \u003C\u003C '\\n';\n        return BT::NodeStatus::RUNNING;\n    }\n\n    BT::NodeStatus onRunning() override\n    {\n        if (++completed_ticks_ \u003C required_ticks_)\n        {\n            return BT::NodeStatus::RUNNING;\n        }\n        if (attempt_ \u003C= failed_attempts_)\n        {\n            std::cout \u003C\u003C \"[NavigateToGoal] failed goal=\" \u003C\u003C goal_\n                      \u003C\u003C \", attempt=\" \u003C\u003C attempt_ \u003C\u003C '\\n';\n            return BT::NodeStatus::FAILURE;\n        }\n\n        auto written = setOutput(\"reached_goal\", goal_);\n        if (!written)\n        {\n            throw BT::RuntimeError(\"Cannot write output [reached_goal]: \", written.error());\n        }\n        std::cout \u003C\u003C \"[NavigateToGoal] arrived goal=\" \u003C\u003C goal_\n                  \u003C\u003C \", attempt=\" \u003C\u003C attempt_ \u003C\u003C '\\n';\n        return BT::NodeStatus::SUCCESS;\n    }\n\n    void onHalted() override\n    {\n        std::cout \u003C\u003C \"[NavigateToGoal] halted goal=\" \u003C\u003C goal_ \u003C\u003C '\\n';\n        completed_ticks_ = 0;\n    }\n\nprivate:\n    std::string goal_;\n    int required_ticks_ = 0;\n    int completed_ticks_ = 0;\n    int failed_attempts_ = 0;\n    int attempt_ = 0;\n};\n\nclass ReportMission : public BT::SyncActionNode\n{\npublic:\n    ReportMission(const std::string& name, const BT::NodeConfiguration& config)\n        : BT::SyncActionNode(name, config)\n    {}\n\n    static BT::PortsList providedPorts()\n    {\n        return {BT::InputPort\u003Cstd::string>(\"pickup\"),\n                BT::InputPort\u003Cstd::string>(\"dropoff\")};\n    }\n\n    BT::NodeStatus tick() override\n    {\n        auto pickup = getInput\u003Cstd::string>(\"pickup\");\n        auto dropoff = getInput\u003Cstd::string>(\"dropoff\");\n        if (!pickup)\n        {\n            throw BT::RuntimeError(\"Cannot read input [pickup]: \", pickup.error());\n        }\n        if (!dropoff)\n        {\n            throw BT::RuntimeError(\"Cannot read input [dropoff]: \", dropoff.error());\n        }\n        std::cout \u003C\u003C \"[ReportMission] pickup=\" \u003C\u003C pickup.value()\n                  \u003C\u003C \", dropoff=\" \u003C\u003C dropoff.value() \u003C\u003C '\\n';\n        return BT::NodeStatus::SUCCESS;\n    }\n};\n\nBT::NodeStatus ReportFailure(BT::TreeNode&)\n{\n    std::cout \u003C\u003C \"[ReportFailure] transport mission failed\\n\";\n    return BT::NodeStatus::SUCCESS;\n}\n\nint main()\n{\n    try\n    {\n        BT::BehaviorTreeFactory factory;\n        factory.registerNodeType\u003CBatteryOK>(\"BatteryOK\");\n        factory.registerNodeType\u003CChargeBattery>(\"ChargeBattery\");\n        factory.registerNodeType\u003CNavigateToGoal>(\"NavigateToGoal\");\n        factory.registerNodeType\u003CReportMission>(\"ReportMission\");\n        factory.registerSimpleAction(\"ReportFailure\", ReportFailure);\n\n        auto blackboard = BT::Blackboard::create();\n        blackboard->set(\"battery\", 20.0);\n        blackboard->set(\"pickup_goal\", std::string(\"loading_area\"));\n        blackboard->set(\"dropoff_goal\", std::string(\"unloading_area\"));\n        auto tree = factory.createTreeFromFile(BT_XML_PATH, blackboard);\n\n        BT::NodeStatus result = tree.tickRoot();\n        while (result == BT::NodeStatus::RUNNING)\n        {\n            tree.sleep(std::chrono::milliseconds(100));\n            result = tree.tickRoot();\n        }\n        std::cout \u003C\u003C \"Tree result: \" \u003C\u003C BT::toStr(result) \u003C\u003C '\\n';\n        if (result == BT::NodeStatus::SUCCESS)\n        {\n            std::cout \u003C\u003C \"[main] pickup_reached=\"\n                      \u003C\u003C blackboard->get\u003Cstd::string>(\"pickup_reached\") \u003C\u003C '\\n';\n            std::cout \u003C\u003C \"[main] dropoff_reached=\"\n                      \u003C\u003C blackboard->get\u003Cstd::string>(\"dropoff_reached\") \u003C\u003C '\\n';\n        }\n        return result == BT::NodeStatus::SUCCESS ? 0 : 1;\n    }\n    catch (const std::exception& error)\n    {\n        std::cerr \u003C\u003C \"Error: \" \u003C\u003C error.what() \u003C\u003C '\\n';\n        return 2;\n    }\n}\n","cpp",[77,549,550,558,565,573,581,589,597,605,610,634,640,646,693,704,710,715,734,740,771,777,782,802,807,832,847,853,880,886,945,950,969,974,1000,1027,1051,1086,1094,1099,1105,1110,1129,1134,1139,1175,1184,1189,1194,1209,1214,1238,1243,1248,1263,1268,1275,1299,1311,1316,1339,1344,1363,1377,1382,1387,1392,1411,1416,1421,1457,1466,1471,1476,1491,1496,1525,1557,1587,1611,1616,1621,1637,1642,1668,1690,1712,1724,1729,1752,1757,1769,1774,1797,1802,1814,1819,1842,1847,1895,1900,1918,1923,1928,1944,1958,1972,1984,1990,1999,2016,2039,2053,2058,2063,2079,2084,2102,2107,2121,2126,2140,2145,2162,2184,2197,2202,2207,2225,2236,2241,2263,2268,2284,2305,2318,2323,2328,2341,2346,2373,2384,2389,2394,2400,2409,2424,2438,2452,2465,2470,2475,2493,2498,2503,2539,2548,2553,2558,2573,2578,2606,2630,2635,2640,2655,2660,2686,2712,2724,2729,2752,2757,2769,2774,2797,2802,2823,2850,2863,2868,2873,2878,2903,2908,2926,2940,2946,2951,2961,2966,2972,2977,2986,3005,3023,3041,3059,3076,3081,3105,3126,3153,3180,3199,3204,3222,3243,3248,3278,3292,3297,3329,3347,3352,3364,3398,3410,3442,3447,3476,3481,3501,3506,3539,3549,3554],{"__ignoreMap":75},[132,551,552,555],{"class":134,"line":135},[132,553,554],{"class":388},"#include",[132,556,557],{"class":152}," \"behaviortree_cpp_v3\u002Fbt_factory.h\"\n",[132,559,561],{"class":134,"line":560},2,[132,562,564],{"emptyLinePlaceholder":563},true,"\n",[132,566,568,570],{"class":134,"line":567},3,[132,569,554],{"class":388},[132,571,572],{"class":152}," \u003Cchrono>\n",[132,574,576,578],{"class":134,"line":575},4,[132,577,554],{"class":388},[132,579,580],{"class":152}," \u003Ccmath>\n",[132,582,584,586],{"class":134,"line":583},5,[132,585,554],{"class":388},[132,587,588],{"class":152}," \u003Ciostream>\n",[132,590,592,594],{"class":134,"line":591},6,[132,593,554],{"class":388},[132,595,596],{"class":152}," \u003Cstdexcept>\n",[132,598,600,602],{"class":134,"line":599},7,[132,601,554],{"class":388},[132,603,604],{"class":152}," \u003Cstring>\n",[132,606,608],{"class":134,"line":607},8,[132,609,564],{"emptyLinePlaceholder":563},[132,611,613,616,619,622,625,628,631],{"class":134,"line":612},9,[132,614,615],{"class":388},"class",[132,617,618],{"class":145}," BatteryOK",[132,620,621],{"class":138}," : ",[132,623,624],{"class":388},"public",[132,626,627],{"class":145}," BT",[132,629,630],{"class":138},"::",[132,632,633],{"class":145},"ConditionNode\n",[132,635,637],{"class":134,"line":636},10,[132,638,639],{"class":138},"{\n",[132,641,643],{"class":134,"line":642},11,[132,644,645],{"class":388},"public:\n",[132,647,649,652,655,658,661,663,666,669,673,676,678,680,682,685,687,690],{"class":134,"line":648},12,[132,650,651],{"class":145},"    BatteryOK",[132,653,654],{"class":138},"(",[132,656,657],{"class":388},"const",[132,659,660],{"class":145}," std",[132,662,630],{"class":138},[132,664,665],{"class":145},"string",[132,667,668],{"class":388},"&",[132,670,672],{"class":671},"s4XuR"," name",[132,674,675],{"class":138},", ",[132,677,657],{"class":388},[132,679,627],{"class":145},[132,681,630],{"class":138},[132,683,684],{"class":145},"NodeConfiguration",[132,686,668],{"class":388},[132,688,689],{"class":671}," config",[132,691,692],{"class":138},")\n",[132,694,696,699,701],{"class":134,"line":695},13,[132,697,698],{"class":138},"        : BT::",[132,700,473],{"class":145},[132,702,703],{"class":138},"(name, config)\n",[132,705,707],{"class":134,"line":706},14,[132,708,709],{"class":138},"    {}\n",[132,711,713],{"class":134,"line":712},15,[132,714,564],{"emptyLinePlaceholder":563},[132,716,718,721,723,725,728,731],{"class":134,"line":717},16,[132,719,720],{"class":388},"    static",[132,722,627],{"class":145},[132,724,630],{"class":138},[132,726,727],{"class":145},"PortsList",[132,729,730],{"class":145}," providedPorts",[132,732,733],{"class":138},"()\n",[132,735,737],{"class":134,"line":736},17,[132,738,739],{"class":138},"    {\n",[132,741,743,746,749,752,754,757,759,762,765,768],{"class":134,"line":742},18,[132,744,745],{"class":388},"        return",[132,747,748],{"class":138}," {",[132,750,751],{"class":145},"BT",[132,753,630],{"class":138},[132,755,756],{"class":145},"InputPort",[132,758,139],{"class":138},[132,760,761],{"class":388},"double",[132,763,764],{"class":138},">(",[132,766,767],{"class":152},"\"level\"",[132,769,770],{"class":138},")};\n",[132,772,774],{"class":134,"line":773},19,[132,775,776],{"class":138},"    }\n",[132,778,780],{"class":134,"line":779},20,[132,781,564],{"emptyLinePlaceholder":563},[132,783,785,788,790,793,796,799],{"class":134,"line":784},21,[132,786,787],{"class":145},"    BT",[132,789,630],{"class":138},[132,791,792],{"class":145},"NodeStatus",[132,794,795],{"class":145}," tick",[132,797,798],{"class":138},"() ",[132,800,801],{"class":388},"override\n",[132,803,805],{"class":134,"line":804},22,[132,806,739],{"class":138},[132,808,810,813,816,818,821,823,825,827,829],{"class":134,"line":809},23,[132,811,812],{"class":388},"        auto",[132,814,815],{"class":138}," level ",[132,817,149],{"class":388},[132,819,820],{"class":145}," getInput",[132,822,139],{"class":138},[132,824,761],{"class":388},[132,826,764],{"class":138},[132,828,767],{"class":152},[132,830,831],{"class":138},");\n",[132,833,835,838,841,844],{"class":134,"line":834},24,[132,836,837],{"class":388},"        if",[132,839,840],{"class":138}," (",[132,842,843],{"class":388},"!",[132,845,846],{"class":138},"level)\n",[132,848,850],{"class":134,"line":849},25,[132,851,852],{"class":138},"        {\n",[132,854,856,859,861,863,866,868,871,874,877],{"class":134,"line":855},26,[132,857,858],{"class":388},"            throw",[132,860,627],{"class":145},[132,862,630],{"class":138},[132,864,865],{"class":145},"RuntimeError",[132,867,654],{"class":138},[132,869,870],{"class":152},"\"Cannot read input [level]: \"",[132,872,873],{"class":138},", level.",[132,875,876],{"class":145},"error",[132,878,879],{"class":138},"());\n",[132,881,883],{"class":134,"line":882},27,[132,884,885],{"class":138},"        }\n",[132,887,889,891,893,895,898,900,903,906,909,912,915,918,920,922,924,928,931,933,935,937,940,943],{"class":134,"line":888},28,[132,890,837],{"class":388},[132,892,840],{"class":138},[132,894,843],{"class":388},[132,896,897],{"class":145},"std",[132,899,630],{"class":138},[132,901,902],{"class":145},"isfinite",[132,904,905],{"class":138},"(level.",[132,907,908],{"class":145},"value",[132,910,911],{"class":138},"()) ",[132,913,914],{"class":388},"||",[132,916,917],{"class":138}," level.",[132,919,908],{"class":145},[132,921,798],{"class":138},[132,923,139],{"class":388},[132,925,927],{"class":926},"sj4cs"," 0.0",[132,929,930],{"class":388}," ||",[132,932,917],{"class":138},[132,934,908],{"class":145},[132,936,798],{"class":138},[132,938,939],{"class":388},">",[132,941,942],{"class":926}," 100.0",[132,944,692],{"class":138},[132,946,948],{"class":134,"line":947},29,[132,949,852],{"class":138},[132,951,953,955,957,959,962,964,967],{"class":134,"line":952},30,[132,954,858],{"class":388},[132,956,660],{"class":145},[132,958,630],{"class":138},[132,960,961],{"class":145},"runtime_error",[132,963,654],{"class":138},[132,965,966],{"class":152},"\"battery level must be between 0 and 100\"",[132,968,831],{"class":138},[132,970,972],{"class":134,"line":971},31,[132,973,885],{"class":138},[132,975,977,980,983,986,988,990,992,994,997],{"class":134,"line":976},32,[132,978,979],{"class":388},"        const",[132,981,982],{"class":388}," auto",[132,984,985],{"class":138}," result ",[132,987,149],{"class":388},[132,989,917],{"class":138},[132,991,908],{"class":145},[132,993,798],{"class":138},[132,995,996],{"class":388},">=",[132,998,999],{"class":926}," 30.0\n",[132,1001,1003,1006,1008,1010,1012,1015,1018,1020,1022,1024],{"class":134,"line":1002},33,[132,1004,1005],{"class":388},"                                ?",[132,1007,627],{"class":145},[132,1009,630],{"class":138},[132,1011,792],{"class":145},[132,1013,1014],{"class":138},"::SUCCESS ",[132,1016,1017],{"class":388},":",[132,1019,627],{"class":145},[132,1021,630],{"class":138},[132,1023,792],{"class":145},[132,1025,1026],{"class":138},"::FAILURE;\n",[132,1028,1030,1033,1036,1039,1042,1045,1047,1049],{"class":134,"line":1029},34,[132,1031,1032],{"class":145},"        std",[132,1034,1035],{"class":138},"::cout ",[132,1037,1038],{"class":388},"\u003C\u003C",[132,1040,1041],{"class":152}," \"[BatteryOK] level=\"",[132,1043,1044],{"class":388}," \u003C\u003C",[132,1046,917],{"class":138},[132,1048,908],{"class":145},[132,1050,733],{"class":138},[132,1052,1054,1057,1060,1062,1064,1066,1069,1072,1074,1077,1080,1083],{"class":134,"line":1053},35,[132,1055,1056],{"class":388},"                  \u003C\u003C",[132,1058,1059],{"class":152}," \" -> \"",[132,1061,1044],{"class":388},[132,1063,627],{"class":145},[132,1065,630],{"class":138},[132,1067,1068],{"class":145},"toStr",[132,1070,1071],{"class":138},"(result) ",[132,1073,1038],{"class":388},[132,1075,1076],{"class":152}," '",[132,1078,1079],{"class":926},"\\n",[132,1081,1082],{"class":152},"'",[132,1084,1085],{"class":138},";\n",[132,1087,1089,1091],{"class":134,"line":1088},36,[132,1090,745],{"class":388},[132,1092,1093],{"class":138}," result;\n",[132,1095,1097],{"class":134,"line":1096},37,[132,1098,776],{"class":138},[132,1100,1102],{"class":134,"line":1101},38,[132,1103,1104],{"class":138},"};\n",[132,1106,1108],{"class":134,"line":1107},39,[132,1109,564],{"emptyLinePlaceholder":563},[132,1111,1113,1115,1118,1120,1122,1124,1126],{"class":134,"line":1112},40,[132,1114,615],{"class":388},[132,1116,1117],{"class":145}," ChargeBattery",[132,1119,621],{"class":138},[132,1121,624],{"class":388},[132,1123,627],{"class":145},[132,1125,630],{"class":138},[132,1127,1128],{"class":145},"SyncActionNode\n",[132,1130,1132],{"class":134,"line":1131},41,[132,1133,639],{"class":138},[132,1135,1137],{"class":134,"line":1136},42,[132,1138,645],{"class":388},[132,1140,1142,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167,1169,1171,1173],{"class":134,"line":1141},43,[132,1143,1144],{"class":145},"    ChargeBattery",[132,1146,654],{"class":138},[132,1148,657],{"class":388},[132,1150,660],{"class":145},[132,1152,630],{"class":138},[132,1154,665],{"class":145},[132,1156,668],{"class":388},[132,1158,672],{"class":671},[132,1160,675],{"class":138},[132,1162,657],{"class":388},[132,1164,627],{"class":145},[132,1166,630],{"class":138},[132,1168,684],{"class":145},[132,1170,668],{"class":388},[132,1172,689],{"class":671},[132,1174,692],{"class":138},[132,1176,1178,1180,1182],{"class":134,"line":1177},44,[132,1179,698],{"class":138},[132,1181,488],{"class":145},[132,1183,703],{"class":138},[132,1185,1187],{"class":134,"line":1186},45,[132,1188,709],{"class":138},[132,1190,1192],{"class":134,"line":1191},46,[132,1193,564],{"emptyLinePlaceholder":563},[132,1195,1197,1199,1201,1203,1205,1207],{"class":134,"line":1196},47,[132,1198,720],{"class":388},[132,1200,627],{"class":145},[132,1202,630],{"class":138},[132,1204,727],{"class":145},[132,1206,730],{"class":145},[132,1208,733],{"class":138},[132,1210,1212],{"class":134,"line":1211},48,[132,1213,739],{"class":138},[132,1215,1217,1219,1221,1223,1225,1228,1230,1232,1234,1236],{"class":134,"line":1216},49,[132,1218,745],{"class":388},[132,1220,748],{"class":138},[132,1222,751],{"class":145},[132,1224,630],{"class":138},[132,1226,1227],{"class":145},"OutputPort",[132,1229,139],{"class":138},[132,1231,761],{"class":388},[132,1233,764],{"class":138},[132,1235,767],{"class":152},[132,1237,770],{"class":138},[132,1239,1241],{"class":134,"line":1240},50,[132,1242,776],{"class":138},[132,1244,1246],{"class":134,"line":1245},51,[132,1247,564],{"emptyLinePlaceholder":563},[132,1249,1251,1253,1255,1257,1259,1261],{"class":134,"line":1250},52,[132,1252,787],{"class":145},[132,1254,630],{"class":138},[132,1256,792],{"class":145},[132,1258,795],{"class":145},[132,1260,798],{"class":138},[132,1262,801],{"class":388},[132,1264,1266],{"class":134,"line":1265},53,[132,1267,739],{"class":138},[132,1269,1271],{"class":134,"line":1270},54,[132,1272,1274],{"class":1273},"sJ8bj","        \u002F\u002F 本例把充电简化为一次数据更新，真实充电应实现为持续任务。\n",[132,1276,1278,1280,1283,1285,1288,1290,1292,1294,1297],{"class":134,"line":1277},55,[132,1279,812],{"class":388},[132,1281,1282],{"class":138}," written ",[132,1284,149],{"class":388},[132,1286,1287],{"class":145}," setOutput",[132,1289,654],{"class":138},[132,1291,767],{"class":152},[132,1293,675],{"class":138},[132,1295,1296],{"class":926},"80.0",[132,1298,831],{"class":138},[132,1300,1302,1304,1306,1308],{"class":134,"line":1301},56,[132,1303,837],{"class":388},[132,1305,840],{"class":138},[132,1307,843],{"class":388},[132,1309,1310],{"class":138},"written)\n",[132,1312,1314],{"class":134,"line":1313},57,[132,1315,852],{"class":138},[132,1317,1319,1321,1323,1325,1327,1329,1332,1335,1337],{"class":134,"line":1318},58,[132,1320,858],{"class":388},[132,1322,627],{"class":145},[132,1324,630],{"class":138},[132,1326,865],{"class":145},[132,1328,654],{"class":138},[132,1330,1331],{"class":152},"\"Cannot write output [level]: \"",[132,1333,1334],{"class":138},", written.",[132,1336,876],{"class":145},[132,1338,879],{"class":138},[132,1340,1342],{"class":134,"line":1341},59,[132,1343,885],{"class":138},[132,1345,1347,1349,1351,1353,1356,1358,1361],{"class":134,"line":1346},60,[132,1348,1032],{"class":145},[132,1350,1035],{"class":138},[132,1352,1038],{"class":388},[132,1354,1355],{"class":152}," \"[ChargeBattery] level=80",[132,1357,1079],{"class":926},[132,1359,1360],{"class":152},"\"",[132,1362,1085],{"class":138},[132,1364,1366,1368,1370,1372,1374],{"class":134,"line":1365},61,[132,1367,745],{"class":388},[132,1369,627],{"class":145},[132,1371,630],{"class":138},[132,1373,792],{"class":145},[132,1375,1376],{"class":138},"::SUCCESS;\n",[132,1378,1380],{"class":134,"line":1379},62,[132,1381,776],{"class":138},[132,1383,1385],{"class":134,"line":1384},63,[132,1386,1104],{"class":138},[132,1388,1390],{"class":134,"line":1389},64,[132,1391,564],{"emptyLinePlaceholder":563},[132,1393,1395,1397,1400,1402,1404,1406,1408],{"class":134,"line":1394},65,[132,1396,615],{"class":388},[132,1398,1399],{"class":145}," NavigateToGoal",[132,1401,621],{"class":138},[132,1403,624],{"class":388},[132,1405,627],{"class":145},[132,1407,630],{"class":138},[132,1409,1410],{"class":145},"StatefulActionNode\n",[132,1412,1414],{"class":134,"line":1413},66,[132,1415,639],{"class":138},[132,1417,1419],{"class":134,"line":1418},67,[132,1420,645],{"class":388},[132,1422,1424,1427,1429,1431,1433,1435,1437,1439,1441,1443,1445,1447,1449,1451,1453,1455],{"class":134,"line":1423},68,[132,1425,1426],{"class":145},"    NavigateToGoal",[132,1428,654],{"class":138},[132,1430,657],{"class":388},[132,1432,660],{"class":145},[132,1434,630],{"class":138},[132,1436,665],{"class":145},[132,1438,668],{"class":388},[132,1440,672],{"class":671},[132,1442,675],{"class":138},[132,1444,657],{"class":388},[132,1446,627],{"class":145},[132,1448,630],{"class":138},[132,1450,684],{"class":145},[132,1452,668],{"class":388},[132,1454,689],{"class":671},[132,1456,692],{"class":138},[132,1458,1460,1462,1464],{"class":134,"line":1459},69,[132,1461,698],{"class":138},[132,1463,503],{"class":145},[132,1465,703],{"class":138},[132,1467,1469],{"class":134,"line":1468},70,[132,1470,709],{"class":138},[132,1472,1474],{"class":134,"line":1473},71,[132,1475,564],{"emptyLinePlaceholder":563},[132,1477,1479,1481,1483,1485,1487,1489],{"class":134,"line":1478},72,[132,1480,720],{"class":388},[132,1482,627],{"class":145},[132,1484,630],{"class":138},[132,1486,727],{"class":145},[132,1488,730],{"class":145},[132,1490,733],{"class":138},[132,1492,1494],{"class":134,"line":1493},73,[132,1495,739],{"class":138},[132,1497,1499,1501,1503,1505,1507,1509,1511,1513,1515,1517,1519,1522],{"class":134,"line":1498},74,[132,1500,745],{"class":388},[132,1502,748],{"class":138},[132,1504,751],{"class":145},[132,1506,630],{"class":138},[132,1508,756],{"class":145},[132,1510,139],{"class":138},[132,1512,897],{"class":145},[132,1514,630],{"class":138},[132,1516,665],{"class":145},[132,1518,764],{"class":138},[132,1520,1521],{"class":152},"\"goal\"",[132,1523,1524],{"class":138},"),\n",[132,1526,1528,1531,1533,1535,1537,1540,1542,1545,1547,1550,1552,1555],{"class":134,"line":1527},75,[132,1529,1530],{"class":145},"                BT",[132,1532,630],{"class":138},[132,1534,756],{"class":145},[132,1536,139],{"class":138},[132,1538,1539],{"class":388},"int",[132,1541,764],{"class":138},[132,1543,1544],{"class":152},"\"ticks\"",[132,1546,675],{"class":138},[132,1548,1549],{"class":926},"2",[132,1551,675],{"class":138},[132,1553,1554],{"class":152},"\"每次导航尝试的检查次数\"",[132,1556,1524],{"class":138},[132,1558,1560,1562,1564,1566,1568,1570,1572,1575,1577,1580,1582,1585],{"class":134,"line":1559},76,[132,1561,1530],{"class":145},[132,1563,630],{"class":138},[132,1565,756],{"class":145},[132,1567,139],{"class":138},[132,1569,1539],{"class":388},[132,1571,764],{"class":138},[132,1573,1574],{"class":152},"\"fail_attempts\"",[132,1576,675],{"class":138},[132,1578,1579],{"class":926},"1",[132,1581,675],{"class":138},[132,1583,1584],{"class":152},"\"模拟前几次尝试失败\"",[132,1586,1524],{"class":138},[132,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606,1609],{"class":134,"line":1589},77,[132,1591,1530],{"class":145},[132,1593,630],{"class":138},[132,1595,1227],{"class":145},[132,1597,139],{"class":138},[132,1599,897],{"class":145},[132,1601,630],{"class":138},[132,1603,665],{"class":145},[132,1605,764],{"class":138},[132,1607,1608],{"class":152},"\"reached_goal\"",[132,1610,770],{"class":138},[132,1612,1614],{"class":134,"line":1613},78,[132,1615,776],{"class":138},[132,1617,1619],{"class":134,"line":1618},79,[132,1620,564],{"emptyLinePlaceholder":563},[132,1622,1624,1626,1628,1630,1633,1635],{"class":134,"line":1623},80,[132,1625,787],{"class":145},[132,1627,630],{"class":138},[132,1629,792],{"class":145},[132,1631,1632],{"class":145}," onStart",[132,1634,798],{"class":138},[132,1636,801],{"class":388},[132,1638,1640],{"class":134,"line":1639},81,[132,1641,739],{"class":138},[132,1643,1645,1647,1650,1652,1654,1656,1658,1660,1662,1664,1666],{"class":134,"line":1644},82,[132,1646,812],{"class":388},[132,1648,1649],{"class":138}," goal ",[132,1651,149],{"class":388},[132,1653,820],{"class":145},[132,1655,139],{"class":138},[132,1657,897],{"class":145},[132,1659,630],{"class":138},[132,1661,665],{"class":145},[132,1663,764],{"class":138},[132,1665,1521],{"class":152},[132,1667,831],{"class":138},[132,1669,1671,1673,1676,1678,1680,1682,1684,1686,1688],{"class":134,"line":1670},83,[132,1672,812],{"class":388},[132,1674,1675],{"class":138}," ticks ",[132,1677,149],{"class":388},[132,1679,820],{"class":145},[132,1681,139],{"class":138},[132,1683,1539],{"class":388},[132,1685,764],{"class":138},[132,1687,1544],{"class":152},[132,1689,831],{"class":138},[132,1691,1693,1695,1698,1700,1702,1704,1706,1708,1710],{"class":134,"line":1692},84,[132,1694,812],{"class":388},[132,1696,1697],{"class":138}," failures ",[132,1699,149],{"class":388},[132,1701,820],{"class":145},[132,1703,139],{"class":138},[132,1705,1539],{"class":388},[132,1707,764],{"class":138},[132,1709,1574],{"class":152},[132,1711,831],{"class":138},[132,1713,1715,1717,1719,1721],{"class":134,"line":1714},85,[132,1716,837],{"class":388},[132,1718,840],{"class":138},[132,1720,843],{"class":388},[132,1722,1723],{"class":138},"goal)\n",[132,1725,1727],{"class":134,"line":1726},86,[132,1728,852],{"class":138},[132,1730,1732,1734,1736,1738,1740,1742,1745,1748,1750],{"class":134,"line":1731},87,[132,1733,858],{"class":388},[132,1735,627],{"class":145},[132,1737,630],{"class":138},[132,1739,865],{"class":145},[132,1741,654],{"class":138},[132,1743,1744],{"class":152},"\"Cannot read input [goal]: \"",[132,1746,1747],{"class":138},", goal.",[132,1749,876],{"class":145},[132,1751,879],{"class":138},[132,1753,1755],{"class":134,"line":1754},88,[132,1756,885],{"class":138},[132,1758,1760,1762,1764,1766],{"class":134,"line":1759},89,[132,1761,837],{"class":388},[132,1763,840],{"class":138},[132,1765,843],{"class":388},[132,1767,1768],{"class":138},"ticks)\n",[132,1770,1772],{"class":134,"line":1771},90,[132,1773,852],{"class":138},[132,1775,1777,1779,1781,1783,1785,1787,1790,1793,1795],{"class":134,"line":1776},91,[132,1778,858],{"class":388},[132,1780,627],{"class":145},[132,1782,630],{"class":138},[132,1784,865],{"class":145},[132,1786,654],{"class":138},[132,1788,1789],{"class":152},"\"Cannot read input [ticks]: \"",[132,1791,1792],{"class":138},", ticks.",[132,1794,876],{"class":145},[132,1796,879],{"class":138},[132,1798,1800],{"class":134,"line":1799},92,[132,1801,885],{"class":138},[132,1803,1805,1807,1809,1811],{"class":134,"line":1804},93,[132,1806,837],{"class":388},[132,1808,840],{"class":138},[132,1810,843],{"class":388},[132,1812,1813],{"class":138},"failures)\n",[132,1815,1817],{"class":134,"line":1816},94,[132,1818,852],{"class":138},[132,1820,1822,1824,1826,1828,1830,1832,1835,1838,1840],{"class":134,"line":1821},95,[132,1823,858],{"class":388},[132,1825,627],{"class":145},[132,1827,630],{"class":138},[132,1829,865],{"class":145},[132,1831,654],{"class":138},[132,1833,1834],{"class":152},"\"Cannot read input [fail_attempts]: \"",[132,1836,1837],{"class":138},", failures.",[132,1839,876],{"class":145},[132,1841,879],{"class":138},[132,1843,1845],{"class":134,"line":1844},96,[132,1846,885],{"class":138},[132,1848,1850,1852,1855,1857,1860,1863,1865,1867,1870,1872,1874,1876,1879,1881,1884,1886,1888,1890,1893],{"class":134,"line":1849},97,[132,1851,837],{"class":388},[132,1853,1854],{"class":138}," (goal.",[132,1856,908],{"class":145},[132,1858,1859],{"class":138},"().",[132,1861,1862],{"class":145},"empty",[132,1864,798],{"class":138},[132,1866,914],{"class":388},[132,1868,1869],{"class":138}," ticks.",[132,1871,908],{"class":145},[132,1873,798],{"class":138},[132,1875,139],{"class":388},[132,1877,1878],{"class":926}," 1",[132,1880,930],{"class":388},[132,1882,1883],{"class":138}," failures.",[132,1885,908],{"class":145},[132,1887,798],{"class":138},[132,1889,139],{"class":388},[132,1891,1892],{"class":926}," 0",[132,1894,692],{"class":138},[132,1896,1898],{"class":134,"line":1897},98,[132,1899,852],{"class":138},[132,1901,1903,1905,1907,1909,1911,1913,1916],{"class":134,"line":1902},99,[132,1904,858],{"class":388},[132,1906,660],{"class":145},[132,1908,630],{"class":138},[132,1910,961],{"class":145},[132,1912,654],{"class":138},[132,1914,1915],{"class":152},"\"invalid navigation simulation parameters\"",[132,1917,831],{"class":138},[132,1919,1921],{"class":134,"line":1920},100,[132,1922,885],{"class":138},[132,1924,1926],{"class":134,"line":1925},101,[132,1927,564],{"emptyLinePlaceholder":563},[132,1929,1931,1934,1936,1939,1941],{"class":134,"line":1930},102,[132,1932,1933],{"class":138},"        goal_ ",[132,1935,149],{"class":388},[132,1937,1938],{"class":138}," goal.",[132,1940,908],{"class":145},[132,1942,1943],{"class":138},"();\n",[132,1945,1947,1950,1952,1954,1956],{"class":134,"line":1946},103,[132,1948,1949],{"class":138},"        required_ticks_ ",[132,1951,149],{"class":388},[132,1953,1869],{"class":138},[132,1955,908],{"class":145},[132,1957,1943],{"class":138},[132,1959,1961,1964,1966,1968,1970],{"class":134,"line":1960},104,[132,1962,1963],{"class":138},"        failed_attempts_ ",[132,1965,149],{"class":388},[132,1967,1883],{"class":138},[132,1969,908],{"class":145},[132,1971,1943],{"class":138},[132,1973,1975,1978,1980,1982],{"class":134,"line":1974},105,[132,1976,1977],{"class":138},"        completed_ticks_ ",[132,1979,149],{"class":388},[132,1981,1892],{"class":926},[132,1983,1085],{"class":138},[132,1985,1987],{"class":134,"line":1986},106,[132,1988,1989],{"class":1273},"        \u002F\u002F 每个节点实例分别保留尝试次数，用于模拟先失败、后成功。\n",[132,1991,1993,1996],{"class":134,"line":1992},107,[132,1994,1995],{"class":388},"        ++",[132,1997,1998],{"class":138},"attempt_;\n",[132,2000,2002,2004,2006,2008,2011,2013],{"class":134,"line":2001},108,[132,2003,1032],{"class":145},[132,2005,1035],{"class":138},[132,2007,1038],{"class":388},[132,2009,2010],{"class":152}," \"[NavigateToGoal] start goal=\"",[132,2012,1044],{"class":388},[132,2014,2015],{"class":138}," goal_\n",[132,2017,2019,2021,2024,2026,2029,2031,2033,2035,2037],{"class":134,"line":2018},109,[132,2020,1056],{"class":388},[132,2022,2023],{"class":152}," \", attempt=\"",[132,2025,1044],{"class":388},[132,2027,2028],{"class":138}," attempt_ ",[132,2030,1038],{"class":388},[132,2032,1076],{"class":152},[132,2034,1079],{"class":926},[132,2036,1082],{"class":152},[132,2038,1085],{"class":138},[132,2040,2042,2044,2046,2048,2050],{"class":134,"line":2041},110,[132,2043,745],{"class":388},[132,2045,627],{"class":145},[132,2047,630],{"class":138},[132,2049,792],{"class":145},[132,2051,2052],{"class":138},"::RUNNING;\n",[132,2054,2056],{"class":134,"line":2055},111,[132,2057,776],{"class":138},[132,2059,2061],{"class":134,"line":2060},112,[132,2062,564],{"emptyLinePlaceholder":563},[132,2064,2066,2068,2070,2072,2075,2077],{"class":134,"line":2065},113,[132,2067,787],{"class":145},[132,2069,630],{"class":138},[132,2071,792],{"class":145},[132,2073,2074],{"class":145}," onRunning",[132,2076,798],{"class":138},[132,2078,801],{"class":388},[132,2080,2082],{"class":134,"line":2081},114,[132,2083,739],{"class":138},[132,2085,2087,2089,2091,2094,2097,2099],{"class":134,"line":2086},115,[132,2088,837],{"class":388},[132,2090,840],{"class":138},[132,2092,2093],{"class":388},"++",[132,2095,2096],{"class":138},"completed_ticks_ ",[132,2098,139],{"class":388},[132,2100,2101],{"class":138}," required_ticks_)\n",[132,2103,2105],{"class":134,"line":2104},116,[132,2106,852],{"class":138},[132,2108,2110,2113,2115,2117,2119],{"class":134,"line":2109},117,[132,2111,2112],{"class":388},"            return",[132,2114,627],{"class":145},[132,2116,630],{"class":138},[132,2118,792],{"class":145},[132,2120,2052],{"class":138},[132,2122,2124],{"class":134,"line":2123},118,[132,2125,885],{"class":138},[132,2127,2129,2131,2134,2137],{"class":134,"line":2128},119,[132,2130,837],{"class":388},[132,2132,2133],{"class":138}," (attempt_ ",[132,2135,2136],{"class":388},"\u003C=",[132,2138,2139],{"class":138}," failed_attempts_)\n",[132,2141,2143],{"class":134,"line":2142},120,[132,2144,852],{"class":138},[132,2146,2148,2151,2153,2155,2158,2160],{"class":134,"line":2147},121,[132,2149,2150],{"class":145},"            std",[132,2152,1035],{"class":138},[132,2154,1038],{"class":388},[132,2156,2157],{"class":152}," \"[NavigateToGoal] failed goal=\"",[132,2159,1044],{"class":388},[132,2161,2015],{"class":138},[132,2163,2165,2168,2170,2172,2174,2176,2178,2180,2182],{"class":134,"line":2164},122,[132,2166,2167],{"class":388},"                      \u003C\u003C",[132,2169,2023],{"class":152},[132,2171,1044],{"class":388},[132,2173,2028],{"class":138},[132,2175,1038],{"class":388},[132,2177,1076],{"class":152},[132,2179,1079],{"class":926},[132,2181,1082],{"class":152},[132,2183,1085],{"class":138},[132,2185,2187,2189,2191,2193,2195],{"class":134,"line":2186},123,[132,2188,2112],{"class":388},[132,2190,627],{"class":145},[132,2192,630],{"class":138},[132,2194,792],{"class":145},[132,2196,1026],{"class":138},[132,2198,2200],{"class":134,"line":2199},124,[132,2201,885],{"class":138},[132,2203,2205],{"class":134,"line":2204},125,[132,2206,564],{"emptyLinePlaceholder":563},[132,2208,2210,2212,2214,2216,2218,2220,2222],{"class":134,"line":2209},126,[132,2211,812],{"class":388},[132,2213,1282],{"class":138},[132,2215,149],{"class":388},[132,2217,1287],{"class":145},[132,2219,654],{"class":138},[132,2221,1608],{"class":152},[132,2223,2224],{"class":138},", goal_);\n",[132,2226,2228,2230,2232,2234],{"class":134,"line":2227},127,[132,2229,837],{"class":388},[132,2231,840],{"class":138},[132,2233,843],{"class":388},[132,2235,1310],{"class":138},[132,2237,2239],{"class":134,"line":2238},128,[132,2240,852],{"class":138},[132,2242,2244,2246,2248,2250,2252,2254,2257,2259,2261],{"class":134,"line":2243},129,[132,2245,858],{"class":388},[132,2247,627],{"class":145},[132,2249,630],{"class":138},[132,2251,865],{"class":145},[132,2253,654],{"class":138},[132,2255,2256],{"class":152},"\"Cannot write output [reached_goal]: \"",[132,2258,1334],{"class":138},[132,2260,876],{"class":145},[132,2262,879],{"class":138},[132,2264,2266],{"class":134,"line":2265},130,[132,2267,885],{"class":138},[132,2269,2271,2273,2275,2277,2280,2282],{"class":134,"line":2270},131,[132,2272,1032],{"class":145},[132,2274,1035],{"class":138},[132,2276,1038],{"class":388},[132,2278,2279],{"class":152}," \"[NavigateToGoal] arrived goal=\"",[132,2281,1044],{"class":388},[132,2283,2015],{"class":138},[132,2285,2287,2289,2291,2293,2295,2297,2299,2301,2303],{"class":134,"line":2286},132,[132,2288,1056],{"class":388},[132,2290,2023],{"class":152},[132,2292,1044],{"class":388},[132,2294,2028],{"class":138},[132,2296,1038],{"class":388},[132,2298,1076],{"class":152},[132,2300,1079],{"class":926},[132,2302,1082],{"class":152},[132,2304,1085],{"class":138},[132,2306,2308,2310,2312,2314,2316],{"class":134,"line":2307},133,[132,2309,745],{"class":388},[132,2311,627],{"class":145},[132,2313,630],{"class":138},[132,2315,792],{"class":145},[132,2317,1376],{"class":138},[132,2319,2321],{"class":134,"line":2320},134,[132,2322,776],{"class":138},[132,2324,2326],{"class":134,"line":2325},135,[132,2327,564],{"emptyLinePlaceholder":563},[132,2329,2331,2334,2337,2339],{"class":134,"line":2330},136,[132,2332,2333],{"class":388},"    void",[132,2335,2336],{"class":145}," onHalted",[132,2338,798],{"class":138},[132,2340,801],{"class":388},[132,2342,2344],{"class":134,"line":2343},137,[132,2345,739],{"class":138},[132,2347,2349,2351,2353,2355,2358,2360,2363,2365,2367,2369,2371],{"class":134,"line":2348},138,[132,2350,1032],{"class":145},[132,2352,1035],{"class":138},[132,2354,1038],{"class":388},[132,2356,2357],{"class":152}," \"[NavigateToGoal] halted goal=\"",[132,2359,1044],{"class":388},[132,2361,2362],{"class":138}," goal_ ",[132,2364,1038],{"class":388},[132,2366,1076],{"class":152},[132,2368,1079],{"class":926},[132,2370,1082],{"class":152},[132,2372,1085],{"class":138},[132,2374,2376,2378,2380,2382],{"class":134,"line":2375},139,[132,2377,1977],{"class":138},[132,2379,149],{"class":388},[132,2381,1892],{"class":926},[132,2383,1085],{"class":138},[132,2385,2387],{"class":134,"line":2386},140,[132,2388,776],{"class":138},[132,2390,2392],{"class":134,"line":2391},141,[132,2393,564],{"emptyLinePlaceholder":563},[132,2395,2397],{"class":134,"line":2396},142,[132,2398,2399],{"class":388},"private:\n",[132,2401,2403,2406],{"class":134,"line":2402},143,[132,2404,2405],{"class":145},"    std",[132,2407,2408],{"class":138},"::string goal_;\n",[132,2410,2412,2415,2418,2420,2422],{"class":134,"line":2411},144,[132,2413,2414],{"class":388},"    int",[132,2416,2417],{"class":138}," required_ticks_ ",[132,2419,149],{"class":388},[132,2421,1892],{"class":926},[132,2423,1085],{"class":138},[132,2425,2427,2429,2432,2434,2436],{"class":134,"line":2426},145,[132,2428,2414],{"class":388},[132,2430,2431],{"class":138}," completed_ticks_ ",[132,2433,149],{"class":388},[132,2435,1892],{"class":926},[132,2437,1085],{"class":138},[132,2439,2441,2443,2446,2448,2450],{"class":134,"line":2440},146,[132,2442,2414],{"class":388},[132,2444,2445],{"class":138}," failed_attempts_ ",[132,2447,149],{"class":388},[132,2449,1892],{"class":926},[132,2451,1085],{"class":138},[132,2453,2455,2457,2459,2461,2463],{"class":134,"line":2454},147,[132,2456,2414],{"class":388},[132,2458,2028],{"class":138},[132,2460,149],{"class":388},[132,2462,1892],{"class":926},[132,2464,1085],{"class":138},[132,2466,2468],{"class":134,"line":2467},148,[132,2469,1104],{"class":138},[132,2471,2473],{"class":134,"line":2472},149,[132,2474,564],{"emptyLinePlaceholder":563},[132,2476,2478,2480,2483,2485,2487,2489,2491],{"class":134,"line":2477},150,[132,2479,615],{"class":388},[132,2481,2482],{"class":145}," ReportMission",[132,2484,621],{"class":138},[132,2486,624],{"class":388},[132,2488,627],{"class":145},[132,2490,630],{"class":138},[132,2492,1128],{"class":145},[132,2494,2496],{"class":134,"line":2495},151,[132,2497,639],{"class":138},[132,2499,2501],{"class":134,"line":2500},152,[132,2502,645],{"class":388},[132,2504,2506,2509,2511,2513,2515,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537],{"class":134,"line":2505},153,[132,2507,2508],{"class":145},"    ReportMission",[132,2510,654],{"class":138},[132,2512,657],{"class":388},[132,2514,660],{"class":145},[132,2516,630],{"class":138},[132,2518,665],{"class":145},[132,2520,668],{"class":388},[132,2522,672],{"class":671},[132,2524,675],{"class":138},[132,2526,657],{"class":388},[132,2528,627],{"class":145},[132,2530,630],{"class":138},[132,2532,684],{"class":145},[132,2534,668],{"class":388},[132,2536,689],{"class":671},[132,2538,692],{"class":138},[132,2540,2542,2544,2546],{"class":134,"line":2541},154,[132,2543,698],{"class":138},[132,2545,488],{"class":145},[132,2547,703],{"class":138},[132,2549,2551],{"class":134,"line":2550},155,[132,2552,709],{"class":138},[132,2554,2556],{"class":134,"line":2555},156,[132,2557,564],{"emptyLinePlaceholder":563},[132,2559,2561,2563,2565,2567,2569,2571],{"class":134,"line":2560},157,[132,2562,720],{"class":388},[132,2564,627],{"class":145},[132,2566,630],{"class":138},[132,2568,727],{"class":145},[132,2570,730],{"class":145},[132,2572,733],{"class":138},[132,2574,2576],{"class":134,"line":2575},158,[132,2577,739],{"class":138},[132,2579,2581,2583,2585,2587,2589,2591,2593,2595,2597,2599,2601,2604],{"class":134,"line":2580},159,[132,2582,745],{"class":388},[132,2584,748],{"class":138},[132,2586,751],{"class":145},[132,2588,630],{"class":138},[132,2590,756],{"class":145},[132,2592,139],{"class":138},[132,2594,897],{"class":145},[132,2596,630],{"class":138},[132,2598,665],{"class":145},[132,2600,764],{"class":138},[132,2602,2603],{"class":152},"\"pickup\"",[132,2605,1524],{"class":138},[132,2607,2609,2611,2613,2615,2617,2619,2621,2623,2625,2628],{"class":134,"line":2608},160,[132,2610,1530],{"class":145},[132,2612,630],{"class":138},[132,2614,756],{"class":145},[132,2616,139],{"class":138},[132,2618,897],{"class":145},[132,2620,630],{"class":138},[132,2622,665],{"class":145},[132,2624,764],{"class":138},[132,2626,2627],{"class":152},"\"dropoff\"",[132,2629,770],{"class":138},[132,2631,2633],{"class":134,"line":2632},161,[132,2634,776],{"class":138},[132,2636,2638],{"class":134,"line":2637},162,[132,2639,564],{"emptyLinePlaceholder":563},[132,2641,2643,2645,2647,2649,2651,2653],{"class":134,"line":2642},163,[132,2644,787],{"class":145},[132,2646,630],{"class":138},[132,2648,792],{"class":145},[132,2650,795],{"class":145},[132,2652,798],{"class":138},[132,2654,801],{"class":388},[132,2656,2658],{"class":134,"line":2657},164,[132,2659,739],{"class":138},[132,2661,2663,2665,2668,2670,2672,2674,2676,2678,2680,2682,2684],{"class":134,"line":2662},165,[132,2664,812],{"class":388},[132,2666,2667],{"class":138}," pickup ",[132,2669,149],{"class":388},[132,2671,820],{"class":145},[132,2673,139],{"class":138},[132,2675,897],{"class":145},[132,2677,630],{"class":138},[132,2679,665],{"class":145},[132,2681,764],{"class":138},[132,2683,2603],{"class":152},[132,2685,831],{"class":138},[132,2687,2689,2691,2694,2696,2698,2700,2702,2704,2706,2708,2710],{"class":134,"line":2688},166,[132,2690,812],{"class":388},[132,2692,2693],{"class":138}," dropoff ",[132,2695,149],{"class":388},[132,2697,820],{"class":145},[132,2699,139],{"class":138},[132,2701,897],{"class":145},[132,2703,630],{"class":138},[132,2705,665],{"class":145},[132,2707,764],{"class":138},[132,2709,2627],{"class":152},[132,2711,831],{"class":138},[132,2713,2715,2717,2719,2721],{"class":134,"line":2714},167,[132,2716,837],{"class":388},[132,2718,840],{"class":138},[132,2720,843],{"class":388},[132,2722,2723],{"class":138},"pickup)\n",[132,2725,2727],{"class":134,"line":2726},168,[132,2728,852],{"class":138},[132,2730,2732,2734,2736,2738,2740,2742,2745,2748,2750],{"class":134,"line":2731},169,[132,2733,858],{"class":388},[132,2735,627],{"class":145},[132,2737,630],{"class":138},[132,2739,865],{"class":145},[132,2741,654],{"class":138},[132,2743,2744],{"class":152},"\"Cannot read input [pickup]: \"",[132,2746,2747],{"class":138},", pickup.",[132,2749,876],{"class":145},[132,2751,879],{"class":138},[132,2753,2755],{"class":134,"line":2754},170,[132,2756,885],{"class":138},[132,2758,2760,2762,2764,2766],{"class":134,"line":2759},171,[132,2761,837],{"class":388},[132,2763,840],{"class":138},[132,2765,843],{"class":388},[132,2767,2768],{"class":138},"dropoff)\n",[132,2770,2772],{"class":134,"line":2771},172,[132,2773,852],{"class":138},[132,2775,2777,2779,2781,2783,2785,2787,2790,2793,2795],{"class":134,"line":2776},173,[132,2778,858],{"class":388},[132,2780,627],{"class":145},[132,2782,630],{"class":138},[132,2784,865],{"class":145},[132,2786,654],{"class":138},[132,2788,2789],{"class":152},"\"Cannot read input [dropoff]: \"",[132,2791,2792],{"class":138},", dropoff.",[132,2794,876],{"class":145},[132,2796,879],{"class":138},[132,2798,2800],{"class":134,"line":2799},174,[132,2801,885],{"class":138},[132,2803,2805,2807,2809,2811,2814,2816,2819,2821],{"class":134,"line":2804},175,[132,2806,1032],{"class":145},[132,2808,1035],{"class":138},[132,2810,1038],{"class":388},[132,2812,2813],{"class":152}," \"[ReportMission] pickup=\"",[132,2815,1044],{"class":388},[132,2817,2818],{"class":138}," pickup.",[132,2820,908],{"class":145},[132,2822,733],{"class":138},[132,2824,2826,2828,2831,2833,2836,2838,2840,2842,2844,2846,2848],{"class":134,"line":2825},176,[132,2827,1056],{"class":388},[132,2829,2830],{"class":152}," \", dropoff=\"",[132,2832,1044],{"class":388},[132,2834,2835],{"class":138}," dropoff.",[132,2837,908],{"class":145},[132,2839,798],{"class":138},[132,2841,1038],{"class":388},[132,2843,1076],{"class":152},[132,2845,1079],{"class":926},[132,2847,1082],{"class":152},[132,2849,1085],{"class":138},[132,2851,2853,2855,2857,2859,2861],{"class":134,"line":2852},177,[132,2854,745],{"class":388},[132,2856,627],{"class":145},[132,2858,630],{"class":138},[132,2860,792],{"class":145},[132,2862,1376],{"class":138},[132,2864,2866],{"class":134,"line":2865},178,[132,2867,776],{"class":138},[132,2869,2871],{"class":134,"line":2870},179,[132,2872,1104],{"class":138},[132,2874,2876],{"class":134,"line":2875},180,[132,2877,564],{"emptyLinePlaceholder":563},[132,2879,2881,2883,2885,2887,2890,2892,2894,2896,2899,2901],{"class":134,"line":2880},181,[132,2882,751],{"class":145},[132,2884,630],{"class":138},[132,2886,792],{"class":145},[132,2888,2889],{"class":145}," ReportFailure",[132,2891,654],{"class":138},[132,2893,751],{"class":145},[132,2895,630],{"class":138},[132,2897,2898],{"class":145},"TreeNode",[132,2900,668],{"class":388},[132,2902,692],{"class":138},[132,2904,2906],{"class":134,"line":2905},182,[132,2907,639],{"class":138},[132,2909,2911,2913,2915,2917,2920,2922,2924],{"class":134,"line":2910},183,[132,2912,2405],{"class":145},[132,2914,1035],{"class":138},[132,2916,1038],{"class":388},[132,2918,2919],{"class":152}," \"[ReportFailure] transport mission failed",[132,2921,1079],{"class":926},[132,2923,1360],{"class":152},[132,2925,1085],{"class":138},[132,2927,2929,2932,2934,2936,2938],{"class":134,"line":2928},184,[132,2930,2931],{"class":388},"    return",[132,2933,627],{"class":145},[132,2935,630],{"class":138},[132,2937,792],{"class":145},[132,2939,1376],{"class":138},[132,2941,2943],{"class":134,"line":2942},185,[132,2944,2945],{"class":138},"}\n",[132,2947,2949],{"class":134,"line":2948},186,[132,2950,564],{"emptyLinePlaceholder":563},[132,2952,2954,2956,2959],{"class":134,"line":2953},187,[132,2955,1539],{"class":388},[132,2957,2958],{"class":145}," main",[132,2960,733],{"class":138},[132,2962,2964],{"class":134,"line":2963},188,[132,2965,639],{"class":138},[132,2967,2969],{"class":134,"line":2968},189,[132,2970,2971],{"class":388},"    try\n",[132,2973,2975],{"class":134,"line":2974},190,[132,2976,739],{"class":138},[132,2978,2980,2983],{"class":134,"line":2979},191,[132,2981,2982],{"class":145},"        BT",[132,2984,2985],{"class":138},"::BehaviorTreeFactory factory;\n",[132,2987,2989,2992,2994,2996,2998,3000,3003],{"class":134,"line":2988},192,[132,2990,2991],{"class":138},"        factory.registerNodeType",[132,2993,139],{"class":388},[132,2995,468],{"class":138},[132,2997,939],{"class":388},[132,2999,654],{"class":138},[132,3001,3002],{"class":152},"\"BatteryOK\"",[132,3004,831],{"class":138},[132,3006,3008,3010,3012,3014,3016,3018,3021],{"class":134,"line":3007},193,[132,3009,2991],{"class":138},[132,3011,139],{"class":388},[132,3013,483],{"class":138},[132,3015,939],{"class":388},[132,3017,654],{"class":138},[132,3019,3020],{"class":152},"\"ChargeBattery\"",[132,3022,831],{"class":138},[132,3024,3026,3028,3030,3032,3034,3036,3039],{"class":134,"line":3025},194,[132,3027,2991],{"class":138},[132,3029,139],{"class":388},[132,3031,498],{"class":138},[132,3033,939],{"class":388},[132,3035,654],{"class":138},[132,3037,3038],{"class":152},"\"NavigateToGoal\"",[132,3040,831],{"class":138},[132,3042,3044,3046,3048,3050,3052,3054,3057],{"class":134,"line":3043},195,[132,3045,2991],{"class":138},[132,3047,139],{"class":388},[132,3049,516],{"class":138},[132,3051,939],{"class":388},[132,3053,654],{"class":138},[132,3055,3056],{"class":152},"\"ReportMission\"",[132,3058,831],{"class":138},[132,3060,3062,3065,3068,3070,3073],{"class":134,"line":3061},196,[132,3063,3064],{"class":138},"        factory.",[132,3066,3067],{"class":145},"registerSimpleAction",[132,3069,654],{"class":138},[132,3071,3072],{"class":152},"\"ReportFailure\"",[132,3074,3075],{"class":138},", ReportFailure);\n",[132,3077,3079],{"class":134,"line":3078},197,[132,3080,564],{"emptyLinePlaceholder":563},[132,3082,3084,3086,3089,3091,3093,3095,3098,3100,3103],{"class":134,"line":3083},198,[132,3085,812],{"class":388},[132,3087,3088],{"class":138}," blackboard ",[132,3090,149],{"class":388},[132,3092,627],{"class":145},[132,3094,630],{"class":138},[132,3096,3097],{"class":145},"Blackboard",[132,3099,630],{"class":138},[132,3101,3102],{"class":145},"create",[132,3104,1943],{"class":138},[132,3106,3108,3111,3114,3116,3119,3121,3124],{"class":134,"line":3107},199,[132,3109,3110],{"class":138},"        blackboard->",[132,3112,3113],{"class":145},"set",[132,3115,654],{"class":138},[132,3117,3118],{"class":152},"\"battery\"",[132,3120,675],{"class":138},[132,3122,3123],{"class":926},"20.0",[132,3125,831],{"class":138},[132,3127,3129,3131,3133,3135,3137,3139,3141,3143,3145,3147,3150],{"class":134,"line":3128},200,[132,3130,3110],{"class":138},[132,3132,3113],{"class":145},[132,3134,654],{"class":138},[132,3136,161],{"class":152},[132,3138,675],{"class":138},[132,3140,897],{"class":145},[132,3142,630],{"class":138},[132,3144,665],{"class":145},[132,3146,654],{"class":138},[132,3148,3149],{"class":152},"\"loading_area\"",[132,3151,3152],{"class":138},"));\n",[132,3154,3156,3158,3160,3162,3165,3167,3169,3171,3173,3175,3178],{"class":134,"line":3155},201,[132,3157,3110],{"class":138},[132,3159,3113],{"class":145},[132,3161,654],{"class":138},[132,3163,3164],{"class":152},"\"dropoff_goal\"",[132,3166,675],{"class":138},[132,3168,897],{"class":145},[132,3170,630],{"class":138},[132,3172,665],{"class":145},[132,3174,654],{"class":138},[132,3176,3177],{"class":152},"\"unloading_area\"",[132,3179,3152],{"class":138},[132,3181,3183,3185,3188,3190,3193,3196],{"class":134,"line":3182},202,[132,3184,812],{"class":388},[132,3186,3187],{"class":138}," tree ",[132,3189,149],{"class":388},[132,3191,3192],{"class":138}," factory.",[132,3194,3195],{"class":145},"createTreeFromFile",[132,3197,3198],{"class":138},"(BT_XML_PATH, blackboard);\n",[132,3200,3202],{"class":134,"line":3201},203,[132,3203,564],{"emptyLinePlaceholder":563},[132,3205,3207,3209,3212,3214,3217,3220],{"class":134,"line":3206},204,[132,3208,2982],{"class":145},[132,3210,3211],{"class":138},"::NodeStatus result ",[132,3213,149],{"class":388},[132,3215,3216],{"class":138}," tree.",[132,3218,3219],{"class":145},"tickRoot",[132,3221,1943],{"class":138},[132,3223,3225,3228,3231,3234,3236,3238,3240],{"class":134,"line":3224},205,[132,3226,3227],{"class":388},"        while",[132,3229,3230],{"class":138}," (result ",[132,3232,3233],{"class":388},"==",[132,3235,627],{"class":145},[132,3237,630],{"class":138},[132,3239,792],{"class":145},[132,3241,3242],{"class":138},"::RUNNING)\n",[132,3244,3246],{"class":134,"line":3245},206,[132,3247,852],{"class":138},[132,3249,3251,3254,3257,3259,3261,3263,3266,3268,3271,3273,3276],{"class":134,"line":3250},207,[132,3252,3253],{"class":138},"            tree.",[132,3255,3256],{"class":145},"sleep",[132,3258,654],{"class":138},[132,3260,897],{"class":145},[132,3262,630],{"class":138},[132,3264,3265],{"class":145},"chrono",[132,3267,630],{"class":138},[132,3269,3270],{"class":145},"milliseconds",[132,3272,654],{"class":138},[132,3274,3275],{"class":926},"100",[132,3277,3152],{"class":138},[132,3279,3281,3284,3286,3288,3290],{"class":134,"line":3280},208,[132,3282,3283],{"class":138},"            result ",[132,3285,149],{"class":388},[132,3287,3216],{"class":138},[132,3289,3219],{"class":145},[132,3291,1943],{"class":138},[132,3293,3295],{"class":134,"line":3294},209,[132,3296,885],{"class":138},[132,3298,3300,3302,3304,3306,3309,3311,3313,3315,3317,3319,3321,3323,3325,3327],{"class":134,"line":3299},210,[132,3301,1032],{"class":145},[132,3303,1035],{"class":138},[132,3305,1038],{"class":388},[132,3307,3308],{"class":152}," \"Tree result: \"",[132,3310,1044],{"class":388},[132,3312,627],{"class":145},[132,3314,630],{"class":138},[132,3316,1068],{"class":145},[132,3318,1071],{"class":138},[132,3320,1038],{"class":388},[132,3322,1076],{"class":152},[132,3324,1079],{"class":926},[132,3326,1082],{"class":152},[132,3328,1085],{"class":138},[132,3330,3332,3334,3336,3338,3340,3342,3344],{"class":134,"line":3331},211,[132,3333,837],{"class":388},[132,3335,3230],{"class":138},[132,3337,3233],{"class":388},[132,3339,627],{"class":145},[132,3341,630],{"class":138},[132,3343,792],{"class":145},[132,3345,3346],{"class":138},"::SUCCESS)\n",[132,3348,3350],{"class":134,"line":3349},212,[132,3351,852],{"class":138},[132,3353,3355,3357,3359,3361],{"class":134,"line":3354},213,[132,3356,2150],{"class":145},[132,3358,1035],{"class":138},[132,3360,1038],{"class":388},[132,3362,3363],{"class":152}," \"[main] pickup_reached=\"\n",[132,3365,3367,3369,3372,3374,3376,3379,3381,3383,3385,3388,3390,3392,3394,3396],{"class":134,"line":3366},214,[132,3368,2167],{"class":388},[132,3370,3371],{"class":138}," blackboard->get",[132,3373,139],{"class":388},[132,3375,897],{"class":145},[132,3377,3378],{"class":138},"::string",[132,3380,939],{"class":388},[132,3382,654],{"class":138},[132,3384,169],{"class":152},[132,3386,3387],{"class":138},") ",[132,3389,1038],{"class":388},[132,3391,1076],{"class":152},[132,3393,1079],{"class":926},[132,3395,1082],{"class":152},[132,3397,1085],{"class":138},[132,3399,3401,3403,3405,3407],{"class":134,"line":3400},215,[132,3402,2150],{"class":145},[132,3404,1035],{"class":138},[132,3406,1038],{"class":388},[132,3408,3409],{"class":152}," \"[main] dropoff_reached=\"\n",[132,3411,3413,3415,3417,3419,3421,3423,3425,3427,3430,3432,3434,3436,3438,3440],{"class":134,"line":3412},216,[132,3414,2167],{"class":388},[132,3416,3371],{"class":138},[132,3418,139],{"class":388},[132,3420,897],{"class":145},[132,3422,3378],{"class":138},[132,3424,939],{"class":388},[132,3426,654],{"class":138},[132,3428,3429],{"class":152},"\"dropoff_reached\"",[132,3431,3387],{"class":138},[132,3433,1038],{"class":388},[132,3435,1076],{"class":152},[132,3437,1079],{"class":926},[132,3439,1082],{"class":152},[132,3441,1085],{"class":138},[132,3443,3445],{"class":134,"line":3444},217,[132,3446,885],{"class":138},[132,3448,3450,3452,3454,3456,3458,3460,3462,3464,3467,3469,3472,3474],{"class":134,"line":3449},218,[132,3451,745],{"class":388},[132,3453,985],{"class":138},[132,3455,3233],{"class":388},[132,3457,627],{"class":145},[132,3459,630],{"class":138},[132,3461,792],{"class":145},[132,3463,1014],{"class":138},[132,3465,3466],{"class":388},"?",[132,3468,1892],{"class":926},[132,3470,3471],{"class":388}," :",[132,3473,1878],{"class":926},[132,3475,1085],{"class":138},[132,3477,3479],{"class":134,"line":3478},219,[132,3480,776],{"class":138},[132,3482,3484,3487,3489,3491,3493,3496,3498],{"class":134,"line":3483},220,[132,3485,3486],{"class":388},"    catch",[132,3488,840],{"class":138},[132,3490,657],{"class":388},[132,3492,660],{"class":145},[132,3494,3495],{"class":138},"::exception",[132,3497,668],{"class":388},[132,3499,3500],{"class":138}," error)\n",[132,3502,3504],{"class":134,"line":3503},221,[132,3505,739],{"class":138},[132,3507,3509,3511,3514,3516,3519,3521,3524,3527,3529,3531,3533,3535,3537],{"class":134,"line":3508},222,[132,3510,1032],{"class":145},[132,3512,3513],{"class":138},"::cerr ",[132,3515,1038],{"class":388},[132,3517,3518],{"class":152}," \"Error: \"",[132,3520,1044],{"class":388},[132,3522,3523],{"class":138}," error.",[132,3525,3526],{"class":145},"what",[132,3528,798],{"class":138},[132,3530,1038],{"class":388},[132,3532,1076],{"class":152},[132,3534,1079],{"class":926},[132,3536,1082],{"class":152},[132,3538,1085],{"class":138},[132,3540,3542,3544,3547],{"class":134,"line":3541},223,[132,3543,745],{"class":388},[132,3545,3546],{"class":926}," 2",[132,3548,1085],{"class":138},[132,3550,3552],{"class":134,"line":3551},224,[132,3553,776],{"class":138},[132,3555,3557],{"class":134,"line":3556},225,[132,3558,2945],{"class":138},[19,3560,3561,35,3564,3567,3568,3571,3572,3575,3576,3579,3580,3583,3584,3587,3588,3591],{},[77,3562,3563],{},"ticks",[77,3565,3566],{},"fail_attempts"," 都是本例的模拟参数。",[77,3569,3570],{},"ticks=\"2\""," 表示一次导航在两次 ",[77,3573,3574],{},"onRunning()"," 检查后给出结果；",[77,3577,3578],{},"fail_attempts=\"1\""," 表示同一个节点实例的第一次尝试失败，后续尝试成功。节点的 ",[77,3581,3582],{},"attempt_"," 从 ",[77,3585,3586],{},"0"," 开始，在每次 ",[77,3589,3590],{},"onStart()"," 中递增。",[19,3593,3594,3596],{},[77,3595,3582],{}," 是教学模拟器自己的计数，和 Retry 装饰节点内部的重试计数不是同一个变量。这里故意保留它，才能在重启导航后模拟“第一次失败、第二次成功”。每次 Launch 都会创建新的树；如果实际程序复用同一棵树处理多个任务，应明确什么时候重置业务成员和结果条目。",[3598,3599,3601],"h3",{"id":3600},"对照本例中的-api-参数","对照本例中的 API 参数",[19,3603,3604,3605,3608,3609,3612,3613,3616],{},"本篇主要组合前面已经使用过的接口。注册和端口接口的原型见 ",[77,3606,3607],{},"第一个完整程序","，外部 Blackboard 的读写见 ",[77,3610,3611],{},"节点之间传数据","，回调与驱动循环见 ",[77,3614,3615],{},"持续任务与中止","。对照本例时，重点看每个实参对应哪一层名称：",[194,3618,3619,3632],{},[197,3620,3621],{},[200,3622,3623,3626,3629],{},[203,3624,3625],{},"调用",[203,3627,3628],{},"参数含义",[203,3630,3631],{},"返回值",[213,3633,3634,3650,3670,3692,3708,3724],{},[200,3635,3636,3641,3644],{},[218,3637,3638],{},[77,3639,3640],{},"factory.registerNodeType\u003CNavigateToGoal>(\"NavigateToGoal\")",[218,3642,3643],{},"模板参数是 C++ 节点类；第一个函数参数是 XML 中使用的注册名",[218,3645,3646,3649],{},[77,3647,3648],{},"void","，注册类型，尚未启动导航",[200,3651,3652,3657,3664],{},[218,3653,3654],{},[77,3655,3656],{},"factory.registerSimpleAction(\"ReportFailure\", ReportFailure)",[218,3658,3659,3660,3663],{},"第一个参数是注册名；第二个参数是回调函数本身，树执行到 ",[77,3661,3662],{},"\u003CReportFailure\u002F>"," 时才调用它",[218,3665,3666,3667,3669],{},"注册函数返回 ",[77,3668,3648],{},"；回调另行返回自己的节点状态",[200,3671,3672,3677,3687],{},[218,3673,3674],{},[77,3675,3676],{},"blackboard->set(\"battery\", 20.0)",[218,3678,3679,3680,3683,3684,3686],{},"第一个参数是 Blackboard 键，第二个参数是值；这里省略 ",[77,3681,3682],{},"\u003Cdouble>","，由 ",[77,3685,3123],{}," 推导类型",[218,3688,3689,3691],{},[77,3690,3648],{},"，写入电量",[200,3693,3694,3699,3702],{},[218,3695,3696],{},[77,3697,3698],{},"factory.createTreeFromFile(BT_XML_PATH, blackboard)",[218,3700,3701],{},"第一个参数是入口 XML 路径；第二个参数是根树使用的 Blackboard 共享指针",[218,3703,3704,3707],{},[77,3705,3706],{},"BT::Tree","，包含创建好的节点实例",[200,3709,3710,3715,3718],{},[218,3711,3712],{},[77,3713,3714],{},"setOutput(\"reached_goal\", goal_)",[218,3716,3717],{},"第一个参数是当前节点的输出端口名；第二个参数是保存的目标字符串",[218,3719,3720,3723],{},[77,3721,3722],{},"BT::Result","，本例检查写出是否成功",[200,3725,3726,3731,3734],{},[218,3727,3728],{},[77,3729,3730],{},"blackboard->get\u003Cstd::string>(\"pickup_reached\")",[218,3732,3733],{},"模板参数指定读取类型；第一个函数参数是根 Blackboard 中的结果键",[218,3735,3736,3739],{},[77,3737,3738],{},"std::string"," 值；键不存在或类型不兼容时抛出异常",[19,3741,3742,3745,3746,3748,3749,3745,3752,3754,3755,3758,3759,3762,3763,3766],{},[77,3743,3744],{},"setOutput()"," 的 ",[77,3747,509],{}," 是节点端口名，",[77,3750,3751],{},"get()",[77,3753,186],{}," 是主程序要读取的 Blackboard 键，两者由后面的 XML 映射连接。",[77,3756,3757],{},"ReportFailure()"," 回调返回 ",[77,3760,3761],{},"SUCCESS"," 表示报告动作完成；整项运输任务的失败结果由 XML 中包裹它的 ",[77,3764,3765],{},"ForceFailure"," 保留，不能把回调返回值与注册函数返回值混为一谈。",[90,3768],{},[12,3770,3772],{"id":3771},"用两个-xml-文件组织任务","用两个 XML 文件组织任务",[3598,3774,406],{"id":3775},"treesmissionxml",[19,3777,3778,3779,3781],{},"用下面的 XML 替换 ",[77,3780,406],{}," 的原有内容，再保存。",[69,3783,3785],{"className":126,"code":3784,"language":128,"meta":75,"style":75},"\u003Croot main_tree_to_execute=\"MainTree\">\n    \u003Cinclude path=\"navigation.xml\"\u002F>\n\n    \u003CBehaviorTree ID=\"MainTree\">\n        \u003CSequence name=\"transport_job\">\n            \u003CFallback name=\"ensure_battery\">\n                \u003CBatteryOK level=\"{battery}\"\u002F>\n                \u003CChargeBattery level=\"{battery}\"\u002F>\n            \u003C\u002FFallback>\n\n            \u003CFallback name=\"run_or_report_failure\">\n                \u003CSequence>\n                    \u003CSubTree ID=\"NavigateLeg\"\n                             target=\"pickup_goal\" reached=\"pickup_reached\"\u002F>\n                    \u003CSubTree ID=\"NavigateLeg\"\n                             target=\"dropoff_goal\" reached=\"dropoff_reached\"\u002F>\n                    \u003CReportMission pickup=\"{pickup_reached}\"\n                                   dropoff=\"{dropoff_reached}\"\u002F>\n                \u003C\u002FSequence>\n                \u003CForceFailure>\n                    \u003CReportFailure\u002F>\n                \u003C\u002FForceFailure>\n            \u003C\u002FFallback>\n        \u003C\u002FSequence>\n    \u003C\u002FBehaviorTree>\n\u003C\u002Froot>\n",[77,3786,3787,3805,3823,3827,3842,3859,3876,3893,3907,3916,3920,3935,3943,3957,3974,3986,4002,4016,4028,4037,4045,4053,4061,4069,4078,4087],{"__ignoreMap":75},[132,3788,3789,3791,3794,3797,3799,3802],{"class":134,"line":135},[132,3790,139],{"class":138},[132,3792,3793],{"class":142},"root",[132,3795,3796],{"class":145}," main_tree_to_execute",[132,3798,149],{"class":138},[132,3800,3801],{"class":152},"\"MainTree\"",[132,3803,3804],{"class":138},">\n",[132,3806,3807,3810,3813,3816,3818,3821],{"class":134,"line":560},[132,3808,3809],{"class":138},"    \u003C",[132,3811,3812],{"class":142},"include",[132,3814,3815],{"class":145}," path",[132,3817,149],{"class":138},[132,3819,3820],{"class":152},"\"navigation.xml\"",[132,3822,172],{"class":138},[132,3824,3825],{"class":134,"line":567},[132,3826,564],{"emptyLinePlaceholder":563},[132,3828,3829,3831,3834,3836,3838,3840],{"class":134,"line":575},[132,3830,3809],{"class":138},[132,3832,3833],{"class":142},"BehaviorTree",[132,3835,146],{"class":145},[132,3837,149],{"class":138},[132,3839,3801],{"class":152},[132,3841,3804],{"class":138},[132,3843,3844,3847,3850,3852,3854,3857],{"class":134,"line":583},[132,3845,3846],{"class":138},"        \u003C",[132,3848,3849],{"class":142},"Sequence",[132,3851,672],{"class":145},[132,3853,149],{"class":138},[132,3855,3856],{"class":152},"\"transport_job\"",[132,3858,3804],{"class":138},[132,3860,3861,3864,3867,3869,3871,3874],{"class":134,"line":591},[132,3862,3863],{"class":138},"            \u003C",[132,3865,3866],{"class":142},"Fallback",[132,3868,672],{"class":145},[132,3870,149],{"class":138},[132,3872,3873],{"class":152},"\"ensure_battery\"",[132,3875,3804],{"class":138},[132,3877,3878,3881,3883,3886,3888,3891],{"class":134,"line":599},[132,3879,3880],{"class":138},"                \u003C",[132,3882,468],{"class":142},[132,3884,3885],{"class":145}," level",[132,3887,149],{"class":138},[132,3889,3890],{"class":152},"\"{battery}\"",[132,3892,172],{"class":138},[132,3894,3895,3897,3899,3901,3903,3905],{"class":134,"line":607},[132,3896,3880],{"class":138},[132,3898,483],{"class":142},[132,3900,3885],{"class":145},[132,3902,149],{"class":138},[132,3904,3890],{"class":152},[132,3906,172],{"class":138},[132,3908,3909,3912,3914],{"class":134,"line":612},[132,3910,3911],{"class":138},"            \u003C\u002F",[132,3913,3866],{"class":142},[132,3915,3804],{"class":138},[132,3917,3918],{"class":134,"line":636},[132,3919,564],{"emptyLinePlaceholder":563},[132,3921,3922,3924,3926,3928,3930,3933],{"class":134,"line":642},[132,3923,3863],{"class":138},[132,3925,3866],{"class":142},[132,3927,672],{"class":145},[132,3929,149],{"class":138},[132,3931,3932],{"class":152},"\"run_or_report_failure\"",[132,3934,3804],{"class":138},[132,3936,3937,3939,3941],{"class":134,"line":648},[132,3938,3880],{"class":138},[132,3940,3849],{"class":142},[132,3942,3804],{"class":138},[132,3944,3945,3948,3950,3952,3954],{"class":134,"line":695},[132,3946,3947],{"class":138},"                    \u003C",[132,3949,122],{"class":142},[132,3951,146],{"class":145},[132,3953,149],{"class":138},[132,3955,3956],{"class":152},"\"NavigateLeg\"\n",[132,3958,3959,3962,3964,3966,3968,3970,3972],{"class":134,"line":706},[132,3960,3961],{"class":145},"                             target",[132,3963,149],{"class":138},[132,3965,161],{"class":152},[132,3967,164],{"class":145},[132,3969,149],{"class":138},[132,3971,169],{"class":152},[132,3973,172],{"class":138},[132,3975,3976,3978,3980,3982,3984],{"class":134,"line":712},[132,3977,3947],{"class":138},[132,3979,122],{"class":142},[132,3981,146],{"class":145},[132,3983,149],{"class":138},[132,3985,3956],{"class":152},[132,3987,3988,3990,3992,3994,3996,3998,4000],{"class":134,"line":717},[132,3989,3961],{"class":145},[132,3991,149],{"class":138},[132,3993,3164],{"class":152},[132,3995,164],{"class":145},[132,3997,149],{"class":138},[132,3999,3429],{"class":152},[132,4001,172],{"class":138},[132,4003,4004,4006,4008,4011,4013],{"class":134,"line":736},[132,4005,3947],{"class":138},[132,4007,516],{"class":142},[132,4009,4010],{"class":145}," pickup",[132,4012,149],{"class":138},[132,4014,4015],{"class":152},"\"{pickup_reached}\"\n",[132,4017,4018,4021,4023,4026],{"class":134,"line":742},[132,4019,4020],{"class":145},"                                   dropoff",[132,4022,149],{"class":138},[132,4024,4025],{"class":152},"\"{dropoff_reached}\"",[132,4027,172],{"class":138},[132,4029,4030,4033,4035],{"class":134,"line":773},[132,4031,4032],{"class":138},"                \u003C\u002F",[132,4034,3849],{"class":142},[132,4036,3804],{"class":138},[132,4038,4039,4041,4043],{"class":134,"line":779},[132,4040,3880],{"class":138},[132,4042,3765],{"class":142},[132,4044,3804],{"class":138},[132,4046,4047,4049,4051],{"class":134,"line":784},[132,4048,3947],{"class":138},[132,4050,530],{"class":142},[132,4052,172],{"class":138},[132,4054,4055,4057,4059],{"class":134,"line":804},[132,4056,4032],{"class":138},[132,4058,3765],{"class":142},[132,4060,3804],{"class":138},[132,4062,4063,4065,4067],{"class":134,"line":809},[132,4064,3911],{"class":138},[132,4066,3866],{"class":142},[132,4068,3804],{"class":138},[132,4070,4071,4074,4076],{"class":134,"line":834},[132,4072,4073],{"class":138},"        \u003C\u002F",[132,4075,3849],{"class":142},[132,4077,3804],{"class":138},[132,4079,4080,4083,4085],{"class":134,"line":849},[132,4081,4082],{"class":138},"    \u003C\u002F",[132,4084,3833],{"class":142},[132,4086,3804],{"class":138},[132,4088,4089,4092,4094],{"class":134,"line":855},[132,4090,4091],{"class":138},"\u003C\u002F",[132,4093,3793],{"class":142},[132,4095,3804],{"class":138},[19,4097,4098,4099,4101,4102,4105,4106,4108,4109,4111],{},"主树中两次 ",[77,4100,122],{}," 使用相同的 ",[77,4103,4104],{},"ID=\"NavigateLeg\"","，但分别映射到取货点和放货点的父键。",[77,4107,100],{}," 是 XML 中定义的行为树名称，",[77,4110,498],{}," 才是注册到工厂的 C++ 叶节点名称。",[3598,4113,4115],{"id":4114},"treesnavigationxml","trees\u002Fnavigation.xml",[19,4117,4118,4119,57],{},"将下面的内容保存到新建的 ",[77,4120,4115],{},[69,4122,4124],{"className":126,"code":4123,"language":128,"meta":75,"style":75},"\u003Croot>\n    \u003CBehaviorTree ID=\"NavigateLeg\">\n        \u003CRetryUntilSuccessful num_attempts=\"2\">\n            \u003CNavigateToGoal goal=\"{target}\" reached_goal=\"{reached}\"\n                            ticks=\"2\" fail_attempts=\"1\"\u002F>\n        \u003C\u002FRetryUntilSuccessful>\n    \u003C\u002FBehaviorTree>\n\u003C\u002Froot>\n",[77,4125,4126,4134,4148,4165,4187,4206,4214,4222],{"__ignoreMap":75},[132,4127,4128,4130,4132],{"class":134,"line":135},[132,4129,139],{"class":138},[132,4131,3793],{"class":142},[132,4133,3804],{"class":138},[132,4135,4136,4138,4140,4142,4144,4146],{"class":134,"line":560},[132,4137,3809],{"class":138},[132,4139,3833],{"class":142},[132,4141,146],{"class":145},[132,4143,149],{"class":138},[132,4145,153],{"class":152},[132,4147,3804],{"class":138},[132,4149,4150,4152,4155,4158,4160,4163],{"class":134,"line":567},[132,4151,3846],{"class":138},[132,4153,4154],{"class":142},"RetryUntilSuccessful",[132,4156,4157],{"class":145}," num_attempts",[132,4159,149],{"class":138},[132,4161,4162],{"class":152},"\"2\"",[132,4164,3804],{"class":138},[132,4166,4167,4169,4171,4174,4176,4179,4182,4184],{"class":134,"line":575},[132,4168,3863],{"class":138},[132,4170,498],{"class":142},[132,4172,4173],{"class":145}," goal",[132,4175,149],{"class":138},[132,4177,4178],{"class":152},"\"{target}\"",[132,4180,4181],{"class":145}," reached_goal",[132,4183,149],{"class":138},[132,4185,4186],{"class":152},"\"{reached}\"\n",[132,4188,4189,4192,4194,4196,4199,4201,4204],{"class":134,"line":583},[132,4190,4191],{"class":145},"                            ticks",[132,4193,149],{"class":138},[132,4195,4162],{"class":152},[132,4197,4198],{"class":145}," fail_attempts",[132,4200,149],{"class":138},[132,4202,4203],{"class":152},"\"1\"",[132,4205,172],{"class":138},[132,4207,4208,4210,4212],{"class":134,"line":591},[132,4209,4073],{"class":138},[132,4211,4154],{"class":142},[132,4213,3804],{"class":138},[132,4215,4216,4218,4220],{"class":134,"line":599},[132,4217,4082],{"class":138},[132,4219,3833],{"class":142},[132,4221,3804],{"class":138},[132,4223,4224,4226,4228],{"class":134,"line":607},[132,4225,4091],{"class":138},[132,4227,3793],{"class":142},[132,4229,3804],{"class":138},[19,4231,4232,4235,4236,4239,4240,4242,4243,57],{},[77,4233,4234],{},"\u003Cinclude path=\"navigation.xml\"\u002F>"," 会在加载主 XML 时引入子树定义，路径相对于包含它的 ",[77,4237,4238],{},"mission.xml"," 所在目录。主程序通过 ",[77,4241,426],{}," 的完整路径加载入口，所以从不同工作目录启动，仍能找到同目录的 ",[77,4244,414],{},[19,4246,4247,4248,35,4250,4253,4254,4256],{},"C++ 中已经注册了叶节点；两个 XML 负责定义和连接任务。工厂加载入口文件时会处理 ",[77,4249,3812],{},[77,4251,4252],{},"BehaviorTree ID","，因此不需要再为 ",[77,4255,100],{}," 编写一个 C++ 节点类。",[16,4258,4259],{},[19,4260,4261,4264,4265,4267],{},[62,4262,4263],{},"截图预留：主树和导航子树。"," 展示两个 XML 文件，以及两处 ",[77,4266,122],{}," 映射到不同父键的位置。",[90,4269],{},[12,4271,4273],{"id":4272},"在-vscode-中运行完整任务","在 VSCode 中运行完整任务",[19,4275,4276,4277,4280,4281,4284,4285,4287,4288,4291],{},"保存所有文件，选择 ",[62,4278,4279],{},"Linux Debug","，执行 ",[62,4282,4283],{},"Configure → Build","，将运行目标设为 ",[62,4286,318],{},"，再点击 ",[62,4289,4290],{},"Launch","。完整输出为：",[69,4293,4296],{"className":4294,"code":4295,"language":74,"meta":75},[72],"[BatteryOK] level=20 -> FAILURE\n[ChargeBattery] level=80\n[NavigateToGoal] start goal=loading_area, attempt=1\n[NavigateToGoal] failed goal=loading_area, attempt=1\n[NavigateToGoal] start goal=loading_area, attempt=2\n[NavigateToGoal] arrived goal=loading_area, attempt=2\n[NavigateToGoal] start goal=unloading_area, attempt=1\n[NavigateToGoal] failed goal=unloading_area, attempt=1\n[NavigateToGoal] start goal=unloading_area, attempt=2\n[NavigateToGoal] arrived goal=unloading_area, attempt=2\n[ReportMission] pickup=loading_area, dropoff=unloading_area\nTree result: SUCCESS\n[main] pickup_reached=loading_area\n[main] dropoff_reached=unloading_area\n",[77,4297,4295],{"__ignoreMap":75},[16,4299,4300],{},[19,4301,4302,4305],{},[62,4303,4304],{},"截图预留：组合任务正常完成。"," 展示从电量不足、模拟充电、两段导航分别重试，到主程序读取结果的完整输出。",[19,4307,4308,4309,4311,4312,4314],{},"初始电量为 20，因此先检查失败，再由 ",[77,4310,483],{}," 更新为 80。两段导航分别经历第一次失败、第二次成功，最后 ",[77,4313,516],{}," 和主程序都能读到两个到达结果。",[194,4316,4317,4330],{},[197,4318,4319],{},[200,4320,4321,4324,4327],{},[203,4322,4323],{},"执行位置",[203,4325,4326],{},"本次使用的数据",[203,4328,4329],{},"结果",[213,4331,4332,4346,4363,4381,4391],{},[200,4333,4334,4337,4343],{},[218,4335,4336],{},"电量 Fallback",[218,4338,4339,4340],{},"主树的 ",[77,4341,4342],{},"battery",[218,4344,4345],{},"低电量时更新到 80",[200,4347,4348,4351,4358],{},[218,4349,4350],{},"第一次 NavigateLeg",[218,4352,4353,4355,4356],{},[77,4354,183],{}," 映射到局部 ",[77,4357,104],{},[218,4359,4360,4361],{},"写出 ",[77,4362,186],{},[200,4364,4365,4368,4376],{},[218,4366,4367],{},"第二次 NavigateLeg",[218,4369,4370,4373,4374],{},[77,4371,4372],{},"dropoff_goal"," 映射到另一个局部 ",[77,4375,104],{},[218,4377,4360,4378],{},[77,4379,4380],{},"dropoff_reached",[200,4382,4383,4385,4388],{},[218,4384,516],{},[218,4386,4387],{},"主树的两个结果键",[218,4389,4390],{},"输出任务完成信息",[200,4392,4393,4396,4399],{},[218,4394,4395],{},"main",[218,4397,4398],{},"从根 Blackboard 读取两个结果",[218,4400,4401],{},"确认跨子树的数据传递",[19,4403,4404],{},"电量检查是这次任务的启动准备。进入导航后，外层普通 Sequence 会从正在执行的位置继续，电量检查不会每次都重跑。如果任务要求导航期间持续检查某个条件，可以沿用上一篇的 ReactiveSequence 方式组织检查层。",[90,4406],{},[12,4408,4409],{"id":4409},"有限重试与失败报告各自负责一层",[19,4411,4412,4415,4416,4419,4420,4422,4423,4426],{},[77,4413,4414],{},"num_attempts=\"2\""," 表示",[62,4417,4418],{},"最多两次总尝试","，不是首次尝试之后再额外重试两次。导航返回 ",[77,4421,84],{}," 时，装饰节点继续等待这一次尝试；只有导航返回 ",[77,4424,4425],{},"FAILURE","，才会记录一次失败并决定是否重新开始。",[19,4428,4429,4430,4432,4433,4435,4436,4439],{},"在 3.8.7 中，Retry 收到失败后可以在同一次根 tick 内重置子节点并立即开始下一次尝试。本例新的 ",[77,4431,3590],{}," 返回 ",[77,4434,84],{}," 后，控制权就会回到主循环。因此日志中一次失败后可以紧接着出现下一次 ",[77,4437,4438],{},"start","，不必假定它们一定属于不同的根 tick。",[19,4441,4442,4443,4445,4446,4448,4449,4452,4453,4455],{},"将 ",[77,4444,414],{}," 中的 ",[77,4447,4414],{}," 改为 ",[77,4450,4451],{},"num_attempts=\"1\"","，只保存 XML，再点击 ",[62,4454,4290],{},"。此时第一次失败已经耗尽次数，输出为：",[69,4457,4460],{"className":4458,"code":4459,"language":74,"meta":75},[72],"[BatteryOK] level=20 -> FAILURE\n[ChargeBattery] level=80\n[NavigateToGoal] start goal=loading_area, attempt=1\n[NavigateToGoal] failed goal=loading_area, attempt=1\n[ReportFailure] transport mission failed\nTree result: FAILURE\n",[77,4461,4459],{"__ignoreMap":75},[19,4463,4464,4465,4467],{},"没有出现放货点导航，也没有执行 ",[77,4466,516],{},"，因为第一段子树失败后，导航 Sequence 立即结束。",[16,4469,4470],{},[19,4471,4472,4475,4476,4478,4479,57],{},[62,4473,4474],{},"截图预留：重试次数耗尽。"," 展示 ",[77,4477,4451],{},"、失败报告以及最终的 ",[77,4480,4425],{},[19,4482,4483,4484,4486],{},"失败报告分支外面包了一层 ",[77,4485,3765],{},"：",[69,4488,4491],{"className":4489,"code":4490,"language":74,"meta":75},[72],"ForceFailure\n└── ReportFailure   报告动作执行完毕，返回 SUCCESS\n         ↓\n该分支向任务 Fallback 返回 FAILURE\n",[77,4492,4490],{"__ignoreMap":75},[19,4494,4495,4497,4498,4500,4501,4503],{},[77,4496,530],{}," 返回成功表示日志报告已经执行；",[77,4499,3765],{}," 保留的是运输任务失败的结果。这样完成失败处理后，整棵树仍返回 ",[77,4502,4425],{},"，主程序也不会进入成功结果的读取分支。",[90,4505],{},[12,4507,4509],{"id":4508},"分别修改电量重试和映射来对照","分别修改电量、重试和映射来对照",[19,4511,4512,4513,4516,4517,57],{},"每次对照只改一项，完成后恢复原值，再进行下一项。修改 C++ 后先 ",[62,4514,4515],{},"Build → Launch","；只改 XML 时保存后直接 ",[62,4518,4290],{},[194,4520,4521,4534],{},[197,4522,4523],{},[200,4524,4525,4528,4531],{},[203,4526,4527],{},"修改位置",[203,4529,4530],{},"修改内容",[203,4532,4533],{},"观察到的结果",[213,4535,4536,4552,4566,4581,4602],{},[200,4537,4538,4544,4549],{},[218,4539,4540,4543],{},[77,4541,4542],{},"main()"," 初始化",[218,4545,4546,4548],{},[77,4547,4342],{}," 从 20.0 改为 80.0",[218,4550,4551],{},"电量检查直接成功，不执行模拟充电",[200,4553,4554,4558,4563],{},[218,4555,4556],{},[77,4557,414],{},[218,4559,4560,4562],{},[77,4561,3566],{}," 从 1 改为 0",[218,4564,4565],{},"两段导航都在第一次尝试成功",[200,4567,4568,4572,4578],{},[218,4569,4570],{},[77,4571,414],{},[218,4573,4574,4575,4577],{},"保持最多两次尝试，将 ",[77,4576,3566],{}," 改为 2",[218,4579,4580],{},"取货点两次都失败，任务失败，放货点不执行",[200,4582,4583,4588,4596],{},[218,4584,4585,4587],{},[77,4586,4238],{}," 的第一次 SubTree",[218,4589,4442,4590,4592,4593],{},[77,4591,244],{}," 改成 ",[77,4594,4595],{},"target=\"{pickup_goal}\"",[218,4597,4598,4599,4601],{},"普通 SubTree 映射到错误的父键，读取 ",[77,4600,296],{}," 报错",[200,4603,4604,4608,4614],{},[218,4605,4606,4587],{},[77,4607,4238],{},[218,4609,4610,4611],{},"删除 ",[77,4612,4613],{},"reached=\"pickup_reached\"",[218,4615,4616,4617,4620],{},"到达结果只写到该子树局部键，主树读取 ",[77,4618,4619],{},"pickup"," 时缺少输入",[19,4622,4623,4624,4627,4628,4630,4631,4633,4634,57],{},"最后两种是数据配置错误，主程序打印 ",[77,4625,4626],{},"Error:"," 并返回 ",[77,4629,1549],{},"。它们不同于导航尝试耗尽时的任务 ",[77,4632,4425],{},"，后者正常返回任务失败码 ",[77,4635,1579],{},[16,4637,4638],{},[19,4639,4640,4643],{},[62,4641,4642],{},"截图预留：子树映射错误。"," 展示其中一种错误映射和终端中的读取错误，便于和正常的任务失败区分。",[19,4645,4646],{},"如果遗漏输出映射，子树内部仍然可以完成一次导航；真正缺失的是通往主树结果条目的连接。局部键名字相同，不代表所有子树自动共享同一个存储位置。",[90,4648],{},[12,4650,4651],{"id":4651},"在断点中确认两次调用是不同的节点实例",[19,4653,4654,4655,4658,4659,4662,4663,4666,4667,57],{},"恢复主示例的电量与 XML，先 ",[62,4656,4657],{},"Build","。在 ",[77,4660,4661],{},"NavigateToGoal::onStart()"," 中 ",[77,4664,4665],{},"++attempt_"," 之后的打印语句处设置断点，再点击 ",[62,4668,4669],{},"Debug",[19,4671,4672,4673,29,4676,4678,4679,4682,4683,4685],{},"每次暂停时查看 ",[77,4674,4675],{},"goal_",[77,4677,3582],{},"，并比较 ",[77,4680,4681],{},"this"," 指针。取货点的两次启动会在同一个节点对象上出现，尝试次数依次为 1、2；进入放货点时，",[77,4684,4681],{}," 指针不同，那个节点自己的尝试次数也从 1 开始。",[19,4687,4688],{},"这个过程对应的是“同一份子树定义，两次独立实例化”。复用的是结构和实现，任务成员与未映射的局部 Blackboard 条目分别属于各自实例。",[16,4690,4691],{},[19,4692,4693,4696,4697,29,4699,29,4701,57],{},[62,4694,4695],{},"截图预留：不同子树实例中的导航节点。"," 展示取货点和放货点暂停时的 ",[77,4698,4681],{},[77,4700,4675],{},[77,4702,3582],{},[19,4704,4705,4706,4709,4710,4713],{},"本篇完整工程，以及电量充足、首次成功、重试耗尽、错误输入映射和遗漏输出映射等对照，已在 Ubuntu 22.04 的 ",[77,4707,4708],{},"ysu_ros_humble"," 容器中，使用 ",[62,4711,4712],{},"C++20、CMake 3.22.1、GCC 11.4、BehaviorTree.CPP 3.8.7"," 编译运行验证。入口 XML 从不同工作目录加载也已验证。测试使用临时工程和 Ninja，保留了容器内已有练习工程。",[90,4715],{},[12,4717,4718],{"id":4718},"当前学习进度",[19,4720,4721],{},"到这里，教程已经给出了从最小程序到组合任务的完整实践路径：",[194,4723,4724,4734],{},[197,4725,4726],{},[200,4727,4728,4731],{},[203,4729,4730],{},"文档",[203,4732,4733],{},"对应的实践主题",[213,4735,4736,4743,4750,4757],{},[200,4737,4738,4740],{},[218,4739,3607],{},[218,4741,4742],{},"注册节点、加载 XML、执行最小树，再逐步增加条件和端口",[200,4744,4745,4747],{},[218,4746,3611],{},[218,4748,4749],{},"自定义类型、输入输出与双向端口、外部 Blackboard",[200,4751,4752,4754],{},[218,4753,3615],{},[218,4755,4756],{},"多次 tick、StatefulActionNode、条件变化和主动中止",[200,4758,4759,4762],{},[218,4760,4761],{},"本篇",[218,4763,4764],{},"子树隔离与映射、多 XML 文件、有限重试和失败处理",[19,4766,4767],{},[62,4768,4769],{},"基础编程实践的文档到此结束。",[4771,4772,4773],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":75,"searchDepth":560,"depth":560,"links":4775},[4776,4777,4778,4779,4782,4786,4787,4788,4789,4790],{"id":14,"depth":560,"text":14},{"id":94,"depth":560,"text":94},{"id":308,"depth":560,"text":308},{"id":441,"depth":560,"text":441,"children":4780},[4781],{"id":3600,"depth":567,"text":3601},{"id":3771,"depth":560,"text":3772,"children":4783},[4784,4785],{"id":3775,"depth":567,"text":406},{"id":4114,"depth":567,"text":4115},{"id":4272,"depth":560,"text":4273},{"id":4409,"depth":560,"text":4409},{"id":4508,"depth":560,"text":4509},{"id":4651,"depth":560,"text":4651},{"id":4718,"depth":560,"text":4718},"1200-0400-0200-0600","2023-12-30","2023-12-30-ros2-tutorial","\u002Fwiki\u002F2023-12-30-ros2-tutorial","Ros2 Tutorial","md",false,{},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0600-zu-he-shi-ji-ren-wu",{"title":5,"description":75},"wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0600-组合实际任务","h0S_kNLTxO0qWnREh9J770pNrZGItq6jh2k2aCK4Jyc",[4804,4811,4817,4823,4829,4835,4840,4846,4852,4858,4864,4870,4876,4882,4888,4894,4900,4906,4912,4918,4924,4930,4935,4940,4945,4947,4953,4959,4965,4971,4977,4983,4989,4995,5001,5006,5012,5017,5023,5029,5035,5041,5047,5053,5059,5065,5071,5077,5083,5089,5095,5101,5107,5113,5119,5125,5131,5137,5143,5149,5155,5161,5167,5173,5179,5185,5191,5197,5203],{"path":4805,"stem":4806,"title":4807,"authors":4808,"date":4792,"chapterOrder":4809,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0100-ros2-jie-shao","wiki\u002F2023-12-30-ros2-tutorial\u002F0100-ROS2介绍","ROS2介绍",[7],"0100",0,{"path":4812,"stem":4813,"title":4814,"authors":4815,"date":4792,"chapterOrder":4816,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0200-ru-men-cao-zuo","wiki\u002F2023-12-30-ros2-tutorial\u002F0200-入门操作","入门操作",[7],"0200",{"path":4818,"stem":4819,"title":4820,"authors":4821,"date":4792,"chapterOrder":4822,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0300-gong-zuo-kong-jian-yu-gong-neng-bao","wiki\u002F2023-12-30-ros2-tutorial\u002F0300-工作空间与功能包","工作空间与功能包",[7],"0300",{"path":4824,"stem":4825,"title":4826,"authors":4827,"date":4792,"chapterOrder":4828,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0400-si-da-tong-xin","wiki\u002F2023-12-30-ros2-tutorial\u002F0400-四大通信","四大通信",[7],"0400",{"path":4830,"stem":4831,"title":4832,"authors":4833,"date":4792,"chapterOrder":4834,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0500-ros2-qi-ta-tong-xin-ji-zhi","wiki\u002F2023-12-30-ros2-tutorial\u002F0500-ROS2其他通信机制","ROS2其他通信机制",[7],"0500",{"path":4836,"stem":4837,"title":4290,"authors":4838,"date":4792,"chapterOrder":4839,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0600-launch","wiki\u002F2023-12-30-ros2-tutorial\u002F0600-Launch",[7],"0600",{"path":4841,"stem":4842,"title":4843,"authors":4844,"date":4792,"chapterOrder":4845,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0700-hui-su-rosbag2","wiki\u002F2023-12-30-ros2-tutorial\u002F0700-回溯rosbag2","回溯rosbag2",[7],"0700",{"path":4847,"stem":4848,"title":4849,"authors":4850,"date":4792,"chapterOrder":4851,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0800-zuo-biao-bian-huan-tf","wiki\u002F2023-12-30-ros2-tutorial\u002F0800-坐标变换TF","坐标变换TF",[7],"0800",{"path":4853,"stem":4854,"title":4855,"authors":4856,"date":4792,"chapterOrder":4857,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F0900-ke-shi-hua-ping-tai-rviz2-yu-urdf-jian-mo-yu-yan","wiki\u002F2023-12-30-ros2-tutorial\u002F0900-可视化平台RVIZ2与URDF建模语言","可视化平台RVIZ2与URDF建模语言",[7],"0900",{"path":4859,"stem":4860,"title":4861,"authors":4862,"date":4792,"chapterOrder":4863,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1000-stage-ros2-fang-zhen-ping-tai","wiki\u002F2023-12-30-ros2-tutorial\u002F1000-Stage_Ros2仿真平台","Stage_Ros2仿真平台",[7],"1000",{"path":4865,"stem":4866,"title":4867,"authors":4868,"date":4792,"chapterOrder":4869,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1100-0100-gazeboclassic","wiki\u002F2023-12-30-ros2-tutorial\u002F1100-0100-GazeboClassic","Gezebo Classic",[7],"1100-0100",{"path":4871,"stem":4872,"title":4873,"authors":4874,"date":4792,"chapterOrder":4875,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1100-0200-ignitiongazebo","wiki\u002F2023-12-30-ros2-tutorial\u002F1100-0200-IgnitionGazebo","Ignition Gazebo（Gazebo Fortress）",[7],"1100-0200",{"path":4877,"stem":4878,"title":4879,"authors":4880,"date":4792,"chapterOrder":4881,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1100-0300-gazebosim","wiki\u002F2023-12-30-ros2-tutorial\u002F1100-0300-GazeboSim","Gz Sim（Gazebo Harmonic）",[7],"1100-0300",{"path":4883,"stem":4884,"title":4885,"authors":4886,"date":4792,"chapterOrder":4887,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1100-0400-igngz2gzsim","wiki\u002F2023-12-30-ros2-tutorial\u002F1100-0400-Igngz2gzsim","将Ign Gazebo迁移至Gz Sim",[7],"1100-0400",{"path":4889,"stem":4890,"title":4891,"authors":4892,"date":4792,"chapterOrder":4893,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1100-gezebo-fang-zhen-ping-tai","wiki\u002F2023-12-30-ros2-tutorial\u002F1100-Gezebo仿真平台","Gezebo仿真平台",[7],"1100",{"path":4895,"stem":4896,"title":4897,"authors":4898,"date":4792,"chapterOrder":4899,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0100-humble-ban-ben","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0100-Humble版本","Humble导航仿真",[7],"1200-0100",{"path":4901,"stem":4902,"title":4903,"authors":4904,"date":4792,"chapterOrder":4905,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0200-jazzy-ban-ben","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0200-Jazzy版本","Jazzy导航仿真",[7],"1200-0200",{"path":4907,"stem":4908,"title":4909,"authors":4910,"date":4792,"chapterOrder":4911,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0300-humble2jazzy","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0300-Humble2Jazzy","Humble与Jazzy导航的差异",[7],"1200-0300",{"path":4913,"stem":4914,"title":4915,"authors":4916,"date":4792,"chapterOrder":4917,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0100-you-xian-zhuang-tai-ji-fsm","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0100-有限状态机FSM","有限状态机（Finite State Machine）",[7],"1200-0400-0100",{"path":4919,"stem":4920,"title":4921,"authors":4922,"date":4792,"chapterOrder":4923,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0100-ji-ben-gai-nian","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0100-基本概念","基本概念",[7],"1200-0400-0200-0100",{"path":4925,"stem":4926,"title":4927,"authors":4928,"date":4792,"chapterOrder":4929,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0200-kong-zhi-yu-zhuang-shi-gui-ze","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0200-控制与装饰规则","控制与装饰规则",[7],"1200-0400-0200-0200",{"path":4931,"stem":4932,"title":3607,"authors":4933,"date":4792,"chapterOrder":4934,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0300-di-yi-ge-wan-zheng-cheng-xu","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0300-第一个完整程序",[7],"1200-0400-0200-0300",{"path":4936,"stem":4937,"title":3611,"authors":4938,"date":4792,"chapterOrder":4939,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0400-jie-dian-zhi-jian-chuan-shu-ju","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0400-节点之间传数据",[7],"1200-0400-0200-0400",{"path":4941,"stem":4942,"title":3615,"authors":4943,"date":4792,"chapterOrder":4944,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0500-chi-xu-ren-wu-yu-zhong-zhi","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-0500-持续任务与中止",[7],"1200-0400-0200-0500",{"path":4799,"stem":4801,"title":5,"authors":4946,"date":4792,"chapterOrder":4791,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},[7],{"path":4948,"stem":4949,"title":4950,"authors":4951,"date":4792,"chapterOrder":4952,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-xing-wei-shu-bt","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-0200-行为树BT","行为树（BehaviorTree.CPP）",[7],"1200-0400-0200",{"path":4954,"stem":4955,"title":4956,"authors":4957,"date":4792,"chapterOrder":4958,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-fsm-yu-bt","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-0400-FSM与BT","有限状态机FSM与行为树BT",[7],"1200-0400",{"path":4960,"stem":4961,"title":4962,"authors":4963,"date":4792,"chapterOrder":4964,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1200-ji-qi-ren-dao-hang-navigation2-fang-zhen-pian","wiki\u002F2023-12-30-ros2-tutorial\u002F1200-机器人导航Navigation2(仿真篇)","机器人导航Navigation2(仿真篇)",[7],"1200",{"path":4966,"stem":4967,"title":4968,"authors":4969,"date":4792,"chapterOrder":4970,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0100-0100-boost-aiso","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0100-0100-Boost.Aiso","Boost.Asio库",[7],"1300-0100-0100",{"path":4972,"stem":4973,"title":4974,"authors":4975,"date":4792,"chapterOrder":4976,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0100-0200-ros2-serial-driver","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0100-0200-ros2_serial_driver","ROS2 Serial Driver库",[7],"1300-0100-0200",{"path":4978,"stem":4979,"title":4980,"authors":4981,"date":4792,"chapterOrder":4982,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0100-chuan-kou-tong-xin","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0100-串口通信","UART串口通信",[7],"1300-0100",{"path":4984,"stem":4985,"title":4986,"authors":4987,"date":4792,"chapterOrder":4988,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0200-0100-socketcan","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0200-0100-socketcan","SocketCAN",[7],"1300-0200-0100",{"path":4990,"stem":4991,"title":4992,"authors":4993,"date":4792,"chapterOrder":4994,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0200-0200-ros2-socketcan","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0200-0200-ros2_socketcan","ROS2_SocketCAN",[7],"1300-0200-0200",{"path":4996,"stem":4997,"title":4998,"authors":4999,"date":4792,"chapterOrder":5000,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0200-can-tong-xin","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0200-CAN通信","CAN通信",[7],"1300-0200",{"path":5002,"stem":5003,"title":4968,"authors":5004,"date":4792,"chapterOrder":5005,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0300-0100-boost-aiso","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0300-0100-Boost.Aiso",[7],"1300-0300-0100",{"path":5007,"stem":5008,"title":5009,"authors":5010,"date":4792,"chapterOrder":5011,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0300-tcp-tong-xin","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0300-TCP通信","TCP通信",[7],"1300-0300",{"path":5013,"stem":5014,"title":4968,"authors":5015,"date":4792,"chapterOrder":5016,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0400-0100-boost-aiso","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0400-0100-Boost.Aiso",[7],"1300-0400-0100",{"path":5018,"stem":5019,"title":5020,"authors":5021,"date":4792,"chapterOrder":5022,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-0400-udp-tong-xin","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-0400-UDP通信","UDP通信",[7],"1300-0400",{"path":5024,"stem":5025,"title":5026,"authors":5027,"date":4792,"chapterOrder":5028,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1300-linux-ying-jian-tong-xin","wiki\u002F2023-12-30-ros2-tutorial\u002F1300-Linux硬件通信","Linux硬件通信",[7],"1300",{"path":5030,"stem":5031,"title":5032,"authors":5033,"date":4792,"chapterOrder":5034,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0100-ji-qi-ren-zu-cheng","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0100-机器人组成","机器人组成",[7],"1400-0100",{"path":5036,"stem":5037,"title":5038,"authors":5039,"date":4792,"chapterOrder":5040,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0200-0100-yuan-cheng-kai-fa-ssh","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0200-0100-远程开发SSH","远程开发SSH",[7],"1400-0200-0100",{"path":5042,"stem":5043,"title":5044,"authors":5045,"date":4792,"chapterOrder":5046,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0200-0200-yuan-cheng-fang-wen-zhuo-mian","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0200-0200-远程访问桌面","远程访问桌面",[7],"1400-0200-0200",{"path":5048,"stem":5049,"title":5050,"authors":5051,"date":4792,"chapterOrder":5052,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0200-gong-kong-ji-zhi-yuan-cheng-kai-fa-huan-jing","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0200-工控机之远程开发环境","工控机之远程开发环境",[7],"1400-0200",{"path":5054,"stem":5055,"title":5056,"authors":5057,"date":4792,"chapterOrder":5058,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0300-gong-kong-ji-zhi-wai-jie-usb-she-bei","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0300-工控机之外接USB设备","工控机之外接USB设备",[7],"1400-0300",{"path":5060,"stem":5061,"title":5062,"authors":5063,"date":4792,"chapterOrder":5064,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0400-fen-bu-shi-da-jian","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0400-分布式搭建","分布式搭建",[7],"1400-0400",{"path":5066,"stem":5067,"title":5068,"authors":5069,"date":4792,"chapterOrder":5070,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0500-you-hua-ri-zhi","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0500-优化日志","优化日志",[7],"1400-0500",{"path":5072,"stem":5073,"title":5074,"authors":5075,"date":4792,"chapterOrder":5076,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0100-li-cheng-ji-odom","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0100-里程计Odom","里程计Odom",[7],"1400-0600-0100",{"path":5078,"stem":5079,"title":5080,"authors":5081,"date":4792,"chapterOrder":5082,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0200-guan-xing-ji-imu","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0200-惯性计IMU","惯性计IMU",[7],"1400-0600-0200",{"path":5084,"stem":5085,"title":5086,"authors":5087,"date":4792,"chapterOrder":5088,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0300-ji-guang-lei-da-lidar","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0300-激光雷达LiDAR","激光雷达LiDAR",[7],"1400-0600-0300",{"path":5090,"stem":5091,"title":5092,"authors":5093,"date":4792,"chapterOrder":5094,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0400-xiang-ji-camera","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0400-相机Camera","相机Camera",[7],"1400-0600-0400",{"path":5096,"stem":5097,"title":5098,"authors":5099,"date":4792,"chapterOrder":5100,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0500-quan-qiu-ding-wei-gnss","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0500-全球定位GNSS","全球定位GNSS",[7],"1400-0600-0500",{"path":5102,"stem":5103,"title":5104,"authors":5105,"date":4792,"chapterOrder":5106,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0600-shou-bing-joy","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0600-手柄joy","手柄JOY",[7],"1400-0600-0600",{"path":5108,"stem":5109,"title":5110,"authors":5111,"date":4792,"chapterOrder":5112,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0700-jian-pan-kong-zhi-jie-dian","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-0700-键盘控制节点","键盘控制节点",[7],"1400-0600-0700",{"path":5114,"stem":5115,"title":5116,"authors":5117,"date":4792,"chapterOrder":5118,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-ying-jian-ping-tai","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0600-硬件平台","硬件平台",[7],"1400-0600",{"path":5120,"stem":5121,"title":5122,"authors":5123,"date":4792,"chapterOrder":5124,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0700-zuo-biao-xi-yu-hua-ti-guan-xi","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0700-坐标系与话题关系","坐标系与话题关系",[7],"1400-0700",{"path":5126,"stem":5127,"title":5128,"authors":5129,"date":4792,"chapterOrder":5130,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0100-0100-lun-shi-li-cheng-ji-biao-ding","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0100-0100-轮式里程计标定","轮式里程计标定",[7],"1400-0800-0100-0100",{"path":5132,"stem":5133,"title":5134,"authors":5135,"date":4792,"chapterOrder":5136,"chapterDepth":567,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0100-0200-lun-shi-li-cheng-ji-yu-imu-rong-he","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0100-0200-轮式里程计与IMU融合","轮式里程计与IMU融合",[7],"1400-0800-0100-0200",{"path":5138,"stem":5139,"title":5140,"authors":5141,"date":4792,"chapterOrder":5142,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0100-lun-shi-li-cheng-ji-biao-ding-yu-rong-he","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0100-轮式里程计标定与融合","轮式里程计标定与融合",[7],"1400-0800-0100",{"path":5144,"stem":5145,"title":5146,"authors":5147,"date":4792,"chapterOrder":5148,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0200-ji-guang-lei-da-gong-ju","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0200-激光雷达工具","激光雷达工具",[7],"1400-0800-0200",{"path":5150,"stem":5151,"title":5152,"authors":5153,"date":4792,"chapterOrder":5154,"chapterDepth":560,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0300-xiang-ji-shi-yong-jin-jie","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-0300-相机使用进阶","相机使用进阶",[7],"1400-0800-0300",{"path":5156,"stem":5157,"title":5158,"authors":5159,"date":4792,"chapterOrder":5160,"chapterDepth":135,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-ying-jian-ping-tai-jin-jie","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-0800-硬件平台进阶","硬件平台进阶",[7],"1400-0800",{"path":5162,"stem":5163,"title":5164,"authors":5165,"date":4792,"chapterOrder":5166,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1400-ji-qi-ren-ying-jian","wiki\u002F2023-12-30-ros2-tutorial\u002F1400-机器人硬件","机器人硬件",[7],"1400",{"path":5168,"stem":5169,"title":5170,"authors":5171,"date":4792,"chapterOrder":5172,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1500-ros2-control","wiki\u002F2023-12-30-ros2-tutorial\u002F1500-ROS2_Control","ROS2_Control",[7],"1500",{"path":5174,"stem":5175,"title":5176,"authors":5177,"date":4792,"chapterOrder":5178,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1600-moveit2-gong-ye-ji-qi-ren-ji-xie-bi","wiki\u002F2023-12-30-ros2-tutorial\u002F1600-Moveit2工业机器人机械臂","Moveit2工业机器人机械臂",[7],"1600",{"path":5180,"stem":5181,"title":5182,"authors":5183,"date":4792,"chapterOrder":5184,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1700-ji-qi-ren-dao-hang-navigation2-shi-ti-pian","wiki\u002F2023-12-30-ros2-tutorial\u002F1700-机器人导航Navigation2(实体篇)","机器人导航Navigation2(实体篇)",[7],"1700",{"path":5186,"stem":5187,"title":5188,"authors":5189,"date":4792,"chapterOrder":5190,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1800-microros","wiki\u002F2023-12-30-ros2-tutorial\u002F1800-MicroROS","MicroROS",[7],"1800",{"path":5192,"stem":5193,"title":5194,"authors":5195,"date":4792,"chapterOrder":5196,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F1900-webots-fang-zhen-ping-tai","wiki\u002F2023-12-30-ros2-tutorial\u002F1900-Webots仿真平台","Webots仿真平台",[7],"1900",{"path":5198,"stem":5199,"title":5200,"authors":5201,"date":4792,"chapterOrder":5202,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":4797},"\u002Fwiki\u002F2023-12-30-ros2-tutorial\u002F2000-opencv","wiki\u002F2023-12-30-ros2-tutorial\u002F2000-OpenCV","OpenCV",[7],"2000",{"path":4794,"stem":5204,"title":5205,"authors":5206,"date":4792,"chapterOrder":5207,"chapterDepth":4810,"docKey":4793,"docRoot":4794,"docTitle":4795,"isWikiDoc":563,"isWikiIndex":563},"wiki\u002F2023-12-30-ros2-tutorial\u002Findex","ROS2机器人操作系统教程",[7],null,[5209,5211,5214,5217],{"name":7,"image":5210},"\u002Fimages\u002Fmember_photo\u002F董佳辉.jpg",{"name":5212,"image":5213},"宫金良","\u002Fimages\u002Fmember_photo\u002F宫金良.jpg",{"name":5215,"image":5216},"巩丽","\u002Fimages\u002Fmember_photo\u002F巩丽.png",{"name":5218,"image":5219},"张彦斐","\u002Fimages\u002Fmember_photo\u002F张彦斐.jpg",1792431903459]