Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added rudimentary support for delta printers #14

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
16f56d1
Added Configuration Parameters for Delta printers from Modified Marli…
armageddon421 Apr 24, 2013
7ad0730
Added variable for the calculated delta coordinates.
armageddon421 Apr 24, 2013
c686a41
Added calculate_delta, used in prepare_move
armageddon421 Apr 24, 2013
add2998
Added square helper function
armageddon421 Apr 24, 2013
a6848e5
Implemented slicing of the movement
armageddon421 Apr 24, 2013
f4dee8f
Added #ifdef to all changes so the code could be merged back
armageddon421 Apr 24, 2013
90aba45
Added define for Quick Homing
armageddon421 Apr 24, 2013
051bca2
Home all axis also true if all three axis are specified in G28
armageddon421 Apr 24, 2013
803d24b
Added quick home (probably dirty)
armageddon421 Apr 24, 2013
fcc0ac7
Check for is_homing before doing delta calculations in prepare_move
armageddon421 Apr 24, 2013
938ddbb
added a comment
armageddon421 Apr 24, 2013
bdbfa9a
Changed some config values to fit a delta printer more closely
armageddon421 Apr 24, 2013
92d8798
Trying to seperate Delta Coordinates from Cartesian
armageddon421 Apr 25, 2013
7de66ea
Adjusted settings to match a given printer
armageddon421 Apr 25, 2013
cf122ee
Set Z Jerk equal to XY in config
armageddon421 Apr 28, 2013
cf1e006
Added comment for IS_DELTA
armageddon421 Apr 29, 2013
818d71f
Enabled plan_set_position in G92 again
armageddon421 Apr 29, 2013
710d4d7
Adjusted plan_set_position to convert to delta coordinates if not homing
armageddon421 Apr 29, 2013
fcc2b85
Changed configuration back to original values, left quck_home added
armageddon421 Apr 29, 2013
1477add
Added example configuration for delta printers.
armageddon421 Apr 29, 2013
ac606b8
Cleaned up and added #ifdef to the delta variable
armageddon421 Apr 29, 2013
20ecbe6
init_configuration_cartesian.h is now the example configuration for "…
armageddon421 Apr 30, 2013
431d9db
Changed Z-Homing-Bounce to be the same as XY for Deltas
armageddon421 Apr 30, 2013
507d91c
Fixed plan_set_position for delta printers.
armageddon421 Apr 30, 2013
fd5049a
Added M208 to set delta axis offsets.
armageddon421 May 4, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions src/gcode_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,33 @@ static int gcode_process_command()
feedrate = 0;
is_homing = 1;

home_all_axis = !((has_code(axis_codes[0])) || (has_code(axis_codes[1])) || (has_code(axis_codes[2])));
home_all_axis = !((has_code(axis_codes[0])) || (has_code(axis_codes[1])) || (has_code(axis_codes[2])))
|| ((has_code(axis_codes[0])) && (has_code(axis_codes[1])) && (has_code(axis_codes[2])));


#ifdef QUICK_HOME
if (home_all_axis) // Move all carriages up together until the first endstop is hit.
{
current_position[X_AXIS] = 0;
current_position[Y_AXIS] = 0;
current_position[Z_AXIS] = 0;
printf("from quickhoming\n\r");
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);

destination[X_AXIS] = 3 * pa.x_max_length;
destination[Y_AXIS] = 3 * pa.y_max_length;
destination[Z_AXIS] = 3 * pa.z_max_length;
feedrate = 1.732 * pa.homing_feedrate[X_AXIS]; //1.732 = sqrt(3), but why?
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
st_synchronize();
//endstops_hit_on_purpose(); //seems not to be implemented in this firmware

current_position[X_AXIS] = destination[X_AXIS];
current_position[Y_AXIS] = destination[Y_AXIS];
current_position[Z_AXIS] = destination[Z_AXIS];
}
#endif

if((home_all_axis) || (has_code(axis_codes[X_AXIS])))
homing_routine(X_AXIS);

