Skip to content

Commit d2136a0

Browse files
authored
Merge pull request #14 from sam-xl/string_bool_fix
Fix reading string booleans
2 parents af33449 + 28b93c2 commit d2136a0

File tree

12 files changed

+52
-22
lines changed

12 files changed

+52
-22
lines changed

README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ and should be evaluated as code. For a concrete example see below:
5252
In the above example the `qos_profile` is evaluated as python code. Notice to
5353
use any python module you must use the fully qualified name.
5454

55-
note: Boolean values should be considered python as checking the truth of a
56-
python string will always be evaluated as `True`, e.g. `if "False":` will evaluate
57-
to `True`.
58-
5955
### Idioms
6056

6157
Idioms are also now supported. An idiom is a special function that produces
@@ -79,14 +75,14 @@ Create an XML file that represents your behavior tree. The XML structure should
7975
define the nodes and their attributes. It should be similar to the following:
8076

8177
```xml
82-
<py_trees.composites.Parallel name="TutorialOne" synchronise="$(False)">
83-
<py_trees.composites.Sequence name="Topics2BB" memory="$(False)">
78+
<py_trees.composites.Parallel name="TutorialOne" synchronise="False">
79+
<py_trees.composites.Sequence name="Topics2BB" memory="False">
8480
<py_trees_ros.battery.ToBlackboard name="Battery2BB"
8581
topic_name="/battery/state"
8682
qos_profile="$(py_trees_ros.utilities.qos_profile_unlatched())"
8783
threshold="30.0" />
8884
</py_trees.composites.Sequence>
89-
<py_trees.composites.Selector name="Tasks" memory="$(False)">
85+
<py_trees.composites.Selector name="Tasks" memory="False">
9086
<py_trees.behaviours.Running name="Idle" />
9187
<py_trees.behaviours.Periodic name="Flip Eggs" n="2" />
9288
</py_trees.composites.Selector>
@@ -162,7 +158,7 @@ another subtree. However, be aware that the all directories are absolute, but it
162158
is possible to use python to determine the path like so:
163159

164160
```xml
165-
<py_trees.composites.Parallel name="Subtree Tutorial" synchronise="$(False)">
161+
<py_trees.composites.Parallel name="Subtree Tutorial" synchronise="False">
166162
<subtree
167163
name="my_subtree"
168164
include="$(os.path.join(ament_index_python.packages.get_package_share_directory('my_package'), 'tree', 'subtree.xml'))" />
@@ -222,4 +218,4 @@ and finally in subtree2
222218
<py_trees.composites.Sequence name="Cascading Arg Tutorial">
223219
<py_trees.behaviors.Success name="${baz}" />
224220
</py_trees.composites.Sequence>
225-
```
221+
```

py_trees_parser/parser.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,22 @@ def is_float(value: str) -> bool:
5959
return False
6060

6161

