Example #1
0
def get_closest_buoy(navigator, explored_ids):
    pose = yield navigator.tx_pose
    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_np = navigator_tools.point_to_numpy(buoy_field.objects[0].position)

    # Find which totems we haven't explored yet
    totems = yield navigator.database_query("totem", raise_exception=False)
    if not totems.found:
        # Need to search for more totems
        defer.returnValue([None, explored_ids])

    u_totems = [totem for totem in totems.objects if totem.id not in explored_ids]
    u_totems_np = map(lambda totem: navigator_tools.point_to_numpy(totem.position), u_totems)

    if len(u_totems_np) == 0:
        defer.returnValue([None, explored_ids])

    # Find the closest buoys, favoring the ones closest to the boat.
    #   J = wa * ca ** 2 + wb * c2 ** 2
    #   a := boat
    #   b := buoy field ROI
    wa = .7
    wb = .3
    ca = np.linalg.norm(u_totems_np - pose[0], axis=1)
    cb = np.linalg.norm(u_totems_np - buoy_field_np, axis=1)
    J = wa * ca + wb * cb

    target_totem = u_totems[np.argmin(J)]
    explored_ids.append(target_totem.id)

    defer.returnValue([target_totem, explored_ids])
Example #2
0
def get_closest_buoy(navigator, explored_ids):
    pose = yield navigator.tx_pose
    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_np = navigator_tools.point_to_numpy(buoy_field.objects[0].position)

    # Find which totems we haven't explored yet
    totems = yield navigator.database_query("totem", raise_exception=False)
    if not totems.found:
        # Need to search for more totems
        defer.returnValue([None, explored_ids])

    u_totems = [totem for totem in totems.objects if totem.id not in explored_ids]
    u_totems_np = map(lambda totem: navigator_tools.point_to_numpy(totem.position), u_totems)

    if len(u_totems_np) == 0:
        defer.returnValue([None, explored_ids])

    # Find the closest buoys, favoring the ones closest to the boat.
    #   J = wa * ca ** 2 + wb * c2 ** 2
    #   a := boat
    #   b := buoy field ROI
    wa = .7
    wb = .3
    ca = np.linalg.norm(u_totems_np - pose[0], axis=1)
    cb = np.linalg.norm(u_totems_np - buoy_field_np, axis=1)
    J = wa * ca + wb * cb

    target_totem = u_totems[np.argmin(J)]
    explored_ids.append(target_totem.id)

    defer.returnValue([target_totem, explored_ids])
Example #3
0
def get_colored_buoy(navigator, color):
    """
    Returns the closest colored buoy with the specified color
    """
    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_point = navigator_tools.point_to_numpy(
        buoy_field.objects[0].position)

    _dist_from_bf = lambda pt: np.linalg.norm(buoy_field_point - pt)

    totems = yield navigator.database_query("totem")
    correct_colored = [
        totem for totem in totems.objects if np.all(
            np.round(
                navigator_tools.rosmsg_to_numpy(
                    totem.color, keys=['r', 'g', 'b'])) == color)
    ]
    if len(correct_colored) == 0:
        closest = None
    else:
        closest = sorted(
            correct_colored,
            key=lambda totem: _dist_from_bf(
                navigator_tools.point_to_numpy(totem.position)))[0]

    defer.returnValue(closest)
Example #4
0
def main(navigator):
    result = navigator.fetch_result()

    #middle_point = np.array([-10, -70, 0]) 
    est_coral_survey = yield navigator.database_query("Coral_Survey")
    
    yield navigator.move.set_position(est_coral_survey.objects[0]).go()

    totem = yield navigator.database_query("totem")
    
    # Get the closest totem object to the boat
    totem_np = map(lambda obj: navigator_tools.point_to_numpy(obj), totem.objects)
    dist = map(lambda totem_np: np.linalg.norm(totem_np - navigator_tools.point_to_numpy(est_coral_survey.objects[0])), totems_np)

    middle_point = navigator_tools.point_to_numpy(totem.objects[0].position)
    quads_to_search = [1, 2, 3, 4]
    if (yield navigator.nh.has_param("/mission/coral_survey/quadrants")):
        quads_to_search = yield navigator.nh.get_param("/mission/coral_survey/quadrants")

    waypoint_from_center = np.array([10 * np.sqrt(2)])

    # Construct waypoint list along NSEW directions then rotate 45 degrees to get a good spot to go to.
    directions = [EAST, NORTH, WEST, SOUTH]
    waypoints = []
    for quad in quads_to_search:
        mid = navigator.move.set_position(middle_point).set_orientation(directions[quad - 1])
        waypoints.append(mid.yaw_left(45, "deg").forward(waypoint_from_center).set_orientation(NORTH))

    # Get into the coral survey area
    yield waypoints[0].go()

    # Publish ogrid with boundaries to stay inside
    ogrid = OgridFactory(middle_point, draw_borders=True)
    msg = ogrid.get_message()
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid, msg)

    searcher = navigator.search("coral_survey", waypoints)
    yield searcher.start_search(move_type='skid', spotings_req=1)

    fprint("Centering over the thing!", title="CORAL_SURVEY")

    # TODO: Center over the thing.

    boat_position = (yield navigator.tx_pose)[0]

    # TODO: make this easier
    quad = np.argmin(np.linalg.norm(boat_position - [[w.pose[0][0][0], w.pose[0][1][0],w.pose[0][2][0]] for w in waypoints], axis=1))
    quad = quads_to_search[quad]
    fprint("Estimated quadrant: {}".format(quad), title="CORAL_SURVEY", msg_color='green')

    yield navigator.nh.sleep(5)
    defer.returnValue(result)
