00001 /* Copyright (C) 2015-2017 Michele Colledanchise - All Rights Reserved 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 00004 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 00005 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 00006 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00009 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00010 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00011 */ 00012 00013 00014 #include <control_node.h> 00015 #include <string> 00016 #include <vector> 00017 00018 BT::ControlNode::ControlNode(std::string name) : TreeNode::TreeNode(name) 00019 { 00020 type_ = BT::CONTROL_NODE; 00021 00022 // TODO(...) In case it is desired to set to idle remove the ReturnStatus 00023 // type in order to set the member variable 00024 // ReturnStatus child_i_status_ = BT::IDLE; // commented out as unused 00025 } 00026 00027 BT::ControlNode::~ControlNode() {} 00028 00029 void BT::ControlNode::AddChild(TreeNode* child) 00030 { 00031 // Checking if the child has a parent already 00032 00033 if (child->has_parent()) 00034 { 00035 throw BehaviorTreeException("'" + child->get_name() + " has a parent already. Please create different objects for multiple nodes. It makes the tinking/halting precedure easier."); 00036 } 00037 00038 child->set_has_parent(true); 00039 children_nodes_.push_back(child); 00040 children_states_.push_back(BT::IDLE); 00041 } 00042 00043 unsigned int BT::ControlNode::GetChildrenNumber() 00044 { 00045 return children_nodes_.size(); 00046 } 00047 00048 void BT::ControlNode::Halt() 00049 { 00050 DEBUG_STDOUT("HALTING: "<< get_name()); 00051 HaltChildren(0); 00052 set_status(BT::HALTED); 00053 } 00054 00055 std::vector<BT::TreeNode*> BT::ControlNode::GetChildren() 00056 { 00057 return children_nodes_; 00058 } 00059 00060 void BT::ControlNode::ResetColorState() 00061 { 00062 set_color_status(BT::IDLE); 00063 for (unsigned int i = 0; i < children_nodes_.size(); i++) 00064 { 00065 children_nodes_[i]->ResetColorState(); 00066 } 00067 } 00068 00069 void BT::ControlNode::HaltChildren(int i) 00070 { 00071 for (unsigned int j=i; j < children_nodes_.size(); j++) 00072 { 00073 if (children_nodes_[j]->get_type() == BT::CONDITION_NODE) 00074 { 00075 children_nodes_[i]->ResetColorState(); 00076 } 00077 else 00078 { 00079 if (children_nodes_[j]->get_status() == BT::RUNNING) 00080 { 00081 DEBUG_STDOUT("SENDING HALT TO CHILD " << children_nodes_[j]-> get_name()); 00082 children_nodes_[j]->Halt(); 00083 } 00084 else 00085 { 00086 DEBUG_STDOUT("NO NEED TO HALT " << children_nodes_[j]-> get_name() 00087 << "STATUS" << children_nodes_[j]->get_status()); 00088 } 00089 } 00090 } 00091 } 00092 00093 int BT::ControlNode::Depth() 00094 { 00095 int depMax = 0; 00096 int dep = 0; 00097 for (unsigned int i = 0; i < children_nodes_.size(); i++) 00098 { 00099 dep = (children_nodes_[i]->Depth()); 00100 if (dep > depMax) 00101 { 00102 depMax = dep; 00103 } 00104 } 00105 return 1 + depMax; 00106 }