00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 from __future__ import division
00043 import roslib; roslib.load_manifest('pr2_gripper_reactive_approach')
00044 import random, time
00045 import rospy
00046 import tf
00047 from geometry_msgs.msg import PoseStamped, Pose, Point, Quaternion, PointStamped, Vector3Stamped
00048 from pr2_mechanism_msgs.srv import SwitchController, LoadController, UnloadController, ListControllers
00049 import actionlib
00050 from pr2_controllers_msgs.msg import JointTrajectoryAction, JointTrajectoryGoal, \
00051 Pr2GripperCommandGoal, Pr2GripperCommandAction
00052 from pr2_gripper_sensor_msgs.msg import PR2GripperFindContactAction, PR2GripperFindContactGoal, \
00053 PR2GripperGrabAction, PR2GripperGrabGoal, PR2GripperEventDetectorAction, PR2GripperEventDetectorGoal
00054 from trajectory_msgs.msg import JointTrajectoryPoint
00055 from pr2_manipulation_controllers.srv import CheckMoving, MoveToPose, MoveToPoseRequest
00056 from std_srvs.srv import Empty, EmptyRequest
00057 from arm_navigation_msgs.msg import MoveArmAction, MoveArmGoal
00058 from arm_navigation_msgs.msg import JointConstraint, PositionConstraint, OrientationConstraint, \
00059 ArmNavigationErrorCodes, AllowedContactSpecification
00060 from arm_navigation_msgs.msg import Shape
00061 from tabletop_collision_map_processing import collision_map_interface
00062 import numpy
00063 import math
00064 import pdb
00065 import copy
00066 from interpolated_ik_motion_planner import ik_utilities
00067 from object_manipulator.convert_functions import *
00068 import joint_states_listener
00069 from actionlib_msgs.msg import GoalStatus
00070 from tf_conversions import posemath
00071 from pr2_gripper_reactive_approach.controller_params import *
00072 import threading
00073 import scipy.linalg
00074
00075
00076 class ControllerManager():
00077
00078
00079 def __init__(self, whicharm, tf_listener = None, using_slip_controller = 0, using_slip_detection = 0):
00080 self.whicharm = whicharm
00081
00082 self.using_slip_controller = using_slip_controller
00083 self.using_slip_detection = using_slip_detection
00084
00085 rospy.loginfo("initializing "+whicharm+" controller manager")
00086 rospy.loginfo("controller manager: using_slip_controller:"+str(using_slip_controller))
00087 rospy.loginfo("controller manager: using_slip_detection:"+str(using_slip_detection))
00088
00089
00090 rospy.loginfo("controller manager waiting for pr2_controller_manager services to be there")
00091 load_controller_serv_name = 'pr2_controller_manager/load_controller'
00092 unload_controller_serv_name = 'pr2_controller_manager/unload_controller'
00093 switch_controller_serv_name = 'pr2_controller_manager/switch_controller'
00094 list_controllers_serv_name = 'pr2_controller_manager/list_controllers'
00095 self.wait_for_service(load_controller_serv_name)
00096 self.wait_for_service(unload_controller_serv_name)
00097 self.wait_for_service(switch_controller_serv_name)
00098 self.wait_for_service(list_controllers_serv_name)
00099 self.load_controller_service = \
00100 rospy.ServiceProxy(load_controller_serv_name, LoadController)
00101 self.unload_controller_service = \
00102 rospy.ServiceProxy(unload_controller_serv_name, UnloadController)
00103 self.switch_controller_service = \
00104 rospy.ServiceProxy(switch_controller_serv_name, SwitchController)
00105 self.list_controllers_service = \
00106 rospy.ServiceProxy(list_controllers_serv_name, ListControllers)
00107
00108
00109 self.joint_states_listener = joint_states_listener.LatestJointStates()
00110
00111
00112 joint_trajectory_action_name = whicharm+'_arm_controller/joint_trajectory_action'
00113 self.joint_action_client = \
00114 actionlib.SimpleActionClient(joint_trajectory_action_name, JointTrajectoryAction)
00115
00116
00117 if self.using_slip_controller:
00118 gripper_action_name = whicharm+'_gripper_sensor_controller/gripper_action'
00119 self.gripper_action_client = actionlib.SimpleActionClient(gripper_action_name, Pr2GripperCommandAction)
00120
00121
00122 else:
00123 gripper_action_name = whicharm+'_gripper_controller/gripper_action'
00124 self.gripper_action_client = \
00125 actionlib.SimpleActionClient(gripper_action_name, Pr2GripperCommandAction)
00126
00127
00128 if self.using_slip_detection:
00129 gripper_find_contact_action_name = whicharm+'_gripper_sensor_controller/find_contact'
00130 gripper_grab_action_name = whicharm+'_gripper_sensor_controller/grab'
00131 gripper_event_detector_action_name = whicharm+'_gripper_sensor_controller/event_detector'
00132
00133 self.gripper_find_contact_action_client = actionlib.SimpleActionClient(gripper_find_contact_action_name, \
00134 PR2GripperFindContactAction)
00135 self.gripper_grab_action_client = actionlib.SimpleActionClient(gripper_grab_action_name, \
00136 PR2GripperGrabAction)
00137 self.gripper_event_detector_action_client = actionlib.SimpleActionClient(gripper_event_detector_action_name, \
00138 PR2GripperEventDetectorAction)
00139
00140
00141 self.move_arm_client = None
00142
00143
00144 self.wait_for_action_server(self.joint_action_client, joint_trajectory_action_name)
00145 self.wait_for_action_server(self.gripper_action_client, gripper_action_name)
00146 if self.using_slip_detection:
00147 self.wait_for_action_server(self.gripper_find_contact_action_client, gripper_find_contact_action_name)
00148 self.wait_for_action_server(self.gripper_grab_action_client, gripper_grab_action_name)
00149 self.wait_for_action_server(self.gripper_event_detector_action_client, gripper_event_detector_action_name)
00150
00151
00152 if tf_listener == None:
00153 self.tf_listener = tf.TransformListener()
00154 else:
00155 self.tf_listener = tf_listener
00156
00157
00158 self.collision_map_interface = collision_map_interface.CollisionMapInterface()
00159
00160
00161 self.use_trajectory_cartesian = rospy.get_param('~use_trajectory_cartesian', 0)
00162 self.use_task_cartesian = rospy.get_param('~use_task_cartesian', 0)
00163 if self.use_trajectory_cartesian and self.use_task_cartesian:
00164 rospy.loginfo("can't use both trajectory and task controllers! Defaulting to task")
00165 self.use_trajectory_cartesian = 0
00166 rospy.loginfo("controller_manager: use_trajectory_cartesian: "+str(self.use_trajectory_cartesian))
00167 rospy.loginfo("controller_manager: use_task_cartesian: "+str(self.use_task_cartesian))
00168
00169
00170 if self.use_trajectory_cartesian:
00171 self.cartesian_controllers = ['_arm_cartesian_pose_controller',
00172 '_arm_cartesian_trajectory_controller']
00173 self.cartesian_controllers = [self.whicharm+x for x in self.cartesian_controllers]
00174 else:
00175 self.cartesian_controllers = [self.whicharm + '_cart']
00176 self.joint_controller = self.whicharm+'_arm_controller'
00177 if self.using_slip_controller:
00178 self.gripper_controller = self.whicharm+'_gripper_sensor_controller'
00179 else:
00180 self.gripper_controller = self.whicharm+'_gripper_controller'
00181
00182
00183 if self.use_trajectory_cartesian:
00184 self.cart_params = JTCartesianParams(self.whicharm)
00185 else:
00186 self.cart_params = JTCartesianTaskParams(self.whicharm, self.use_task_cartesian)
00187
00188
00189 self.joint_params = JointParams(self.whicharm)
00190
00191
00192 rospy.loginfo("loading any unloaded Cartesian controllers")
00193 self.load_cartesian_controllers()
00194 time.sleep(2)
00195 rospy.loginfo("done loading controllers")
00196
00197
00198 if self.use_trajectory_cartesian:
00199 cartesian_check_moving_name = whicharm+'_arm_cartesian_trajectory_controller/check_moving'
00200 cartesian_move_to_name = whicharm+'_arm_cartesian_trajectory_controller/move_to'
00201 cartesian_preempt_name = whicharm+'_arm_cartesian_trajectory_controller/preempt'
00202 self.wait_for_service(cartesian_check_moving_name)
00203 self.wait_for_service(cartesian_move_to_name)
00204 self.wait_for_service(cartesian_preempt_name)
00205 self.cartesian_moving_service = rospy.ServiceProxy(cartesian_check_moving_name, CheckMoving)
00206 self.cartesian_cmd_service = rospy.ServiceProxy(cartesian_move_to_name, MoveToPose)
00207 self.cartesian_preempt_service = rospy.ServiceProxy(cartesian_preempt_name, Empty)
00208
00209
00210 self.cart_params.set_params_to_gentle()
00211 self.reload_cartesian_controllers()
00212 else:
00213 cartesian_cmd_name = whicharm+'_cart/command_pose'
00214 self.cartesian_cmd_pub = rospy.Publisher(cartesian_cmd_name, PoseStamped)
00215
00216
00217 rospy.loginfo("creating IKUtilities class objects")
00218 if whicharm == 'r':
00219 self.ik_utilities = ik_utilities.IKUtilities('right', self.tf_listener)
00220 else:
00221 self.ik_utilities = ik_utilities.IKUtilities('left', self.tf_listener)
00222 rospy.loginfo("done creating IKUtilities class objects")
00223
00224
00225 joint_names = ["_shoulder_pan_joint",
00226 "_shoulder_lift_joint",
00227 "_upper_arm_roll_joint",
00228 "_elbow_flex_joint",
00229 "_forearm_roll_joint",
00230 "_wrist_flex_joint",
00231 "_wrist_roll_joint"]
00232 self.joint_names = [whicharm + x for x in joint_names]
00233
00234
00235 if not self.use_trajectory_cartesian:
00236 self.dist_tol = .001
00237 self.angle_tol = .05
00238 self.overshoot_dist = 0.005
00239 self.overshoot_angle = 0.087
00240 self.timestep = 1./30.
00241 self.cartesian_command_lock = threading.Lock()
00242 self.cartesian_command_thread_running = False
00243 self.cartesian_desired_pose = self.get_current_wrist_pose_stamped('/base_link')
00244 self.cartesian_command_thread = threading.Thread(target=self.cartesian_command_thread_func)
00245 self.cartesian_command_thread.setDaemon(True)
00246 self.cartesian_command_thread.start()
00247
00248 rospy.loginfo("done with controller_manager init for the %s arm"%whicharm)
00249
00250
00251
00252 def wait_for_action_server(self, client, name):
00253 while not rospy.is_shutdown():
00254 rospy.loginfo("controller manager: waiting for %s to be there"%name)
00255 if client.wait_for_server(rospy.Duration(5.0)):
00256 break
00257 rospy.loginfo("controller manager: %s found"%name)
00258
00259
00260
00261 def wait_for_service(self, name):
00262 while not rospy.is_shutdown():
00263 rospy.loginfo("controller manager: waiting for %s to be there"%name)
00264 try:
00265 rospy.wait_for_service(name, 5.0)
00266 except rospy.ROSException:
00267 continue
00268 break
00269 rospy.loginfo("controller manager: %s found"%name)
00270
00271
00272
00273
00274 def find_gripper_contact(self, contacts_desired, zero_fingertips = 0, blocking = 1, timeout = 12.):
00275
00276 goal = PR2GripperFindContactGoal()
00277 contacts_desired_dict = {"both":goal.command.BOTH, "left":goal.command.LEFT, "right":goal.command.RIGHT, "either":goal.command.EITHER}
00278
00279 goal.command.contact_conditions = contacts_desired_dict[contacts_desired]
00280 goal.command.zero_fingertip_sensors = zero_fingertips
00281
00282 rospy.loginfo("controller manager: sending find contact goal")
00283 self.gripper_find_contact_action_client.send_goal(goal)
00284
00285
00286 if blocking:
00287 finished_within_time = self.gripper_find_contact_action_client.wait_for_result(rospy.Duration(timeout))
00288 if not finished_within_time:
00289 self.gripper_find_contact_action_client.cancel_goal()
00290 rospy.logerr("Gripper didn't see the desired number of contacts while closing in time")
00291 return (0, 0, 0, 0)
00292 state = self.gripper_find_contact_action_client.get_state()
00293 if state == GoalStatus.SUCCEEDED:
00294 result = self.gripper_find_contact_action_client.get_result()
00295 return (result.data.left_fingertip_pad_contact, result.data.right_fingertip_pad_contact, \
00296 result.data.left_fingertip_pad_contact_force, result.data.right_fingertip_pad_contact_force)
00297 return (0,0,0,0)
00298
00299
00300
00301 def get_find_gripper_contact_state(self):
00302 return self.gripper_find_contact_action_client.get_state()
00303
00304
00305
00306 def get_find_gripper_contact_result(self):
00307 result = self.gripper_find_contact_action_client.get_result()
00308 if result:
00309 return (result.data.left_fingertip_pad_contact, result.data.right_fingertip_pad_contact, \
00310 result.data.left_fingertip_pad_force, result.data.right_fingertip_pad_force)
00311 else:
00312 rospy.logerr("gripper_find_contact_action_client.get_result returned None!")
00313 return (0, 0, 0, 0)
00314
00315
00316
00317 def start_gripper_grab(self, hardness_gain = 0.035, timeout = 10., blocking = 1):
00318
00319 goal = PR2GripperGrabGoal()
00320 goal.command.hardness_gain = hardness_gain
00321
00322 rospy.loginfo("starting slip controller grab")
00323 self.gripper_grab_action_client.send_goal(goal)
00324
00325 if blocking:
00326 finished_within_time = self.gripper_grab_action_client.wait_for_result(rospy.Duration(timeout))
00327 if not finished_within_time:
00328 self.gripper_find_contact_action_client.cancel_goal()
00329 rospy.logerr("Gripper grab timed out")
00330 state = self.gripper_find_contact_action_client.get_state()
00331 if state == GoalStatus.SUCCEEDED:
00332 return 1
00333 return 0
00334
00335 return 1
00336
00337
00338
00339
00340 def start_gripper_event_detector(self, blocking = 0, timeout = 15.):
00341
00342 goal = PR2GripperEventDetectorGoal()
00343 goal.command.trigger_conditions = goal.command.FINGER_SIDE_IMPACT_OR_SLIP_OR_ACC
00344 goal.command.acceleration_trigger_magnitude = 3.25
00345 goal.command.slip_trigger_magnitude = 0.008
00346
00347 rospy.loginfo("starting gripper event detector")
00348 self.gripper_event_detector_action_client.send_goal(goal)
00349
00350
00351 if blocking:
00352 finished_within_time = self.gripper_event_detector_action_client.wait_for_result(rospy.Duration(timeout))
00353 if not finished_within_time:
00354 rospy.logerr("Gripper didn't see the desired event trigger before timing out")
00355 return 0
00356 state = self.gripper_event_detector_action_client.get_state()
00357 if state == GoalStatus.SUCCEEDED:
00358 result = self.gripper_event_detector_action_client.get_result()
00359 if result.data.placed:
00360 return 1
00361 return 0
00362
00363
00364
00365 def get_gripper_event_detector_state(self):
00366 return self.gripper_event_detector_action_client.get_state()
00367
00368
00369
00370 def create_move_arm_goal(self):
00371 goal = MoveArmGoal()
00372 if self.whicharm == "r":
00373 goal.motion_plan_request.group_name = "right_arm"
00374 else:
00375 goal.motion_plan_request.group_name = "left_arm"
00376 goal.motion_plan_request.num_planning_attempts = 2;
00377 goal.motion_plan_request.allowed_planning_time = rospy.Duration(5.0);
00378 goal.motion_plan_request.planner_id = ""
00379 goal.planner_service_name = "ompl_planning/plan_kinematic_path"
00380 return goal
00381
00382
00383
00384
00385 def send_move_arm_goal(self, goal, blocking = 1):
00386
00387
00388 if self.move_arm_client == None:
00389 if self.whicharm == "r":
00390 self.move_arm_client = actionlib.SimpleActionClient('move_right_arm', MoveArmAction)
00391 if self.whicharm == "l":
00392 self.move_arm_client = actionlib.SimpleActionClient('move_left_arm', MoveArmAction)
00393 rospy.loginfo("waiting for move arm server")
00394 self.move_arm_client.wait_for_server()
00395 rospy.loginfo("move arm server was there")
00396
00397
00398 self.move_arm_client.send_goal(goal)
00399
00400
00401 if blocking:
00402 for add_contact_tries in range(10):
00403 finished_within_time = self.move_arm_client.wait_for_result(rospy.Duration(60))
00404 if not finished_within_time:
00405 self.move_arm_client.cancel_goal()
00406 rospy.logerr("Timed out when asking move_arm to go to a joint goal")
00407 return 0
00408
00409 state = self.move_arm_client.get_state()
00410 result = self.move_arm_client.get_result()
00411 if state == GoalStatus.SUCCEEDED:
00412 if result.error_code.val == 1:
00413 rospy.loginfo("move_arm succeeded")
00414 break
00415
00416
00417 elif result.error_code.val == ArmNavigationErrorCodes.START_STATE_IN_COLLISION:
00418
00419
00420 rospy.loginfo("move arm start state in collision! Resetting the collision map and trying again, try number %d"%add_contact_tries)
00421 repopulate = True
00422 if add_contact_tries > 2:
00423 rospy.logerr("Not repopulating collision map, too many tries!")
00424 repopulate = False
00425 self.reset_collision_map(False, repopulate)
00426 self.move_arm_client.send_goal(goal)
00427 continue
00428 else:
00429 rospy.logerr("move_arm did not succeed, state %d, error code %d"%(state, result.error_code.val))
00430 break
00431 return result.error_code.val
00432 else:
00433 return 1
00434
00435
00436
00437 def reset_collision_map(self, clear_objects, repopulate):
00438 if clear_objects:
00439 self.collision_map_interface.reset_collision_map()
00440 else:
00441 self.collision_map_interface.clear_octomap()
00442 if repopulate:
00443 rospy.sleep(5.0)
00444
00445
00446
00447 def set_planning_scene(self):
00448 self.collision_map_interface.set_planning_scene()
00449
00450
00451
00452
00453 def move_arm_joint(self, joint_angles, blocking = 1):
00454 self.check_controllers_ok('joint')
00455 self.set_planning_scene()
00456
00457 rospy.loginfo("asking move_arm to go to angles: %s"%self.pplist(joint_angles))
00458
00459 goal = self.create_move_arm_goal()
00460
00461
00462
00463 for (joint_name, joint_angle) in zip(self.joint_names, joint_angles):
00464 joint_constraint = JointConstraint()
00465 joint_constraint.joint_name = joint_name
00466 joint_constraint.position = joint_angle
00467 joint_constraint.tolerance_below = .1
00468 joint_constraint.tolerance_above = .1
00469 goal.motion_plan_request.goal_constraints.joint_constraints.append(joint_constraint)
00470
00471
00472 result = self.send_move_arm_goal(goal, blocking)
00473 return result
00474
00475
00476
00477
00478 def modify_move_arm_goal(self, goal, contact_info):
00479 allowed_contacts = []
00480 allowed_penetration_depth = .5
00481 for (i, contact) in enumerate(contact_info):
00482 allowed_contact_tmp = AllowedContactSpecification()
00483 allowed_contact_tmp.shape.type = allowed_contact_tmp.shape.BOX
00484 allowed_contact_tmp.shape.dimensions = [allowed_penetration_depth]*3
00485 allowed_contact_tmp.pose_stamped.pose.position = contact.position
00486 set_xyzw(allowed_contact_tmp.pose_stamped.pose.orientation, [0,0,0,1])
00487 allowed_contact_tmp.pose_stamped.header.stamp = rospy.Time.now()
00488 allowed_contact_tmp.pose_stamped.header.frame_id = contact.header.frame_id
00489 allowed_contact_tmp.link_names.append(contact.contact_body_1)
00490 allowed_contact_tmp.penetration_depth = allowed_penetration_depth
00491 allowed_contacts.append(allowed_contact_tmp);
00492 rospy.loginfo("Added allowed contact region: %d"%i)
00493
00494
00495
00496 rospy.loginfo("Bodies : %s and %s"%(contact.contact_body_1, contact.contact_body_2))
00497 goal.motion_plan_request.allowed_contacts.extend(allowed_contacts)
00498
00499
00500
00501
00502
00503
00504 def move_arm_constrained(self, constraint_in = None, start_angles = None, location = None, blocking = 1, compute_feasible_goal = True, frame_id = 'torso_lift_link'):
00505
00506
00507 self.set_planning_scene()
00508
00509 self.check_controllers_ok('joint')
00510 current_pose = self.get_current_wrist_pose_stamped(frame_id)
00511 move_arm_goal = self.create_move_arm_goal()
00512 if move_arm_goal.motion_plan_request.group_name == "right_arm":
00513 move_arm_goal.motion_plan_request.group_name = "right_arm_cartesian"
00514 if move_arm_goal.motion_plan_request.group_name == "left_arm":
00515 move_arm_goal.motion_plan_request.group_name = "left_arm_cartesian"
00516
00517
00518 position_constraint = PositionConstraint()
00519 position_constraint.header.frame_id = frame_id
00520 position_constraint.link_name = self.ik_utilities.link_name
00521 set_xyz(position_constraint.position, location)
00522 position_constraint.constraint_region_shape.type = Shape.BOX
00523 position_constraint.constraint_region_shape.dimensions = [0.02]*3
00524 position_constraint.constraint_region_orientation.w = 1.0
00525 position_constraint.weight = 1.0
00526 move_arm_goal.motion_plan_request.goal_constraints.position_constraints.append(position_constraint)
00527
00528 orientation_constraint = copy.deepcopy(constraint_in.orientation_constraints[0])
00529
00530
00531
00532 if compute_feasible_goal == True:
00533 current_pose_mat = pose_to_mat(current_pose.pose)
00534 found_ik_solution = 0
00535 for angle in range(0, 180, 5):
00536 for dir in [1, -1]:
00537 rot_mat = tf.transformations.rotation_matrix(dir*angle/180.*math.pi, [0,0,1])
00538 rotated_pose_mat = rot_mat * current_pose_mat
00539 desired_pose = stamp_pose(mat_to_pose(rotated_pose_mat), frame_id)
00540 desired_pose.pose.position = position_constraint.position
00541
00542
00543 (solution, error_code) = self.ik_utilities.run_ik(desired_pose, start_angles, \
00544 self.ik_utilities.link_name, collision_aware = 1)
00545 if error_code == "SUCCESS":
00546 found_ik_solution = 1
00547
00548 rospy.loginfo("IK solution found for constrained goal")
00549 orientation_constraint.orientation = desired_pose.pose.orientation
00550 break
00551
00552 if found_ik_solution:
00553 break
00554 else:
00555 rospy.loginfo("no IK solution found for goal, aborting")
00556 return 0
00557
00558 move_arm_goal.motion_plan_request.goal_constraints.orientation_constraints.append(orientation_constraint)
00559
00560
00561 joint_constraint = JointConstraint()
00562 if move_arm_goal.motion_plan_request.group_name == "right_arm_cartesian":
00563 joint_constraint.joint_name = "r_upper_arm_roll_joint"
00564 if move_arm_goal.motion_plan_request.group_name == "left_arm_cartesian":
00565 joint_constraint.joint_name = "l_upper_arm_roll_joint"
00566 joint_constraint.position = solution[2]
00567 joint_constraint.tolerance_below = .1
00568 joint_constraint.tolerance_above = .1
00569 move_arm_goal.motion_plan_request.goal_constraints.joint_constraints.append(joint_constraint)
00570
00571
00572 path_orientation_constraint = copy.deepcopy(orientation_constraint)
00573
00574
00575 path_orientation_constraint.header.stamp = rospy.Time(orientation_constraint.header.stamp.secs)
00576 path_orientation_constraint.orientation = current_pose.pose.orientation
00577 move_arm_goal.motion_plan_request.path_constraints.orientation_constraints.append(path_orientation_constraint)
00578
00579 move_arm_goal.motion_plan_request.planner_id = "SBLkConfig1"
00580 move_arm_goal.disable_ik = True
00581 move_arm_goal.planner_service_name= "/ompl_planning/plan_kinematic_path/"
00582
00583
00584 result = self.send_move_arm_goal(move_arm_goal, blocking)
00585 return result
00586
00587
00588
00589
00590 def move_arm_pose(self, pose_stamped, start_angles = None, blocking = 1):
00591
00592
00593 self.set_planning_scene()
00594
00595 if start_angles == None:
00596 start_angles = self.get_current_arm_angles()
00597 (solution, error_code) = self.ik_utilities.run_ik(pose_stamped, start_angles, \
00598 self.ik_utilities.link_name)
00599 if not solution:
00600 rospy.logerr("no IK solution found for goal pose!")
00601 return 0
00602 else:
00603 result = self.move_arm_joint(solution, blocking)
00604 return result
00605
00606
00607
00608
00609 def normalize_trajectory(self, trajectory):
00610 current_angles = self.get_current_arm_angles()
00611 trajectory_copy = [list(angles) for angles in trajectory]
00612 for angles in trajectory_copy:
00613 angles[4] = self.normalize_angle(angles[4], current_angles[4])
00614 angles[6] = self.normalize_angle(angles[6], current_angles[6])
00615 return trajectory_copy
00616
00617
00618
00619
00620 def normalize_angle(self, angle, current_angle):
00621 while current_angle-angle > math.pi:
00622 angle += 2*math.pi
00623 while angle - current_angle > math.pi:
00624 angle -= 2*math.pi
00625 return angle
00626
00627
00628
00629
00630 def command_interpolated_ik(self, end_pose, start_pose = None, collision_aware = 1, step_size = .02, max_joint_vel = .05):
00631 self.check_controllers_ok('joint')
00632
00633
00634 current_angles = self.get_current_arm_angles()
00635
00636 if start_pose == None:
00637
00638 (current_trans, current_rot) = self.return_cartesian_pose()
00639
00640
00641 start_pose = create_pose_stamped(current_trans+current_rot)
00642
00643
00644
00645
00646 self.set_planning_scene()
00647
00648
00649
00650 (trajectory, error_codes) = self.ik_utilities.check_cartesian_path(start_pose, \
00651 end_pose, current_angles, step_size, .1, math.pi/4, collision_aware)
00652
00653
00654 if any(error_codes):
00655 rospy.loginfo("can't execute an interpolated IK trajectory to that pose")
00656 return 0
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 self.command_joint_trajectory(trajectory, max_joint_vel)
00668 return 1
00669
00670
00671
00672 def get_current_arm_angles(self):
00673 (found, positions, vels, efforts) = \
00674 self.joint_states_listener.return_joint_states(self.joint_names)
00675 return positions
00676
00677
00678
00679 def get_current_wrist_pose_stamped(self, frame = 'base_link'):
00680 (current_trans, current_rot) = self.return_cartesian_pose(frame)
00681 return create_pose_stamped(current_trans+current_rot, frame)
00682
00683
00684
00685 def get_current_gripper_opening(self):
00686 (found, positions, vels, efforts) = \
00687 self.joint_states_listener.return_joint_states([self.whicharm+'_gripper_joint'])
00688 return positions[0]
00689
00690
00691
00692 def clip_pose(self, pose, max_pos_dist = 0.02, max_rot_dist = math.pi/20., current_pose = None):
00693 if current_pose == None:
00694 current_pose = self.get_current_wrist_pose_stamped(pose.header.frame_id)
00695 current_mat = pose_to_mat(current_pose.pose)
00696 target_mat = pose_to_mat(pose.pose)
00697
00698 target_to_current = current_mat**-1 * target_mat
00699 desired_trans = target_to_current[0:3, 3].copy()
00700 desired_trans_mag = scipy.linalg.norm(desired_trans)
00701 target_to_current[0:3, 3] = 0
00702
00703 desired_angle, desired_axis, point = tf.transformations.rotation_from_matrix(target_to_current)
00704
00705 frac_trans = math.fabs(desired_trans_mag / max_pos_dist)
00706 frac_rot = math.fabs(desired_angle / max_rot_dist)
00707
00708 if frac_trans <= 1 and frac_rot <= 1:
00709 return pose
00710 frac = max(frac_rot, frac_trans)
00711
00712 clamped_angle = desired_angle / frac
00713 clamped_trans = desired_trans / frac
00714
00715 clamped_transformation = scipy.matrix(tf.transformations.rotation_matrix(clamped_angle, desired_axis))
00716 clamped_transformation[0:3, 3] = clamped_trans
00717 clamped_mat = current_mat * clamped_transformation
00718 clamped_pose = stamp_pose(mat_to_pose(clamped_mat), pose.header.frame_id)
00719 return clamped_pose
00720
00721
00722
00723 def overshoot_pose(self, desired_pose, overshoot_dist, overshoot_angle, dist_tol, angle_tol, current_pose = None):
00724 if current_pose == None:
00725 current_pose = self.get_current_wrist_pose_stamped(desired_pose.header.frame_id)
00726 current_mat = pose_to_mat(current_pose.pose)
00727 target_mat = pose_to_mat(desired_pose.pose)
00728
00729 target_to_current = current_mat**-1 * target_mat
00730 desired_trans = target_to_current[0:3, 3].copy()
00731 desired_trans_mag = scipy.linalg.norm(desired_trans)
00732 target_to_current[0:3, 3] = 0
00733
00734 desired_angle, desired_axis, point = tf.transformations.rotation_from_matrix(target_to_current)
00735
00736 if desired_trans_mag <= dist_tol and abs(desired_angle) <= angle_tol:
00737 return desired_pose
00738 pos_change = 0
00739 angle_change = 0
00740 if desired_trans_mag > dist_tol:
00741 pos_change = (desired_trans_mag + overshoot_dist)/desired_trans_mag * desired_trans
00742 if abs(desired_angle) > angle_tol:
00743 angle_sign = desired_angle / abs(desired_angle)
00744 angle_change = desired_angle + angle_sign*overshoot_angle
00745
00746 overshoot_transformation = scipy.matrix(tf.transformations.rotation_matrix(angle_change, desired_axis))
00747 overshoot_transformation[0:3, 3] = pos_change
00748 overshoot_mat = current_mat * overshoot_transformation
00749 overshoot_pose = stamp_pose(mat_to_pose(overshoot_mat), desired_pose.header.frame_id)
00750 return overshoot_pose
00751
00752
00753
00754 def cartesian_command_thread_func(self):
00755 r = rospy.Rate(1./self.timestep)
00756 while not rospy.is_shutdown():
00757 with self.cartesian_command_lock:
00758 running = self.cartesian_command_thread_running
00759 if running:
00760 self.cartesian_desired_pose.header.stamp = rospy.Time.now()
00761 with self.cartesian_command_lock:
00762 desired_pose = self.cartesian_desired_pose
00763 overshoot_dist = self.overshoot_dist
00764 overshoot_angle = self.overshoot_angle
00765 dist_tol = self.dist_tol
00766 angle_tol = self.angle_tol
00767
00768 current_pose = self.get_current_wrist_pose_stamped(desired_pose.header.frame_id)
00769
00770
00771 overshoot_pose = self.overshoot_pose(desired_pose, overshoot_dist, overshoot_angle,
00772 dist_tol, angle_tol, current_pose)
00773
00774
00775 clipped_pose = self.clip_pose(overshoot_pose, current_pose = current_pose)
00776
00777
00778 self.cartesian_cmd_pub.publish(clipped_pose)
00779 r.sleep()
00780
00781
00782
00783 def stop_cartesian_commands(self):
00784 if not self.use_trajectory_cartesian:
00785 with self.cartesian_command_lock:
00786 self.cartesian_command_thread_running = False
00787
00788
00789
00790 def start_cartesian_commands(self):
00791 if not self.use_trajectory_cartesian:
00792 with self.cartesian_command_lock:
00793 self.cartesian_command_thread_running = True
00794
00795
00796
00797 def set_desired_cartesian_to_current(self):
00798 if not self.use_trajectory_cartesian:
00799 current_pose = self.get_current_wrist_pose_stamped('/base_link')
00800 with self.cartesian_command_lock:
00801 self.cartesian_desired_pose = current_pose
00802
00803
00804
00805
00806
00807 def command_cartesian(self, pose, frame_id = '/base_link'):
00808 self.check_controllers_ok('cartesian')
00809
00810 if type(pose) == list:
00811 m = create_pose_stamped(pose, frame_id)
00812 else:
00813 m = pose
00814
00815 if self.use_trajectory_cartesian:
00816 req = MoveToPoseRequest()
00817 req.pose = m
00818 try:
00819 self.cartesian_preempt_service(EmptyRequest())
00820 except:
00821 rospy.loginfo("preempt unnecessary, robot not moving")
00822 else:
00823 rospy.loginfo("Cartesian movement preempted before issuing new command")
00824
00825 self.cartesian_cmd_service(req)
00826
00827 else:
00828 self.start_cartesian_commands()
00829 with self.cartesian_command_lock:
00830 self.cartesian_desired_pose = m
00831
00832
00833
00834 def check_cartesian_done(self):
00835 if self.use_trajectory_cartesian:
00836 resp = self.cartesian_moving_service()
00837 return resp.ismoving
00838 else:
00839 return 1
00840
00841
00842
00843
00844 def check_cartesian_near_pose(self, goal_pose, pos_thres, rot_thres):
00845 if type(goal_pose) == list:
00846 goal_pos = goal_pose[0:3]
00847 goal_rot = goal_pose[3:7]
00848 else:
00849 (goal_pos, goal_rot) = pose_stamped_to_lists(self.tf_listener, goal_pose, 'base_link')
00850
00851 (pos_dist, rot_dist) = self.dist_from_current_pos_and_rot(goal_pos, goal_rot)
00852 if pos_dist < pos_thres and rot_dist < rot_thres:
00853 return 1
00854 return 0
00855
00856
00857
00858 def dist_from_current_pos_and_rot(self, goal_pos, goal_rot, current_pos = None, current_rot = None):
00859
00860 if current_pos == None or current_rot == None:
00861 (current_pos, current_rot) = self.return_cartesian_pose()
00862
00863
00864 diff = [x-y for (x,y) in zip(goal_pos, current_pos)]
00865 pos_diff = self.ik_utilities.vect_norm(diff)
00866
00867
00868 norm_goal_rot = self.ik_utilities.normalize_vect(goal_rot)
00869 norm_current_rot = self.ik_utilities.normalize_vect(current_rot)
00870 rot_diff = self.ik_utilities.quat_angle(norm_current_rot, norm_goal_rot)
00871
00872
00873 return (pos_diff, rot_diff)
00874
00875
00876
00877 def check_cartesian_really_done(self, goal_pose, pos_thres, rot_thres, current_pos = None, current_rot = None):
00878 if not self.check_cartesian_done():
00879 return 0
00880 if current_pos == None or current_rot == None:
00881 (current_pos, current_rot) = self.return_cartesian_pose()
00882 done = self.check_cartesian_near_pose(goal_pose, pos_thres, rot_thres)
00883 if done:
00884 self.stop_cartesian_commands()
00885 return done
00886
00887
00888
00889
00890 def wait_cartesian_really_done(self, goal_pose, pos_thres = .02, rot_thres = .1,
00891 timeout = rospy.Duration(30.), settling_time = rospy.Duration(3.0),
00892 overshoot_dist = 0., overshoot_angle = 0.,
00893 stuck_dist = .03, stuck_angle = .12):
00894
00895
00896 if not self.use_trajectory_cartesian:
00897 with self.cartesian_command_lock:
00898 self.dist_tol = pos_thres
00899 self.angle_tol = rot_thres
00900 self.overshoot_dist = overshoot_dist
00901 self.overshoot_angle = overshoot_angle
00902
00903
00904 start_time = rospy.get_rostime()
00905 done_time = None
00906 r = rospy.Rate(10)
00907 (last_pos, last_rot) = self.return_cartesian_pose()
00908 last_pos_array = [last_pos]*5
00909 last_rot_array = [last_rot]*5
00910 while not rospy.is_shutdown():
00911 now = rospy.get_rostime()
00912
00913
00914 (current_pos, current_rot) = self.return_cartesian_pose()
00915 if self.check_cartesian_really_done(goal_pose, pos_thres, rot_thres, current_pos, current_rot):
00916 rospy.loginfo("got to the goal")
00917 return "success"
00918
00919
00920 if stuck_dist or stuck_angle:
00921 (pos_change, angle_change) = self.dist_from_current_pos_and_rot(last_pos_array[0], last_rot_array[0])
00922 for ind in range(len(last_pos_array)-1):
00923 last_pos_array[ind] = last_pos_array[ind+1]
00924 last_rot_array[ind] = last_rot_array[ind+1]
00925 last_pos_array[-1] = current_pos
00926 last_rot_array[-1] = current_rot
00927 if now - start_time > rospy.Duration(2.0) and \
00928 abs(pos_change) <= stuck_dist*self.timestep and \
00929 abs(angle_change) <= stuck_angle*self.timestep:
00930 rospy.loginfo("Cartesian controller is stuck, stopping!")
00931
00932 self.stop_cartesian_commands()
00933 return "failed"
00934
00935
00936 if done_time == None and self.check_cartesian_done():
00937
00938 done_time = rospy.get_rostime()
00939 if self.use_trajectory_cartesian and done_time and rospy.get_rostime() - done_time > settling_time:
00940 rospy.loginfo("settling time ran out")
00941 return "failed"
00942
00943
00944 if timeout != 0. and rospy.get_rostime() - start_time > timeout:
00945 rospy.loginfo("timed out")
00946 self.stop_cartesian_commands()
00947 return "timed out"
00948 r.sleep()
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 def move_cartesian(self, goal_pose, collision_aware = 0, blocking = 1,
00966 step_size = .005, pos_thres = .001, rot_thres = .05,
00967 timeout = rospy.Duration(30.),
00968 settling_time = rospy.Duration(1.),
00969 overshoot_dist = 0.005, overshoot_angle = 0.05,
00970 stuck_dist = .005, stuck_angle = .001):
00971
00972
00973 (current_pos, current_rot) = self.return_cartesian_pose('base_link')
00974 start_pose = create_pose_stamped(current_pos+current_rot)
00975
00976
00977 if collision_aware:
00978 self.set_planning_scene()
00979 current_angles = self.get_current_arm_angles()
00980 (traj, error_codes) = self.ik_utilities.check_cartesian_path(start_pose, \
00981 goal_pose, current_angles, .01, .1, math.pi/4, 1)
00982 if any(error_codes):
00983 return "no solution"
00984
00985
00986 self.command_cartesian(goal_pose)
00987 if not blocking:
00988 return "sent goal"
00989
00990
00991 result = self.wait_cartesian_really_done(goal_pose, pos_thres, \
00992 rot_thres, timeout = timeout, settling_time = settling_time, \
00993 overshoot_dist = overshoot_dist, overshoot_angle = overshoot_angle, \
00994 stuck_dist = stuck_dist, stuck_angle = stuck_angle)
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 def move_cartesian_ik(self, goal_pose, collision_aware = 0, blocking = 1,
01005 step_size = .005, pos_thres = .02, rot_thres = .1,
01006 timeout = rospy.Duration(30.),
01007 settling_time = rospy.Duration(0.25), vel = .15):
01008
01009
01010 result = self.command_interpolated_ik(goal_pose, collision_aware = collision_aware, \
01011 step_size = step_size, max_joint_vel = vel)
01012 if not result:
01013 return "no solution"
01014 if not blocking:
01015 return "sent goal"
01016
01017
01018 joint_action_result = self.wait_joint_trajectory_done(timeout)
01019 if joint_action_result == "timed out":
01020 return "timed out"
01021
01022 if self.check_cartesian_really_done(goal_pose, pos_thres, rot_thres):
01023 return "success"
01024 return "failed"
01025
01026
01027
01028
01029 def check_controllers_ok(self, mode):
01030 modewrong = 0
01031 if mode == 'joint':
01032 self.check_controller_states()
01033 if not self.joint_controller_state == 'running' and \
01034 any([x == 'running' for x in self.cartesian_controllers_state]):
01035 self.switch_to_joint_mode()
01036 elif not self.joint_controller_state == 'running':
01037 rospy.logwarn("joint controllers aren't running! Attempting to start")
01038 self.start_joint_controllers()
01039 elif any([x == 'running' for x in self.cartesian_controllers_state]):
01040 rospy.logwarn("Cartesian controllers are running! Attempting to stop")
01041 self.stop_controllers(stop_cartesian = 1)
01042 self.stop_cartesian_commands()
01043
01044 elif mode == 'cartesian':
01045 self.check_controller_states()
01046 if not all([x == 'running' for x in self.cartesian_controllers_state]) and \
01047 self.joint_controller_state == 'running':
01048 self.switch_to_cartesian_mode()
01049 elif not all([x == 'running' for x in self.cartesian_controllers_state]):
01050 rospy.logwarn("Cartesian controllers aren't running! Attempting to start")
01051 self.start_cartesian_controllers()
01052 elif self.joint_controller_state == 'running':
01053 rospy.logwarn("joint controllers are running! Attempting to stop")
01054 self.stop_controllers(stop_joint = 1)
01055
01056
01057
01058 def command_joint(self, jointangles):
01059 self.check_controllers_ok('joint')
01060
01061 goal = JointTrajectoryGoal()
01062 goal.trajectory.header.stamp = rospy.get_rostime()
01063
01064 goal.trajectory.joint_names = self.joint_names
01065
01066 point = JointTrajectoryPoint(jointangles, [0]*7, [0]*7, rospy.Duration(0.01))
01067 goal.trajectory.points = [point,]
01068
01069 self.joint_action_client.send_goal(goal)
01070
01071
01072
01073 def command_joint_trajectory(self, trajectory, max_joint_vel = 0.2, current_angles = None, blocking = 0, times_and_vels = None):
01074 self.check_controllers_ok('joint')
01075
01076 goal = JointTrajectoryGoal()
01077 goal.trajectory.joint_names = self.joint_names
01078
01079
01080 trajectory = self.normalize_trajectory(trajectory)
01081
01082
01083 goal.trajectory.header.stamp = rospy.get_rostime() + rospy.Duration(0.05)
01084
01085
01086 if times_and_vels == None:
01087
01088
01089 if current_angles == None:
01090 current_angles = list(self.get_current_arm_angles())
01091
01092
01093 trajectory = [current_angles] + trajectory
01094
01095
01096 (times, vels) = self.ik_utilities.trajectory_times_and_vels(trajectory, [max_joint_vel]*7)
01097
01098 else:
01099 (times, vels) = times_and_vels
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 for ind in range(len(trajectory)):
01111 point = JointTrajectoryPoint(trajectory[ind], vels[ind], [0]*7, rospy.Duration(times[ind]))
01112 goal.trajectory.points.append(point)
01113
01114
01115 self.joint_action_client.send_goal(goal)
01116
01117
01118 if blocking:
01119 self.wait_joint_trajectory_done(timeout = rospy.Duration(times[-1]+5))
01120
01121
01122
01123 def check_joint_trajectory_done(self):
01124 state = self.joint_action_client.get_state()
01125 return state > 1
01126
01127
01128
01129
01130
01131 def wait_joint_trajectory_done(self, timeout = rospy.Duration(0)):
01132 finished = self.joint_action_client.wait_for_result(timeout)
01133 if not finished:
01134 return "timed out"
01135 state = self.joint_action_client.get_state()
01136 if state == 3:
01137 return "succeeded"
01138 return "other"
01139
01140
01141
01142 def freeze_arm(self):
01143 current_angles = self.get_current_arm_angles()
01144 self.command_joint(current_angles)
01145
01146
01147
01148 def command_gripper(self, position, max_effort, blocking = 0):
01149 if not self.gripper_controller_state == 'running':
01150 self.check_controller_states()
01151 if not self.gripper_controller_state == 'running':
01152 rospy.logwarn("gripper controller not running! Attempting to start")
01153 self.start_gripper_controller()
01154
01155 goal = Pr2GripperCommandGoal()
01156 goal.command.position = position
01157 goal.command.max_effort = max_effort
01158 self.gripper_action_client.send_goal(goal)
01159
01160
01161 if blocking:
01162 self.gripper_action_client.wait_for_result(rospy.Duration(4.0))
01163 time.sleep(.5)
01164
01165
01166
01167
01168
01169 def check_controller_states(self):
01170 resp = self.list_controllers_service()
01171
01172 if self.gripper_controller in resp.controllers:
01173 self.gripper_controller_state = resp.state[resp.controllers.index(self.gripper_controller)]
01174 else:
01175 self.gripper_controller_state = 'not loaded'
01176
01177 if self.joint_controller in resp.controllers:
01178 self.joint_controller_state = resp.state[resp.controllers.index(self.joint_controller)]
01179 else:
01180 self.joint_controller_state = 'not loaded'
01181
01182 self.cartesian_controllers_state = []
01183 for controller in self.cartesian_controllers:
01184 if controller not in resp.controllers:
01185 self.cartesian_controllers_state.append('not loaded')
01186 else:
01187 self.cartesian_controllers_state.append(resp.state[resp.controllers.index(controller)])
01188
01189
01190
01191 def load_cartesian_controllers(self):
01192 self.check_controller_states()
01193
01194 for (controller, state) in zip(self.cartesian_controllers, self.cartesian_controllers_state):
01195 if state == 'not loaded':
01196 success = self.load_controller_service(controller)
01197 if not success:
01198 rospy.logerr("error in loading Cartesian controller!")
01199 break
01200 else:
01201 rospy.loginfo("all Cartesian controllers loaded")
01202
01203 self.check_controller_states()
01204
01205
01206
01207 def unload_cartesian_controllers(self):
01208
01209 self.check_controller_states()
01210 if any([x=='running' for x in self.cartesian_controllers_state]):
01211 self.stop_controllers(stop_cartesian = 1)
01212
01213 if all([x=='not loaded' for x in self.cartesian_controllers_state]):
01214 return
01215
01216 self.stop_cartesian_commands()
01217
01218 cart_controllers_reversed = self.cartesian_controllers[:]
01219 cart_controllers_reversed.reverse()
01220 state_reversed = self.cartesian_controllers_state[:]
01221 state_reversed.reverse()
01222 for (controller, state) in zip(cart_controllers_reversed, state_reversed):
01223 if state == 'stopped':
01224 success = self.unload_controller_service(controller)
01225 if not success:
01226 rospy.logerr("error in unloading Cartesian controller!")
01227 break
01228 else:
01229 rospy.loginfo("Cartesian controllers unloaded")
01230 self.check_controller_states()
01231
01232
01233
01234 def load_joint_controllers(self):
01235 self.check_controller_states()
01236 if self.joint_controller_state == 'not loaded':
01237 success = self.load_controller_service(self.joint_controller)
01238 if not success:
01239 rospy.logerr("error in loading joint controller!")
01240 else:
01241 rospy.loginfo("joint controller already loaded")
01242 self.stop_cartesian_commands()
01243
01244 self.check_controller_states()
01245
01246
01247
01248 def unload_joint_controllers(self):
01249 self.check_controller_states()
01250 if self.joint_controller_state == 'running':
01251 self.stop_controllers(stop_joint = 1)
01252 elif self.joint_controller_state == 'not loaded':
01253 return
01254
01255 success = self.unload_controller_service(self.joint_controller)
01256 if not success:
01257 rospy.logerr("error in unloading joint controller!")
01258
01259 self.check_controller_states()
01260
01261
01262
01263 def switch_to_cartesian_mode(self):
01264 self.set_desired_cartesian_to_current()
01265 self.check_controller_states()
01266 if all([x=='stopped' for x in self.cartesian_controllers_state]) and \
01267 self.joint_controller_state == 'running':
01268 success = self.switch_controller_service(self.cartesian_controllers, [self.joint_controller,], 2)
01269 if success:
01270 rospy.loginfo("switched joint to Cartesian successfully")
01271 else:
01272 rospy.logerr("switching joint to Cartesian failed")
01273 else:
01274 self.start_cartesian_controllers()
01275 self.stop_controllers(stop_joint = 1)
01276 self.check_controller_states()
01277
01278
01279
01280 def switch_to_joint_mode(self):
01281 self.check_controller_states()
01282 if self.joint_controller_state == 'stopped' and \
01283 any([x=='running' for x in self.cartesian_controllers_state]):
01284 success = self.switch_controller_service([self.joint_controller,], self.cartesian_controllers, 2)
01285 if success:
01286 rospy.loginfo("switched Cartesian to joint successfully")
01287 else:
01288 rospy.logerr("switching Cartesian to joint failed")
01289 else:
01290 self.start_joint_controllers()
01291 self.stop_controllers(stop_cartesian = 1)
01292 self.stop_cartesian_commands()
01293 self.check_controller_states()
01294
01295
01296
01297 def start_joint_controllers(self):
01298 self.check_controller_states()
01299 if self.joint_controller_state == 'stopped':
01300 success = self.switch_controller_service([self.joint_controller,], [], 2)
01301 if success:
01302 rospy.loginfo("started joint controller successfully")
01303 else:
01304 rospy.logerr("starting joint controller failed")
01305 elif self.joint_controller_state == 'not loaded':
01306 rospy.logerr("joint controller not loaded!")
01307 self.stop_cartesian_commands()
01308
01309 self.check_controller_states()
01310
01311
01312
01313 def start_cartesian_controllers(self):
01314 self.set_desired_cartesian_to_current()
01315 self.check_controller_states()
01316 if any([x=='not loaded' for x in self.cartesian_controllers_state]):
01317 print "not all Cartesian controllers are loaded!"
01318
01319 elif any([x=='stopped' for x in self.cartesian_controllers_state]):
01320 success = self.switch_controller_service(self.cartesian_controllers, [], 2)
01321 if success:
01322 rospy.loginfo("started Cartesian controllers successfully")
01323 else:
01324 rospy.logerr("starting Cartesian controllers failed")
01325 self.check_controller_states()
01326
01327
01328
01329 def start_gripper_controller(self):
01330 self.check_controller_states()
01331 if self.gripper_controller_state == 'stopped':
01332 success = self.switch_controller_service([self.gripper_controller,], [], 2)
01333 if success:
01334 rospy.loginfo("started gripper controller successfully")
01335 else:
01336 rospy.logerr("starting gripper controller failed")
01337 elif self.gripper_controller_state == 'not loaded':
01338 rospy.logerr("gripper controller isn't loaded!")
01339 self.check_controller_states()
01340
01341
01342
01343 def stop_all_controllers(self):
01344 self.stop_controllers(stop_joint = 1, stop_cartesian = 1, stop_gripper = 1)
01345
01346
01347
01348 def stop_controllers(self, stop_joint = 0, stop_cartesian = 0, stop_gripper = 0):
01349 self.check_controller_states()
01350
01351
01352 if stop_cartesian and any([x=='running' for x in self.cartesian_controllers_state]):
01353 success = self.switch_controller_service([], self.cartesian_controllers, 2)
01354 if success:
01355 rospy.loginfo("stopped Cartesian controllers successfully")
01356 else:
01357 rospy.logerr("stopping Cartesian controllers failed")
01358
01359
01360 if stop_joint and self.joint_controller_state == 'running':
01361 success = self.switch_controller_service([], [self.joint_controller,], 2)
01362 if success:
01363 rospy.loginfo("stopped joint controller successfully")
01364 else:
01365 rospy.logerr("stopping joint controller failed")
01366
01367
01368 if stop_gripper and self.gripper_controller_state == 'running':
01369 success = self.switch_controller_service([], [self.gripper_controller,], 2)
01370 if success:
01371 rospy.loginfo("stopped gripper controller successfully")
01372 else:
01373 rospy.logerr("stopping gripper controller failed")
01374
01375 self.check_controller_states()
01376
01377
01378
01379 def reload_cartesian_controllers(self, set_params = 1):
01380 self.check_controller_states()
01381
01382
01383 if set_params:
01384 self.cart_params.set_params()
01385
01386
01387 restart = 0
01388 if any([x=='running' for x in self.cartesian_controllers_state]):
01389 restart = 1
01390 self.switch_to_joint_mode()
01391
01392
01393 self.unload_cartesian_controllers()
01394
01395
01396 self.load_cartesian_controllers()
01397
01398
01399 if restart:
01400 self.switch_to_cartesian_mode()
01401
01402 self.check_controller_states()
01403
01404
01405
01406 def reload_joint_controllers(self, fraction = 1.):
01407 self.check_controller_states()
01408
01409
01410 self.joint_params.set_gains_fraction(fraction)
01411
01412
01413 restart = 0
01414 if self.joint_controller_state == 'running':
01415 restart = 1
01416 self.switch_to_cartesian_mode()
01417
01418
01419 self.unload_joint_controllers()
01420
01421
01422 self.load_joint_controllers()
01423
01424
01425 if restart:
01426 self.switch_to_joint_mode()
01427
01428 self.check_controller_states()
01429
01430
01431
01432 def return_cartesian_pose(self, frame = 'base_link'):
01433 start_time = rospy.get_rostime()
01434 while not rospy.is_shutdown():
01435 try:
01436 t = self.tf_listener.getLatestCommonTime(frame, self.whicharm+'_wrist_roll_link')
01437 (trans, rot) = self.tf_listener.lookupTransform(frame, self.whicharm+'_wrist_roll_link', t)
01438 break
01439 except (tf.Exception, tf.ExtrapolationException):
01440 rospy.sleep(0.5)
01441 current_time = rospy.get_rostime()
01442 rospy.logerr("waiting for a tf transform between %s and %s"%(frame, \
01443 self.whicharm+'_wrist_roll_link'))
01444 if current_time - start_time > rospy.Duration(30.):
01445 rospy.logerr("return_cartesian_pose waited 30 seconds for a tf transform! Returning None")
01446 return (None, None)
01447 return (list(trans), list(rot))
01448
01449
01450
01451 def print_cartesian_pose(self):
01452 (trans, rot) = self.return_cartesian_pose()
01453 print "Cartesian pose trans:", self.pplist(trans), "rot:", self.pplist(rot)
01454 print "rotation matrix:\n", self.ppmat(tf.transformations.quaternion_matrix(rot))
01455
01456
01457
01458 def pplist(self, list):
01459 return ' '.join(['%5.3f'%x for x in list])
01460
01461
01462
01463 def ppmat(self, mat):
01464 str = ''
01465 for i in range(mat.shape[0]):
01466 for j in range(mat.shape[1]):
01467 str += '%2.3f\t'%mat[i,j]
01468 str += '\n'
01469 return str
01470
01471
01472
01473
01474 if __name__ == '__main__':
01475
01476 def keypause():
01477 print "press enter to continue"
01478 raw_input()
01479
01480 rospy.init_node('controller_manager', anonymous=True)
01481
01482
01483 points = [
01484 [0.5, -0.5, 0.8, 0.5, 0.0, 0.0, 0.5],
01485 [0.6, -0.2, 0.4, 0.0, 0.0, 0.5, 0.5],
01486 [0.2, -0.8, 0.4, 0.0, 0.5, 0.0, 0.5],
01487 [0.5, -0.5, 1.2, 0.5, 0.0, 0.0, 0.5],
01488 [0.6, -0.2, 1.2, 0.0, 0.0, 0.5, 0.5],
01489 [0.2, -0.8, 1.2, 0.0, 0.5, 0.0, 0.5],
01490 [.62, -.05, .65, -0.5, 0.5, 0.5, 0.5],
01491 [.62, -.05, .56, -0.5, 0.5, 0.5, 0.5]
01492 ]
01493
01494 zeros = [0]*7
01495 sideangles = [-0.447, -0.297, -2.229, -0.719, 0.734, -1.489, 1.355]
01496
01497 cm = ControllerManager('r')
01498
01499 test_angles = [
01500 [-0.094, 0.711, -0.000, -1.413, -2.038, -1.172, -0.798],
01501 [0.126, 0.832, 0.000, -1.740, -2.977, -1.091, 3.043]]
01502
01503 print "going through test_angles and waiting for the trajectory to finish"
01504 cm.command_joint_trajectory(test_angles)
01505 result = cm.wait_joint_trajectory_done(rospy.Duration(30.0))
01506 print result
01507
01508
01509
01510
01511 print "switching to cartesian controllers"
01512 cm.switch_to_cartesian_mode()
01513
01514 print "moving to point 6 and waiting for it to get there"
01515 cm.command_cartesian(points[6])
01516 result = cm.wait_cartesian_really_done(points[6], .01, .1, rospy.Duration(30.0), rospy.Duration(15.0))
01517 print result
01518 print "desired pose:", cm.pplist(points[6])
01519 cm.print_cartesian_pose()
01520 keypause()
01521
01522 print "going to all 0 angles with joint controllers, testing contingency-switch"
01523 cm.command_joint(zeros)
01524 keypause()
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561 print "moving to point 0 in Cartesian mode, testing contingency switch"
01562 cm.command_cartesian(points[0])
01563 keypause()
01564 cm.print_cartesian_pose()
01565
01566 if cm.use_trajectory_cartesian:
01567 print "reloading cartesian controllers with zero PID terms (should be unable to move)"
01568 cm.cart_params.pose_fb_trans_p = 0.
01569 cm.cart_params.pose_fb_trans_d = 0.
01570 cm.cart_params.pose_fb_rot_p = 0.
01571 cm.cart_params.pose_fb_rot_d = 0.
01572 cm.reload_cartesian_controllers()
01573 else:
01574 print "setting cartesian gains to near-zero (should be unable to move)"
01575 cm.cart_params.set_gains([0.001]*3, [0.001]*3, [0.001]*3, [0.001]*3)
01576
01577 print "trying to move to point 2 (should fail)"
01578 cm.command_cartesian(points[2])
01579 keypause()
01580
01581 if cm.use_trajectory_cartesian:
01582 print "reloading cartesian controllers with normal PID terms"
01583 cm.cart_params.pose_fb_trans_p=800.
01584 cm.cart_params.pose_fb_trans_d=12.
01585 cm.cart_params.pose_fb_rot_p=80.
01586 cm.cart_params.pose_fb_rot_d=0.0
01587 cm.reload_cartesian_controllers()
01588 else:
01589 print "setting cartesian gains back"
01590 cm.cart_params.set_params_to_defaults()
01591 cm.cart_params.set_gains()
01592
01593 print "trying again to move to point 2 (should succeed)"
01594 cm.command_cartesian(points[2])
01595 keypause()
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605