00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 import numpy as np, math
00019 import copy
00020
00021 import roslib; roslib.load_manifest('hrl_common_code_darpa_m3')
00022 import hrl_lib.viz as hv
00023 import hrl_lib.util as ut
00024 import hrl_lib.transforms as tr
00025
00026 import rospy
00027 import tf
00028
00029 from visualization_msgs.msg import Marker
00030 from hrl_haptic_manipulation_in_clutter_msgs.msg import SkinContact
00031
00032 from hrl_msgs.msg import FloatArrayBare
00033 from geometry_msgs.msg import Point
00034 from geometry_msgs.msg import Vector3
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 def simulate_ft_sensor_on_link_base(fc_mat, xc_mat, o, o_next):
00045 f_res = fc_mat.sum(1)
00046 tau_res = np.matrix(np.cross((xc_mat-o).T.A, fc_mat.T.A)).T.sum(1)
00047
00048 if np.linalg.norm(f_res) < 0.01:
00049 return np.matrix([0,0,0]).T, None
00050
00051 poc = np.cross(f_res.A1, tau_res.A1) / (f_res.T * f_res)[0,0]
00052 nrml = np.cross(np.array([0.,0.,1.]), (o_next - o).A1)
00053 nrml = nrml / np.linalg.norm(nrml)
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 l = -np.dot(poc, nrml) / np.dot(nrml, f_res.A1)
00066
00067 return f_res, o + np.matrix(poc).T + l * f_res
00068
00069 def skin_contact_cb(sc, callback_args):
00070 sc_pub, kinematics = callback_args
00071 sf = SkinContact()
00072
00073 sf.header.frame_id = '/torso_lift_link'
00074 sf.header.stamp = sc.header.stamp
00075
00076 if len(sc.link_names) == 0:
00077 sc_pub.publish(sc)
00078 return
00079
00080 fc_l = []
00081 xc_l = []
00082
00083
00084
00085
00086 link_names = sc.link_names
00087 idxs = range(len(link_names))
00088 sorted_list = zip(link_names, idxs)
00089 sorted_list.sort()
00090
00091 i = 0
00092 for nm, idx in sorted_list:
00093 jt_num = int(nm[-1]) - 1
00094
00095 fc_l.append(np.matrix([sc.forces[idx].x, sc.forces[idx].y, sc.forces[idx].z]).T)
00096 xc_l.append(np.matrix([sc.locations[idx].x, sc.locations[idx].y, sc.locations[idx].z]).T)
00097
00098 if i == len(sorted_list)-1 or sorted_list[i+1][0] != nm:
00099 o, _ = kinematics.FK(q, jt_num)
00100 o_next, _ = kinematics.FK(q, jt_num+1)
00101 f_res, loc = simulate_ft_sensor_on_link_base(np.column_stack(fc_l),
00102 np.column_stack(xc_l),
00103 o, o_next)
00104 if loc == None:
00105 continue
00106
00107 nrml = np.cross(np.array([0.,0.,1.]), (o_next - o).A1)
00108 nrml = np.matrix(nrml / np.linalg.norm(nrml)).T
00109 if (nrml.T * f_res)[0,0] < 0.:
00110 nrml = -1. * nrml
00111
00112 f_res_direc = f_res / np.linalg.norm(f_res)
00113 link_length = np.linalg.norm(o-o_next)
00114 link_direc = (o_next - o) / link_length
00115 if (link_direc.T * f_res_direc)[0,0] > 0.93:
00116
00117 loc = o_next
00118 elif (link_direc.T * f_res_direc)[0,0] < -0.93:
00119 f_res = f_res * -1
00120 loc = o_next
00121 f_res_direc = -f_res_direc
00122
00123 dist_from_o = np.linalg.norm(loc-o)
00124 dist_from_o_next = np.linalg.norm(loc-o_next)
00125 if dist_from_o > link_length or dist_from_o_next > link_length:
00126 if dist_from_o > dist_from_o_next:
00127 loc = o_next
00128 else:
00129 loc = o
00130
00131
00132
00133 if np.linalg.norm(loc-o_next) < 0.02:
00134 nrml = f_res_direc
00135
00136
00137
00138 sf.link_names.append(nm)
00139 sf.forces.append(Vector3(f_res[0,0], f_res[1,0], f_res[2,0]))
00140 sf.locations.append(Point(loc[0,0], loc[1,0], loc[2,0]))
00141 sf.normals.append(Vector3(nrml[0,0], nrml[1,0], nrml[2,0]))
00142 sf.pts_x.append(FloatArrayBare([loc[0,0]]))
00143 sf.pts_y.append(FloatArrayBare([loc[1,0]]))
00144 sf.pts_z.append(FloatArrayBare([loc[2,0]]))
00145
00146 fc_l = []
00147 xc_l = []
00148
00149 i+=1
00150
00151 sc_pub.publish(sf)
00152
00153
00154 def joint_angles_cb(fab):
00155 global q
00156 q = copy.copy(fab.data)
00157
00158
00159
00160 if __name__ == '__main__':
00161 import hrl_common_code_darpa_m3.robot_config.three_link_planar_capsule as d_robot
00162 roslib.load_manifest('hrl_software_simulation_darpa_m3')
00163 import hrl_software_simulation_darpa_m3.gen_sim_arms as gsa
00164
00165 node_nm = 'skin_contact_to_resultant_force'
00166 rospy.init_node(node_nm)
00167
00168 kinematics = gsa.RobotSimulatorKDL(d_robot)
00169 q = [0.,0.,0.]
00170
00171 skin_topic = '/skin/contacts'
00172 sc_pub = rospy.Publisher(skin_topic, SkinContact)
00173
00174 rospy.Subscriber('/skin/contacts_all', SkinContact,
00175 skin_contact_cb,
00176 callback_args = (sc_pub, kinematics))
00177 rospy.Subscriber('/sim_arm/joint_angles', FloatArrayBare,
00178 joint_angles_cb)
00179
00180 rospy.loginfo('Started skin_contact to resultant force!')
00181 rospy.spin()
00182
00183