Example #1
0
    def state_cb(self, msg):
        if self.target in msg.name:
            target_index = msg.name.index(self.target)

            twist = msg.twist[target_index]
            enu_pose = navigator_tools.pose_to_numpy(msg.pose[target_index])

            self.last_ecef = self.enu_to_ecef(enu_pose[0])
            self.last_enu = enu_pose

            self.last_odom = Odometry(
                header=navigator_tools.make_header(frame='/enu'),
                child_frame_id='/base_link',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(
                        *self.last_enu)),
                twist=TwistWithCovariance(twist=twist))

            self.last_absodom = Odometry(
                header=navigator_tools.make_header(frame='/ecef'),
                child_frame_id='/base_link',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(
                        self.last_ecef, self.last_enu[1])),
                twist=TwistWithCovariance(twist=twist))
    def state_cb(self, msg):
        if rospy.Time.now() - self.last_state_sub_time < self.state_sub_max_prd:
            return
        self.last_state_sub_time = rospy.Time.now()

        if self.target in msg.name:
            target_index = msg.name.index(self.target)

            twist = msg.twist[target_index]
            enu_pose = navigator_tools.pose_to_numpy(msg.pose[target_index])

            self.last_ecef = self.enu_to_ecef(enu_pose[0])
            self.last_enu = enu_pose

            self.last_odom = Odometry(
                header=navigator_tools.make_header(frame='/enu'),
                child_frame_id='/measurement',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(*self.last_enu)
                ),
                twist=TwistWithCovariance(
                    twist=twist
                )
            )

            self.last_absodom = Odometry(
                header=navigator_tools.make_header(frame='/ecef'),
                child_frame_id='/measurement',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(self.last_ecef, self.last_enu[1])
                ),
                twist=TwistWithCovariance(
                    twist=twist
                )
            )
    def state_cb(self, msg):
        if self.target in msg.name:
            target_index = msg.name.index(self.target)

            twist = msg.twist[target_index]
            enu_pose = navigator_tools.pose_to_numpy(msg.pose[target_index])

            self.last_ecef = self.enu_to_ecef(enu_pose[0])
            self.last_enu = enu_pose

            self.last_odom = Odometry(
                header=navigator_tools.make_header(frame='/enu'),
                child_frame_id='/base_link',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(*self.last_enu)
                ),
                twist=TwistWithCovariance(
                    twist=twist
                )
            )


            self.last_absodom = Odometry(
                header=navigator_tools.make_header(frame='/ecef'),
                child_frame_id='/base_link',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(self.last_ecef, self.last_enu[1])
                ),
                twist=TwistWithCovariance(
                    twist=twist
                )
            )
Example #4
0
    def state_cb(self, msg):
        if rospy.Time.now(
        ) - self.last_state_sub_time < self.state_sub_max_prd:
            return
        self.last_state_sub_time = rospy.Time.now()

        if self.target in msg.name:
            target_index = msg.name.index(self.target)

            twist = msg.twist[target_index]
            enu_pose = navigator_tools.pose_to_numpy(msg.pose[target_index])

            self.last_ecef = self.enu_to_ecef(enu_pose[0])
            self.last_enu = enu_pose

            self.last_odom = Odometry(
                header=navigator_tools.make_header(frame='/enu'),
                child_frame_id='/measurement',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(
                        *self.last_enu)),
                twist=TwistWithCovariance(twist=twist))

            self.last_absodom = Odometry(
                header=navigator_tools.make_header(frame='/ecef'),
                child_frame_id='/measurement',
                pose=PoseWithCovariance(
                    pose=navigator_tools.numpy_quat_pair_to_pose(
                        self.last_ecef, self.last_enu[1])),
                twist=TwistWithCovariance(twist=twist))
    def move_cb(self, msg):
        fprint("Move request received!", msg_color="blue")
        
        if msg.move_type not in ['hold', 'drive', 'skid', 'circle']:
            fprint("Move type '{}' not found".format(msg.move_type), msg_color='red')
            self.move_server.set_aborted(MoveResult('move_type'))
            return
        
        self.blind = msg.blind

        p = PoseStamped()
        p.header = navigator_tools.make_header(frame="enu")
        p.pose = msg.goal
        self.goal_pose_pub.publish(p)

        # Sleep before you continue
        rospy.sleep(1)

        yaw = trns.euler_from_quaternion(navigator_tools.rosmsg_to_numpy(msg.goal.orientation))[2]        
        if not self.is_feasible(np.array([msg.goal.position.x, msg.goal.position.y, yaw]), np.zeros(3)):
            fprint("Not feasible", msg_color='red')
            self.move_server.set_aborted(MoveResult('occupied'))
            return

        fprint("Finished move!", newline=2)
        self.move_server.set_succeeded(MoveResult(''))
Example #6
0
    def __init__(self):
        '''Alarm Handler
            Listen for alarms, call scenarios
        TODO:
            - Add alarm queue
            - Handle alarms in sequence (Don't get stuck in the callback)
            - bag (if set) EVERY single alarm received
        '''
        # Queue size is large because you bet your ass we are addressing every alarm
        self.alarm_sub = rospy.Subscriber('/alarm_raise', Alarm, self.alarm_callback, queue_size=100)
        self.alarm_pub = rospy.Publisher('/alarm', Alarm, queue_size=100)
        
        self.alarms = {}
        self.scenarios = {}

        for alarm in meta_alarms_inv:
           self.alarms[alarm] = Alarm(alarm_name=alarm, clear=True, header=navigator_tools.make_header()) 

        self.alarm_republish_timer = rospy.Timer(rospy.Duration(0.05), self.republish_alarms)
        
        # Go through everything in the navigator_alarm.alarm_handlers package
        for candidate_alarm_name in dir(alarm_handlers):
            # Discard __* nonsense
            if not candidate_alarm_name.startswith('_'):
                # Verify that it is actually an alarm handler by checking if the class inherits from `HandlerBase`
                handlers = inspect.getmembers(getattr(alarm_handlers, candidate_alarm_name), inspect.isclass)
                handlers = [handler for handler in handlers if handler[0] != "HandlerBase" and \
                                                               issubclass(handler[1], HandlerBase)]
                for handler_name, handler_class in handlers:
                    rospy.loginfo("Registered scenario with name '{}'".format(handler_class.alarm_name))
                    self.scenarios[handler_class.alarm_name] = handler_class()
