@@ -37,83 +37,83 @@ BT::NodeStatus RecoveryNode::tick()
37
37
throw BT::BehaviorTreeException (" Recovery Node '" + name () + " ' must only have 2 children." );
38
38
}
39
39
40
- if (retry_count_ > number_of_retries_) {
41
- halt ();
42
- return BT::NodeStatus::FAILURE;
43
- }
44
40
setStatus (BT::NodeStatus::RUNNING);
45
41
46
- TreeNode * child_node = children_nodes_[current_child_idx_];
47
- const BT::NodeStatus child_status = child_node->executeTick ();
48
-
49
- if (current_child_idx_ == 0 ) {
50
- switch (child_status) {
51
- case BT::NodeStatus::SKIPPED:
52
- // If first child is skipped, the entire branch is considered skipped
53
- halt ();
54
- return BT::NodeStatus::SKIPPED;
55
-
56
- case BT::NodeStatus::SUCCESS:
57
- // reset node and return success when first child returns success
58
- halt ();
59
- return BT::NodeStatus::SUCCESS;
60
-
61
- case BT::NodeStatus::RUNNING:
62
- return BT::NodeStatus::RUNNING;
63
-
64
- case BT::NodeStatus::FAILURE:
65
- {
66
- if (retry_count_ < number_of_retries_) {
67
- // halt first child and tick second child in next iteration
68
- ControlNode::haltChild (0 );
69
- current_child_idx_ = 1 ;
70
- return BT::NodeStatus::RUNNING;
71
- } else {
72
- // reset node and return failure when max retries has been exceeded
73
- halt ();
42
+ while (current_child_idx_ < children_count && retry_count_ <= number_of_retries_) {
43
+ TreeNode * child_node = children_nodes_[current_child_idx_];
44
+ const BT::NodeStatus child_status = child_node->executeTick ();
45
+
46
+ if (current_child_idx_ == 0 ) {
47
+ switch (child_status) {
48
+ case BT::NodeStatus::SKIPPED:
49
+ // If first child is skipped, the entire branch is considered skipped
50
+ halt ();
51
+ return BT::NodeStatus::SKIPPED;
52
+
53
+ case BT::NodeStatus::SUCCESS:
54
+ // reset node and return success when first child returns success
55
+ halt ();
56
+ return BT::NodeStatus::SUCCESS;
57
+
58
+ case BT::NodeStatus::RUNNING:
59
+ return BT::NodeStatus::RUNNING;
60
+
61
+ case BT::NodeStatus::FAILURE:
62
+ {
63
+ if (retry_count_ < number_of_retries_) {
64
+ // halt first child and tick second child in next iteration
65
+ ControlNode::haltChild (0 );
66
+ current_child_idx_++;
67
+ break ;
68
+ } else {
69
+ // reset node and return failure when max retries has been exceeded
70
+ halt ();
71
+ return BT::NodeStatus::FAILURE;
72
+ }
73
+ }
74
+
75
+ default :
76
+ throw BT::LogicError (" A child node must never return IDLE" );
77
+ } // end switch
78
+
79
+ } else if (current_child_idx_ == 1 ) {
80
+ switch (child_status) {
81
+ case BT::NodeStatus::SKIPPED:
82
+ {
83
+ // if we skip the recovery (maybe a precondition fails), then we
84
+ // should assume that no recovery is possible. For this reason,
85
+ // we should return FAILURE and reset the index.
86
+ // This does not count as a retry.
87
+ current_child_idx_ = 0 ;
88
+ ControlNode::haltChild (1 );
74
89
return BT::NodeStatus::FAILURE;
75
90
}
76
- }
77
-
78
- default :
79
- throw BT::LogicError (" A child node must never return IDLE" );
80
- } // end switch
81
-
82
- } else if (current_child_idx_ == 1 ) {
83
- switch (child_status) {
84
- case BT::NodeStatus::SKIPPED:
85
- {
86
- // if we skip the recovery (maybe a precondition fails), then we
87
- // should assume that no recovery is possible. For this reason,
88
- // we should return FAILURE and reset the index.
89
- // This does not count as a retry.
90
- current_child_idx_ = 0 ;
91
- ControlNode::haltChild (1 );
91
+ case BT::NodeStatus::RUNNING:
92
+ return child_status;
93
+
94
+ case BT::NodeStatus::SUCCESS:
95
+ {
96
+ // halt second child, increment recovery count, and tick first child in next iteration
97
+ ControlNode::haltChild (1 );
98
+ retry_count_++;
99
+ current_child_idx_ = 0 ;
100
+ }
101
+ break ;
102
+
103
+ case BT::NodeStatus::FAILURE:
104
+ // reset node and return failure if second child fails
105
+ halt ();
92
106
return BT::NodeStatus::FAILURE;
93
- }
94
- case BT::NodeStatus::RUNNING:
95
- return child_status;
96
-
97
- case BT::NodeStatus::SUCCESS:
98
- {
99
- // halt second child, increment recovery count, and tick first child in next iteration
100
- ControlNode::haltChild (1 );
101
- retry_count_++;
102
- current_child_idx_ = 0 ;
103
- return BT::NodeStatus::RUNNING;
104
- }
105
107
106
- case BT::NodeStatus::FAILURE:
107
- // reset node and return failure if second child fails
108
- halt ();
109
- return BT::NodeStatus::FAILURE;
108
+ default :
109
+ throw BT::LogicError (" A child node must never return IDLE" );
110
+ } // end switch
111
+ }
112
+ } // end while loop
110
113
111
- default :
112
- throw BT::LogicError (" A child node must never return IDLE" );
113
- } // end switch
114
- }
114
+ // reset node and return failure
115
115
halt ();
116
- throw BT::LogicError ( " A recovery node has exactly 2 children and should never reach here " ) ;
116
+ return BT::NodeStatus::FAILURE ;
117
117
}
118
118
119
119
void RecoveryNode::halt ()
0 commit comments