Module: RfBeam::KLD7

Included in:
Kld7
Defined in:
lib/rfbeam/kld7/streamer.rb,
lib/rfbeam/kld7/constants.rb,
lib/rfbeam/kld7/radar_messages.rb,
lib/rfbeam/kld7/detection_params.rb,
lib/rfbeam/kld7/operation_params.rb,
lib/rfbeam/kld7/serial_connection.rb

Defined Under Namespace

Classes: Error, Streamer

Constant Summary collapse

BAUDE_RATES =

All supported Serial port baude rates

{ 0 => 115_200, 1 => 460_800, 2 => 921_600, 3 => 2_000_000, 4 => 3_000_000 }.freeze
RESP_CODES =

‘INIT’ command response codes

{
  0 => 'OK',
  1 => 'Unknown command',
  2 => 'Invalid parameter value',
  3 => 'Invalid RPST version',
  4 => 'Uart error (parity, framing, noise)',
  5 => 'Sensor busy',
  6 => 'Timeout error'
}.freeze
RESPONSE_DELAY =

Delays are determined empirically and may need adjusting with baude rate

0.05
MEASUREMENT_DELAY =
0.15
FRAME_DATA_TYPES =

‘GNFD’ command types

{ disabled: 0x00, radc: 0x01, rfft: 0x02, pdat: 0x04, tdat: 0x08, ddat: 0x10, done: 0x20 }.freeze
DETECTION_FLAGS =

The angle, direction, range and speed flags are only valid if the detection flag is 1.

{
  detection: ['No Detection', 'Detection'],
  micro_detection: ['No Detection', 'Detection'],
  angle: %w[Left Right],
  direction: %w[Receding Approaching],
  range: %w[Far Near],
  speed: %w[Low High]
}.freeze
Param =
Data.define(:name, :grps_index, :description, :default, :units, :values) do |_param|
  def initialize(name:, grps_index:, description: nil, default: nil, units: nil, values: [])
    super(name:, grps_index:, description:, default:, units:, values:)
  end