Example #7
0
    def get_message(self):
        ogrid = OccupancyGrid()
        ogrid.header = navigator_tools.make_header(frame="enu")
        ogrid.info.resolution = self.resolution
        ogrid.info.height, ogrid.info.width = self.grid.shape
        ogrid.info.origin = self.origin
        grid = np.copy(self.grid)
        ogrid.data = np.clip(grid.flatten(), -100, 100).astype(np.int8)

        return ogrid
Example #8
0
    def get_message(self):
        ogrid = OccupancyGrid()
        ogrid.header = navigator_tools.make_header(frame="enu")
        ogrid.info.resolution = self.resolution
        ogrid.info.height, ogrid.info.width = self.grid.shape
        ogrid.info.origin = self.origin
        grid = np.copy(self.grid)
        ogrid.data = np.clip(grid.flatten() - 1, -100, 100).astype(np.int8)

        return ogrid
Example #9
0
    def pub_ogrid(self, *args):
        ogrid = OccupancyGrid()
        ogrid.header = navigator_tools.make_header(frame="enu")
        ogrid.info = self.map_metadata

        # Over saturate and clip to get range of [-1, 1]
        self.grid = np.clip(self.grid * 1000, -1, 1)
        ogrid.data = self.grid.flatten().astype(np.int8).tolist()

        self.ogrid_pub.publish(ogrid)
Example #10
0
    def position_to_object(self, position, color, id,  name="totem"):
        obj = PerceptionObject()
        obj.id = int(id)
        obj.header = navigator_tools.make_header(frame="enu")
        obj.name = name
        obj.position = navigator_tools.numpy_to_point(position)
        obj.color.r = color[0]
        obj.color.g = color[1]
        obj.color.b = color[2]
        obj.color.a = 1

        return obj
Example #11
0
    def position_to_object(self, position, color, id, name="totem"):
        obj = PerceptionObject()
        obj.id = int(id)
        obj.header = navigator_tools.make_header(frame="enu")
        obj.name = name
        obj.position = navigator_tools.numpy_to_point(position)
        obj.color.r = color[0]
        obj.color.g = color[1]
        obj.color.b = color[2]
        obj.color.a = 1

        return obj
Example #12
0
    def publish_odom(self, *args):
        if self.last_odom is None:
            return

        msg = self.last_odom
        if self.target in msg.name:

            target_index = msg.name.index(self.target)
            twist = msg.twist[target_index]

            twist = msg.twist[target_index]
            pose = msg.pose[target_index]
            self.state_pub.publish(
                header=navigator_tools.make_header(frame='/enu'),
                child_frame_id='/base_link',
                pose=PoseWithCovariance(pose=pose),
                twist=TwistWithCovariance(twist=twist))
            self.absstate_pub.publish(
                header=navigator_tools.make_header(frame='/ecef'),
                child_frame_id='/base_link',
                pose=PoseWithCovariance(pose=pose),
                twist=TwistWithCovariance(twist=twist))
Example #13
0
    def get_message(self):
        if self.grid is None:
            fprint("Ogrid was requested but no ogrid was found. Using blank.", msg_color='yellow')
            self.grid = np.zeros((self.height / self.resolution, self.width / self.resolution))

        ogrid = OccupancyGrid()
        ogrid.header = navigator_tools.make_header(frame="enu")
        ogrid.info.resolution = self.resolution
        ogrid.info.height, ogrid.info.width = self.grid.shape
        ogrid.info.origin = self.origin
        grid = np.copy(self.grid)
        ogrid.data = np.clip(grid.flatten() - 1, -100, 100).astype(np.int8)

        return ogrid
Example #14
0
    def raise_alarm(self,
                    problem_description=None,
                    parameters=None,
                    severity=None):
        '''
            Arguments are override parameters
        '''
        got_problem_description = (problem_description != "") or (
            self._problem_description is not None)
        assert got_problem_description, "No problem description has been set for this alarm"

        # Allow overrideable severity
        if severity is None:
            severity = self._severity

        if parameters is not None:
            assert isinstance(
                parameters,
                dict), "Parameters must be in the form of  dictionary"

        if problem_description is not None:
            _problem_description = problem_description
        else:
            _problem_description = self._problem_description

        if parameters is not None:
            _parameters = parameters
        else:
            _parameters = self._parameters

        alarm_contents = {
            'action_required': self._action_required,
            'problem_description': _problem_description,
            'parameters': json.dumps(_parameters),
            'severity': self._severity,
            'alarm_name': self._alarm_name,
            'node_name': self._node_name,
            'clear': False,
        }
        if not self.different(**alarm_contents):
            return
        else:
            self._previous_stuff = alarm_contents

        alarm_msg = Alarm(header=navigator_tools.make_header(),
                          **alarm_contents)

        self._alarm_pub.publish(alarm_msg)
        return alarm_msg
Example #15
0
def make_ray(base, direction, length, color, frame='/base_link', m_id=0, **kwargs):
    '''Handle the frustration that Rviz cylinders are designated by their center, not base'''
    marker = visualization_msgs.Marker(
        ns='wamv',
        id=m_id,
        header=navigator_tools.make_header(frame=frame),
        type=visualization_msgs.Marker.LINE_STRIP,
        action=visualization_msgs.Marker.ADD,
        color=ColorRGBA(*color),
        scale=Vector3(0.05, 0.05, 0.05),
        points=map(lambda o: Point(*o), [base, direction * length]),
        lifetime=rospy.Duration(),
        **kwargs
    )
    return marker
