rplidar 0.1.3 → 0.1.4
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 +4 -4
- data/README.md +1 -1
- data/lib/rplidar.rb +0 -1
- data/lib/rplidar/csv.rb +15 -0
- data/lib/rplidar/device_info_data_response.rb +2 -0
- data/lib/rplidar/driver.rb +9 -27
- data/lib/rplidar/response_descriptor.rb +13 -3
- data/lib/rplidar/util.rb +16 -0
- data/lib/rplidar/version.rb +1 -1
- data/spec/rplidar/driver_spec.rb +72 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa1dc51107f51fd3c8837dadfe94554acb6bd0f4bfb0cfa01ff62ddf02bfb41c
|
4
|
+
data.tar.gz: 831187436c56cbd6d0177f0ae8b42031fff1e21edbdf4383927c673ce15dd636
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1edb2e50c064b17bdda2ebd06938a329c27f5f0cba0db00e948346ff949996a5a659579c307b2183095328d7e72c218dc3733495a178142252c19a8ac9b773c2
|
7
|
+
data.tar.gz: aa06473faf5ae16c26667055f87d74e9d37f0930b1bc43dd51e4d3225a36e971b4961b458759648d3b747f7c55bf7ca0b9b6358b84a01bc53ad1fe47484e79fc
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://semaphoreci.com/yurykotlyarov/rplidar) [](https://codecov.io/gh/yura/rplidar) [](https://codeclimate.com/github/yura/rplidar/maintainability) [](https://hakiri.io/github/yura/rplidar/master) [](https://badge.fury.io/rb/rplidar)
|
4
4
|
|
5
|
-
Ruby implementation of SLAMTEK RPLIDAR A2M8
|
5
|
+
Ruby implementation of SLAMTEK RPLIDAR lidar driver. Tested on A2M8 model.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
data/lib/rplidar.rb
CHANGED
data/lib/rplidar/csv.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Rplidar
|
2
|
+
# Dump measurements to CSV file.
|
3
|
+
module CSV
|
4
|
+
def dump_scans(filename = 'output.csv', iterations = 1)
|
5
|
+
responses = scan(iterations)
|
6
|
+
|
7
|
+
file = File.open(filename, 'w')
|
8
|
+
file.puts 'start,quality,angle,distance'
|
9
|
+
responses.each do |r|
|
10
|
+
file.puts "#{r[:start]},#{r[:quality]},#{r[:angle]},#{r[:distance]}"
|
11
|
+
end
|
12
|
+
file.close
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rplidar/driver.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
+
require 'rplidar/csv'
|
2
|
+
require 'rplidar/util'
|
1
3
|
require 'rubyserial'
|
2
4
|
|
3
5
|
module Rplidar
|
4
6
|
# Ruby implementation of driver of the SLAMTEC RPLIDAR A2.
|
5
7
|
class Driver
|
8
|
+
include Rplidar::CSV
|
9
|
+
include Rplidar::Util
|
10
|
+
|
6
11
|
# Commands
|
7
12
|
COMMAND_GET_HEALTH = 0x52
|
8
13
|
COMMAND_GET_INFO = 0x50
|
@@ -48,17 +53,6 @@ module Rplidar
|
|
48
53
|
request_with_payload(COMMAND_MOTOR_PWM, 0)
|
49
54
|
end
|
50
55
|
|
51
|
-
def scan_to_file(filename = 'output.csv', iterations = 1)
|
52
|
-
responses = scan(iterations)
|
53
|
-
|
54
|
-
File.open(filename, 'w') do |file|
|
55
|
-
file.puts 'start,quality,angle,distance'
|
56
|
-
responses.each do |r|
|
57
|
-
file.puts "#{r[:start]},#{r[:quality]},#{r[:angle]},#{r[:distance]}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
56
|
def scan(iterations = 1)
|
63
57
|
command(COMMAND_SCAN)
|
64
58
|
responses = collect_scan_data_responses(iterations)
|
@@ -87,14 +81,6 @@ module Rplidar
|
|
87
81
|
command(COMMAND_RESET)
|
88
82
|
end
|
89
83
|
|
90
|
-
def port
|
91
|
-
@port ||= Serial.new(@port_address, UART_BAUD_RATE, 8, :none, 1)
|
92
|
-
end
|
93
|
-
|
94
|
-
def close
|
95
|
-
@port.close if @port
|
96
|
-
end
|
97
|
-
|
98
84
|
def command(command)
|
99
85
|
request(command)
|
100
86
|
response_descriptor if COMMANDS_WITH_RESPONSE.include?(command)
|
@@ -117,10 +103,6 @@ module Rplidar
|
|
117
103
|
port.write(string)
|
118
104
|
end
|
119
105
|
|
120
|
-
def checksum(string)
|
121
|
-
binary_to_ints(string).reduce(:^)
|
122
|
-
end
|
123
|
-
|
124
106
|
def response_descriptor
|
125
107
|
raw_response = read_response(RESPONSE_DESCRIPTOR_LENGTH)
|
126
108
|
Rplidar::ResponseDescriptor.new(raw_response).response
|
@@ -147,12 +129,12 @@ module Rplidar
|
|
147
129
|
end
|
148
130
|
end
|
149
131
|
|
150
|
-
def
|
151
|
-
|
132
|
+
def close
|
133
|
+
@port.close if @port
|
152
134
|
end
|
153
135
|
|
154
|
-
def
|
155
|
-
|
136
|
+
def port
|
137
|
+
@port ||= Serial.new(@port_address, UART_BAUD_RATE, 8, :none, 1)
|
156
138
|
end
|
157
139
|
end
|
158
140
|
end
|
@@ -1,5 +1,10 @@
|
|
1
1
|
module Rplidar
|
2
|
-
DATA_TYPE_DEVICE_INFO
|
2
|
+
DATA_TYPE_DEVICE_INFO = 0x4
|
3
|
+
DATA_TYPE_CURRENT_STATE = 0x6
|
4
|
+
DATA_TYPE_SCAN = 0x81
|
5
|
+
|
6
|
+
SEND_MODE_SINGLE_REQUEST_SINGLE_RESPONSE = 0x0
|
7
|
+
SEND_MODE_SINGLE_REQUEST_MULTIPLE_RESPONSE = 0x1
|
3
8
|
|
4
9
|
# Incapsulates Response Descriptor processing. Format of Response Descriptor:
|
5
10
|
#
|
@@ -44,11 +49,16 @@ module Rplidar
|
|
44
49
|
end
|
45
50
|
|
46
51
|
def correct_send_mode?
|
47
|
-
[
|
52
|
+
[
|
53
|
+
SEND_MODE_SINGLE_REQUEST_SINGLE_RESPONSE,
|
54
|
+
SEND_MODE_SINGLE_REQUEST_MULTIPLE_RESPONSE
|
55
|
+
].include?(send_mode)
|
48
56
|
end
|
49
57
|
|
50
58
|
def correct_data_type?
|
51
|
-
[
|
59
|
+
[
|
60
|
+
DATA_TYPE_DEVICE_INFO, DATA_TYPE_CURRENT_STATE, DATA_TYPE_SCAN
|
61
|
+
].include?(data_type)
|
52
62
|
end
|
53
63
|
|
54
64
|
def data_response_length
|
data/lib/rplidar/util.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Rplidar
|
2
|
+
# Binary encoding, decoding, checksum methods.
|
3
|
+
module Util
|
4
|
+
def checksum(string)
|
5
|
+
binary_to_ints(string).reduce(:^)
|
6
|
+
end
|
7
|
+
|
8
|
+
def ints_to_binary(array, format = 'C*')
|
9
|
+
[array].flatten.pack(format)
|
10
|
+
end
|
11
|
+
|
12
|
+
def binary_to_ints(string, format = 'C*')
|
13
|
+
string.unpack(format)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/rplidar/version.rb
CHANGED
data/spec/rplidar/driver_spec.rb
CHANGED
@@ -22,6 +22,78 @@ RSpec.describe Rplidar::Driver do
|
|
22
22
|
.and_return(port)
|
23
23
|
end
|
24
24
|
|
25
|
+
describe '#dump_scans' do
|
26
|
+
subject(:dump_scans) { lidar.dump_scans('dump_30.csv', 30) }
|
27
|
+
|
28
|
+
let(:file) { instance_double('file') }
|
29
|
+
|
30
|
+
before do
|
31
|
+
allow(lidar).to receive(:scan).with(30).and_return([
|
32
|
+
{ start: true, quality: 2, angle: 3, distance: 4 }
|
33
|
+
])
|
34
|
+
allow(File).to receive(:open).with('dump_30.csv', 'w').and_return(file)
|
35
|
+
allow(file).to receive(:puts).with('start,quality,angle,distance')
|
36
|
+
allow(file).to receive(:puts).with('true,2,3,4')
|
37
|
+
allow(file).to receive(:close)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'reads measurements' do
|
41
|
+
dump_scans
|
42
|
+
expect(lidar).to have_received(:scan).with(30)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'opens a file for writing' do
|
46
|
+
dump_scans
|
47
|
+
expect(File).to have_received(:open).with('dump_30.csv', 'w')
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'writes a CSV header to the file' do
|
51
|
+
dump_scans
|
52
|
+
expect(file).to have_received(:puts).with('start,quality,angle,distance')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'writes scans' do
|
56
|
+
dump_scans
|
57
|
+
expect(file).to have_received(:puts).with('true,2,3,4')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'closes the file' do
|
61
|
+
dump_scans
|
62
|
+
expect(file).to have_received(:close)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#device_info' do
|
67
|
+
subject(:device_info) { lidar.device_info }
|
68
|
+
|
69
|
+
before do
|
70
|
+
allow(lidar).to receive(:command)
|
71
|
+
.with(0x50)
|
72
|
+
.and_return(data_response_length: 20)
|
73
|
+
allow(lidar).to receive(:read_response).and_return([
|
74
|
+
40, 24, 1, 4, 168, 226, 154, 240, 197, 226,
|
75
|
+
157, 210, 182, 227, 157, 245, 43, 49, 49, 22
|
76
|
+
])
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'calls GET_INFO command' do
|
80
|
+
device_info
|
81
|
+
expect(lidar).to have_received(:command).with(0x50)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'reads device info data response' do
|
85
|
+
device_info
|
86
|
+
expect(lidar).to have_received(:read_response).with(20)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns device info' do
|
90
|
+
expect(device_info).to eq(
|
91
|
+
model: 40, firmware: '1.24',
|
92
|
+
hardware: 4, serial_number: 'A8E29AF0C5E29DD2B6E39DF52B313116'
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
25
97
|
describe '#current_state' do
|
26
98
|
subject(:current_state) { lidar.current_state }
|
27
99
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rplidar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yury Kotlyarov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyserial
|
@@ -112,12 +112,14 @@ files:
|
|
112
112
|
- bin/console
|
113
113
|
- bin/setup
|
114
114
|
- lib/rplidar.rb
|
115
|
+
- lib/rplidar/csv.rb
|
115
116
|
- lib/rplidar/current_state_data_response.rb
|
116
117
|
- lib/rplidar/device_info_data_response.rb
|
117
118
|
- lib/rplidar/driver.rb
|
118
119
|
- lib/rplidar/response.rb
|
119
120
|
- lib/rplidar/response_descriptor.rb
|
120
121
|
- lib/rplidar/scan_data_response.rb
|
122
|
+
- lib/rplidar/util.rb
|
121
123
|
- lib/rplidar/version.rb
|
122
124
|
- rplidar.gemspec
|
123
125
|
- spec/rplidar/current_state_data_response_spec.rb
|