def get_placement_recipe(chosen_object, handarm_params, grasp_type): place_time = handarm_params['place_duration'] down_speed = handarm_params['place_down_speed'] # The twists are defined on the world frame down_twist = np.array([0, 0, -down_speed, 0, 0, 0]) # assemble controller sequence control_sequence = [] # 1. Place in IFCO control_sequence.append( ha.CartesianVelocityControlMode(down_twist, controller_name='PlaceInIFCO', name='PlaceInIFCO', reference_frame="world")) # 1b. Switch after a certain amount of time control_sequence.append( ha.TimeSwitch('PlaceInIFCO', 'softhand_open', duration=place_time)) # 2. Release SKU control_sequence.append( ha.GeneralHandControlMode(goal=np.array([0]), name='softhand_open', synergy=1)) # 2b. Switch when hand opening time ends control_sequence.append( ha.TimeSwitch('softhand_open', 'finished', duration=0.5)) # 3. Block joints to finish motion control_sequence.append(ha.BlockJointControlMode(name='finished')) return control_sequence
def create_surface_grasp(chosen_object, handarm_params, pregrasp_transform, alternative_behavior=None): object_type = chosen_object['type'] # Get the relevant parameters for hand object combination if object_type in handarm_params['SurfaceGrasp']: params = handarm_params['SurfaceGrasp'][object_type] else: params = handarm_params['SurfaceGrasp']['object'] # Get params per phase # Approach phase downward_force = params['downward_force'] down_speed = params['down_speed'] # Grasping phase lift_time = params['corrective_lift_duration'] up_speed = params['up_speed'] hand_closing_time = params['hand_closing_duration'] hand_synergy = params['hand_closing_synergy'] success_estimator_timeout = handarm_params['success_estimator_timeout'] # Set the twists to use TRIK controller with # Down speed is positive because it is defined on the EE frame down_twist = np.array([0, 0, down_speed, 0, 0, 0]) # Slow Up speed is also positive because it is defined on the world frame up_twist = np.array([0, 0, up_speed, 0, 0, 0]) # assemble controller sequence control_sequence = [] # 0. Trigger pre-shaping the hand (if there is a synergy). The first 1 in the name represents a surface grasp. control_sequence.append(ha.BlockJointControlMode(name = 'softhand_preshape_1_1')) # 0b. Time to trigger pre-shape control_sequence.append(ha.TimeSwitch('softhand_preshape_1_1', 'PreGrasp', duration = hand_closing_time)) # 1. Go above the object - Pregrasp control_sequence.append(ha.InterpolatedHTransformControlMode(pregrasp_transform, controller_name = 'GoAboveObject', goal_is_relative='0', name = 'PreGrasp')) # 1b. Switch when hand reaches the goal pose control_sequence.append(ha.FramePoseSwitch('PreGrasp', 'PrepareForMassMeasurement', controller = 'GoAboveObject', epsilon = '0.01')) # 2. Go to gravity compensation control_sequence.append(ha.BlockJointControlMode(name = 'PrepareForMassMeasurement')) # 2b. Wait for a bit to allow vibrations to attenuate control_sequence.append(ha.TimeSwitch('PrepareForMassMeasurement', 'ReferenceMassMeasurement', duration = 0.5)) # 3. Reference mass measurement with empty hand (TODO can this be replaced by offline calibration?) control_sequence.append(ha.BlockJointControlMode(name='ReferenceMassMeasurement')) # TODO use gravity comp instead? # 3b. Switches when reference measurement was done # 3b.1 Successful reference measurement control_sequence.append(ha.RosTopicSwitch('ReferenceMassMeasurement', 'GoDown', ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.REFERENCE_MEASUREMENT_SUCCESS.value]), )) # 3b.2 The grasp success estimator module is inactive control_sequence.append(ha.RosTopicSwitch('ReferenceMassMeasurement', 'GoDown', ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.GRASP_SUCCESS_ESTIMATOR_INACTIVE.value]), )) # 3b.3 Timeout (grasp success estimator module not started, an error occurred or it takes too long) control_sequence.append(ha.TimeSwitch('ReferenceMassMeasurement', 'GoDown', duration=success_estimator_timeout)) # 3b.4 There is no special switch for unknown error response (estimator signals REFERENCE_MEASUREMENT_FAILURE) # Instead the timeout will trigger giving the user an opportunity to notice the erroneous result in the GUI. # 4. Go down onto the object (relative in EE frame) - Godown control_sequence.append(ha.CartesianVelocityControlMode(down_twist, controller_name='GoDown', name="GoDown", reference_frame="EE")) # force threshold that if reached will trigger the closing of the hand force = np.array([0, 0, downward_force, 0, 0, 0]) # 4b. Switch when force-torque sensor is triggered control_sequence.append(ha.ForceTorqueSwitch('GoDown', 'LiftHand', goal = force, norm_weights = np.array([0, 0, 1, 0, 0, 0]), jump_criterion = "THRESH_UPPER_BOUND", goal_is_relative = '1', frame_id = 'world')) # 5. Lift upwards so the hand can inflate control_sequence.append( ha.CartesianVelocityControlMode(up_twist, controller_name='CorrectiveLift', name="LiftHand", reference_frame="world")) # the 1 in softhand_close_1 represents a surface grasp. This way the strategy is encoded in the HA. mode_name_hand_closing = 'softhand_close_1_0' # 5b. We switch after a short time control_sequence.append(ha.TimeSwitch('LiftHand', mode_name_hand_closing, duration=lift_time)) # 6. Call hand controller control_sequence.append(ha.GeneralHandControlMode(goal = np.array([1]), name = mode_name_hand_closing, synergy = hand_synergy)) # 6b. Switch when hand closing time ends control_sequence.append(ha.TimeSwitch(mode_name_hand_closing, 'GoUp_1', duration = hand_closing_time)) return control_sequence
def create_wall_grasp(chosen_object, wall_frame, handarm_params, pregrasp_transform, alternative_behavior=None): object_type = chosen_object['type'] # Get the relevant parameters for hand object combination if object_type in handarm_params['WallGrasp']: params = handarm_params['WallGrasp'][object_type] else: params = handarm_params['WallGrasp']['object'] # Get params per phase # Approach phase downward_force = params['downward_force'] down_speed = params['down_speed'] lift_time = params['corrective_lift_duration'] up_speed = params['up_speed'] wall_force = params['wall_force'] slide_speed = params['slide_speed'] # Grasping phase pre_grasp_twist = params['pre_grasp_twist'] pre_grasp_rotate_time = params['pre_grasp_rotation_duration'] hand_closing_time = params['hand_closing_duration'] hand_synergy = params['hand_closing_synergy'] # Post-grasping phase post_grasp_twist = params['post_grasp_twist'] post_grasp_rotate_time = params['post_grasp_rotation_duration'] success_estimator_timeout = handarm_params['success_estimator_timeout'] # Set the twists to use TRIK controller with # Down speed is negative because it is defined on the world frame down_twist = np.array([0, 0, -down_speed, 0, 0, 0]) # Slow Up speed is positive because it is defined on the world frame up_twist = np.array([0, 0, up_speed, 0, 0, 0]) # Slide twist is positive because it is defined on the EE frame slide_twist = np.array([0, 0, slide_speed, 0, 0, 0]) control_sequence = [] # 0 trigger pre-shaping the hand (if there is a synergy). The 2 in the name represents a wall grasp. control_sequence.append(ha.BlockJointControlMode(name='softhand_preshape_2_1')) # 0b. Time for pre-shape control_sequence.append(ha.TimeSwitch('softhand_preshape_2_1', 'PreGrasp', duration=hand_closing_time)) # 1. Go above the object - Pregrasp control_sequence.append(ha.InterpolatedHTransformControlMode(pregrasp_transform, controller_name = 'GoAboveObject', goal_is_relative='0', name = 'PreGrasp')) # 1b. Switch when hand reaches the goal pose control_sequence.append(ha.FramePoseSwitch('PreGrasp', 'PrepareForMassMeasurement', controller = 'GoAboveObject', epsilon = '0.01')) # 2. Go to gravity compensation control_sequence.append(ha.BlockJointControlMode(name = 'PrepareForMassMeasurement')) # 2b. Wait for a bit to allow vibrations to attenuate control_sequence.append(ha.TimeSwitch('PrepareForMassMeasurement', 'ReferenceMassMeasurement', duration = 0.5)) # 3. Reference mass measurement with empty hand (TODO can this be replaced by offline calibration?) control_sequence.append(ha.BlockJointControlMode(name='ReferenceMassMeasurement')) # TODO use gravity comp instead? # 3b. Switches when reference measurement was done # 3b.1 Successful reference measurement control_sequence.append(ha.RosTopicSwitch('ReferenceMassMeasurement', 'GoDown', ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.REFERENCE_MEASUREMENT_SUCCESS.value]), )) # 3b.2 The grasp success estimator module is inactive control_sequence.append(ha.RosTopicSwitch('ReferenceMassMeasurement', 'GoDown', ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.GRASP_SUCCESS_ESTIMATOR_INACTIVE.value]), )) # 3b.3 Timeout (grasp success estimator module not started, an error occurred or it takes too long) control_sequence.append(ha.TimeSwitch('ReferenceMassMeasurement', 'GoDown', duration=success_estimator_timeout)) # 3b.4 There is no special switch for unknown error response (estimator signals REFERENCE_MEASUREMENT_FAILURE) # Instead the timeout will trigger giving the user an opportunity to notice the erroneous result in the GUI. # 4. Go down onto the object/table, in world frame control_sequence.append( ha.CartesianVelocityControlMode(down_twist, controller_name='GoDown', name="GoDown", reference_frame="world")) # 4b. Switch when force threshold is exceeded force = np.array([0, 0, downward_force, 0, 0, 0]) control_sequence.append(ha.ForceTorqueSwitch('GoDown', 'LiftHand', goal=force, norm_weights=np.array([0, 0, 1, 0, 0, 0]), jump_criterion="THRESH_UPPER_BOUND", goal_is_relative='1', frame_id='world')) # 5. Lift upwards so the hand doesn't slide on table surface control_sequence.append( ha.CartesianVelocityControlMode(up_twist, controller_name='Lift1', name="LiftHand", reference_frame="world")) # 5b. We switch after a short time as this allows us to do a small, precise lift motion control_sequence.append(ha.TimeSwitch('LiftHand', 'SlideToWall', duration=lift_time)) # 6. Go towards the wall to slide object to wall control_sequence.append( ha.CartesianVelocityControlMode(slide_twist, controller_name='SlideToWall', name="SlideToWall", reference_frame="EE")) # 6b. Switch when the f/t sensor is triggered with normal force from wall force = np.array([0, 0, wall_force, 0, 0, 0]) control_sequence.append(ha.ForceTorqueSwitch('SlideToWall', 'SlideBackFromWall', 'ForceSwitch', goal=force, norm_weights=np.array([0, 0, 1, 0, 0, 0]), jump_criterion="THRESH_UPPER_BOUND", goal_is_relative='1', frame_id='world', frame=wall_frame)) # 7. Go back a bit to allow the hand to inflate control_sequence.append( ha.CartesianVelocityControlMode(pre_grasp_twist, controller_name='SlideBackFromWall', name="SlideBackFromWall", reference_frame="EE")) # The 2 in softhand_close_2 represents a wall grasp. This way the strategy is encoded in the HA. # The 0 encodes the synergy id mode_name_hand_closing = 'softhand_close_2_0' # 7b. We switch after a short time control_sequence.append(ha.TimeSwitch('SlideBackFromWall', mode_name_hand_closing, duration=pre_grasp_rotate_time)) # 8. Maintain contact while closing the hand # Call general hand controller control_sequence.append(ha.GeneralHandControlMode(goal = np.array([1]), name = mode_name_hand_closing, synergy = hand_synergy)) # 8b. Switch when hand closing duration ends control_sequence.append(ha.TimeSwitch(mode_name_hand_closing, 'PostGraspRotate', duration=hand_closing_time)) # 9. Rotate a bit to roll the object in the hand control_sequence.append( ha.CartesianVelocityControlMode(post_grasp_twist, controller_name='PostGraspRotate', name="PostGraspRotate", reference_frame="EE")) # 9b. We switch after a short time control_sequence.append(ha.TimeSwitch('PostGraspRotate', 'GoUp_1', duration=post_grasp_rotate_time)) return control_sequence
def get_transport_recipe(chosen_object, handarm_params, reaction, FailureCases, grasp_type, alternative_behavior=None): object_type = chosen_object['type'] # Get the relevant parameters for hand object combination if object_type in handarm_params[grasp_type]: params = handarm_params[grasp_type][object_type] else: params = handarm_params[grasp_type]['object'] lift_time = params['lift_duration'] up_speed = params['up_speed'] drop_off_pose = handarm_params['drop_off_pose'] success_estimator_timeout = handarm_params['success_estimator_timeout'] # Up speed is positive because it is defined on the world frame up_twist = np.array([0, 0, up_speed, 0, 0, 0]) # assemble controller sequence control_sequence = [] # 1. Lift upwards control_sequence.append( ha.CartesianVelocityControlMode(up_twist, controller_name='GoUpHTransform', name='GoUp_1', reference_frame="world")) # 1b. Switch after half the lift time control_sequence.append( ha.TimeSwitch('GoUp_1', 'EstimationMassMeasurement', duration=lift_time / 2)) # 2. Measure the mass again and estimate number of grasped objects (grasp success estimation) control_sequence.append( ha.BlockJointControlMode(name='EstimationMassMeasurement')) # 2b. Switches after estimation measurement was done target_cm_okay = 'GoUp_2' # 2b.1 No object was grasped => go to failure mode. target_cm_estimation_no_object = reaction.cm_name_for( FailureCases.MASS_ESTIMATION_NO_OBJECT, default=target_cm_okay) control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_estimation_no_object, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.ESTIMATION_RESULT_NO_OBJECT.value]), )) # 2b.2 More than one object was grasped => failure target_cm_estimation_too_many = reaction.cm_name_for( FailureCases.MASS_ESTIMATION_TOO_MANY, default=target_cm_okay) control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_estimation_too_many, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.ESTIMATION_RESULT_TOO_MANY.value]), )) # 2b.3 Exactly one object was grasped => success (continue lifting the object and go to drop off) control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_okay, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.ESTIMATION_RESULT_OKAY.value]), )) # 2b.4 The grasp success estimator module is inactive => directly continue lifting the object and go to drop off control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_okay, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.GRASP_SUCCESS_ESTIMATOR_INACTIVE.value]), )) # 2b.5 Timeout (grasp success estimator module not started, an error occurred or it takes too long) control_sequence.append( ha.TimeSwitch('EstimationMassMeasurement', target_cm_okay, duration=success_estimator_timeout)) # 2b.6 There is no special switch for unknown error response (estimator signals ESTIMATION_RESULT_UNKNOWN_FAILURE) # Instead the timeout will trigger giving the user an opportunity to notice the erroneous result in the GUI. # 3. After estimation measurement control modes. extra_failure_cms = set() if target_cm_estimation_no_object != target_cm_okay: extra_failure_cms.add(target_cm_estimation_no_object) if target_cm_estimation_too_many != target_cm_okay: extra_failure_cms.add(target_cm_estimation_too_many) for cm in extra_failure_cms: if cm.startswith('failure_rerun'): # 3.1 Failure control mode representing grasping failure, which might be corrected by re-running the plan. control_sequence.append(ha.BlockJointControlMode(name=cm)) if cm.startswith('failure_replan'): # 3.2 Failure control mode representing grasping failure, which can't be corrected and requires to re-plan. control_sequence.append(ha.BlockJointControlMode(name=cm)) # 3.3 Success control mode. Lift hand even further control_sequence.append( ha.CartesianVelocityControlMode(up_twist, controller_name='GoUpHTransform', name=target_cm_okay, reference_frame="world")) # 3b. Switch after half the lift time control_sequence.append( ha.TimeSwitch(target_cm_okay, 'GoDropOff', duration=lift_time / 2)) # 4. Go above the object - Pregrasp control_sequence.append( ha.InterpolatedHTransformControlMode(drop_off_pose, controller_name='GoToDropPose', goal_is_relative='0', name='GoDropOff')) # 4b. Switch when hand reaches the goal pose control_sequence.append( ha.FramePoseSwitch('GoDropOff', 'PlaceInIFCO', controller='GoToDropPose', epsilon='0.01')) return control_sequence
def create_hybrid_automaton(roblib_trajectory): hybrid_automaton = ha.HybridAutomaton(current_control_mode='goto_0') # go through trajectory points and add control mode + switch points = roblib_trajectory.shape[0] in_contact = False for t in range(points): # add motion depending on contact change next_in_contact = (roblib_trajectory[t, 7] == 1) normal = roblib_trajectory[t, 8:11] normal_undefined = np.linalg.norm(normal) == 0 ctrl_mode_name = 'goto_{}'.format(t) next_ctrl_mode_name = 'goto_{}'.format(t + 1) ctrller_name = 'cntrl_{}'.format(t) mykp = np.array([300, 200, 150, 200, 10, 10, 5]) mykv = np.array([2, 4, 2, 0.8, 0.2, 0.2, 0.15]) #mykp = np.array([900, 2500, 600, 500, 50, 50, 8]) #mykv = np.array([10, 20, 5, 2, 0.5, 0.5, 0.05]) myv_max = np.array([0.1, 0.04]) #np.array([0.25, 0.08]) if absolute_motion: if t == 0: print "(absolute goal)" rlab_traj = roblib_trajectory[:, :7].transpose() print rlab_traj ctrl_mode = ha.JointControlMode(rlab_traj, name=ctrl_mode_name, controller_name=ctrller_name) # that's important to avoid jerky behavior on the spot! --> it's actually the minimum_completion_time #ctrl_mode.controlset.controllers[0].properties['completion_times'] = '[1,1]1.0' ctrl_mode.controlset.controllers[0].properties['kp'] = mykp ctrl_mode.controlset.controllers[0].properties['kv'] = mykv ctrl_switch = ha.JointConfigurationSwitch( ctrl_mode_name, next_ctrl_mode_name, controller=ctrller_name, epsilon=str(math.radians(5.0))) elif (not in_contact or normal_undefined) and not next_in_contact: #if True: # free space motion print "(free space -> free space)" if t == 0: ctrl_mode = ha.JointControlMode(roblib_trajectory[t, :7], name=ctrl_mode_name, controller_name=ctrller_name) # that's important to avoid jerky behavior on the spot! --> it's actually the minimum_completion_time ctrl_mode.controlset.controllers[0].properties[ 'completion_times'] = '[1,1]1.0' #ctrl_mode.controlset.controllers[0].properties['kp'] = mykp #ctrl_mode.controlset.controllers[0].properties['kv'] = mykv ctrl_switch = ha.JointConfigurationSwitch( ctrl_mode_name, next_ctrl_mode_name, controller=ctrller_name, epsilon=str(math.radians(5.0))) elif t == (points - 1): # last one goal = roblib_trajectory[t, :7] - roblib_trajectory[t - 1, :7] ctrl_mode = ha.JointControlMode(goal, goal_is_relative='1', name=ctrl_mode_name, controller_name=ctrller_name) ctrl_switch = ha.JointConfigurationSwitch( ctrl_mode_name, next_ctrl_mode_name, controller=ctrller_name, epsilon=str(math.radians(5.0)), goal_is_relative='1') #tmp = ha.ForceTorqueSwitch(ctrl_mode_name, next_ctrl_mode_name, goal = np.array([0., 0., 0., 0, 0, 0]), norm_weights = np.array([1, 1, 1, 0, 0, 0]), negate = '1', epsilon='1', jump_criterion = "NORM_L2", frame_id = '', goal_is_relative = '1') #ctrl_switch.add(tmp.con) else: goal = (roblib_trajectory[t, :7] - roblib_trajectory[t - 1, :7]) * 2. ctrl_mode = ha.JointControlMode(goal, goal_is_relative='1', name=ctrl_mode_name, controller_name=ctrller_name) ctrl_switch = ha.JointConfigurationSwitch( ctrl_mode_name, next_ctrl_mode_name, name='TheSpecialOne', controller=ctrller_name, epsilon=str(math.radians(5.0)), goal_is_relative='1') elif (not in_contact or normal_undefined) and next_in_contact: # move until contact print "(free space -> in contact)" if False: goal = extrapolate_transform(roblib_trajectory[t - 1, -7:], roblib_trajectory[t, -7:], 1.2) ctrl_mode = ha.HTransformControlMode( goal, name=ctrl_mode_name, controller_name=ctrller_name, goal_is_relative='1') ctrl_mode.controlset.controllers[0].properties[ 'v_max'] = myv_max goal = (roblib_trajectory[t, :7] - roblib_trajectory[t - 1, :7]) * 2. #goal = extrapolate_configuration(roblib_trajectory[t-1, :7], roblib_trajectory[t, :7], 1.3) ctrl_mode = ha.JointControlMode(goal, goal_is_relative='1', name=ctrl_mode_name, controller_name=ctrller_name) #ctrl_mode.controlset.controllers[0].properties['kp'] = mykp #ctrl_mode.controlset.controllers[0].properties['kv'] = mykv ctrl_mode.controlset.controllers[0].properties['v_max'] = np.array( [0.1] * 7) ctrl_switch = ha.ForceTorqueSwitch( ctrl_mode_name, next_ctrl_mode_name, epsilon='4', goal=np.array([0., 0., 0., 0, 0, 0]), norm_weights=np.array([1, 1, 1, 0, 0, 0]), negate='1', jump_criterion="NORM_L2", frame_id='', goal_is_relative='1') time_switch = ha.TimeSwitch(ctrl_mode_name, next_ctrl_mode_name, duration=1.0) ctrl_switch.add(time_switch.conditions[0]) elif in_contact and next_in_contact: # move until contact changes print "(in contact -> in contact)" goal = extrapolate_configuration(roblib_trajectory[t - 1, :7], roblib_trajectory[t, :7], 1.5) ctrl_mode = ha.JointControlMode(goal, name=ctrl_mode_name, controller_name=ctrller_name) ctrl_switch = ha.ForceTorqueSwitch( ctrl_mode_name, next_ctrl_mode_name, goal=np.array([0., 0., 0., 0, 0, 0]), norm_weights=np.array([1, 1, 1, 0, 0, 0]), negate='1', epsilon='1', jump_criterion="NORM_L2", frame_id='', goal_is_relative='1') elif in_contact and not next_in_contact: # move until no more contact print "(in contact -> free space) normal_defined:", ~normal_undefined ft_in_ee = tra.translation_matrix([0, 0, 0]) goal = extrapolate_transform([0, 0, 0, 0, 0, 0, 1], roblib_trajectory[t, -7:], 1.0) delta = extrapolate_transform(roblib_trajectory[t - 1, -7:], roblib_trajectory[t, -7:], 1.0) normal_in_ee = np.dot( tra.inverse_matrix( transform_from_vector(roblib_trajectory[t - 1, -7:]))[:3, :3], normal) normal_in_ft = np.dot(ft_in_ee[:3, :3], normal_in_ee) print "Normal in world: ", normal # in world print "Normal in ee: ", normal_in_ee # project onto normal plane print delta[:3, 3] #print desired_delta dist = np.linalg.norm(delta[:3, 3]) delta[:3, 3] = delta[:3, 3] * (0.03 / dist) print dist print normal_in_ft print delta #ctrl_mode = ha.HTransformControlMode(delta, name = ctrl_mode_name, controller_name = ctrller_name, goal_is_relative='1') #ctrl_mode = ha.InterpolatedHTransformImpedanceControlMode(goal, name = ctrl_mode_name, controller_name = ctrller_name, goal_is_relative='1') # three things needed: # 1) desired_displacement: delta vector in ee frame # 2) force_gradient: normal vector in ee frame ctrl_mode = ha.ControlMode(name=ctrl_mode_name).set( ha.NakamuraControlSet().add( ha.ForceHTransformController( name=ctrller_name, desired_distance=dist * 1.2, desired_displacement=tra.translation_matrix(delta[:3, 3]), #force_gradient=tra.translation_matrix([0, 0, 0.005]), force_gradient=tra.translation_matrix(-normal_in_ee * 0.0025), desired_force_dimension=np.array(-normal_in_ft + [0, 0, 0])))) ctrl_mode.controlset.controllers[0].properties[ 'desired_min_force'] = '-5' ctrl_mode.controlset.controllers[0].properties[ 'desired_max_force'] = '-3' #ctrl_mode = ha.ControlMode(name = ctrl_mode_name).set(ha.NakamuraControlSet().add(ha.ForceHTransformController(name = ctrller_name, desired_distance = dist*1.2, desired_displacement=tra.translation_matrix(delta[:3, 3]), force_gradient=tra.translation_matrix(normal * 0.005), desired_force_dimension=np.array([0, 0, 1, 0, 0, 0])))) ctrl_mode.controlset.controllers[0].properties['v_max'] = np.array( [0.01, 0.01]) #myv_max ctrl_switch = ha.ForceTorqueSwitch( ctrl_mode_name, next_ctrl_mode_name, epsilon='1.2', goal_is_relative='0', negate='0', goal=np.array([0., 0., 0., 0, 0, 0]), norm_weights=np.array([1, 1, 1, 0, 0, 0]), jump_criterion="NORM_L1", frame_id='') pose_condition = ha.JumpCondition('FrameDisplacementSensor', goal=np.zeros(3), controller='', jump_criterion='NORM_L2', epsilon='{}'.format(dist * 0.5), negate='1', goal_is_relative='1', frame_id='EE', norm_weights=np.ones(3)) ctrl_switch.add(pose_condition) #del ctrl_switch.conditions[0] if t == (points - 1): hybrid_automaton.add([ctrl_mode]) elif not absolute_motion: hybrid_automaton.add([ctrl_mode, ctrl_switch]) in_contact = next_in_contact # add final gravity mode #hybrid_automaton.add(ha.GravityCompensationMode(name = 'goto_{}'.format(points))) #hybrid_automaton.add(ha.JointControlMode(np.zeros(7), name = 'goto_{}'.format(points), goal_is_relative='1')) return hybrid_automaton
def create_wall_grasp(object_frame, bounding_box, wall_frame, handarm_params, object_type, pre_grasp_pose=None, alternative_behavior=None): # Get the parameters from the handarm_parameters.py file obj_type_params = {} obj_params = {} if object_type in handarm_params['wall_grasp']: obj_type_params = handarm_params['wall_grasp'][object_type] if 'object' in handarm_params['wall_grasp']: obj_params = handarm_params['wall_grasp']['object'] hand_transform = getParam(obj_type_params, obj_params, 'hand_transform') downward_force = getParam(obj_type_params, obj_params, 'downward_force') wall_force = getParam(obj_type_params, obj_params, 'wall_force') slide_IFCO_speed = getParam(obj_type_params, obj_params, 'slide_speed') pre_approach_transform = getParam(obj_type_params, obj_params, 'pre_approach_transform') scooping_angle_deg = getParam(obj_type_params, obj_params, 'scooping_angle_deg') init_joint_config = handarm_params['init_joint_config'] thumb_pos_preshape = getParam(obj_type_params, obj_params, 'thumb_pos_preshape') post_grasp_transform = getParam(obj_type_params, obj_params, 'post_grasp_transform') rotate_time = handarm_params['rotate_duration'] down_IFCO_speed = handarm_params['down_IFCO_speed'] # Set the twists to use TRIK controller with # Down speed is negative because it is defined on the world frame down_IFCO_twist = np.array([0, 0, -down_IFCO_speed, 0, 0, 0]) # Slide speed is positive because it is defined on the EE frame + rotation of the scooping angle slide_IFCO_twist_matrix = tra.rotation_matrix( math.radians(scooping_angle_deg), [1, 0, 0]).dot(tra.translation_matrix([0, 0, slide_IFCO_speed])) slide_IFCO_twist = np.array([ slide_IFCO_twist_matrix[0, 3], slide_IFCO_twist_matrix[1, 3], slide_IFCO_twist_matrix[2, 3], 0, 0, 0 ]) rviz_frames = [] if pre_grasp_pose is None: # this is the EC frame. It is positioned like object and oriented to the wall ec_frame = np.copy(wall_frame) ec_frame[:3, 3] = tra.translation_from_matrix(object_frame) ec_frame = ec_frame.dot(hand_transform) pre_approach_pose = ec_frame.dot(pre_approach_transform) else: pre_approach_pose = pre_grasp_pose # Rviz debug frames rviz_frames.append(object_frame) rviz_frames.append(pre_approach_pose) # rviz_frames.append(pm.toMatrix(pm.fromMsg(res.reachable_hand_pose))) control_sequence = [] # # 0. Go to initial nice mid-joint configuration # control_sequence.append(ha.JointControlMode(goal = init_joint_config, goal_is_relative = '0', name = 'init', controller_name = 'GoToInitController')) # # 0b. Switch when config is reached # control_sequence.append(ha.JointConfigurationSwitch('init', 'Pregrasp', controller = 'GoToInitController', epsilon = str(math.radians(1.0)))) # 1. Go above the object control_sequence.append( ha.InterpolatedHTransformControlMode(pre_approach_pose, controller_name='GoAboveObject', goal_is_relative='0', name="Pregrasp")) # 1b. Switch when hand reaches the goal pose control_sequence.append( ha.FramePoseSwitch('Pregrasp', 'StayStill', controller='GoAboveObject', epsilon='0.01')) # 2. Go to gravity compensation control_sequence.append( ha.CartesianVelocityControlMode(np.array([0, 0, 0, 0, 0, 0]), controller_name='StayStillCtrl', name="StayStill", reference_frame="EE")) # 2b. Wait for a bit to allow vibrations to attenuate control_sequence.append( ha.TimeSwitch('StayStill', 'softhand_pretension', duration=handarm_params['stay_still_duration'])) # 3. Pretension speed = np.array([20]) thumb_pos = np.array([0, 0, 0]) diff_pos = np.array([0, 0, 15]) thumb_contact_force = np.array([0]) thumb_grasp_force = np.array([0]) diff_contact_force = np.array([0]) diff_grasp_force = np.array([0]) thumb_pretension = np.array([0]) diff_pretension = np.array([15]) force_feedback_ratio = np.array([0]) prox_level = np.array([0]) touch_level = np.array([0]) mode = np.array([0]) command_count = np.array([0]) control_sequence.append( ha.ros_CLASHhandControlMode(goal=np.concatenate( (speed, thumb_pos, diff_pos, thumb_contact_force, thumb_grasp_force, diff_contact_force, diff_grasp_force, thumb_pretension, diff_pretension, force_feedback_ratio, prox_level, touch_level, mode, command_count)), name='softhand_pretension')) # 3b. Switch when hand closing time ends control_sequence.append( ha.TimeSwitch('softhand_pretension', 'GoDown', duration=handarm_params['hand_closing_duration'])) # 4. Go down onto the object/table, in world frame control_sequence.append( ha.CartesianVelocityControlMode(down_IFCO_twist, controller_name='GoDown', name="GoDown", reference_frame="world")) # 4b. Switch when force threshold is exceeded force = np.array([0, 0, downward_force, 0, 0, 0]) control_sequence.append( ha.ForceTorqueSwitch('GoDown', 'CloseBeforeSlide', goal=force, norm_weights=np.array([0, 0, 1, 0, 0, 0]), jump_criterion="THRESH_UPPER_BOUND", goal_is_relative='1', frame_id='world', port='2')) # 5. Close a bit before sliding speed = np.array([30]) thumb_pos = thumb_pos_preshape diff_pos = np.array([10, 15, 0]) thumb_contact_force = np.array([0]) thumb_grasp_force = np.array([0]) diff_contact_force = np.array([0]) diff_grasp_force = np.array([0]) thumb_pretension = np.array([15]) diff_pretension = np.array([15]) force_feedback_ratio = np.array([0]) prox_level = np.array([0]) touch_level = np.array([0]) mode = np.array([0]) command_count = np.array([1]) control_sequence.append( ha.ros_CLASHhandControlMode(goal=np.concatenate( (speed, thumb_pos, diff_pos, thumb_contact_force, thumb_grasp_force, diff_contact_force, diff_grasp_force, thumb_pretension, diff_pretension, force_feedback_ratio, prox_level, touch_level, mode, command_count)), name='CloseBeforeSlide')) # 5b. Time switch control_sequence.append( ha.TimeSwitch('CloseBeforeSlide', 'SlideToWall', duration=handarm_params['hand_closing_duration'])) # 6. Go towards the wall to slide object to wall control_sequence.append( ha.CartesianVelocityControlMode(slide_IFCO_twist, controller_name='SlideToWall', name="SlideToWall", reference_frame="EE")) # 6b. Switch when the f/t sensor is triggered with normal force from wall force = np.array([0, 0, wall_force, 0, 0, 0]) control_sequence.append( ha.ForceTorqueSwitch('SlideToWall', 'softhand_close', 'ForceSwitch', goal=force, norm_weights=np.array([0, 0, 1, 0, 0, 0]), jump_criterion="THRESH_UPPER_BOUND", goal_is_relative='1', frame_id='world', frame=wall_frame, port='2')) # 7. Close the hand speed = np.array([30]) thumb_pos = np.array([0, 50, 30]) diff_pos = np.array([55, 50, 20]) thumb_contact_force = np.array([0]) thumb_grasp_force = np.array([0]) diff_contact_force = np.array([0]) diff_grasp_force = np.array([0]) thumb_pretension = np.array([15]) diff_pretension = np.array([15]) force_feedback_ratio = np.array([0]) prox_level = np.array([0]) touch_level = np.array([0]) mode = np.array([0]) command_count = np.array([1]) control_sequence.append( ha.ros_CLASHhandControlMode(goal=np.concatenate( (speed, thumb_pos, diff_pos, thumb_contact_force, thumb_grasp_force, diff_contact_force, diff_grasp_force, thumb_pretension, diff_pretension, force_feedback_ratio, prox_level, touch_level, mode, command_count)), name='softhand_close')) # 7b. Switch when hand closing time ends control_sequence.append( ha.TimeSwitch('softhand_close', 'PostGraspRotate', duration=handarm_params['hand_closing_duration'])) # 8. Rotate hand after closing and before lifting it up relative to current hand pose control_sequence.append( ha.CartesianVelocityControlMode(post_grasp_transform, controller_name='PostGraspRotate', name='PostGraspRotate', reference_frame='EE')) # 8b. Switch when hand rotated control_sequence.append( ha.TimeSwitch('PostGraspRotate', 'GoUp', duration=rotate_time)) return control_sequence, rviz_frames
def create_surface_grasp(object_frame, bounding_box, handarm_params, object_type, pre_grasp_pose=None, alternative_behavior=None): # Get the parameters from the handarm_parameters.py file obj_type_params = {} obj_params = {} if (object_type in handarm_params['surface_grasp']): obj_type_params = handarm_params['surface_grasp'][object_type] if 'object' in handarm_params['surface_grasp']: obj_params = handarm_params['surface_grasp']['object'] hand_transform = getParam(obj_type_params, obj_params, 'hand_transform') downward_force = getParam(obj_type_params, obj_params, 'downward_force') ee_in_goal_frame = getParam(obj_type_params, obj_params, 'ee_in_goal_frame') lift_time = getParam(obj_type_params, obj_params, 'short_lift_duration') init_joint_config = handarm_params['init_joint_config'] down_IFCO_speed = handarm_params['down_IFCO_speed'] up_IFCO_speed = handarm_params['up_IFCO_speed'] thumb_pos_closing = getParam(obj_type_params, obj_params, 'thumb_pos') diff_pos_closing = getParam(obj_type_params, obj_params, 'diff_pos') thumb_pos_preshape = getParam(obj_type_params, obj_params, 'thumb_pos_preshape') diff_pos_preshape = getParam(obj_type_params, obj_params, 'diff_pos_preshape') zflip_transform = tra.rotation_matrix(math.radians(180.0), [0, 0, 1]) if object_frame[0][1] < 0: object_frame = object_frame.dot(zflip_transform) if pre_grasp_pose is None: # Set the initial pose above the object goal_ = np.copy(object_frame) goal_ = goal_.dot( hand_transform ) #this is the pre-grasp transform of the signature frame expressed in the world goal_ = goal_.dot(ee_in_goal_frame) else: goal_ = pre_grasp_pose # Set the twists to use TRIK controller with # Down speed is positive because it is defined on the EE frame down_IFCO_twist = np.array([0, 0, down_IFCO_speed, 0, 0, 0]) # Slow Up speed is also positive because it is defined on the world frame up_IFCO_twist = np.array([0, 0, up_IFCO_speed, 0, 0, 0]) # Set the frames to visualize with RViz rviz_frames = [] rviz_frames.append(object_frame) rviz_frames.append(goal_) # rviz_frames.append(pm.toMatrix(pm.fromMsg(res.reachable_hand_pose))) # assemble controller sequence control_sequence = [] # # 0. Go to initial nice mid-joint configuration # control_sequence.append(ha.JointControlMode(goal = init_joint_config, goal_is_relative = '0', name = 'init', controller_name = 'GoToInitController')) # # 0b. Switch when config is reached # control_sequence.append(ha.JointConfigurationSwitch('init', 'Pregrasp', controller = 'GoToInitController', epsilon = str(math.radians(1.0)))) # 1. Go above the object - Pregrasp control_sequence.append( ha.InterpolatedHTransformControlMode(goal_, controller_name='GoAboveObject', goal_is_relative='0', name='Pregrasp')) # 1b. Switch when hand reaches the goal pose control_sequence.append( ha.FramePoseSwitch('Pregrasp', 'StayStill', controller='GoAboveObject', epsilon='0.01')) # 2. Go to gravity compensation control_sequence.append( ha.CartesianVelocityControlMode(np.array([0, 0, 0, 0, 0, 0]), controller_name='StayStillCtrl', name="StayStill", reference_frame="EE")) # 2b. Wait for a bit to allow vibrations to attenuate control_sequence.append( ha.TimeSwitch('StayStill', 'softhand_preshape', duration=handarm_params['stay_still_duration'])) speed = np.array([20]) thumb_pos = thumb_pos_preshape diff_pos = diff_pos_preshape thumb_contact_force = np.array([0]) thumb_grasp_force = np.array([0]) diff_contact_force = np.array([0]) diff_grasp_force = np.array([0]) thumb_pretension = np.array([0]) diff_pretension = np.array([0]) force_feedback_ratio = np.array([0]) prox_level = np.array([0]) touch_level = np.array([0]) mode = np.array([0]) command_count = np.array([0]) # 3. Preshape the hand control_sequence.append( ha.ros_CLASHhandControlMode(goal=np.concatenate( (speed, thumb_pos, diff_pos, thumb_contact_force, thumb_grasp_force, diff_contact_force, diff_grasp_force, thumb_pretension, diff_pretension, force_feedback_ratio, prox_level, touch_level, mode, command_count)), name='softhand_preshape')) # 3b. Switch when hand is preshaped control_sequence.append( ha.TimeSwitch('softhand_preshape', 'GoDown', duration=handarm_params['hand_closing_duration'])) # 4. Go down onto the object (relative in EE frame) - Godown control_sequence.append( ha.CartesianVelocityControlMode(down_IFCO_twist, controller_name='GoDown', name="GoDown", reference_frame="EE")) # 4b. Switch when force-torque sensor is triggered force = np.array([0, 0, downward_force, 0, 0, 0]) control_sequence.append( ha.ForceTorqueSwitch('GoDown', 'LiftHand', goal=force, norm_weights=np.array([0, 0, 1, 0, 0, 0]), jump_criterion="THRESH_UPPER_BOUND", goal_is_relative='1', frame_id='world', port='2')) # 5. Lift upwards so the hand can close control_sequence.append( ha.CartesianVelocityControlMode(up_IFCO_twist, controller_name='Lift1', name="LiftHand", reference_frame="world")) # 5b. We switch after a short time control_sequence.append( ha.TimeSwitch('LiftHand', 'softhand_close', duration=lift_time)) # 6. Close the hand speed = np.array([30]) thumb_pos = thumb_pos_closing diff_pos = diff_pos_closing thumb_contact_force = np.array([0]) thumb_grasp_force = np.array([0]) diff_contact_force = np.array([0]) diff_grasp_force = np.array([0]) thumb_pretension = np.array([15]) diff_pretension = np.array([15]) force_feedback_ratio = np.array([0]) prox_level = np.array([0]) touch_level = np.array([0]) mode = np.array([0]) command_count = np.array([2]) control_sequence.append( ha.ros_CLASHhandControlMode(goal=np.concatenate( (speed, thumb_pos, diff_pos, thumb_contact_force, thumb_grasp_force, diff_contact_force, diff_grasp_force, thumb_pretension, diff_pretension, force_feedback_ratio, prox_level, touch_level, mode, command_count)), name='softhand_close')) # 6b. Switch when hand closing time ends control_sequence.append( ha.TimeSwitch('softhand_close', 'GoUp', duration=handarm_params['hand_closing_duration'])) return control_sequence, rviz_frames
def get_transport_recipe(chosen_object, handarm_params, reaction, FailureCases, grasp_type): object_type = chosen_object['type'] # Get the relevant parameters for hand object combination if object_type in handarm_params[grasp_type]: params = handarm_params[grasp_type][object_type] else: params = handarm_params[grasp_type]['object'] # ############################ # # Get params # ############################ # up_dist = params['up_dist'] # split the lifted distance into two consecutive lifts (with success estimation in between) scale_up = 0.7 dir_up1 = tra.translation_matrix([0, 0, scale_up * up_dist]) dir_up2 = tra.translation_matrix([0, 0, (1.0 - scale_up) * up_dist]) success_estimator_timeout = handarm_params['success_estimator_timeout'] drop_off_config = handarm_params['drop_off_config'] # ############################ # # Assemble controller sequence # ############################ # control_sequence = [] # 1. Lift upwards a little bit (half way up) control_sequence.append( ha.InterpolatedHTransformControlMode(dir_up1, controller_name='GoUpHTransform', name='GoUp_1', goal_is_relative='1', reference_frame="world")) # 1b. Switch when joint configuration (half way up) is reached control_sequence.append( ha.FramePoseSwitch('GoUp_1', 'PrepareForEstimationMassMeasurement', controller='GoUpHTransform', epsilon='0.01', goal_is_relative='1', reference_frame="world")) # 2. Hold current joint config control_sequence.append( ha.BlockJointControlMode(name='PrepareForEstimationMassMeasurement')) # 2b. Wait for a bit to allow vibrations to attenuate # TODO check if this is required... control_sequence.append( ha.TimeSwitch('PrepareForEstimationMassMeasurement', 'EstimationMassMeasurement', duration=0.5)) # 3. Measure the mass again and estimate number of grasped objects (grasp success estimation) control_sequence.append( ha.BlockJointControlMode(name='EstimationMassMeasurement')) # 3b. Switches after estimation measurement was done target_cm_okay = 'GoUp_2' # 3b.1 No object was grasped => go to failure mode. target_cm_estimation_no_object = reaction.cm_name_for( FailureCases.MASS_ESTIMATION_NO_OBJECT, default=target_cm_okay) control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_estimation_no_object, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.ESTIMATION_RESULT_NO_OBJECT.value]), )) # 3b.2 More than one object was grasped => failure target_cm_estimation_too_many = reaction.cm_name_for( FailureCases.MASS_ESTIMATION_TOO_MANY, default=target_cm_okay) control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_estimation_too_many, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.ESTIMATION_RESULT_TOO_MANY.value]), )) # 3b.3 Exactly one object was grasped => success (continue lifting the object and go to drop off) control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_okay, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.ESTIMATION_RESULT_OKAY.value]), )) # 3b.4 The grasp success estimator module is inactive => directly continue lifting the object and go to drop off control_sequence.append( ha.RosTopicSwitch( 'EstimationMassMeasurement', target_cm_okay, ros_topic_name='/graspSuccessEstimator/status', ros_topic_type='Float64', goal=np.array([RESPONSES.GRASP_SUCCESS_ESTIMATOR_INACTIVE.value]), )) # 3b.5 Timeout (grasp success estimator module not started, an error occurred or it takes too long) control_sequence.append( ha.TimeSwitch('EstimationMassMeasurement', target_cm_okay, duration=success_estimator_timeout)) # 3b.6 There is no special switch for unknown error response (estimator signals ESTIMATION_RESULT_UNKNOWN_FAILURE) # Instead the timeout will trigger giving the user an opportunity to notice the erroneous result in the GUI. # 4. After estimation measurement control modes. extra_failure_cms = set() if target_cm_estimation_no_object != target_cm_okay: extra_failure_cms.add(target_cm_estimation_no_object) if target_cm_estimation_too_many != target_cm_okay: extra_failure_cms.add(target_cm_estimation_too_many) for cm in extra_failure_cms: if cm.startswith('failure_rerun'): # 4.1 Failure control mode representing grasping failure, which might be corrected by re-running the plan. control_sequence.append(ha.GravityCompensationMode(name=cm)) if cm.startswith('failure_replan'): # 4.2 Failure control mode representing grasping failure, which can't be corrected and requires to re-plan. control_sequence.append(ha.GravityCompensationMode(name=cm)) # 4.3 Success control mode. Lift hand even further control_sequence.append( ha.InterpolatedHTransformControlMode(dir_up2, controller_name='GoUpHTransform', name=target_cm_okay, goal_is_relative='1', reference_frame="world")) # 4.3b Switch when joint configuration is reached control_sequence.append( ha.FramePoseSwitch(target_cm_okay, 'GoDropOff', controller='GoUpHTransform', epsilon='0.01', goal_is_relative='1', reference_frame="world")) # 5. Go to dropOFF location control_sequence.append( ha.JointControlMode(drop_off_config, controller_name='GoToDropJointConfig', name='GoDropOff')) # 5.b Switch when joint is reached control_sequence.append( ha.JointConfigurationSwitch('GoDropOff', 'finished', controller='GoToDropJointConfig', epsilon=str(math.radians(7.)))) # 6. Block joints to finish motion and hold object in air control_sequence.append(ha.BlockJointControlMode(name='finished')) return control_sequence