lignite 0.2.0 → 0.3.0

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +12 -0
  4. data/NEWS.md +5 -1
  5. data/README.md +2 -2
  6. data/Rakefile +1 -1
  7. data/VERSION +1 -1
  8. data/bin/ev3tool +111 -104
  9. data/examples/bobbee.rb +7 -7
  10. data/examples/hello.rb +2 -0
  11. data/examples/hello.yml +4 -0
  12. data/examples/light-sensor.rb +2 -0
  13. data/examples/light-sensor.yml +3 -0
  14. data/examples/lights.rb +7 -7
  15. data/examples/lights.yml +4 -0
  16. data/examples/sys_list_files.rb +4 -2
  17. data/examples/sys_list_files.yml +9 -0
  18. data/lib/lignite.rb +5 -1
  19. data/lib/lignite/assembler.rb +6 -6
  20. data/lib/lignite/body_compiler.rb +4 -0
  21. data/lib/lignite/connection.rb +59 -1
  22. data/lib/lignite/connection/bluetooth.rb +7 -1
  23. data/lib/lignite/connection/replay.rb +57 -0
  24. data/lib/lignite/connection/tap.rb +45 -0
  25. data/lib/lignite/connection/usb.rb +10 -7
  26. data/lib/lignite/direct_commands.rb +56 -5
  27. data/lib/lignite/message.rb +8 -5
  28. data/lib/lignite/motors.rb +5 -5
  29. data/lib/lignite/op_compiler.rb +19 -18
  30. data/lib/lignite/rbf_object.rb +1 -1
  31. data/lib/lignite/system_commands.rb +30 -2
  32. data/lib/lignite/variables.rb +2 -2
  33. data/lignite.gemspec +14 -4
  34. data/rubocop-suse.yml +74 -0
  35. data/spec/connection_usb_spec.rb +42 -0
  36. data/spec/data/ColorReadout.rb +11 -12
  37. data/spec/data/HelloWorld-subop.rb +1 -1
  38. data/spec/data/HelloWorld.rb +1 -1
  39. data/spec/data/NoDebug.rb +1 -1
  40. data/spec/data/VernierReadout.rb +4 -4
  41. data/spec/direct_commands_spec.rb +25 -0
  42. data/spec/system_commands_spec.rb +22 -0
  43. metadata +28 -3
  44. data/lib/lignite/message_sender.rb +0 -94
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4ffc33346a586d1761204e68f028b383303cc742
4
- data.tar.gz: a57b880c420ef54dac5ea3b0023293867f5e9bdf
3
+ metadata.gz: bf1b7c4214285394b080eee7ac292b74a02583ec
4
+ data.tar.gz: 2e8eceb5bb0058722da49642ac252c9054f3582b
5
5
  SHA512:
