def __init__(self, name, hand_or_arm="both"): self.__save = rospy.ServiceProxy( 'save_robot_state', SaveState) self.__name = name if hand_or_arm == "arm": self.__commander = SrArmCommander() elif hand_or_arm == 'hand': hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() hand_serial = hand_parameters.mapping.keys()[0] self.__commander = SrHandCommander(hand_parameters=hand_parameters, hand_serial=hand_serial) else: self.__arm_commander = SrArmCommander() hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() hand_serial = hand_parameters.mapping.keys()[0] self.__hand_commander = SrHandCommander(hand_parameters=hand_parameters, hand_serial=hand_serial) self.__hand_or_arm = hand_or_arm
def test_hand_finder_init(self): hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() hand_commander = SrHandCommander( hand_parameters=hand_parameters, hand_serial=hand_parameters.mapping.keys()[0]) self.assertGreater(len(hand_commander.get_joints_position()), 0, "No joints found, init must have failed.")
def test_no_hand_robot_description_exists_finder(self): if rospy.has_param("hand"): rospy.delete_param("hand") if rospy.has_param("robot_description"): rospy.delete_param("robot_description") rospy.set_param("robot_description", rospy.get_param("two_hands_description")) hand_finder = HandFinder() self.assertEqual(len(hand_finder.get_hand_parameters().joint_prefix), 0, "correct parameters without a hand") self.assertEqual(len(hand_finder.get_hand_parameters().mapping), 0, "correct parameters without a hand") self.assertEqual(len(hand_finder.get_hand_joints()), 0, "correct joints without a hand") self.assertEqual(len(hand_finder.get_calibration_path()), 0, "correct calibration path without a hand") self.assertEqual( len(hand_finder.get_hand_control_tuning().friction_compensation), 0, "correct tuning without a hands") self.assertEqual( len(hand_finder.get_hand_control_tuning().host_control), 0, "correct tuning without a hands") self.assertEqual( len(hand_finder.get_hand_control_tuning().motor_control), 0, "correct tuning without a hands")
def __init__(self, trajectory, service_timeout): self.trajectory = trajectory self.service_timeout = service_timeout self.hand_finder = HandFinder() self.joints = self.hand_finder.get_hand_joints() ros_pack = rospkg.RosPack() sr_robot_launch_path = ros_pack.get_path('sr_robot_launch') self.hand_mapping = self.hand_finder.get_hand_parameters().mapping self.yaml_file_path = {} for hand in self.hand_mapping: self.yaml_file_path[self.hand_mapping[hand]] = ( sr_robot_launch_path + "/config/" + self.hand_mapping[hand] + "_trajectory_controller.yaml")
def test_no_hand_no_robot_description_finder(self): if rospy.has_param("hand"): rospy.delete_param("hand") if rospy.has_param("robot_description"): rospy.delete_param("robot_description") hand_finder = HandFinder() self.assertEqual(len(hand_finder.get_hand_parameters().joint_prefix), 0, "correct parameters without a hand") self.assertEqual(len(hand_finder.get_hand_parameters().mapping), 0, "correct parameters without a hand") self.assertEqual(len(hand_finder.get_hand_joints()), 0, "correct joints without a hand")
def __init__(self): """ Useful python library to communicate with the etherCAT hand. """ self.hand_finder = HandFinder() self.hand_params = self.hand_finder.get_hand_parameters() self.hand_id = '' if len(self.hand_params.mapping) is not 0: self.hand_id = self.hand_params.mapping.itervalues().next() self.debug_subscriber = None self.joint_state_subscriber = None self.record_js_callback = None self.raw_values = [] self.pid_services = {} self.publishers = {} self.positions = {} self.velocities = {} self.efforts = {} self.msg_to_send = Float64() self.msg_to_send.data = 0.0 # TODO: read this from parameter server self.compounds = {} joint_to_sensor_mapping = [] try: rospy.wait_for_message(self.hand_id + "/debug_etherCAT_data", EthercatDebug, timeout=0.2) try: joint_to_sensor_mapping \ = rospy.get_param(self.hand_id + "/joint_to_sensor_mapping") except: rospy.logwarn("The parameter joint_to_sensor_mapping " "was not found, you won't be able to get the " "raw values from the EtherCAT compound sensors.") except: pass for mapping in joint_to_sensor_mapping: if mapping[0] is 1: if "THJ5" in mapping[1][0]: self.compounds["THJ5"] = [["THJ5A", mapping[1][1]], ["THJ5B", mapping[2][1]]] elif "WRJ1" in mapping[1][0]: self.compounds["WRJ1"] = [["WRJ1A", mapping[1][1]], ["WRJ1B", mapping[2][1]]]
def __init__(self, config_file_path, service_timeout, excluded_joints=[]): self._config_file_path = config_file_path self._service_timeout = service_timeout hand_finder = HandFinder() self._hand_mapping = hand_finder.get_hand_parameters().mapping self._joints = hand_finder.get_hand_joints() self._nonpresent_joints = list(ControllerSpawner.JOINT_NAMES) for side in self._joints: for joint in self._joints[side]: if joint in self._nonpresent_joints: self._nonpresent_joints.remove(joint) self._excluded_joints = excluded_joints self._excluded_joints = list( set(self._excluded_joints) | set(self._nonpresent_joints)) rospy.logwarn("Excluded joints:") rospy.logwarn(self._excluded_joints)
def __init__(self, name, prefix=None): """ Initialize MoveGroupCommander object @param name - name of the MoveIt group """ self._name = name self._move_group_commander = MoveGroupCommander(name) self._robot_commander = RobotCommander() self._robot_name = self._robot_commander._r.get_robot_name() self.refresh_named_targets() self._warehouse_name_get_srv = rospy.ServiceProxy("get_robot_state", GetState) self._planning_scene = PlanningSceneInterface() self._joint_states_lock = threading.Lock() self._joint_states_listener = \ rospy.Subscriber("joint_states", JointState, self._joint_states_callback, queue_size=1) self._joints_position = {} self._joints_velocity = {} self._joints_effort = {} self.__plan = None rospy.wait_for_service('compute_ik') self._compute_ik = rospy.ServiceProxy('compute_ik', GetPositionIK) self._forward_k = rospy.ServiceProxy('compute_fk', GetPositionFK) # prefix of the trajectory controller if prefix is not None: self._prefix = prefix elif name in self.__group_prefixes.keys(): self._prefix = self.__group_prefixes[name] else: # Group name is one of the ones to plan for specific fingers. # We need to find the hand prefix using the hand finder hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() hand_serial = hand_parameters.mapping.keys()[0] self._prefix = hand_parameters.joint_prefix[hand_serial] self._set_up_action_client() threading.Thread(None, rospy.spin)
def generate_controllers(): controllers = [] hand_finder = HandFinder() joints = hand_finder.get_hand_joints() mapping = hand_finder.get_hand_parameters().mapping for hand in mapping: prefix = mapping[hand] for joint in joints[prefix]: if joint[3:5].lower() == 'th' or joint[3:5].lower( ) == 'wr' or (joint[6] != '1' and joint[6] != '2'): joint_controller = 'cal_sh_' + joint.lower() else: joint = joint[:6] + '0' joint_controller = 'cal_sh_' + joint.lower() if joint_controller not in controllers: controllers.append(joint_controller) return controllers
def generate_reset_services_list(self): reset_service_list = [] generated_reset_service_list = [] service_list = [] # We first read the list of available motor reset services in this namespace # this will allow us to avoid having to know the name of the robot driver node ns = rospy.get_namespace() while not reset_service_list: rospy.sleep(0.5) service_list = rosservice.get_service_list(namespace=ns) reset_service_list = [ srv for srv in service_list if '/reset_motor_' in srv ] if not reset_service_list: rospy.loginfo("Waiting for motor reset services") # We generate a list of the services that we expect to find # and merely throw a warning if some of them didn't turn up in the available service list hand_finder = HandFinder() joints = hand_finder.get_hand_joints() mapping = hand_finder.get_hand_parameters().mapping for hand in mapping: prefix = mapping[hand] for joint in joints[prefix]: if not (joint[3:5].lower() == 'th' or joint[3:5].lower() == 'wr' or (joint[6] != '1' and joint[6] != '2')): joint = joint[:6] + '0' joint_reset_service = joint[:2] + '/reset_motor_' + joint[ 3:].upper() if joint_reset_service not in generated_reset_service_list: generated_reset_service_list.append(joint_reset_service) for gen_srv in generated_reset_service_list: gen_srv_match_list = [ srv for srv in reset_service_list if gen_srv in srv ] if not gen_srv_match_list: rospy.logwarn("Expected service not found: %s", gen_srv) return reset_service_list
def __init__(self, name, hand_or_arm="both", hand_h=False): self.__save = rospy.ServiceProxy('save_robot_state', SaveState) self.__name = name self.__hand_h = hand_h if hand_or_arm == "arm": self.__commander = SrArmCommander() elif hand_or_arm == 'hand': if self.__hand_h: self.__commander = SrRobotCommander("hand_h", prefix="H1_") else: hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() hand_serial = hand_parameters.mapping.keys()[0] self.__commander = SrHandCommander( hand_parameters=hand_parameters, hand_serial=hand_serial) else: self.__arm_commander = SrArmCommander() if self.__hand_h: self.__hand_commander = SrRobotCommander("hand_h", prefix="H1_") else: hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() hand_serial = hand_parameters.mapping.keys()[0] self.__hand_commander = SrHandCommander( hand_parameters=hand_parameters, hand_serial=hand_serial) self.__hand_or_arm = hand_or_arm rs = RobotState() current_dict = {} if self.__hand_or_arm == "both": current_dict = self.__arm_commander.get_robot_state_bounded() robot_name = self.__arm_commander.get_robot_name() elif self.__hand_or_arm == "arm": current_dict = self.__commander.get_current_state_bounded() robot_name = self.__commander.get_robot_name() elif self.__hand_or_arm == "hand": current_dict = self.__commander.get_current_state_bounded() robot_name = self.__commander.get_robot_name() else: rospy.logfatal("Unknown save type") exit(-1) rospy.loginfo(current_dict) rs.joint_state = JointState() rs.joint_state.name = current_dict.keys() rs.joint_state.position = current_dict.values() self.__save(self.__name, robot_name, rs)
def __init__(self, name=None, prefix=None, hand_parameters=None, hand_serial=None, hand_number=0): """ Initialize the hand commander, using either a name + prefix, or the parameters returned by the hand finder. @param name - name of the MoveIt group @param prefix - prefix used for the tactiles and max_force @param hand_parameters - from hand_finder.get_hand_parameters(). Will overwrite the name and prefix @param hand_serial - which hand are you using @param hand_number - which hand in a multi-hand system to use (starting at 0 and sorted by name/serial). """ self._hand_h = False if name is None and prefix is None and hand_parameters is None and hand_serial is None: hand_finder = HandFinder() if hand_finder.hand_e_available(): name, prefix, hand_serial = hand_finder.get_hand_e(number=hand_number) elif hand_finder.hand_h_available(): self._hand_h = True name, prefix, hand_serial = hand_finder.get_hand_h(number=hand_number) else: rospy.logfatal("No hands found and no information given to define hand commander.") raise SrRobotCommanderException("No hand found.") elif hand_parameters is not None: # extracting the name and prefix from the hand finder parameters if len(hand_parameters.mapping) == 0: rospy.logfatal("No hand detected") raise SrRobotCommanderException("No hand found.") hand_mapping = hand_parameters.mapping[hand_serial] prefix = hand_parameters.joint_prefix[hand_serial] if name is None: if hand_mapping == 'rh': name = "right_hand" else: name = "left_hand" else: if name is None: name = "right_hand" if prefix is None: prefix = "rh_" super(SrHandCommander, self).__init__(name) if not self._hand_h: self._tactiles = TactileReceiver(prefix) # appends trailing slash if necessary self._topic_prefix = prefix if self._topic_prefix and self._topic_prefix.endswith("_"): self._topic_prefix = self._topic_prefix[:-1] # Remove trailing _ if self._topic_prefix and not self._topic_prefix.endswith("/"): self._topic_prefix += "/" self._hand_serial = hand_serial
def test_two_hand_robot_description_exists_finder(self): if rospy.has_param("hand"): rospy.delete_param("hand") if rospy.has_param("robot_description"): rospy.delete_param("robot_description") rospy.set_param("hand/joint_prefix/1", "rh_") rospy.set_param("hand/mapping/1", "right") rospy.set_param("hand/joint_prefix/2", "lh_") rospy.set_param("hand/mapping/2", "left") rospy.set_param("robot_description", rospy.get_param("two_hands_description")) hand_finder = HandFinder() # hand params self.assertIsNotNone(hand_finder.get_hand_parameters(), "Parameters extracted.") self.assertEqual(len(hand_finder.get_hand_parameters().mapping), 2, "It should be two mappings") self.assertIn("right", hand_finder.get_hand_parameters().mapping.values(), "It should be right mapping") self.assertIn("left", hand_finder.get_hand_parameters().mapping.values(), "It should be left mapping") self.assertEqual(len(hand_finder.get_hand_parameters().joint_prefix), 2, "It should be two joint_prefixes") self.assertIn("rh_", hand_finder.get_hand_parameters().joint_prefix.values(), "It should be rh_ prefix") self.assertIn("lh_", hand_finder.get_hand_parameters().joint_prefix.values(), "It should be rh_ prefix") # hand joints self.assertIsNotNone(hand_finder.get_hand_joints(), "Joints extracted.") self.assertEqual(len(hand_finder.get_hand_joints().keys()), 2, "It should be two mappings") self.assertIn("right", hand_finder.get_hand_joints(), "Mapping should be in the joints result") joints = hand_finder.get_hand_joints()['right'] self.assertEqual(len(joints), 1, "Joint number should be 1") self.assertNotIn("rh_FFJ3", hand_finder.get_hand_joints()["right"], "rh_FFJ3 joint should not be in the joints list") self.assertIn("rh_RFJ4", hand_finder.get_hand_joints()["right"], "rh_RFJ4 joint should be in the joints list") self.assertIn("left", hand_finder.get_hand_joints(), "Mapping should be in the joints result") joints = hand_finder.get_hand_joints()['left'] self.assertEqual(len(joints), 1, "Joint number should be 1") self.assertNotIn("lh_FFJ3", hand_finder.get_hand_joints()["left"], "lh_FFJ3 joint should not be in the joints list") self.assertIn("lh_LFJ4", hand_finder.get_hand_joints()["left"], "lh_LFJ4 joint should be in the joints list") # calibration self.assertIsNotNone(hand_finder.get_calibration_path(), "Calibration extracted.") calibration_path = hand_finder.get_calibration_path()['right'] self.assertEqual( calibration_path, self.ethercat_path + "/calibrations/right/" + "calibration.yaml", "incorrect calibration file") calibration_path = hand_finder.get_calibration_path()['left'] self.assertEqual( calibration_path, self.ethercat_path + "/calibrations/left/" + "calibration.yaml", "incorrect calibration file") # tuning self.assertIsNotNone(hand_finder.get_hand_control_tuning(), "Control tuning parameters extracted.") ctrl_tun_friction_comp_path = hand_finder.get_hand_control_tuning( ).friction_compensation['right'] self.assertEqual( ctrl_tun_friction_comp_path, self.ethercat_path + "/controls/friction_compensation.yaml", "incorrect friction compensation file") ctrl_tun_motors_path = hand_finder.get_hand_control_tuning( ).motor_control['right'] self.assertEqual( ctrl_tun_motors_path, self.ethercat_path + "/controls/motors/right/motor_board_effort_controllers.yaml", "incorrect motor config file") ctrl_tun_host_control_paths = hand_finder.get_hand_control_tuning( ).host_control['right'] self.assertEqual(len(ctrl_tun_host_control_paths), len(controller_params), "incorrect number of host controllers param") for controller_path, controller_param in zip( ctrl_tun_host_control_paths, controller_params): self.assertEqual( controller_path, self.ethercat_path + "/controls/host/right/" + controller_param, "incorrect controller config file") ctrl_tun_friction_comp_path = hand_finder.get_hand_control_tuning( ).friction_compensation['left'] self.assertEqual( ctrl_tun_friction_comp_path, self.ethercat_path + "/controls/friction_compensation.yaml", "incorrect friction compensation file") ctrl_tun_motors_path = hand_finder.get_hand_control_tuning( ).motor_control['left'] self.assertEqual( ctrl_tun_motors_path, self.ethercat_path + "/controls/motors/left/motor_board_effort_controllers.yaml", "incorrect motor config file") ctrl_tun_host_control_paths = hand_finder.get_hand_control_tuning( ).host_control['left'] self.assertEqual(len(ctrl_tun_host_control_paths), len(controller_params), "incorrect number of host controllers param") for controller_path, controller_param in zip( ctrl_tun_host_control_paths, controller_params): self.assertEqual( controller_path, self.ethercat_path + "/controls/host/left/" + controller_param, "incorrect controller config file")
class TrajectoryControllerSpawner(object): def __init__(self, trajectory, service_timeout): self.trajectory = trajectory self.service_timeout = service_timeout self.hand_finder = HandFinder() self.joints = self.hand_finder.get_hand_joints() ros_pack = rospkg.RosPack() sr_robot_launch_path = ros_pack.get_path('sr_robot_launch') self.hand_mapping = self.hand_finder.get_hand_parameters().mapping self.yaml_file_path = {} for hand in self.hand_mapping: self.yaml_file_path[self.hand_mapping[hand]] = ( sr_robot_launch_path + "/config/" + self.hand_mapping[hand] + "_trajectory_controller.yaml") def generate_parameters(self): for hand in self.yaml_file_path: with open(self.yaml_file_path[hand], 'r') as yaml_file: yaml_content = yaml.load(yaml_file) if hand + "_trajectory_controller" not in yaml_content.keys(): rospy.logerr("there are errors opening trajectory controller yaml file") else: hand_trajectory = yaml_content[hand + "_trajectory_controller"] if rospy.has_param('~exclude_wrist') and rospy.get_param('~exclude_wrist'): hand_trajectory['joints'] = [s for s in self.joints[hand] if "WR" not in s] else: hand_trajectory['joints'] = self.joints[hand] for joint_name in hand_trajectory['constraints'].keys(): if (joint_name not in hand_trajectory['joints'] and joint_name != 'goal_time' and joint_name != 'stopped_velocity_tolerance'): del hand_trajectory['constraints'][joint_name] param_prefix = hand + "_trajectory_controller/" rospy.set_param(param_prefix + 'allow_partial_joints_goal', hand_trajectory['allow_partial_joints_goal']) rospy.set_param(param_prefix + 'joints', hand_trajectory['joints']) rospy.set_param(param_prefix + 'stop_trajectory_duration', hand_trajectory['stop_trajectory_duration']) rospy.set_param(param_prefix + 'type', hand_trajectory['type']) constrain_prefix = param_prefix + 'constraints/' for constraint in hand_trajectory['constraints']: if constraint == 'goal_time' or constraint == 'stopped_velocity_tolerance': rospy.set_param(constrain_prefix + constraint, hand_trajectory['constraints'][constraint]) else: rospy.set_param(constrain_prefix + constraint + '/goal', hand_trajectory['constraints'][constraint]['goal']) rospy.set_param(constrain_prefix + constraint + '/trajectory', hand_trajectory['constraints'][constraint]['trajectory']) @staticmethod def check_joint(joint, controllers_to_start, controller_names): if joint[3:5].lower() == 'th' or joint[3:5].lower() == 'wr' or (joint[6] != '1' and joint[6] != '2'): joint_controller = 'sh_' + joint.lower() + "_position_controller" else: joint = joint[:6] + '0' joint_controller = 'sh_' + joint.lower() + "_position_controller" if joint_controller not in controller_names and joint_controller not in controllers_to_start: controllers_to_start.append(joint_controller) def set_controller(self): controllers_to_start = [] for hand_serial in self.hand_mapping: hand_prefix = self.hand_mapping[hand_serial] success = True try: rospy.wait_for_service('controller_manager/list_controllers', self.service_timeout) list_controllers = rospy.ServiceProxy( 'controller_manager/list_controllers', ListControllers) running_controllers = list_controllers() except rospy.ServiceException: success = False rospy.logerr("Failed to load trajectory controller") if success: already_running = False controller_names = [] for controller_state in running_controllers.controller: controller_names.append(controller_state.name) if controller_state.name == hand_prefix + '_trajectory_controller': already_running = True if self.trajectory and not already_running: controllers_to_start.append(hand_prefix + '_trajectory_controller') for joint in self.joints[hand_prefix]: TrajectoryControllerSpawner.check_joint(joint, controllers_to_start, controller_names) for load_control in controllers_to_start: try: rospy.wait_for_service('controller_manager/load_controller', self.service_timeout) load_controllers = rospy.ServiceProxy('controller_manager/load_controller', LoadController) loaded_controllers = load_controllers(load_control) except rospy.ServiceException: success = False if not loaded_controllers.ok: success = False try: rospy.wait_for_service('controller_manager/switch_controller', self.service_timeout) switch_controllers = rospy.ServiceProxy('controller_manager/switch_controller', SwitchController) switched_controllers = switch_controllers(controllers_to_start, None, SwitchController._request_class.BEST_EFFORT) except rospy.ServiceException: success = False if not switched_controllers.ok: success = False if not success: rospy.logerr("Failed to launch trajectory controller!") @staticmethod def wait_for_topic(topic_name, timeout): if not topic_name: return True # This has to be a list since Python has a peculiar mechanism to determine # whether a variable is local to a function or not: # if the variable is assigned in the body of the function, then it is # assumed to be local. Modifying a mutable object (like a list) # works around this debatable "design choice". wait_for_topic_result = [None] def wait_for_topic_cb(msg): wait_for_topic_result[0] = msg rospy.logdebug("Heard from wait-for topic: %s" % str(msg.data)) rospy.Subscriber(topic_name, Bool, wait_for_topic_cb) started_waiting = rospy.Time.now().to_sec() # We might not have received any time messages yet warned_about_not_hearing_anything = False while not wait_for_topic_result[0]: rospy.sleep(0.01) if rospy.is_shutdown(): return False if not warned_about_not_hearing_anything: if rospy.Time.now().to_sec() - started_waiting > timeout: warned_about_not_hearing_anything = True rospy.logwarn("Controller Spawner hasn't heard anything from its \"wait for\" topic (%s)" % topic_name) while not wait_for_topic_result[0].data: rospy.sleep(0.01) if rospy.is_shutdown(): return False return True
class EtherCAT_Hand_Lib(object): """ Useful python library to communicate with the etherCAT hand. """ sensors = ["FFJ1", "FFJ2", "FFJ3", "FFJ4", "MFJ1", "MFJ2", "MFJ3", "MFJ4", "RFJ1", "RFJ2", "RFJ3", "RFJ4", "LFJ1", "LFJ2", "LFJ3", "LFJ4", "LFJ5", "THJ1", "THJ2", "THJ3", "THJ4", "THJ5A", "THJ5B", "WRJ1A", "WRJ1B", "WRJ2", "ACCX", "ACCY", "ACCZ", "GYRX", "GYRY", "GYRZ", "AN0", "AN1", "AN2", "AN3"] def __init__(self): """ Useful python library to communicate with the etherCAT hand. """ self.hand_finder = HandFinder() self.hand_params = self.hand_finder.get_hand_parameters() self.hand_id = '' if len(self.hand_params.mapping) is not 0: self.hand_id = self.hand_params.mapping.itervalues().next() self.debug_subscriber = None self.joint_state_subscriber = None self.record_js_callback = None self.raw_values = [] self.pid_services = {} self.publishers = {} self.positions = {} self.velocities = {} self.efforts = {} self.msg_to_send = Float64() self.msg_to_send.data = 0.0 # TODO: read this from parameter server self.compounds = {} joint_to_sensor_mapping = [] try: rospy.wait_for_message(self.hand_id + "/debug_etherCAT_data", EthercatDebug, timeout=0.2) try: joint_to_sensor_mapping \ = rospy.get_param(self.hand_id + "/joint_to_sensor_mapping") except: rospy.logwarn("The parameter joint_to_sensor_mapping " "was not found, you won't be able to get the " "raw values from the EtherCAT compound sensors.") except: pass for mapping in joint_to_sensor_mapping: if mapping[0] is 1: if "THJ5" in mapping[1][0]: self.compounds["THJ5"] = [["THJ5A", mapping[1][1]], ["THJ5B", mapping[2][1]]] elif "WRJ1" in mapping[1][0]: self.compounds["WRJ1"] = [["WRJ1A", mapping[1][1]], ["WRJ1B", mapping[2][1]]] def sendupdate(self, joint_name, target, controller_type="effort"): if joint_name not in self.publishers: topic = "sh_" + joint_name.lower() + "_" + controller_type \ + "_controller/command" self.publishers[joint_name] = rospy.Publisher(topic, Float64) self.msg_to_send.data = math.radians(float(target)) self.publishers[joint_name].publish(self.msg_to_send) def get_position(self, joint_name): value = None try: value = self.positions[joint_name] except: # We check if the reason to except is that we are trying to # access the joint 0 # Position of the J0 is the addition of the positions of J1 and J2 m = re.match("(?P<finger>\w{2})J0", joint_name) if m is not None: value = self.positions[m.group("finger") + "J1"] +\ self.positions[m.group("finger") + "J2"] else: raise return value def get_velocity(self, joint_name): value = None try: value = self.velocities[joint_name] except: # We check if the reason to except is that we are # trying to access the joint 0 m = re.match("(?P<finger>\w{2})J0", joint_name) if m is not None: value = self.velocities[m.group("finger") + "J1"] + \ self.velocities[m.group("finger") + "J2"] else: raise return value def get_effort(self, joint_name): value = None try: value = self.efforts[joint_name] except: # We check if the reason to except is that we are # trying to access the joint 0 # Effort of the J0 is the same as the effort of # J1 and J2, so we pick J1 m = re.match("(?P<finger>\w{2})J0", joint_name) if m is not None: value = self.efforts[m.group("finger") + "J1"] else: raise return value def start_record(self, joint_name, callback): self.record_js_callback = callback def stop_record(self, joint_name): self.callback = None def set_pid(self, joint_name, pid_parameters): """ """ if joint_name not in self.pid_services: service_name = "sr_hand_robot/change_force_PID_" + joint_name self.pid_services[joint_name] = rospy.ServiceProxy(service_name, ForceController) self.pid_services[joint_name](pid_parameters["max_pwm"], pid_parameters["sgleftref"], pid_parameters["sgrightref"], pid_parameters["f"], pid_parameters["p"], pid_parameters["i"], pid_parameters["d"], pid_parameters["imax"], pid_parameters["deadband"], pid_parameters["sign"]) def debug_callback(self, msg): if not(all(v == 0 for v in msg.sensors)): self.raw_values = msg.sensors def joint_state_callback(self, msg): for name, pos, vel, effort in \ zip(msg.name, msg.position, msg.velocity, msg.effort): self.positions[name] = pos self.velocities[name] = vel self.efforts[name] = effort if self.record_js_callback is not None: self.record_js_callback() def get_raw_value(self, sensor_name): value = 0.0 if not self.raw_values: rospy.logwarn("No values received from the etherCAT hand.") return -1.0 try: if sensor_name in self.compounds.keys(): for sub_compound in self.compounds[sensor_name]: index = self.sensors.index(sub_compound[0]) value = value + (self.raw_values[index] * sub_compound[1]) else: index = self.sensors.index(sensor_name) value = self.raw_values[index] except: # if the value is not found we're returning 4095 value = 4095 return value def get_average_raw_value(self, sensor_name, number_of_samples=10): """ Get the average raw value for the given sensor, average on number_of_samples """ tmp_raw_values = [] for i in range(0, number_of_samples): tmp_raw_values.append(self.get_raw_value(sensor_name)) time.sleep(0.002) average = float(sum(tmp_raw_values)) / len(tmp_raw_values) return average def activate(self): # check if something is being published to those topics, otherwise # return false (the library is not activated) try: rospy.wait_for_message(self.hand_id + "/debug_etherCAT_data", EthercatDebug, timeout=0.2) rospy.wait_for_message("joint_states", JointState, timeout=0.2) except: return False self.debug_subscriber =\ rospy.Subscriber(self.hand_id + "/debug_etherCAT_data", EthercatDebug, self.debug_callback) self.joint_state_subscriber =\ rospy.Subscriber("joint_states", JointState, self.joint_state_callback) return True def activate_joint_states(self): # check if something is being published to this topic, otherwise # return false (the library is not activated) try: rospy.wait_for_message("joint_states", JointState, timeout=0.2) self.joint_state_subscriber = \ rospy.Subscriber("joint_states", JointState, self.joint_state_callback) except: return False return True def on_close(self): if self.debug_subscriber is not None: self.debug_subscriber.unregister() self.debug_subscriber = None if self.joint_state_subscriber is not None: self.joint_state_subscriber.unregister() self.joint_state_subscriber = None
#!/usr/bin/env python # Example where two joints are specified and move with a sinusoidal trajectory, with a pi/4 phase difference import rospy from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint from sr_robot_commander.sr_hand_commander import SrHandCommander from sr_utilities.hand_finder import HandFinder from numpy import sin, cos, pi, arange rospy.init_node("joint_sine_example", anonymous=True) # handfinder is used to access the hand parameters hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() prefix = hand_parameters.mapping.values() hand_serial = hand_parameters.mapping.keys()[0] hand_commander = SrHandCommander(hand_parameters=hand_parameters, hand_serial=hand_serial) # cycles per second of sine wave f = 1 # angular frequency, rads/s w = 2 * pi * f # time for motion to complete ts = 20 # specify 2 joints to move joint_names = [prefix[0] + '_FFJ3', prefix[0] + '_RFJ3']
def test_one_hand_no_prefix_no_ns_robot_description_exists_finder(self): if rospy.has_param("hand"): rospy.delete_param("hand") if rospy.has_param("robot_description"): rospy.delete_param("robot_description") rospy.set_param("hand/joint_prefix/1", "") rospy.set_param("hand/mapping/1", "") rospy.set_param("robot_description", rospy.get_param("right_hand_description_no_prefix")) hand_finder = HandFinder() # hand params self.assertIsNotNone(hand_finder.get_hand_parameters(), "Parameters extracted.") self.assertEqual(len(hand_finder.get_hand_parameters().mapping), 1, "It should be only one mapping") self.assertEqual(len(hand_finder.get_hand_parameters().joint_prefix), 1, "It should be only one joint_prefix") self.assertEqual(hand_finder.get_hand_parameters().mapping['1'], "1", "It should be the serial id as mapping") self.assertEqual(hand_finder.get_hand_parameters().joint_prefix['1'], "", "It should be only an empty prefix") # hand joints self.assertIsNotNone(hand_finder.get_hand_joints(), "Joints extracted.") self.assertEqual(len(list(hand_finder.get_hand_joints().keys())), 1, "It should be only one mapping") self.assertIn("1", hand_finder.get_hand_joints(), "Mapping should be in the joints result") joints = hand_finder.get_hand_joints()['1'] self.assertEqual(len(joints), 1, "Joint number should be 1") self.assertNotIn("FFJ3", hand_finder.get_hand_joints()["1"], "FFJ3 joint should not be in the joints list") self.assertIn("RFJ4", hand_finder.get_hand_joints()["1"], "RFJ4 joint should be in the joints list")
def test_one_hand_no_prefix_no_ns_robot_description_exists_finder(self): if rospy.has_param("hand"): rospy.delete_param("hand") if rospy.has_param("robot_description"): rospy.delete_param("robot_description") rospy.set_param("hand/joint_prefix/1", "") rospy.set_param("hand/mapping/1", "") rospy.set_param("robot_description", rospy.get_param("right_hand_description_no_prefix")) hand_finder = HandFinder() # hand params self.assertIsNotNone(hand_finder.get_hand_parameters(), "Parameters extracted.") self.assertEqual(len(hand_finder.get_hand_parameters().mapping), 1, "It should be only one mapping") self.assertEqual(len(hand_finder.get_hand_parameters().joint_prefix), 1, "It should be only one joint_prefix") self.assertEqual(hand_finder.get_hand_parameters().mapping['1'], "1", "It should be the serial id as mapping") self.assertEqual(hand_finder.get_hand_parameters().joint_prefix['1'], "", "It should be only an empty prefix") # hand joints self.assertIsNotNone(hand_finder.get_hand_joints(), "Joints extracted.") self.assertEqual(len(hand_finder.get_hand_joints().keys()), 1, "It should be only one mapping") self.assertIn("1", hand_finder.get_hand_joints(), "Mapping should be in the joints result") joints = hand_finder.get_hand_joints()['1'] self.assertEqual(len(joints), 1, "Joint number should be 1") self.assertNotIn("FFJ3", hand_finder.get_hand_joints()["1"], "FFJ3 joint should not be in the joints list") self.assertIn("RFJ4", hand_finder.get_hand_joints()["1"], "RFJ4 joint should be in the joints list") # calibration self.assertIsNotNone(hand_finder.get_calibration_path(), "Calibration extracted.") calibration_path = hand_finder.get_calibration_path()['1'] self.assertEqual( calibration_path, self.ethercat_path + "/calibrations/1/" + "calibration.yaml", "incorrect calibration file") # tuning self.assertIsNotNone(hand_finder.get_hand_control_tuning(), "Control tuning parameters extracted.") ctrl_tun_friction_comp_path = hand_finder.get_hand_control_tuning( ).friction_compensation['1'] self.assertEqual( ctrl_tun_friction_comp_path, self.ethercat_path + "/controls/friction_compensation.yaml", "incorrect friction compensation file") ctrl_tun_motors_path = hand_finder.get_hand_control_tuning( ).motor_control['1'] self.assertEqual( ctrl_tun_motors_path, self.ethercat_path + "/controls/motors/1/motor_board_effort_controllers.yaml", "incorrect motor config file") ctrl_tun_host_control_paths = hand_finder.get_hand_control_tuning( ).host_control['1'] self.assertEqual(len(ctrl_tun_host_control_paths), len(controller_params), "incorrect number of host controllers param") for controller_path, controller_param in zip( ctrl_tun_host_control_paths, controller_params): self.assertEqual( controller_path, self.ethercat_path + "/controls/host/1/" + controller_param, "incorrect controller config file")
def test_two_hand_robot_description_exists_finder(self): if rospy.has_param("hand"): rospy.delete_param("hand") if rospy.has_param("robot_description"): rospy.delete_param("robot_description") rospy.set_param("hand/joint_prefix/1", "rh_") rospy.set_param("hand/mapping/1", "right") rospy.set_param("hand/joint_prefix/2", "lh_") rospy.set_param("hand/mapping/2", "left") rospy.set_param("robot_description", rospy.get_param("two_hands_description")) hand_finder = HandFinder() # hand params self.assertIsNotNone(hand_finder.get_hand_parameters(), "Parameters extracted.") self.assertEqual(len(hand_finder.get_hand_parameters().mapping), 2, "It should be two mappings") self.assertIn("right", list(hand_finder.get_hand_parameters().mapping.values()), "It should be right mapping") self.assertIn("left", list(hand_finder.get_hand_parameters().mapping.values()), "It should be left mapping") self.assertEqual(len(hand_finder.get_hand_parameters().joint_prefix), 2, "It should be two joint_prefixes") self.assertIn( "rh_", list(hand_finder.get_hand_parameters().joint_prefix.values()), "It should be rh_ prefix") self.assertIn( "lh_", list(hand_finder.get_hand_parameters().joint_prefix.values()), "It should be rh_ prefix") # hand joints self.assertIsNotNone(hand_finder.get_hand_joints(), "Joints extracted.") self.assertEqual(len(list(hand_finder.get_hand_joints().keys())), 2, "It should be two mappings") self.assertIn("right", hand_finder.get_hand_joints(), "Mapping should be in the joints result") joints = hand_finder.get_hand_joints()['right'] self.assertEqual(len(joints), 1, "Joint number should be 1") self.assertNotIn("rh_FFJ3", hand_finder.get_hand_joints()["right"], "rh_FFJ3 joint should not be in the joints list") self.assertIn("rh_RFJ4", hand_finder.get_hand_joints()["right"], "rh_RFJ4 joint should be in the joints list") self.assertIn("left", hand_finder.get_hand_joints(), "Mapping should be in the joints result") joints = hand_finder.get_hand_joints()['left'] self.assertEqual(len(joints), 1, "Joint number should be 1") self.assertNotIn("lh_FFJ3", hand_finder.get_hand_joints()["left"], "lh_FFJ3 joint should not be in the joints list") self.assertIn("lh_LFJ4", hand_finder.get_hand_joints()["left"], "lh_LFJ4 joint should be in the joints list")
from sr_robot_commander.sr_hand_commander import SrHandCommander from sr_utilities.hand_finder import HandFinder rospy.init_node("partial_traj_example", anonymous=True) rospy.sleep(1) # Do not start at time zero def construct_trajectory_point(posture, duration): trajectory_point = JointTrajectoryPoint() trajectory_point.time_from_start = rospy.Duration.from_sec(float(duration)) for key in joint_trajectory.joint_names: trajectory_point.positions.append(posture[key]) return trajectory_point hand_finder = HandFinder() hand_parameters = hand_finder.get_hand_parameters() hand_serial = hand_parameters.mapping.keys()[0] hand_commander = SrHandCommander(hand_parameters=hand_parameters, hand_serial=hand_serial) hand_mapping = hand_parameters.mapping[hand_serial] # Hand joints are detected joints = hand_finder.get_hand_joints()[hand_mapping] open_hand = {'rh_FFJ1': 0.0, 'rh_FFJ2': 0.0, 'rh_FFJ3': 0.0, 'rh_FFJ4': 0.0, 'rh_MFJ1': 0.0, 'rh_MFJ2': 0.0, 'rh_MFJ3': 0.0, 'rh_MFJ4': 0.0, 'rh_RFJ1': 0.0, 'rh_RFJ2': 0.0, 'rh_RFJ3': 0.0, 'rh_RFJ4': 0.0,
def test_one_hand_no_mapping_no_robot_description_finder(self): if rospy.has_param("hand"): rospy.delete_param("hand") if rospy.has_param("robot_description"): rospy.delete_param("robot_description") rospy.set_param("hand/joint_prefix/1", "rh_") rospy.set_param("hand/mapping/1", "") hand_finder = HandFinder() # hand params self.assertIsNotNone(hand_finder.get_hand_parameters(), "Parameters extracted.") self.assertEqual(len(hand_finder.get_hand_parameters().mapping), 1, "It should be only one mapping") self.assertEqual(len(hand_finder.get_hand_parameters().joint_prefix), 1, "It should be only one joint_prefix") self.assertEqual(hand_finder.get_hand_parameters().mapping['1'], "1", "It should be the serial id as mapping") self.assertEqual(hand_finder.get_hand_parameters().joint_prefix['1'], "rh_", "It should be only rh_ prefix") # hand joints self.assertIsNotNone(hand_finder.get_hand_joints(), "Joints extracted.") self.assertEqual(len(list(hand_finder.get_hand_joints().keys())), 1, "It should be only one mapping") print(hand_finder.get_hand_joints()) self.assertIn("1", hand_finder.get_hand_joints(), "Serial should be in the joints result") joints = hand_finder.get_hand_joints()['1'] # use serial self.assertEqual(len(joints), 24, "Joint number should be 24") self.assertIn("rh_FFJ3", hand_finder.get_hand_joints()["1"], "FFJ3 joint should be in the joints list")