grab_cb_data.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 
00003 import numpy as np
00004 import yaml
00005 import sys
00006 import cv
00007 
00008 import roslib
00009 roslib.load_manifest('camera_calibration')
00010 roslib.load_manifest('hrl_geom')
00011 roslib.load_manifest('tf')
00012 
00013 import rospy
00014 import rosbag
00015 import tf
00016 from sensor_msgs.msg import Image, PointCloud2, CameraInfo
00017 
00018 from hrl_geom.pose_converter import PoseConv
00019 from cv_bridge import CvBridge, CvBridgeError
00020 from camera_calibration.calibrator import ChessboardInfo, Calibrator
00021 from point_cloud import read_points, create_cloud, create_cloud_xyz32
00022 
00023 class DataListener(object):
00024     def __init__(self, is_kinect, bridge, calib):
00025         self.is_kinect = is_kinect
00026         self.cur_img = None
00027         self.cur_pc = None
00028         self.cam_info = None
00029         self.cur_corners = None
00030         self.bridge = bridge
00031         self.calib = calib
00032         self.cam_sub = rospy.Subscriber("/camera", Image, self.sub_img)
00033         if self.is_kinect:
00034             self.pc_sub = rospy.Subscriber("/pc", PointCloud2, self.sub_pc)
00035         else:
00036             self.cam_info_sub = rospy.Subscriber("/camera_info", CameraInfo, self.sub_info)
00037         self.vis_pub = rospy.Publisher("/cb_img_raw", Image)
00038         print "Waiting for image/PC"
00039         r = rospy.Rate(10)
00040         while not rospy.is_shutdown():
00041             if self.cur_img is not None:
00042                 if self.is_kinect:
00043                     if self.cur_pc is not None:
00044                         break
00045                 else:
00046                     if self.cam_info is not None:
00047                         break
00048             r.sleep()
00049         print "Received image/PC"
00050 
00051     def sub_img(self, img):
00052         self.cur_img = img
00053         cv_img = self.bridge.imgmsg_to_cv(img, "rgb8")
00054         has_corners, cur_corners, chess = self.calib.get_corners(cv_img)
00055         if not has_corners:
00056             cur_corners = None
00057             return
00058         self.cur_corners = cur_corners
00059         cv.DrawChessboardCorners(cv_img, 
00060                                  (self.calib._boards[0].n_cols, self.calib._boards[0].n_rows), 
00061                                  self.cur_corners, has_corners)
00062         new_img = self.bridge.cv_to_imgmsg(cv_img, "rgb8")
00063         new_img.header = img.header
00064         self.vis_pub.publish(new_img)
00065 
00066     def sub_pc(self, pc):
00067         self.cur_pc = pc
00068 
00069     def sub_info(self, cam_info):
00070         self.cam_info = cam_info
00071 
00072     def wait_for_new(self, timeout):
00073         last_img_id = self.cur_img.header.seq
00074         if self.is_kinect:
00075             last_other_id = self.cur_pc.header.seq
00076         else:
00077             last_other_id = self.cam_info.header.seq
00078         r = rospy.Rate(10)
00079         start_time = rospy.get_time()
00080         while not rospy.is_shutdown():
00081             if rospy.get_time() - start_time > timeout:
00082                 print "Timed out"
00083                 return None
00084             if last_img_id != self.cur_img.header.seq:
00085                 if self.is_kinect:
00086                     cur_id = self.cur_pc.header.seq
00087                 else:
00088                     cur_id = self.cam_info.header.seq
00089                 if last_other_id != cur_id:
00090                     return self.cur_corners
00091             r.sleep()
00092 
00093 def main():
00094     if len(sys.argv) < 3:
00095         print 'grab_cbs_auto cb_config.yaml output_bag.bag'
00096         return
00097     rospy.init_node("grab_cbs")
00098 
00099     f = file(sys.argv[1], 'r')
00100     cb_config = yaml.safe_load(f.read())
00101     print cb_config
00102     f.close()
00103     is_kinect = rospy.get_param("/grab_cbs/is_kinect", True)
00104 
00105     # load cb stuff
00106     chessboard = ChessboardInfo()
00107     chessboard.n_cols = cb_config['cols'] # 6
00108     chessboard.n_rows = cb_config['rows'] # 7
00109     chessboard.dim = cb_config['dim'] # 0.0258 
00110     calib = Calibrator([chessboard])
00111     bridge = CvBridge()
00112 
00113     l = DataListener(is_kinect, bridge, calib)
00114     tf_list = tf.TransformListener()
00115 
00116     cb_knowns = []
00117     for j in range(chessboard.n_cols):
00118         for i in range(chessboard.n_rows):
00119             cb_knowns.append((chessboard.dim*i, chessboard.dim*j, 0.0))
00120         
00121     bag = rosbag.Bag(sys.argv[2], 'w')
00122     i = 0
00123     while not rospy.is_shutdown():
00124         if raw_input("Press enter to take CB, type 'q' to quit: ") == "q":
00125             break
00126 
00127         tries = 0
00128         while not rospy.is_shutdown() and tries < 3:
00129             corners = l.wait_for_new(5.)
00130             if corners is None:
00131                 print "No corners detected"
00132                 tries += 1
00133                 continue
00134             corners_2d = np.uint32(np.round(corners)).tolist()
00135             corners_3d = []
00136             if is_kinect:
00137                 for x,y,z in read_points(l.cur_pc, field_names=['x', 'y', 'z'], uvs=corners_2d):
00138                     corners_3d.append((x,y,z))
00139                 frame_id = l.cur_pc.header
00140             else:
00141                 obj_pts = cv.fromarray(np.array(cb_knowns))
00142                 img_pts = cv.fromarray(np.array(corners))
00143                 K = cv.fromarray(np.reshape(l.cam_info.K,(3,3)))
00144                 D = cv.fromarray(np.array([l.cam_info.D]))
00145                 R_vec = cv.fromarray(np.zeros((3,1)))
00146                 t = cv.fromarray(np.zeros((3,1)))
00147                 cv.FindExtrinsicCameraParams2(obj_pts, img_pts, K, D, R_vec, t)
00148                 R_mat = cv.fromarray(np.zeros((3,3)))
00149                 cv.Rodrigues2(R_vec, R_mat)
00150                 T = PoseConv.to_homo_mat(np.mat(np.asarray(t)).T.A.tolist(), 
00151                                          np.mat(np.asarray(R_mat)).A.tolist())
00152                 cb_knowns_mat = np.vstack((np.mat(cb_knowns).T, np.mat(np.ones((1, len(cb_knowns))))))
00153                 corners_3d = np.array((T * cb_knowns_mat)[:3,:].T)
00154                 frame_id = l.cur_img.header
00155             print corners_3d
00156             if np.any(np.isnan(corners_3d)):
00157                 print "Pointcloud malformed"
00158                 tries += 1
00159                 continue
00160             now = rospy.Time.now()
00161             corners_pc = create_cloud_xyz32(frame_id, corners_3d)
00162             try:
00163                 pose = tf_list.lookupTransform('/base_link', '/ee_link', rospy.Time(0))
00164             except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
00165                 print "TF screwed up..."
00166                 continue
00167             bag.write("/pose", PoseConv.to_pose_stamped_msg('/base_link', pose), now)
00168             bag.write("/pc", corners_pc, now)
00169             print "Wrote pose/CB to bag file"
00170             break
00171         i += 1
00172     bag.close()
00173 
00174 if __name__ == "__main__":
00175     main()


arm_3d_cb_calib
Author(s): Kelsey
autogenerated on Wed Nov 27 2013 12:04:05