Expand All @@ -362,6 +387,17 @@ static int gcode_process_command()

if((home_all_axis) || (has_code(axis_codes[Z_AXIS])))
homing_routine(Z_AXIS);


#ifdef IS_DELTA
if(home_all_axis){
current_position[X_AXIS] = 0;
current_position[Y_AXIS] = 0;
current_position[Z_AXIS] = 250;
printf("from after homing\n\r");
plan_set_position(pa.x_max_length, pa.y_max_length, pa.z_max_length, current_position[E_AXIS]);
}
#endif

#ifdef ENDSTOPS_ONLY_FOR_HOMING
enable_endstops(0);
Expand All @@ -385,7 +421,8 @@ static int gcode_process_command()
st_synchronize();

GET_ALL_AXES(current_position,float);
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
printf("from G92\n\r");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This messed up the separation between cartesian and delta coordinate space. The printf was to find out where the change came from, then I just commented the disturber out. I just noticed this mysel and I am changing the plan_set_position function to do the necessary calculations. Also, I will clean up the printfs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really happy with changing the plan_set_position to reacalculate the delta position.
This would only work well for x=y=0, because otherwise the delta calculations would assume wrong xy-positions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'll Ignore the command if x and y are not zero or the current values or something.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that's no good for cartesian setups. It's used quite a lot. Delta users are going to expect the same functionality I guess, but we definitely should not be breaking it for cartesian.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course. Least I can do is add #ifdef. What exactly is it used for?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

G92 is used to set position after manually moving the machine. A number of people with no endstops use it for homing (adjust position by hand or with G1 commands and then issue G92). It's used to restart a partially failed print by setting the last known printer position. It's also used (on E) to set filament position to a known value after changing filament mid-print. Other than the restart function all of these are possible with x=y=0. That limitation on delta would be better than making it a no-op.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm breaking my head over how to avoid incostistencies in behaviour.
If I force it to xy zero and the user entered something other than 0, The
printer will just move to the center with the next G1 X0 Y0 instead of the
set position. If I do the recalculations anyways, the delta coordinate
space might be messed up. If I ignore the command for xy != 0, well
obviously the command is ignored... Which is what the user least expects.
However, if it is really only used to set "sane" positions and not to set
an offset or something, this could maybe used to continue prints - even on
delta printers. Decisions, decisions,...

On Mon, Apr 29, 2013 at 10:21 AM, kliment [email protected] wrote:

In src/gcode_parser.c:

@@ -385,7 +421,8 @@ static int gcode_process_command()
st_synchronize();

                GET_ALL_AXES(current_position,float);
  •               plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
    
  •               printf("from G92\n\r");
    

G92 is used to set position after manually moving the machine. A number of
people with no endstops use it for homing (adjust position by hand or with
G1 commands and then issue G92). It's used to restart a partially failed
print by setting the last known printer position. It's also used (on E) to
set filament position to a known value after changing filament mid-print.
Other than the restart function all of these are possible with x=y=0. That
limitation on delta would be better than making it a no-op.


Reply to this email directly or view it on GitHubhttps://github.com//pull/14/files#r3994832
.

Robert

//plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);

break;
}
Expand Down
86 changes: 64 additions & 22 deletions src/init_configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
//// Calibration variables
//-----------------------------------------------------------------------
// X, Y, Z, E steps per unit
#define _AXIS_STEP_PER_UNIT {80, 80, 3200/0.8,700}
#define _AXIS_STEP_PER_UNIT {29.0909, 29.0909, 29.0909,700}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really happy with the config defaulting to the delta settings. Can you change them back?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want, we can keep the delta version as a different branch. I can try to maintain it, at least for a while.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also add a second configuration file as kind of an example for delta printer configurations.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend making it a separate sample config file that can be copied onto the original one

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I'll do this. So no seperate branch then?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think a second example config file is easier to maintain


