00001 import roslib; roslib.load_manifest('hai_sandbox') 00002 import rospy 00003 import actionlib 00004 00005 import hrl_lib.tf_utils as tfu 00006 import hrl_lib.util as ut 00007 import hrl_pr2_lib.devices as hd 00008 import hrl_camera.ros_camera as rc 00009 00010 import hai_sandbox.recognize_3d as r3d 00011 #import hai_sandbox.msg as hmsg 00012 import geometry_msgs.msg as gmsg 00013 import tf 00014 from cv_bridge import CvBridge, CvBridgeError 00015 import numpy as np 00016 import ml_lib.dataset as ds 00017 import cv 00018 import datetime 00019 import hrl_lib.util as ut 00020 import math 00021 00022 def str_from_time(ctime): 00023 return datetime.datetime.fromtimestamp(ctime).strftime('%Y_%m_%d_%H_%M_%S') 00024 00025 class InterestPointPerception(r3d.InterestPointAppBase): 00026 00027 def __init__(self, object_name, labeled_data_fname, tf_listener): 00028 r3d.InterestPointAppBase.__init__(self, object_name, labeled_data_fname) 00029 00030 self.tf_listener = tf_listener 00031 if tf_listener == None: 00032 self.tf_listener = tf.TransformListener() 00033 self.laser_scan = hd.LaserScanner('point_cloud_srv') 00034 self.prosilica = rc.Prosilica('prosilica', 'polled') 00035 self.prosilica_cal = rc.ROSCameraCalibration('/prosilica/camera_info') 00036 self.image_pub = r3d.ImagePublisher(object_name + '_perception', self.prosilica_cal) 00037 self.last_added = None 00038 self.disp = r3d.RvizDisplayThread(self.prosilica_cal) 00039 self.disp.start() 00040 00041 def scan(self, point3d): 00042 rospy.loginfo('InterestPointPerception: scanning..') 00043 point_cloud_bl = self.laser_scan.scan(math.radians(180.), math.radians(-180.), 15) 00044 prosilica_image = self.prosilica.get_frame() 00045 image_T_laser = tfu.transform('/high_def_optical_frame', '/base_link', self.tf_listener) 00046 00047 #Extract features 00048 self.feature_extractor = r3d.IntensityCloudData(point_cloud_bl, 00049 prosilica_image, image_T_laser, self.prosilica_cal, 00050 point3d, self.rec_params) 00051 00052 fex = self.feature_extractor 00053 self.disp.display_scan(fex.point_cloud3d_orig, fex.points3d_valid_laser, fex.colors_valid, 00054 prosilica_image, self.prosilica_cal) 00055 00056 rospy.loginfo('InterestPointPerception: extracting features..') 00057 #self.instances, self.points2d, self.points3d = self.feature_extractor.extract_vectorized_features() 00058 rospy.loginfo('InterestPointPerception: finished extraction.') 00059 00060 def is_ready(self): 00061 return self.learner != None 00062 00063 def add_example(self, point3d_bl, label, pt2d=None): 00064 fex = self.feature_extractor 00065 feature = fex.feature_vec_at_mat(point3d_bl) 00066 if feature == None: 00067 return False 00068 pt2d = fex.calibration_obj.project(tfu.transform_points(fex.image_T_laser, point3d_bl)) 00069 label = np.matrix(label) 00070 self.add_to_dataset(feature, label, pt2d, point3d_bl) 00071 self.last_added = {'pt': pt2d, 'l': label} 00072 return True 00073 00074 def select_next_instances(self, n): 00075 #selected_idx, selected_dist = self.learner.select_next_instances(self.instances, n) 00076 return self.learner.select_next_instances(self.instances, n) 00077 00078 def get_likely_success_points(self): 00079 #do something to reduce number of points 00080 points3d_pos = self.classified_dataset.pt3d[:, np.where(self.classified_dataset.outputs == r3d.POSITIVE)[1].A1] 00081 return points3d_pos 00082 00083 def draw_and_send(self): 00084 self.classify() 00085 img = cv.CloneMat(self.feature_extractor.image_cv) 00086 #draw classified points. 00087 colors = {r3d.POSITIVE: [0,255,0], r3d.NEGATIVE: [0,0,255]} 00088 r3d.draw_labeled_points(img, self.classified_dataset) 00089 00090 #draw labeled data. 00091 r3d.draw_labeled_points(img, self.dataset, colors[r3d.POSITIVE], colors[r3d.NEGATIVE]) 00092 00093 #draw latest addition and its label. 00094 r3d.draw_points(img, self.last_added['pt'], colors[self.last_added['l']], 4) 00095 00096 self.image_pub.publish(img, self.feature_extractor.calibration_obj) 00097 00098 00099 if __name__ == '__main__': 00100 import sys 00101 00102 object_name = sys.argv[1] 00103 datafile = sys.argv[2] 00104 server = InterestPointActions(object_name, datafile) 00105 rospy.spin() 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 #def classify(self): 00128 # r3d.InterestPointAppBase.classify(self) 00129 # points3d_pos = self.classified_dataset.pt3d[:, np.where(self.classified_dataset.outputs == r3d.POSITIVE)[1].A1] 00130 # return points3d_pos 00131 00132 #def add_to_dataset(self, feature, label, pt2d, pt3d): 00133 # if self.dataset == None: 00134 # self.dataset = InterestPointDataset(feature, label, [pt2d], [pt3d], self.feature_extractor) 00135 # else: 00136 # self.dataset.add(feature, label, pt2d, pt3d) 00137 # #pos_ex = np.sum(self.dataset.outputs) 00138 # #neg_ex = self.dataset.outputs.shape[1] - pos_ex 00139 # #if pos_ex > 2 and neg_ex > 2 and self.blank: 00140 # # self.train_learner() 00141 # # self.blank = False 00142 00143 #def train(self): 00144 # return None 00145 00146 #def train(self): 00147 # if self.dataset != None: 00148 # #train 00149 # self.ipdetector.train(self.dataset) 00150 # #classify 00151 # #pdb.set_trace() 00152 # results = [] 00153 # for i in range(self.instances.shape[1]): 00154 # results.append(self.ipdetector.learner.classify(self.instances[:,i])) 00155 # #pdb.set_trace() 00156 # plist = [self.points2d[:, i] for i in range(self.points2d.shape[1])] 00157 # p3list = [self.points3d[:, i] for i in range(self.points3d.shape[1])] 00158 # self.classified_dataset = InterestPointDataset(self.instances, np.matrix(results), 00159 # plist, p3list, self.feature_extractor) 00160 00161 #self.object_name = object_name 00162 #self.ipdetector = r3d.InterestPointDetector() 00163 #self.dataset = None 00164 #self.labeled_data_fname = datafile 00165 #if datafile != None: 00166 # self.load_labeled_data() 00167 #self.feature_extractor = None 00168 00169 #def load_labeled_data(self): 00170 # self.dataset = ut.load_pickle(self.labeled_data_fname) 00171 # print 'loaded from', self.labeled_data_fname 00172 # self.dataset.pt2d = [None] * len(self.dataset.pt2d) 00173 # self.dataset.pt3d = [None] * len(self.dataset.pt3d) 00174 # self.ipdetector = InterestPointDetector(self.dataset) 00175 # self.ipdetector.train(self.dataset) 00176 00177 #def add_to_dataset(self, feature, label, pt2d, pt3d): 00178 # if self.dataset == None: 00179 # self.dataset = InterestPointDataset(feature, label, [pt2d], [pt3d], self.feature_extractor) 00180 # else: 00181 # self.dataset.add(feature, label, pt2d, pt3d) 00182 # pos_ex = np.sum(self.dataset.outputs) 00183 # neg_ex = self.dataset.outputs.shape[1] - pos_ex 00184 # if pos_ex > 2 and neg_ex > 2 and self.blank: 00185 # self.train_learner() 00186 # self.blank = False 00187 00188 00189 00190 00191 # def __init__(self, object_name, datafile): 00192 # self.node_name = object_name + '_active_perception_server' 00193 # self.object_name = object_name 00194 # rospy.init_node(self.node_name) 00195 # 00196 # #Load learner 00197 # self.learner = r3d.SVMPCA_ActiveLearner() 00198 # self.rec_params = r3d.Recognize3DParam() 00199 # 00200 # rospy.loginfo('Loading dataset: ' + datafile) 00201 # labeled_light_switch_dataset = ut.load_pickle(datafile) 00202 # rospy.loginfo('Training %s.' % object_name) 00203 # self.learner.train(labeled_light_switch_dataset, 00204 # labeled_light_switch_dataset.sizes['intensity'], 00205 # self.rec_params.variance_keep) 00206 # 00207 # rospy.loginfo('Launching ROS connections') 00208 # 00209 # #Create message listeners 00210 # self.tf_listener = tf.TransformListener() 00211 # self.bridge = CvBridge() 00212 # 00213 # #Create servers 00214 # self.find_as = actionlib.SimpleActionServer('find_' + object_name, 00215 # hmsg.InterestPointLocate, self.find_cb, False) 00216 # self.find_as.start() 00217 # #self.find_as.is_preempt_requested() 00218 # #self.find_as.set_preempted() 00219 # #self.find_as.publish_feedback(self._feedback) 00220 # #self.find_as.set_succeeded() 00221 # 00222 # self.add_example_as = actionlib.SimpleActionServer('add_example_' + object_name, 00223 # hmsg.InterestPointAddExample, self.add_example_cb, False) 00224 # self.add_example_as.start() 00225 # 00226 # self.pick_as = actionlib.SimpleActionServer('pick_' + object_name, 00227 # hmsg.InterestPointPick, self.pick_cb, False) 00228 # self.pick_as.start() 00229 # 00230 # rospy.loginfo('Ready.') 00231 # 00232 # #rospy.loginfo('Loading dataset: ' + datafile) 00233 # #rospy.loginfo('Training %s.' % object_name) 00234 # #rospy.loginfo('Launching ROS connections') 00235 # 00236 # def _find(self, cloud, image, calib, center, radius): 00237 # #preprocess 00238 # self.rec_params.radius = goal.radius 00239 # image_T_laser = tfu.transform(calib.frame, cloud.header.frame_id, self.tf_listener) 00240 # ic_data = r3d.IntensityCloudData(cloud, image, image_T_laser, calib, center, self.rec_params) 00241 # 00242 # #label 00243 # instances = ic_data.extract_vectorized_features() 00244 # results = [] 00245 # for i in range(instances.shape[1]): 00246 # nlabel = self.learner.classify(instances[:, i]) 00247 # results.append(nlabel) 00248 # 00249 # results = np.matrix(results) 00250 # 00251 # #draw and save results 00252 # image_cpy = cv.CloneImage(image) 00253 # r3d.draw_labeled_points(ic_data, ds.Dataset(self.instances, results), image_cpy) 00254 # cv.SaveImage('%s_%s.png' % (self.object_name, str_from_time(cloud.header.stamp.to_time())), image_cpy) 00255 # 00256 # #want 3d location of each instance 00257 # positive_indices = np.where(results == r3d.POSITIVE)[1] 00258 # positive_points_3d = ic_data.sampled_points[:, positive_indices] 00259 # 00260 # #return a random point for now 00261 # rindex = np.random.randint(0, len(positive_indices)) 00262 # 00263 # return positive_points_3d[:,rindex] 00264 # 00265 # 00266 # def find_cb(self, goal): 00267 # calib = rc.ROSCameraCalibration(offline=True) 00268 # calib.camera_info(goal.camera_info) 00269 # imagecv = self.bridge.imgmsg_to_cv(goal.image, encoding="bgr8") 00270 # centermat = np.matrix([goal.center.x, goal.center.y, goal.center.z]).T 00271 # round_points = self._find(goal.cloud, imagecv, centermat, goal_radius) 00272 # 00273 # results = hmsg.InterestPointLocateResult() 00274 # results.header.frame_id = goal.cloud.header.frame_id 00275 # results.header.stamp = rospy.Time.now() 00276 # results.interest_points = [gmsg.Point(*round_point[:,i].T.A1.tolist()) for i in range(round_points.shape[1])] 00277 # self.find_as.set_succeeded() 00278 # 00279 # def add_example_cb(self, goal): 00280 # pass 00281 # 00282 # def pick_cb(self, goal): 00283 # pass