Go to the documentation of this file.00001
00002
00003 import numpy as np, math
00004 from threading import RLock
00005 import copy
00006
00007 import roslib; roslib.load_manifest('hrl_meka_skin_sensor_darpa_m3')
00008
00009 import rospy
00010 import hrl_lib.util as ut
00011 import hrl_lib.transforms as tr
00012
00013 from m3skin_ros.msg import TaxelArray
00014 from m3skin_ros.msg import RawTaxelArray
00015 from m3skin_ros.srv import None_TransformArray
00016 from m3skin_ros.srv import None_String
00017
00018 from std_msgs.msg import Empty
00019
00020 class RawDataClient():
00021 def __init__(self, raw_data_topic):
00022 self.raw_data = None
00023 self.fresh_data = False
00024 self.bias = None
00025 self.lock = RLock()
00026
00027 rospy.Subscriber(raw_data_topic, RawTaxelArray, self.raw_cb)
00028
00029 def raw_cb(self, msg):
00030 with self.lock:
00031 self.raw_data = np.array(msg.val_z)
00032 self.fresh_data = True
00033
00034 def get_raw_data(self, fresh):
00035 if fresh:
00036 while not self.fresh_data:
00037 rospy.sleep(0.002)
00038 with self.lock:
00039 self.fresh_data = False
00040 d = copy.copy(self.raw_data)
00041 return d
00042
00043
00044 class SkinCalibration():
00045 def __init__(self):
00046 self.ta_pub = rospy.Publisher('taxels/forces', TaxelArray)
00047
00048 self.pos_arr = None
00049 self.nrml_arr = None
00050
00051 self.bias_mn = None
00052 self.bias_std = None
00053
00054 self.disable_sensor = False
00055
00056 srv_nm1 = 'taxels/srv/local_coord_frames'
00057 srv_nm2 = 'taxels/srv/link_name'
00058
00059 rospy.loginfo('Waiting for services ...')
00060 rospy.wait_for_service(srv_nm1)
00061 rospy.wait_for_service(srv_nm2)
00062 rospy.loginfo('... Done')
00063
00064 self.local_coord_frames_srv = rospy.ServiceProxy(srv_nm1,
00065 None_TransformArray)
00066 self.link_name_srv = rospy.ServiceProxy(srv_nm2, None_String)
00067 self.link_name = self.link_name_srv().data
00068
00069 rospy.Subscriber('disable_sensor', Empty, self.disable_sensor_cb)
00070 rospy.Subscriber('enable_sensor', Empty, self.enable_sensor_cb)
00071
00072 def precompute_taxel_location_and_normal(self):
00073 resp = self.local_coord_frames_srv()
00074 pos_list = []
00075 nrml_list = []
00076 for t in resp.data:
00077 pos = (t.translation.x, t.translation.y, t.translation.z)
00078 pos_list.append(pos)
00079 q = (t.rotation.x, t.rotation.y, t.rotation.z, t.rotation.w)
00080 rot_mat = tr.quaternion_to_matrix(q)
00081 nrml_list.append(rot_mat[:,2].A1)
00082
00083 self.pos_arr = np.array(pos_list)
00084 self.nrml_arr = np.array(nrml_list)
00085
00086 def publish_taxel_array(self, raw_data):
00087 ta = TaxelArray()
00088 ta.header.frame_id = self.link_name
00089 ta.header.stamp = rospy.Time.now()
00090
00091 ta.centers_x = self.pos_arr[:,0]
00092 ta.centers_y = self.pos_arr[:,1]
00093 ta.centers_z = self.pos_arr[:,2]
00094
00095 ta.normals_x = self.nrml_arr[:,0]
00096 ta.normals_y = self.nrml_arr[:,1]
00097 ta.normals_z = self.nrml_arr[:,2]
00098
00099 min_idx = np.argmin(raw_data)
00100 calib_data = self.raw_data_to_force(raw_data)
00101
00102 if self.disable_sensor:
00103 calib_data[:] = 0.
00104
00105 ta.values_x = ta.normals_x * calib_data
00106 ta.values_y = ta.normals_y * calib_data
00107 ta.values_z = ta.normals_z * calib_data
00108
00109 self.ta_pub.publish(ta)
00110
00111
00112 def raw_data_to_force(self, raw_data):
00113 raise RuntimeError('Unimplemented function')
00114
00115
00116 def subtract_bias(self, data, n_std=0):
00117 d_biased = data - self.bias_mn
00118 idxs = np.where(np.abs(d_biased) < n_std * self.bias_std)[0]
00119 d_biased[idxs] = 0
00120 return d_biased
00121
00122
00123 def compute_bias(self, rdc, n):
00124 rospy.loginfo('started bias computation ...')
00125 d_list = []
00126 for i in range(n):
00127 d_list.append(rdc.get_raw_data(fresh = True))
00128
00129 d_arr = np.row_stack(d_list)
00130 mn = np.mean(d_arr, 0)
00131 std = np.std(d_arr, 0)
00132 self.bias_mn = mn
00133 self.bias_std = std
00134 rospy.loginfo('...done')
00135
00136 def disable_sensor_cb(self, msg):
00137 self.disable_sensor = True
00138
00139 def enable_sensor_cb(self, msg):
00140 self.disable_sensor = False
00141
00142
00143 class SkinCalibration_Naive(SkinCalibration):
00144 def __init__(self):
00145 SkinCalibration.__init__(self)
00146
00147 def raw_data_to_force(self, raw_data):
00148 meka_taxel_saturate_threshold = 17.
00149 saturated_taxel_force_value = 80.
00150
00151 d_biased = self.subtract_bias(raw_data, 6)
00152 calib_data = d_biased / 1000.
00153 idxs = np.where(calib_data < 1.0)[0]
00154 calib_data[idxs] = 0.
00155 idxs = np.where(calib_data > meka_taxel_saturate_threshold)[0]
00156 calib_data[idxs] = saturated_taxel_force_value
00157 return calib_data
00158
00159 def zero_sensor_cb(msg):
00160 scn.compute_bias(rdc, 10)
00161
00162
00163 if __name__ == '__main__':
00164 rospy.init_node('forearm_raw_data_subscriber')
00165
00166 zero_sensor_subscriber = rospy.Subscriber('zero_sensor', Empty, zero_sensor_cb)
00167
00168 scn = SkinCalibration_Naive()
00169 scn.precompute_taxel_location_and_normal()
00170
00171 rdc = RawDataClient('taxels/raw_data')
00172 scn.compute_bias(rdc, 1000)
00173
00174
00175 while not rospy.is_shutdown():
00176 d = rdc.get_raw_data(True)
00177 scn.publish_taxel_array(d)
00178
00179 if False:
00180 ut.get_keystroke('Hit a key to get biased data')
00181 d = rdc.get_biased_data(False, 5)
00182 print 'd:', d
00183
00184
00185
00186
00187
00188
00189
00190