Ejemplo n.º 1
0
    def get_forward_kinematics(self, joints):
        """
        Get forward kinematic from joints
        :param joints: list of joints value
        :type joints: Pose
        :return: A RobotState object
        """
        try:
            rospy.wait_for_service('compute_fk', 2)
        except (rospy.ServiceException, rospy.ROSException) as e:
            rospy.logerr("Arm commander - Impossible to connect to FK service : " + str(e))
            return RobotState()
        try:
            moveit_fk = rospy.ServiceProxy('compute_fk', GetPositionFK)
            fk_link = ['base_link', 'tool_link']
            header = Header(0, rospy.Time.now(), "world")
            rs = RobotStateMoveIt()
            rs.joint_state.name = self.__arm_state.joints_name
            rs.joint_state.position = joints
            response = moveit_fk(header, fk_link, rs)
        except rospy.ServiceException as e:
            rospy.logerr("Arm commander - Failed to get FK : " + str(e))
            return RobotState()

        pose = self.__transform_handler.ee_link_to_tcp_pose_target(response.pose_stamped[1].pose, "tool_link")

        quaternion = [pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w]
        rpy = euler_from_quaternion(quaternion)
        quaternion = (round(quaternion[0], 3), round(quaternion[1], 3), round(quaternion[2], 3),
                      round(quaternion[3], 3))
        point = (round(pose.position.x, 3),
                 round(pose.position.y, 3),
                 round(pose.position.z, 3))

        return RobotState(position=Point(*point), rpy=RPY(*rpy), orientation=Quaternion(*quaternion))
Ejemplo n.º 2
0
    def _get_new_joints_w_ik(self, shift_command):
        quat_jog = quaternion_from_euler(shift_command[3], shift_command[4],
                                         shift_command[5])
        quat_target = quaternion_multiply(quat_jog, [
            self._last_robot_state_published.orientation.x,
            self._last_robot_state_published.orientation.y,
            self._last_robot_state_published.orientation.z,
            self._last_robot_state_published.orientation.w
        ])
        rpy_target = RPY(*euler_from_quaternion(quat_target))

        self._new_robot_state = RobotState()
        self._new_robot_state.position.x = self._last_robot_state_published.position.x + shift_command[
            0]
        self._new_robot_state.position.y = self._last_robot_state_published.position.y + shift_command[
            1]
        self._new_robot_state.position.z = self._last_robot_state_published.position.z + shift_command[
            2]
        self._new_robot_state.orientation = Quaternion(*quat_target)
        self._new_robot_state.rpy = rpy_target

        self.__validate_params_pose(self._new_robot_state)

        success, joints = self.__kinematics_handler.get_inverse_kinematics(
            Pose(self._new_robot_state.position,
                 self._new_robot_state.orientation))
        return success, joints
Ejemplo n.º 3
0
 def get_workspace_poses(self, name):
     ws_raw = self.__ws_manager.read(name)
     poses = [
         RobotState(position=Point(*pose[0]), rpy=RPY(*pose[1]))
         for pose in ws_raw.robot_poses
     ]
     return poses
Ejemplo n.º 4
0
 def __callback_get_workspace_poses(self, req):
     try:
         poses = self.get_workspace_poses(req.name)
         return CommandStatus.SUCCESS, "Success", poses
     except Exception as e:
         return CommandStatus.POSES_HANDLER_READ_FAILURE, str(
             e), 4 * [RobotState()]
    def __init__(self):

        super(HoldingRegisterDataBlock, self).__init__()
        self.execution_thread = threading.Thread()
        self.is_action_client_running = False
        self.cmd_action_client = None

        # Tool
        self.current_tool_id = None
        self.list_id_grippers = [11, 12, 13, 14]
        rospy.Subscriber('/niryo_robot_tools_commander/current_id', Int32,
                         self.sub_selected_tool_id)

        # Variables
        self.workspace_name = None
        self.vision_color = None
        self.vision_shape = None
        self.height_offset = None
        self.x_rel = None
        self.y_rel = None
        self.yaw_rel = None

        # List of enums names for color and type that are available in vision package
        self.list_enum_color = [color_obj.name for color_obj in ColorHSV]
        self.list_enum_type = [type_obj.name for type_obj in ObjectType]

        # List of enums values for color and shape that are available for modbus client
        self.list_enum_color_nb = [color_obj.value for color_obj in ColorRequest]
        self.list_enum_shape_nb = [shape_obj.value for shape_obj in ShapeRequest]

        self.null_robot_state = RobotState()
