예제 #1
0
def recover():
    """Recover from difficult situations:
        - No home tags are in view anymore
        - The tag to drive to is too close (we might be inside of home)

    Raises:
        InsideHomeException: if we're stuck inside of home.
    """
    # TODO: should sonar be ignored when recovering?
    # TODO: is simply backing up a little bit a reliable recovery move?
    ignore = (Obstacle.TAG_TARGET | Obstacle.TAG_HOME |
              Obstacle.INSIDE_HOME | Obstacle.IS_SONAR)

    check_inside_home()

    if swarmie.has_home_odom_location():
        home_odom = swarmie.get_home_odom_location()
        loc = swarmie.get_odom_location().get_pose()
        angle = angles.shortest_angular_distance(loc.theta,
                                                 math.atan2(home_odom.y - loc.y,
                                                            home_odom.x - loc.x))
        # If the rover is facing away from home's center, turn toward it
        if abs(angle) > math.pi / 3:
            swarmie.turn(angle, ignore=ignore)
            return

    swarmie.drive(-.1, ignore=ignore)
예제 #2
0
def exit_home():
    """After we drop of a cube, back up out of home and turn away from home."""
    # TODO: Is this simple function call reliable enough during congested rounds?
    #  it's very bad if the rover don't make it fully back out of the home ring.
    swarmie.drive(-.5, ignore=Obstacle.IS_VISION | Obstacle.IS_SONAR)
    swarmie.turn(-8 * math.pi / 9,
                 ignore=Obstacle.IS_VISION | Obstacle.IS_SONAR)
예제 #3
0
def recover():
    global claw_offset_distance

    print("Missed, trying to recover.")
    try:
        swarmie.drive(-0.15,
                      ignore=Obstacle.VISION_SAFE | Obstacle.IS_SONAR,
                      timeout=20)
        # Wait a moment to detect tags before possible backing up further
        rospy.sleep(0.25)

        block = swarmie.get_nearest_block_location(targets_buffer_age=1.0)

        if block is not None:
            pass
        else:
            swarmie.drive(-0.15,
                          ignore=Obstacle.VISION_SAFE | Obstacle.IS_SONAR,
                          timeout=20)

    except (AbortException, InsideHomeException):
        raise
    except DriveException as e:
        print("Oh no, we have an exception!", e)
        pass
예제 #4
0
def approach(save_loc=False):
    global claw_offset_distance
    print("Attempting a pickup.")

    setup_approach(save_loc)

    block = swarmie.get_nearest_block_location(targets_buffer_age=0.5)

    if block is not None:
        # claw_offset should be a positive distance of how short drive_to needs to be.
        swarmie.drive_to(block,
                         claw_offset=claw_offset_distance,
                         ignore=Obstacle.VISION_SAFE | Obstacle.IS_SONAR,
                         timeout=20,
                         **swarmie.speed_slow)
        # Grab - minimal pickup with sim_check.

        if swarmie.simulator_running():
            finger_close_angle = 0
        else:
            finger_close_angle = 0.2

        swarmie.set_finger_angle(finger_close_angle)  #close
        rospy.sleep(1)
        swarmie.wrist_up()
        rospy.sleep(.5)
        # did we succesuflly grab a block?
        if swarmie.has_block():
            swarmie.wrist_middle()
            swarmie.drive(-0.3,
                          ignore=Obstacle.VISION_SAFE | Obstacle.IS_SONAR,
                          timeout=20)
            return True
        else:
            swarmie.set_wrist_angle(0.55)
            rospy.sleep(1)
            swarmie.fingers_open()
            # Wait a moment for a block to fall out of claw
            rospy.sleep(0.25)
    else:
        print("No legal blocks detected.")
        swarmie.wrist_up()
        sys.exit(1)

    # otherwise reset claw and return Falase
    swarmie.wrist_up()
    return False
예제 #5
0
def dumb_square(distance):
    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.turn(math.pi / 2, ignore=Obstacle.IS_VISION)

    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.turn(math.pi / 2, ignore=Obstacle.IS_VISION)

    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.turn(math.pi / 2, ignore=Obstacle.IS_VISION)

    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.turn(math.pi / 2, ignore=Obstacle.IS_VISION)