62+
def is_bool(value: str) -> bool:
63+
"""
64+
Check if a string is a boolean type, i.e. True or False.
65+
66+
Args:
67+
----
68+
value: The string to check.
69+
70+
Returns:
71+
-------
72+
True if the string is "true", "True", "false", or "False", False otherwise.
73+
74+
"""
75+
return value.lower() == "true" or value.lower() == "false"
76+
77+
6278
def is_code(value: str) -> bool:
6379
"""
6480
Check if a string is intended to be code.
@@ -244,6 +260,8 @@ def _string_num_or_code(self, value: str) -> Any:
244260
value = int(value)
245261
elif is_float(value):
246262
value = float(value)
263+
elif is_bool(value):
264+
value = value.lower() == "true"
247265
elif is_code(value):
248266
value = self._parse_code(value)
249267

test/data/test1.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
https://py-trees-ros-tutorials.readthedocs.io/en/release-2.1.x/tutorials.html#tree -->
33
<py_trees.composites.Parallel name="TutorialOne"
44
policy="$(py_trees.common.ParallelPolicy.SuccessOnAll(synchronise=False))">
5-
<py_trees.composites.Sequence name="Topics2BB" memory="$(False)">
5+
<py_trees.composites.Sequence name="Topics2BB" memory="False">
66
<py_trees_ros.battery.ToBlackboard name="Battery2BB"
77
topic_name="/battery/state"
88
qos_profile="$(py_trees_ros.utilities.qos_profile_unlatched())"
99
threshold="30.0" />
1010
</py_trees.composites.Sequence>
11-
<py_trees.composites.Selector name="Tasks" memory="$(False)">
11+
<py_trees.composites.Selector name="Tasks" memory="False">
1212
<py_trees.behaviours.Running name="Idle" />
1313
<py_trees.behaviours.Periodic name="Flip Eggs" n="2" />
1414
</py_trees.composites.Selector>

test/data/test6.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22
https://py-trees-ros-tutorials.readthedocs.io/en/release-2.1.x/tutorials.html#id13 -->
33
<py_trees.composites.Parallel name="TutorialSix"
44
policy="$(py_trees.common.ParallelPolicy.SuccessOnAll(synchronise=False))">
5-
<py_trees.composites.Sequence name="Topics2BB" memory="$(False)">
5+
<py_trees.composites.Sequence name="Topics2BB" memory="False">
66
<py_trees_ros.subscribers.EventToBlackboard name="Scan2BB"
77
topic_name="/dashboard/scan"
88
qos_profile="$(py_trees_ros.utilities.qos_profile_unlatched())"
99
variable_name="event_scan_button" />
1010
<py_trees_ros.battery.ToBlackboard name="Battery2BB" topic_name="/battery/state"
1111
qos_profile="py_trees_ros.utilities.qos_profile_unlatched()" threshold="30.0" />
1212
</py_trees.composites.Sequence>
13-
<py_trees.composites.Selector name="Tasks" memory="$(False)">
13+
<py_trees.composites.Selector name="Tasks" memory="False">
1414
<py_trees.decorators.EternalGuard name="Battery Low?"
1515
condition="$(py_trees_parser.behaviors.testing_behaviors.check_battery_low_on_blackboard)"
1616
blackboard_keys="$({'battery_low_warning'})">
1717
<py_trees_parser.behaviors.testing_behaviors.FlashLedStrip name="Flash Red" colour="red" />
1818
</py_trees.decorators.EternalGuard>
19-
<py_trees.composites.Sequence name="Scan" memory="$(False)">
19+
<py_trees.composites.Sequence name="Scan" memory="False">
2020
<py_trees.behaviours.CheckBlackboardVariableValue name="Scan?"
2121
check="$(py_trees.common.ComparisonExpression(variable='event_scan_button', value=True, operator=operator.eq))" />
22-
<py_trees.composites.Selector name="Preempt?" memory="$(False)">
22+
<py_trees.composites.Selector name="Preempt?" memory="False">
2323
<py_trees.decorators.SuccessIsRunning name="SuccessIsRunning">
2424
<py_trees.behaviours.CheckBlackboardVariableValue name="Scan?"
2525
check="$(py_trees.common.ComparisonExpression(variable='event_scan_button', value=True, operator=operator.eq))" />
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<py_trees.composites.Selector name="Argument Substitution Test" memory="$(False)">
1+
<py_trees.composites.Selector name="Argument Substitution Test" memory="False">
22
<py_trees.behaviours.Running name="prefix_${arg1}_suffix" />
33
<py_trees.behaviours.Success name="task_${arg2}_complete" />
44
<py_trees.behaviours.Periodic name="periodic_${arg3}" n="${n}" />
55
<py_trees.behaviours.Success name="multiple_${arg1}_and_${arg2}_args" />
6-
</py_trees.composites.Selector>
6+
</py_trees.composites.Selector>

test/data/test_arg_substitution_main.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
<arg name="arg2" value="value2" />
44
<arg name="arg3" value="value3" />
55
<arg name="n" value="3" />
6-
</subtree>
6+
</subtree>

test/data/test_bool.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<py_trees.composites.Sequence name="No Memory" memory="False">
2+
<py_trees.composites.Sequence name="Memory" memory="True">
3+
<py_trees.behaviours.Success name="Feature 1" />
4+
</py_trees.composites.Sequence>
5+
</py_trees.composites.Sequence>

test/data/test_idioms.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<py_trees.composites.Sequence name="Idioms" memory="$(False)">
1+
<py_trees.composites.Sequence name="Idioms" memory="False">
22
<py_trees.idioms.oneshot name="OneShot"
33
variable_name="one_shot"
44
policy="$(py_trees.common.OneShotPolicy)">

test/data/test_subtree_args.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<py_trees.composites.Selector name="${selector_name}" memory="$(False)">
1+
<py_trees.composites.Selector name="${selector_name}" memory="False">
22
<py_trees.behaviours.Running name="${idle_name}" />
33
<py_trees.behaviours.Periodic name="${flip_name}" n="${n}" />
44
</py_trees.composites.Selector>

test/data/test_subtree_main.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<py_trees.composites.Parallel name="SubtreeMain"
22
policy="$(py_trees.common.ParallelPolicy.SuccessOnAll(synchronise=False))">
3-
<py_trees.composites.Sequence name="Topics2BB" memory="$(False)">
3+
<py_trees.composites.Sequence name="Topics2BB" memory="False">
44
<py_trees_ros.battery.ToBlackboard name="Battery2BB" topic_name="/battery/state"
55
qos_profile="$(py_trees_ros.utilities.qos_profile_unlatched())" threshold="30.0" />
66
</py_trees.composites.Sequence>

0 commit comments

Comments
 (0)