Go to the documentation of this file.00001
00002
00003 from __future__ import print_function
00004
00005 import rospy
00006 import tf
00007 from geometry_msgs.msg import Pose
00008 from gazebo_msgs.msg import LinkStates
00009 import tf_conversions.posemath as pm
00010 from tf.transformations import *
00011
00012 import pysdf
00013
00014 tfBroadcaster = None
00015 submodelsToBeIgnored = []
00016 lastUpdateTime = None
00017 updatePeriod = 0.05
00018 model_cache = {}
00019
00020
00021
00022 def on_link_states_msg(link_states_msg):
00023 """
00024 Publish tf for each model in current Gazebo world
00025 """
00026 global lastUpdateTime
00027 sinceLastUpdateDuration = rospy.get_rostime() - lastUpdateTime
00028 if sinceLastUpdateDuration.to_sec() < updatePeriod:
00029 return
00030 lastUpdateTime = rospy.get_rostime()
00031
00032 poses = {'gazebo_world': identity_matrix()}
00033 for (link_idx, link_name) in enumerate(link_states_msg.name):
00034 poses[link_name] = pysdf.pose_msg2homogeneous(link_states_msg.pose[link_idx])
00035
00036
00037 for (link_idx, link_name) in enumerate(link_states_msg.name):
00038
00039 modelinstance_name = link_name.split('::')[0]
00040
00041 model_name = pysdf.name2modelname(modelinstance_name)
00042
00043 if not model_name in model_cache:
00044 sdf = pysdf.SDF(model=model_name)
00045 model_cache[model_name] = sdf.world.models[0] if len(sdf.world.models) >= 1 else None
00046 if model_cache[model_name]:
00047 print('Loaded model: %s' % model_cache[model_name].name)
00048 else:
00049 print('Unable to load model: %s' % model_name)
00050 model = model_cache[model_name]
00051 link_name_in_model = link_name.replace(modelinstance_name + '::', '')
00052 if model:
00053 link = model.get_link(link_name_in_model)
00054 if link.tree_parent_joint:
00055 parent_link = link.tree_parent_joint.tree_parent_link
00056 parent_link_name = parent_link.get_full_name()
00057
00058 parentinstance_link_name = parent_link_name.replace(model_name, modelinstance_name, 1)
00059 else:
00060 parentinstance_link_name = 'gazebo_world'
00061 else:
00062 parentinstance_link_name = 'gazebo_world'
00063
00064 pose = poses[link_name]
00065 parent_pose = poses[parentinstance_link_name]
00066 rel_tf = concatenate_matrices(inverse_matrix(parent_pose), pose)
00067 translation, quaternion = pysdf.homogeneous2translation_quaternion(rel_tf)
00068
00069 tfBroadcaster.sendTransform(translation, quaternion, rospy.get_rostime(), pysdf.sdf2tfname(link_name), pysdf.sdf2tfname(parentinstance_link_name))
00070
00071
00072
00073 def main():
00074 rospy.init_node('gazebo2tf')
00075
00076 global submodelsToBeIgnored
00077 submodelsToBeIgnored = rospy.get_param('~ignore_submodels_of', '').split(';')
00078 rospy.loginfo('Ignoring submodels of: ' + str(submodelsToBeIgnored))
00079
00080 global tfBroadcaster
00081 tfBroadcaster = tf.TransformBroadcaster()
00082
00083 global lastUpdateTime
00084 lastUpdateTime = rospy.get_rostime()
00085 linkStatesSub = rospy.Subscriber('gazebo/link_states', LinkStates, on_link_states_msg)
00086
00087 rospy.loginfo('Spinning')
00088 rospy.spin()
00089
00090 if __name__ == '__main__':
00091 main()