def __init__(self, robot_helper):
        self.gripper_usage = self.BOTH_ARM
        super(ArtPr2Interface, self).__init__(robot_helper)
        self.motors_halted_sub = rospy.Subscriber(
            "/pr2_ethercat/motors_halted", Bool, self.motors_halted_cb)
        self.halt_motors_srv = rospy.ServiceProxy(
            '/pr2_ethercat/halt_motors',
            Empty)  # TODO wait for service? where?

        self.reset_motors_srv = rospy.ServiceProxy(
            '/pr2_ethercat/reset_motors',
            Empty)  # TODO wait for service? where?

        self.look_at_pub = rospy.Publisher(robot_helper.robot_ns + "/look_at",
                                           PointStamped,
                                           queue_size=10)

        self.gripper_pubs = []
        for pref in ('/l_', '/r_'):
            self.gripper_pubs.append(
                rospy.Publisher(pref + 'gripper_controller/command',
                                Pr2GripperCommand,
                                queue_size=10))

        for arm in self._arms:  # type: ArtGripper
            if arm.arm_id == self.LEFT_ARM:
                arm.arm_up = ArtBrainUtils.create_service_client(
                    robot_helper.robot_ns + "/" + self.LEFT_ARM + "/arm_up",
                    Trigger)
            elif arm.arm_id == self.RIGHT_ARM:
                arm.arm_up = ArtBrainUtils.create_service_client(
                    robot_helper.robot_ns + "/" + self.RIGHT_ARM + "/arm_up",
                    Trigger)
Ejemplo n.º 2
0
    def select_arm_for_drill(self, obj_to_drill, objects_frame_id, tf_listener):

        assert isinstance(obj_to_drill, ObjInstance)

        free_arm = self.select_free_arm()
        if free_arm in [None, self.LEFT_ARM, self.RIGHT_ARM]:
            return free_arm
        objects_frame_id = ArtBrainUtils.normalize_frame_id(objects_frame_id)

        # frameExists("marker") always returns False -> but it is probably not necessary to test it - it should exist
        # if tf_listener.frameExists(
        #        "base_link") and tf_listener.frameExists(ArtBrainUtils.normalize_frame_id(objects_frame_id)):

        obj_pose = PoseStamped()
        obj_pose.pose = obj_to_drill.pose
        obj_pose.header.frame_id = objects_frame_id
        # exact time does not matter in this case
        obj_pose.header.stamp = rospy.Time(0)
        tf_listener.waitForTransform(
            'base_link',
            obj_pose.header.frame_id,
            obj_pose.header.stamp,
            rospy.Duration(1))
        obj_pose = tf_listener.transformPose(
            'base_link', obj_pose)
        if obj_pose.pose.position.y < 0:
            return self.RIGHT_ARM
        else:
            return self.LEFT_ARM
Ejemplo n.º 3
0
    def select_arm_for_pick(self, obj, objects_frame_id, tf_listener):

        assert isinstance(obj, ObjInstance)

        free_arm = self.select_free_arm()
        if free_arm in [None, self.LEFT_ARM, self.RIGHT_ARM]:
            return free_arm
        objects_frame_id = ArtBrainUtils.normalize_frame_id(objects_frame_id)

        obj_pose = PoseStamped()
        obj_pose.pose = obj.pose
        obj_pose.header.frame_id = objects_frame_id
        # exact time does not matter in this case
        obj_pose.header.stamp = rospy.Time(0)
        tf_listener.waitForTransform(
            'base_link',
            obj_pose.header.frame_id,
            obj_pose.header.stamp,
            rospy.Duration(1))
        obj_pose = tf_listener.transformPose(
            'base_link', obj_pose)
        if obj_pose.pose.position.y < 0:
            return self.RIGHT_ARM
        else:
            return self.LEFT_ARM