#define _AXIS_CURRENT {128, 128, 128, 128, 128}
#define _AXIS_USTEP {3, 3, 3, 3, 3}
Expand All @@ -47,7 +47,7 @@
//-----------------------------------------------------------------------
//The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.
//If your axes are only moving in one direction, make sure the endstops are connected properly.
#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors
//#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors

//If your axes move in one direction ONLY when the endstops are triggered, set [XYZ]_ENDSTOP_INVERT to true here:
#define _X_ENDSTOP_INVERT false
Expand All @@ -56,58 +56,61 @@

//#define ENDSTOPS_ONLY_FOR_HOMING // If defined the endstops will only be used for homing

#define _MIN_SOFTWARE_ENDSTOPS false; //If true, axis won't move to coordinates less than zero.
#define _MIN_SOFTWARE_ENDSTOPS true; //If true, axis won't move to coordinates less than zero.
#define _MAX_SOFTWARE_ENDSTOPS true; //If true, axis won't move to coordinates greater than the defined lengths below.

//-----------------------------------------------------------------------
//// ENDSTOP INPUT ACTIV: 1 --> Active // -1 --> NO ENDSTOP
//-----------------------------------------------------------------------
#define X_MIN_ACTIV 1
#define X_MAX_ACTIV -1
#define X_MIN_ACTIV -1
#define X_MAX_ACTIV 1

#define Y_MIN_ACTIV 1
#define Y_MAX_ACTIV -1
#define Y_MIN_ACTIV -1
#define Y_MAX_ACTIV 1

#define Z_MIN_ACTIV 1
#define Z_MAX_ACTIV -1
#define Z_MIN_ACTIV -1
#define Z_MAX_ACTIV 1

//-----------------------------------------------------------------------
// Disables axis when it's not being used.
//-----------------------------------------------------------------------

#define _DISABLE_X_EN false
#define _DISABLE_Y_EN false
#define _DISABLE_Z_EN true
#define _DISABLE_Z_EN false
#define _DISABLE_E_EN false

//-----------------------------------------------------------------------
// Inverting axis direction
//-----------------------------------------------------------------------
#define _INVERT_X_DIR false
#define _INVERT_Y_DIR false
#define _INVERT_Z_DIR true
#define _INVERT_Z_DIR false
#define _INVERT_E_DIR false

//-----------------------------------------------------------------------
//// HOMING SETTINGS:
//-----------------------------------------------------------------------
// Sets direction of endstops when homing; 1=MAX, -1=MIN
#define X_HOME_DIR -1
#define Y_HOME_DIR -1
#define Z_HOME_DIR -1
#define X_HOME_DIR 1
#define Y_HOME_DIR 1
#define Z_HOME_DIR 1

//Move all axis until the first endstop is hit. Should be enabled for Delta printers.
#define QUICK_HOME

//-----------------------------------------------------------------------
//Max Length for Prusa Mendel, check the ways of your axis and set this Values
//Check the ways of your axis and set these Values
//-----------------------------------------------------------------------
#define _X_MAX_LENGTH 200
#define _Y_MAX_LENGTH 200
#define _Z_MAX_LENGTH 100
#define _X_MAX_LENGTH 700
#define _Y_MAX_LENGTH 700
#define _Z_MAX_LENGTH 700

//-----------------------------------------------------------------------
//// MOVEMENT SETTINGS
//-----------------------------------------------------------------------
#define _MAX_FEEDRATE {400, 400, 2, 45} // (mm/sec)
#define _HOMING_FEEDRATE {1500,1500,120} // (mm/min) !!
#define _MAX_FEEDRATE {400, 400, 400, 45} // (mm/sec)
#define _HOMING_FEEDRATE {2000,2000,2000} // (mm/min) !!
#define _AXIS_RELATIVE_MODES {false, false, false, false}


