Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
queue-refactor [2017/01/25 18:35]
arthur
queue-refactor [2017/09/01 22:29]
77.100.94.53
Line 9: Line 9:
 == The problem with the queue == The problem with the queue
  
-So essentially,​ Smoothie was originally coded with no consideration whatsoever for RAM usage. Yes. Sue me.+So essentially,​ Smoothie was originally coded with no consideration whatsoever for RAM usage. Yes. Sue me.
  
 It ended up not too bad, but still very very far from optimal. It ended up not too bad, but still very very far from optimal.
Line 15: Line 15:
 I guess we can start by explaining the problem the queue tries to solve before explaining the problem with the way we currently do it. I guess we can start by explaining the problem the queue tries to solve before explaining the problem with the way we currently do it.
  
-A pretty good explanation can be found here : [[howitworks]]+A pretty good explanation can be found here:​ [[howitworks]]
  
 === How it now works === How it now works
  
-In short, when we get say, a G-code for a movement, the following happens ( oversimplified ) : +In short, when we get say, a G-code for a movement, the following happens ( oversimplified ) : 
  
 * Robot interprets the G-code and makes a line from it * Robot interprets the G-code and makes a line from it
Line 36: Line 36:
 * Go to first step * Go to first step
  
-Now what this means for a module is there are two different processes/​loops : +Now what this means for a module is there are two different processes/​loops : 
 * The one in which you receive an instruction * The one in which you receive an instruction
 * The one in which you have to execute an instruction * The one in which you have to execute an instruction
Line 94: Line 94:
 Then when the time comes, they get that information back. Then when the time comes, they get that information back.
  
-This has so many advantages : +This has so many advantages :
 * Much lower RAM usage * Much lower RAM usage
 * Can be about as simple to the coder as we do now * Can be about as simple to the coder as we do now
Line 100: Line 100:
 * Fixed-size ( in bytes not Blocks ) Queue for **all** the data ( including non-movement data ), for easier RAM management * Fixed-size ( in bytes not Blocks ) Queue for **all** the data ( including non-movement data ), for easier RAM management
  
-Here is the proposed format for the new Blocks ( now called "​Actions"​ to differentiate them from the movement Blocks ( which become just another kind of Action ) ) : +Here is the proposed format for the new Blocks ( now called "​Actions"​ to differentiate them from the movement Blocks ( which become just another kind of Action ) ) :
  
 * 1 byte : Owner module ID * 1 byte : Owner module ID
-* 1 byte : Length ​in bytes <​kbd>​n</​kbd>​+* 1 byte : Length ​in bytes <​kbd>​n</​kbd>​
 * <​kbd>​n</​kbd>​ bytes : Data * <​kbd>​n</​kbd>​ bytes : Data
  
 The queue is composed of a series of those Actions. When a module tries to add an Action to the Queue, and the Queue does not have enough room, we wait until there is room ( similar to what the current movement queue does ). The queue is composed of a series of those Actions. When a module tries to add an Action to the Queue, and the Queue does not have enough room, we wait until there is room ( similar to what the current movement queue does ).
  
-Example queue ( random non-real-life actions ) : +Example queue ( random non-real-life actions ) : 
  
 ||~ Byte ||~ Length ||~ Value ||~ Explanation || ||~ Byte ||~ Length ||~ Value ||~ Explanation ||
-|| 0 || uint8 || 2 || Action owner ID 2 ​: Laser ​module ||+|| 0 || uint8 || 2 || Action owner ID 2 Laser module ||
 || 1 || uint8 || 1 || 1 byte long Action || || 1 || uint8 || 1 || 1 byte long Action ||
 || 2 || uint8 || 127 || Laser module understands this as : set laser power to 50% || || 2 || uint8 || 127 || Laser module understands this as : set laser power to 50% ||
 || 3 || uint8 || 5 || Action owner ID 5 : Extruder module || || 3 || uint8 || 5 || Action owner ID 5 : Extruder module ||
 || 4 || uint8 || 1 || 1 byte long Action || || 4 || uint8 || 1 || 1 byte long Action ||
-|| 5 || uint8 || 3 || Extruder module understands this as : Extruder ​action ID 3 : do ​unretract ​ ||+|| 5 || uint8 || 3 || Extruder module understands this as : Extruder ​action ID 3 : do unretract ​ ||
 || 6 || uint8 || 5 || Action owner ID 5 : Extruder module || || 6 || uint8 || 5 || Action owner ID 5 : Extruder module ||
 || 7 || uint8 || 3 || 3 bytes long Action || || 7 || uint8 || 3 || 3 bytes long Action ||
Line 143: Line 143:
 * When there is enough room in the Queue, the Action is added * When there is enough room in the Queue, the Action is added
  
-And it sleeps there for a while, until, in another context : +And it sleeps there for a while, until, in another context :
  
 * All Actions in the queue have been executed up to our Action * All Actions in the queue have been executed up to our Action
Line 163: Line 163:
 This is what <​kbd>​ack-grep :​on_gcode_execute *</​kbd>​ gives us :  This is what <​kbd>​ack-grep :​on_gcode_execute *</​kbd>​ gives us : 
  
