def setup(self, win):
        self.plots = []
        self.curves = []
        for i in range(self.num_depths):
            title = "{:.0f} cm".format(100 * self.depths[i])
            plot = win.addPlot(row=0, col=i, title=title)
            plot.showGrid(x=True, y=True)
            plot.setYRange(-2**15, 2**15)
            plot.hideAxis("left")
            plot.hideAxis("bottom")
            plot.plot(np.arange(self.num_subsweeps),
                      np.zeros(self.num_subsweeps))
            curve = plot.plot(pen=example_utils.pg_pen_cycler())
            self.plots.append(plot)
            self.curves.append(curve)

        self.ft_plot = win.addPlot(row=1, col=0, colspan=self.num_depths)
        self.ft_im = pg.ImageItem(autoDownsample=True)
        self.ft_im.setLookupTable(example_utils.pg_mpl_cmap("viridis"))
        self.ft_plot.addItem(self.ft_im)
        self.ft_plot.setLabel("bottom", "Depth (cm)")
        self.ft_plot.getAxis("bottom").setTickSpacing(6 * self.stepsize, 6)

        self.smooth_max = example_utils.SmoothMax(
            self.smooth_max_f,
            tau_grow=0,
            tau_decay=0.5,
            hysteresis=0.1,
        )

        self.setup_is_done = True
        self.update_processing_config()
    def setup(self, win):
        win.setWindowTitle("Acconeer envelope mode example")
        self.envelope_plot_window = win.addPlot(row=0, col=0, title="Envelope",
                                                colspan=self.num_sensors)
        self.envelope_plot_window.showGrid(x=True, y=True)
        self.envelope_plot_window.addLegend(offset=(-10, 10))
        self.envelope_plot_window.setYRange(0, 1)
        self.envelope_plot_window.setLabel("left", "Amplitude")
        self.envelope_plot_window.setLabel("bottom", "Distance (mm)")

        self.peak_text = pg.TextItem(text="", color=(1, 1, 1), anchor=(0, 1), fill="#f0f0f0")
        self.peak_text.setZValue(3)
        self.envelope_plot_window.addItem(self.peak_text)

        self.envelope_plots = []
        self.peak_vlines = []
        self.clutter_plots = []
        self.hist_plot_images = []
        self.hist_plots = []
        self.hist_plot_peaks = []

        lut = example_utils.pg_mpl_cmap("viridis")
        hist_pen = example_utils.pg_pen_cycler(1)

        for s in range(self.num_sensors):
            legend_text = "Sensor {}".format(self.sensor_config.sensor[s])
            pen = example_utils.pg_pen_cycler(s+1)
            self.envelope_plots.append(
                self.envelope_plot_window.plot(range(10), np.zeros(10), pen=pen, name=legend_text)
                )
            self.peak_vlines.append(
                pg.InfiniteLine(pos=0, angle=90, pen=pg.mkPen(width=2, style=QtCore.Qt.DotLine))
                )
            self.envelope_plot_window.addItem(self.peak_vlines[s])

            hist_title = "Envelope history"
            if self.num_sensors == 1:
                pen = pg.mkPen(0.2, width=2, style=QtCore.Qt.DotLine)
                self.clutter_plots.append(
                    self.envelope_plot_window.plot(
                        range(10),
                        np.zeros(10),
                        pen=pen,
                        name="Background")
                    )
                self.clutter_plots[0].setZValue(2)
            else:
                hist_title = "History {}".format(legend_text)

            self.hist_plot_images.append(win.addPlot(row=2, col=s,
                                                     title=hist_title))
            self.hist_plot_images[s].setLabel("left", "Distance (mm)")
            self.hist_plot_images[s].setLabel("bottom", "Time (s)")
            self.hist_plots.append(pg.ImageItem())
            self.hist_plots[s].setAutoDownsample(True)
            self.hist_plots[s].setLookupTable(lut)
            self.hist_plot_images[s].addItem(self.hist_plots[s])

            self.hist_plot_peaks.append(
                self.hist_plot_images[s].plot(range(10), np.zeros(10), pen=hist_pen))