Ejemplo n.º 6
0
 def __callback_target_pose(self, req):
     try:
         pose = self.get_target_pose(req.workspace, req.height_offset,
                                     req.x_rel, req.y_rel, req.yaw_rel)
         return CommandStatus.SUCCESS, "Success", pose
     except Exception as e:
         return CommandStatus.POSES_HANDLER_COMPUTE_FAILURE, str(
             e), RobotState()
Ejemplo n.º 7
0
 def save_workspace(name, list_poses_raw):
     list_poses = []
     for p in list_poses_raw:
         point = Point(*p[0])
         rpy = RPY(*p[1])
         list_poses.append(RobotState(point, rpy, Quaternion()))
     req = ManageWorkspaceRequest()
     req.cmd = ManageWorkspaceRequest.SAVE
     req.workspace.name = name
     req.workspace.poses = list_poses
     return call_service('/niryo_robot_poses_handlers/manage_workspace', ManageWorkspace, req)
Ejemplo n.º 8
0
    def __publish_state(self, _):
        self.__update_ee_link_pose()

        msg = RobotState()
        msg.position.x = self.__position[0]
        msg.position.y = self.__position[1]
        msg.position.z = self.__position[2]
        msg.rpy.roll = self.__rpy[0]
        msg.rpy.pitch = self.__rpy[1]
        msg.rpy.yaw = self.__rpy[2]
        msg.orientation.x = self.__quaternion[0]
        msg.orientation.y = self.__quaternion[1]
        msg.orientation.z = self.__quaternion[2]
        msg.orientation.w = self.__quaternion[3]
        msg.twist = self.__twist
        msg.tcp_speed = self.__tcp_speed

        self.__arm_state.robot_state = msg
        try:
            self.__robot_state_publisher.publish(msg)
        except rospy.ROSException:
            return
Ejemplo n.º 9
0
 def __callback_target_pose(self, req):
     try:
         if req.grip == req.GRIP_AUTO:
             pose = self.get_target_pose_auto_grip(req.workspace,
                                                   req.tool_id,
                                                   req.height_offset,
                                                   req.x_rel, req.y_rel,
                                                   req.yaw_rel)
         else:
             pose = self.get_target_pose(req.workspace, req.grip,
                                         req.height_offset, req.x_rel,
                                         req.y_rel, req.yaw_rel)
         return CommandStatus.SUCCESS, "Success", pose
     except Exception as e:
         return CommandStatus.POSES_HANDLER_COMPUTE_FAILURE, str(
             e), RobotState()