Ejemplo n.º 4
0
    def __init__(self, *args, **kwargs):

        super(VisualInspectionFSM, self).__init__(*args, **kwargs)

        self.visual_inspection_srv = ArtBrainUtils.create_service_client('/art/visual_inspection/start', Trigger)
        self.visual_inspection_result_sub = rospy.Subscriber(
            '/art/visual_inspection/result', Bool, self.visual_inspection_result_cb, queue_size=1)
        self.visual_inspection_result = None
Ejemplo n.º 5
0
    def __init__(self, robot_helper):
        self.gripper_usage = self.BOTH_ARM
        super(ArtPr2Interface, self).__init__(robot_helper)
        self.motors_halted_sub = rospy.Subscriber(
            "/pr2_ethercat/motors_halted", Bool, self.motors_halted_cb)
        self.halt_motors_srv = rospy.ServiceProxy(
            '/pr2_ethercat/halt_motors', Empty)  # TODO wait for service? where?

        self.reset_motors_srv = rospy.ServiceProxy(
            '/pr2_ethercat/reset_motors', Empty)  # TODO wait for service? where?

        self.gripper_pubs = []
        for pref in ('/l_', '/r_'):
            self.gripper_pubs.append(rospy.Publisher(pref + 'gripper_controller/command', Pr2GripperCommand, queue_size=10))

        for arm in self._arms:  # type: ArtGripper
            if arm.arm_id == self.LEFT_ARM:
                arm.arm_up = ArtBrainUtils.create_service_client(robot_helper.robot_ns + "/" + self.LEFT_ARM + "/arm_up", Trigger)
            elif arm.arm_id == self.RIGHT_ARM:
                arm.arm_up = ArtBrainUtils.create_service_client(robot_helper.robot_ns + "/" + self.RIGHT_ARM + "/arm_up", Trigger)
    def select_arm_for_pick_from_feeder(self, pick_pose, tf_listener):

        assert isinstance(pick_pose, PoseStamped)

        pick_pose.header.frame_id = ArtBrainUtils.normalize_frame_id(
            pick_pose.header.frame_id)
        free_arm = self.select_free_arm()
        if free_arm in [None, self.LEFT_ARM, self.RIGHT_ARM]:
            return free_arm

        pick_pose.header.stamp = rospy.Time(0)
        tf_listener.waitForTransform('base_link', pick_pose.header.frame_id,
                                     pick_pose.header.stamp, rospy.Duration(1))
        obj_pose = tf_listener.transformPose('base_link', pick_pose)
        if obj_pose.pose.position.y < 0:
            return self.RIGHT_ARM
        else:
            return self.LEFT_ARM
Ejemplo n.º 7
0
    def select_arm_for_pick_from_feeder(self, pick_pose, tf_listener):

        assert isinstance(pick_pose, PoseStamped)

        pick_pose.header.frame_id = ArtBrainUtils.normalize_frame_id(pick_pose.header.frame_id)
        free_arm = self.select_free_arm()
        if free_arm in [None, self.LEFT_ARM, self.RIGHT_ARM]:
            return free_arm

        pick_pose.header.stamp = rospy.Time(0)
        tf_listener.waitForTransform(
            'base_link',
            pick_pose.header.frame_id,
            pick_pose.header.stamp,
            rospy.Duration(1))
        obj_pose = tf_listener.transformPose(
            'base_link', pick_pose)
        if obj_pose.pose.position.y < 0:
            return self.RIGHT_ARM
        else:
            return self.LEFT_ARM
