static_transforms.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 # Software License Agreement (BSD License)
00004 #
00005 #  Copyright (c) 2010, UC Regents
00006 #  All rights reserved.
00007 #
00008 #  Redistribution and use in source and binary forms, with or without
00009 #  modification, are permitted provided that the following conditions
00010 #  are met:
00011 #
00012 #   * Redistributions of source code must retain the above copyright
00013 #     notice, this list of conditions and the following disclaimer.
00014 #   * Redistributions in binary form must reproduce the above
00015 #     copyright notice, this list of conditions and the following
00016 #     disclaimer in the documentation and/or other materials provided
00017 #     with the distribution.
00018 #   * Neither the name of the University of California nor the names of its
00019 #     contributors may be used to endorse or promote products derived
00020 #     from this software without specific prior written permission.
00021 #
00022 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 #  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 #  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 #  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 #  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 #  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 #  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 #  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 #  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 #  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 #  POSSIBILITY OF SUCH DAMAGE.
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 = (# parent child trans rot (Y-P-R, degrees)
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) # how many seconds to broadcast at faster rate
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         # print 'TF prefix:' + self.tfb.getTFPrefix() # d'arggh.. ros-pkg #4943 still hasn't been fixed..
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()


flyer_common
Author(s): Patrick Bouffard
autogenerated on Sun Jan 5 2014 11:37:49