Exemple #1
0
    def plot_y_lever_arm_error(self, subplot: plt.subplot = None, add_regression: bool = True):
        """
        Plot to find the y lever arm error, which is determined by looking at the correlation between filtered depth
        and roll.  Y lever arm error affects the induced heave by the following equation:

        Induced Heave Error = -(x_error) * sin(pitch) + (y_error) * sin(roll) * cos(pitch) +
                              (z_error) * (1 - cos(roll) * cos(pitch))

        or in isloating the y

        Induced Heave Error (y) = y_error * sin(roll) * cos(pitch)

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        add_regression
            bool, if True, will include a regression line
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.scatter(self.roll_at_ping_time, self.hpf_depth)
        subplot.set_ylim(-self.hpf_depth.max() * 4, self.hpf_depth.max() * 4)
        subplot.set_title('Y Sonar Offset Error')
        subplot.set_xlabel('Roll (deg)')
        subplot.set_ylabel('Highpassfilter Depth (m)')
        if add_regression:
            self._add_regression_line(subplot, self.roll_at_ping_time, self.hpf_depth)
Exemple #2
0
    def plot_attitude_scaling_two(self, subplot: plt.subplot = None, add_regression: bool = True):
        """
        See attitude_scaling_one, same concept.  We have two plots for a good reason.  If you are trying to
        differentiate between 1. and 2., do the following:
        | - if scaling_one and scaling_two have your artifact, its probably a scaling issue
        | - otherwise, if the plots are different, it most likely is the sound speed one.  Inner swath and outer swath
        |   will differ as the swath is curved

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        add_regression
            bool, if True, will include a regression line
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.scatter(self.roll_at_ping_time, self.hpf_inner_slope)
        subplot.set_ylim(-self.hpf_inner_slope.max() * 4, self.hpf_inner_slope.max() * 4)
        subplot.set_title('Attitude Scaling/Surface Sound Speed 2')
        subplot.set_xlabel('Roll (deg)')
        subplot.set_ylabel('Trimmed Slope (deg)')
        if add_regression:
            self._add_regression_line(subplot, self.roll_at_ping_time, self.hpf_inner_slope)
Exemple #3
0
    def _add_regression_line(self, ax: plt.subplot, x: np.array, y: np.array):
        """
        Build linear regression of x y data and plot on included ax

        Parameters
        ----------
        ax
            pyplot AxesSubplot instance
        x
            numpy array, 1d
        y
            numpy array, 1d

        Returns
        -------
        str
            regression line slope rounded to 6 places as string
        """
        # nan not allowed for regression line
        filter_nan = np.logical_or(np.isnan(x), np.isnan(y))
        x = x[~filter_nan]
        y = y[~filter_nan]

        slopes, intercepts, stderrs, percent_deviation = linear_regression(x, y)
        slope_label = np.round(slopes, 6)
        ax.plot(x, slopes * x + intercepts,
                label='y = {}x + {}'.format(slope_label, np.round(intercepts, 6)), color='red')
        ax.legend()
        return slope_label
Exemple #4
0
    def plot_attitude_scaling_one(self, subplot: plt.subplot = None, add_regression: bool = True):
        """
        | This plot (as well as the trimmed plot scaling_two) deal with identifying:
        |  1. sensor scaling issues (should not be present in modern systems I think)
        |  2. rolling with imperfect sound speed (probably more likely)

        Focusing on the second one:

        When the soundspeed at the face is incorrect, roll angles will introduce steering angle error, so your
        beampointingangle will be off.  As the roll changes, the error will change, making this a dynamic error that
        is correlated with roll.

        We aren't going to make up some kind of time series bpa corrector for this error, so if you have this, i
        believe you are just screwed.

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        add_regression
            bool, if True, will include a regression line
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.scatter(self.roll_at_ping_time, self.hpf_slope)
        subplot.set_ylim(-self.hpf_slope.max() * 4, self.hpf_slope.max() * 4)
        subplot.set_title('Attitude Scaling/Surface Sound Speed 1')
        subplot.set_xlabel('Roll (deg)')
        subplot.set_ylabel('Ping Slope (deg)')
        if add_regression:
            self._add_regression_line(subplot, self.roll_at_ping_time, self.hpf_slope)
Exemple #5
0
    def plot_heave_sound_speed_two(self,
                                   subplot: plt.subplot = None,
                                   add_regression: bool = True):
        """
        See plot_heave_sound_speed_one.  There are two plots for the port/starboard swaths.  You need two as the
        swath artifact is a smile/frown, so the two plots should be mirror images if the artifact exists.  A full
        swath analysis would not show this.

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        add_regression
            bool, if True, will include a regression line
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.scatter(self.vert_motion_at_ping_time, self.hpf_stbd_slope)
        subplot.set_ylim(-self.hpf_stbd_slope.max() * 4,
                         self.hpf_stbd_slope.max() * 4)
        subplot.set_title('Heave Through Sound Speed Layers 2')
        subplot.set_xlabel('Heave (m)')
        subplot.set_ylabel('Stbd Slope (deg)')
        if add_regression:
            self._add_regression_line(subplot, self.vert_motion_at_ping_time,
                                      self.hpf_stbd_slope)
