Basics

6249349954_bff0ecc9f2_z.jpg

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

6248821477_15aac886cd_z.jpg

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

6249350092_9ddb8439d8_z.jpg

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 … ).

The Robot also converts the cartesian coordinates (in the machine coordinate system) into actuator specific coordinates, this transform is done in the arm solution, which takes machine coordinates and spits out actuator coordinates. In the case of a simple Cartesian mechanical system this is a one to one transform.

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

Planner

6249350188_90566e9a2e_z.jpg

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

6249350300_b53acde8ed_b.jpg

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.