Example #5
0
def main(navigator):
    res = navigator.fetch_result()

    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_point = navigator_tools.point_to_numpy(buoy_field.objects[0])

    #yield navigator.move.set_position(buoy_field_point).go()

    circle_colors = ['blue', 'red']
    color_map = {'blue': (255, 0, 0), 'red': (0, 0, 255)}

    explored_ids = []
    all_found = False

    while not all_found:
        target_totem, explored_ids = yield get_closest_buoy(navigator, explored_ids)

        if target_totem is None:
            fprint("No suitable totems found.", msg_color='red', title="CIRCLE_TOTEM")
            continue

        # Visualization
        points = [target_totem.position]
        pc = PointCloud(header=navigator_tools.make_header(frame='/enu'),
                        points=points)
        yield navigator._point_cloud_pub.publish(pc)

        # Let's go there
        target_distance = 7  # m
        target_totem_np = navigator_tools.point_to_numpy(target_totem.position)
        q = get_sun_angle()
        lookat = navigator.move.set_position(target_totem_np).set_orientation(q).backward(target_distance)
        yield lookat.go()

        # Now that we're looking him in the eyes, aim no higher.
        # Check the color and see if it's one we want.
        fprint("Color request", title="CIRCLE_TOTEM")

        #if target_totem is not None:
        #   all_found = True
            
    defer.returnValue(res)

    pattern = navigator.move.circle_point(focus, radius=5)

    for p in pattern:
        yield p.go(move_type='skid', focus=focus)
        print "Nexting"
Example #6
0
def get_colored_buoy(navigator, color):
    """
    Returns the closest colored buoy with the specified color
    """
    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_point = navigator_tools.point_to_numpy(buoy_field.objects[0].position)

    _dist_from_bf = lambda pt: np.linalg.norm(buoy_field_point - pt)

    totems = yield navigator.database_query("totem")
    correct_colored = [totem for totem in totems.objects if np.all(np.round(navigator_tools.rosmsg_to_numpy(totem.color, keys=['r', 'g', 'b'])) == color)]
    if len(correct_colored) == 0:
        closest = None 
    else:
        closest = sorted(correct_colored, key=lambda totem: _dist_from_bf(navigator_tools.point_to_numpy(totem.position)))[0]

    defer.returnValue(closest)
Example #7
0
def main(navigator, **kwargs):
    #middle_point = np.array([-10, -70, 0])
    est_coral_survey = yield navigator.database_query("CoralSurvey")

    # Going to get all the objects and using the closest one as the totem
    totem = yield navigator.database_query("all")

    # Get the closest totem object to the boat
    totems_np = map(lambda obj: navigator_tools.point_to_numpy(obj.position),
                    totem.objects)
    dist = map(
        lambda totem_np: np.linalg.norm(
            totem_np - navigator_tools.point_to_numpy(est_coral_survey.objects[
                0].position)), totems_np)
    middle_point = totems_np[np.argmin(dist)]

    print "Totem sorted:", totems_np
    print "Totem selected: ", totems_np[0]
    quads_to_search = [1, 2, 3, 4]
    quad = yield navigator.mission_params[
        "acoustic_pinger_active_index_correct"].get()

    waypoint_from_center = np.array([10 * np.sqrt(2)])

    # Publish ogrid with boundaries to stay inside
    ogrid = OgridFactory(middle_point, draw_borders=True)
    msg = ogrid.get_message()
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid,
                                           msg)

    # Construct waypoint list along NSEW directions then rotate 45 degrees to get a good spot to go to.
    directions = [EAST, NORTH, WEST, SOUTH]
    waypoints = []
    #for quad in quads_to_search:
    mid = navigator.move.set_position(middle_point).set_orientation(
        directions[quad - 1])
    search_center = mid.yaw_left(
        45, "deg").forward(waypoint_from_center).set_orientation(NORTH)
    yield search_center.left(6).go()
    yield navigator.move.circle_point(search_center.position,
                                      direction='cw').go()

    yield navigator.mission_params["coral_survey_shape1"].set(shapes[0])
    latched.cancel()
    defer.returnValue(None)