Example #3
0
    def setup(self, win):
        win.setWindowTitle("Acconeer sparse example")

        self.data_plot = win.addPlot(title="Sparse data")
        self.data_plot.showGrid(x=True, y=True)
        self.data_plot.setLabel("bottom", "Depth (m)")
        self.data_plot.setLabel("left", "Amplitude")
        self.data_plot.setYRange(-2**15, 2**15)
        self.scatter = pg.ScatterPlotItem(size=10)
        self.data_plot.addItem(self.scatter)

        win.nextRow()

        cmap_cols = ["steelblue", "lightblue", "#f0f0f0", "moccasin", "darkorange"]
        cmap = LinearSegmentedColormap.from_list("mycmap", cmap_cols)
        cmap._init()
        lut = (cmap._lut * 255).view(np.ndarray)

        self.data_history_plot = win.addPlot(title="Data history")
        self.data_history_im = pg.ImageItem(autoDownsample=True)
        self.data_history_im.setLookupTable(lut)
        self.data_history_plot.addItem(self.data_history_im)
        self.data_history_plot.setLabel("bottom", "Time (s)")
        self.data_history_plot.setLabel("left", "Depth (m)")

        win.nextRow()

        self.movement_history_plot = win.addPlot(title="Movement history")
        self.movement_history_im = pg.ImageItem(autoDownsample=True)
        self.movement_history_im.setLookupTable(example_utils.pg_mpl_cmap("viridis"))
        self.movement_history_plot.addItem(self.movement_history_im)
        self.movement_history_plot.setLabel("bottom", "Time (s)")
        self.movement_history_plot.setLabel("left", "Depth (m)")
    def setup(self, win):
        win.setWindowTitle("Acconeer sparse example")

        self.data_plots = []
        self.scatters = []
        self.data_history_ims = []
        self.presence_history_ims = []

        for i in range(len(self.sensor_config.sensor)):
            data_plot = win.addPlot(title="Sparse data", row=0, col=i)
            data_plot.showGrid(x=True, y=True)
            data_plot.setLabel("bottom", "Depth (m)")
            data_plot.setLabel("left", "Amplitude")
            data_plot.setYRange(-2**15, 2**15)
            scatter = pg.ScatterPlotItem(size=10)
            data_plot.addItem(scatter)

            cmap_cols = [
                "steelblue", "lightblue", "#f0f0f0", "moccasin", "darkorange"
            ]
            cmap = LinearSegmentedColormap.from_list("mycmap", cmap_cols)
            cmap._init()
            lut = (cmap._lut * 255).view(np.ndarray)

            data_history_plot = win.addPlot(title="Data history", row=1, col=i)
            data_history_im = pg.ImageItem(autoDownsample=True)
            data_history_im.setLookupTable(lut)
            data_history_plot.addItem(data_history_im)
            data_history_plot.setLabel("bottom", "Time (s)")
            data_history_plot.setLabel("left", "Depth (m)")

            presence_history_plot = win.addPlot(title="Movement history",
                                                row=2,
                                                col=i)
            presence_history_im = pg.ImageItem(autoDownsample=True)
            presence_history_im.setLookupTable(
                example_utils.pg_mpl_cmap("viridis"))
            presence_history_plot.addItem(presence_history_im)
            presence_history_plot.setLabel("bottom", "Time (s)")
            presence_history_plot.setLabel("left", "Depth (m)")

            self.data_plots.append(data_plot)
            self.scatters.append(scatter)
            self.data_history_ims.append(data_history_im)
            self.presence_history_ims.append(presence_history_im)

            for im in [presence_history_im, data_history_im]:
                im.resetTransform()
                im.translate(-self.history_len_s,
                             self.depths[0] - self.depth_res / 2)
                im.scale(self.time_res, self.depth_res)
    def setup(self, win):
        win.setWindowTitle("Acconeer obstacle detection example")

        self.env_ax = win.addPlot(row=0, col=0, title="Envelope and max FFT")
        self.env_ax.setLabel("bottom", "Depth (cm)")
        self.env_ax.setXRange(*(self.config.range_interval * 100))
        self.env_ax.showGrid(True, True)
        self.env_ax.addLegend()
        self.env_ax.setYRange(0, 0.1)

        self.env_ampl = self.env_ax.plot(pen=example_utils.pg_pen_cycler(0),
                                         name="Envelope")
        self.fft_max = self.env_ax.plot(pen=example_utils.pg_pen_cycler(
            1, "--"),
                                        name="FFT max")

        self.peak_dist_text = pg.TextItem(color="k", anchor=(0, 1))
        self.env_ax.addItem(self.peak_dist_text)
        self.peak_dist_text.setPos(self.config.range_start * 100, 0)
        self.peak_dist_text.setZValue(3)

        self.env_peak_vline = pg.InfiniteLine(pos=0,
                                              angle=90,
                                              pen=pg.mkPen(
                                                  width=2,
                                                  style=QtCore.Qt.DotLine))
        self.env_ax.addItem(self.env_peak_vline)

        self.obstacle_ax = win.addPlot(row=1, col=0, title="Obstacle map")
        self.obstacle_im = pg.ImageItem()
        self.obstacle_ax.setLabel("bottom", "Velocity (cm/s)")
        self.obstacle_ax.setLabel("left", "Distance (cm)")
        self.obstacle_im.setLookupTable(example_utils.pg_mpl_cmap("viridis"))
        self.obstacle_ax.addItem(self.obstacle_im)

        self.obstacle_ax.setXRange(-self.max_velocity, self.max_velocity)
        self.obstacle_ax.setYRange(*self.config.range_interval * 100)

        self.obstacle_peak = pg.ScatterPlotItem(brush=pg.mkBrush("k"), size=15)
        self.obstacle_ax.addItem(self.obstacle_peak)

        self.peak_fft_text = pg.TextItem(color="w", anchor=(0, 1))
        self.obstacle_ax.addItem(self.peak_fft_text)
        self.peak_fft_text.setPos(-self.max_velocity,
                                  self.config.range_start * 100)

        self.smooth_max = example_utils.SmoothMax(self.config.sweep_rate,
                                                  tau_decay=1,
                                                  tau_grow=0.2)
