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 print("Press Ctrl-C to end session")
44
45 while not interrupt_handler.got_signal:
46 detector_result = detector.get_next()
47 try:
48 pg_process.put_data(detector_result)
49 except et.PGProccessDiedException:
50 break
51
52 detector.stop()
53
54 print("Disconnecting...")
55 client.close()
56
57
58class PGUpdater:
59 def __init__(self, num_curves):
60 self.num_curves = num_curves
61 self.distance_history = [np.nan] * 100
62
63 def setup(self, win):
64 self.sweep_plot = win.addPlot(row=0, col=0)
65 self.sweep_plot.setMenuEnabled(False)
66 self.sweep_plot.showGrid(x=True, y=True)
67 self.sweep_plot.addLegend()
68 self.sweep_plot.setLabel("left", "Amplitude")
69 self.sweep_plot.addItem(pg.PlotDataItem())
70
71 pen = et.utils.pg_pen_cycler(0)
72 brush = et.utils.pg_brush_cycler(0)
73 symbol_kw = dict(symbol="o", symbolSize=1, symbolBrush=brush, symbolPen="k")
74 feat_kw = dict(pen=pen, **symbol_kw)
75 self.sweep_curves = [self.sweep_plot.plot(**feat_kw) for _ in range(self.num_curves)]
76
77 pen = et.utils.pg_pen_cycler(1)
78 brush = et.utils.pg_brush_cycler(1)
79 symbol_kw = dict(symbol="o", symbolSize=1, symbolBrush=brush, symbolPen="k")
80 feat_kw = dict(pen=pen, **symbol_kw)
81 self.threshold_curves = [self.sweep_plot.plot(**feat_kw) for _ in range(self.num_curves)]
82
83 self.dist_history_plot = win.addPlot(row=1, col=0)
84 self.dist_history_plot.setMenuEnabled(False)
85 self.dist_history_plot.showGrid(x=True, y=True)
86 self.dist_history_plot.addLegend()
87 self.dist_history_plot.setLabel("left", "Estimated_distance")
88 self.dist_history_plot.addItem(pg.PlotDataItem())
89
90 pen = et.utils.pg_pen_cycler(0)
91 brush = et.utils.pg_brush_cycler(0)
92 symbol_kw = dict(symbol="o", symbolSize=5, symbolBrush=brush, symbolPen="k")
93 feat_kw = dict(pen=pen, **symbol_kw)
94 self.dist_history_curve = self.dist_history_plot.plot(**feat_kw)
95
96 self.distance_hist_smooth_lim = et.utils.SmoothLimits()
97
98 def update(self, multi_sensor_result):
99 # Get the first element as the example only supports single sensor operation.
100 result = multi_sensor_result[SENSOR_ID]
101 self.distance_history.pop(0)
102 if len(result.distances) != 0:
103 self.distance_history.append(result.distances[0])
104 else:
105 self.distance_history.append(np.nan)
106
107 for idx, processor_result in enumerate(result.processor_results):
108 threshold = processor_result.extra_result.used_threshold
109 valid_threshold_idx = np.where(~np.isnan(threshold))[0]
110 threshold = threshold[valid_threshold_idx]
111 self.sweep_curves[idx].setData(
112 processor_result.extra_result.distances_m, processor_result.extra_result.abs_sweep
113 )
114 self.threshold_curves[idx].setData(
115 processor_result.extra_result.distances_m[valid_threshold_idx], threshold
116 )
117 if np.any(~np.isnan(self.distance_history)):
118 self.dist_history_curve.setData(self.distance_history)
119 lims = self.distance_hist_smooth_lim.update(self.distance_history)
120 self.dist_history_plot.setYRange(lims[0], lims[1])
121 else:
122 self.dist_history_curve.setData([])
123
124
125if __name__ == "__main__":
126 main()
View this example on GitHub: acconeer/acconeer-python-exploration