examples/a121/algo/distance/detector.py#
1# Copyright (c) Acconeer AB, 2022-2026
2# All rights reserved
3
4from __future__ import annotations
5
6import numpy as np
7
8# Added here to force pyqtgraph to choose PySide
9import PySide6 # noqa: F401
10
11import pyqtgraph as pg
12
13import acconeer.exptool as et
14from acconeer.exptool import a121
15from acconeer.exptool.a121.algo.distance import Detector, DetectorConfig
16
17
18SENSOR_ID = 1
19
20
21def main():
22 args = a121.ExampleArgumentParser().parse_args()
23 et.utils.config_logging(args)
24
25 client = a121.Client.open(**a121.get_client_args(args))
26 detector_config = DetectorConfig(
27 start_m=0.0,
28 end_m=2.0,
29 max_profile=a121.Profile.PROFILE_3,
30 max_step_length=12,
31 )
32 detector = Detector(client=client, sensor_ids=[SENSOR_ID], detector_config=detector_config)
33
34 detector.calibrate_detector()
35
36 detector.start()
37
38 pg_updater = PGUpdater(num_curves=len(detector.processor_specs))
39 pg_process = et.PGProcess(pg_updater)
40 pg_process.start()
41
42 interrupt_handler = et.utils.ExampleInterruptHandler()
43
44 while not interrupt_handler.got_signal:
45 detector_result = detector.get_next()
46 try:
47 pg_process.put_data(detector_result)
48 except et.PGProccessDiedException:
49 break
50
51 detector.stop()
52
53 print("Disconnecting...")
54 client.close()
55
56
57class PGUpdater:
58 def __init__(self, num_curves):
59 self.num_curves = num_curves
60 self.distance_history = [np.nan] * 100
61
62 def setup(self, win):
63 self.sweep_plot = win.addPlot(row=0, col=0)
64 self.sweep_plot.setMenuEnabled(False)
65 self.sweep_plot.showGrid(x=True, y=True)
66 self.sweep_plot.addLegend()
67 self.sweep_plot.setLabel("left", "Amplitude")
68 self.sweep_plot.addItem(pg.PlotDataItem())
69
70 pen = et.utils.pg_pen_cycler(0)
71 brush = et.utils.pg_brush_cycler(0)
72 symbol_kw = dict(symbol="o", symbolSize=1, symbolBrush=brush, symbolPen="k")
73 feat_kw = dict(pen=pen, **symbol_kw)
74 self.sweep_curves = [self.sweep_plot.plot(**feat_kw) for _ in range(self.num_curves)]
75
76 pen = et.utils.pg_pen_cycler(1)
77 brush = et.utils.pg_brush_cycler(1)
78 symbol_kw = dict(symbol="o", symbolSize=1, symbolBrush=brush, symbolPen="k")
79 feat_kw = dict(pen=pen, **symbol_kw)
80 self.threshold_curves = [self.sweep_plot.plot(**feat_kw) for _ in range(self.num_curves)]
81
82 self.dist_history_plot = win.addPlot(row=1, col=0)
83 self.dist_history_plot.setMenuEnabled(False)
84 self.dist_history_plot.showGrid(x=True, y=True)
85 self.dist_history_plot.addLegend()
86 self.dist_history_plot.setLabel("left", "Estimated_distance")
87 self.dist_history_plot.addItem(pg.PlotDataItem())
88
89 pen = et.utils.pg_pen_cycler(0)
90 brush = et.utils.pg_brush_cycler(0)
91 symbol_kw = dict(symbol="o", symbolSize=5, symbolBrush=brush, symbolPen="k")
92 feat_kw = dict(pen=pen, **symbol_kw)
93 self.dist_history_curve = self.dist_history_plot.plot(**feat_kw)
94
95 self.distance_hist_smooth_lim = et.utils.SmoothLimits()
96
97 def update(self, multi_sensor_result):
98 # Get the first element as the example only supports single sensor operation.
99 result = multi_sensor_result[SENSOR_ID]
100 self.distance_history.pop(0)
101 if len(result.distances) != 0:
102 self.distance_history.append(result.distances[0])
103 else:
104 self.distance_history.append(np.nan)
105
106 for idx, processor_result in enumerate(result.processor_results):
107 threshold = processor_result.extra_result.used_threshold
108 valid_threshold_idx = np.where(~np.isnan(threshold))[0]
109 threshold = threshold[valid_threshold_idx]
110 self.sweep_curves[idx].setData(
111 processor_result.extra_result.distances_m, processor_result.extra_result.abs_sweep
112 )
113 self.threshold_curves[idx].setData(
114 processor_result.extra_result.distances_m[valid_threshold_idx], threshold
115 )
116 if np.any(~np.isnan(self.distance_history)):
117 self.dist_history_curve.setData(self.distance_history)
118 lims = self.distance_hist_smooth_lim.update(self.distance_history)
119 self.dist_history_plot.setYRange(lims[0], lims[1])
120 else:
121 self.dist_history_curve.setData([])
122
123
124if __name__ == "__main__":
125 main()
View this example on GitHub: acconeer/acconeer-python-exploration