Example #16
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 #17
0
    def clear_alarm(self):
        alarm_contents = {
            'alarm_name': self._alarm_name,
            'node_name': self._node_name,
            'severity': self._severity,
            'action_required': False,
            'clear': True,
        }
        if not self.different(**alarm_contents):
            return
        else:
            self._previous_stuff = alarm_contents

        alarm_msg = Alarm(header=navigator_tools.make_header(),
                          **alarm_contents)
        self._alarm_pub.publish(alarm_msg)
Example #18
0
 def make_ogrid(self, np_arr, size, center):
     np_center = np.array(center)
     np_origin = np.append((np_center - size / 2)[:2], 0)
     origin = navigator_tools.numpy_quat_pair_to_pose(np_origin, [0, 0, 0, 1])
      
     grid = np.zeros((size / self.resolution, size / self.resolution))
      
     ogrid = OccupancyGrid()
     ogrid.header = navigator_tools.make_header(frame='enu')
     ogrid.info.origin = origin
     ogrid.info.width = size / self.resolution
     ogrid.info.height = size / self.resolution
     ogrid.info.resolution = self.resolution 
      
     ogrid.data = np.clip(np_arr.flatten() - 1, -100, 100).astype(np.int8)
     return ogrid
Example #19
0
    def get_message(self):
        if self.grid is None:
            fprint("Ogrid was requested but no ogrid was found. Using blank.",
                   msg_color='yellow')
            self.grid = np.zeros(
                (self.height / self.resolution, self.width / self.resolution))

        ogrid = OccupancyGrid()
        ogrid.header = navigator_tools.make_header(frame="enu")
        ogrid.info.resolution = self.resolution
        ogrid.info.height, ogrid.info.width = self.grid.shape
        ogrid.info.origin = self.origin
        grid = np.copy(self.grid)
        ogrid.data = np.clip(grid.flatten() - 1, -100, 100).astype(np.int8)

        return ogrid
Example #20
0
    def make_ogrid(self, np_arr, size, center):
        np_center = np.array(center)
        np_origin = np.append((np_center - size / 2)[:2], 0)
        origin = navigator_tools.numpy_quat_pair_to_pose(
            np_origin, [0, 0, 0, 1])

        grid = np.zeros((size / self.resolution, size / self.resolution))

        ogrid = OccupancyGrid()
        ogrid.header = navigator_tools.make_header(frame='enu')
        ogrid.info.origin = origin
        ogrid.info.width = size / self.resolution
        ogrid.info.height = size / self.resolution
        ogrid.info.resolution = self.resolution

        ogrid.data = np.clip(np_arr.flatten() - 1, -100, 100).astype(np.int8)
        return ogrid
Example #21
0
    def __init__(self, rand_size):
        self.odom_pub = rospy.Publisher("/odom", Odometry, queue_size=2)
        self.odom = None
        self.carrot_sub = rospy.Subscriber("/lqrrt/ref", Odometry, self.set_odom)
        
        fprint("Shaking hands and taking names.")
        rospy.sleep(1)

        # We need to publish an inital odom message for lqrrt
        start_ori = trns.quaternion_from_euler(0, 0, np.random.normal() * 3.14)
        start_pos = np.append(np.random.uniform(rand_size, size=(2)), 1)
        start_pose = navigator_tools.numpy_quat_pair_to_pose(start_pos, start_ori)
        start_odom = Odometry()
        start_odom.header = navigator_tools.make_header(frame='enu')
        start_odom.child_frame_id = 'base_link'
        start_odom.pose.pose = start_pose
        self.odom_pub.publish(start_odom)
Example #22
0
    def raise_alarm(self, problem_description=None, parameters=None, severity=None):
        '''
            Arguments are override parameters
        '''
        got_problem_description = (problem_description != "") or (self._problem_description is not None)
        assert got_problem_description, "No problem description has been set for this alarm"

        # Allow overrideable severity
        if severity is None:
            severity = self._severity

        if parameters is not None:
            assert isinstance(parameters, dict), "Parameters must be in the form of  dictionary"

        if problem_description is not None:
            _problem_description = problem_description
        else:
            _problem_description = self._problem_description

        if parameters is not None:
            _parameters = parameters
        else:
            _parameters = self._parameters

        alarm_contents = {
            'action_required': self._action_required,
            'problem_description': _problem_description,
            'parameters': json.dumps(_parameters),
            'severity': self._severity,
            'alarm_name': self._alarm_name,
            'node_name': self._node_name,
            'clear': False,
        }
        if not self.different(**alarm_contents):
            return
        else:
            self._previous_stuff = alarm_contents

        alarm_msg = Alarm(
            header=navigator_tools.make_header(),
            **alarm_contents
        )

        self._alarm_pub.publish(alarm_msg)
        return alarm_msg
Example #23
0
    def clear_alarm(self):
        alarm_contents = {
            'alarm_name': self._alarm_name,
            'node_name': self._node_name,
            'severity': self._severity,
            'action_required': False,
            'clear': True,
        }
        if not self.different(**alarm_contents):
            return
        else:
            self._previous_stuff = alarm_contents

        alarm_msg = Alarm(
            header=navigator_tools.make_header(),
            **alarm_contents
        )
        self._alarm_pub.publish(alarm_msg)
Example #24
0
def draw_sphere(position, color, scaling=(0.11, 0.11, 0.11), m_id=4, frame='/base_link'):
    pose = Pose(
        position=navigator_tools.numpy_to_point(position),
        orientation=navigator_tools.numpy_to_quaternion([0.0, 0.0, 0.0, 1.0])
    )

    marker = visualization_msgs.Marker(
        ns='wamv',
        id=m_id,
        header=navigator_tools.make_header(frame=frame),
        type=visualization_msgs.Marker.SPHERE,
        action=visualization_msgs.Marker.ADD,
        pose=pose,
        color=ColorRGBA(*color),
        scale=Vector3(*scaling),
        lifetime=rospy.Duration(),
    )
    rviz_pub.publish(marker)
