rfbeam 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19f39170dee64099fe6806a345393beff434035df70fe525fa31b361468cac9e
4
- data.tar.gz: 622aba1c5ab9f85fdb8cadf90f10339344306db39ab9299b2ef8b437d228d82d
3
+ metadata.gz: f97b41caa1ea2bb28202406b3c2ae9ab2cec96977f7238e3638407f7aa2e2fad
4
+ data.tar.gz: 12ecf75b483f934c2436a799405598ffd611d858acd15d099d00bcd73a4de30e
5
5
  SHA512:
6
- metadata.gz: 57bd136ef560a32dab06e08c841b44e6e1b192525d9d3d44db1a88885c0b30b9b9b28ab28b1f408d628e191195373a012d31405ae24372fa4efd76ecbb3af46c
7
- data.tar.gz: 5dc08c9c71c511e210a4c30599248bb5be53f1ccd7373af73edeb1ff35043dc76b90235bf46de93b9b755123af598225d6b96f06f6c0c5ab89bf4d1bc2e81d57
6
+ metadata.gz: e4a69f4f0501b19f05eb57887129089ac549a327f6fcb7ded1ffad3186f36260cb71ec766ef69916532447fd0138db5843111f4fad1b5b6c57c1d5c08466fb17
7
+ data.tar.gz: a7e7dc0c45b862dd2d37f28424e712236f4220bdef87ed4faccdb65b96f0e9cdf4984e3ff7c792940bb91b5896c32ac4f9cb678db45ba25a5f138bf6d475ecb1
data/.rubocop.yml CHANGED
@@ -1,11 +1,9 @@
1
- inherit_from:
2
- - node_modules/@prettier/plugin-ruby/rubocop.yml
3
-
4
1
  AllCops:
5
- TargetRubyVersion: 3.2
2
+ TargetRubyVersion: 3.1
6
3
 
7
4
  Layout/LineLength:
8
5
  Max: 120
6
+ AutoCorrect: true
9
7
 
10
8
  Metrics/ModuleLength:
11
9
  Enabled: false
@@ -13,5 +11,8 @@ Metrics/ModuleLength:
13
11
  Metrics/MethodLength:
14
12
  Max: 20
15
13
 
14
+ Metrics/ClassLength:
15
+ Enabled: false
16
+
16
17
  Documentation:
17
18
  Enabled: false
data/.streerc ADDED
@@ -0,0 +1,2 @@
1
+ --print-width=120
2
+ --plugins=plugin/single_quotes
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.2.1
1
+ ruby 3.1.2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.4.2] - 2023-4-4
2
+
3
+ - Changed Data.define to Struct to support ruby 3.1.2
4
+
1
5
  ## [0.4.0] - 2023-4-4
2
6
 
3
7
  - rough CLI implementation
data/Gemfile CHANGED
@@ -20,3 +20,7 @@ gem "unicode_plot", "~> 0.0.5"
20
20
  gem "tty-logger", "~> 0.6.0"
21
21
 
22
22
  gem "tty-screen", "~> 0.8.1"
23
+
24
+ gem "tty-option", "~> 0.2.0"
25
+
26
+ gem "tty-command", "~> 0.10.1"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rfbeam (0.4.0)
4
+ rfbeam (0.4.2)
5
5
  activesupport (~> 6.1.0)
6
6
  rubyserial (~> 0.6.0)
7
7
  thor (~> 1.2.1)
@@ -54,9 +54,12 @@ GEM
54
54
  strings-ansi (0.2.0)
55
55
  thor (1.2.1)
56
56
  tty-color (0.6.0)
57
+ tty-command (0.10.1)
58
+ pastel (~> 0.8)
57
59
  tty-cursor (0.7.1)
58
60
  tty-logger (0.6.0)
59
61
  pastel (~> 0.8)
62
+ tty-option (0.2.0)
60
63
  tty-screen (0.8.1)
61
64
  tty-spinner (0.9.3)
62
65
  tty-cursor (~> 0.7)
