Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 """
00036 static_transforms.py
00037
00038 Uses a tf broadcaster to broadcast static transforms as necessary. These can be specific to
00039 a particular flyer (e.g. the Vicon-to-IMU offset) or global, as in the /enu to /ned offset.
00040
00041 Parameters:
00042 ~mode: specifies what to broadcast:
00043 'flyer' - broadcast transform(s) specific to flyer (see 'flyer' parameter)
00044 'global' - broadcast global transform(s)
00045 'both' - broadcast both flyer and global transforms
00046
00047 ~flyer: specifies the name of the flyer (e.g. 'grey' or 'yellow')
00048
00049 ~period: interval at which to publish the transform(s), in milliseconds
00050 """
00051 import roslib; roslib.load_manifest('flyer_common')
00052 import rospy
00053 import tf
00054 from math import radians
00055
00056 tft = tf.transformations
00057
00058 global_transforms = (
00059 ('/enu','/ned', (0,0,0), (90, 0, 180)),
00060 )
00061 class StaticTransformBroadcaster:
00062
00063 def __init__(self):
00064 rospy.init_node('static_transforms')
00065 self.tfb = tf.TransformBroadcaster()
00066 self.mode = rospy.get_param('~mode')
00067 self.flyer = rospy.get_param('~flyer','')
00068 self.period = rospy.get_param('~period', 1000)
00069 self.startup_time = rospy.get_param('~startup_time', 10)
00070 self.startup_period = rospy.get_param('~startup_period', 100)
00071 self.get_frame_params()
00072
00073 def get_frame_params(self):
00074 self.flyer_transforms = rospy.get_param('frames')
00075
00076 def broadcast_one(self, parent, child, trans, rot, rot_type, rot_unit):
00077 flyer_prefix = '/'+self.flyer+'/'
00078 if parent[0] == '/':
00079 parent_prefix = ''
00080 else:
00081 parent_prefix = flyer_prefix
00082 if child[0] == '/':
00083 child_prefix = ''
00084 else:
00085 child_prefix = flyer_prefix
00086
00087 assert len(trans) == 3
00088 assert len(rot_unit) == 0 or rot_unit in ('deg','rad')
00089 if rot_type.startswith('euler_'):
00090 assert len(rot) == 3
00091 rot_seq = rot_type.split('_')[1]
00092 if rot_unit == 'deg':
00093 rot_rad = [radians(r) for r in rot]
00094 else:
00095 rot_rad = rot
00096 quat = tft.quaternion_from_euler(rot_rad[0], rot_rad[1], rot_rad[2], rot_seq)
00097 elif rot_type == 'quaternion':
00098 assert len(rot) == 4
00099 raise NotImplementedError
00100 elif rot_type == 'matrix':
00101 assert len(rot) == 9
00102 raise NotImplementedError
00103 else:
00104 raise SyntaxError
00105 self.tfb.sendTransform(trans, quat, rospy.Time.now() + self.dur,
00106 child_prefix + child, parent_prefix + parent)
00107
00108 def broadcast(self):
00109 for f in self.flyer_transforms.values():
00110 self.broadcast_one(f['parent'], f['child'],
00111 f['translation'], f['rotation'], f['rot_type'],
00112 f.get('rot_unit',''))
00113
00114 def start(self):
00115
00116 start = rospy.Time.now()
00117 now = start
00118 startup = True
00119 self.dur = rospy.Duration.from_sec(self.startup_period/1000.0)
00120 while not rospy.is_shutdown():
00121 if startup and (now - start).to_sec() > self.startup_time:
00122 startup = False
00123 self.dur = rospy.Duration.from_sec(self.period/1000.0)
00124 rospy.loginfo('Lowering static transform broadcast rate (period: ' + str(self.period/1000.0) + ' s)')
00125 self.broadcast()
00126 rospy.sleep(self.dur)
00127 if startup:
00128 now = rospy.Time.now()
00129
00130 if __name__ == "__main__":
00131 stb = StaticTransformBroadcaster()
00132 stb.start()