Skip to content

Commit adf5cef

Browse files
committed
Add ROS2 interop example.
1 parent 404a195 commit adf5cef

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

python_examples/ex04_ros_interop.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
Demonstration of stateful action nodes.
5+
6+
To run, ensure that the `btpy_cpp` Python extension is on your `PYTHONPATH`
7+
variable. It is probably located in your build directory if you're building from
8+
source.
9+
"""
10+
11+
import rclpy
12+
from rclpy.node import Node
13+
from tf2_ros.buffer import Buffer
14+
from tf2_ros.transform_listener import TransformListener
15+
16+
from btpy import (
17+
BehaviorTreeFactory,
18+
StatefulActionNode,
19+
SyncActionNode,
20+
NodeStatus,
21+
ports,
22+
)
23+
24+
25+
xml_text = """
26+
<root BTCPP_format="4" >
27+
28+
<BehaviorTree ID="MainTree">
29+
<Sequence>
30+
<ReactiveSequence name="root">
31+
<Print value="{tf}" />
32+
<GetRosTransform frame_id="odom" child_frame_id="base_link" tf="{tf}" />
33+
</ReactiveSequence>
34+
</Sequence>
35+
</BehaviorTree>
36+
37+
</root>
38+
"""
39+
40+
41+
@ports(inputs=["frame_id", "child_frame_id"], outputs=["tf"])
42+
class GetRosTransform(StatefulActionNode):
43+
def __init__(self, name, config, node):
44+
super().__init__(name, config)
45+
46+
self.node = node
47+
self.tf_buffer = Buffer()
48+
self.tf_listener = TransformListener(self.tf_buffer, self.node)
49+
50+
def on_start(self):
51+
return NodeStatus.RUNNING
52+
53+
def on_running(self):
54+
frame_id = self.get_input("frame_id")
55+
child_frame_id = self.get_input("child_frame_id")
56+
57+
time = self.node.get_clock().now()
58+
if self.tf_buffer.can_transform(frame_id, child_frame_id, time):
59+
tf = self.tf_buffer.lookup_transform(frame_id, child_frame_id, time)
60+
self.set_output("tf", tf)
61+
62+
return NodeStatus.RUNNING
63+
64+
def on_halted(self):
65+
pass
66+
67+
68+
@ports(inputs=["value"])
69+
class Print(SyncActionNode):
70+
def tick(self):
71+
value = self.get_input("value")
72+
if value is not None:
73+
print(value)
74+
return NodeStatus.SUCCESS
75+
76+
77+
rclpy.init()
78+
node = Node("ex04_ros_interopt")
79+
80+
factory = BehaviorTreeFactory()
81+
factory.register(GetRosTransform, node)
82+
factory.register(Print)
83+
84+
tree = factory.create_tree_from_text(xml_text)
85+
86+
node.create_timer(0.01, lambda: tree.tick_once())
87+
rclpy.spin(node)

0 commit comments

Comments
 (0)