Example #6
0
    def update(self, data):
        feat_map = None
        if data["ml_frame_data"] is not None:
            frame_data = data["ml_frame_data"]
            feat_map = frame_data["current_frame"]["feature_map"]
            frame_size = frame_data["frame_info"]["frame_size"]
            frame_pad = frame_data["frame_info"]["frame_pad"]
            frame_complete = frame_data["current_frame"]["frame_complete"]
            model_dimension = data["ml_frame_data"]["model_dimension"]
        else:
            return

        sensors = []
        if self.sensor_config is not None:
            sensors = self.sensor_config.sensor

        mode = data["sensor_config"].mode

        if self.first:
            self.first = False
            self.env_plot_max_y = 0
            s_buff = frame_size + 2 * frame_pad
            self.feat_plot.resetTransform()
            if model_dimension > 1:
                self.feat_plot.translate(-frame_pad, 0)
            self.feat_plot_image.setXRange(-frame_pad, s_buff - frame_pad)

            self.border_left.setValue(0)
            self.border_right.setValue(frame_size)

            self.border_left.show()
            self.border_right.show()

            nr_sensors = len(sensors)
            self.hist_plot_max_y = np.zeros(nr_sensors)

            lut = example_utils.pg_mpl_cmap("viridis")
            if mode == "sparse":
                cmap_cols = [
                    "steelblue", "lightblue", "#f0f0f0", "moccasin",
                    "darkorange"
                ]
                cmap = LinearSegmentedColormap.from_list("mycmap", cmap_cols)
                cmap._init()
                lut = (cmap._lut * 255).view(np.ndarray)

            for i in range(4):
                if (i + 1) in sensors:
                    self.hist_plot_images[i].show()
                    self.set_axis(data, self.hist_plot_images[i])
                    self.hist_plots[i].setLookupTable(lut)
                else:
                    self.hist_plot_images[i].hide()

        for idx, sensor in enumerate(sensors):

            if mode == "sparse":
                data_history_adj = data["hist_env"][idx, :, :].T
                sign = np.sign(data_history_adj)
                data_history_adj = np.abs(data_history_adj)
                data_history_adj /= data_history_adj.max()
                data_history_adj = np.power(data_history_adj,
                                            1 / 2.2)  # gamma correction
                data_history_adj *= sign
                self.hist_plots[sensor - 1].updateImage(data_history_adj,
                                                        levels=(-1.05, 1.05))
            else:
                max_val = np.max(data["env_ampl"][idx])

                ymax_level = min(
                    1.5 * np.max(np.max(data["hist_env"][idx, :, :])),
                    self.hist_plot_max_y[idx])

                if max_val > self.hist_plot_max_y[idx]:
                    self.hist_plot_max_y[idx] = 1.2 * max_val

                self.hist_plots[sensor - 1].updateImage(
                    data["hist_env"][idx, :, :].T, levels=(0, ymax_level))

        if self.show_predictions and data.get("prediction") is not None:
            self.predictions_plot_window.show()
            predictions = data["prediction"]["label_predictions"]
            pred_num = data["prediction"]["number_labels"]
            pred_history = data["prediction_hist"]
            if len(self.prediction_plots) < pred_num:
                self.generate_predciction_plots(predictions, pred_num)

            if pred_history is not None:
                for idx in range(pred_num):
                    self.prediction_plots[idx].setData(pred_history[idx, :])

        detected = True
        if feat_map is None:
            detected = False

        if detected and not len(feat_map):
            detected = False

        if not detected:
            motion_score = frame_data.pop("motion_score", None)
            text = "Waiting..."
            if motion_score is not None:
                text = "Waiting.. (Motion score: {:.1f})".format(motion_score)
            self.detected_text.setText(text)
            return
        else:
            self.detected_text.setText("Collecting..")

        if not frame_complete:
            self.border_rolling.show()
            self.border_rolling.setValue(
                frame_data["current_frame"]["sweep_counter"] - frame_pad)
        else:
            self.border_rolling.hide()

        feauture_nr = frame_data["current_frame"]["frame_nr"]
        self.feature_nr_text.setText("Feature: {}".format(feauture_nr))

        self.feat_plot_image.setYRange(0, feat_map.shape[0])

        map_max = 1.2 * np.max(feat_map)
        ymax_level = max(map_max, self.env_plot_max_y)

        g = 1 / 2.2
        feat_map = 254 / (ymax_level + 1.0e-9)**g * feat_map**g

        feat_map[feat_map > 254] = 254

        self.feat_plot.updateImage(feat_map.T, levels=(0, 256))

        if map_max > self.env_plot_max_y:
            self.env_plot_max_y = map_max
