rintcore 0.0.3 → 0.0.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 CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 25584e4760c4e1b347a2bd718be2d15ea3e6a3a8
4
- data.tar.gz: dc98357e1b8995492a12f18622dbfae6b0bab95b
5
- SHA512:
6
- metadata.gz: 630a045a5a1c463447b5d84c712bf313b9c0a14d080c1386d7b687963b7364ab36c0b023a079c4a8294094e9cdb7a2c7634087615a9ac5f66a4be021a9edc48a
7
- data.tar.gz: 679a641143bc7ffe4e3d95e80448bb575c45c16e5b8bbcbbac3729ce27c3bca07186cdf6eb7e7be24f4a98dd52638490f08e3855cc3105a6a3f65e64b4a780f6
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f672b74c95d07cfb62eb006d5209065f57c51bd2
4
+ data.tar.gz: 64b07a334627117937c29c59d863b0371df74160
5
+ SHA512:
6
+ metadata.gz: 874f9595f51204151351828eedcb403d679d608a8b04b611283a476a75872fe8711da16c4b25031628278425ce85d96080a69afadf0acff08622da80cb58d269
7
+ data.tar.gz: 84da65e8d7d6ed60c02c06e4b3dcba01d9ce3cd9479961105d0690769d19d2006c477f471069b9362c9958a8cd6f0dcafcb74d7b2a38ad18b4a7f2c7e540145e
data/.gitignore CHANGED
@@ -15,4 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- .ruby-version
18
+ .ruby-version
19
+ profiling.txt
data/README.md CHANGED
@@ -21,7 +21,8 @@ printer.port = '/dev/ttyUSB0' # Set to /dev/ttyACM0 by default
21
21
  printer.baud = 250000 # Set to 115200 by default
22
22
  printer.callbacks[:temperature] = Proc.new { |line| puts(line) }
23
23
  printer.connect!
24
- printer.start_print gcode```
24
+ printer.start_print gcode
25
+ ```
25
26
 
26
27
  ### TODO
27
28
  Documentation and spec writing.
data/bin/rintcore CHANGED
@@ -1,4 +1,7 @@
1
1
  #!env ruby