Exemple #6
0
    def plot_heave_sound_speed_one(self,
                                   subplot: plt.subplot = None,
                                   add_regression: bool = True):
        """
        Plot to find error associated with heaving through sound speed layers.  For flat face sonar that are mostly
        level while receiving, this affect should be minimal.  If I'm understanding this correctly, it's because the
        system is actively steering the beams using the surface sv sensor.  For barrel arrays, there is no active
        beam steering so there will be an error in the beam angles.

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        add_regression
            bool, if True, will include a regression line
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.scatter(self.vert_motion_at_ping_time, self.hpf_port_slope)
        subplot.set_ylim(-self.hpf_port_slope.max() * 4,
                         self.hpf_port_slope.max() * 4)
        subplot.set_title('Heave Through Sound Speed Layers 1')
        subplot.set_xlabel('Heave (m)')
        subplot.set_ylabel('Port Slope (deg)')
        if add_regression:
            self._add_regression_line(subplot, self.vert_motion_at_ping_time,
                                      self.hpf_port_slope)
Exemple #7
0
    def plot_yaw_alignment(self,
                           subplot: plt.subplot = None,
                           add_regression: bool = True):
        """
        Plot to determine the misalignment between roll/pitch and heading.  For us, the POSMV is a tightly
        coupled system that provides these three data streams, so there really shouldn't be any yaw misalignment with
        roll/pitch.

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        add_regression
            bool, if True, will include a regression line
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.scatter(self.pitch_at_ping_time, self.hpf_slope)
        subplot.set_ylim(-self.hpf_slope.max() * 4, self.hpf_slope.max() * 4)
        subplot.set_title('Yaw Alignment with Reference')
        subplot.set_xlabel('Pitch (deg)')
        subplot.set_ylabel('Ping Slope (deg)')
        if add_regression:
            self._add_regression_line(subplot, self.pitch_at_ping_time,
                                      self.hpf_slope)
Exemple #8
0
def setup_subplots(subplot: plt.subplot, width: int, height: int, color: str, title: str):
    """ Configure subplots.

    :param subplot: plt.subplot
    :param width: int
    :param height: int
    :param color: str
    :param title: str
    """

    subplot.set_xlim(0, width)
    subplot.xaxis.tick_top()
    subplot.set_ylim(height, 0)
    subplot.grid(color=color, linestyle='-', linewidth=1)
    subplot.set_aspect('equal', adjustable='box')
    subplot.set_title(title)
Exemple #9
0
    def plot_attitude_latency(self, subplot: plt.subplot = None, add_regression: bool = True):
        """
        Plot to determine the attitude latency either in the POSMV initial processing or the transmission to the sonar.
        We use roll just because it is the most sensitive, most easy to notice.  It's a linear tilt we are looking for,
        so the timing latency would be equal to the slope of the regression of roll rate vs ping slope.

        If you add_regression, you can get the slope that equates to the latency adjustment

        slope of regression = ping slope (deg) / roll rate (deg/s) = latency (s)

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        add_regression
            bool, if True, will include a regression line
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.scatter(self.rollrate_at_ping_time, self.hpf_slope)
        maxslope = self.hpf_slope.max()
        subplot.set_ylim(-maxslope * 4, maxslope * 4)
        subplot.set_title('Attitude Time Latency')
        subplot.set_xlabel('Roll Rate (deg/s)')
        subplot.set_ylabel('Ping Slope (deg)')
        if add_regression:
            slope = self._add_regression_line(subplot, self.rollrate_at_ping_time, self.hpf_slope)
            subplot.text(0, maxslope * 3.5, 'calculated latency = {} seconds'.format(slope))
Exemple #10
0
    def plot_allowable_percent_deviation(self, subplot: plt.subplot = None):
        """
        Plot the correlation plot between ping time and percent deviation in the ping slope linear regression.  Percent
        deviation here is related to the standard error of the y in the regression.  Include bounds for invalid data
        in the plot as a filled in red area.  According to source paper, greater than 5% should be rejected.

        Need to include segment identification in final version for exluding greater than 5%

        Parameters
        ----------
        subplot
            pyplot AxesSubplot instance to add to, if None will generate new instance
        """

        if subplot is None:
            subplot = plt.subplots(1)[1]
        subplot.plot(self.times, self.slope_percent_deviation)
        subplot.set_ylim(self.slope_percent_deviation.min(), np.max([6, self.slope_percent_deviation.max() * 1.5]))
        subplot.axhline(5, c='red', linestyle='--')
        subplot.fill_between(self.times, 5, np.max([6, self.slope_percent_deviation.max() * 1.5]), color='red', alpha=0.2)
        subplot.set_title('Allowable Percent Deviation (red = data unusable)')
        subplot.set_xlabel('Time (s)')
        subplot.set_ylabel('% deviation')