rintcore 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,73 @@
1
+ require 'rint_core/g_code/codes'
2
+ require 'active_support/core_ext/object/blank'
3
+
4
+ module RintCore
5
+ module Driver
6
+ module Queueing
7
+
8
+ private
9
+
10
+ def initialize_queueing
11
+ @main_queue = []
12
+ @priority_queue = []
13
+ @queue_index = 0
14
+ @line_number = 0
15
+ @resend_from = -1
16
+ @machine_history = []
17
+ end
18
+
19
+ def advance_queue
20
+ return false unless online? && printing?
21
+ until clear_to_send? do
22
+ sleep(config.sleep_time)
23
+ end
24
+ not_clear_to_send!
25
+ return true if resend_line
26
+ return true if run_priority_queue
27
+ if run_main_queue
28
+ return true
29
+ else
30
+ not_printing!
31
+ unless paused?
32
+ @queue_index = 0
33
+ @line_number = 0
34
+ send!(RintCore::GCode::Codes::SET_LINE_NUM, -1, true)
35
+ end
36
+ return true
37
+ end
38
+ end
39
+
40
+ def resend_line
41
+ if @resend_from == @line_number
42
+ @resend_from = -1
43
+ return nil
44
+ elsif @resend_from < @line_number && @resend_from > -1
45
+ send!(@machine_history[@resend_from], @resend_from, false)
46
+ @resend_from += 1
47
+ return true
48
+ end
49
+ end
50
+
51
+ def run_priority_queue
52
+ unless @priority_queue.blank?
53
+ send!(@priority_queue.shift)
54
+ # clear_to_send!
55
+ end
56
+ end
57
+
58
+ def run_main_queue
59
+ if !paused? && @queue_index < @main_queue.length
60
+ current_line = @main_queue[@queue_index]
61
+ current_line = current_line.to_s unless current_line.class == String
62
+ unless current_line.blank?
63
+ send!(current_line, @line_number, true)
64
+ @line_number += 1
65
+ end
66
+ @queue_index += 1
67
+ return true
68
+ end
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,71 @@
1
+ require 'rint_core/g_code/codes'
2
+ require 'active_support/core_ext/object/blank'
3
+
4
+ module RintCore
5
+ module Driver
6
+ module State
7
+
8
+ def can_print?
9
+ connected? && online? && !printing?
10
+ end
11
+
12
+ def connected?
13
+ @connection.present?
14
+ end
15
+
16
+ def clear_to_send?
17
+ @clear && online?
18
+ end
19
+
20
+ def listen_can_continue?
21
+ !@stop_listening && connected?
22
+ end
23
+
24
+ def online?
25
+ connected? && @online
26
+ end
27
+
28
+ def paused?
29
+ @paused
30
+ end
31
+
32
+ def printing?
33
+ @printing
34
+ end
35
+
36
+ private
37
+
38
+ def initialize_state
39
+ @clear = false
40
+ @online = false
41
+ @printing = false
42
+ @paused = false
43
+ @stop_listening = false
44
+ end
45
+
46
+ def clear_to_send!
47
+ @clear = true
48
+ end
49
+
50
+ def not_clear_to_send!
51
+ @clear = false
52
+ end
53
+
54
+ def online!
55
+ @online = true
56
+ end
57
+
58
+ def offline!
59
+ @online = false
60
+ end
61
+
62
+ def printing!
63
+ @printing = true
64
+ end
65
+
66
+ def not_printing!
67
+ @printing = false
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,5 +1,6 @@
1
+ require 'rint_core/g_code/codes'
1
2
  module RintCore
2
- class GCode
3
-
3
+ module GCode
4
+
4
5
  end
5
6
  end
@@ -1,12 +1,12 @@
1
1
  module RintCore
2
2
  module GCode
3
- class Codes
3
+ module Codes
4
4
  RAPID_MOVE = 'G0'
5
5
  CONTROLLED_MOVE = 'G1'
6
6
  DWELL = 'G4'
7
7
  HEAD_OFFSET = 'G10'
8
8
  USE_INCHES = 'G20'
9
- USE_MILIMETRES = 'G21'
9
+ USE_MILLIMETRES = 'G21'
10
10
  HOME = 'G28'
11
11
  ABS_POSITIONING = 'G90'
12
12
  REL_POSITIONING = 'G91'