예제 #6
0
def main(**kwargs):
    remove_from_queue = rospy.ServiceProxy('start_queue/remove', QueueRemove)

    # During a normal startup the rover will be facing the center and close to
    # the nest. But there's no guarantee where we will be if mobility crashes
    # and is forced to restart. This checks to see if we know home's location.
    if swarmie.has_home_odom_location():
        rospy.logwarn("Init started, but home's location is already known. " +
                      "Returning normally.")
        return 0

    # Assume the starting position is facing the center.
    # This should be valid by contest rules.
    #
    # Drive closer until we can see the center.
    try:
        # Ignore cubes if they're put in the way. It's more important to continue
        # this behavior and find a corner of home than it is to stop for a cube.
        swarmie.drive(1, ignore=Obstacle.TAG_TARGET | Obstacle.IS_SONAR)
    except AbortException:
        raise
    except DriveException:
        # This could happen if we bump into another rover.
        # Let's just call it good.
        pass

    try:
        find_home_corner()
    except PathException as e:
        # It isn't ideal if we can't find a home corner, but it's worth
        # continuing to turn around and let the rover begin searching.
        swarmie.print_infoLog('<font color="red">{}</font>'.format(e.status))
        rospy.logwarn(e.status)

    swarmie.turn(-2 * math.pi / 3,
                 ignore=Obstacle.IS_VISION | Obstacle.IS_SONAR)

    remove_from_queue(
        QueueRemoveRequest(rover_name=swarmie.rover_name, notify_others=True))

    return 0
예제 #7
0
def wander():
    try:
        rospy.loginfo("Wandering...")
        swarmie.drive(random.gauss(2.5, 1), **swarmie.speed_fast)
        prev_heading = swarmie.get_odom_location().get_pose().theta

        rospy.loginfo("Circling...")
        swarmie.circle()
        swarmie.set_heading(prev_heading + random.gauss(0, math.pi / 6),
                            **swarmie.speed_fast)

    except HomeException:
        print("I saw home!")
        # TODO: We used to set the home odom location here, while we had
        #  the chance. If finding home during gohome becomes difficult,
        #  it may be useful to have home_transform publish a less
        #  accurate, but easier to update, home position estimate.
        turnaround()

    except ObstacleException:
        print("I saw an obstacle!")
        turnaround(ignore=Obstacle.IS_SONAR | Obstacle.VISION_HOME)
예제 #8
0
def abs_square(distance):

    start_pose = swarmie.get_odom_location().get_pose()

    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.set_heading(start_pose.theta + math.pi / 2, ignore=-1)

    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.set_heading(start_pose.theta + math.pi, ignore=-1)

    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.set_heading(start_pose.theta + (3 * math.pi) / 2, ignore=-1)

    swarmie.drive(distance, ignore=Obstacle.IS_VISION)
    swarmie.set_heading(start_pose.theta, ignore=-1)
예제 #9
0
def main(**kwargs):
    global claw_offset_distance

    claw_offset_distance = 0.23
    if swarmie.simulator_running():
        claw_offset_distance = 0.16

    for i in range(3):
        try:
            if approach(save_loc=bool(i == 0)):
                print("Got it!")
                sys.exit(0)
            recover()
        except TimeoutException:
            rospy.logwarn(
                ('Timeout exception during pickup. This rover may be ' +
                 'physically deadlocked with an obstacle or another rover.'))
            swarmie.drive(random.uniform(-0.1, -0.2),
                          ignore=Obstacle.VISION_SAFE | Obstacle.IS_SONAR,
                          timeout=20)

    print("Giving up after too many attempts.")
    return 1
예제 #10
0
def main():
    rospy.sleep(5)
    swarmie.pump_backward(True)
    rospy.sleep(5)
    swarmie.pump_backward(False)
    prev_heading = swarmie.get_odom_location().get_pose().theta
    for _ in range(0, 3):
        swarmie.drive(-.4, ignore=Obstacle.IS_SONAR)
        swarmie.turn(-math.pi / 2, ignore=Obstacle.IS_SONAR)
        swarmie.drive(.2, ignore=Obstacle.IS_SONAR)
        swarmie.set_heading(prev_heading, ignore=Obstacle.IS_SONAR)
        swarmie.drive(.4, ignore=Obstacle.IS_SONAR)
        swarmie.pump_forward(True)
        rospy.sleep(5)
        swarmie.pump_forward(False)
    swarmie.drive(-.4, ignore=Obstacle.IS_SONAR)