Ejemplo n.º 10
0
    def get_target_pose(self, workspace, height_offset, x_rel, y_rel, yaw_rel):
        """
        Computes the robot pose that can be used to grab an object which is
        positioned relative to the given workspace.

        :param workspace: name of the workspace the object is in
        :param height_offset: z-offset that is added
        :param x_rel: x relative position of the object inside working zone
        :param y_rel: y relative position of the object inside working zone
        :param yaw_rel: angle of the object inside working zone
        """
        current_ws = self.__ws_manager.read(workspace)
        self.__transform_handler.set_relative_pose_object(
            current_ws,
            x_rel,
            y_rel,
            yaw_rel,
            yaw_center=current_ws.yaw_center)
        if self.__tcp_enabled:
            base_link_to_tool_target = self.__transform_handler.get_object_transform(
                z_off=height_offset)
        else:
            current_grip = self.__grip_manager.read(
                self.__tool_id_gripname_dict[self.__tool_id])
            current_grip.transform.transform.translation.z += height_offset
            self.__transform_handler.set_grip(current_grip)
            base_link_to_tool_target = self.__transform_handler.get_gripping_transform(
            )

        q = base_link_to_tool_target.transform.rotation

        roll, pitch, yaw = euler_from_quaternion([q.x, q.y, q.z, q.w])

        pose = RobotState()
        pose.position.x = base_link_to_tool_target.transform.translation.x
        pose.position.y = base_link_to_tool_target.transform.translation.y
        pose.position.z = base_link_to_tool_target.transform.translation.z
        pose.rpy.roll = roll
        pose.rpy.pitch = pitch
        pose.rpy.yaw = yaw

        return pose
Ejemplo n.º 11
0
    def _get_new_joints_w_ik(self, shift_command):
        self._new_robot_state = RobotState()
        self._new_robot_state.position.x = self._last_robot_state_published.position.x + shift_command[
            0]
        self._new_robot_state.position.y = self._last_robot_state_published.position.y + shift_command[
            1]
        self._new_robot_state.position.z = self._last_robot_state_published.position.z + shift_command[
            2]
        self._new_robot_state.rpy.roll = self._last_robot_state_published.rpy.roll + shift_command[
            3]
        self._new_robot_state.rpy.pitch = self._last_robot_state_published.rpy.pitch + shift_command[
            4]
        self._new_robot_state.rpy.yaw = self._last_robot_state_published.rpy.yaw + shift_command[
            5]
        self._new_robot_state.orientation = Quaternion()

        self.__validate_params_pose(self._new_robot_state)

        response = self._service_ik(self._new_robot_state)
        return response.success, response.joints
Ejemplo n.º 12
0
    def __init__(self, arm_state):
        self.__arm_state = arm_state

        # - Values Init
        self._shift_mode = None
        self.__collision_detected = False
        self._last_target_values = [0.0 for _ in range(6)]
        self._last_shift_values_cmd = None
        self._target_lock = Lock()
        self._target_values = None

        self._current_jogged_joints = []
        self.__error_tolerance_joint = rospy.get_param(
            "~error_tolerance_joint")
        self.__time_without_jog_limit = rospy.get_param(
            "~time_without_jog_TCP_limit"
        )  # jog disabled after one second for the jogTCP Niryo Studio

        # - Move It Commander / Get Arm MoveGroupCommander
        self.__arm = self.__arm_state.arm

        # - Kinematics
        self.__kinematics_handler = self.__arm_state.kinematics

        # Validation
        self.__parameters_validator = self.__arm_state.parameters_validator

        jog_limits = rospy.get_param("~jog_limits")
        self.__pose_translation_max = jog_limits["translation"]
        self.__pose_rotation_max = jog_limits["rotation"]
        self.__joints_rotation_max = jog_limits["joints"]

        self._new_robot_state = RobotState()
        self._last_robot_state_published = RobotState()

        # - Publisher which publishes if JogController is enabled
        self._enabled = False
        self.__jog_errors_cpt = 0

        self._jog_enabled_publisher = rospy.Publisher(
            '/niryo_robot/jog_interface/is_enabled', Bool, queue_size=3)
        self._jog_errors_publisher = rospy.Publisher(
            '/niryo_robot/jog_interface/errors', String, queue_size=3)

        rospy.Timer(
            rospy.Duration(1.0 / rospy.get_param("~jog_enable_publish_rate")),
            self._publish_jog_enabled)

        self._check_disable_jog_timer = None
        self._last_command_timer = rospy.get_time()
        self._publish_jog_enabled()

        # - Direct publisher to joint controller
        self._joint_trajectory_publisher = rospy.Publisher(
            rospy.get_param("~joint_controller_name") + '/command',
            JointTrajectory,
            queue_size=3)

        # Publishing rate
        self._timer_rate = rospy.get_param("~jog_timer_rate_sec")
        self._publisher_joint_trajectory_timer = None

        # - Subscribers
        # - Joint controller state, used to check collisions
        rospy.Subscriber(
            rospy.get_param("~joint_controller_name") + '/state',
            JointTrajectoryControllerState,
            self.__callback_joint_controller_state)

        # topic used to jog pose via Niryo Studio, to avoid calling the service
        self._jog_command_ik = None
        rospy.Subscriber('/niryo_robot_arm_commander/send_jog_command_ik',
                         CommandJog,
                         self.__callback_send_jog_command_ik,
                         queue_size=20)

        # topic used to jog joints via Niryo Studio, to avoid calling the service
        rospy.Subscriber('/niryo_robot_arm_commander/send_jog_joints_command',
                         CommandJog,
                         self.__callback_send_jog_joints_command,
                         queue_size=10)

        # - Service
        # Service to enable Jog Controller
        rospy.Service('/niryo_robot/jog_interface/enable', SetBool,
                      self.__callback_enable_jog)
        rospy.Service('/niryo_robot/jog_interface/jog_shift_commander',
                      JogShift, self.__callback_jog_commander)
