00001
00002
00003 import roslib
00004 roslib.load_manifest('camera_pose_calibration')
00005
00006 import itertools
00007 import collections
00008 import rospy
00009 import threading
00010
00011 from tf_conversions import posemath
00012 from std_msgs.msg import Empty
00013 from camera_pose_calibration.msg import CalibrationEstimate
00014 from camera_pose_calibration.msg import CameraPose
00015 from camera_pose_calibration.msg import RobotMeasurement, CameraCalibration
00016 from camera_pose_calibration import init_optimization_prior
00017 from camera_pose_calibration import estimate
00018 from camera_pose_calibration import camera_info_converter
00019
00020 class Estimator:
00021 def __init__(self):
00022 self.lock = threading.Lock()
00023 self.reset()
00024 self.pub = rospy.Publisher('camera_calibration', CameraCalibration)
00025 self.sub_reset = rospy.Subscriber('reset', Empty, self.reset_cb)
00026 self.sub_meas = rospy.Subscriber('robot_measurement', RobotMeasurement, self.meas_cb)
00027
00028 def reset_cb(self, msg):
00029 self.reset()
00030
00031 def reset(self):
00032 with self.lock:
00033 self.state = None
00034 self.meas = []
00035 rospy.loginfo('Reset calibration state')
00036
00037
00038 def meas_cb(self, msg):
00039 with self.lock:
00040
00041 for camera in msg.M_cam:
00042 P = camera.cam_info.P
00043 all_zero = True
00044 for i in range(12):
00045 if P[i] != 0:
00046 all_zero = False
00047 if all_zero:
00048 rospy.logfatal("Camera info of %s is all zero. You should calibrate your camera intrinsics first "%camera.camera_id)
00049 exit(-1)
00050
00051
00052
00053
00054
00055
00056
00057 self.meas.append(msg)
00058 print "MEAS", len(self.meas)
00059 for m in self.meas:
00060 print " - stamp: %f"%m.header.stamp.to_sec()
00061
00062
00063 if True:
00064 self.state = CalibrationEstimate()
00065 camera_poses, checkerboard_poses = init_optimization_prior.find_initial_poses(self.meas)
00066 self.state.targets = [ posemath.toMsg(checkerboard_poses[i]) for i in range(len(checkerboard_poses)) ]
00067 self.state.cameras = [ CameraPose(camera_id, posemath.toMsg(camera_pose)) for camera_id, camera_pose in camera_poses.iteritems()]
00068
00069
00070 self.state = estimate.enhance(self.meas, self.state)
00071
00072
00073 res = CameraCalibration()
00074 res.camera_pose = [camera.pose for camera in self.state.cameras]
00075 res.camera_id = [camera.camera_id for camera in self.state.cameras]
00076 self.pub.publish(res)
00077
00078
00079 def main():
00080 rospy.init_node('online_calibration')
00081 e = Estimator()
00082
00083 rospy.spin()
00084
00085 if __name__ == '__main__':
00086 main()
00087
00088
00089