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
00038
00039 import pr2_calibration_propagation.update_joint as update_joint
00040 import pr2_calibration_propagation.process_changelist as process_changelist
00041 import tf.transformations as transformations
00042 import math
00043
00044 def update_urdf(initial_system, calibrated_system, xml_in):
00045
00046 dh_offsets = {"right_arm_chain":[],
00047 "left_arm_chain":[],
00048 "head_chain":[]}
00049
00050 dh_joint_names = {"right_arm_chain" : ['r_shoulder_pan_joint', 'r_shoulder_lift_joint', 'r_upper_arm_roll_joint', 'r_elbow_flex_joint', 'r_forearm_roll_joint', 'r_wrist_flex_joint', 'r_wrist_roll_joint'],
00051 "left_arm_chain" : ['l_shoulder_pan_joint', 'l_shoulder_lift_joint', 'l_upper_arm_roll_joint', 'l_elbow_flex_joint', 'l_forearm_roll_joint', 'l_wrist_flex_joint', 'l_wrist_roll_joint'],
00052 "head_chain" : ['head_pan_joint', 'head_tilt_joint'] }
00053
00054
00055 chains_to_remove = [x for x in dh_offsets.keys() if x not in initial_system['dh_chains'].keys()];
00056 print "Need to ignore the following chains:", chains_to_remove
00057 for chain_to_remove in chains_to_remove:
00058 del dh_offsets[chain_to_remove]
00059
00060 print "Computing All dh chain offsets"
00061 for chain_name in dh_offsets.keys():
00062 dh_offsets[chain_name] = find_dh_param_offsets(chain_name, initial_system, calibrated_system)
00063 print "%s offsets:" % chain_name, pplist(dh_offsets[chain_name])
00064
00065
00066 joint_offsets_list = []
00067 for chain_name in dh_offsets.keys():
00068 joint_offsets_list.extend(zip(dh_joint_names[chain_name], dh_offsets[chain_name]))
00069 joint_offsets = dict(joint_offsets_list)
00070
00071
00072 transformdict = dict()
00073 for(name, rotvect) in calibrated_system['transforms'].iteritems():
00074 floatvect = [mixed_to_float(x) for x in rotvect]
00075
00076 transformdict[name] = [floatvect[0:3], angle_axis_to_RPY(floatvect[3:6])]
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 joints_dict = dict([(joint_name, [None, None, None]) for joint_name in transformdict.keys() + joint_offsets.keys()])
00095 for joint_name, val in transformdict.items():
00096 joints_dict[joint_name][0] = val[0]
00097 joints_dict[joint_name][1] = val[1]
00098
00099 for joint_name, offset in joint_offsets.items():
00100 joints_dict[joint_name][2] = offset
00101
00102 not_found = joints_dict.keys()
00103 changelist = []
00104
00105 for joint_name, val in joints_dict.items():
00106 cur_cl = update_joint.update_joint(xml_in, joint_name, xyz=val[0], rpy=val[1], ref_shift=val[2])
00107 if cur_cl is not None:
00108 not_found.remove(joint_name)
00109 changelist.extend(cur_cl)
00110
00111
00112
00113
00114
00115
00116
00117
00118 print "jointnames never found: ", not_found
00119
00120 for span, result in changelist:
00121 print "\"%s\" -> \"%s\"" % (xml_in[span[0]:span[1]], result)
00122
00123 xml_out = process_changelist.process_changelist(changelist, xml_in)
00124
00125 return xml_out
00126
00127
00128 def pplist(list):
00129 zeroed = []
00130 for x in list:
00131 if x is None:
00132 zeroed.append(0.)
00133 else:
00134 zeroed.append(x)
00135 return ' '.join(['%2.3f'%x for x in zeroed])
00136
00137
00138
00139 def epsEq(value1, value2, eps = 1e-10):
00140 if math.fabs(value1-value2) <= eps:
00141 return 1
00142 return 0
00143
00144
00145
00146 def mixed_to_float(mixed):
00147 pi = math.pi
00148 if type(mixed) == str:
00149 try:
00150 val = eval(mixed)
00151 except:
00152 print >> sys.stderr, "bad value:", mixed, "substituting zero!!\n\n"
00153 val = 0.
00154 else:
00155 val = float(mixed)
00156 return val
00157
00158
00159
00160 def find_dh_param_offsets(chain_name, system_default, system_calibrated):
00161 offsets = []
00162 for (default_params, calib_params) in zip(system_default['dh_chains'][chain_name]['dh'], system_calibrated['dh_chains'][chain_name]['dh']):
00163
00164 diff = mixed_to_float(calib_params[0]) - mixed_to_float(default_params[0])
00165 if epsEq(diff, 0):
00166 diff = None
00167 offsets.append(diff)
00168
00169 return offsets
00170
00171
00172
00173
00174 def angle_axis_to_RPY(vec):
00175 angle = math.sqrt(sum([vec[i]**2 for i in range(3)]))
00176 hsa = math.sin(angle/2.)
00177 if epsEq(angle, 0):
00178 return (0.,0.,0.)
00179 quat = [vec[0]/angle*hsa, vec[1]/angle*hsa, vec[2]/angle*hsa, math.cos(angle/2.)]
00180 rpy = quat_to_rpy(quat)
00181 return rpy
00182
00183 def rpy_to_quat(rpy):
00184 return transformations.quaternion_from_euler(rpy[0], rpy[1], rpy[2], 'sxyz')
00185
00186 def quat_to_rpy(q):
00187 rpy = transformations.euler_from_quaternion(q, 'sxyz')
00188 return rpy
00189
00190 def parse_rpy(line):
00191 return [float(x) for x in line.split("rpy=\"")[1].split("\"")[0].split()]
00192
00193 def parse_xyz(line):
00194 return [float(x) for x in line.split("xyz=\"")[1].split("\"")[0].split()]