5 from rospkg
import RosPack, ResourceNotFound
7 from flexbe_core
import Logger, BehaviorLibrary
8 from std_msgs.msg
import String
15 import xml.etree.ElementTree
as ET
24 self.
_sub = rospy.Subscriber(
"flexbe/request_behavior", BehaviorRequest, self.
_callback)
27 self.
_pub = rospy.Publisher(
"flexbe/start_behavior", BehaviorSelection, queue_size=100)
28 self.
_status_pub = rospy.Publisher(
"flexbe/status", BEStatus, queue_size=100)
29 self.
_mirror_pub = rospy.Publisher(
"flexbe/mirror/structure", ContainerStructure, queue_size=100)
34 rospy.loginfo(
"%d behaviors available, ready for start request." % self._behavior_lib.count_behaviors())
38 be_id, behavior = self._behavior_lib.find_behavior(msg.behavior_name)
40 Logger.logerr(
"Did not find behavior with requested name: %s" % msg.behavior_name)
41 self._status_pub.publish(BEStatus(code=BEStatus.ERROR))
44 rospy.loginfo(
"Request for behavior " + behavior[
"name"])
46 be_selection = BehaviorSelection()
47 be_selection.behavior_id = be_id
48 be_selection.autonomy_level = msg.autonomy_level
50 for k, v
in zip(msg.arg_keys, msg.arg_values):
51 if k.startswith(
'/YAML:'):
52 key = k.replace(
'/YAML:',
'/', 1)
53 path = v.split(
':')[0]
55 if path.startswith(
'~')
or path.startswith(
'/'):
56 yamlpath = os.path.expanduser(path)
58 yamlpath = os.path.join(self._rp.get_path(path.split(
'/')[0]),
'/'.join(path.split(
'/')[1:]))
59 with open(yamlpath,
'r') as f: 60 content = yaml.load(f) 61 if ns !=
'' and ns
in content:
63 be_selection.arg_keys.append(key)
64 be_selection.arg_values.append(yaml.dump(content))
66 be_selection.arg_keys.append(k)
67 be_selection.arg_values.append(v)
68 except Exception
as e:
69 rospy.logwarn(
'Failed to parse and substitute behavior arguments, will use direct input.\n%s' % str(e))
70 be_selection.arg_keys = msg.arg_keys
71 be_selection.arg_values = msg.arg_values
73 be_structure = ContainerStructure()
74 be_structure.containers = msg.structure
77 be_filepath_new = os.path.join(self._rp.get_path(behavior[
"package"]),
'src/' + behavior[
"package"] +
'/' + behavior[
"file"] +
'.py')
78 except ResourceNotFound:
79 rospy.logerr(
"Could not find behavior package '%s'" % (behavior[
"package"]))
80 rospy.loginfo(
"Have you updated your ROS_PACKAGE_PATH after creating the behavior?")
83 with open(be_filepath_new,
"r") as f: 84 be_content_new = f.read() 86 be_filepath_old = os.path.join(self._rp.get_path(behavior["package"]),
'src/' + behavior[
"package"] +
'/' + behavior[
"file"] +
'_tmp.py')
87 if not os.path.isfile(be_filepath_old):
88 be_selection.behavior_checksum = zlib.adler32(be_content_new)
89 if msg.autonomy_level != 255:
90 be_structure.behavior_id = be_selection.behavior_checksum
91 self._mirror_pub.publish(be_structure)
92 self._pub.publish(be_selection)
93 rospy.loginfo(
"No changes to behavior version.")
96 with open(be_filepath_old,
"r") as f: 97 be_content_old = f.read() 99 sqm = difflib.SequenceMatcher(a=be_content_old, b=be_content_new) 100 diffs = [x[1] for x
in sqm.get_grouped_opcodes(0)]
101 for opcode, a0, a1, b0, b1
in diffs:
102 content = be_content_new[b0:b1]
103 be_selection.modifications.append(BehaviorModification(a0, a1, content))
105 be_selection.behavior_checksum = zlib.adler32(be_content_new)
106 if msg.autonomy_level != 255:
107 be_structure.behavior_id = be_selection.behavior_checksum
108 self._mirror_pub.publish(be_structure)
110 self._pub.publish(be_selection)
116 Logger.logwarn(
'FlexBE App needs to be updated!\n' \
117 +
'Require at least version %s, but have %s\n' % (BehaviorLauncher.MIN_VERSION, msg.data) \
118 +
'Please run a "git pull" in "roscd flexbe_app".')
123 for n
in reversed(v.split(
'.')):
124 result += int(n) * offset