Expand All @@ -118,9 +121,9 @@
#define _ACCELERATION 1000 // Axis Normal acceleration mm/s^2
#define _RETRACT_ACCELERATION 2000 // Extruder Normal acceleration mm/s^2
#define _MAX_XY_JERK 20.0
#define _MAX_Z_JERK 0.4
#define _MAX_Z_JERK 20.0
#define _MAX_E_JERK 5.0
#define _MAX_ACCELERATION_UNITS_PER_SQ_SECOND {5000,5000,50,5000} // X, Y, Z and E max acceleration in mm/s^2 for printing moves or retracts
#define _MAX_ACCELERATION_UNITS_PER_SQ_SECOND {5000,5000,5000,5000} // X, Y, Z and E max acceleration in mm/s^2 for printing moves or retracts

//For the retract (negative Extruder) move this maxiumum Limit of Feedrate is used
//The next positive Extruder move use also this Limit,
Expand Down Expand Up @@ -212,4 +215,43 @@





//===========================================================================
//============================== Delta Settings =============================
//===========================================================================

#define IS_DELTA

// Make delta curves from many straight lines (linear interpolation).
// This is a trade-off between visible corners (not enough segments)
// and processor overload (too many expensive sqrt calls).
#define DELTA_SEGMENTS_PER_SECOND 200 //200

// Center-to-center distance of the holes in the diagonal push rods.
#define DELTA_DIAGONAL_ROD 492.0 // mm

// Horizontal offset from middle of printer to smooth rod center.
#define DELTA_SMOOTH_ROD_OFFSET 267.0 // mm

// Horizontal offset of the universal joints on the end effector.
#define DELTA_EFFECTOR_OFFSET 45.0 // mm

// Horizontal offset of the universal joints on the carriages.
#define DELTA_CARRIAGE_OFFSET 15.0 // mm

// Effective horizontal distance bridged by diagonal push rods.
#define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-DELTA_EFFECTOR_OFFSET-DELTA_CARRIAGE_OFFSET)

// Effective X/Y positions of the three vertical towers.
#define SIN_60 0.8660254037844386
#define COS_60 0.5
#define DELTA_TOWER1_X -SIN_60*DELTA_RADIUS // front left tower
#define DELTA_TOWER1_Y -COS_60*DELTA_RADIUS
#define DELTA_TOWER2_X SIN_60*DELTA_RADIUS // front right tower
#define DELTA_TOWER2_Y -COS_60*DELTA_RADIUS
#define DELTA_TOWER3_X 0.0 // back middle tower
#define DELTA_TOWER3_Y DELTA_RADIUS


#endif
92 changes: 87 additions & 5 deletions src/planner.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@


float destination[NUM_AXIS] = {0.0, 0.0, 0.0, 0.0};
float delta[3] = {0.0, 0.0, 0.0};
float current_position[NUM_AXIS] = {0.0, 0.0, 0.0, 0.0};
float add_homing[3]={0,0,0};
char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
Expand Down Expand Up @@ -118,6 +119,32 @@ void get_arc_coordinates()
}


#ifdef IS_DELTA

//square helper function
float sq(float x){
return x*x;
}

//calculates the movements for delta printers
void calculate_delta(float cartesian[3])
{
delta[X_AXIS] = sqrt(sq(DELTA_DIAGONAL_ROD)
- sq(DELTA_TOWER1_X-cartesian[X_AXIS])
- sq(DELTA_TOWER1_Y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS];
delta[Y_AXIS] = sqrt(sq(DELTA_DIAGONAL_ROD)
- sq(DELTA_TOWER2_X-cartesian[X_AXIS])
- sq(DELTA_TOWER2_Y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS];
delta[Z_AXIS] = sqrt(sq(DELTA_DIAGONAL_ROD)
- sq(DELTA_TOWER3_X-cartesian[X_AXIS])
- sq(DELTA_TOWER3_Y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS];
}

#endif //IS_DELTA


void prepare_move()
{
Expand Down Expand Up @@ -149,10 +176,54 @@ void prepare_move()
{
help_feedrate = ((long)feedrate*(long)100);
}

#ifdef IS_DELTA
//do not make any delta calculations if we are homing!
//if (!is_homing){

//calculate relative movement
float difference[NUM_AXIS];
for (i=0; i < NUM_AXIS; i++) {
difference[i] = destination[i] - current_position[i];
}

//calculate length of movement
float cartesian_mm = sqrt(sq(difference[X_AXIS]) +
sq(difference[Y_AXIS]) +
sq(difference[Z_AXIS]));
if (cartesian_mm < 0.000001) { return; }

//calculate number of slices to divide movement
float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
int steps = max(1, (int)(DELTA_SEGMENTS_PER_SECOND * seconds));

printf("new POS 1:%d %d %d %d %d\n\r",(int)destination[0],(int)destination[1],(int)destination[2],(int)destination[3],(int)feedrate);
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], help_feedrate/6000.0,active_extruder);


//calculate the slices
int s;
for (s = 1; s <= steps; s++) {
float fraction = (float)(s) / (float)(steps);

//calculate absolute position for this slice
for(i=0; i < NUM_AXIS; i++) {
destination[i] = current_position[i] + difference[i] * fraction;
}
//stores results in delta[3] array
calculate_delta(destination);

//add to buffer
printf("new POS 1:%d %d %d %d %d\n\r",(int)delta[0],(int)delta[1],(int)delta[2],(int)destination[3],(int)feedrate);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], help_feedrate/6000.0, active_extruder);

}
//}
#else //IS_DELTA

