<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Paul,</p>
<p>Cool beans! <br>
</p>
<p>You are way beyond me here but the implications are extremely
intriguing. Thanks for the links!</p>
<p>David</p>
<p><br>
</p>
<div class="moz-cite-prefix">On 11/4/21 12:38 AM, Paul Bouchier via
DPRGlist wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CABfe6oQCr96BF_xAWRzdhw3Kgf99AHqNG7pbKVd_MC8EeemF1w@mail.gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<p style="background-color: #f4eaa5;color: #000000
;margin:5px;padding: 2px;text-align: left !important;
align-content: center; display: block; border: 1px solid
#000000; font-size: large; font-family: sans-serif;"><strong><em
style="font-size: 11px;"> [EXTERNAL SENDER]</em></strong></p>
<div dir="ltr">
<div>David, Rud,</div>
<div><br>
</div>
<div>At Tuesday's RBNV you guys seemed to have agreed that the
Subsumption architecture was a special case of behavior trees.
I wanted to understand behavior trees, and to understand
whether your assertion is correct. I found a basic explanation
of behavior trees here:</div>
<div><a
href="https://secure-web.cisco.com/1ScxbgdzSKyu2yhbQ7ntNhde1u_xOyavxoz28lGa8YZmJDpAnOb1xDujqt4WQ3TFMXv3y6hc-s-qTAhRPPT_9EnIn8F63T4u3i0dKKbXsI7lZlUbkEX6q37Z1c_iFyXHqvZQO8WE5Cl7G8PGD3_sKwXlY5HL3p401IHytbaChcwu9xCGRCQaGwwEndiXkRugEHvd26EZwu0hCZRo0HJIjcpmCIka1jEJE0J35pUFmUEQO8se4WdmbMeR8XD8NuSxHqRVFApWh6L7qvQchRgTPBKw0vxUP_h76hTjvYdjqQ9k/https%3A%2F%2Ftowardsdatascience.com%2Fdesigning-ai-agents-behaviors-with-behavior-trees-b28aa1c3cf8a"
moz-do-not-send="true">https://towardsdatascience.com/designing-ai-agents-behaviors-with-behavior-trees-b28aa1c3cf8a</a></div>
<div><br>
</div>
<div>It's a good overview, but is missing sufficient detail to
design a subsumption stack as a behavior tree. For example
it's description of a sequence node is "A node that returns
success if all children return SUCCESS" but it doesn't specify
what happens if a child returns RUNNING - does it retry all
previous nodes next tick time? It only describes one kind of
decorator node (invert). It doesn't specify whether a Fallback
node re-ticks all nodes next tick-time if a child after the
first returns SUCCESS.</div>
<div><br>
</div>
<div>After some searching, I found this set of pages</div>
<div><a
href="https://secure-web.cisco.com/1BGcY91DyPGL6NOqN1I4BK3VOGRePCXGox-N_BmBPk3tXeKotQh2fDALOYU7wYI9W81jsuFkIFFlw5TWiL0ZHI76kUnb4-bTlG3kAGcKfRPM4tyfwcKCvNZhZyaoPo-BGmB2AHY5ulWT0oj1zH8GUK7oP4rjgPOdy0RX3koTjEvS8sGnU78iuokoNOc_X-3H8xEv5f8J8uJSqg4U1l2JRHAg-QFiXzfUuizqTenzi7V_bKXNQJA7VDkRiK8QryKUA984S7JBmCrQ9mevkOYED39znbjLWYdcvrqrmeIBbCBg/https%3A%2F%2Fwww.behaviortree.dev%2F"
moz-do-not-send="true">https://www.behaviortree.dev/</a></div>
<div>They describe an implementation by David Faconte (of
PlotJuggler fame) of a behavior tree library that is general
purpose, and doesn't depend on, but works well with ROS. In
the "Learn the basics" section they describe variations on the
sequence and fallback nodes which seem sufficient to design a
subsumption robot behavior. The attached image is that design.
I'd be interested in your thoughts on whether I'm on the right
track here. <br>
</div>
<div><br>
</div>
<div>The following description of the design assumes the reader
has read the Sequence Nodes and Fallback Nodes and Decorators
Nodes pages, and it offers commentary on how the behavior tree
implements the subsumption stack, including non-ballistic
behavior.</div>
<div><br>
</div>
<div>ReactiveFallback always ticks all nodes below it until it
gets the first SUCCESS. Thus, if Action ReverseTurn was
running owing to a bumper press, and then BatteryLow becomes
active (SUCCESS), the ReactiveFallback node calls
HaltAllChildren() which propagates down the tree and halts
(subsumes) the ReverseTurn action. (This implementation
produces an abort behavior, but it's included to show that
BumperPressed->ReverseTurn is subsumable, not ballistic.)</div>
<div><br>
</div>
<div>The subsumption behavior arises from the way
ReactiveFallback stops ticking lower-priority (more rightward)
nodes when any preceding nodes return SUCCESS. If no bumper is
pressed, no IR detection is made, and battery isn't low, then
the last action, "Drive toward goal" gets to run. But as soon
as bumper or IRDetection is true (SUCCESS), the corresponding
behavior is executed, and DriveTowardGoal is subsumed (doesn't
run) until the corresponding Sequence node is done and returns
FAILURE</div>
<div><br>
</div>
<div>If IRDetection returns SUCCESS (IR sensor detects object),
Action "SteerAway" runs, and steers the robot away from the
sensor with the detection. Once the sensor clears, IRDetection
condition returns FAILURE, Action SteerAway doesn't run (is
halted), and no longer subsumes DriveTowardGoal, which can
then start running again. This behavior relies on
ReactiveSequence ticking all nodes (starting at the beginning
of its list of children), so the sensor gets checked each
tick.</div>
<div><br>
</div>
<div>By contrast, BumperPressed is called by a regular Sequence,
which doesn't tick all its children; if a child returns
RUNNING (which will happen while ReverseTurn action is
active), it will only tick the running child. Thus
BumperPressed can become false as the robot backs away from
the obstacle, but it won't be ticked, so it won't affect the
"ReverseTurn" action that should run for some time after a
bumper contact clears. The RepeatNode decorator runs
ReverseTurn up to 40 times (2 seconds at 20 Hz tick rate) as
long as ReverseTurn returns SUCCESS, then returns FAILURE
(maybe - the documentation isn't clear on this point - it
might not work as described). When it returns FAILURE the
subsumption of lower priority actions ends.</div>
<div><br>
</div>
<div>The tree shown is a DriveToWaypoint behavior tree - it
could be used as an element in a higher-level sequence that
did something else after achieving the waypoint, like seek a
cone.<br>
</div>
<div><br>
</div>
<div>This is of course all theoretical - may not work in
practice - but it looks to me as if your assertion that
Subsumption can be represented as a behavior tree is correct,
and that a richer set of control-node behaviors is beneficial.
The Fallback node acts like David's arbiter, running the
highest priority behavior, as assessed by traversing the list
of nodes and not running any beyond the first to report
SUCCESS. It relies on its children to return FAILURE if they
don't want to control the robot, so that arbitration can pass
on down the line.</div>
<div><br>
</div>
<div>A very nice aspect of this library is it works with GROOT
which apparently allows realtime and after-the-fact replay of
state transitions (active behaviors).<br>
</div>
<div><br>
</div>
<div>Thanks for an interesting exploration down an avenue I've
wondered about. I feel more knowledgeable now than I was.</div>
<div><br>
</div>
<div>Regards</div>
<div><br>
</div>
<div>Paul</div>
<div><br>
</div>
<div> <br>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
DPRGlist mailing list
<a class="moz-txt-link-abbreviated" href="mailto:DPRGlist@lists.dprg.org">DPRGlist@lists.dprg.org</a>
<a class="moz-txt-link-freetext" href="http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org">http://lists.dprg.org/listinfo.cgi/dprglist-dprg.org</a>
</pre>
</blockquote>
</body>
</html>