Example #8
0
def main(navigator, **kwargs):
    #middle_point = np.array([-10, -70, 0]) 
    est_coral_survey = yield navigator.database_query("CoralSurvey")
    
    # Going to get all the objects and using the closest one as the totem
    totem = yield navigator.database_query("all")
    
    # Get the closest totem object to the boat
    totems_np = map(lambda obj: navigator_tools.point_to_numpy(obj.position), totem.objects)
    dist = map(lambda totem_np: np.linalg.norm(totem_np - navigator_tools.point_to_numpy(est_coral_survey.objects[0].position)), totems_np)
    middle_point = totems_np[np.argmin(dist)]

    print "Totem sorted:", totems_np
    print "Totem selected: ", totems_np[0]
    quads_to_search = [1, 2, 3, 4]
    quad = yield navigator.mission_params["acoustic_pinger_active_index_correct"].get() 

    waypoint_from_center = np.array([10 * np.sqrt(2)])

    # Publish ogrid with boundaries to stay inside
    ogrid = OgridFactory(middle_point, draw_borders=True)
    msg = ogrid.get_message()
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid, msg)

    # Construct waypoint list along NSEW directions then rotate 45 degrees to get a good spot to go to.
    directions = [EAST, NORTH, WEST, SOUTH]
    waypoints = []
    #for quad in quads_to_search:
    mid = navigator.move.set_position(middle_point).set_orientation(directions[quad - 1])
    search_center = mid.yaw_left(45, "deg").forward(waypoint_from_center).set_orientation(NORTH)
    yield search_center.left(6).go()
    yield navigator.move.circle_point(search_center.position, direction='cw').go()
    
    yield navigator.mission_params["coral_survey_shape1"].set(shapes[0])
    latched.cancel()
    defer.returnValue(None)
Example #9
0
 def ping_cb(self, ping):
     print rospkg.get_ros_package_path()
     print "PINGERFINDER: freq={p.freq:.0f}  amp={p.amplitude:.0f}".format(
         p=ping)
     if abs(
             ping.freq - self.target_freq
     ) < self.freq_tol and ping.amplitude > self.min_amp and self.listen:
         trans, rot = None, None
         try:
             self.tf_listener.waitForTransform(self.map_frame,
                                               self.hydrophone_frame,
                                               ping.header.stamp,
                                               rospy.Duration(0.25))
             trans, rot = self.tf_listener.lookupTransform(
                 self.map_frame, self.hydrophone_frame, ping.header.stamp)
         except (tf.LookupException, tf.ConnectivityException,
                 tf.ExtrapolationException) as e:
             print e
             return
         p0 = np.array([trans[0], trans[1]])
         R = tf.transformations.quaternion_matrix(rot)[:3, :3]
         delta = R.dot(navigator_tools.point_to_numpy(ping.position))[:2]
         p1 = p0 + self.heading_pseudorange * delta / npl.norm(delta)
         # p0 and p1 define a line
         line_coeffs = np.array([[p0[0], p0[1], p1[0], p1[1]]])
         self.visualize_arrow(Point(p0[0], p0[1], 0),
                              Point(p1[0], p1[1], 0))
         self.line_array = np.append(self.line_array, line_coeffs, 0)
         self.observation_amplitudes = np.append(
             self.observation_amplitudes, ping.amplitude)
         # delete softest samples if we have over max_observations
         if len(self.line_array) >= self.max_observations:
             softest_idx = np.argmin(self.observation_amplitudes)
             self.line_array = np.delete(self.line_array,
                                         softest_idx,
                                         axis=0)
             self.observation_amplitudes = np.delete(
                 self.observation_amplitudes, softest_idx)
         print "PINGERFINDER: Observation collected. Total: {}".format(
             self.line_array.shape[0])
Example #10
0
def head_for_pinger(navigator):
    ping_sub = yield navigator.nh.subscribe("/hydrophones/processed", ProcessedPing)
    yield ping_sub.get_next_message()
    while True:
        yield navigator.nh.sleep(1)
        processed_ping = yield ping_sub.get_last_message()
        print processed_ping
        if isinstance(processed_ping, ProcessedPing):
            print "Got processed ping message:\n{}".format(processed_ping)
            if processed_ping.freq > 35000 and processed_ping.freq < 36000:
                print "Trustworthy pinger heading"
                t = yield navigator.tf_listener.get_transform("/enu", "/hydrophones", processed_ping.header.stamp)
                base_vect = t.transform_vector(navigator_tools.point_to_numpy(processed_ping.position))
                base_vect = base_vect / np.linalg.norm(base_vect) * 10
                odom_enu = (yield navigator.tx_pose)[0]
                #pinger_move = navigator.move.set_position(navigator_tools.point_to_numpy(processed_ping.position)).go()
                pinger_move = yield navigator.move.set_position(odom_enu + base_vect).go()
                print "Heading towards pinger"
            else:
                print "Untrustworthy pinger heading. Freq = {} kHZ".format(processed_ping.freq)
        else:
            print "Expected ProcessedPing, got {}".format(type(processed_ping))