Ejemplo n.º 13
0
    def __callback_jog_commander(self, msg):
        # check if the learning mode is false and the robot is calibrated
        self.__check_before_use_jog()

        shift_mode = msg.cmd
        if shift_mode != self._shift_mode:
            self._reset_last_pub()
            self._shift_mode = shift_mode

        shift_command = list(msg.shift_values)
        if shift_mode == JogShiftRequest.POSE_SHIFT:
            shift_command[:3] = [
                min([v, math.copysign(self.__pose_translation_max, v)],
                    key=abs) for v in shift_command[:3]
            ]
            shift_command[3:] = [
                min([v, math.copysign(self.__pose_rotation_max, v)], key=abs)
                for v in shift_command[3:]
            ]
            try:
                success, potential_target_values = self._get_new_joints_w_ik(
                    shift_command)
            except ArmCommanderException as e:
                return e.status, "Error while validating pose : {}".format(
                    e.message)
            if not success:
                return CommandStatus.NO_PLAN_AVAILABLE, "Unable to find on invert kinematics for the target position"
            else:
                self.set_target_values(potential_target_values)
        else:
            # Accumulate multiple commands if they come faster than the publish rate
            shift_command = [
                min([v, math.copysign(self.__joints_rotation_max, v)], key=abs)
                for v in shift_command
            ]
            target_values = [
                actual + shift for actual, shift in zip(
                    self._last_target_values, shift_command)
            ]

            target_values = self.__limit_params_joints(target_values)

            joints_to_jog = [
                i for i, value in enumerate(shift_command) if value != 0
            ]

            try:
                self.__validate_params_joints(
                    target_values
                )  # validate joints according to joints limits
            except ArmCommanderException as e:
                return e.status, "Error while validating joints : {}".format(
                    e.message)

            # validate target joints validity, based on collisions checking
            try:
                valid, link_colliding1, link_colliding2 = self.__check_joint_validity_moveit(
                    target_values)
                if not valid:
                    if link_colliding1 is not None and link_colliding2 is not None:
                        return CommandStatus.JOG_CONTROLLER_FAILURE, \
                               "Joints target unreachable because of collision between {} and {}".format(
                                   link_colliding1, link_colliding2)
                    else:
                        return CommandStatus.JOG_CONTROLLER_FAILURE, \
                               "Joints target unreachable because of collision between two parts of Ned"
            except rospy.ServiceException as e:
                return e, "Error while validating joint : {}".format(e.message)

            self._current_jogged_joints = joints_to_jog
            self.set_target_values(target_values)
            self._new_robot_state = RobotState()
        return CommandStatus.SUCCESS, "Command send"