Example #7
0
    def setup(self, win):
        win.setWindowTitle("Feature plotting")
        self.feat_plot_image = win.addPlot(row=0, col=0)
        self.feat_plot = pg.ImageItem()
        self.feat_plot.setAutoDownsample(True)
        self.feat_plot_image.addItem(self.feat_plot)
        self.feat_plot_image.setLabel("left", "Features")
        self.feat_plot_image.setLabel("bottom", "Sweeps")

        lut = example_utils.pg_mpl_cmap("viridis")
        self.feat_plot.setLookupTable(lut)

        self.feat_plot_image.setXRange(0, 40)
        self.feat_plot_image.setYRange(0, 1)

        self.border_right = pg.InfiniteLine(pos=0,
                                            angle=90,
                                            pen=pg.mkPen(
                                                width=2,
                                                style=QtCore.Qt.DotLine))
        self.border_left = pg.InfiniteLine(pos=0,
                                           angle=90,
                                           pen=pg.mkPen(
                                               width=2,
                                               style=QtCore.Qt.DotLine))
        self.border_rolling = pg.InfiniteLine(pos=0,
                                              angle=90,
                                              pen=pg.mkPen(width=2))

        self.detected_text = pg.TextItem(color="r", anchor=(0, 1))
        self.feature_nr_text = pg.TextItem(color="r", anchor=(0, 2))

        self.feat_plot_image.addItem(self.detected_text)
        self.feat_plot_image.addItem(self.feature_nr_text)
        self.feat_plot_image.addItem(self.border_left)
        self.feat_plot_image.addItem(self.border_right)
        self.feat_plot_image.addItem(self.border_rolling)

        self.border_left.hide()
        self.border_right.hide()
        self.border_rolling.hide()

        self.history_plot_window = win.addLayout(row=1, col=0)

        self.envelope_plots = []
        self.peak_vlines = []
        self.clutter_plots = []
        self.hist_plot_images = []
        self.hist_plots = []
        self.hist_plot_peaks = []

        lut = example_utils.pg_mpl_cmap("viridis")

        for s in range(4):
            legend_text = "Sensor {}".format(s + 1)
            hist_title = "History {}".format(legend_text)
            self.hist_plot_images.append(
                self.history_plot_window.addPlot(row=0,
                                                 col=s,
                                                 title=hist_title))
            self.hist_plot_images[s].setLabel("left", "Distance (mm)")
            self.hist_plot_images[s].setLabel("bottom", "Time (s)")
            self.hist_plots.append(pg.ImageItem())
            self.hist_plots[s].setAutoDownsample(True)
            self.hist_plots[s].setLookupTable(lut)
            self.hist_plot_images[s].addItem(self.hist_plots[s])

        if self.show_predictions:
            self.predictions_plot_window = win.addPlot(
                row=2, col=0, title="Prediction results")
            self.predictions_plot_window.showGrid(x=True, y=True)
            self.predictions_plot_window.addLegend(offset=(-10, 10))
            self.predictions_plot_window.setYRange(0, 1)
            self.predictions_plot_window.setLabel("left", "Probability")
            self.predictions_plot_window.setLabel("bottom", "Iteration")

            self.prediction_plots = []