Ejemplo n.º 8
0
    def pick_object_from_polygon(self, instruction, update_state_manager=True):

        obj_type = self.brain.ph.get_object(self.brain.block_id,
                                            instruction.id)[0][0]
        polygon = self.brain.ph.get_polygon(self.brain.block_id,
                                            instruction.id)[0][0]

        obj = ArtBrainUtils.get_pick_obj_from_polygon(obj_type, polygon,
                                                      self.brain.objects)
        if obj is None or obj.object_id is None or obj.object_id == "":
            self.fsm.error(
                severity=ArtBrainErrorSeverities.WARNING,
                error=ArtBrainErrors.ERROR_OBJECT_MISSING_IN_POLYGON)
            if update_state_manager:
                self.brain.state_manager.update_program_item(
                    self.brain.ph.get_program_id(), self.brain.block_id,
                    instruction)
            return
        if update_state_manager:
            self.brain.state_manager.update_program_item(
                self.brain.ph.get_program_id(), self.brain.block_id,
                instruction, {"SELECTED_OBJECT_ID": obj.object_id})
        arm_id = self.brain.robot.select_arm_for_pick(
            obj, self.brain.objects.header.frame_id, self.brain.tf_listener)
        severity, error, arm_id = self.brain.robot.pick_object(
            obj, instruction.id, arm_id)
        if error is not None:
            if error is not ArtBrainErrors.ERROR_ROBOT_HALTED:
                self.brain.try_robot_arms_get_ready([arm_id])
            else:
                self.fsm.error(severity=severity, error=error, halted=True)
                return
            self.fsm.error(severity=severity, error=error)

        else:
            self.fsm.done(success=True)
Ejemplo n.º 9
0
    def place_object_to_grid(self,
                             instruction,
                             update_state_manager=True,
                             get_ready_after_place=True):
        rospy.logerr(
            "DO NOT USE, DEPRECATED! (place_object_to_grid in node.py)")
        pose = ArtBrainUtils.get_place_pose(instruction)

        if pose is None or len(pose) < 1:
            self.fsm.error(severity=ArtBrainErrorSeverities.ERROR,
                           error=ArtBrainErrors.ERROR_NOT_ENOUGH_PLACE_POSES)
            if update_state_manager:
                self.brain.state_manager.update_program_item(
                    self.brain.ph.get_program_id(), self.brain.block_id,
                    instruction)
            return
        else:
            if len(instruction.ref_id) < 1:
                self.fsm.error(severity=ArtBrainErrorSeverities.ERROR,
                               error=ArtBrainErrors.
                               ERROR_NO_PICK_INSTRUCTION_ID_FOR_PLACE)
                if update_state_manager:
                    self.brain.state_manager.update_program_item(
                        self.brain.ph.get_program_id(), self.brain.block_id,
                        instruction)
                return
            rospy.logdebug(self.brain.instruction)
            gripper = self.brain.get_gripper_by_pick_instruction_id(
                instruction.ref_id)

            if not self.brain.check_gripper_for_place(gripper):
                return

            if gripper.holding_object is None:
                rospy.logerr("Robot is not holding selected object")
                self.fsm.error(severity=ArtBrainErrorSeverities.WARNING,
                               error=ArtBrainErrors.
                               ERROR_GRIPPER_NOT_HOLDING_SELECTED_OBJECT)
                if update_state_manager:
                    self.brain.state_manager.update_program_item(
                        self.brain.ph.get_program_id(), self.brain.block_id,
                        instruction)
                return
            if update_state_manager:
                self.brain.state_manager.update_program_item(
                    self.brain.ph.get_program_id(), self.brain.block_id,
                    instruction,
                    {"SELECTED_OBJECT_ID": gripper.holding_object.object_id})

            if self.brain.place_object(gripper.holding_object,
                                       pose[0],
                                       gripper,
                                       pick_only_y_axis=False):
                instruction.pose.pop(0)
                gripper.holding_object = None
                if get_ready_after_place:
                    gripper.get_ready()
                if len(instruction.pose) > 0:
                    self.fsm.done(success=True)
                else:
                    self.fsm.error(
                        severity=ArtBrainErrorSeverities.ERROR,
                        error=ArtBrainErrors.ERROR_NOT_ENOUGH_PLACE_POSES)
            else:
                gripper.get_ready()
                self.fsm.error(severity=ArtBrainErrorSeverities.WARNING,
                               error=ArtBrainErrors.ERROR_PLACE_FAILED)
