rfbeam 0.4.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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