-[[code]]+<code>
 src/​modules/​robot/​Stepper.cpp src/​modules/​robot/​Stepper.cpp
 112:void Stepper::​on_gcode_execute(void *argument) 112:void Stepper::​on_gcode_execute(void *argument)
Line 180: Line 180:
 src/​libs/​Module.cpp src/​libs/​Module.cpp
 20:    &​Module::​on_gcode_execute,​ 20:    &​Module::​on_gcode_execute,​
-[[/code]]+</code>
  
-So now, per module, here is what needs to change : +So now, per module, here is what needs to change :
  
 === Planner === Planner
Line 194: Line 194:
 What we have now :  What we have now : 
  
-[[code]]+<code>
 block = queue->​recycle_old_block() block = queue->​recycle_old_block()
 set all of the block'​s properties set all of the block'​s properties
 mark the block as complete mark the block as complete
-[[/code]]+</code>
  
 What we would do in action queue What we would do in action queue
  
-[[code]]+<code>
 block = new Block(); block = new Block();
 set all of the block'​s properties set all of the block'​s properties
 queue->​add_action(the block'​s data) queue->​add_action(the block'​s data)
-[[/code]]+</code>
  
 === Stepper === Stepper
Line 222: Line 222:
 As with Stepper, SlowTicker is another example of a place where <​kbd>​on_gcode_execute</​kbd>​ is used uselessly As with Stepper, SlowTicker is another example of a place where <​kbd>​on_gcode_execute</​kbd>​ is used uselessly
  
-[[code]]+<code>
 on_gcode_execute{ on_gcode_execute{
  do_stuff  do_stuff
 } }
-[[/code]]+</code>
  
-can here too be replaced with :  +can here too be replaced with :  
-[[code]]+<code>
 on_gcode_received{ on_gcode_received{
  wait_for_queue_to_empty  wait_for_queue_to_empty
  do_stuff  do_stuff
 } }
-[[/code]]+</code>
  
 === Spindle === Spindle
Line 242: Line 242:
 There are only two possible actions ( Spindle ON, Spindle OFF ), and one bit of data ( Spindle Speed ) There are only two possible actions ( Spindle ON, Spindle OFF ), and one bit of data ( Spindle Speed )
  
-So the action data is, for a Spindle OFF event : +So the action data is, for a Spindle OFF event :
  
-* <​kbd>​0x0</​kbd>​ ( 1 byte ​)+* <​kbd>​0x0</​kbd>​ ( 1 byte ​)
  
 For a Spindle ON event :  For a Spindle ON event : 
Line 250: Line 250:
 * <​kbd>​0x1</​kbd>​ ( 1 byte ) * <​kbd>​0x1</​kbd>​ ( 1 byte )
  
-And for a Spindle set speed : +And for a Spindle set speed : 
  
 * <​kbd>​0x2</​kbd>​ ( 1 byte ) * <​kbd>​0x2</​kbd>​ ( 1 byte )
Line 257: Line 257:
 Those are simply added to the action queue [[https://​github.com/​Smoothieware/​Smoothieware/​blob/​edge/​src/​modules/​tools/​spindle/​Spindle.cpp#​L198|Here]] Those are simply added to the action queue [[https://​github.com/​Smoothieware/​Smoothieware/​blob/​edge/​src/​modules/​tools/​spindle/​Spindle.cpp#​L198|Here]]
  
-Then [[https://​github.com/​Smoothieware/​Smoothieware/​blob/​edge/​src/​modules/​tools/​spindle/​Spindle.cpp#​L204|on_gcode_execute]] becomes simply : +Then [[https://​github.com/​Smoothieware/​Smoothieware/​blob/​edge/​src/​modules/​tools/​spindle/​Spindle.cpp#​L204|on_gcode_execute]] becomes simply :
  
-[[code]]+<code>
 on_action_execute( data ){ on_action_execute( data ){
  if( data[0] == 0 ){ turn spindle off }  if( data[0] == 0 ){ turn spindle off }
Line 265: Line 265:
  if( data[[0]|== 2 ){ set spindle speed to (float)data[1-4]] }  if( data[[0]|== 2 ){ set spindle speed to (float)data[1-4]] }
 } }
-[[/code]]+</code>
  
 === TemperatureControl === TemperatureControl
Line 271: Line 271:
 Another one where <​kbd>​on_gcode_execute</​kbd>​ is used uselessly Another one where <​kbd>​on_gcode_execute</​kbd>​ is used uselessly
  
-[[code]]+<code>
 on_gcode_execute{ on_gcode_execute{
  do_stuff  do_stuff
 } }
-[[/code]]+</code>
  
 can here too be replaced with :  can here too be replaced with : 
-[[code]]+<code>
 on_gcode_received{ on_gcode_received{
  wait_for_queue_to_empty  wait_for_queue_to_empty
  do_stuff  do_stuff
 } }
-[[/code]]+</code>
  
 The code to replace is [[https://​github.com/​Smoothieware/​Smoothieware/​blob/​edge/​src/​modules/​tools/​temperaturecontrol/​TemperatureControl.cpp#​L294|here]] The code to replace is [[https://​github.com/​Smoothieware/​Smoothieware/​blob/​edge/​src/​modules/​tools/​temperaturecontrol/​TemperatureControl.cpp#​L294|here]]