Example #11
0
 def ping_cb(self, ping):
     print rospkg.get_ros_package_path()
     print "PINGERFINDER: freq={p.freq:.0f}  amp={p.amplitude:.0f}".format(p=ping)
     if abs(ping.freq - self.target_freq) < self.freq_tol and ping.amplitude > self.min_amp and self.listen:
         trans, rot = None, None
         try:
             self.tf_listener.waitForTransform(self.map_frame, self.hydrophone_frame, ping.header.stamp, rospy.Duration(0.25))
             trans, rot = self.tf_listener.lookupTransform(self.map_frame, self.hydrophone_frame, ping.header.stamp)
         except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException) as e:
             print e
             return
         p0 = np.array([trans[0], trans[1]])
         R = tf.transformations.quaternion_matrix(rot)[:3, :3]
         delta = R.dot(navigator_tools.point_to_numpy(ping.position))[:2]
         p1 = p0 + self.heading_pseudorange * delta / npl.norm(delta)
         line_coeffs = np.array([[p0[0], p0[1], p1[0], p1[1]]]) # p0 and p1 define a line
         self.visualize_arrow(Point(p0[0], p0[1], 0), Point(p1[0], p1[1], 0))
         self.line_array = np.append(self.line_array, line_coeffs, 0)
         self.observation_amplitudes = np.append(self.observation_amplitudes, ping.amplitude)
         if len(self.line_array) >= self.max_observations:  # delete softest samples if we have over max_observations
             softest_idx = np.argmin(self.observation_amplitudes)
             self.line_array = np.delete(self.line_array, softest_idx, axis=0)  
             self.observation_amplitudes = np.delete(self.observation_amplitudes, softest_idx)
         print "PINGERFINDER: Observation collected. Total: {}".format(self.line_array.shape[0])
Example #12
0
    def do_update(self, *args):
        resp = self.make_request(name='all')

        if resp.found:
            # temp
            time_of_marker = rospy.Time.now() - ros_t(
                .2)  # header.stamp not filled out
            image_holder = self.image_history.get_around_time(time_of_marker)
            if not image_holder.contains_valid_image:
                return

            header = navigator_tools.make_header(
                frame="/enu", stamp=image_holder.time)  #resp.objects[0].header
            image = image_holder.image
            self.debug.image = np.copy(image)

            cam_tf = self.camera_model.tfFrame()
            fprint("Getting transform between /enu and {}...".format(cam_tf))
            self.tf_listener.waitForTransform("/enu", cam_tf, time_of_marker,
                                              ros_t(1))
            t_mat44 = self.tf_listener.asMatrix(
                cam_tf, header)  # homogenous 4x4 transformation matrix

            for obj in resp.objects:
                if len(obj.points) > 0 and obj.name == "totem":
                    fprint("{} {}".format(obj.id, "=" * 50))

                    print obj.position
                    # Get objects position in camera frame and make sure it's in view
                    object_cam = t_mat44.dot(
                        np.append(navigator_tools.point_to_numpy(obj.position),
                                  1))
                    object_px = map(
                        int,
                        self.camera_model.project3dToPixel(object_cam[:3]))
                    if not self._object_in_frame(object_cam):
                        continue

                    #print object_px

                    points_np = np.array(
                        map(navigator_tools.point_to_numpy, obj.points))
                    # We dont want points below a certain level
                    points_np = points_np[points_np[:, 2] > -2.5]
                    # Shove ones in there to make homogenous points
                    points_np_homo = np.hstack(
                        (points_np, np.ones((points_np.shape[0], 1)))).T
                    points_cam = t_mat44.dot(points_np_homo).T
                    points_px = map(self.camera_model.project3dToPixel,
                                    points_cam[:, :3])
                    #print points_px

                    roi = self._get_ROI_from_points(points_px)
                    color_info = self._get_color_from_ROI(
                        roi, image)  # hue, string_color, error
                    bgr = (0, 0, 0)

                    if color_info is not None:
                        hue, color, error = color_info
                        c = (int(hue), 255, 255)
                        hsv = np.array([[c]])[:, :3].astype(np.uint8)
                        bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)[0, 0]
                        bgr = tuple(bgr.astype(np.uint8).tolist())

                        if hue is not None:
                            if obj.id not in self.colored:
                                self.colored[obj.id] = []

                            self.colored[obj.id].append({
                                'color': color,
                                'err': error
                            })

                            if self.valid_color(obj.id):
                                fprint("COLOR IS VALID", msg_color='green')
                                self.make_request(
                                    cmd=
                                    '{name}={bgr[2]},{bgr[1]},{bgr[0]},{_id}'.
                                    format(name=obj.name, _id=obj.id, bgr=bgr))

                    [
                        cv2.circle(self.debug.image, tuple(map(int, p)), 2,
                                   bgr, -1) for p in points_px
                    ]
                    cv2.circle(self.debug.image, tuple(object_px), 10, bgr, -1)
                    font = cv2.FONT_HERSHEY_SIMPLEX
                    cv2.putText(self.debug.image, str(obj.id),
                                tuple(object_px), font, 1, bgr, 2)

                    print '\n' * 2