Ejemplo n.º 10
0
    def pick_object_from_feeder(self, instruction):

        self.brain.state_manager.update_program_item(
            self.brain.ph.get_program_id(), self.brain.block_id, instruction)

        if not self.brain.ph.is_object_set(self.brain.block_id,
                                           instruction.id):
            self.fsm.error(severity=ArtBrainErrorSeverities.ERROR,
                           error=ArtBrainErrors.ERROR_OBJECT_NOT_DEFINED)
            return
        obj_type = self.brain.ph.get_object(self.brain.block_id,
                                            instruction.id)[0][0]
        obj = ArtBrainUtils.get_pick_obj_from_feeder(obj_type)

        if not self.brain.ph.is_pose_set(self.brain.block_id, instruction.id):
            self.fsm.error(severity=ArtBrainErrorSeverities.ERROR,
                           error=ArtBrainErrors.ERROR_PICK_POSE_NOT_SELECTED)
            return
        pick_pose, _ = self.brain.ph.get_pose(self.brain.block_id,
                                              instruction.id)
        if pick_pose is None:
            self.fsm.error(severity=ArtBrainErrorSeverities.ERROR,
                           error=ArtBrainErrors.ERROR_PICK_POSE_NOT_SELECTED)
        else:
            pick_pose = pick_pose[0]
        arm_id = self.brain.robot.select_arm_for_pick_from_feeder(
            pick_pose, self.brain.tf_listener)
        severity, error, arm_id = self.brain.robot.move_arm_to_pose(
            pick_pose, arm_id, picking=True)
        if error is not None:
            if error is not ArtBrainErrors.ERROR_ROBOT_HALTED:
                self.brain.try_robot_arms_get_ready([arm_id])
            else:
                self.fsm.error(severity=severity, error=error, halted=True)
                return
            self.fsm.error(severity=severity, error=error)
            return

        start_time = rospy.Time.now()
        object_found_time = None

        pick_object = None
        pick_object_dist = None
        rospy.loginfo("Looking for: " + str(obj.object_type))

        ignored_objects = []

        while True:

            now = rospy.Time.now()

            if start_time + rospy.Duration(5.0) < now:
                rospy.logwarn("Can't find object in feeder in given time.")
                break

            if object_found_time and object_found_time + \
                    rospy.Duration(1.0) < now:
                break

            for inst in self.brain.objects.instances:  # type: ObjInstance

                if inst.object_id in ignored_objects:
                    continue

                if inst.object_type != obj.object_type:
                    continue

                # TODO read table size from some param
                # TODO on_table -> use method from some helper class (shared
                # with gui...), add it to message?
                on_table = inst.pose.position.z < 0.1 and 0 < inst.pose.position.x < 1.5

                if on_table:
                    rospy.logdebug("Ignoring 'on_table' object: " +
                                   inst.object_id)
                    ignored_objects.append(inst.object_id)
                    continue

                ps = PoseStamped()
                ps.header.frame_id = self.brain.objects.header.frame_id
                ps.header.stamp = rospy.Time(0)
                ps.pose = inst.pose
                # TODO compute transform once and then only apply it
                ps = self.brain.tf_listener.transformPose(
                    self.brain.robot.get_arm_by_id(arm_id).gripper_link, ps)
                # distance in x does not matter - we want the object closest to
                # the x-axis of gripper
                dist = math.sqrt(ps.pose.position.y**2 + ps.pose.position.z**2)
                rospy.logdebug("Distance to object ID " + inst.object_id +
                               " is: " + str(dist) + ", dist to gripper: " +
                               str(ps.pose.position.x))

                if dist > 0.1:
                    rospy.logdebug("Object is too far in y/z.")
                    continue

                # dist in x has to be bigger than length of the gripper
                if 0.05 < ps.pose.position.x < 0.2:

                    if pick_object_dist is None or dist < pick_object_dist:
                        object_found_time = now
                        pick_object = inst
                        pick_object_dist = dist
                        rospy.logdebug("Storing object: " + inst.object_id)

                else:
                    rospy.logdebug("Object to far in x.")

        if not pick_object:
            self.brain.try_robot_arms_get_ready([arm_id])
            self.fsm.error(severity=ArtBrainErrorSeverities.WARNING,
                           error=ArtBrainErrors.ERROR_OBJECT_MISSING)
            return

        severity, error, arm_id = self.brain.robot.pick_object(
            pick_object, instruction.id, arm_id, from_feeder=True)
        if error is not None:
            if error is not ArtBrainErrors.ERROR_ROBOT_HALTED:
                self.brain.try_robot_arms_get_ready([arm_id])
            else:
                self.fsm.error(severity=severity, error=error, halted=True)
                return
            self.fsm.error(severity=severity, error=error)
        else:
            self.fsm.done(success=True)
