lignite 0.2.0 → 0.3.0

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