Example #13
0
def main(navigator, **kwargs):
    # rgb color map to param vlues
    color_map = {'BLUE': [0, 0, 1], 'RED': [1, 0, 0], 'YELLOW': [1, 1, 0], 'GREEN': [0, 1, 0]}

    explored_ids = []
    all_found = False

    # Get colors of intrest and directions
    c1 = navigator.mission_params['totem_color_1'].get()
    d1 = navigator.mission_params['totem_direction_1'].get()
    c2 = navigator.mission_params['totem_color_2'].get()
    d2 = navigator.mission_params['totem_direction_2'].get()
    
    colors = [c1, c2]
    directions = [d1, d2]

    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_point = navigator_tools.point_to_numpy(buoy_field.objects[0].position)

    _dist_from_bf = lambda pt: np.linalg.norm(buoy_field_point - pt)

    # We want to go to an observation point based on solar position
    # TODO: Check which side to go to based on relative distance
    center = navigator.move.set_position(buoy_field_point).set_orientation(get_solar_q())
    obs_point = center.backward(BF_WIDTH / 2 + BF_EST_COFIDENCE) 
    yield obs_point.go()

    # Next jig around to see buoys, first enforce that we're looking at the buoy field
    buoy_field_point[2] = 1
    #yield navigator.move.look_at(buoy_field_point).go(move_type='skid', focus=buoy_field_point)
    yield navigator.nh.sleep(3)
    #yield navigator.move.yaw_right(.5).go(move_type='skid')
    #yield navigator.nh.sleep(3)
    #yield navigator.move.yaw_left(1).go(move_type='skid')

    
    # TODO: What if we don't see the colors?
    for color, direction in zip(colors, directions):
        color = yield color
        direction = yield direction

        target = yield get_colored_buoy(navigator, color_map[color])
        if target is None or _dist_from_bf(navigator_tools.point_to_numpy(target.position)) > (BF_WIDTH / 2 + BF_EST_COFIDENCE):
            # Need to do something
            fprint("No suitable totems found.", msg_color='red', title="CIRCLE_TOTEM")
            defer.returnValue(None)

        target_np = navigator_tools.point_to_numpy(target.position)
        set_up = navigator.move.look_at(target_np).set_position(target_np).backward(TOTEM_SAFE_DIST)
        
        # Approach totem, making sure we actually get there.
        res = yield set_up.go(initial_plan_time=2)
        while res.failure_reason is not '':
            set_up = set_up.backward(.1)
            res = yield set_up.go(move_type='skid')
        
        fprint("Going {}".format(direction), title="CIRCLE_TOTEM")

        print TOTEM_SAFE_DIST - ROT_SAFE_DIST
        if direction == "COUNTER-CLOCKWISE":
            rot_move = navigator.move.yaw_right(1.57).left(TOTEM_SAFE_DIST - ROT_SAFE_DIST)
            while (yield rot_move.go(move_type='skid')).failure_reason is not '':
               rot_move = rot_move.right(.25)
               print rot_move

            circle = navigator.move.d_circle_point(target_np, radius=ROT_SAFE_DIST, direction='ccw', theta_offset=-1.57)
            for c in circle:
                yield c.go(move_type='skid')

        elif direction == "CLOCKWISE":
            rot_move = navigator.move.yaw_left(1.57).right(TOTEM_SAFE_DIST - ROT_SAFE_DIST)
            while (yield rot_move.go(move_type='skid')).failure_reason is not '':
               rot_move = rot_move.left(.25)
               print rot_move

            res = yield navigator.move.circle_point(target_np, direction='cw').go()

        print "Mission result:", res

        
    
    defer.returnValue(None)