예제 #11
0
def approach(save_loc=False):
    global claw_offset_distance
    print("Attempting a pickup.")

    setup_approach(save_loc)

    block = swarmie.get_nearest_block_location(targets_buffer_age=0.5)

    if block is not None:
        # claw_offset should be a positive distance of how short drive_to needs to be.
        swarmie.drive_to(block,
                         claw_offset=claw_offset_distance,
                         ignore=Obstacle.VISION_SAFE | Obstacle.IS_SONAR,
                         timeout=20,
                         **swarmie.speed_slow)

        swarmie.drive(-0.3,
                      ignore=Obstacle.VISION_SAFE | Obstacle.IS_SONAR,
                      timeout=20)
        return True
    else:
        print("No plant detected.")
        sys.exit(1)
    return False
예제 #12
0
 def run(self):
     status_msgs = []
     try:
         while True:
             print(textwrap.dedent(TeleopSwarmie.msg))
             print(self.obstacle_msg())
             print(self.params_msg())
             for status in status_msgs:
                 print(status)
             status_msgs = []
             key = self.get_key()
             try:
                 if key in self.drive_bindings.keys():
                     dist = self.params['drive_dist']
                     if self.drive_bindings[key] < 0:
                         dist = -dist
                     swarmie.drive(dist, ignore=self.ignore_obst)
                 elif key in self.turn_bindings.keys():
                     theta = self.params['turn_theta']
                     if self.turn_bindings[key] < 0:
                         theta = -theta
                     swarmie.turn(theta, ignore=self.ignore_obst)
                 elif key in self.claw_bindings.keys():
                     self.claw_bindings[key]()
                 elif key in self.param_bindings.keys():
                     self.params[self.param_bindings[key][0]]\
                         *= self.param_bindings[key][1]
                     if self.param_bindings[key][0] == 'drive_speed':
                         self.param_client.update_configuration(
                             {'DRIVE_SPEED': self.params['drive_speed']})
                     elif self.param_bindings[key][0] == 'reverse_speed':
                         self.param_client.update_configuration({
                             'REVERSE_SPEED':
                             self.params['reverse_speed']
                         })
                     elif self.param_bindings[key][0] == 'turn_speed':
                         self.param_client.update_configuration(
                             {'TURN_SPEED': self.params['turn_speed']})
                     # Update params once now to make sure no params were
                     # set to invalid values.
                     server_config = self.param_client.get_configuration()
                     self.update_params(server_config)
                 elif key in self.obst_bindings.keys():
                     if self.obst_bindings[key][1] == 0:
                         self.ignore_obst = 0
                     else:
                         if (self.obst_bindings[key][1] & self.ignore_obst
                                 == self.obst_bindings[key][1]):
                             self.ignore_obst ^= self.obst_bindings[key][1]
                         else:
                             self.ignore_obst |= self.obst_bindings[key][1]
                 else:
                     if (key == '\x03'):
                         break
             except TagException as e:
                 status_msgs.append('\033[91m*****I saw a tag!*****\033[0m')
             except HomeException as e:
                 status_msgs.append('\033[91m*****I saw Home!*****\033[0m')
             except HomeCornerException as e:
                 status_msgs.append(
                     '\033[91m*****I saw a corner of Home!*****\033[0m')
             except InsideHomeException as e:
                 status_msgs.append(
                     '\033[91m*****I might be inside of Home!*****\033[0m')
             except ObstacleException as e:
                 status_msgs.append(
                     "\033[91m*****There's an obstacle in front of " +
                     "me*****\033[0m")
             except (PathException, AbortException) as e:
                 status_msgs.append('\033[91m*****Exception:*****\033[0m')
                 for exception in traceback.format_exception_only(
                         type(e), e):
                     status_msgs.append(exception)
     except Exception as e:
         print('Something went wrong:')
         for exception in traceback.format_exception_only(type(e), e):
             print(exception)
         traceback.print_exc()
     finally:
         termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.settings)
예제 #13
0
def escape_home(detections):
    rospy.logwarn('Getting out of the home ring!!')

    angle, dist = get_angle_and_dist_to_escape_home(detections)
    swarmie.turn(angle, ignore=Obstacle.IS_SONAR | Obstacle.IS_VISION)
    swarmie.drive(dist, ignore=Obstacle.IS_SONAR | Obstacle.IS_VISION)