end
RADAR_PARAMETERS =
{
  sw_version: Param.new(name: 'Software Version', grps_index: 2, default: 'K-LD7_APP-RFB-XXXX'),
  base_frequency:
    Param.new(
      name: 'Base Frequency',
      grps_index: 3,
      description: '0 = Low, 1 = Middle, 2 = High',
      default: 1,
      values: %w[Low Middle High]
    ),
  max_speed:
    Param.new(
      name: 'Maximum Speed',
      grps_index: 4,
      description: '0 = 12km/h, 1 = 25km/h, 2 = 50km/h, 3 = 100km/h',
      default: 1,
      units: 'km/h',
      values: %w[12.5 25 50 100]
    ),
  max_range:
    Param.new(
      name: 'Maximum Range',
      grps_index: 5,
      description: '0 = 5m, 1 = 10m, 2 = 30m, 3 = 100m',
      default: 1,
      values: %w[5m 10m 30m 100m]
    ),
  threshold_offset:
    Param.new(name: 'Threshold Offset', grps_index: 6, description: '10db - 60db', default: 30, units: 'db'),
  tracking_filter:
    Param.new(
      name: 'Tracking Filter Type',
      grps_index: 7,
      description: '0 = Standard, 2 = Fast Detection, 3 = Long Visibility',
      default: 0,
      values: ['standard', 'Fast Detection', 'Long Visibility']
    ),
  vibration_suppression:
    Param.new(
      name: 'Vibration Suppression',
      grps_index: 8,
      description: '0-16, 0 = No Suppression, 16 = High Suppression',
      default: 2
    ),
  min_detection_distance:
    Param.new(
      name: 'Minimum Detection Distance',
      grps_index: 9,
      description: '0 - 100% of range setting',
      default: 0,
      units: '%'
    ),
  max_detection_distance:
    Param.new(
      name: 'Maximum Detection Distance',
      grps_index: 10,
      description: '0 - 100% of range setting',
      default: 50,
      units: '%'
    ),
  min_detection_angle:
    Param.new(name: 'Minimum Detection Angle', grps_index: 11, description: '-90° - 90°', default: -90, units: '°'),
  max_detection_angle:
    Param.new(name: 'Maximum Detection Angle', grps_index: 12, description: '-90° - 90°', default: 90, units: '°'),
  min_detection_speed:
    Param.new(
      name: 'Minimum Detection Speed',
      grps_index: 13,
      description: '0 - 100% of speed setting',
      default: 0,
      units: '%'
    ),
  max_detection_speed:
    Param.new(
      name: 'Maximum Detection Speed',
      grps_index: 14,
      description: '0 - 100% of speed setting',
      default: 100,
      units: '%'
    ),
  detection_direction:
    Param.new(
      name: 'Detection Direction',
      grps_index: 15,
      description: '0 = Receding, 1 = Approaching, 2 = Both',
      default: 2,
      values: %w[Receding Approaching Both]
    ),
  range_threshold:
    Param.new(
      name: 'Range Threshold',
      grps_index: 16,
      description: '0 - 100% of range setting',
      default: 10,
      units: '%'
    ),
  angle_threshold:
    Param.new(name: 'Angle Threshold', grps_index: 17, description: '-90° - 90°', default: 0, units: '°'),
  speed_threshold:
    Param.new(
      name: 'Speed Threshold',
      grps_index: 18,
      description: '0 - 100% of speed setting',
      default: 50,
      units: '%'
    ),
  digital_output1:
    Param.new(
      name: 'Digital Output 1',
      grps_index: 19,
      description: '0 = Direction, 1 = Angle, 2 = Range, 3 = Speed, 4 = Micro Detection',
      default: 0,
      values: %w[Direction Angle Range Speed Micro]
    ),
  digital_output2:
    Param.new(
      name: 'Digital Output 2',
      grps_index: 20,
      description: '0 = Direction, 1 = Angle, 2 = Range, 3 = Speed, 4 = Micro Detection',
      default: 1,
      values: %w[Direction Angle Range Speed Micro]
    ),
  digital_output3:
    Param.new(
      name: 'Digital Output 3',
      grps_index: 21,
      description: '0 = Direction, 1 = Angle, 2 = Range, 3 = Speed, 4 = Micro Detection',
      default: 2,
      values: %w[Direction Angle Range Speed Micro]
    ),
  hold_time: Param.new(name: 'Hold Time', grps_index: 22, description: '1 - 7200s', default: 1, units: 's'),
  micro_detection_retrigger:
    Param.new(
      name: 'Micro Detection Trigger',
      grps_index: 23,
      description: '0 = Off, 1 = Retrigger',
      default: 0,
      values: %w[Off Retrigger]
    ),
  micro_detection_sensativity:
    Param.new(
      name: 'Micro Detection Sensativity',
      grps_index: 24,
      description: '0 - 9, 0 = Min, 9 = Max',
      default: 4
    )
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#serial_portObject (readonly)

Returns the value of attribute serial_port.



11
12
13
# File 'lib/rfbeam/kld7/serial_connection.rb', line 11

def serial_port
  @serial_port
end

Instance Method Details

#base_frequencyObject Also known as: rbfr


Base Frequency, 0 = low, 1 = middle (default), 2 = high




8
9
10
# File 'lib/rfbeam/kld7/operation_params.rb', line 8

def base_frequency
  query_parameter RADAR_PARAMETERS[:base_frequency].grps_index
end

#base_frequency=(frequency = 1) ⇒ Object Also known as: set_base_frequency, rbfr=



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/rfbeam/kld7/operation_params.rb', line 13

def base_frequency=(frequency = 1)
  value =
    case frequency
    when 0, :low, 'low'
      0
    when 1, :middle, 'middle'
      1
    when 2, :high, 'high'
      2
    else
      raise ArgumentError, "Invalid arg: '#{frequency}'"
    end
  set_parameter(:rbfr, value, :uint32)
end

#closeObject



23
24
25
26
27
28
29
# File 'lib/rfbeam/kld7/serial_connection.rb', line 23

def close
  return unless connected?

  @serial_port.close
  @serial_port = nil
  @serial_port.nil?
end

#configObject



76
77
78
79
80
81
# File 'lib/rfbeam/kld7/radar_messages.rb', line 76

def config
  data = grps
  output = "\n"
  RADAR_PARAMETERS.each_key { |key| output << formatted_parameter(key, data[RADAR_PARAMETERS[key].grps_index]) }
  output
end

#ddatObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/rfbeam/kld7/radar_messages.rb', line 53

def ddat
  request_frame_data(:ddat)
  array = read(14).unpack('a4LC6')
  {
    label: array[0],
    detection: array[2] == 1,
    detection_str: DETECTION_FLAGS[:detection][array[2]],
    micro_detection: DETECTION_FLAGS[:micro_detection][array[3]],
    angle: DETECTION_FLAGS[:angle][array[4]],
    direction: DETECTION_FLAGS[:direction][array[5]],
    range: DETECTION_FLAGS[:range][array[6]],
    speed: DETECTION_FLAGS[:speed][array[7]]
  }
end

#detection?Boolean

Returns:

  • (Boolean)


7
8
9
10
# File 'lib/rfbeam/kld7/radar_messages.rb', line 7

def detection?
  data = ddat
  (data[2] == 1)
end

#detection_directionObject


Detection Direction, 0 = Receding, 1 = Approaching, 2 = Both (default)




104
105
106
# File 'lib/rfbeam/kld7/detection_params.rb', line 104

def detection_direction
  query_parameter RADAR_PARAMETERS[:detection_direction].grps_index
end

#detection_direction=(direction = 2) ⇒ Object Also known as: dedi=, set_detection_direction

Raises:

  • (ArgumentError)


108
109
110
111
112
113
# File 'lib/rfbeam/kld7/detection_params.rb', line 108

def detection_direction=(direction = 2)
  raise ArgumentError, "Invalid arg: '#{direction}'" unless (0..2).cover?(direction)
  raise ArgumentError, 'Expected an Integer' unless direction.is_a?(Integer)

  set_parameter :dedi, direction, :uint32
end

#formatted_parameter(param, value = nil) ⇒ Object



83
84
85
86
87
88
89
90
91
# File 'lib/rfbeam/kld7/radar_messages.rb', line 83

def formatted_parameter(param, value = nil)
  param = RADAR_PARAMETERS[param]
  if value.nil?
    data = grps
    value = data[param.grps_index]
  end
  param_str_value = param.values.empty? ? value.to_s : param.values[value]
  "#{param.name}: #{param_str_value}#{param.units}\n"
end

#grpsObject

Get the radar parameter structure



69
70
71
72
73
74
# File 'lib/rfbeam/kld7/radar_messages.rb', line 69

def grps
  command = ['GRPS', 0]
  write command.pack('a4L')
  check_response
  read(50).unpack('a4LA19C8c2C4cCCCCSCC')
end

#init_radarObject



44
45
46
47
48
# File 'lib/rfbeam/kld7/serial_connection.rb', line 44

def init_radar
  command = ['INIT', 4, 0]
  @serial_port.write command.pack('a4LL')
  check_response
end

#initialize(path, baude_rate = 0) {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:

  • _self (RfBeam::KLD7)

    the object that the method was called on



13
14
15
16
17
18
19
20
21
# File 'lib/rfbeam/kld7/serial_connection.rb', line 13

def initialize(path, baude_rate = 0)
  baude_rate = check_speed(baude_rate)
  data_bits = 8
  parity = :even
  stop_bits = 1
  open_serial_port(path, baude_rate, data_bits, parity, stop_bits)

  yield self if block_given?
end

#max_detection_angle=(angle = 90) ⇒ Object Also known as: maan=, set_max_detection_angle

Raises:

  • (ArgumentError)


60
61
62
63
64
65
# File 'lib/rfbeam/kld7/detection_params.rb', line 60

def max_detection_angle=(angle = 90)
  raise ArgumentError, "Invalid arg: '#{angle}'" unless (-90..90).cover?(angle)
  raise ArgumentError, 'Expected an Integer' unless angle.is_a?(Integer)

  set_parameter :maan, angle, :int32
end

#max_detection_angleqObject


Maximum Detection Angle, -90° - 90°, default = 90




56
57
58
# File 'lib/rfbeam/kld7/detection_params.rb', line 56

def max_detection_angleq
  query_parameter RADAR_PARAMETERS[:max_detection_angle].grps_index
end

#max_detection_distanceObject


Maximum Detection distance, 0 - 100% of Range setting, default = 50




24
25
26
# File 'lib/rfbeam/kld7/detection_params.rb', line 24

def max_detection_distance
  query_parameter RADAR_PARAMETERS[:min_detection_distance].grps_index
end

#max_detection_distance=(value = 50) ⇒ Object Also known as: mara=, set_max_detection_distance

Raises:

  • (ArgumentError)


28
29
30
31
32
33
# File 'lib/rfbeam/kld7/detection_params.rb', line 28

def max_detection_distance=(value = 50)
  raise ArgumentError, "Invalid arg: '#{value}'" unless (0..100).cover?(value)
  raise ArgumentError, 'Expected an Integer' unless value.is_a?(Integer)

  set_parameter :mara, value, :uint32
end

#max_detection_speedObject


Maximum Detection Speed, 0 - 100% of Speed setting, default = 100




88
89
90
# File 'lib/rfbeam/kld7/detection_params.rb', line 88

def max_detection_speed
  query_parameter RADAR_PARAMETERS[:max_detection_speed].grps_index
end

#max_detection_speed=(speed = 100) ⇒ Object Also known as: masp=, set_max_detection_speed

Raises:

  • (ArgumentError)


92
93
94
95
96
97
# File 'lib/rfbeam/kld7/detection_params.rb', line 92

def max_detection_speed=(speed = 100)
  raise ArgumentError, "Invalid arg: '#{speed}'" unless (0..100).cover?(speed)
  raise ArgumentError, 'Expected an Integer' unless speed.is_a?(Integer)

  set_parameter :masp, speed, :uint32
end

#max_rangeObject


Maximum Range, 0 = 5m, 1 = 10m (default), 2 = 30m, 3 = 100m




51
52
53
# File 'lib/rfbeam/kld7/operation_params.rb', line 51

def max_range
  query_parameter(RADAR_PARAMETERS[:max_range].grps_index)
end

#max_range=(range = 1) ⇒ Object Also known as: rrai=, set_max_range

Raises:

  • (ArgumentError)


55
56
57
58
59
60
# File 'lib/rfbeam/kld7/operation_params.rb', line 55

def max_range=(range = 1)
  raise ArgumentError, "Invalid arg: '#{range}'" unless (0..3).cover?(range)
  raise ArgumentError, 'Expected an Integer' unless range.is_a?(Integer)

  set_parameter :rrai, range, :uint32
end

#max_speedObject


Maximum Speed, 0 = 12.5km/h, 1 = 25km/h (default), 2 = 50km/h, 3 = 100km/h




34
35
36
# File 'lib/rfbeam/kld7/operation_params.rb', line 34

def max_speed
  query_parameter(RADAR_PARAMETERS[:max_speed].grps_index)
end

#max_speed=(speed = 1) ⇒ Object Also known as: set_max_speed, rspi

Raises:

  • (ArgumentError)


38
39
40
41
42
43
# File 'lib/rfbeam/kld7/operation_params.rb', line 38

def max_speed=(speed = 1)
  raise ArgumentError, "Invalid arg: '#{speed}'" unless (0..3).cover?(speed)
  raise ArgumentError, 'Expected an Integer' unless speed.is_a?(Integer)

  set_parameter :rspi, speed, :uint32
end

#micro_detection_retriggerObject


Micro Detection retrigger, 0 = Off (default), 1 = Retrigger




120
121
122
# File 'lib/rfbeam/kld7/detection_params.rb', line 120

def micro_detection_retrigger
  query_parameter RADAR_PARAMETERS[:set_micro_detection_retrigger].grps_index
end

#micro_detection_retrigger=(value = 0) ⇒ Object Also known as: mide=, set_micro_detection_retrigger

Raises:

  • (ArgumentError)


124
125
126
127
128
129
# File 'lib/rfbeam/kld7/detection_params.rb', line 124

def micro_detection_retrigger=(value = 0)
  raise ArgumentError, "Invalid arg: '#{value}'" unless (0..1).cover?(value)
  raise ArgumentError, 'Expected an Integer' unless value.is_a?(Integer)

  set_parameter :mide, value, :uint32
end

#micro_detection_sensitivityObject


Micro Detection sensitivity, 0 - 9, 0 = Min, 9 = Max, default = 4




136
137
138
# File 'lib/rfbeam/kld7/detection_params.rb', line 136

def micro_detection_sensitivity
  query_parameter RADAR_PARAMETERS[:micro_detection_sensitivity].grps_index
end

#micro_detection_sensitivity=(value = 4) ⇒ Object Also known as: mids=, set_micro_detection_sensitivity

Raises:

  • (ArgumentError)


140
141
142
143
144
145
# File 'lib/rfbeam/kld7/detection_params.rb', line 140

def micro_detection_sensitivity=(value = 4)
  raise ArgumentError, "Invalid arg: '#{value}'" unless (0..9).cover?(value)
  raise ArgumentError, 'Expected an Integer' unless value.is_a?(Integer)

  set_parameter :mids, value, :uint32
end

#min_detection_angleObject


Minimum Detection Angle, -90° - 90°, default = -90




40
41
42
# File 'lib/rfbeam/kld7/detection_params.rb', line 40

def min_detection_angle
  query_parameter RADAR_PARAMETERS[:min_detection_angle].grps_index
end

#min_detection_angle=(angle = -90)) ⇒ Object Also known as: mian=, set_min_detection_angle

Raises:

  • (ArgumentError)


44
45
46
47
48
49
# File 'lib/rfbeam/kld7/detection_params.rb', line 44

def min_detection_angle=(angle = -90)
  raise ArgumentError, "Invalid arg: '#{angle}'" unless (-90..90).cover?(angle)
  raise ArgumentError, 'Expected an Integer' unless angle.is_a?(Integer)

  set_parameter :mian, angle, :int32
end

#min_detection_distanceObject


Minimum Detection distance, 0 - 100% of Range setting, default = 0




8
9
10
# File 'lib/rfbeam/kld7/detection_params.rb', line 8

def min_detection_distance
  query_parameter RADAR_PARAMETERS[:min_detection_distance].grps_index
end

#min_detection_distance=(value = 0) ⇒ Object Also known as: mira=, set_min_detection_distance

Raises:

  • (ArgumentError)


12
13
14
15
16
17
# File 'lib/rfbeam/kld7/detection_params.rb', line 12

def min_detection_distance=(value = 0)
  raise ArgumentError, "Invalid arg: '#{value}'" unless (0..100).cover?(value)
  raise ArgumentError, 'Expected an Integer' unless value.is_a?(Integer)

  set_parameter :mira, value, :uint32
end

#min_detection_speedObject


Minimum Detection Speed, 0 - 100% of Speed setting, default = 0




72
73
74
# File 'lib/rfbeam/kld7/detection_params.rb', line 72

def min_detection_speed
  query_parameter RADAR_PARAMETERS[:min_detection_angle].grps_index
end

#min_detection_speed=(speed = 0) ⇒ Object Also known as: misp=, set_min_detection_speed

Raises:

  • (ArgumentError)


76
77
78
79
80
81
# File 'lib/rfbeam/kld7/detection_params.rb', line 76

def min_detection_speed=(speed = 0)
  raise ArgumentError, "Invalid arg: '#{speed}'" unless (0..100).cover?(speed)
  raise ArgumentError, 'Expected an Integer' unless speed.is_a?(Integer)

  set_parameter :misp, speed, :uint32
end

#pdat(formatted: false) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rfbeam/kld7/radar_messages.rb', line 30

def pdat(formatted: false)
  request_frame_data(:pdat)
  resp = read(102).unpack('a4LSssSSssSSssSSssSSssSSssSSssSSssSSssSSssS')
  return resp unless formatted

  target_count = Integer(resp[1], 10) / 8
  return [] if target_count <= 0

  resp.shift 2
  resp.compact
  detected_raw_targets = []
  target_count.times { detected_raw_targets << format_raw_target_data(resp.shift(4)) }
  detected_raw_targets
end

#read(bytes) ⇒ Object



31
32
33
34
35
# File 'lib/rfbeam/kld7/serial_connection.rb', line 31

def read(bytes)
  return unless connected?

  @serial_port.read(bytes)
end

#resetObject Also known as: rfse



23
24
25
26
27
# File 'lib/rfbeam/kld7/radar_messages.rb', line 23

def reset
  command = ['RFSE', 0]
  write command.pack('a4L')
  check_response
end

#rfftObject

Raises:



12
13
14
15
16
17
18
19
20
21
# File 'lib/rfbeam/kld7/radar_messages.rb', line 12

def rfft
  request_frame_data(:rfft)
  sleep MEASUREMENT_DELAY
  data = read(1032).unpack('a4LS256S256')
  header, length = data.shift(2)
  raise Error, "RFFT header response, header=#{header}" unless header == 'RFFT'
  raise Error, "RFFT payload length, length=#{length}" unless length == 1024

  data
end

#tdatObject



45
46
47
48
49
50
51
# File 'lib/rfbeam/kld7/radar_messages.rb', line 45

def tdat
  request_frame_data(:tdat)

  sleep 0.1
  resp = read(16).unpack('a4LSssS')
  return { dist: resp[2], speed: resp[3], angle: resp[4], mag: resp[5] } if resp[1].nonzero?
end

#threshold_offsetObject


Threshold Offset, 10 - 60db, (default = 30)




68
69
70
# File 'lib/rfbeam/kld7/operation_params.rb', line 68

def threshold_offset
  query_parameter RADAR_PARAMETERS[:threshold_offset].grps_index
end

#threshold_offset=(offset = 30) ⇒ Object Also known as: thof=, set_threshold_offset

Raises:

  • (ArgumentError)


72
73
74
75
76
77
# File 'lib/rfbeam/kld7/operation_params.rb', line 72

def threshold_offset=(offset = 30)
  raise ArgumentError, "Invalid arg: '#{offset}'" unless (10..60).cover?(offset)
  raise ArgumentError, 'Expected an Integer' unless offset.is_a?(Integer)

  set_parameter :thof, offset, :uint32
end

#tracking_filterObject


Tracking filter type, 0 = Standard (Default), 1 = Fast Tracking, 2 = Long visibility




85
86
87
# File 'lib/rfbeam/kld7/operation_params.rb', line 85

def tracking_filter
  query_parameter RADAR_PARAMETERS[:tracking_filter].grps_index
end

#tracking_filter=(type = 0) ⇒ Object Also known as: trtf=, set_tracking_filter

Raises:

  • (ArgumentError)


89
90
91
92
93
94
# File 'lib/rfbeam/kld7/operation_params.rb', line 89

def tracking_filter=(type = 0)
  raise ArgumentError, "Invalid arg: '#{type}'" unless (0..2).cover?(type)
  raise ArgumentError, 'Expected an Integer' unless type.is_a?(Integer)

  set_parameter :trft, type, :uint32
end

#vibration_suppressionObject


Vibration suppression, 0 - 16, 0 = No Suppression, 16 = High Suppression, default = 2




101
102
103
# File 'lib/rfbeam/kld7/operation_params.rb', line 101

def vibration_suppression
  query_parameter RADAR_PARAMETERS[:vibration_suppression].grps_index
end

#vibration_suppression=(value = 2) ⇒ Object Also known as: visu=, set_vibration_suppression

Raises:

  • (ArgumentError)


105
106
107
108
109
110
# File 'lib/rfbeam/kld7/operation_params.rb', line 105

def vibration_suppression=(value = 2)
  raise ArgumentError, "Invalid arg: '#{value}'" unless (0..16).cover?(value)
  raise ArgumentError, 'Expected an Integer' unless value.is_a?(Integer)

  set_parameter :visu, value, :uint32
end

#write(string) ⇒ Object



37
38
39
40
41
42
# File 'lib/rfbeam/kld7/serial_connection.rb', line 37

def write(string)
  return unless connected?

  @serial_port.write(string)
  sleep 0.1
end