Example #14
0
def main(navigator, **kwargs):
    # rgb color map to param vlues
    color_map = {
        'BLUE': [0, 0, 1],
        'RED': [1, 0, 0],
        'YELLOW': [1, 1, 0],
        'GREEN': [0, 1, 0]
    }
    directions = {'RED': 'cw', 'GREEN': 'ccw', 'BLUE': 'cw', 'YELLOW': 'ccw'}

    ogrid = OccupancyGridFactory(navigator)

    explored_ids = []
    all_found = False

    # Get colors of intrest and directions
    c1 = navigator.mission_params['scan_the_code_color1'].get()
    c2 = navigator.mission_params['scan_the_code_color2'].get()
    c3 = navigator.mission_params['scan_the_code_color3'].get()

    colors = [c1, c2, c3]

    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_point = navigator_tools.point_to_numpy(
        buoy_field.objects[0].position)

    _dist_from_bf = lambda pt: np.linalg.norm(buoy_field_point - pt)

    # We want to go to an observation point based on solar position
    center = navigator.move.set_position(buoy_field_point).set_orientation(
        get_solar_q())

    searched = []

    for color in colors:
        target = None
        need_recolor = False

        color = yield color
        direction = directions[color]

        fprint("Going to totem colored {} in direction {}".format(
            color, direction),
               title="CIRCLE_TOTEM")
        target = yield get_colored_buoy(navigator, color_map[color])
        if target is None or _dist_from_bf(
                navigator_tools.point_to_numpy(
                    target.position)) > (BF_WIDTH / 2 + BF_EST_COFIDENCE):
            # Need to do something
            fprint(
                "No suitable totems found, going to circle any nearby totems.",
                msg_color='red',
                title="CIRCLE_TOTEM")
            target, searched = yield get_closest_totem(navigator, searched)
            need_recolor = True

        target_np = navigator_tools.point_to_numpy(target.position)
        circler = navigator.move.d_circle_point(point=target_np,
                                                radius=TOTEM_SAFE_DIST,
                                                direction=direction)

        # Give the totem a look at
        for p in circler:
            res = yield p.go(speed_factor=SPEED_FACTOR)
            if res.failure_reason is '':
                break

        if need_recolor:
            fprint("Recoloring...")
            # Check for color?
            yield navigator.nh.sleep(5)
            target = yield navigator.database_query(str(target.id),
                                                    raise_exception=False)
            if len(target.objects) == 0:
                direction = directions[DEFAULT_COLOR]
            else:
                direction = directions[check_color(target.objects[0],
                                                   color_map)]

        mult = 1 if direction == 'cw' else -1
        left_offset = mult * CIRCLE_OFFSET

        tangent_circler = navigator.move.d_circle_point(point=target_np,
                                                        radius=ROT_SAFE_DIST,
                                                        theta_offset=mult *
                                                        1.57,
                                                        direction=direction)

        # Point tangent
        for p in tangent_circler:
            res = yield p.go(speed_factor=SPEED_FACTOR)
            if res.failure_reason is '':
                break

        msg, goal = ogrid.circle_around(target_np, direction=direction)
        latched_pub = ogrid.latching_publisher(msg)

        yield navigator.nh.sleep(2)
        goal = navigator.move.set_position(np.append(goal, 1)).look_at(
            navigator.pose[0]).left(left_offset).backward(2)
        yield goal.go(move_type='drive!', initial_plan_time=10)

        latched_pub.cancel()

        fprint("Canceling ogrid")
        yield navigator.nh.sleep(3)

        print "Mission result:", res

    defer.returnValue(None)
Example #15
0
 def from_srv(cls, srv):
     return cls(navigator_tools.point_to_numpy(srv.position), srv.color)
