Class: Rplidar::Driver

Inherits:
Object
  • Object
show all
Includes:
CSV, Util
Defined in:
lib/rplidar/driver.rb

Overview

Ruby implementation of driver of the SLAMTEC RPLIDAR A2.

Constant Summary collapse

COMMAND_GET_HEALTH =

Commands

0x52
COMMAND_GET_INFO =
0x50
COMMAND_MOTOR_PWM =
0xF0
COMMAND_SCAN =
0x20
COMMAND_STOP =
0x25
COMMAND_RESET =
0x40
COMMANDS_WITH_RESPONSE =
[
  COMMAND_GET_HEALTH,
  COMMAND_GET_INFO,
  COMMAND_SCAN
].freeze
RESPONSE_DESCRIPTOR_LENGTH =

Default length of responses

7
GET_INFO_RESPONSE_LENGTH =
20
SCAN_DATA_RESPONSE_LENGTH =
5
UART_BAUD_RATE =
115_200

Instance Method Summary collapse

Methods included from Util

#binary_to_ints, #checksum, #ints_to_binary

Methods included from CSV

#dump_scans

Constructor Details

#initialize(port_address) ⇒ Driver

Returns a new instance of Driver.


32
33
34
# File 'lib/rplidar/driver.rb', line 32

def initialize(port_address)
  @port_address = port_address
end

Instance Method Details

#clear_portObject


127
128
129
130
# File 'lib/rplidar/driver.rb', line 127

def clear_port
  while port.getbyte
  end
end

#closeObject


132
133
134
# File 'lib/rplidar/driver.rb', line 132

def close
  @port.close if @port
end

#collect_scan_data_responses(iterations) ⇒ Object


64
65
66
67
68
69
70
71
72
73
# File 'lib/rplidar/driver.rb', line 64

def collect_scan_data_responses(iterations)
  responses = []
  iteration = -1
  while iteration < iterations
    response = scan_data_response
    iteration += 1 if response[:start]
    responses << response if iteration.between?(0, iterations - 1)
  end
  responses
end

#command(command) ⇒ Object


84
85
86
87
# File 'lib/rplidar/driver.rb', line 84

def command(command)
  request(command)
  response_descriptor if COMMANDS_WITH_RESPONSE.include?(command)
end

#current_stateObject


36
37
38
39
40
# File 'lib/rplidar/driver.rb', line 36

def current_state
  descriptor = command(COMMAND_GET_HEALTH)
  raw_response = read_response(descriptor[:data_response_length])
  Rplidar::CurrentStateDataResponse.new(raw_response).response
end

#device_infoObject


42
43
44
45
46
# File 'lib/rplidar/driver.rb', line 42

def device_info
  descriptor = command(COMMAND_GET_INFO)
  raw_response = read_response(descriptor[:data_response_length])
  Rplidar::DeviceInfoDataResponse.new(raw_response).response
end

#portObject


136
137
138
# File 'lib/rplidar/driver.rb', line 136

def port
  @port ||= Serial.new(@port_address, UART_BAUD_RATE, 8, :none, 1)
end

#read_response(length) ⇒ Object


116
117
118
119
120
121
122
123
124
125
# File 'lib/rplidar/driver.rb', line 116

def read_response(length)
  t = Time.now
  response = []
  while response.size < length
    byte = port.getbyte
    response << byte if byte
    raise 'Timeout while reading a byte from the port' if Time.now - t > 2
  end
  response
end

#request(command) ⇒ Object


89
90
91
92
93
# File 'lib/rplidar/driver.rb', line 89

def request(command)
  params = [0xA5, command]
  port.write(ints_to_binary(params))
  sleep 0.5
end

#request_with_payload(command, payload) ⇒ Object


95
96
97
98
99
100
101
102
103
104
# File 'lib/rplidar/driver.rb', line 95

def request_with_payload(command, payload)
  payload_string = ints_to_binary(payload, 'S<*')
  payload_size = payload_string.size

  string = ints_to_binary([0xA5, command, payload_size])
  string += payload_string
  string += ints_to_binary(checksum(string))

  port.write(string)
end

#resetObject


80
81
82
# File 'lib/rplidar/driver.rb', line 80

def reset
  command(COMMAND_RESET)
end

#response_descriptorObject


106
107
108
109
# File 'lib/rplidar/driver.rb', line 106

def response_descriptor
  raw_response = read_response(RESPONSE_DESCRIPTOR_LENGTH)
  Rplidar::ResponseDescriptor.new(raw_response).response
end

#scan(iterations = 1) ⇒ Object


56
57
58
59
60
61
62
# File 'lib/rplidar/driver.rb', line 56

def scan(iterations = 1)
  command(COMMAND_SCAN)
  responses = collect_scan_data_responses(iterations)
  stop

  responses
end

#scan_data_responseObject


111
112
113
114
# File 'lib/rplidar/driver.rb', line 111

def scan_data_response
  raw_response = read_response(SCAN_DATA_RESPONSE_LENGTH)
  Rplidar::ScanDataResponse.new(raw_response).response
end

#start_motor(pwm = 660) ⇒ Object


48
49
50
# File 'lib/rplidar/driver.rb', line 48

def start_motor(pwm = 660)
  request_with_payload(COMMAND_MOTOR_PWM, pwm)
end

#stopObject


75
76
77
78
# File 'lib/rplidar/driver.rb', line 75

def stop
  command(COMMAND_STOP)
  clear_port
end

#stop_motorObject


52
53
54
# File 'lib/rplidar/driver.rb', line 52

def stop_motor
  request_with_payload(COMMAND_MOTOR_PWM, 0)
end