Basics

flickr:6249349954

In it's most basic form, the job of Smoothie is to receive G-code commands, and translate those into actual movement for a robot.

This is done in several steps : 

  • The SerialConsole module, reads the serial port ( UART or USB ), and when a line is recognized, it follows it to all modules that asked for it by triggering the on_console_line_received event.
  • The GcodeDispatch module is one of those : it registered for the on_console_line_received event, and is thus called everytime the SerialConsole module triggers it. It takes the new line, and if it recognizes a G-code command, transforms it into a new Gcode object, and triggers the on_gcode_received event.
  • The Robot module listens to this event, and so is then triggered. It uses math to cut the requested move into line segments, and passes those to the Planner module. There they are transformed into Block objects, containing speed, direction and acceleration information. The acceleration profile for the Planner's queue ( list of upcoming Blocks ) is re-computed to take the new Block into account, and finally that Block is added to the queue.
  • The Stepper module itself enters the game whenever there is a Block in the Planner's queue : is composed of two loops : 
    • The stepping loop, which pops new blocks if necessary, and actually sends the step and direction command to the stepper motor drivers to move the motors
    • The acceleration loop, which updates the stepping loop's speed depending on the acceleration profile for this block

Now let's get into more detail for each part : 

GcodeDispatch

flickr:6248821477

It is interesting to note that here we are interested only in G-code commands, but the on_console_line_received event actually gets called with any new line, to any module that registered for it ( see Kernel, Module and the Module example ). This can for example be used to handle command-line like instructions.

The Gcode object is just a wrapper around the actual string, it just provides helper function to retrieve values from that string.

Robot

flickr:6249350092

Again here we are interested only in movement G-codes, but any module that registers for the on_gcode_received event will be called with that G-code and gets a chance to use it. Even this module ( Robot ) actually recognizes not only movement G-codes, but also mode changing G-codes ( absolute/relative, inch/millimeter etc … ).

However, if you are coding a new module, you are probably more interested in the on_gcode_execute event which is triggered when the move actually happens ( when the corresponding Block in the queue is about to be executed ), than in this event, which is only for when the command is received.

The segment cutting part is a port of grbl, more specifically, chamnit's ameliorations to edge.

Planner

flickr:6249350188

To the contrary of previous module-to-module transfer, we did not here use an event call/even handler. This is because the new line segment the Planner receives really only matters for the Planner, so an event call here would be superfluous. However if you have an use case where plugging in here would have some sense, just ask.

Again here, the math-heavy acceleration curves planning part is a port of grbl, more specifically, chamnit's ameliorations to edge.

At the end here, we add the new Block to the queue. Now the goal of this is for the Stepper to use this Block and move the stepper motors according to it. But we don't need to call the Stepper to tell it to step this Block : it is probably busy stepping a Block we previously added to the queue. We just push the Block to the top of the queue, and it will be executed by the Stepper when it reaches the bottom of the queue because all of the previous Blocks have been executed.

Stepper

flickr:6249350300

So the first, most important loop in the Stepper module is the stepping loop. It is the one that actually makes the stepper motor move. It also if necessary gets a new Block from the Planner's queue when it has finished stepping the previous one.

This is the very speed-critical part of Smoothie : everything is done using integer math, and the speed here determines the maximum speed at which the robot can move. At the time of this writing, Smoothie is comfortable with stepping speeds of up to 110kHz, which is much higher than what most uses require.

The other loop is the acceleration loop. The work of the Planner is done for this loop : depending on where we are inside the current Block/line segment, it raises or lowers the current stepping speed ( the speed of the previous loop ), thus accelerating or decelerating.

If any of this is not clear enough or if you need precisions, please don't hesitate to contact.