Example #25
0
    def __init__(self, rand_size):
        self.odom_pub = rospy.Publisher("/odom", Odometry, queue_size=2)
        self.odom = None
        self.carrot_sub = rospy.Subscriber("/lqrrt/ref", Odometry,
                                           self.set_odom)

        fprint("Shaking hands and taking names.")
        rospy.sleep(1)

        # We need to publish an inital odom message for lqrrt
        start_ori = trns.quaternion_from_euler(0, 0, np.random.normal() * 3.14)
        start_pos = np.append(np.random.uniform(rand_size, size=(2)), 1)
        start_pose = navigator_tools.numpy_quat_pair_to_pose(
            start_pos, start_ori)
        start_odom = Odometry()
        start_odom.header = navigator_tools.make_header(frame='enu')
        start_odom.child_frame_id = 'base_link'
        start_odom.pose.pose = start_pose
        self.odom_pub.publish(start_odom)
Example #26
0
def make_ray(base,
             direction,
             length,
             color,
             frame='/base_link',
             m_id=0,
             **kwargs):
    '''Handle the frustration that Rviz cylinders are designated by their center, not base'''
    marker = visualization_msgs.Marker(
        ns='wamv',
        id=m_id,
        header=navigator_tools.make_header(frame=frame),
        type=visualization_msgs.Marker.LINE_STRIP,
        action=visualization_msgs.Marker.ADD,
        color=ColorRGBA(*color),
        scale=Vector3(0.05, 0.05, 0.05),
        points=map(lambda o: Point(*o), [base, direction * length]),
        lifetime=rospy.Duration(),
        **kwargs)
    return marker
Example #27
0
def draw_sphere(position,
                color,
                scaling=(0.11, 0.11, 0.11),
                m_id=4,
                frame='/base_link'):
    pose = Pose(position=navigator_tools.numpy_to_point(position),
                orientation=navigator_tools.numpy_to_quaternion(
                    [0.0, 0.0, 0.0, 1.0]))

    marker = visualization_msgs.Marker(
        ns='wamv',
        id=m_id,
        header=navigator_tools.make_header(frame=frame),
        type=visualization_msgs.Marker.SPHERE,
        action=visualization_msgs.Marker.ADD,
        pose=pose,
        color=ColorRGBA(*color),
        scale=Vector3(*scaling),
        lifetime=rospy.Duration(),
    )
    rviz_pub.publish(marker)
Example #28
0
    def __init__(self):
        '''Alarm Handler
            Listen for alarms, call scenarios
        TODO:
            - Add alarm queue
            - Handle alarms in sequence (Don't get stuck in the callback)
            - bag (if set) EVERY single alarm received
        '''
        # Queue size is large because you bet your ass we are addressing every alarm
        self.alarm_sub = rospy.Subscriber('/alarm_raise',
                                          Alarm,
                                          self.alarm_callback,
                                          queue_size=100)
        self.alarm_pub = rospy.Publisher('/alarm', Alarm, queue_size=100)

        self.alarms = {}
        self.scenarios = {}

        for alarm in meta_alarms_inv:
            self.alarms[alarm] = Alarm(alarm_name=alarm,
                                       clear=True,
                                       header=navigator_tools.make_header())

        self.alarm_republish_timer = rospy.Timer(rospy.Duration(0.05),
                                                 self.republish_alarms)

        # Go through everything in the navigator_alarm.alarm_handlers package
        for candidate_alarm_name in dir(alarm_handlers):
            # Discard __* nonsense
            if not candidate_alarm_name.startswith('_'):
                # Verify that it is actually an alarm handler by checking if the class inherits from `HandlerBase`
                handlers = inspect.getmembers(
                    getattr(alarm_handlers, candidate_alarm_name),
                    inspect.isclass)
                handlers = [handler for handler in handlers if handler[0] != "HandlerBase" and \
                                                               issubclass(handler[1], HandlerBase)]
                for handler_name, handler_class in handlers:
                    rospy.loginfo("Registered scenario with name '{}'".format(
                        handler_class.alarm_name))
                    self.scenarios[handler_class.alarm_name] = handler_class()
Example #29
0
def main(navigator):
    result = navigator.fetch_result()

    found_buoys = yield navigator.database_query("start_gate")

    buoys = np.array(map(Buoy.from_srv, found_buoys.objects))

    if len(buoys) == 2:
        ogrid, setup, target = yield two_buoys(navigator, buoys, 10)
    elif len(buoys) == 4:
        ogrid, setup, target = yield four_buoys(navigator, buoys, 10)
    else:
        raise Exception

    # Put the target into the point cloud as well
    points = []
    points.append(navigator_tools.numpy_to_point(target.position))
    pc = PointCloud(header=navigator_tools.make_header(frame='/enu'),
                    points=np.array(points))
   
    yield navigator._point_cloud_pub.publish(pc)
    print "Waiting 3 seconds to move..."
    yield navigator.nh.sleep(3)
    yield setup.go(move_type='skid')
 
    pose = yield navigator.tx_pose
    ogrid.generate_grid(pose)
    msg = ogrid.get_message()

    print "publishing"
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid, msg)


    print "START_GATE: Moving in 5 seconds!"
    yield target.go(initial_plan_time=5)
    return_with(result)
Example #30
0
def main(navigator):
    result = navigator.fetch_result()

    found_buoys = yield navigator.database_query("start_gate")

    buoys = np.array(map(Buoy.from_srv, found_buoys.objects))

    if len(buoys) == 2:
        ogrid, setup, target = yield two_buoys(navigator, buoys, 10)
    elif len(buoys) == 4:
        ogrid, setup, target = yield four_buoys(navigator, buoys, 10)
    else:
        raise Exception

    # Put the target into the point cloud as well
    points = []
    points.append(navigator_tools.numpy_to_point(target.position))
    pc = PointCloud(header=navigator_tools.make_header(frame='/enu'),
                    points=np.array(points))

    yield navigator._point_cloud_pub.publish(pc)
    print "Waiting 3 seconds to move..."
    yield navigator.nh.sleep(3)
    yield setup.go(move_type='skid')

    pose = yield navigator.tx_pose
    ogrid.generate_grid(pose)
    msg = ogrid.get_message()

    print "publishing"
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid,
                                           msg)

    print "START_GATE: Moving in 5 seconds!"
    yield target.go(initial_plan_time=5)
    return_with(result)