@@ -0,0 +1,83 @@
1
+ require 'rint_core/g_code/codes'
2
+ require 'active_support/core_ext/object/blank'
3
+
4
+ module RintCore
5
+ module GCode
6
+ class Line
7
+ include RintCore::GCode::Codes
8
+
9
+ attr_accessor :imperial, :relative, :f
10
+ attr_reader :raw
11
+ attr_writer :x, :y, :z, :e
12
+
13
+ def initialize(line)
14
+ @coordinates = ['X','Y','Z','E','F']
15
+ @number_pattern = /[-]?\d+[.]?\d*/
16
+ @raw = line.upcase.strip
17
+ @raw = @raw.split(COMMENT_SYMBOL).first.strip if line.include?(COMMENT_SYMBOL)
18
+
19
+ parse_coordinates
20
+ end
21
+
22
+ def to_mm(number)
23
+ number *= 25.4 if number.present? && @imperial
24
+ number
25
+ end
26
+
27
+ def x
28
+ to_mm @x
29
+ end
30
+
31
+ def y
32
+ to_mm @y
33
+ end
34
+
35
+ def z
36
+ to_mm @z
37
+ end
38
+
39
+ def e
40
+ to_mm @e
41
+ end
42
+
43
+ def command
44
+ if @raw.present?
45
+ @raw.split(' ').first
46
+ else
47
+ ''
48
+ end
49
+ end
50
+
51
+ def get_float(axis)
52
+ @raw.split(axis).last.scan(@number_pattern).first.to_f
53
+ end
54
+
55
+ def parse_coordinates
56
+ @coordinates.each do |axis|
57
+ send(axis.downcase+'=', get_float(axis)) if @raw.include?(axis)
58
+ end
59
+ end
60
+
61
+ def is_move?
62
+ @raw.start_with?(RAPID_MOVE) || @raw.start_with?(CONTROLLED_MOVE)
63
+ end
64
+
65
+ def travel_move?
66
+ is_move? && !@e.present?
67
+ end
68
+
69
+ def extrusion_move?
70
+ is_move? && @e.present? && @e > 0
71
+ end
72
+
73
+ def full_home?
74
+ command == HOME && @x.blank? && @y.blank? && @z.blank?
75
+ end
76
+
77
+ def to_s
78
+ @raw
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,173 @@
1
+ require 'rint_core/g_code/codes'
2
+ require 'rint_core/g_code/line'
3
+ require 'active_support/core_ext/object/blank'
4
+
5
+ module RintCore
6
+ module GCode
7
+ class Object
8
+ include RintCore::GCode::Codes
9
+
10
+ attr_accessor :raw_data, :layers
11
+ attr_reader :lines, :x_min, :x_max, :y_min, :y_max, :z_min, :z_max,
12
+ :filament_used, :x_travel, :y_travel, :z_travel, :e_travel,
13
+ :width, :depth, :height
14
+
15
+ def initialize(data = nil)
16
+ if data.class == String && self.class.is_file?(data)
17
+ data = self.class.get_file(data)
18
+ end
19
+ return false if data.blank? || data.class != Array
20
+ @raw_data = data
21
+ @imperial = false
22
+ @relative = false
23
+ @lines = []
24
+ data.each do |line|
25
+ line = RintCore::GCode::Line.new(line)
26
+ @lines << line if line.raw.present?
27
+ end
28
+ process
29
+ end
30
+
31
+ def self.is_file?(file)
32
+ file.present? && File.exist?(file) && File.file?(file)
33
+ end
34
+
35
+ def self.get_file(file)
36
+ IO.readlines(file)
37
+ end
38
+
39
+ private
40
+
41
+ def process
42
+ set_variables
43
+
44
+ @lines.each do |line|
45
+ case line.command
46
+ when USE_INCHES
47
+ @imperial = true
48
+ when USE_MILLIMETRES
49
+ @imperial = false
50
+ when ABS_POSITIONING
51
+ @relative = false
52
+ when REL_POSITIONING
53
+ @relative = true
54
+ when SET_POSITION
55
+ set_positions(line)
56
+ when HOME
57
+ home_axes(line)
58
+ when RAPID_MOVE
59
+ movement_line(line)
60
+ when CONTROLLED_MOVE
61
+ count_layers(line)
62
+ movement_line(line)
63
+ end
64
+ end
65
+
66
+ @width = @x_max - @x_min
67
+ @depth = @y_max - @y_min
68
+ @height = @z_max - @z_min
69
+ end
70
+
71
+ def count_layers(line)
72
+ if line.z.present? && line.z > @current_z
73
+ @layers += 1
74
+ end
75
+ end
76
+
77
+ def movement_line(line)
78
+ line.imperial = @imperial
79
+ line.relative = @relative
80
+ measure_travel(line)
81
+ set_current_position(line)
82
+ set_limits(line)
83
+ end
84
+
85
+ def measure_travel(line)
86
+ if line.relative
87
+ @x_travel += line.x.abs if line.x.present?
88
+ @y_travel += line.y.abs if line.y.present?
89
+ @z_travel += line.z.abs if line.z.present?
90
+ else
91
+ @x_travel += (@current_x - line.x).abs if line.x.present?
92
+ @y_travel += (@current_y - line.y).abs if line.y.present?
93
+ @z_travel += (@current_z - line.z).abs if line.z.present?
94
+ end
95
+ end
96
+
97
+ def home_axes(line)
98
+ if line.x.present? || line.full_home?
99
+ @x_travel += @current_x
100
+ @current_x = 0
101
+ end
102
+ if line.y.present? || line.full_home?
103
+ @y_travel += @current_y
104
+ @current_y = 0
105
+ end
106
+ if line.z.present? || line.full_home?
107
+ @z_travel += @current_z
108
+ @current_z = 0
109
+ end
110
+ end
111
+
112
+ def set_positions(line)
113
+ @current_x = line.x if line.x.present?
114
+ @current_y = line.y if line.y.present?
115
+ @current_z = line.z if line.z.present?
116
+ if line.e.present?
117
+ @filament_used += @current_e
118
+ @current_e = line.e
119
+ end
120
+ end
121
+
122
+ def set_current_position(line)
123
+ if line.relative
124
+ @current_x += line.x if line.x.present?
125
+ @current_y += line.y if line.y.present?
126
+ @current_z += line.z if line.z.present?
127
+ @current_e += line.e if line.e.present?
128
+ else
129
+ @current_x = line.x if line.x.present?
130
+ @current_y = line.y if line.y.present?
131
+ @current_z = line.z if line.z.present?
132
+ @current_e = line.e if line.e.present?
133
+ end
134
+ end
135
+
136
+ def set_limits(line)
137
+ if line.extrusion_move?
138
+ if line.x.present? && !line.x.zero?
139
+ @x_min = @current_x if @current_x < @x_min
140
+ @x_max = @current_x if @current_x > @x_max
141
+ end
142
+ if line.y.present? && !line.y.zero?
143
+ @y_min = @current_y if @current_y < @y_min
144
+ @y_max = @current_y if @current_y > @y_max
145
+ end
146
+ end
147
+ if line.z.present?
148
+ @z_min = @current_z if @current_z < @z_min
149
+ @z_max = @current_z if @current_z > @z_max
150
+ end
151
+ end
152
+
153
+ def set_variables
154
+ @x_travel = 0
155
+ @y_travel = 0
156
+ @z_travel = 0
157
+ @current_x = 0
158
+ @current_y = 0
159
+ @current_z = 0
160
+ @current_e = 0
161
+ @x_min = 999999999
162
+ @y_min = 999999999
163
+ @z_min = 0
164
+ @x_max = -999999999
165
+ @y_max = -999999999
166
+ @z_max = -999999999
167
+ @filament_used = 0
168
+ @layers = 0
169
+ end
170
+
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,59 @@
1
+ require 'rint_core/driver'
2
+ require 'active_support/configurable'
3
+
4
+ module RintCore
5
+ class Printer
6
+ include RintCore::Driver
7
+ include ActiveSupport::Configurable
8
+
9
+ # Callbacks are typically given a string argument, usually the current line
10
+ config_accessor :port, :baud, :callbacks, :error_response, :debug_response,
11
+ :online_response, :good_response, :temperature_response,
12
+ :resend_response, :encoding, :sleep_time, :wait_period,
13
+ :read_timeout, :long_sleep
14
+
15
+ self.port = "/dev/ttyACM0"
16
+ self.baud = 115200
17
+ self.callbacks = {}
18
+ self.error_response = 'Error'
19
+ self.debug_response = 'DEBUG_'
20
+ self.online_response = ['start','Grbl']
21
+ self.good_response = ['ok']
22
+ self.temperature_response = 'T:'
23
+ self.resend_response = ['rs','resend']
24
+ self.encoding = 'us-ascii'
25
+ self.sleep_time = 0.001
26
+ self.wait_period = 0
27
+ self.read_timeout = 0
28
+ self.long_sleep = 0.25
29
+
30
+ attr_reader :last_line_received, :main_queue, :queue_index, :resend_from, :machine_history, :full_history
31
+
32
+ def initialize(auto_connect = false)
33
+ initialize_driver
34
+ connect! if auto_connect
35
+ end
36
+
37
+ def time_from_start
38
+ @start_time ||= Time.now
39
+ secs = Time.now - @start_time
40
+ [[60, :seconds], [60, :minutes], [24, :hours], [1000, :days]].map{ |count, name|
41
+ if secs > 0
42
+ secs, n = secs.divmod(count)
43
+ "#{n.to_i} #{name}"
44
+ end
45
+ }.compact.reverse.join(' ')
46
+ end
47
+
48
+ class << self
49
+ def baud_rates
50
+ [2400, 9600, 19200, 38400, 57600, 115200, 250000]
51
+ end
52
+
53
+ def is_port?(port)
54
+ port.present? && File.exist?(port) && File.new(port).isatty
55
+ end
56
+ end
57
+
58
+ end
59
+ end