@@ -81,7 +84,9 @@ DEPENDENCIES
81
84
  rake (~> 13.0)
82
85
  rfbeam!
83
86
  rubocop (~> 1.21)
87
+ tty-command (~> 0.10.1)
84
88
  tty-logger (~> 0.6.0)
89
+ tty-option (~> 0.2.0)
85
90
  tty-screen (~> 0.8.1)
86
91
  tty-spinner (~> 0.9.3)
87
92
  tty-table (~> 0.12.0)
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Rfbeam
2
2
 
3
3
  ![Gem](https://img.shields.io/gem/v/rfbeam?color=green&label=version)
4
- ![Ruby](https://img.shields.io/static/v1?message=Ruby&color=red&logo=Ruby&logoColor=FFFFFF&label=v3.2.1)
4
+ ![Ruby](https://img.shields.io/static/v1?message=Ruby&color=red&logo=Ruby&logoColor=FFFFFF&label=v3.1.2)
5
5
  ![Ruby](https://img.shields.io/gitlab/license/robcarruthers/rfbeam?color=orange)
6
6
 
7
7
  RfBeam is a simple, high-level interface for the RFBeam radar modules.
@@ -67,12 +67,12 @@ Returns a formatted String of all parameter settings. The only way to read param
67
67
 
68
68
  radar.config
69
69
 
70
- Software Version: K-LD7_APP-RFB-0103
71
- Base Frequency: Low
72
- Maximum Speed: 100km/h
73
- Maximum Range: 100m
74
- Threshold Offset: 30db
75
- Tracking Filter Type: Long Visibility
70
+ Software Version: K-LD7_APP-RFB-0103
71
+ Base Frequency: Low
72
+ Maximum Speed: 100km/h
73
+ Maximum Range: 100m
74
+ Threshold Offset: 30db
75
+ Tracking Filter Type: Long Visibility
76
76
  Vibration Suppression: 16
77
77
  Minimum Detection Distance: 0%
78
78
  Maximum Detection Distance: 100%
@@ -91,7 +91,7 @@ Returns a formatted String of all parameter settings. The only way to read param
91
91
  Micro Detection Trigger: Off
92
92
  Micro Detection Sensativity: 4
93
93
 
94
- ## Parameter setters
94
+ ## Parameter API
95
95
 
96
96
  ### Base Frequency
97
97
 
@@ -100,7 +100,7 @@ Returns a formatted String of all parameter settings. The only way to read param
100
100
  alias :rbfr
101
101
 
102
102
  ```ruby
103
- set_base_frequency(1)
103
+ radar.radar.base_frequency = 1
104
104
  ```
105
105
 
106
106
  ### Maximum Speed
@@ -108,7 +108,7 @@ set_base_frequency(1)
108
108
  0 = 12.5km/h, 1 = 25km/h (default), 2 = 50km/h, 3 = 100km/h, alias :rspi
109
109
 
110
110
  ```ruby
111
- set_max_speed(1)
111
+ radar.max_speed = 1
112
112
  ```
113
113
 
114
114
  ### Maximum Range
@@ -116,7 +116,7 @@ set_max_speed(1)
116
116
  0 = 5m, 1 = 10m (default), 2 = 30m, 3 = 100m, alias :rrai
117
117
 
118
118
  ```ruby
119
- set_max_range(1)
119
+ radar.max_range = 1
120
120
  ```
121
121
 
122
122
  ### Threshold Offset
@@ -124,7 +124,7 @@ set_max_range(1)
124
124
  10 - 60db, (default = 30), alias :thof
125
125
 
126
126
  ```ruby
127
- set_threshold_offset(30)
127
+ radar.threshold_offset = 30
128
128
  ```
129
129
 
130
130
  ### Tracking filter type
@@ -132,7 +132,7 @@ set_threshold_offset(30)
132
132
  0 = Standard (Default), 1 = Fast Tracking, 2 = Long visibility, alias :trtf
133
133
 
134
134
  ```ruby
135
- set_tracking_filter(0)
135
+ radar.tracking_filter = 0
136
136
  ```
137
137
 
138
138
  ### Vibration suppression
@@ -140,7 +140,7 @@ set_tracking_filter(0)
140
140
  0 - 16, 0 = No Suppression, 16 = High Suppression, default = 2, alias :visu
141
141
 
142
142
  ```ruby
143
- set_vibration_suppression(2)
143
+ radar.vibration_suppression = 2
144
144
  ```
145
145
 
146
146
  ### Minimum Detection distance
@@ -148,7 +148,7 @@ set_vibration_suppression(2)
148
148
  0 - 100% of Range setting, default = 0, alias :mira
149
149
 
150
150
  ```ruby
151
- set_min_detection_distance(0)
151
+ radar.min_detection_distance = 0
152
152
  ```
153
153
 
154
154
  ### Maximum Detection distance
@@ -156,7 +156,7 @@ set_min_detection_distance(0)
156
156
  0 - 100% of Range setting, default = 50, alias :mara
157
157
 
158
158
  ```ruby
159
- set_max_detection_distance(50)
159
+ radar.max_detection_distance = 50
160
160
  ```
161
161
 
162
162
  ### Minimum Detection Angle
@@ -164,7 +164,7 @@ set_max_detection_distance(50)
164
164
  -90° - 90°, default = -90, alias :mian
165
165
 
166
166
  ```ruby
167
- set_min_detection_angle(-90
167
+ radar.min_detection_angle = -90
168
168
  ```
169
169
 
170
170
  ### Maximum Detection Angle
@@ -172,7 +172,7 @@ set_min_detection_angle(-90
172
172
  -90° - 90°, default = 90, alias :maan
173
173
 
174
174
  ```ruby
175
- set_min_detection_angle(90)
175
+ radar.min_detection_angle = 90
176
176
  ```
177
177
 
178
178
  ### Minimum Detection Speed
@@ -180,7 +180,7 @@ set_min_detection_angle(90)
180
180
  0 - 100% of Speed setting, default = 0, alias :misp
181
181
 
182
182
  ```ruby
183
- set_min_detection_speed(0)
183
+ radar.min_detection_speed = 0
184
184
  ```
185
185
 
186
186
  ### Maximum Detection Speed
@@ -188,7 +188,7 @@ set_min_detection_speed(0)
188
188
  0 - 100% of Speed setting, default = 100, alias :masp
189
189
 
190
190
  ```ruby
191
- set_max_detection_speed(100)
191
+ radar.max_detection_speed = 100
192
192
  ```
193
193
 
194
194
  ### Detection Direction
@@ -196,7 +196,7 @@ set_max_detection_speed(100)
196
196
  0 = Receding, 1 = Approaching, 2 = Both (default), alias :dedi
197
197
 
198
198
  ```ruby
199
- set_detection_direction(2)
199
+ radar. detection_direction = 2
200
200
  ```
201
201
 
202
202
  ### Range Threshold
@@ -204,7 +204,7 @@ set_max_detection_speed(100)
204
204
  0 - 100% of Range setting, default = 10, alias :rath
205
205
 
206
206
  ```ruby
207
- set_range_threshold(10)
207
+ radar. range_threshold = 10
208
208
  ```
209
209
 
210
210
  ### Angle Threshold
@@ -212,7 +212,7 @@ set_max_detection_speed(100)
212
212
  -90° to 90°, default = 0, alias :anth
213
213
 
214
214
  ```ruby
215
- set_range_threshold(0)
215
+ radar. range_threshold = 0
216
216
  ```
217
217
 
218
218
  ### Speed Threshold
@@ -220,37 +220,37 @@ set_max_detection_speed(100)
220
220
  0 - 100% of speed setting, default = 50, alias :spth
221
221
 
222
222
  ```ruby
223
- set_angle_threshold(50)
223
+ radar. angle_threshold = 50
224
224
  ```
225
225
 
226
226
  ### Digital output 1
227
227
 
228
228
  0 = Direction, 1 = Angle, 2 = Range, 3 = Speed, 4 = Micro Detection, default = 0
229
229
 
230
- alias :dig1, :set_dio_1
230
+ alias :dig1
231
231
 
232
232
  ```ruby
233
- set_dio_1(0)
233
+ radar.digital_output1 = 0
234
234
  ```
235
235
 
236
236
  ### Digital output 2
237
237
 
238
238
  0 = Direction, 1 = Angle, 2 = Range, 3 = Speed, 4 = Micro Detection, default = 1
239
239
 
240
- alias :dig2, :set_dio_2
240
+ alias :dig2
241
241
 
242
242
  ```ruby
243
- set_dio_2(1)
243
+ radar.digital_output2 = 1
244
244
  ```
245
245
 
246
246
  ### Digital output 3
247
247
 
248
248
  0 = Direction, 1 = Angle, 2 = Range, 3 = Speed, 4 = Micro Detection, default = 2
249
249
 
250
- alias :dig3, :set_dio_3
250
+ alias :dig3
251
251
 
252
252
  ```ruby
253
- set_dio_3(2)
253
+ radar.digital_output3 = 2
254
254
  ```
255
255
 
256
256
  ### Hold Time
@@ -260,7 +260,7 @@ set_dio_3(2)
260
260
  alias :hold
261
261
 
262
262
  ```ruby
263
- set_hold_time(1)
263
+ radar.hold_time = 1
264
264
  ```
265
265
 
266
266
  ### Micro Detection retrigger
@@ -270,7 +270,7 @@ set_hold_time(1)
270
270
  alias: :mide
271
271
 
272
272
  ```ruby
273
- set_micro_detection_retrigger(0)
273
+ radar.micro_detection_retrigger = 0
274
274
  ```
275
275
 
276
276
  ### Micro Detection sensitivity
@@ -280,7 +280,31 @@ set_micro_detection_retrigger(0)
280
280
  alias: :mids
281
281
 
282
282
  ```ruby
283
- set_micro_detection_sensitivty(4)
283
+ radar.micro_detection_sensitivty = 4
284
+ ```
285
+
286
+ ## CLI
287
+
288
+ ``` fish
289
+ ❯ bundle exec rfbeam list
290
+
291
+ +--+------------+------------------+
292
+ |id|Path |Version |
293
+ +--+------------+------------------+
294
+ |0 |/dev/ttyUSB0|K-LD7_APP-RFB-0103|
295
+ +--+------------+------------------+
296
+
297
+ ❯ bundle exec rfbeam help
298
+ Commands:
299
+ rfbeam config <radar_id> # Shows the parameter setting for the Radar module
300
+ rfbeam ddat <radar_id> -s, [--stream] # stream any valid detections, stop stream with q and enter
301
+ rfbeam help [COMMAND] # Describe available commands or one specific command
302
+ rfbeam list # List available radar modules
303
+ rfbeam pdat <radar_id> # Display Tracked Targets
304
+ rfbeam reset <radar_id> # Shows the parameter setting for the Radar module
305
+ rfbeam rfft <radar_id> -s, [--stream] # Display the dopplar radar data as a plot
306
+ rfbeam set_param <radar_id> <key> <value> # Set radar parameters, see readme for keys
307
+ rfbeam tdat <radar_id> # Display tracked target data
284
308
  ```
285
309
 
286
310
  ## Development
data/lib/rfbeam/cli.rb CHANGED
@@ -1,4 +1,3 @@
1
- # rubocop:disable all
2
1
  require 'thor'
3
2
  require 'rfbeam'
4
3
  require 'tty-table'
@@ -9,122 +8,78 @@ require 'unicode_plot'
9
8
 
10
9
  module RfBeam
11
10
  class CLI < Thor
12
-
13
11
  attr_accessor :radar, :logger
14
12
 
15
13
  desc 'list', 'List available radar modules'
16
14
  def list
15
+ logger = TTY::Logger.new
17
16
  devices = RfBeam.connected
18
- @logger.warning 'No Radar modules found.' unless devices.count.positive?
17
+ logger.warning 'No Radar modules found.' unless devices.count.positive?
19
18
 
20
- table = TTY::Table.new( header: ['id', 'Path', 'Version'])
19
+ table = TTY::Table.new(header: %w[id Path Version])
21
20
 
22
- devices.each.with_index do |path, index|
23
- table << ["R#{index}", path, @radar.sw_version]
24
- end
21
+ devices.each.with_index { |path, index| table << ["#{index}", path, radar(index).sw_version] }
25
22
  puts table.render(:ascii)
26
23
  end
27
24
 
28
25
  desc 'config <radar_id>', 'Shows the parameter setting for the Radar module'
29
26
  def config(radar_id)
30
- init_radar(radar_id)
31
- puts @radar.config
27
+ puts radar(radar_id).config
28
+ end
29
+
30
+ desc 'reset <radar_id>', 'Shows the parameter setting for the Radar module'
31
+ def reset(radar_id)
32
+ @logger.success 'Radar reset to factory defaults' if radar(radar_id).reset
32
33
  end
33
34
 
34
35
  desc 'set_param <radar_id> <key> <value>', 'Set radar parameters, see readme for keys'
35
36
  def set_param(radar_id, param, value)
36
- return logger.warning("Invalid param: '#{param}'") unless RfBeam::K_ld7::RADAR_PARAMETERS.include?(param.to_sym)
37
+ return @logger.warn("Invalid param: '#{param}'") unless RfBeam::K_ld7::RADAR_PARAMETERS.include?(param.to_sym)
37
38
 
38
- init_radar radar_id
39
- @radar.send("#{param}=", value.to_i)
40
- logger.success "Set #{@radar.formatted_parameter(param.to_sym)}"
39
+ r = radar(radar_id)
40
+ r.send("#{param}=", value.to_i)
41
+ @logger.success r.formatted_parameter(param.to_sym)
41
42
  end
42
43
 
43
44
  desc 'ddat <radar_id>', 'stream any valid detections, stop stream with q and enter'
44
- option :stream, type: :boolean, aliases: '-s', desc: "Stream the data from the device"
45
+ option :stream, type: :boolean, aliases: '-s', desc: 'Stream the data from the device'
45
46
  def ddat(radar_id)
46
- init_radar radar_id
47
-
48
- if options[:stream]
49
- Thread.new { monitor_keypress }
50
- spinner = TTY::Spinner.new("[:spinner] :title ", format: :bouncing_ball)
51
- loop do
52
- break if @stop_streaming
53
- spinner.spin
54
- data = @radar.ddat
55
- spinner.update title: "Searching... #{data}"
56
- spinner.success @radar.tdat if data[2] == 1
57
- end
58
- spinner.stop
59
- puts "\nTask Quit."
60
- else
61
- puts "\n#{@radar.ddat}"
62
- end
63
-
47
+ cli = RfBeam::KLD7::CliOutput.new(radar_id)
48
+ cli.display(:ddat, stream: options[:stream])
64
49
  end
65
50
 
66
51
  desc 'pdat <radar_id>', 'Display Tracked Targets'
67
52
  def pdat(radar_id)
68
- init_radar radar_id
69
- puts @radar.pdat
53
+ cli = RfBeam::KLD7::CliOutput.new(radar_id)
54
+ cli.display(:pdat, stream: options[:stream])
70
55
  end
71
56
 
72
- desc "rfft <radar_id>", "Display the dopplar radar data as a plot"
73
- option :stream, type: :boolean, aliases: '-s', desc: "Stream the data from the device"
74
- option :period, type: :numeric, aliases: '-p', default: 0.5, desc: "Update period (in seconds) for the streaming data"
57
+ desc 'rfft <radar_id>', 'Display the dopplar radar data as a plot'
58
+ option :stream, type: :boolean, aliases: '-s', desc: 'Stream the data from the device'
59
+ option :raw, type: :boolean, aliases: '-r', desc: 'Display raw data'
75
60
  def rfft(radar_id)
76
- init_radar(radar_id)
77
-
78
- if options[:stream]
79
- streamer = RfBeam::KLD7::Streamer.new(@radar)
80
- streamer.rfft
61
+ plotter = RfBeam::KLD7::CliOutput.new(radar_id)
62
+ if options[:raw]
63
+ print radar(radar_id).rfft
81
64
  else
82
- plot = rfft_plot(@radar)
83
- p plot.render
65
+ plotter.plot(:rfft, stream: options[:stream])
84
66
  end
85
67
  end
86
68
 
69
+ desc 'tdat <radar_id>', 'Display tracked target data'
70
+ def tdat(radar_id)
71
+ cli = RfBeam::KLD7::CliOutput.new(radar_id)
72
+ cli.display(:tdat, stream: options[:stream])
73
+ end
74
+
87
75
  private
88
76
 
89
- def init_radar(id)
77
+ def radar(id)
90
78
  devices = RfBeam.connected
91
79
  @logger = TTY::Logger.new
92
80
  return @logger.warning 'No Radar modules found.' unless devices.count.positive?
93
81
 
94
- @radar = RfBeam::K_ld7.new(devices[id.to_i])
95
- end
96
-
97
- def plot_data(data)
98
- { x: Array(-128...128), series1: data.shift(256).map { |value| value / 100 }, series2: data.shift(256).map { |value| value.to_i / 100 } }
99
- end
100
-
101
- def monitor_keypress
102
- loop do
103
- key = STDIN.getch
104
- if key.downcase == 'q'
105
- @stop_streaming = true
106
- break
107
- end
108
- end
109
- end
110
-
111
- def rfft_plot(radar)
112
- speed = radar.max_speed
113
- speed_label = radar.formatted_parameter(:max_speed)
114
- xlim = [speed - speed * 2, speed]
115
- data = plot_data(radar.rfft)
116
- plot = UnicodePlot.lineplot(
117
- data[:x],
118
- data[:series1],
119
- name: 'IF1/2 Averaged',
120
- title: 'Raw FFT',
121
- height: 25,
122
- width: 120,
123
- xlabel: "Speed (km/h), #{speed_label}",
124
- ylabel: 'Signal (db)', xlim: [-128, 128],
125
- ylim: [0, 100])
126
- UnicodePlot.lineplot!(plot, data[:x], data[:series2], name: "Threshold")
127
- plot
82
+ RfBeam::K_ld7.new(devices[id.to_i])
128
83
  end
129
84
  end
130
- end
85
+ end
@@ -0,0 +1,41 @@
1
+ require 'tty-table'
2
+
3
+ module RfBeam
4
+ module KLD7
5
+ class CliFormatter
6
+ def tdat(data)
7
+ { dist: data[2], speed: data[3], angle: data[4], mag: data[5] }
8
+ end
9
+
10
+ def pdat_table(data)
11
+ table = TTY::Table.new header: ['index', 'dist (M)', 'speed (Km/h)', 'angle (°)', 'mag (db)']
12
+ count = data[1] / 8
13
+ data.shift(2)
14
+ count.times.with_index do |index|
15
+ values = data.shift(4).map { |value| value.to_f / 100.0 }
16
+ table << [index, values].flatten
17
+ end
18
+ table
19
+ end
20
+
21
+ def ddat(data)
22
+ if data[2] == 1
23
+ labels = ['Detection', 'Micro Detection', 'Angle', 'Direction', 'Range', 'Speed']
24
+ labels
25
+ .map
26
+ .with_index { |label, index| "#{label}: #{DETECTION_FLAGS[to_symbol(label)][data[index + 2]]}" }
27
+ .join("\n")
28
+ else
29
+ 'DDAT: No Detection'
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def to_symbol(string)
36
+ modified_string = string.gsub(' ', '_').downcase
37
+ modified_string.to_sym
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,127 @@
1
+ require 'unicode_plot'
2
+ require 'io/console'
3
+ require 'stringio'
4
+ require 'tty-screen'
5
+ require 'tty-logger'
6
+
7
+ module RfBeam
8
+ module KLD7
9
+ class CliOutput
10
+ attr_reader :radar
11
+
12
+ def initialize(radar_id)
13
+ devices = RfBeam.connected
14
+ return TTY::Logger.new.warning 'No Radar modules found.' unless devices.count.positive?
15
+
16
+ @radar = RfBeam::K_ld7.new(devices[radar_id.to_i])
17
+ end
18
+
19
+ def display(type, stream: false)
20
+ send("display_#{type}", stream)
21
+ end
22
+
23
+ def plot(type, stream: false)
24
+ stream ? stream_plot(type) : display_plot(type)
25
+ end
26
+
27
+ def display_plot(type)
28
+ out = StringIO.new
29
+ def out.tty?
30
+ true
31
+ end
32
+ out.truncate(0)
33
+
34
+ plot = send("#{type}_plot")
35
+ plot.render(out)
36
+
37
+ lines = out.string.lines
38
+ lines.each { |line| $stdout.print "\r#{line}" }
39
+ $stdout.print "\e[0J"
40
+ $stdout.flush
41
+
42
+ if @streaming
43
+ n = lines.count
44
+ $stdout.print "\e[#{n}F"
45
+ end
46
+ end
47
+
48
+ def stream_plot(type)
49
+ @streaming = true
50
+ Thread.new { monitor_keypress }
51
+
52
+ loop do
53
+ display_plot(type)
54
+ break unless @streaming
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def monitor_keypress
61
+ loop do
62
+ key = STDIN.getch
63
+ if key.downcase == 'q'
64
+ @streaming = false
65
+ break
66
+ end
67
+ end
68
+ end
69
+
70
+ def rfft_plot_data(data)
71
+ {
72
+ x: Array(-128...128),
73
+ series1: data.shift(256).map { |value| value / 100 },
74
+ series2: data.shift(256).map { |value| value.to_i / 100 }
75
+ }
76
+ end
77
+
78
+ def display_ddat(stream)
79
+ if stream
80
+ @streaming = true
81
+ Thread.new { monitor_keypress }
82
+ spinner = TTY::Spinner.new('[:spinner] :title ', format: :bouncing_ball)
83
+ logger = TTY::Logger.new
84
+ loop do
85
+ break unless @streaming
86
+ spinner.spin
87
+ data = @radar.ddat
88
+ spinner.update title: "Searching... #{data[:detection_str]}"
89
+ logger.success "#{@radar.tdat}" if data[:detection]
90
+ end
91
+ else
92
+ puts RfBeam::KLD7::CliFormatter.new.ddat(@radar.ddat)
93
+ end
94
+ end
95
+
96
+ def display_tdat(stream)
97
+ puts RfBeam::KLD7::CliFormatter.new.tdat(@radar.tdat)
98
+ end
99
+
100
+ def display_pdat(stream)
101
+ table = RfBeam::KLD7::CliFormatter.new.pdat_table(@radar.pdat)
102
+ puts "\n Detected Raw Targets"
103
+ puts table.render(:unicode, alignment: :center)
104
+ end
105
+
106
+ def rfft_plot
107
+ width = TTY::Screen.width * 0.65
108
+ data = rfft_plot_data(@radar.rfft)
109
+ plot =
110
+ UnicodePlot.lineplot(
111
+ data[:x],
112
+ data[:series1],
113
+ name: 'IF1/2 Averaged',
114
+ title: 'Raw FFT',
115
+ height: 25,
116
+ width: width,
117
+ xlabel: 'Speed (km/h)',
118
+ ylabel: 'Signal (db)',
119
+ xlim: [-128, 128],
120
+ ylim: [0, 100]
121
+ )
122
+ UnicodePlot.lineplot!(plot, data[:x], data[:series2], name: 'Threshold')
123
+ plot
124
+ end
125
+ end
126
+ end
127
+ end