Skip to content

Commit fbf34c9

Browse files
authored
Add behavior CompareBlackboardVariables (#472)
1 parent d998975 commit fbf34c9

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

py_trees/behaviours.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,80 @@ def update(self) -> common.Status:
607607
return common.Status.FAILURE
608608

609609

610+
class CompareBlackboardVariables(behaviour.Behaviour):
611+
"""
612+
Non-blocking comparison between two blackboard variables.
613+
614+
Gets two blackboard variables and applies the given operator between them,
615+
returning SUCCESS if the comparison holds.
616+
This is non-blocking, so it will always tick with
617+
:data:`~py_trees.common.Status.SUCCESS` or
618+
:data:`~py_trees.common.Status.FAILURE`.
619+
620+
Args:
621+
name: name of the behaviour
622+
var1_key: blackboard key for the first variable
623+
var2_key: blackboard key for the second variable
624+
operator: a callable comparison operator
625+
626+
.. note::
627+
If the variables do not yet exist on the blackboard, the behaviour will
628+
return with status :data:`~py_trees.common.Status.FAILURE`.
629+
630+
.. tip::
631+
The python `operator module`_ includes many useful comparison operations.
632+
"""
633+
634+
def __init__(
635+
self,
636+
name: str,
637+
var1_key: str,
638+
var2_key: str,
639+
operator: typing.Callable[[common.ComparisonV, common.ComparisonV], bool],
640+
):
641+
super().__init__(name=name)
642+
643+
self.var1_key = var1_key
644+
self.var2_key = var2_key
645+
self.operator = operator
646+
self.blackboard = self.attach_blackboard_client()
647+
self.blackboard.register_key(key=self.var1_key, access=common.Access.READ)
648+
self.blackboard.register_key(key=self.var2_key, access=common.Access.READ)
649+
650+
def update(self) -> common.Status:
651+
"""
652+
Check for the two variables and applies the operator between them.
653+
654+
Returns:
655+
:class:`~py_trees.common.Status`: :data:`~py_trees.common.Status.FAILURE`
656+
if not matched, :data:`~py_trees.common.Status.SUCCESS` otherwise.
657+
"""
658+
self.logger.debug("%s.update()" % self.__class__.__name__)
659+
try:
660+
lhs_value = self.blackboard.get(self.var1_key)
661+
rhs_value = self.blackboard.get(self.var2_key)
662+
except KeyError as err:
663+
self.logger.error(str(err))
664+
return common.Status.FAILURE
665+
666+
if self.operator(lhs_value, rhs_value):
667+
self.feedback_message = "'%s, %s' comparison succeeded [v1: %s][v2: %s]" % (
668+
self.var1_key,
669+
self.var2_key,
670+
lhs_value,
671+
rhs_value,
672+
)
673+
return common.Status.SUCCESS
674+
else:
675+
self.feedback_message = "'%s, %s' comparison failed [v1: %s][v2: %s]" % (
676+
self.var1_key,
677+
self.var2_key,
678+
lhs_value,
679+
rhs_value,
680+
)
681+
return common.Status.FAILURE
682+
683+
610684
class WaitForBlackboardVariableValue(CheckBlackboardVariableValue):
611685
"""
612686
Block until a blackboard variable matches a given value/expression.

py_trees/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ class ComparisonExpression(object):
209209
value=5,
210210
operator=operator.eq
211211
)
212-
success = check.operator(blackboard[check.variable], check.value)
212+
success = check.operator(blackboard[check.variable], check.value_generator())
213213
"""
214214

215215
def __init__(

0 commit comments

Comments
 (0)