Example #16
0
    def do_update(self, *args):
        resp = self.make_request(name='all')

        if resp.found:
            # temp
            time_of_marker = rospy.Time.now() - ros_t(.2)  # header.stamp not filled out
            image_holder = self.image_history.get_around_time(time_of_marker)
            if not image_holder.contains_valid_image:
                return

            header = navigator_tools.make_header(frame="/enu", stamp=image_holder.time) #resp.objects[0].header
            image = image_holder.image
            self.debug.image = np.copy(image)

            cam_tf = self.camera_model.tfFrame()
            fprint("Getting transform between /enu and {}...".format(cam_tf))
            self.tf_listener.waitForTransform("/enu", cam_tf, time_of_marker, ros_t(1))
            t_mat44 = self.tf_listener.asMatrix(cam_tf, header)  # homogenous 4x4 transformation matrix

            for obj in resp.objects:
                if len(obj.points) > 0 and obj.name == "totem":
                    fprint("{} {}".format(obj.id, "=" * 50))

                    print obj.position
                    # Get objects position in camera frame and make sure it's in view
                    object_cam = t_mat44.dot(np.append(navigator_tools.point_to_numpy(obj.position), 1))
                    object_px = map(int, self.camera_model.project3dToPixel(object_cam[:3]))
                    if not self._object_in_frame(object_cam):
                        continue

                    #print object_px

                    points_np = np.array(map(navigator_tools.point_to_numpy, obj.points))
                    # We dont want points below a certain level
                    points_np = points_np[points_np[:, 2] > -2.5]
                    # Shove ones in there to make homogenous points
                    points_np_homo = np.hstack((points_np, np.ones((points_np.shape[0], 1)))).T
                    points_cam = t_mat44.dot(points_np_homo).T
                    points_px = map(self.camera_model.project3dToPixel, points_cam[:, :3])
                    #print points_px

                    roi = self._get_ROI_from_points(points_px)
                    color_info = self._get_color_from_ROI(roi, image)  # hue, string_color, error
                    bgr = (0, 0, 0)
                                        
                    if color_info is not None:
                        hue, color, error = color_info
                        c = (int(hue), 255, 255)
                        hsv = np.array([[c]])[:, :3].astype(np.uint8)
                        bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)[0, 0] 
                        bgr = tuple(bgr.astype(np.uint8).tolist())

                        if hue is not None:
                            if obj.id not in self.colored:
                                self.colored[obj.id] = []

                            self.colored[obj.id].append({'color':color, 'err':error})

                            if self.valid_color(obj.id):
                                fprint("COLOR IS VALID", msg_color='green')
                                self.make_request(cmd='{name}={bgr[2]},{bgr[1]},{bgr[0]},{_id}'.format(name=obj.name,_id=    obj.id, bgr=bgr))

                    [cv2.circle(self.debug.image, tuple(map(int, p)), 2, bgr, -1) for p in points_px]
                    cv2.circle(self.debug.image, tuple(object_px), 10, bgr, -1)
                    font = cv2.FONT_HERSHEY_SIMPLEX
                    cv2.putText(self.debug.image, str(obj.id), tuple(object_px), font, 1, bgr, 2)

                    print '\n' * 2
Example #17
0
def main(navigator, **kwargs):
    # rgb color map to param vlues
    color_map = {'BLUE': [0, 0, 1], 'RED': [1, 0, 0], 'YELLOW': [1, 1, 0], 'GREEN': [0, 1, 0]}
    directions = {'RED': 'cw', 'GREEN': 'ccw', 'BLUE': 'cw', 'YELLOW': 'ccw'}
    
    ogrid = OccupancyGridFactory(navigator)

    explored_ids = []
    all_found = False

    # Get colors of intrest and directions
    c1 = navigator.mission_params['scan_the_code_color1'].get()
    c2 = navigator.mission_params['scan_the_code_color2'].get()
    c3 = navigator.mission_params['scan_the_code_color3'].get()
    
    colors = [c1, c2, c3]

    buoy_field = yield navigator.database_query("BuoyField")
    buoy_field_point = navigator_tools.point_to_numpy(buoy_field.objects[0].position)

    _dist_from_bf = lambda pt: np.linalg.norm(buoy_field_point - pt)

    # We want to go to an observation point based on solar position
    center = navigator.move.set_position(buoy_field_point).set_orientation(get_solar_q())
    
    searched = []

    for color in colors:
        target = None
        need_recolor = False

        color = yield color
        direction = directions[color]
    
        fprint("Going to totem colored {} in direction {}".format(color, direction), title="CIRCLE_TOTEM")
        target = yield get_colored_buoy(navigator, color_map[color])
        if target is None or _dist_from_bf(navigator_tools.point_to_numpy(target.position)) > (BF_WIDTH / 2 + BF_EST_COFIDENCE):
            # Need to do something
            fprint("No suitable totems found, going to circle any nearby totems.", msg_color='red', title="CIRCLE_TOTEM")
            target, searched = yield get_closest_totem(navigator, searched)
            need_recolor = True

        target_np = navigator_tools.point_to_numpy(target.position)
        circler = navigator.move.d_circle_point(point=target_np, radius=TOTEM_SAFE_DIST, direction=direction)
        
        # Give the totem a look at
        for p in circler:
            res = yield p.go(speed_factor=SPEED_FACTOR)
            if res.failure_reason is '':
                break

        if need_recolor:
            fprint("Recoloring...")
            # Check for color?
            yield navigator.nh.sleep(5)
            target = yield navigator.database_query(str(target.id), raise_exception=False)
            if len(target.objects) == 0:
                direction = directions[DEFAULT_COLOR]
            else:
                direction = directions[check_color(target.objects[0], color_map)]

        mult = 1 if direction == 'cw' else -1
        left_offset = mult * CIRCLE_OFFSET
        
        tangent_circler = navigator.move.d_circle_point(point=target_np, radius=ROT_SAFE_DIST, theta_offset=mult * 1.57, direction=direction)
        
        # Point tangent
        for p in tangent_circler:
            res = yield p.go(speed_factor=SPEED_FACTOR)
            if res.failure_reason is '':
                break
      
        msg, goal = ogrid.circle_around(target_np, direction=direction)
        latched_pub = ogrid.latching_publisher(msg)

        yield navigator.nh.sleep(2)
        goal = navigator.move.set_position(np.append(goal, 1)).look_at(navigator.pose[0]).left(left_offset).backward(2)
        yield goal.go(move_type='drive!', initial_plan_time=10)
         
        latched_pub.cancel()

        fprint("Canceling ogrid")
        yield navigator.nh.sleep(3)

        print "Mission result:", res
    
    defer.returnValue(None)