def main():
    args = example_utils.ExampleArgumentParser(num_sens=1).parse_args()
    example_utils.config_logging(args)

    if args.socket_addr:
        client = JSONClient(args.socket_addr)
    else:
        port = args.serial_port or example_utils.autodetect_serial_port()
        client = RegClient(port)

    config = configs.EnvelopeServiceConfig()
    config.sensor = args.sensors
    config.range_interval = [0.2, 0.6]
    config.sweep_rate = 60
    config.gain = 0.65

    info = client.setup_session(config)
    num_points = info["data_length"]
    xs = np.linspace(*config.range_interval, num_points)
    num_hist = 2 * config.sweep_rate

    hist_data = np.zeros([num_hist, num_points])
    hist_max = np.zeros(num_hist)
    smooth_max = example_utils.SmoothMax(config.sweep_rate)

    app = QtGui.QApplication([])
    pg.setConfigOption("background", "w")
    pg.setConfigOption("foreground", "k")
    pg.setConfigOptions(antialias=True)
    win = pg.GraphicsLayoutWidget()
    win.closeEvent = lambda _: interrupt_handler.force_signal_interrupt()
    win.setWindowTitle("Acconeer PyQtGraph example")

    env_plot = win.addPlot(title="Envelope")
    env_plot.showGrid(x=True, y=True)
    env_plot.setLabel("bottom", "Depth (m)")
    env_plot.setLabel("left", "Amplitude")
    env_curve = env_plot.plot(pen=pg.mkPen("k", width=2))

    win.nextRow()
    hist_plot = win.addPlot()
    hist_plot.setLabel("bottom", "Time (s)")
    hist_plot.setLabel("left", "Depth (m)")
    hist_image_item = pg.ImageItem()
    hist_image_item.translate(-2, config.range_start)
    hist_image_item.scale(2 / num_hist, config.range_length / num_points)
    hist_plot.addItem(hist_image_item)

    # try to get a colormap from matplotlib
    try:
        hist_image_item.setLookupTable(example_utils.pg_mpl_cmap("viridis"))
    except ImportError:
        pass

    win.show()

    interrupt_handler = example_utils.ExampleInterruptHandler()
    print("Press Ctrl-C to end session")

    client.start_streaming()

    while not interrupt_handler.got_signal:
        info, sweep = client.get_next()

        hist_data = np.roll(hist_data, -1, axis=0)
        hist_data[-1] = sweep
        hist_max = np.roll(hist_max, -1)
        hist_max[-1] = np.max(sweep)
        y_max = smooth_max.update(np.amax(hist_max))
        env_curve.setData(xs, sweep)
        env_plot.setYRange(0, y_max)
        hist_image_item.updateImage(hist_data, levels=(0, y_max))

        app.processEvents()

    print("Disconnecting...")
    app.closeAllWindows()
    client.disconnect()