Example #31
0
 def as_MoveToGoal(self, linear=[0, 0, 0], angular=[0, 0, 0], **kwargs):
     return MoveToGoal(
         header=make_header(),
         posetwist=self.as_PoseTwist(linear, angular),
         **kwargs
     )
Example #32
0
    def do_observe(self, *args):
        resp = self.make_request(name='totem')

        # If atleast one totem was found start observing
        if resp.found:
            # Time of the databse request
            time_of_marker = resp.objects[0].header.stamp  # - ros_t(1)
            fprint("Looking for image at {}".format(time_of_marker.to_sec()),
                   msg_color='yellow')
            image_holder = self.image_history.get_around_time(time_of_marker)
            if not image_holder.contains_valid_image:
                t = self.image_history.newest_image.time
                if t is None:
                    fprint("No images found.")
                    return

                fprint("No valid image found for t={} ({}) dt: {}".format(
                    time_of_marker.to_sec(), t.to_sec(),
                    (rospy.Time.now() - t).to_sec()),
                       msg_color='red')
                return
            header = navigator_tools.make_header(frame='/enu',
                                                 stamp=image_holder.time)
            image = image_holder.image
            self.debug.image = np.copy(image)

            cam_tf = self.camera_model.tfFrame()
            try:
                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)
            except tf.ExtrapolationException as e:
                fprint("TF error found and excepted: {}".format(e))
                return

            for obj in resp.objects:
                if len(obj.points) <= 1:
                    fprint("No points in object")
                    continue

                fprint("{} {}".format(obj.id, "=" * 50))

                # Get object position in px coordinates to determine if it's in frame
                object_cam = t_mat44.dot(np.append(p2np(obj.position), 1))
                object_px = map(
                    int, self.camera_model.project3dToPixel(object_cam[:3]))
                if not self._object_in_frame(object_cam):
                    fprint("Object not in frame")
                    continue

                # Get enu points associated with this totem and remove ones that are too low
                points_np = np.array(map(p2np, obj.points))
                height = np.max(points_np[:, 2]) - np.min(points_np[:, 2])
                if height < .1:
                    # If the height of the object is too small, skip (units are meters)
                    fprint("Object too small")
                    continue

                threshold = np.min(points_np[:,
                                             2]) + self.height_remove * height
                points_np = points_np[points_np[:, 2] > threshold]

                # Shove ones in there to make homogenous points to get points in image frame
                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])

                [
                    cv2.circle(self.debug.image, tuple(map(int, p)), 2,
                               (255, 255, 255), -1) for p in points_px
                ]

                # Get color information from the points
                roi = self._get_ROI_from_points(points_px)
                h, s, v = self._get_hsv_from_ROI(roi, image)

                # Compute parameters that go into the confidence
                boat_q = self.odom[1]
                target_q = self._get_solar_angle()
                q_err = self._get_quaternion_error(boat_q, target_q)

                dist = np.linalg.norm(self.odom[0] - p2np(obj.position))

                fprint("H: {}, S: {}, V: {}".format(h, s, v))
                fprint("q_err: {}, dist: {}".format(q_err, dist))

                # Add to database and setup debug image
                if s < self.saturation_reject or v < self.value_reject:
                    err_msg = "The colors aren't expressive enough s: {} ({}) v: {} ({}). Rejecting."
                    fprint(err_msg.format(s, self.saturation_reject, v,
                                          self.value_reject),
                           msg_color='red')

                else:
                    if obj.id not in self.colored:
                        self.colored[obj.id] = Observation()

                    # Add this observation in
                    self.colored[obj.id] += h, v, dist, q_err
                    print self.colored[obj.id]

                rgb = (0, 0, 0)
                color = self.do_estimate(obj.id)
                # Do we have a valid color estimate
                if color:
                    fprint("COLOR IS VALID", msg_color='green')
                    rgb = self.database_color_map[color[0]]

                    cmd = '{name}={rgb[0]},{rgb[1]},{rgb[2]},{_id}'
                    self.make_request(
                        cmd=cmd.format(name=obj.name, _id=obj.id, rgb=rgb))

                bgr = rgb[::-1]
                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)