Example #18
0
import tf
from tf import transformations as trans

ping_sub = yield navigator.nh.subscribe("/hydrophones/processed", ProcessedPing)
yield ping_sub.get_next_message()
target_freq = 35000
while True:
    processed_ping = yield ping_sub.get_next_message()
    print processed_ping
    if isinstance(processed_ping, ProcessedPing):
        print "Got processed ping message:\n{}".format(processed_ping)
        if processed_ping.freq > 35000 and processed_ping.freq < 36000:
            freq_dev = abs(target_freq - processed_ping.freq)
            print "Trustworthy pinger heading"
            hydrophones_enu_p, hydrophones_enu_q = tf.lookupTransform("/hydrophones", "/enu", processed_ping.header.stamp)
            pinger_enu_p = navigator_tools.point_to_numpy(tf.transformPoint())
            dir_ = navigator_tools.point_to_numpy(processed_ping.position)
        	mv_mag = 2
            mv_hyd_frame = dir_ / np.linalg.norm(dir_)
            pinger_move = navigator.move.set_position(navigator_tools.point_to_numpy(processed_ping.position)).go()

            print "Heading towards pinger"
        else:
            print "Untrustworthy pinger heading. Freq = {} kHZ".format(processed_ping.freq)
    else:
        print "Expected ProcessedPing, got {}".format(type(processed_ping))

# Hydrophone locate mission
@txros.util.cancellableInlineCallbacks
def main(navigator):
    kill_alarm_broadcaster, kill_alarm = single_alarm('kill', action_required=True, problem_description="Killing wamv to listen to pinger")
Example #19
0
 def from_srv(cls, srv):
     return cls(navigator_tools.point_to_numpy(srv.position), srv.color)
Example #20
0
def main(navigator):
    result = navigator.fetch_result()

    #middle_point = np.array([-10, -70, 0])
    resp = yield navigator.database_query("coral_survey")
    if not resp.found:
        result.success = False
        result.response = "coral_survey database entry not found!"
        result.need_rerun = True

        defer.returnValue(result)

    middle_point = navigator_tools.point_to_numpy(resp.objects[0].position)
    quads_to_search = [1, 2, 3, 4]
    if (yield navigator.nh.has_param("/mission/coral_survey/quadrants")):
        quads_to_search = yield navigator.nh.get_param(
            "/mission/coral_survey/quadrants")

    waypoint_from_center = np.array([10 * np.sqrt(2)])

    # Construct waypoint list along NSEW directions then rotate 45 degrees to get a good spot to go to.
    directions = [EAST, NORTH, WEST, SOUTH]
    waypoints = []
    for quad in quads_to_search:
        mid = navigator.move.set_position(middle_point).set_orientation(
            directions[quad - 1])
        waypoints.append(
            mid.yaw_left(
                45,
                "deg").forward(waypoint_from_center).set_orientation(NORTH))

    # Get into the coral survey area
    yield waypoints[0].go()

    # Publish ogrid with boundaries to stay inside
    ogrid = OgridFactory(middle_point, draw_borders=True)
    msg = ogrid.get_message()
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid,
                                           msg)

    searcher = navigator.search("coral_survey", waypoints)
    yield searcher.start_search(move_type='skid', spotings_req=1)

    fprint("Centering over the thing!", title="CORAL_SURVEY")

    # TODO: Center over the thing.

    boat_position = (yield navigator.tx_pose)[0]

    # TODO: make this easier
    quad = np.argmin(
        np.linalg.norm(boat_position -
                       [[w.pose[0][0][0], w.pose[0][1][0], w.pose[0][2][0]]
                        for w in waypoints],
                       axis=1))
    quad = quads_to_search[quad]
    fprint("Estimated quadrant: {}".format(quad),
           title="CORAL_SURVEY",
           msg_color='green')

    yield navigator.nh.sleep(5)
    defer.returnValue(result)