6
- metadata.gz: 41357f5c2e71a45aef56e9de73a36b2010462417210b18ea9fbd3cd654889a0103ff1aaf82ebb81f29571fa88f0f4bf43020e7dc56ac1f5862147d6b7278dd2e
7
- data.tar.gz: 8a278113af2c9a7500d4ca7774dcb5e99a4ce163ad24e2446eb06e0b7ae4baddae676bbd736741b2d33491b3f52c75ec9f6b0bb2e8be05eff4386cf053292535
6
+ metadata.gz: 7dba38b35d34ffbafce9c5788c792f12d598623d4862dbfa0f3a3ed99c1c31c490495619cef96970047e9622832d0c92ae97cbfc9282a5e3c52a0f2e06992114
7
+ data.tar.gz: dddf6c17fd11bd751b111d6c03e70c6114a5333a3acd61ee7fe4dd8958195ab7c3b5c44260144b5e2bea2d3945a8b2621b36d278fc55a5b08d969766a81e417a
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format documentation
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ inherit_from: rubocop-suse.yml
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.1
5
+
6
+ Naming/FileName:
7
+ Exclude:
8
+ - spec/data/*.rb
9
+
10
+ Layout/IndentHeredoc:
11
+ Exclude:
12
+ - lignite.gemspec
data/NEWS.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  ## unreleased
4
4
 
5
- - (none)
5
+ ## 0.3.0, 2018-03-02
6
+
7
+ - Added Tap and Replay to simulate a real robot with YAML files for tests
8
+ - `ev3tool help` added
9
+ - `ev3tool run` changed to `ev3tool start` (because Thor reserves `run`)
6
10
 
7
11
  ## 0.2.0, 2018-02-26
8
12
 
data/README.md CHANGED
@@ -41,11 +41,11 @@ section of the
41
41
  Running the built-in demo program: Connect the brick with a USB cable. Run
42
42
 
43
43
  ```sh
44
- sudo ev3tool run BrkProg_SAVE/Demo.rpf
44
+ sudo ev3tool start BrkProg_SAVE/Demo.rpf
45
45
  ```
46
46
 
47
47
  In the usual case where the folder and the program name are the same, a
48
- shortcut works: `ev3tool run everstorm` is like `ev3tool run
48
+ shortcut works: `ev3tool start everstorm` is like `ev3tool start
49
49
  everstorm/everstorm.rbf`.
50
50
 
51
51
  > The `sudo` is needed to access the USB device.
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- task :default => :test
1
+ task default: :test
2
2
 
3
3
  desc "Run tests"
4
4
  task :test do
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/bin/ev3tool CHANGED
@@ -1,144 +1,151 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "lignite"
3
+ require "thor"
3
4
  require "fileutils"
4
5
  include Lignite::Bytes
5
6
 
6
7
  # The VM current working directory is /home/root/lms2012/sys
7
8
  # which is not very useful. A better default is /home/root/lms2012/prjs
8
9
  # which is displayed on the 2nd tab of the brick UI.
9
- EV3TOOL_HOME = "../prjs"
10
+ EV3TOOL_HOME = "../prjs".freeze
10
11
 
11
12
  def phandles
12
- handles = $sc.list_open_handles
13
+ handles = sc.list_open_handles
13
14
  puts "OPEN HANDLES: ", hexdump(handles)
14
15
  end
15
16
 
16
- def upload(local_filename, brick_filename = nil)
17
- data = File.read(local_filename, encoding: Encoding::BINARY)
18
- unless brick_filename
19
- prj = File.basename(local_filename, ".rbf")
20
- brick_filename = "#{EV3TOOL_HOME}/#{prj}/#{prj}.rbf"
17
+ class Ev3Tool < Thor
18
+ desc "upload LOCAL_FILENAME [BRICK_FILENAME]", "upload a program or a file"
19
+ map "ul" => "upload"
20
+ def upload(local_filename, brick_filename = nil)
21
+ data = File.read(local_filename, encoding: Encoding::BINARY)
22
+ unless brick_filename
23
+ prj = File.basename(local_filename, ".rbf")
24
+ brick_filename = "#{EV3TOOL_HOME}/#{prj}/#{prj}.rbf"
25
+ end
26
+ handle = sc.begin_download(data.bytesize, brick_filename)
27
+ sc.continue_download(handle, data)
21
28
  end
22
- handle = $sc.begin_download(data.bytesize, brick_filename)
23
- $sc.continue_download(handle, data)
24
- end
25
29
 
26
- def download(brick_filename, local_filename = nil)
27
- local_filename ||= File.basename(brick_filename)
28
- fsize, handle, data = $sc.begin_upload(4096, brick_filename)
29
- File.open(local_filename, "w") do |f|
30
+ desc "download BRICK_FILENAME [LOCAL_FILENAME]", "download a file"
31
+ map "dl" => "download"
32
+ def download(brick_filename, local_filename = nil)
33
+ local_filename ||= File.basename(brick_filename)
34
+ fsize, handle, data = sc.begin_upload(4096, brick_filename)
35
+ File.open(local_filename, "w") do |f|
36
+ loop do
37
+ f.write(data)
38
+ fsize -= data.bytesize
39
+ break if fsize.zero?
40
+ handle, data = sc.continue_upload(handle, 4096)
41
+ end
42
+ end
43
+ end
44
+
45
+ desc "list-files DIRNAME", "list DIRNAME in a long format"
46
+ map "ls-l" => "list-files"
47
+ def list_files(name)
48
+ name ||= EV3TOOL_HOME
49
+ name = "#{EV3TOOL_HOME}/#{name}" unless name.start_with?("/")
50
+
51
+ result = ""
52
+ fsize, handle, data = sc.list_files(4096, name)
30
53
  loop do
31
- f.write(data)
54
+ result += data
32
55
  fsize -= data.bytesize
33
56
  break if fsize.zero?
34
- handle, data = $sc.continue_upload(handle, 4096)
57
+ handle, data = sc.continue_list_files(handle, 4096)
35
58
  end
36
- end
37
- end
38
-
39
- def list_files(name)
40
- name ||= EV3TOOL_HOME
41
- unless name.start_with?("/")
42
- name = "#{EV3TOOL_HOME}/#{name}"
59
+ result
60
+ rescue Lignite::VMError
61
+ nil
43
62
  end
44
63
 
45
- result = ""
46
- fsize, handle, data = $sc.list_files(4096, name)
47
- loop do
48
- result += data
49
- fsize -= data.bytesize
50
- break if fsize.zero?
51
- handle, data = $sc.continue_list_files(handle, 4096)
64
+ desc "ls DIRNAME", "list DIRNAME in a short format"
65
+ def ls(name)
66
+ raw = list_files(name)
67
+ return nil if raw.nil?
68
+
69
+ raw.lines.map do |l|
70
+ l = l.chomp
71
+ next nil if ["./", "../"].include?(l)
72
+ next l if l.end_with?("/")
73
+ # skip checksum + space + size + space
74
+ l[32 + 1 + 8 + 1..-1]
75
+ end.compact
52
76
  end
53
- result
54
- rescue Lignite::VMError
55
- nil
56
- end
57
77
 
58
- def ls(name)
59
- raw = list_files(name)
60
- return nil if raw.nil?
61
-
62
- raw.lines.map do |l|
63
- l = l.chomp
64
- next nil if l == "./" || l == "../"
65
- next l if l.end_with?("/")
66
- # skip checksum + space + size + space
67
- l[32 + 1 + 8 + 1 .. -1]
68
- end.compact
69
- end
70
-
71
- def file_exist?(name)
72
- dirname = File.dirname(name)
73
- filename = File.basename(name)
74
- files = ls(dirname) || []
75
- files.include?(filename)
76
- end
78
+ desc "start NAME", "start a program"
79
+ def start(name)
80
+ if name.include?("/")
81
+ name = "#{EV3TOOL_HOME}/#{name}" unless name.start_with?("/")
82
+ else
83
+ name = "#{EV3TOOL_HOME}/#{name}/#{name}.rbf"
84
+ end
77
85
 
78
- def run(name)
79
- if name.include?("/")
80
- unless name.start_with?("/")
81
- name = "#{EV3TOOL_HOME}/#{name}"
86
+ unless file_exist?(name)
87
+ $stderr.puts "File #{name.inspect} not found"
88
+ exit 1
82
89
  end
83
- else
84
- name = "#{EV3TOOL_HOME}/#{name}/#{name}.rbf"
85
- end
86
90
 
87
- unless file_exist?(name)
88
- $stderr.puts "File #{name.inspect} not found"
89
- exit 1
91
+ slot = Lignite::USER_SLOT
92
+ no_debug = 0
93
+ dc.block do
94
+ # these are local variables
95
+ data32 :size
96
+ data32 :ip
97
+ file_load_image(slot, name, :size, :ip)
98
+ program_start(slot, :size, :ip, no_debug)
99
+ end
90
100
  end
91
101
 
92
- slot = Lignite::USER_SLOT
93
- no_debug = 0
94
- $dc.block do
95
- # these are local variables
96
- data32 :size
97
- data32 :ip
98
- file_load_image(slot, name, :size, :ip)
99
- program_start(slot, :size, :ip, no_debug)
102
+ desc "stop", "stop a running program"
103
+ def stop
104
+ dc.program_stop(Lignite::USER_SLOT)
100
105
  end
101
- end
102
106
 
103
- def stop
104
- $dc.program_stop(Lignite::USER_SLOT)
105
- end
107
+ no_commands do
108
+ def file_exist?(name)
109
+ dirname = File.dirname(name)
110
+ filename = File.basename(name)
111
+ files = ls(dirname) || []
112
+ files.include?(filename)
113
+ end
106
114
 
107
- def assisted_connection
108
- Lignite::Connection.create
109
- rescue => e
110
- fn = Lignite::Connection::Bluetooth.config_filename
111
- $stderr.puts <<MSG
115
+ def assisted_connection
116
+ Lignite::Connection.create
117
+ rescue => e
118
+ fn = Lignite::Connection::Bluetooth.config_filename
119
+ $stderr.puts <<MSG
112
120
  Could not connect to EV3.
113
121
  Use a USB cable or configure a Bluetooth address in #{fn.inspect}.
114
122
  Details:
115
123
  #{e.message}
116
124
  MSG
117
125
 
118
- template = Lignite::Connection::Bluetooth.template_config_filename
119
- if !File.exist?(fn) && File.exist?(template)
120
- FileUtils.mkdir_p(File.dirname(fn))
121
- FileUtils.install(template, fn)
122
- $stderr.puts "(A template config file has been copied for your convenience)"
126
+ template = Lignite::Connection::Bluetooth.template_config_filename
127
+ if !File.exist?(fn) && File.exist?(template)
128
+ FileUtils.mkdir_p(File.dirname(fn))
129
+ FileUtils.install(template, fn)
130
+ $stderr.puts "(A template config file has been copied for your convenience)"
131
+ end
132
+ exit 1
133
+ end
134
+
135
+ def sc
136
+ return @sc if @sc
137
+ @sc = Lignite::SystemCommands.new(conn)
138
+ end
139
+
140
+ def dc
141
+ return @dc if @dc
142
+ @dc = Lignite::DirectCommands.new(conn)
143
+ end
144
+
145
+ def conn
146
+ @conn ||= assisted_connection
147
+ end
123
148
  end
124
- exit 1
125
149
  end
126
150
 
127
- conn = assisted_connection
128
- $sc = Lignite::SystemCommands.new(conn)
129
- $dc = Lignite::DirectCommands.new(conn)
130
-
131
- case ARGV[0]
132
- when "upload", "ul"
133
- upload(ARGV[1], ARGV[2])
134
- when "download", "dl"
135
- download(ARGV[1], ARGV[2])
136
- when "list", "ls"
137
- puts ls(ARGV[1])
138
- when "ls-l"
139
- puts list_files(ARGV[1])
140
- when "run"
141
- run(ARGV[1])
142
- when "stop"
143
- stop
144
- end
151
+ Ev3Tool.start(ARGV)
data/examples/bobbee.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/ruby
2
- # coding: utf-8
2
+
3
3
  # https://www.lego.com/mindstorms/build-a-robot/bobb3e
4
4
  # A Bobcat® like two-tracked forklift
5
5
 
@@ -7,10 +7,10 @@ require "lignite"
7
7
 
8
8
  class Bobbee
9
9
  # @return [Lignite::Motors]
10
- attr :drive
10
+ attr_reader :drive
11
11
  # @return [Lignite::Motors]
12
- attr :lift
13
- attr :dc
12
+ attr_reader :lift
13
+ attr_reader :dc
14
14
 
15
15
  def initialize(drive: Lignite::PORT_B | Lignite::PORT_C,
16
16
  lift: Lignite::PORT_A,
@@ -49,7 +49,7 @@ class Bobbee
49
49
  end
50
50
 
51
51
  def third_raise(wait: true)
52
- lift.step_power(30, 10, LIFT_FULL/3 - 20, 10)
52
+ lift.step_power(30, 10, LIFT_FULL / 3 - 20, 10)
53
53
  lift.ready if wait
54
54
 
55
55
  beep
@@ -57,7 +57,7 @@ class Bobbee
57
57
  end
58
58
 
59
59
  def lower(wait: true)
60
- lift.step_power(-1, 10, LIFT_FULL - 20, 10) #, Lignite::COAST)
60
+ lift.step_power(-1, 10, LIFT_FULL - 20, 10) # , Lignite::COAST)
61
61
  lift.ready if wait
62
62
 
63
63
  beep
@@ -65,7 +65,7 @@ class Bobbee
65
65
  end
66
66
 
67
67
  def third_lower(wait: true)
68
- lift.step_power(-1, 10, LIFT_FULL/3 - 20, 10)
68
+ lift.step_power(-1, 10, LIFT_FULL / 3 - 20, 10)
69
69
  lift.ready if wait
70
70
  end
71
71
 
data/examples/hello.rb CHANGED
@@ -6,3 +6,5 @@ dc = Lignite::DirectCommands.new
6
6
  dc.ui_draw_clean
7
7
  dc.ui_draw_text(Lignite::FG_COLOR, 20, 40, "Hello, world!")
8
8
  dc.ui_draw_update
9
+
10
+ dc.close
@@ -0,0 +1,4 @@
1
+ ---
2
+ - SEND: 01008000008401
3
+ - SEND: 02008000008405011481288048656c6c6f2c20776f726c642100
4
+ - SEND: 03008000008400
@@ -17,3 +17,5 @@ pct = dc.with_reply do
17
17
  end
18
18
  end
19
19
  puts "Light sensor percentage: #{pct}"
20
+
21
+ dc.close
@@ -0,0 +1,3 @@
1
+ ---
2
+ - SEND: 0100000400991d000200000160
3
+ - RECV: 0100020000c07f
data/examples/lights.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/ruby
2
2
  require "lignite"
3
3
 
4
- dc = Lignite::DirectCommands.new
5
-
6
- dc.ui_write_led(Lignite::LED_RED_FLASH)
7
- sleep 3
8
- dc.ui_write_led(Lignite::LED_ORANGE_PULSE)
9
- sleep 3
10
- dc.ui_write_led(Lignite::LED_GREEN)
4
+ Lignite::DirectCommands.run do |_dc|
5
+ ui_write_led(Lignite::LED_RED_FLASH)
6
+ sleep 3
7
+ ui_write_led(Lignite::LED_ORANGE_PULSE)
8
+ sleep 3
9
+ ui_write_led(Lignite::LED_GREEN)
10
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ - SEND: 0100800000821b05
3
+ - SEND: 0200800000821b09
4
+ - SEND: 0300800000821b01
@@ -4,8 +4,8 @@ require "lignite"
4
4
  sc = Lignite::SystemCommands.new
5
5
 
6
6
  result = ""
7
- name = "/home/root/lms2012/prjs/"
8
- bufsize = 42 # to demonstrate chunking
7
+ name = "/home/root/lms2012/prjs/BrkProg_SAVE/"
8
+ bufsize = 20 # to demonstrate chunking
9
9
  fsize, handle, data = sc.list_files(bufsize, name)
10
10
  loop do
11
11
  result += data
@@ -14,3 +14,5 @@ loop do
14
14
  handle, data = sc.continue_list_files(handle, bufsize)
15
15
  end
16
16
  puts result
17
+
18
+ sc.close
@@ -0,0 +1,9 @@
1
+ ---
2
+ - SEND: 0100019914002f686f6d652f726f6f742f6c6d73323031322f70726a732f42726b50726f675f534156452f00
3
+ - RECV: 01000399003f000000004642384444353337303742313432304633413330
4
+ - SEND: 0200019a001400
5
+ - RECV: 0200039a00003234333546453241344230422030303030303941
6
+ - SEND: 0300019a001400
7
+ - RECV: 0300039a0000302044656d6f2e7270660a4356532f0a2e2e2f0a
8
+ - SEND: 0400019a001400
9
+ - RECV: 0400039a08002e2f0a