Example #33
0
def do_buoys(srv, left, right, red_seg, green_seg, tf_listener):
    '''
    FYI:
        `left`: the left camera ImageGetter object
        `right`: the right camera ImageGetter object
    '''
    left_point = None
    right_point = None

    while not rospy.is_shutdown():
        # Get all the required TF links
        try:
            # Working copy of the current frame obtained at the same time as the tf link
            tf_listener.waitForTransform("enu", "front_left_cam", rospy.Time(),
                                         rospy.Duration(4.0))
            left_image, right_image = left.frame, right.frame
            cam_tf = tf_listener.lookupTransform("front_left_cam",
                                                 "front_right_cam",
                                                 left.sub.last_image_time)
            cam_p, cam_q = tf_listener.lookupTransform(
                "enu", "front_left_cam", left.sub.last_image_time)
            cam_p = np.array([cam_p])
            cam_r = tf.transformations.quaternion_matrix(cam_q)[:3, :3]
            break

        except (tf.LookupException, tf.ConnectivityException,
                tf.ExtrapolationException, TypeError) as e:
            print e
            rospy.logwarn("TF link not found.")
            time.sleep(.5)
            continue

    red_left_pt, rl_area = red_seg.segment(left_image)
    red_right_pt, rr_area = red_seg.segment(right_image)
    green_left_pt, gl_area = green_seg.segment(left_image)
    green_right_pt, gr_area = green_seg.segment(right_image)

    area_tol = 50
    if np.linalg.norm(rl_area - rr_area) > area_tol or np.linalg.norm(
            gl_area - gr_area) > area_tol:
        rospy.logwarn("Unsafe segmentation")
        StartGateResponse(success=False)

    red_point_np = do_the_magic(red_left_pt, red_right_pt, cam_tf)
    red_point_np = np.array(cam_r.dot(red_point_np) + cam_p)[0]
    green_point_np = do_the_magic(green_left_pt, green_right_pt, cam_tf)
    green_point_np = np.array(cam_r.dot(green_point_np) + cam_p)[0]

    # Just for visualization
    for i in range(5):
        # Publish it 5 times so we can see it in rviz
        navigator_tools.draw_ray_3d(red_left_pt,
                                    left_cam, [1, 0, 0, 1],
                                    m_id=0,
                                    frame="front_left_cam")
        navigator_tools.draw_ray_3d(red_right_pt,
                                    right_cam, [1, 0, 0, 1],
                                    m_id=1,
                                    frame="front_right_cam")
        navigator_tools.draw_ray_3d(green_left_pt,
                                    left_cam, [0, 1, 0, 1],
                                    m_id=2,
                                    frame="front_left_cam")
        navigator_tools.draw_ray_3d(green_right_pt,
                                    right_cam, [0, 1, 0, 1],
                                    m_id=3,
                                    frame="front_right_cam")

        red_point = PointStamped()
        red_point.header = navigator_tools.make_header(frame="enu")
        red_point.point = navigator_tools.numpy_to_point(red_point_np)
        red_pub.publish(red_point)

        green_point = PointStamped()
        green_point.header = navigator_tools.make_header(frame="enu")
        green_point.point = navigator_tools.numpy_to_point(green_point_np)
        green_pub.publish(green_point)

        time.sleep(1)

    # Now we have two points, find their midpoint and calculate a target angle
    midpoint = (red_point_np + green_point_np) / 2
    between_vector = green_point_np - red_point_np  # Red is on the left when we go out.
    yaw_theta = np.arctan2(between_vector[1], between_vector[0])
    # Rotate that theta by 90 deg to get the angle through the buoys
    yaw_theta += np.pi / 2.0

    p = midpoint
    q = tf.transformations.quaternion_from_euler(0, 0, yaw_theta)

    target_pose = PoseStamped()
    target_pose.header = navigator_tools.make_header(frame="enu")
    target_pose.pose = navigator_tools.numpy_quat_pair_to_pose(p, q)

    return StartGateResponse(target=target_pose, success=True)
Example #34
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 #35
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
def do_buoys(srv, left, right, red_seg, green_seg, tf_listener):
    '''
    FYI:
        `left`: the left camera ImageGetter object
        `right`: the right camera ImageGetter object
    '''
    left_point = None
    right_point = None

    while not rospy.is_shutdown():
        # Get all the required TF links
        try:
            # Working copy of the current frame obtained at the same time as the tf link
            tf_listener.waitForTransform("enu", "stereo_left_cam", rospy.Time(), rospy.Duration(4.0))
            left_image, right_image = left.frame, right.frame
            cam_tf = tf_listener.lookupTransform("stereo_left_cam", "stereo_right_cam", left.sub.last_image_time)
            cam_p, cam_q = tf_listener.lookupTransform("enu", "stereo_left_cam", left.sub.last_image_time)
            cam_p = np.array([cam_p])
            cam_r = tf.transformations.quaternion_matrix(cam_q)[:3, :3]
            break

        except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException, TypeError) as e:
            print e
            rospy.logwarn("TF link not found.")
            time.sleep(.5)
            continue

    red_left_pt, rl_area = red_seg.segment(left_image)
    red_right_pt, rr_area = red_seg.segment(right_image)
    green_left_pt, gl_area = green_seg.segment(left_image)
    green_right_pt, gr_area = green_seg.segment(right_image)

    area_tol = 50
    if np.linalg.norm(rl_area - rr_area) > area_tol or np.linalg.norm(gl_area - gr_area) > area_tol:
        rospy.logwarn("Unsafe segmentation")
        StartGateResponse(success=False)

    red_point_np = do_the_magic(red_left_pt, red_right_pt, cam_tf)
    red_point_np = np.array(cam_r.dot(red_point_np) + cam_p)[0]
    green_point_np = do_the_magic(green_left_pt, green_right_pt, cam_tf)
    green_point_np = np.array(cam_r.dot(green_point_np) + cam_p)[0]

    # Just for visualization
    for i in range(5):
        # Publish it 5 times so we can see it in rviz
        navigator_tools.draw_ray_3d(red_left_pt, left_cam, [1, 0, 0, 1],  m_id=0, frame="stereo_left_cam")
        navigator_tools.draw_ray_3d(red_right_pt, right_cam, [1, 0, 0, 1],  m_id=1, frame="stereo_right_cam")
        navigator_tools.draw_ray_3d(green_left_pt, left_cam, [0, 1, 0, 1],  m_id=2, frame="stereo_left_cam")
        navigator_tools.draw_ray_3d(green_right_pt, right_cam, [0, 1, 0, 1],  m_id=3, frame="stereo_right_cam")

        red_point = PointStamped()
        red_point.header = navigator_tools.make_header(frame="enu")
        red_point.point = navigator_tools.numpy_to_point(red_point_np)
        red_pub.publish(red_point)

        green_point = PointStamped()
        green_point.header = navigator_tools.make_header(frame="enu")
        green_point.point = navigator_tools.numpy_to_point(green_point_np)
        green_pub.publish(green_point)

        time.sleep(1)

    # Now we have two points, find their midpoint and calculate a target angle
    midpoint = (red_point_np + green_point_np) / 2
    between_vector = green_point_np - red_point_np  # Red is on the left when we go out.
    yaw_theta = np.arctan2(between_vector[1], between_vector[0])
    # Rotate that theta by 90 deg to get the angle through the buoys
    yaw_theta += np.pi / 2.0

    p = midpoint
    q = tf.transformations.quaternion_from_euler(0, 0, yaw_theta)

    target_pose = PoseStamped()
    target_pose.header = navigator_tools.make_header(frame="enu")
    target_pose.pose = navigator_tools.numpy_quat_pair_to_pose(p, q)

    return StartGateResponse(target=target_pose, success=True)