Example #9
0
    def setup(self, win):
        win.setWindowTitle("Acconeer obstacle detection example")

        row_idx = 0
        self.env_ax = win.addPlot(row=row_idx,
                                  col=0,
                                  colspan=4,
                                  title="Envelope and max FFT")
        self.env_ax.setLabel("bottom", "Depth (cm)")
        self.env_ax.setXRange(*(self.sensor_config.range_interval * 100))
        self.env_ax.showGrid(True, True)
        self.env_ax.addLegend()
        self.env_ax.setYRange(0, 0.1)

        self.env_ampl = self.env_ax.plot(pen=example_utils.pg_pen_cycler(0),
                                         name="Envelope")
        self.fft_max = self.env_ax.plot(pen=example_utils.pg_pen_cycler(
            1, "--"),
                                        name="FFT max")

        self.peak_dist_text = pg.TextItem(color="k", anchor=(0, 1))
        self.env_ax.addItem(self.peak_dist_text)
        self.peak_dist_text.setPos(self.sensor_config.range_start * 100, 0)
        self.peak_dist_text.setZValue(3)

        self.env_peak_vline = pg.InfiniteLine(pos=0,
                                              angle=90,
                                              pen=pg.mkPen(
                                                  width=2,
                                                  style=QtCore.Qt.DotLine))
        self.env_ax.addItem(self.env_peak_vline)
        row_idx += 1

        self.obstacle_ax = win.addPlot(row=row_idx,
                                       col=0,
                                       colspan=self.num_hist_plots,
                                       title="Obstacle map")
        self.obstacle_im = pg.ImageItem()
        self.obstacle_ax.setLabel("bottom", "Velocity (cm/s)")
        self.obstacle_ax.setLabel("left", "Distance (cm)")
        self.obstacle_im.setLookupTable(example_utils.pg_mpl_cmap("viridis"))
        self.obstacle_ax.addItem(self.obstacle_im)

        self.obstacle_ax.setXRange(-self.max_velocity, self.max_velocity)
        self.obstacle_ax.setYRange(*self.sensor_config.range_interval * 100)

        self.obstacle_ax.setXRange(-self.max_velocity, self.max_velocity)
        self.obstacle_ax.setYRange(*self.sensor_config.range_interval * 100)

        self.obstacle_peak = pg.ScatterPlotItem(brush=pg.mkBrush("k"), size=15)
        self.obstacle_ax.addItem(self.obstacle_peak)

        self.peak_fft_text = pg.TextItem(color="w", anchor=(0, 1))
        self.obstacle_ax.addItem(self.peak_fft_text)
        self.peak_fft_text.setPos(-self.max_velocity,
                                  self.sensor_config.range_start * 100)

        self.peak_val_text = pg.TextItem(color="w", anchor=(0, 0))
        self.obstacle_ax.addItem(self.peak_val_text)
        self.peak_val_text.setPos(-self.max_velocity,
                                  self.sensor_config.range_end * 100)

        row_idx += 1
        if self.advanced_plots["background_map"]:
            self.obstacle_bg_ax = win.addPlot(row=row_idx,
                                              col=0,
                                              colspan=self.num_hist_plots,
                                              title="Obstacle background")
            self.obstacle_bg_im = pg.ImageItem()
            self.obstacle_bg_ax.setLabel("bottom", "Velocity (cm/s)")
            self.obstacle_bg_ax.setLabel("left", "Distance (cm)")
            self.obstacle_bg_im.setLookupTable(
                example_utils.pg_mpl_cmap("viridis"))
            self.obstacle_bg_ax.addItem(self.obstacle_bg_im)
            row_idx += 1

        if self.advanced_plots["threshold_map"]:
            self.obstacle_thresh_ax = win.addPlot(row=row_idx,
                                                  col=0,
                                                  colspan=self.num_hist_plots,
                                                  title="Obstacle threshold")
            self.obstacle_thresh_im = pg.ImageItem()
            self.obstacle_thresh_ax.setLabel("bottom", "Velocity (cm/s)")
            self.obstacle_thresh_ax.setLabel("left", "Distance (cm)")
            self.obstacle_thresh_im.setLookupTable(
                example_utils.pg_mpl_cmap("viridis"))
            self.obstacle_thresh_ax.addItem(self.obstacle_thresh_im)
            row_idx += 1

        hist_col = 0
        row_idx += self.num_hist_plots
        if self.hist_plots["distance"][1]:
            self.peak_hist_ax_l = win.addPlot(row=row_idx,
                                              col=hist_col,
                                              title="Distance history")
            self.peak_hist_ax_l.setLabel("bottom", "Sweep")
            self.peak_hist_ax_l.setXRange(0, self.peak_hist_len)
            self.peak_hist_ax_l.showGrid(True, True)
            self.peak_hist_ax_l.addLegend(offset=(-10, 10))
            self.peak_hist_ax_l.setYRange(self.sensor_config.range_start * 100,
                                          self.sensor_config.range_end * 100)
            hist_col += 1

        if self.hist_plots["velocity"][1]:
            self.peak_hist_ax_c = win.addPlot(row=row_idx,
                                              col=hist_col,
                                              title="Velocity history")
            self.peak_hist_ax_c.setLabel("bottom", "Sweep")
            self.peak_hist_ax_c.setXRange(0, self.peak_hist_len)
            limit = np.round(self.max_velocity / 10) * 10
            if limit < 1.0:
                limit = self.max_velocity
            self.peak_hist_ax_c.setYRange(-limit, limit)
            self.peak_hist_ax_c.showGrid(True, True)
            self.peak_hist_ax_c.addLegend(offset=(-10, 10))
            hist_col += 1

        if self.hist_plots["angle"][1]:
            self.peak_hist_ax_r = win.addPlot(row=row_idx,
                                              col=hist_col,
                                              title="Angle history")
            self.peak_hist_ax_r.setLabel("bottom", "Sweep")
            self.peak_hist_ax_r.setXRange(0, self.peak_hist_len)
            self.peak_hist_ax_r.showGrid(True, True)
            self.peak_hist_ax_r.addLegend(offset=(-10, 10))
            self.peak_hist_ax_r.setYRange(-100, 100)
            hist_col += 1

        if self.hist_plots["amplitude"][1]:
            self.peak_hist_ax_r1 = win.addPlot(row=row_idx,
                                               col=hist_col,
                                               title="Amplitude history")
            self.peak_hist_ax_r1.setLabel("bottom", "Sweep")
            self.peak_hist_ax_r1.setXRange(0, self.peak_hist_len)
            self.peak_hist_ax_r1.showGrid(True, True)
            self.peak_hist_ax_r1.addLegend(offset=(-10, 10))
            hist_col += 1

        for i in range(self.nr_locals):
            if self.hist_plots["velocity"][1]:
                self.hist_plots["velocity"][0].append(
                    self.peak_hist_ax_c.plot(
                        pen=example_utils.pg_pen_cycler(i),
                        name="Veloctiy {:d}".format(i)))
            if self.hist_plots["angle"][1]:
                self.hist_plots["angle"][0].append(
                    self.peak_hist_ax_r.plot(
                        pen=example_utils.pg_pen_cycler(i),
                        name="Angle {:d}".format(i)))
            if self.hist_plots["distance"][1]:
                self.hist_plots["distance"][0].append(
                    self.peak_hist_ax_l.plot(
                        pen=example_utils.pg_pen_cycler(i),
                        name="Distance {:d}".format(i)))
            if self.hist_plots["amplitude"][1]:
                self.hist_plots["amplitude"][0].append(
                    self.peak_hist_ax_r1.plot(
                        pen=example_utils.pg_pen_cycler(i),
                        name="Amplitude {:d}".format(i)))

        self.smooth_max = example_utils.SmoothMax(
            self.sensor_config.sweep_rate, tau_decay=1, tau_grow=0.2)