Ejemplo n.º 11
0
    def drill_points(self, instruction, set_drilled_flag=True):

        # TODO drill_enabled() je metoda ArtRobotArmHelper - jenze tady jeste nevim ktere rameno se bude pouzivat
        # TODO ERROR_NOT_IMPLEMENTED -> myslim ze by bylo lepsi zkontrolovat program pri pozadavku na spusteni -
        # jestli neobsahuje robotem nepodporovane instrukce a pak uz se tim nezabyvat - ke spusteni programu s
        # instrukci co robot nepodporuje by vubec nemelo dojit
        # if not self.rh.drill_enabled():
        #    self.fsm.error(severity=ArtBrainErrorSeverities.ERROR,
        #                   error=ArtBrainErrors.ERROR_NOT_IMPLEMENTED)
        #    return

        if not self.brain.check_robot():
            return
        objects, _ = self.brain.ph.get_object(self.brain.block_id,
                                              instruction.id)

        # TODO tohle nemuze nastat - kontroluje program helper
        if len(objects) < 1:
            self.fsm.error(severity=ArtBrainErrorSeverities.ERROR,
                           error=ArtBrainErrors.ERROR_OBJECT_NOT_DEFINED)
            return
        obj_type = self.brain.ph.get_object(self.brain.block_id,
                                            instruction.id)[0][0]

        obj_to_drill = None
        objects_in_polygon = ArtBrainUtils.get_objects_in_polygon(
            obj_type,
            self.brain.ph.get_polygon(self.brain.block_id,
                                      instruction.id)[0][0],
            self.brain.objects)
        if not objects_in_polygon:
            self.fsm.error(
                severity=ArtBrainErrorSeverities.WARNING,
                error=ArtBrainErrors.ERROR_OBJECT_MISSING_IN_POLYGON)
            return

        for obj in objects_in_polygon:

            drilled = False
            for flag in obj.flags:
                if flag.key == "drilled" and flag.value == "true":
                    rospy.logdebug("Object " + obj.object_id +
                                   " already drilled.")
                    drilled = True
                    break
            if drilled:
                continue

            obj_to_drill = obj
            break

        if obj_to_drill is None:
            rospy.loginfo("All objects in polygon seems to be drilled.")
            # self.try_robot_arms_get_ready([arm_id])
            self.fsm.done(success=False)
            return

        arm_id = self.brain.robot.select_arm_for_drill(obj_to_drill,
                                                       self.brain.tf_listener)
        if arm_id != self.brain.last_drill_arm_id:
            if self.brain.last_drill_arm_id is not None:
                self.brain.robot.arms_get_ready([self.brain.last_drill_arm_id])
            self.brain.last_drill_arm_id = copy.deepcopy(arm_id)

        rospy.loginfo("Drilling object: " + obj_to_drill.object_id)

        poses = self.brain.ph.get_pose(self.brain.block_id, instruction.id)[0]

        for hole_number, pose in enumerate(poses):
            rospy.loginfo("Hole number: " + str(hole_number + 1) +
                          " (out of: " + str(len(poses)) + ")")

            if self.brain.program_pause_request or self.brain.program_paused:
                self.brain.program_pause_request = False
                self.brain.program_paused = True
                r = rospy.Rate(2)
                while self.brain.program_paused:
                    r.sleep()
            self.brain.state_manager.update_program_item(
                self.brain.ph.get_program_id(), self.brain.block_id,
                instruction, {
                    "SELECTED_OBJECT_ID": obj_to_drill.object_id,
                    "DRILLED_HOLE_NUMBER": str(hole_number + 1)
                })

            severity, error, arm_id = self.brain.robot.drill_point(
                arm_id, [pose], obj_to_drill, "TODO", drill_duration=0)
            if error:
                rospy.logwarn("Drilling failed...")
                self.fsm.error(severity=severity, error=error)
                return

        if set_drilled_flag:
            req = ObjectFlagSetRequest()
            req.object_id = obj_to_drill.object_id
            req.flag.key = "drilled"
            req.flag.value = "true"

            ret = self.brain.set_object_flag_srv_client.call(req)

            if not ret.success:
                rospy.logerr("Failed to set flag!")

            st = copy.deepcopy(self.brain.objects.header.stamp)
            # need to wait (for new message from tracker) until flag is really set
            # otherwise object might be drilled again...
            # TODO check object flags insted of stamp? or remember that object
            # was drilled e.g. in self.drilled_objects ?
            while self.brain.objects.header.stamp == st:
                rospy.sleep(0.1)

        rospy.loginfo("Object drilled: " + obj_to_drill.object_id)

        self.fsm.done(success=True)