Example #37
0
def main(navigator):
    result = navigator.fetch_result()

    found_buoys = yield navigator.database_query("start_gate")

    if found_buoys.found:
        buoys = np.array(map(Buoy.from_srv, found_buoys.objects))
    else:
        print "START_GATE: Error 4 - No db buoy response..."
        result.success = False
        result.response = result.DbObjectNotFound
        result.message = "Start gates not found in the database."
        return_with(result)

    if len(buoys) != 4:
        print "START_GATE: Error 5 - Invaild number of buoys found: {} (expecting 4)".format(
            len(buoys))
        result.success = False
        result.message = "Invaild number of buoys found: {} (expecting 4)".format(
            len(buoys))
        return_with(result)

    # buoys = [Buoy.from_srv(left), Buoy.from_srv(right)]
    #buoys = np.array(get_buoys())
    pose = yield navigator.tx_pose
    # Get the ones closest to us and assume those are the front
    distances = np.array([b.distance(pose[0]) for b in buoys])
    back = buoys[np.argsort(distances)[-2:]]
    front = buoys[np.argsort(distances)[:2]]

    #print "front", front
    #print "back", back

    # Made it this far, make sure the red one is on the left and green on the right ================
    t = txros.tf.Transform.from_Pose_message(
        navigator_tools.numpy_quat_pair_to_pose(*pose))
    t_mat44 = t.as_matrix()
    f_bl_buoys = [t_mat44.dot(np.append(buoy.position, 1)) for buoy in front]
    b_bl_buoys = [t_mat44.dot(np.append(buoy.position, 1)) for buoy in back]

    # Angles are w.r.t positive x-axis. Positive is CCW around the z-axis.
    angle_buoys = np.array(
        [np.arctan2(buoy[1], buoy[0]) for buoy in f_bl_buoys])
    #print angle_buoys, front
    f_left_buoy, f_right_buoy = front[np.argmax(angle_buoys)], front[np.argmin(
        angle_buoys)]

    angle_buoys = np.array(
        [np.arctan2(buoy[1], buoy[0]) for buoy in b_bl_buoys])
    b_left_buoy, b_right_buoy = back[np.argmax(angle_buoys)], back[np.argmin(
        angle_buoys)]

    points = [
        navigator_tools.numpy_to_point(b.position) for b in [f_left_buoy]
    ]

    # Lets plot a course, yarrr
    f_between_vector, f_direction_vector = get_path(f_left_buoy, f_right_buoy)
    f_mid_point = f_left_buoy.position + f_between_vector / 2
    b_between_vector, _ = get_path(b_left_buoy, b_right_buoy)
    b_mid_point = b_left_buoy.position + b_between_vector / 2
    through_vector = b_mid_point - f_mid_point
    through_vector = through_vector / np.linalg.norm(through_vector)

    #print mid_point
    setup_dist = 20  # Line up with the start gate this many meters infront of the gate.
    setup = f_mid_point - f_direction_vector * setup_dist
    target = b_mid_point + through_vector * setup_dist

    # Put the target into the point cloud as well
    #points.append(navigator_tools.numpy_to_point(b_left_buoy))
    points.append(navigator_tools.numpy_to_point(target))
    pc = PointCloud(header=navigator_tools.make_header(frame='/enu'),
                    points=np.array(points))

    yield navigator._point_cloud_pub.publish(pc)
    print "Waiting 3 seconds to move..."
    yield navigator.nh.sleep(3)
    yield navigator.move.set_position(setup).look_at(f_mid_point).go(
        move_type="skid")

    pose = yield navigator.tx_pose
    ogrid = OgridFactory(f_left_buoy.position,
                         f_right_buoy.position,
                         pose[0],
                         target,
                         left_b_pos=b_left_buoy.position,
                         right_b_pos=b_right_buoy.position)
    msg = ogrid.get_message()

    print "publishing"
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid,
                                           msg)

    yield navigator.nh.sleep(5)

    print "START_GATE: Moving in 5 seconds!"
    yield navigator.move.set_position(target).go(initial_plan_time=5)
    return_with(result)
Example #38
0
    def do_observe(self, *args):
        resp = self.make_request(name='totem')
        
        # If atleast one totem was found start observing
        if resp.found:
            # Time of the databse request
            time_of_marker = resp.objects[0].header.stamp# - ros_t(1)
            fprint("Looking for image at {}".format(time_of_marker.to_sec()), msg_color='yellow')
            image_holder = self.image_history.get_around_time(time_of_marker)
            if not image_holder.contains_valid_image:
                t = self.image_history.newest_image.time
                if t is None:
                    fprint("No images found.")
                    return
                
                fprint("No valid image found for t={} ({}) dt: {}".format(time_of_marker.to_sec(), t.to_sec(), (rospy.Time.now() - t).to_sec()), msg_color='red')
                return
            header = navigator_tools.make_header(frame='/enu', stamp=image_holder.time)
            image = image_holder.image
            self.debug.image = np.copy(image)

            cam_tf = self.camera_model.tfFrame()
            try:
                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)
            except tf.ExtrapolationException as e:
                fprint("TF error found and excepted: {}".format(e))
                return

            for obj in resp.objects:
                if len(obj.points) <= 1:
                    fprint("No points in object")
                    continue

                fprint("{} {}".format(obj.id, "=" * 50))
                
                # Get object position in px coordinates to determine if it's in frame
                object_cam = t_mat44.dot(np.append(p2np(obj.position), 1))
                object_px = map(int, self.camera_model.project3dToPixel(object_cam[:3]))
                if not self._object_in_frame(object_cam):
                    fprint("Object not in frame")
                    continue
                
                # Get enu points associated with this totem and remove ones that are too low
                points_np = np.array(map(p2np, obj.points))
                height = np.max(points_np[:, 2]) - np.min(points_np[:, 2])
                if height < .1:
                    # If the height of the object is too small, skip (units are meters)
                    fprint("Object too small")
                    continue

                threshold = np.min(points_np[:, 2]) + self.height_remove * height  
                points_np = points_np[points_np[:, 2] > threshold]
                
                # Shove ones in there to make homogenous points to get points in image frame
                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])
                
                [cv2.circle(self.debug.image, tuple(map(int, p)), 2, (255, 255, 255), -1) for p in points_px]
                
                # Get color information from the points
                roi = self._get_ROI_from_points(points_px)
                h, s, v = self._get_hsv_from_ROI(roi, image)

                # Compute parameters that go into the confidence
                boat_q = self.odom[1]
                target_q = self._get_solar_angle()
                q_err = self._get_quaternion_error(boat_q, target_q)
                
                dist = np.linalg.norm(self.odom[0] - p2np(obj.position))

                fprint("H: {}, S: {}, V: {}".format(h, s, v))
                fprint("q_err: {}, dist: {}".format(q_err, dist))

                # Add to database and setup debug image
                if s < self.saturation_reject or v < self.value_reject:
                    err_msg = "The colors aren't expressive enough s: {} ({}) v: {} ({}). Rejecting."
                    fprint(err_msg.format(s, self.saturation_reject, v, self.value_reject), msg_color='red')

                else:
                    if obj.id not in self.colored:
                       self.colored[obj.id] = Observation() 
                    
                    # Add this observation in
                    self.colored[obj.id] += h, v, dist, q_err
                    print self.colored[obj.id]

                rgb = (0, 0, 0)
                color = self.do_estimate(obj.id)
                # Do we have a valid color estimate
                if color:
                    fprint("COLOR IS VALID", msg_color='green')
                    rgb = self.database_color_map[color[0]]
                    
                    cmd = '{name}={rgb[0]},{rgb[1]},{rgb[2]},{_id}'
                    self.make_request(cmd=cmd.format(name=obj.name,_id=obj.id, rgb=rgb))

                bgr = rgb[::-1]
                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)