Ejemplo n.º 14
0
    def __callback_send_jog_joints_command(self, msg):
        # check if the learning mode is false and the robot is calibrated
        self.__check_before_use_jog()

        shift_mode = msg.cmd
        if shift_mode != self._shift_mode:
            self._reset_last_pub()
            self._shift_mode = shift_mode

        if self._last_shift_values_cmd != msg.shift_values:
            self._last_shift_values_cmd = msg.shift_values
            self.__jog_errors_cpt = 0

        shift_command = list(msg.shift_values)
        if shift_mode == JogShiftRequest.JOINTS_SHIFT:
            # Accumulate multiple commands if they come faster than the publish rate
            shift_command = [
                min([v, math.copysign(self.__joints_rotation_max, v)], key=abs)
                for v in shift_command
            ]
            target_values = [
                actual + shift for actual, shift in zip(
                    self._last_target_values, shift_command)
            ]

            # get index of the jogged joints in a list
            joints_to_jog = [
                i for i, value in enumerate(shift_command) if value != 0
            ]

            target_values = self.__limit_params_joints(target_values)

            try:
                self.__validate_params_joints(
                    target_values
                )  # validate joints according to joints limits
            except ArmCommanderException as e:
                message = "Jog Controller - Error while validating joint : {}".format(
                    e.message)
                rospy.logwarn_throttle(1, message)
                return self.__publish_jog_error(
                    CommandStatus.JOG_CONTROLLER_FAILURE, message)

            # validate target joints validity, based on collisions checking
            try:
                valid, link_colliding1, link_colliding2 = self.__check_joint_validity_moveit(
                    target_values)
                if not valid:
                    return self.__publish_jog_error(
                        CommandStatus.JOG_CONTROLLER_FAILURE,
                        "Joints target unreachable because of collision between {} and {}"
                        .format(link_colliding1, link_colliding2))
            except rospy.ServiceException as e:
                message = "Jog Controller - Error while validating joint : {}".format(
                    e.message)
                rospy.logwarn_throttle(1, message)
                return self.__publish_jog_error(
                    CommandStatus.JOG_CONTROLLER_FAILURE, message)

            if self.__collision_detected:
                return self.__publish_jog_error(
                    CommandStatus.JOG_CONTROLLER_FAILURE, "Collision detected")

            self.set_target_values(target_values)
            self._current_jogged_joints = joints_to_jog
            self._new_robot_state = RobotState()
            return self.__publish_jog_error(CommandStatus.SUCCESS, "Success")
Ejemplo n.º 15
0
    def __init__(self, parameters_validator):
        # - Publisher which publishes if JogController is enabled
        self._enabled = False
        self._jog_enabled_publisher = rospy.Publisher(
            '/niryo_robot/jog_interface/is_enabled', Bool, queue_size=1)
        rospy.Timer(
            rospy.Duration(1.0 / rospy.get_param("~jog_enable_publish_rate")),
            self._publish_jog_enabled)
        self._check_disable_jog_timer = None
        self._last_command_timer = rospy.get_time()

        self._publish_jog_enabled()

        # Service to enable Jog Controller
        rospy.Service('/niryo_robot/jog_interface/enable', SetBool,
                      self.__callback_enable_jog)

        # - Direct publisher to joint controller
        self._joint_trajectory_publisher = rospy.Publisher(
            rospy.get_param("~joint_controller_name") + '/command',
            JointTrajectory,
            queue_size=3)
        # Publishing rate
        self._timer_rate = rospy.get_param("~jog_timer_rate_sec")
        self._publisher_joint_trajectory_timer = None

        # - Subscribers
        self._joint_states = None
        rospy.Subscriber('/joint_states', JointState,
                         self.__callback_joint_states)

        self._robot_state = None
        rospy.Subscriber('/niryo_robot/robot_state', RobotState,
                         self.__callback_sub_robot_state)

        self.__learning_mode_on = None
        rospy.Subscriber('/niryo_robot/learning_mode/state', Bool,
                         self.__callback_sub_learning_mode)

        self.__hardware_status = None
        rospy.Subscriber('/niryo_robot_hardware_interface/hardware_status',
                         HardwareStatus, self.__callback_hardware_status)

        # - Service
        rospy.Service('/niryo_robot/jog_interface/jog_shift_commander',
                      JogShift, self.__callback_jog_commander)

        # - Kinematics
        self._new_robot_state = RobotState()
        self._last_robot_state_published = RobotState()
        self._service_ik = rospy.ServiceProxy(
            '/niryo_robot/kinematics/inverse', GetIK)

        # - Values Init
        self._shift_mode = None
        self._last_target_values = [0.0 for _ in range(6)]
        self._target_values = None

        # Validation
        self.__parameters_validator = parameters_validator
        jog_limits = rospy.get_param("~jog_limits")
        self.__pose_translation_max = jog_limits["translation"]
        self.__pose_rotation_max = jog_limits["rotation"]
        self.__joints_rotation_max = jog_limits["joints"]

        # - Others param
        self.__time_without_jog_limit = rospy.get_param(
            "~time_without_jog_limit")
