Exemple #1
0
    def observation_update(self, left_lane_image, right_lane_image):
        """Update particle weights using observation

        :param left_lane_image: an array of line points for the left lane in the image, e.g. [u1, v1, u2, v2]
        :param right_lane_image: an array of line points for the right lane in the image, e.g. [u1, v1, u2, v2]
        :return:
        """

        if left_lane_image is None and right_lane_image is None:
            # No lanes detected
            return
        elif right_lane_image is None:
            # Only left lane is detected
            left_lane_ground = functions.line_image2ground(left_lane_image)
            left_slope, left_intercept = functions.line_points2slope_intercept(left_lane_ground)

            y_expected = (self.lane_width / 2.) - left_intercept

            left_angle = np.arctan(left_slope)
            phi_expected = -left_angle

        elif left_lane_image is None:
            # Only right lane detected
            right_lane_ground = functions.line_image2ground(right_lane_image)
            right_slope, right_intercept = functions.line_points2slope_intercept(right_lane_ground)

            y_expected = (-self.lane_width / 2.) + right_intercept

            right_angle = np.arctan(right_slope)
            phi_expected = -right_angle

        else:
            # Both lanes are detected
            left_lane_ground = functions.line_image2ground(left_lane_image)
            right_lane_ground = functions.line_image2ground(right_lane_image)

            # Determine Duckiebot pose from observation
            left_slope, left_intercept = functions.line_points2slope_intercept(left_lane_ground)
            right_slope, right_intercept = functions.line_points2slope_intercept(right_lane_ground)

            # Expected y position is the deviation from the centre of the left and right intercepts
            y_expected = -(left_intercept + right_intercept) / 2.

            # Convert slopes to angles
            left_angle = np.arctan(left_slope)
            right_angle = np.arctan(right_slope)

            # Expected angle is the negative of the average of the left and right slopes
            phi_expected = -((left_angle + right_angle) / 2.)

        # Compare the position of each particle with the expected position from the observation to adjust weight
        for particle in self.particles:
            y_diff = np.abs(particle.y - y_expected)
            phi_diff = np.abs(particle.phi - phi_expected)

            # This isn't a good way of determining likelihood, but it seems to be work
            y_likelihood = max(1. - y_diff / 0.5, 0.1)
            phi_likelihood = max(1. - phi_diff / (np.pi / 4.), 0.1)

            particle.weight *= y_likelihood * phi_likelihood
def estimate_pose(left_lane_image, right_lane_image):
    # Estimate pose from a single observation

    global lane_width

    if right_lane_image is None:
        # Only left lane is detected
        left_lane_ground = functions.line_image2ground(left_lane_image)
        left_slope, left_intercept = functions.line_points2slope_intercept(
            left_lane_ground)

        y_expected = (lane_width / 2.) - left_intercept

        left_angle = np.arctan(left_slope)
        phi_expected = -left_angle

    elif left_lane_image is None:
        # Only right lane detected
        right_lane_ground = functions.line_image2ground(right_lane_image)
        right_slope, right_intercept = functions.line_points2slope_intercept(
            right_lane_ground)

        y_expected = (-lane_width / 2.) + right_intercept

        right_angle = np.arctan(right_slope)
        phi_expected = -right_angle

    else:
        # Both lanes are detected
        left_lane_ground = functions.line_image2ground(left_lane_image)
        right_lane_ground = functions.line_image2ground(right_lane_image)

        # Determine Duckiebot pose from observation
        left_slope, left_intercept = functions.line_points2slope_intercept(
            left_lane_ground)
        right_slope, right_intercept = functions.line_points2slope_intercept(
            right_lane_ground)

        # Expected y position is the deviation from the centre of the left and right intercepts
        y_expected = -(left_intercept + right_intercept) / 2.

        # Convert slopes to angles
        left_angle = np.arctan(left_slope)
        right_angle = np.arctan(right_slope)

        # Expected angle is the negative of the average of the left and right slopes
        phi_expected = -((left_angle + right_angle) / 2.)

    return [y_expected, phi_expected]