printf("new POS 1:%d %d %d %d %d\n\r",(int)destination[0],(int)destination[1],(int)destination[2],(int)destination[3],(int)feedrate);
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], help_feedrate/6000.0, active_extruder);

#endif //IS_DELTA

for(i=0; i < NUM_AXIS; i++)
{
current_position[i] = destination[i];
Expand Down Expand Up @@ -264,27 +335,31 @@ void homing_routine(unsigned char axis)
if ((min_pin > (-1) && home_dir==(-1)) || (max_pin > (-1) && home_dir==1))
{
current_position[axis] = (-1.5) * max_length * home_dir;
printf("from homing 1\n\r");
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
destination[axis] = 0;
feedrate = pa.homing_feedrate[axis];
prepare_move();
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
st_synchronize();

current_position[axis] = home_bounce/2 * home_dir;
printf("from homing 2\n\r");
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
destination[axis] = 0;
prepare_move();
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
st_synchronize();

current_position[axis] = (home_bounce * home_dir)*(-1);
printf("from homing 3\n\r");
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
destination[axis] = 0;
feedrate = pa.homing_feedrate[axis]/2;
prepare_move();
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
st_synchronize();

current_position[axis] = (home_dir == (-1)) ? 0 : max_length;
current_position[axis] += add_homing[axis];
printf("from homing 4\n\r");
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
destination[axis] = current_position[axis];
feedrate = 0;
Expand Down Expand Up @@ -723,6 +798,9 @@ unsigned char retract_feedrate_aktiv = 0;
// calculation the caller must also provide the physical length of the line in millimeters.
void plan_buffer_line(float x, float y, float z, float e, float feed_rate, unsigned char extruder)
{

printf("new POS 2:%d %d %d\n\r",(int)position[0]/29,(int)position[1]/29, (int)position[2]/29);

// Calculate the buffer head after we push this byte
short next_buffer_head = next_block_index(block_buffer_head);

Expand Down Expand Up @@ -1079,6 +1157,8 @@ void plan_buffer_line(float x, float y, float z, float e, float feed_rate, unsig

// Update position
memcpy(position, target, sizeof(target)); // position[] = target[]



planner_recalculate();
st_wake_up();
Expand All @@ -1096,6 +1176,8 @@ void plan_set_position(float x, float y, float z, float e)
position[Y_AXIS] = lround(y*pa.axis_steps_per_unit[Y_AXIS]);
position[Z_AXIS] = lround(z*pa.axis_steps_per_unit[Z_AXIS]);
position[E_AXIS] = lround(e*pa.axis_steps_per_unit[E_AXIS]);

printf("set_position:%d %d %d\n\r",(int)position[0]/29,(int)position[1]/29, (int)position[2]/29);

virtual_steps_x = 0;
virtual_steps_y = 0;
Expand Down