skin_patch_calibration.py
Go to the documentation of this file.
00001 #!/usr/bin/python
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 # 1D np array
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 # Nx3
00049         self.nrml_arr = None # Nx3
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     # implement this function in classes derived from this one.
00112     def raw_data_to_force(self, raw_data):
00113         raise RuntimeError('Unimplemented function')
00114 
00115     # n_std = 0 is the same as no thresholding.
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     # rdc - raw data client
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. # calibration!
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 


hrl_meka_skin_sensor_darpa_m3
Author(s): Advait Jain. Advisor: Prof. Charlie Kemp. Healthcare Robotics Lab, Georgia Tech.
autogenerated on Wed Nov 27 2013 12:02:01