Ejemplo n.º 16
0
    def __callback_jog_commander(self, msg):
        if self.__hardware_status.calibration_needed or self.__hardware_status.calibration_in_progress:
            return CommandStatus.ABORTED, "Cannot send command cause Jog because calibration is not done"
        if self.__learning_mode_on:
            try:
                rospy.wait_for_service('/niryo_robot/learning_mode/activate',
                                       2)
                service = rospy.ServiceProxy(
                    '/niryo_robot/learning_mode/activate', SetBool)
                result = service(True)
                if result.status != CommandStatus.SUCCESS:
                    return CommandStatus.ABORTED, "Cannot send command cause Jog because learning mode is on and" \
                                                  " cannot be disabled"
                rospy.sleep(0.1)
            except (rospy.ROSException, rospy.ServiceException):
                return CommandStatus.ABORTED, "Error while trying to turn Off learning mode"

        if not self._enabled:
            ret, str_msg = self.enable()
            if ret == CommandStatus.ABORTED:
                return CommandStatus.ABORTED, "Cannot send command cause Jog is not activated and cannot be"
        self._last_command_timer = rospy.get_time()

        shift_mode = msg.cmd
        if shift_mode != self._shift_mode:
            self._reset_last_pub()
            self._shift_mode = shift_mode

        shift_command = list(msg.shift_values)
        if shift_mode == JogShiftRequest.POSE_SHIFT:
            shift_command[:3] = [
                min([v, math.copysign(self.__pose_translation_max, v)],
                    key=abs) for v in shift_command[:3]
            ]
            shift_command[3:] = [
                min([v, math.copysign(self.__pose_rotation_max, v)], key=abs)
                for v in shift_command[3:]
            ]
            try:
                success, potential_target_values = self._get_new_joints_w_ik(
                    shift_command)
            except ArmCommanderException as e:
                return e.status, "Error while validating pose : {}".format(
                    e.message)
            if not success:
                return CommandStatus.NO_PLAN_AVAILABLE, "Unable to find on invert kinematics for the target position"
            else:
                self._target_values = potential_target_values
        else:
            # Accumulate multiple commands if they come faster than the publish rate
            shift_command = [
                min([v, math.copysign(self.__joints_rotation_max, v)], key=abs)
                for v in shift_command
            ]
            target_values = [
                actual + shift for actual, shift in zip(
                    self._last_target_values, shift_command)
            ]

            target_values = self.__limit_params_joints(target_values)

            try:
                self.__validate_params_joints(target_values)
            except ArmCommanderException as e:
                return e.status, "Error while validating joints : {}".format(
                    e.message)

            self._target_values = target_values
            self._new_robot_state = RobotState()
        return CommandStatus.SUCCESS, "Command send"