2
+ lib = File.expand_path('../../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
2
5
  require 'rubygems'
3
6
  require 'rint_core/cli'
4
7
 
data/lib/rint_core.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "rint_core/version"
2
2
 
3
+ # A collection of classes and modules for parsing, analyzing and sending GCode to a RepRap 3D printer.
3
4
  module RintCore
4
- # Your code goes here...
5
+
5
6
  end
data/lib/rint_core/cli.rb CHANGED
@@ -5,41 +5,54 @@ require 'thor'
5
5
  require 'active_support/core_ext/object/blank'
6
6
 
7
7
  module RintCore
8
+ # Provides command line interfaces for interacting with RintCore's classes.
8
9
  class Cli < Thor
9
10
  map '-a' => :analyze, '-p' => :print
10
11
 
11
12
  desc 'analyze FILE', 'Get statistics about the given GCode file.'
12
13
  method_option :decimals, default: 2, aliases: '-d', type: :numeric, desc: 'The number of decimal places given for measurements.'
14
+ # Analyze the given file, also sets the @object instance variable to a {RintCore::GCode::Object}.
15
+ # @param file [String] path to a GCode file on the system.
16
+ # @return [String] statistics about the given GCode file.
13
17
  def analyze(file)
14
18
  unless RintCore::GCode::Object.is_file?(file)
15
19
  puts "Non-exsitant file: #{file}"
16
20
  exit
17
21
  end
18
22
  @object = RintCore::GCode::Object.new(RintCore::GCode::Object.get_file(file))
23
+
24
+ unless @object.present?
25
+ puts "Non-GCode or empty file: #{file}"
26
+ exit
27
+ end
28
+
19
29
  decimals = options[:decimals]
20
30
  decimals ||= 2
21
- output = <<EOS
22
- Dimensions:
23
- \tX: #{@object.x_min.round(decimals)} - #{@object.x_max.round(decimals)} (#{@object.width.round(decimals)}mm)
24
- \tY: #{@object.y_min.round(decimals)} - #{@object.y_max.round(decimals)} (#{@object.depth.round(decimals)}mm)
25
- \tZ: #{@object.z_min.round(decimals)} - #{@object.z_max.round(decimals)} (#{@object.height.round(decimals)}mm)
26
- Total Travel:
27
- \tX: #{@object.x_travel.round(decimals)}mm
28
- \tY: #{@object.y_travel.round(decimals)}mm
29
- \tZ: #{@object.z_travel.round(decimals)}mm
30
- Filament used: #{@object.filament_used.round(decimals)}mm
31
- Number of layers: #{@object.layers}
32
- #{@object.raw_data.length} lines / #{@object.lines.length} commands
33
- EOS
34
- puts output
31
+
32
+ puts "Dimensions:\n"\
33
+ "\tX: #{@object.x_min.round(decimals)} - #{@object.x_max.round(decimals)} (#{@object.width.round(decimals)}mm)\n"\
34
+ "\tY: #{@object.y_min.round(decimals)} - #{@object.y_max.round(decimals)} (#{@object.depth.round(decimals)}mm)\n"\
35
+ "\tZ: #{@object.z_min.round(decimals)} - #{@object.z_max.round(decimals)} (#{@object.height.round(decimals)}mm)\n"\
36
+ "Total Travel:\n"\
37
+ "\tX: #{@object.x_travel.round(decimals)}mm\n"\
38
+ "\tY: #{@object.y_travel.round(decimals)}mm\n"\
39
+ "\tZ: #{@object.z_travel.round(decimals)}mm\n"\
40
+ "Filament used:\n"
41
+ @object.filament_used.each_with_index do |filament,extruder|
42
+ puts "\tExtruder #{extruder+1}: #{filament.round(decimals)}mm"
43
+ end
44
+ puts "Number of layers: #{@object.layers}\n"\
45
+ "#{@object.raw_data.length} lines / #{@object.lines.length} commands"
35
46
  end
36
47
 
37
48
  desc 'print FILE', 'Print the given GCode file.'
38
49
  method_option :port, aliases: '-p', type: :string, desc: 'The port that the printer is connected to.'
39
50
  method_option :baud, aliases: '-b', type: :numeric, desc: 'The baud rate at which the printer communicates at.'
40
51
  method_option :loud, aliases: '-l', default: false, type: :boolean, desc: 'Output additional info (temperature, progress, etc.)'
52
+ # Analyzes, then prints the given file.
53
+ # @param file [String] path to a GCode file on the system.
54
+ # @return [String] value of the disconnect callback in this function.
41
55
  def print(file)
42
- analyze(file)
43
56
  port = options[:port]
44
57
  baud = options[:baud]
45
58
  baud = baud.to_i unless baud.blank?
@@ -56,6 +69,7 @@ EOS
56
69
  baud = baud.to_i unless baud.blank?
57
70
  baud = nil unless RintCore::Printer.baud_rates.include?(baud)
58
71
  end
72
+ analyze(file)
59
73
  printer = RintCore::Printer.new
60
74
  printer.port = port
61
75
  printer.baud = baud
@@ -72,7 +86,6 @@ EOS
72
86
  until printer.online?
73
87
  sleep(printer.long_sleep)
74
88
  end
75
- start_time = Time.now
76
89
  printer.start_print(@object)
77
90
  while printer.printing?
78
91
  printer.send_now(RintCore::GCode::Codes::GET_EXT_TEMP)
@@ -5,6 +5,7 @@ require 'rint_core/driver/queueing'
5
5
  require 'rint_core/driver/operations'
6
6
 
7
7
  module RintCore
8
+ # Conatians the elements of the printer driver.
8
9
  module Driver
9
10
  include RintCore::Driver::OperatingSystem
10
11
  include RintCore::Driver::State
@@ -12,6 +13,7 @@ module RintCore
12
13
  include RintCore::Driver::Queueing
13
14
  include RintCore::Driver::Operations
14
15
 
16
+ # Calls the initialization functions of the submodules in the correct order
15
17
  def initialize_driver
16
18
  initialize_state
17
19
  initialize_queueing
@@ -1,6 +1,18 @@
1
1
  module RintCore
2
2
  module Driver
3
+ # Utilities for performing OS level tasks
3
4
  module OperatingSystem
5
+
6
+ # Return name of OS as a symbol.
7
+ # @return [Symbol] name of OS as symbol.
8
+ def get_os
9
+ return :linux if /linux/ =~ RUBY_PLATFORM
10
+ return :mac if /darwin/ =~ RUBY_PLATFORM
11
+ return :windows if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
12
+ return :unknown
13
+ end
14
+
15
+ private
4
16
  def control_ttyhup(port, disable_hup)
5
17
  if get_os == :linux
6
18
  if disable_hup
@@ -18,13 +30,6 @@ module RintCore
18
30
  def disable_hup(port)
19
31
  control_ttyhup(port, false)
20
32
  end
21
-
22
- def get_os
23
- return :linux if /linux/ =~ RUBY_PLATFORM
24
- return :mac if /darwin/ =~ RUBY_PLATFORM
25
- return :windows if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
26
- return :unknown
27
- end
28
33
  end
29
34
  end
30
35
  end
@@ -5,8 +5,11 @@ require 'active_support/core_ext/object/blank'
5
5
 
6
6
  module RintCore
7
7
  module Driver
8
+ # Provides the raw functionality of the printer.
8
9
  module Operations
9
10
 
11
+ # Connects to the printer.
12
+ # @return [Undefined] returns the value of the connect callback.
10
13
  def connect!
11
14
  return false if connected?
12
15
  if config.port.present? && config.baud.present?
@@ -20,6 +23,8 @@ module RintCore
20
23
  end
21
24
  end
22
25
 
26
+ # Disconnects to the printer.
27
+ # @return [Undefined] returns the value of the disconnect callback.
23
28
  def disconnect!
24
29
  if connected?
25
30
  if @listening_thread
@@ -36,29 +41,45 @@ module RintCore
36
41
  config.callbacks[:disconnect].call if config.callbacks[:disconnect].present?
37
42
  end
38
43
 
44
+ # Resets the printer.
45
+ # @return [false] if not connected.
46
+ # @return [1] if printer was reset.
39
47
  def reset!
48
+ return false unless connected?
40
49
  @connection.dtr = 0
41
50
  sleep(config.long_sleep)
42
51
  @connection.dtr = 1
43
52
  end
44
53
 
54
+ # Pauses printing.
55
+ # @return [Undefined] returns the value of the pause callback.
45
56
  def pause!
46
57
  return false unless printing?
47
58
  @paused = true
48
- not_printing!
49
- @print_thread.join
59
+ until @print_thread.alive?
60
+ sleep(config.sleep_time)
61
+ end
62
+ #@print_thread.join
50
63
  @print_thread = nil
64
+ not_printing!
51
65
  config.callbacks[:pause].call if config.callbacks[:pause].present?
52
66
  end
53
67
 
68
+ # Resumes printing.
69
+ # @return [Undefined] returns the value of the resume callback.
54
70
  def resume!
55
71
  return false unless paused?
56
- paused!
72
+ @paused = false
57
73
  printing!
58
74
  @print_thread = Thread.new{print!()}
59
75
  config.callbacks[:resume].call if config.callbacks[:resume].present?
60
76
  end
61
77
 
78
+ # Sends the given command to the printer, if printing, will send command after print completion.
79
+ # @param command [String] the command to send to the printer.
80
+ # @param wait [Fixnum] number of times to sleep ({RintCore::Printer.sleep_time}).
81
+ # @param priority [Boolean] defines if command is a priority.
82
+ # @todo finalize return value.
62
83
  def send(command, wait = 0, priority = false)
63
84
  if online?
64
85
  if printing?
@@ -80,10 +101,18 @@ module RintCore
80
101
  end
81
102
  end
82
103
 
104
+ # Sends command to the printer immediately by placing it in the priority queue.
105
+ # @see send
83
106
  def send_now(command, wait = 0)
84
107
  send(command, wait, true)
85
108
  end
86
109
 
110
+ # Starts a print.
111
+ # @param data [RintCore::GCode::Object] prints the given object.
112
+ # @param data [Array] executes the each command in the array.
113
+ # @param start_index [Fixnum] starts printing from the given index (used by {#pause!} and {#resume!}).
114
+ # @return [false] if printer isn't ready to print or already printing.
115
+ # @return [true] if print has been started.
87
116
  def start_print(data, start_index = 0)
88
117
  return false unless can_print?
89
118
  data = data.lines if data.class == RintCore::GCode::Object
@@ -104,7 +133,7 @@ private
104
133
  def initialize_operations
105
134
  @connection = nil
106
135
  @listening_thread = nil
107
- @printing_thread = nil
136
+ @print_thread = nil
108
137
  @full_history = []
109
138
  end
110
139
 
@@ -121,6 +150,7 @@ private
121
150
  config.callbacks[:start].call if config.callbacks[:start].present?
122
151
  while online? && printing? do
123
152
  advance_queue
153
+ return true if paused?
124
154
  end
125
155
  @print_thread.join
126
156
  @print_thread = nil
@@ -3,8 +3,10 @@ require 'active_support/core_ext/object/blank'
3
3
 
4
4
  module RintCore
5
5
  module Driver
6
+ # Handles the parsing of printer responses and formats commands sent to the printer.
6
7
  module Parsing
7
8
 
9
+ private
8
10
  def format_command(command)
9
11
  (command.strip + "\n").split(RintCore::GCode::Codes::COMMENT_SYMBOL).first.encode(config.encoding)
10
12
  end
@@ -23,9 +25,9 @@ module RintCore
23
25
  return :error if line.include?(config.error_response)
24
26
  return :debug if line.include?(config.debug_response)
25
27
  return :online if line.start_with?(*config.online_response)
26
- return :valid if line.start_with?(*config.good_response) && !line.include?(config.temperature_response)
27
- return :temperature_response if line.start_with?(*config.good_response) && line.include?(config.temperature_response)
28
- return :temperature if line.include?(config.temperature_response)
28
+ return :valid if line.start_with?(*config.good_response) && !line.include?(*config.temperature_response)
29
+ return :temperature_response if line.start_with?(*config.good_response) && line.include?(*config.temperature_response)
30
+ return :temperature if line.include?(*config.temperature_response)
29
31
  return :resend if line.start_with?(*config.resend_response)
30
32
  return :invalid
31
33
  end
@@ -3,6 +3,7 @@ require 'active_support/core_ext/object/blank'
3
3
 
4
4
  module RintCore
5
5
  module Driver
6
+ # Controls the print queue and manages the sending of commands while printing.
6
7
  module Queueing
7
8
 
8
9
  private
@@ -49,17 +50,14 @@ private
49
50
  end
50
51
 
51
52
  def run_priority_queue
52
- unless @priority_queue.blank?
53
- send!(@priority_queue.shift)
54
- # clear_to_send!
55
- end
53
+ send!(@priority_queue.shift) if @priority_queue.present?
56
54
  end
57
55
 
58
56
  def run_main_queue
59
57
  if !paused? && @queue_index < @main_queue.length
60
58
  current_line = @main_queue[@queue_index]
61
- current_line = current_line.to_s unless current_line.class == String
62
- unless current_line.blank?
59
+ current_line = apply_multipliers(current_line) unless current_line.class == String
60
+ if current_line.present?
63
61
  send!(current_line, @line_number, true)
64
62
  @line_number += 1
65
63
  end
@@ -68,6 +66,13 @@ private
68
66
  end
69
67
  end
70
68
 
69
+ def apply_multipliers(line)
70
+ line.speed_multiplier = config.speed_multiplier if config.speed_multiplier.present?
71
+ line.extrusion_multiplier = config.extrusion_multiplier if config.extrusion_multiplier.present?
72
+ line.travel_multiplier = config.travel_multiplier if config.travel_multiplier.present?
73
+ line.to_s
74
+ end
75
+
71
76
  end
72
77
  end
73
78
  end
@@ -3,32 +3,35 @@ require 'active_support/core_ext/object/blank'
3
3
 
4
4
  module RintCore
5
5
  module Driver
6
+ # keeps track of the driver's state
6
7
  module State
7
8
 
9
+ # Checks if the printer can start a print.
10
+ # @return [Boolean] true if printer is ready to print, false otherwise.
8
11
  def can_print?
9
12
  connected? && online? && !printing?
10
13
  end
11
14
 
15
+ # Checks if printer is connected.
16
+ # @return [Boolean] true if serial port connection is present, false otherwise.
12
17
  def connected?
13
18
  @connection.present?
14
19
  end
15
20
 
16
- def clear_to_send?
17
- @clear && online?
18
- end
19
-
20
- def listen_can_continue?
21
- !@stop_listening && connected?
22
- end
23
-
21
+ # Checks if the printer is online.
22
+ # @return [Boolean] true if online, false otherwise.
24
23
  def online?
25
24
  connected? && @online
26
25
  end
27
26
 
27
+ # Checks if printing is paused.
28
+ # @return [Boolean] true if pause, false otherwise.
28
29
  def paused?
29
30
  @paused
30
31
  end
31
32
 
33
+ # Checks if the printer is currently printing.
34
+ # @return [Boolean] true if printing, false otherwise.
32
35
  def printing?
33
36
  @printing
34
37
  end
@@ -43,10 +46,18 @@ private
43
46
  @stop_listening = false
44
47
  end
45
48
 
49
+ def clear_to_send?
50
+ @clear && online?
51
+ end
52
+
46
53
  def clear_to_send!
47
54
  @clear = true
48
55
  end
49
56
 
57
+ def listen_can_continue?
58
+ !@stop_listening && connected?
59
+ end
60
+
50
61
  def not_clear_to_send!
51
62
  @clear = false
52
63
  end
@@ -1,5 +1,6 @@
1
1
  require 'rint_core/g_code/codes'
2
2
  module RintCore
3
+ # Contains classes for analyzing and parsing GCode.
3
4
  module GCode
4
5
 
5
6
  end
@@ -1,49 +1,105 @@
1
+ #require 'active_support/core_ext/string/inflections'
2
+
1
3
  module RintCore
2
4
  module GCode
5
+ # Contains GCodes.
3
6
  module Codes
7
+ # Do a rapid move.
4
8
  RAPID_MOVE = 'G0'
9
+ # Do a move at the given or previously given acceleration (F).
5
10
  CONTROLLED_MOVE = 'G1'
11
+ # Pause for (P) a given number of milliseconds.
6
12
  DWELL = 'G4'
13
+ # Set head offset (for multiple extruders).
7
14
  HEAD_OFFSET = 'G10'
15
+ # Set units in following commands to be imperial.
8
16
  USE_INCHES = 'G20'
17
+ # Set units in following commands to be metric (default).
9
18
  USE_MILLIMETRES = 'G21'
19
+ # Home axes.
10
20
  HOME = 'G28'
21
+ # Set following commands to use absolute coordinates.
11
22
  ABS_POSITIONING = 'G90'
23
+ # Set following commands to use relative coordinates.
12
24
  REL_POSITIONING = 'G91'
25
+ # Set current position.
13
26
  SET_POSITION = 'G92'
27
+ # Finish moves, then shutdown (reset required to wake machine).
14
28
  STOP = 'M0'
29
+ # Finish moves the shutdown (sending commands will wake machine).
15
30
  SLEEP = 'M1'
31
+ # Enable motors.
16
32
  ENABLE_MOTORS = 'M17'
33
+ # Disable motors.
17
34
  DISABLE_MOTORS = 'M18'
35
+ # List contents of SD card.
18
36
  LIST_SD = 'M20'
37
+ # Initialize SD card (needed if card wasn't present at bootup).
19
38
  INIT_SD = 'M21'
39
+ # Release SD (safe removal of SD).
20
40
  RELEASE_SD = 'M22'
41
+ # Select SD file (require to print from SD).
21
42
  SELECT_SD_FILE = 'M23'
43
+ # Print selected file from SD (requires file to be selected).
22
44
  START_SD_PRINT = 'M24'
45
+ # Pause printing from SD card.
23
46
  PAUSE_SD_PRINT = 'M25'
47
+ # Set SD position in bytes.
24
48
  SET_SD_POSITION = 'M26'
49
+ # Report SD printing status.
25
50
  SD_PRINT_STATUS = 'M27'
51
+ # Write following GCodes to given file (requires 8.3 file name).
26
52
  START_SD_WRITE = 'M28'
53
+ # Signal end of SD write, following commands will be executed as normal.
27
54
  STOP_SD_WRITE = 'M29'
55
+ # Power on.
28
56
  POWER_ON = 'M80'
57
+ # Power off.
29
58
  POWER_OFF = 'M81'
59
+ # Set extrusion units in following commands to absolute coordinates.
30
60
  ABS_EXT_MODE = 'M82'
61
+ # Set extrusion units in following commands to relative coordinates.
31
62
  REL_EXT_MODE = 'M83'
63
+ # Trun off powered holding of motors when idle.
32
64
  IDLE_HOLD_OFF = 'M84'
65
+ # Set Extruder tmeperature and return control to host.
33
66
  SET_EXT_TEMP_NW = 'M104'
67
+ # Report temperatures
34
68
  GET_EXT_TEMP = 'M105'
69
+ # Trun fans on to given value (S, 0-255).
35
70
  FAN_ON = 'M106'
71
+ # Turn off fans
36
72
  FAN_OFF = 'M107'
73
+ # Set extruder temperature and wait for it to reach temperature.
37
74
  SET_EXT_TEMP_W = 'M109'
75
+ # Reset the line number for the following commands.
38
76
  SET_LINE_NUM = 'M110'
77
+ # Emergency stop.
39
78
  EMRG_STOP = 'M112'
79
+ # Report position.
40
80
  GET_POSITION = 'M114'
81
+ # Report firmware details.
41
82
  GET_FW_DETAILS = 'M115'
83
+ # Wait for temperature (all extruders and bed) to reach the temerature they were set to.
42
84
  WIAT_FOR_TEMP = 'M116'
43
- # ... Left out codes that probably won't be used
85
+ # Set bed temperature and return control to host.
44
86
  SET_BED_TEMP_NW = 'M140'
87
+ # Set bed temperature and wait for it to reach temperature.
45
88
  SET_BED_TEMP_W = 'M190'
89
+ # Comment symbol
90
+ # @todo Move this to a configurable option.
46
91
  COMMENT_SYMBOL = ';'
92
+
93
+ # An array of the constant's values.
94
+ # @return [Array] of GCode commands.
95
+ # REMOVED: major performance issues
96
+ # def available_commands
97
+ # commands = []
98
+ # RintCore::GCode::Codes.constants.each do |constant|
99
+ # commands << ('RintCore::GCode::Codes::'+constant.to_s).constantize
100
+ # end
101
+ # commands
102
+ # end
47
103
  end
48
104
  end
49
105
  end