Ejemplo n.º 12
0
    def place_object_to_container(self,
                                  instruction,
                                  update_state_manager=True,
                                  get_ready_after_place=False):

        container_type = self.brain.ph.get_object(self.brain.block_id,
                                                  instruction.id)[0][0]

        arm_id = self.brain.robot.select_arm_for_place("", instruction.ref_id)
        if arm_id is None:
            if update_state_manager:
                self.brain.state_manager.update_program_item(
                    self.brain.ph.get_program_id(), self.brain.block_id,
                    instruction)
            self.fsm.error(
                severity=ArtBrainErrorSeverities.WARNING,
                error=InterfaceState.ERROR_GRIPPER_NOT_HOLDING_SELECTED_OBJECT)
            return

        polygon = self.brain.ph.get_polygon(self.brain.block_id,
                                            self.brain.instruction.id)[0][0]
        container = ArtBrainUtils.get_pick_obj_from_polygon(
            container_type, polygon, self.brain.objects)
        if container is None:
            self.fsm.error(
                severity=ArtBrainErrorSeverities.WARNING,
                error=ArtBrainErrors.ERROR_OBJECT_MISSING_IN_POLYGON)
            return

        if update_state_manager:
            self.brain.state_manager.update_program_item(
                self.brain.ph.get_program_id(), self.brain.block_id,
                self.brain.instruction, {
                    "SELECTED_OBJECT_ID":
                    self.brain.robot.get_arm_holding_object(arm_id).object_id,
                    "SELECTED_CONTAINER_ID":
                    container.object_id
                })

        container_bb = self.brain.art.get_object_type(
            container_type).bbox.dimensions
        place_pose = PoseStamped()
        place_pose.header.frame_id = "marker"
        place_pose.pose = container.pose

        place_pose.pose.position.z += container_bb[
            2] / 2.0 + 0.065  # TODO plus half of bb height of the picked object
        severity, error, _ = self.brain.robot.place_object_to_pose(
            place_pose, arm_id)
        if error is not None:
            if error is not ArtBrainErrors.ERROR_ROBOT_HALTED:
                self.brain.try_robot_arms_get_ready([arm_id])
            else:
                self.fsm.error(severity=severity, error=error, halted=True)
                return
            self.fsm.error(severity=severity, error=error)
            return
        else:
            self.brain.robot.get_arm_by_id(
                arm_id).last_pick_instruction_id = None
            if get_ready_after_place:
                self.brain.try_robot_arms_get_ready([arm_id])
            self.fsm.done(success=True)
            return