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
00037 import roslib; roslib.load_manifest('calibration_estimation')
00038 import rospy
00039
00040 from urdf_parser_py.urdf import *
00041 import yaml
00042 import numpy
00043 from numpy import matrix, vsplit, sin, cos, reshape, zeros, pi
00044
00045 from calibration_estimation.joint_chain import JointChain
00046 from calibration_estimation.tilting_laser import TiltingLaser
00047 from calibration_estimation.camera import RectifiedCamera
00048 from calibration_estimation.checkerboard import Checkerboard
00049 from calibration_estimation.single_transform import SingleTransform
00050 from calibration_estimation.single_transform import RPY_to_angle_axis, angle_axis_to_RPY
00051
00052
00053 def init_primitive_dict(start_index, config_dict, PrimitiveType):
00054 cur_index = start_index
00055
00056
00057 primitive_dict = dict()
00058
00059
00060 for key, elem in config_dict.items():
00061 primitive_dict[key] = PrimitiveType(elem)
00062
00063 primitive_dict[key].start = cur_index
00064 primitive_dict[key].end = cur_index + primitive_dict[key].get_length()
00065 cur_index = primitive_dict[key].end
00066
00067
00068 return primitive_dict, cur_index
00069
00070
00071
00072 def inflate_primitive_dict(param_vec, primitive_dict):
00073 for key, elem in primitive_dict.items():
00074 elem.inflate(param_vec[elem.start:elem.end,0])
00075
00076
00077
00078 def deflate_primitive_dict(param_vec, primitive_dict):
00079 for key, elem in primitive_dict.items():
00080 param_vec[elem.start:elem.end,0] = elem.deflate()
00081
00082
00083
00084
00085 def update_primitive_free(target_list, config_dict, free_dict):
00086 for key, elem in config_dict.items():
00087 if key in free_dict.keys():
00088 free = elem.calc_free(free_dict[key])
00089 target_list[elem.start:elem.end] = free
00090
00091
00092 def primitive_params_to_config(param_vec, primitive_dict):
00093 config_dict = dict()
00094 for key, elem in primitive_dict.items():
00095 config_dict[key] = elem.params_to_config(param_vec[elem.start:elem.end,0])
00096 return config_dict
00097
00098
00099
00100 class UrdfParams:
00101 def __init__(self, raw_urdf, config):
00102 urdf = URDF().parse(raw_urdf)
00103 self.configure(urdf, config)
00104
00105 def configure(self, urdf, config_dict):
00106 self.urdf = urdf
00107 self.fakes = list()
00108
00109
00110 try:
00111 self.base_link = config_dict['base_link']
00112 except:
00113 self.base_link = 'base_link'
00114 transforms = config_dict['transforms']
00115 checkerboards = config_dict["checkerboards"]
00116 config_dict = config_dict['sensors']
00117
00118
00119 cur_index = 0
00120
00121
00122 for joint_name in urdf.joint_map.keys():
00123 j = urdf.joint_map[joint_name]
00124 if j.origin == None:
00125 j.origin = Pose([0.0, 0.0, 0.0], [0.0, 0.0, 0.0])
00126 if j.origin.rotation == None:
00127 j.origin.rotation = [0.0, 0.0, 0.0]
00128 if j.origin.position == None:
00129 j.origin.position = [0.0, 0.0, 0.0]
00130
00131
00132 self.transforms = dict()
00133 for joint_name in urdf.joint_map.keys():
00134 joint_name = str(joint_name)
00135 j = urdf.joint_map[joint_name]
00136 rot = j.origin.rotation
00137 rot = RPY_to_angle_axis(rot)
00138 p = j.origin.position + rot
00139 self.transforms[joint_name] = SingleTransform(p, joint_name)
00140 self.transforms[joint_name].start = cur_index
00141 self.transforms[joint_name].end = cur_index + self.transforms[joint_name].get_length()
00142 cur_index = self.transforms[joint_name].end
00143 for name, transform in transforms.items():
00144 transform = [eval(str(x)) for x in transform]
00145 transform[3:6] = RPY_to_angle_axis(transform[3:6])
00146 try:
00147 self.transforms[name].inflate(reshape(matrix(transform, float), (-1,1)))
00148 except:
00149 rospy.logwarn("Transform not found in URDF %s", name)
00150 self.transforms[name] = SingleTransform(transform, name)
00151 self.transforms[name].start = cur_index
00152 self.transforms[name].end = cur_index + self.transforms[name].get_length()
00153 cur_index = self.transforms[name].end
00154
00155
00156 self.chains = dict()
00157 chain_dict = config_dict['chains']
00158 for chain_name in config_dict['chains']:
00159
00160 this_config = config_dict['chains'][chain_name]
00161 this_config['joints'] = urdf.get_chain(this_config['root'], this_config['tip'], links=False)
00162 this_config['active_joints'] = list()
00163 this_config['axis'] = list()
00164 this_config['transforms'] = dict()
00165 this_config['gearing'] = config_dict['chains'][chain_name]['gearing']
00166 this_config['cov'] = config_dict['chains'][chain_name]['cov']
00167 for joint_name in this_config["joints"]:
00168 this_config['transforms'][joint_name] = self.transforms[joint_name]
00169 if urdf.joint_map[joint_name].joint_type in ['revolute','continuous'] :
00170 this_config["active_joints"].append(joint_name)
00171 axis = urdf.joint_map[joint_name].axis
00172 this_config["axis"].append( sum( [i[0]*int(i[1]) for i in zip([4,5,6], axis)] ) )
00173
00174 rot = urdf.joint_map[joint_name].origin.rotation
00175 if rot != None and (sum([abs(x) for x in rot]) - rot[abs(this_config["axis"][-1])-4]) > 0.001:
00176 print 'Joint origin is rotated, calibration will fail: ', joint_name
00177 elif urdf.joint_map[joint_name].joint_type == 'prismatic':
00178 this_config["active_joints"].append(joint_name)
00179 axis = urdf.joint_map[joint_name].axis
00180 this_config["axis"].append( sum( [i[0]*int(i[1]) for i in zip([1,2,3], axis)] ) )
00181 elif urdf.joint_map[joint_name].joint_type != 'fixed':
00182 print 'Unknown joint type:', urdf.joint_map[joint_name].joint_type
00183
00184 self.urdf.add_link(Link(chain_name+"_cb_link"))
00185 self.urdf.add_joint(Joint(chain_name+"_cb",this_config['tip'],chain_name+"_cb_link","fixed",origin=Pose([0.0,0.0,0.0],[0.0,0.0,0.0])))
00186 self.fakes += [chain_name+"_cb_link", chain_name+"_cb"]
00187 self.chains[chain_name] = JointChain(this_config)
00188 self.chains[chain_name].start = cur_index
00189 self.chains[chain_name].end = cur_index + self.chains[chain_name].get_length()
00190 cur_index = self.chains[chain_name].end
00191
00192
00193 self.tilting_lasers = dict()
00194 if 'tilting_lasers' in config_dict.keys():
00195 self.tilting_lasers, cur_index = init_primitive_dict(cur_index, config_dict["tilting_lasers"], TiltingLaser)
00196 self.rectified_cams, cur_index = init_primitive_dict(cur_index, config_dict["rectified_cams"], RectifiedCamera)
00197 self.checkerboards, cur_index = init_primitive_dict(cur_index, checkerboards, Checkerboard)
00198
00199 self.length = cur_index
00200
00201
00202 def calc_free(self, free_dict):
00203 free_list = [0] * self.length
00204 update_primitive_free(free_list, self.transforms, free_dict["transforms"])
00205 update_primitive_free(free_list, self.chains, free_dict["chains"])
00206 update_primitive_free(free_list, self.tilting_lasers, free_dict["tilting_lasers"])
00207 update_primitive_free(free_list, self.rectified_cams, free_dict["rectified_cams"])
00208 update_primitive_free(free_list, self.checkerboards, free_dict["checkerboards"])
00209 return free_list
00210
00211 def params_to_config(self, param_vec):
00212 config_dict = dict()
00213 config_dict["base_link"] = self.base_link
00214 config_dict["transforms"] = dict()
00215 for key, elem in self.transforms.items():
00216 config_dict["transforms"][key] = elem.params_to_config(param_vec[elem.start:elem.end,0])
00217 config_dict["transforms"][key][3:6] = angle_axis_to_RPY(config_dict["transforms"][key][3:6])
00218 config_dict["sensors"] = {}
00219 config_dict["sensors"]["chains"] = primitive_params_to_config(param_vec, self.chains)
00220 config_dict["sensors"]["tilting_lasers"] = primitive_params_to_config(param_vec, self.tilting_lasers)
00221 config_dict["sensors"]["rectified_cams"] = primitive_params_to_config(param_vec, self.rectified_cams)
00222 config_dict["checkerboards"] = primitive_params_to_config(param_vec, self.checkerboards)
00223 return config_dict
00224
00225 def inflate(self, param_vec):
00226 inflate_primitive_dict(param_vec, self.transforms)
00227 for key, elem in self.chains.items():
00228 elem.inflate(param_vec[elem.start:elem.end,0])
00229 for joint_name in elem._joints:
00230 elem._transforms[joint_name] = self.transforms[joint_name]
00231 inflate_primitive_dict(param_vec, self.tilting_lasers)
00232 inflate_primitive_dict(param_vec, self.rectified_cams)
00233 inflate_primitive_dict(param_vec, self.checkerboards)
00234
00235 def deflate(self):
00236 param_vec = numpy.matrix( numpy.zeros((self.length,1), float))
00237 deflate_primitive_dict(param_vec, self.transforms)
00238 deflate_primitive_dict(param_vec, self.chains)
00239 deflate_primitive_dict(param_vec, self.tilting_lasers)
00240 deflate_primitive_dict(param_vec, self.rectified_cams)
00241 deflate_primitive_dict(param_vec, self.checkerboards)
00242 return param_vec
00243
00244 def get_clean_urdf(self):
00245 ''' Remove checkerboard links/joints. '''
00246 for joint in self.urdf.joint_map.keys():
00247 if joint in self.fakes:
00248 self.urdf.joints.remove(self.urdf.joint_map[joint])
00249 del self.urdf.joint_map[joint]
00250 for link in self.urdf.link_map.keys():
00251 if link in self.fakes:
00252 self.urdf.links.remove(self.urdf.link_map[link])
00253 del self.urdf.link_map[link]
00254 return self.urdf
00255