20 import os,sys,itertools
24 def __init__(self, robot_description, base_link, arm_root_link, arm_tip_link, head_root_link, head_tip_link, arm_controller, head_controller, head_camera_frame, head_camera_joint, camera_namespace):
42 if self.robot.link_map.has_key(self.
base_link) ==
False:
48 if self.robot.link_map.has_key(self.
arm_tip_link) ==
False:
59 all_chain.append(self.robot.get_chain(base_link, end_link)[1:])
60 for c1,c2
in itertools.product(*all_chain):
62 rospy.logerr(
'arm/head chain share same joint ({}), this will cause failure'.format(c1))
66 joint_list = filter(
lambda x: self.robot.joint_map.has_key(x)
and self.robot.joint_map[x].type !=
'fixed', [c
for c
in self.robot.get_chain(base_link, end_link)])
67 exec(
'self.{0}_joint_list = {1}'.format(limb, joint_list))
in locals()
69 rospy.loginfo(
'using following joint for {} chain'.format(
'arm'))
70 rospy.loginfo(
'... {}'.format(self.arm_joint_list))
71 rospy.loginfo(
'using following joint for {} chain'.format(
'head'))
72 rospy.loginfo(
'... {}'.format(self.head_joint_list))
85 except Exception
as e:
105 rospy.logfatal(
'could not find valid link name ... {}'.format(link))
106 rospy.logfatal(
'use {0} from one of following names {1}'.format(option, map(
lambda x: x.name, self.robot.links)))
107 f = open(
'/tmp/{0}.xml'.format(self.
robot_name),
'w+')
110 rospy.logfatal(
'try \'urdf_to_graphiz /tmp/{}.xml\'.'.format(self.
robot_name))
114 rospy.logfatal(
'could not find valid joint name ... {}'.format(joint))
115 rospy.logfatal(
'use {0} from one of following names {1}'.format(option, map(
lambda x: x.name, self.robot.joints)))
116 f = open(
'/tmp/{0}.xml'.format(self.
robot_name),
'w+')
119 rospy.logfatal(
'try \'urdf_to_graphiz /tmp/{}.xml\'.'.format(self.
robot_name))
124 f = open(file_name,
'w+')
127 <include file="$(find calibration_launch)/capture_data/chain_settler.launch" ns="arm_chain" /> 128 <include file="$(find calibration_launch)/capture_data/chain_settler.launch" ns="head_chain" /> 130 <arg name="use_kinect" default="{0}" /> 131 <group if="$(arg use_kinect)" > 132 <include file="$(find calibration_launch)/capture_data/kinect_pipeline.launch" ns="{1}"> 133 <arg name="image_topic" value="image_rect_color"/> <!-- openni2.launch publishes image_raw and image_rect_color --> 134 <arg name="depth_topic" value="/camera/depth/image"/> <!-- this is floar value --> 135 <arg name="camera_info_topic" value="camera_info"/> 138 <group unless="$(arg use_kinect)" > 139 <include file="$(find calibration_launch)/capture_data/monocam_pipeline.launch" ns="{1}"> 140 <arg name="image_topic" value="image_rect_color"/> <!-- openni2.launch publishes image_raw and image_rect_color --> 144 <node type="interval_intersection_action" 145 pkg="interval_intersection" 146 name="interval_intersection" 148 <remap from="head_chain" to="head_chain/settled_interval" /> 149 <remap from="arm_chain" to="arm_chain/settled_interval" /> 150 <remap from="head_camera" to="{1}/settled_interval" /> 159 f = open(file_name,
'w+')
163 <!-- Hack to create the directory --> 164 <param name="mkdir_tmp" command="mkdir -m 777 -p /tmp/{0}_calibration" /> 165 <param name="mkdir_tmp" command="mkdir -m 777 -p /tmp/{0}_calibration/cb_fail" /> 167 <param name="{2}/annotated_viewer/filename_format" type="string" value="/tmp/{0}_calibration/cb_fail/cb_{1}_%04i.jpg" /> 169 <include file="$(find calibration_launch)/capture_data/annotated_viewer.launch" 171 <arg name="image_topic" value="image_rect_annotated" /> 180 f = open(file_name,
'w+')
183 <include file="$(find {0}_calibration)/capture_data/all_viewers.launch"/> 184 <include file="$(find {0}_calibration)/capture_data/all_pipelines.launch"/> 185 <include file="$(find {0}_calibration)/capture_data/capture_exec.launch"/> 191 f = open(file_name,
'w+')
195 <node type="capture_exec.py" 196 pkg="calibration_launch" 197 name="calibration_exec" 198 args="$(find {0}_calibration)/capture_data/samples/ $(find {0}_calibration)/capture_data/hardware_config $(find {0}_calibration)/estimate_params/config/system.yaml" 200 <remap from="head_camera/camera_info" to="{1}/camera_info"/> 201 <remap from="head_camera/image_rect" to="{1}/image_rect_throttle"/> 202 <remap from="head_camera/image" to="{1}/image_rect_throttle"/> 203 <remap from="head_camera/features" to="{1}/features"/> 206 <node type="urdf_pub.py" pkg="calibration_launch" name="urdf_pub"/> 208 <node type="record" pkg="rosbag" name="robot_measurement_recorder" output="screen" 209 args="-O /tmp/{0}_calibration/cal_measurements robot_measurement robot_description" > 210 <!-- Hack to create the directory --> 211 <param name="mkdir_tmp" command="mkdir -m 777 -p /tmp/{0}_calibration" /> 220 os.makedirs(config_dir)
221 except Exception
as e:
225 f = open(config_dir+
'/cam_config.yaml',
'w+')
227 # ----- Microsoft Kinect ----- 229 cb_detector_config: {0}/cb_detector_config ## FIXME 230 led_detector_config: {0}/led_detector 231 settler_config: {0}/monocam_settler_config ## FIXME 237 ignore_failures: True 247 subpixel_zero_zone: 1 254 f = open(config_dir+
'/chain_config.yaml',
'w+')
255 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
256 if len(joint_list) == 0:
259 f.write(
'# ----- {} -----\n'.format(limb))
260 f.write(
'{}_chain:\n'.format(limb))
261 f.write(
' settler_config: /{}_chain/settler_config\n\n'.format(limb))
262 f.write(
' configs:\n')
263 f.write(
' tight_tol:\n')
264 f.write(
' settler:\n')
265 f.write(
' joint_names:\n')
267 f.write(
' - {}\n'.format(j))
268 f.write(
' tolerances:\n')
270 f.write(
' - {}\n'.format(tolerance))
271 f.write(
' max_step: 1.0\n')
272 f.write(
' cache_size: 1500\n\n')
276 f = open(config_dir+
'/controller_config.yaml',
'w+')
277 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
278 if len(joint_list) == 0:
280 f.write(
'{}_controller:\n'.format(limb))
281 exec(
'controller = self.{}_controller'.format(limb))
282 rospy.loginfo(
'Subscribing controller topic is \'{}\''.format(controller))
283 f.write(
' topic: {0}\n'.format(controller))
284 f.write(
' joint_names:\n')
286 f.write(
' - {}\n'.format(j))
290 f = open(config_dir+
'/laser_config.yaml',
'w+')
291 f.write(
'# laser config')
297 os.makedirs(samples_dir+
'/arm')
298 except Exception
as e:
300 f = open(samples_dir+
'/arm/config.yaml',
'w+')
303 prompt: "Please put the checkerboard in the hand (open/close the gripper with the joystick's square/circle buttons)." 304 finish: "Skipping arm samples" 309 f = open(samples_dir+
'/../make_samples.py',
'w+')
310 os.chmod(samples_dir+
'/../make_samples.py', 0744)
311 f.write(
"""#!/usr/bin/env python 313 # capture samples!!!!1!one 315 # this script should eventually be replaced by something that finds 316 # samples automatically 319 from sensor_msgs.msg import JointState 323 header1 = \"\"\"camera_measurements: 324 - {cam_id: head_camera, config: small_cb_4x5} 328 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
329 if len(joint_list) == 0:
332 header2_{0} = \"\"\"- controller: {0}_controller 338 header3 = \"\"\"joint_measurements: 340 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
341 if len(joint_list) == 0:
343 f.write(
'- {{chain_id: {0}_chain, config: tight_tol}}\n'.format(limb))
345 sample_id: arm_\"\"\" 347 header4 = \"\"\"target: {chain_id: arm_chain, target_id: small_cb_4x5}\"\"\" 352 rospy.init_node("make_samples") 353 rospy.Subscriber("joint_states", JointState, self.callback) 355 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
356 if len(joint_list) == 0:
358 f.write(
' self.{}_joints = ['.format(limb))
360 f.write(
'\"{}\", '.format(j))
362 f.write(
' self.{0}_state = [0.0 for joint in self.{0}_joints]\n'.format(limb))
366 while not rospy.is_shutdown(): 367 print "Move arm/head to a new sample position." 368 resp = raw_input("press <enter> ") 369 if string.upper(resp) == "EXIT": 373 count = str(self.count).zfill(4) 374 f = open(os.path.dirname(__file__)+"/samples/arm/arm_"+count+".yaml", "w") 377 f.write(
""" print('saving ... {0}'.format(self.count))\n""")
378 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
379 if len(joint_list) == 0:
381 f.write(
""" print(' {0}_state: {{0}}'.format(self.{0}_state))\n""".format(limb))
384 print>>f, self.{0}_state 392 def callback(self, msg): 394 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
395 if len(joint_list) == 0:
398 for i in range(len(self.{0}_joints)): 400 idx = msg.name.index(self.{0}_joints[i]) 401 self.{0}_state[i] = msg.position[idx] 407 if __name__=="__main__": 414 f = open(file_name,
'w+')
418 <group ns="calibration_config" clear_params="true"> 419 <rosparam file="$(find {0}_calibration)/estimate_params/config/system.yaml" command="load" /> 421 <group ns="cal_steps"> 423 <group ns="{0} - 00 - Estimating Checkerboard Locations"> 424 <param name="free_params" textfile="$(find {0}_calibration)/estimate_params/config/free_cb_locations.yaml" /> 425 <param name="use_cov" type="bool" value="False" /> 431 <param name="output_filename" type="string" value="config_0" /> 434 <group ns="{0} - 01 - Adding Camera Locations"> 435 <param name="free_params" textfile="$(find {0}_calibration)/estimate_params/config/free_cameras.yaml" /> 436 <param name="use_cov" type="bool" value="True" /> 442 <param name="output_filename" type="string" value="system_calibrated" /> 454 f = open(file_name,
'w+')
455 os.chmod(file_name, 0744)
456 f.write(
"""#! /bin/bash 458 if [ -f robot_calibrated.xml ]; then 459 echo "./robot_calibrated.xml already exists. Either back up this file or remove it before continuing" 463 echo "Checking if we can write to ./robot_calibrated.xml..." 464 touch robot_calibrated.xml 465 if [ "$?" -ne "0" ]; then 466 echo "Not able to write to ./robot_calibrated.xml" 467 echo "Make sure you run this script from a directory that for which you have write permissions." 470 rm robot_calibrated.xml 473 roslaunch {0}_calibration estimation_config.launch 474 rosrun calibration_estimation multi_step_cov_estimator.py /tmp/{0}_calibration/cal_measurements.bag /tmp/{0}_calibration __name:=cal_cov_estimator 478 if [ "$est_return_val" -ne "0" ]; then 479 echo "Estimator exited prematurely with error code [$est_return_val]" 483 # Make all the temporary files writable 484 chmod ag+w /tmp/{0}_calibration/* 491 os.makedirs(config_dir)
492 except Exception
as e:
496 f = open(config_dir+
'/free_arms.yaml',
'w+')
498 f.write(
' transforms:\n')
499 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
500 if len(joint_list) == 0:
503 f.write(
' {0}: [ 0, 0, 0, {1}, {2}, {3} ]\n'.format(self.robot.joint_map[j].name, self.robot.joint_map[j].axis[0], self.robot.joint_map[j].axis[1], self.robot.joint_map[j].axis[2]))
505 f.write(
' chains:\n')
506 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
507 if len(joint_list) == 0:
509 f.write(
' {}_chain:\n'.format(limb))
510 f.write(
' gearing: {}\n'.format([0]*len(joint_list)))
530 f = open(config_dir+
'/free_cameras.yaml',
'w+')
533 arm_chain_cb: [1, 1, 1, 1, 1, 1] 534 {0}: [1, 1, 1, 1, 1, 1] 538 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
539 if len(joint_list) == 0:
541 f.write(
' {}_chain:\n'.format(limb))
542 f.write(
' gearing: {}\n'.format([0]*len(joint_list)))
562 f = open(config_dir+
'/free_cb_locations.yaml',
'w+')
565 arm_chain_cb: [1, 1, 1, 1, 1, 1] 569 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
570 if len(joint_list) == 0:
572 f.write(
' {}_chain:\n'.format(limb))
573 f.write(
' gearing: {}\n'.format([0]*len(joint_list)))
593 f = open(config_dir+
'/free_torso.yaml',
'w+')
596 head_joint: [0, 0, 1, 0, 0, 0] 600 for limb, joint_list
in zip([
'arm',
'head'], [self.arm_joint_list, self.head_joint_list]):
601 if len(joint_list) == 0:
603 f.write(
' {}_chain:\n'.format(limb))
604 f.write(
' gearing: {}\n'.format([0]*len(joint_list)))
623 f = open(config_dir+
'/system.yaml',
'w+')
625 f.write(
'base_link: {0}\n'.format(self.
base_link))
627 f.write(
'sensors:\n')
629 f.write(
' chains:\n')
630 if len(self.arm_joint_list) > 0:
631 f.write(
' arm_chain:\n')
635 f.write(
' joint_angles: {}\n'.format([0.01]*len(self.arm_joint_list)))
636 f.write(
' gearing: {}\n'.format([1.0]*len(self.arm_joint_list)))
637 if len(self.head_joint_list) > 0:
638 f.write(
' head_chain:\n')
642 f.write(
' joint_angles: {}\n'.format([0.01]*len(self.head_joint_list)))
643 f.write(
' gearing: {}\n'.format([1.0]*len(self.head_joint_list)))
645 f.write(
' rectified_cams:\n')
646 f.write(
' head_camera:\n')
647 f.write(
' chain_id: head_chain #TODO: get rid of this\n')
649 f.write(
' baseline_shift: 0.0\n')
651 f.write(
' baseline_rgbd: 0.075\n')
653 f.write(
'# baseline_rgbd: 0.075 ## comment out if we run all_pipelines.launch with use_kinect\n')
654 f.write(
' f_shift: 0.0\n')
655 f.write(
' cx_shift: 0.0\n')
656 f.write(
' cy_shift: 0.0\n')
657 f.write(
' cov: {u: 0.25, v: 0.25, x: 0.25}\n')
659 f.write(
' tilting_lasers: {}\n')
661 f.write(
'checkerboards:\n')
662 f.write(
' small_cb_4x5:\n')
663 f.write(
' corners_x: 4\n')
664 f.write(
' corners_y: 5\n')
665 f.write(
' spacing_x: 0.0245\n')
666 f.write(
' spacing_y: 0.0245\n')
668 f.write(
'transforms:\n')
669 f.write(
' arm_chain_cb: [ .25, 0, 0, pi/2, 0, 0]\n')
674 f = open(file_name,
'w+')
675 f.write(
'- name: "Head Camera: Arm"\n')
676 f.write(
' 3d: arm_chain\n')
677 f.write(
' cam: head_camera\n')
678 f.write(
' plot_ops:\n')
679 f.write(
' color: g\n')
680 f.write(
' marker: s\n')
684 f = open(file_name,
'w+')
685 os.chmod(file_name, 0744)
686 f.write(
"""#!/bin/bash 687 rosrun calibration_estimation error_visualization.py /tmp/{0}_calibration/cal_measurements.bag /tmp/{0}_calibration/ `rospack find {0}_calibration`/view_results/scatter_config.yaml\n""".format(self.
robot_name))
691 if __name__ ==
'__main__':
692 parser = argparse.ArgumentParser(description=
'Calibration setup helper.')
693 parser.add_argument(
'robot_description', type=file, default=
False, nargs=
'?', help=
'path to urdf file')
694 parser.add_argument(
'--use-kinect', action=
'store_const', const=
True, default=
False, help=
'use kinect for calibraiton')
695 parser.add_argument(
'--base-link', help=
'base link name')
696 parser.add_argument(
'--arm-root-link', help=
'arm root link name')
697 parser.add_argument(
'--arm-tip-link', help=
'arm tip link name')
698 parser.add_argument(
'--head-root-link', help=
'head root link name')
699 parser.add_argument(
'--head-tip-link', help=
'head tip link name')
700 parser.add_argument(
'--arm-controller', help=
'arm controller name', default=
'arm_controller/command')
701 parser.add_argument(
'--head-controller', help=
'head controller name', default=
'head_controller/command')
702 parser.add_argument(
'--head-camera-frame', help=
'frame name for target camera', default=
'camera_rgb_optical_frame')
703 parser.add_argument(
'--head-camera-joint', help=
'joint between head and camera', default=
'camera_rgb_joint')
704 parser.add_argument(
'--camera-namespace', help=
'namespace for camera', default=
'/camera/rgb')
705 args = parser.parse_args()
707 if args.arm_root_link ==
None:
708 args.arm_root_link = args.base_link
709 if args.head_root_link ==
None:
710 args.head_root_link = args.base_link
712 rospy.init_node(
"claibration_setup_helper", anonymous=
True)
714 write_upload_launch =
False 716 if args.robot_description:
717 robot_description = args.robot_description.read()
718 write_upload_launch =
True 720 robot_description = rospy.get_param(
'robot_description')
722 rospy.logfatal(
'robot_description not set, exiting')
725 helper =
CalibrationSetupHelper(robot_description, args.base_link, args.arm_root_link, args.arm_tip_link, args.head_root_link, args.head_tip_link, args.arm_controller, args.head_controller, args.head_camera_frame, args.head_camera_joint, args.camera_namespace)
727 f = open(helper.dirname_top+
'/package.xml',
'w+')
730 <name>{robot_name}_calibration</name> 731 <version>0.2.0</version> 733 Launch and configuration files for calibrating {robot_name} using the new generic 'calibration' stack. 734 THIS FILE IS AUTOMATICALLY GENERATED BY: 737 <author>Calibration Setup Helper</author> 738 <maintainer email="kei.okada@gmail.com">Calibration Setup Helper</maintainer> 740 <license>BSD</license> 741 <url>http://ros.org/wiki/{robot_name}_calibration</url> 743 <buildtool_depend>catkin</buildtool_depend> 745 <run_depend>calibration_launch</run_depend> 746 <run_depend>calibration_estimation</run_depend> 747 <run_depend>kdl</run_depend> 748 <run_depend>kdl_parser</run_depend>--> 750 """.format(robot_name=helper.robot_name, command=
' '.join(sys.argv)))
753 f = open(helper.dirname_top+
'/CMakeLists.txt',
'w+')
755 cmake_minimum_required(VERSION 2.8.3) 756 project({0}_calibration) 761 install(DIRECTORY capture_data estimate_params # view_results 762 DESTINATION ${{CATKIN_PACKAGE_SHARE_DESTINATION}} 763 USE_SOURCE_PERMISSIONS 766 """.format(helper.robot_name))
769 if write_upload_launch:
770 f = open(helper.dirname_top+
'/upload_urdf.launch',
'w+')
773 <arg name="model" default="{}" /> 774 <!-- send maxwell urdf to param server --> 775 <param name="robot_description" textfile="$(arg model)" /> 778 """.format(args.robot_description.name))
def __init__(self, robot_description, base_link, arm_root_link, arm_tip_link, head_root_link, head_tip_link, arm_controller, head_controller, head_camera_frame, head_camera_joint, camera_namespace)
def write_view_results(self)
def write_estimate_params_config(self, use_kinect=False)
def write_calibrate_sh(self)
def write_hardware_config(self)
def write_make_samples(self)
def error_joint(self, joint, option)
def write_all_pipelines(self, use_kinect)
def write_estimation_config(self)
def write_capture_data(self)
def write_all_viewers(self, use_kinect)
def write_capture_exec(self)
def error_tip_link(self, link, option)