Example #39
0
 def keepalive_pub(self, *args):
     h = navigator_tools.make_header()
     self.pub.publish(h)
Example #40
0
def main(navigator):
    result = navigator.fetch_result()

    found_buoys = yield navigator.database_query("start_gate")

    if found_buoys.found:
       buoys = np.array(map(Buoy.from_srv, found_buoys.objects))
    else:
       print "START_GATE: Error 4 - No db buoy response..."
       result.success = False
       result.response = result.DbObjectNotFound
       result.message = "Start gates not found in the database."
       return_with(result)

    if len(buoys) != 4:
       print "START_GATE: Error 5 - Invaild number of buoys found: {} (expecting 4)".format(len(buoys))
       result.success = False
       result.message = "Invaild number of buoys found: {} (expecting 4)".format(len(buoys))
       return_with(result)


    # buoys = [Buoy.from_srv(left), Buoy.from_srv(right)]
    #buoys = np.array(get_buoys())
    pose = yield navigator.tx_pose
    # Get the ones closest to us and assume those are the front
    distances = np.array([b.distance(pose[0]) for b in buoys])
    back = buoys[np.argsort(distances)[-2:]]
    front = buoys[np.argsort(distances)[:2]]

    #print "front", front
    #print "back", back

    # Made it this far, make sure the red one is on the left and green on the right ================
    t = txros.tf.Transform.from_Pose_message(navigator_tools.numpy_quat_pair_to_pose(*pose))
    t_mat44 = t.as_matrix()
    f_bl_buoys = [t_mat44.dot(np.append(buoy.position, 1)) for buoy in front]
    b_bl_buoys = [t_mat44.dot(np.append(buoy.position, 1)) for buoy in back]

    # Angles are w.r.t positive x-axis. Positive is CCW around the z-axis.
    angle_buoys = np.array([np.arctan2(buoy[1], buoy[0]) for buoy in f_bl_buoys])
    #print angle_buoys, front
    f_left_buoy, f_right_buoy = front[np.argmax(angle_buoys)], front[np.argmin(angle_buoys)]

    angle_buoys = np.array([np.arctan2(buoy[1], buoy[0]) for buoy in b_bl_buoys])
    b_left_buoy, b_right_buoy = back[np.argmax(angle_buoys)], back[np.argmin(angle_buoys)]
 
    points = [navigator_tools.numpy_to_point(b.position) for b in [f_left_buoy]]

    # Lets plot a course, yarrr
    f_between_vector, f_direction_vector = get_path(f_left_buoy, f_right_buoy)
    f_mid_point = f_left_buoy.position + f_between_vector / 2
    b_between_vector, _ = get_path(b_left_buoy, b_right_buoy)
    b_mid_point = b_left_buoy.position + b_between_vector / 2
    through_vector = b_mid_point - f_mid_point
    through_vector = through_vector / np.linalg.norm(through_vector)

    #print mid_point
    setup_dist = 20  # Line up with the start gate this many meters infront of the gate.
    setup = f_mid_point - f_direction_vector * setup_dist
    target = b_mid_point + through_vector * setup_dist

    # Put the target into the point cloud as well
    #points.append(navigator_tools.numpy_to_point(b_left_buoy))
    points.append(navigator_tools.numpy_to_point(target))
    pc = PointCloud(header=navigator_tools.make_header(frame='/enu'),
                    points=np.array(points))
   
    yield navigator._point_cloud_pub.publish(pc)
    print "Waiting 3 seconds to move..."
    yield navigator.nh.sleep(3)
    yield navigator.move.set_position(setup).look_at(f_mid_point).go(move_type="skid")

    pose = yield navigator.tx_pose
    ogrid = OgridFactory(f_left_buoy.position, f_right_buoy.position, pose[0],
                         target, left_b_pos=b_left_buoy.position, right_b_pos=b_right_buoy.position)
    msg = ogrid.get_message()

    print "publishing"
    latched = navigator.latching_publisher("/mission_ogrid", OccupancyGrid, msg)

    yield navigator.nh.sleep(5)

    print "START_GATE: Moving in 5 seconds!"
    yield navigator.move.set_position(target).go(initial_plan_time=5)
    return_with(result)
Example #41
0
 def as_MoveToGoal(self, linear=[0, 0, 0], angular=[0, 0, 0], **kwargs):
     return MoveToGoal(header=make_header(),
                       posetwist=self.as_PoseTwist(linear, angular),
                       **kwargs)