Feature/delta segmentation #144

Merged
merged 2 commits into from Mar 4, 2013
@@ -2,7 +2,8 @@
default_feed_rate 4000 # Default rate ( mm/minute ) for G1/G2/G3 moves
default_seek_rate 4000 # Default rate ( mm/minute ) for G0 moves
mm_per_arc_segment 0.5 # Arcs are cut into segments ( lines ), this is the length for these segments. Smaller values mean more resolution, higher values mean faster computation
-mm_per_line_segment 0.5 # Lines can be cut into segments ( not usefull with cartesian coordinates robots, but very useful on a delta type bot ).
+mm_per_line_segment 0.0 # Lines can be cut into segments ( not usefull with cartesian coordinates robots, but very useful on a delta type bot ). set to 0.0 to disable
+delta_segments_per_second 100 # for deltas only same as in Marlin/Delta, set to 0 to disable and use mm_per_line_segment
# Arm solution configuration : Cartesian robot. Translates mm positions into stepper positions
arm_solution rostock # selects the rostock arm solution
@@ -52,28 +52,29 @@ void Robot::on_config_reload(void* argument){
if (this->arm_solution) delete this->arm_solution;
int solution_checksum = get_checksum(this->kernel->config->value(arm_solution_checksum)->by_default("cartesian")->as_string());
- // Note checksums are not const expressions when in debug mode, so don't use switch
- if(solution_checksum == rostock_checksum) {
- this->arm_solution = new RostockSolution(this->kernel->config);
+ // Note checksums are not const expressions when in debug mode, so don't use switch
+ if(solution_checksum == rostock_checksum) {
+ this->arm_solution = new RostockSolution(this->kernel->config);
- }else if(solution_checksum == delta_checksum) {
- // place holder for now
- this->arm_solution = new RostockSolution(this->kernel->config);
+ }else if(solution_checksum == delta_checksum) {
+ // place holder for now
+ this->arm_solution = new RostockSolution(this->kernel->config);
}else if(solution_checksum == rotatable_cartesian_checksum) {
this->arm_solution = new RotatableCartesianSolution(this->kernel->config);
- }else if(solution_checksum == cartesian_checksum) {
- this->arm_solution = new CartesianSolution(this->kernel->config);
+ }else if(solution_checksum == cartesian_checksum) {
+ this->arm_solution = new CartesianSolution(this->kernel->config);
- }else{
- this->arm_solution = new CartesianSolution(this->kernel->config);
- }
+ }else{
+ this->arm_solution = new CartesianSolution(this->kernel->config);
+ }
this->feed_rate = this->kernel->config->value(default_feed_rate_checksum )->by_default(100 )->as_number() / 60;
this->seek_rate = this->kernel->config->value(default_seek_rate_checksum )->by_default(100 )->as_number() / 60;
- this->mm_per_line_segment = this->kernel->config->value(mm_per_line_segment_checksum )->by_default(5.0 )->as_number();
+ this->mm_per_line_segment = this->kernel->config->value(mm_per_line_segment_checksum )->by_default(0.0 )->as_number();
+ this->delta_segments_per_second = this->kernel->config->value(delta_segments_per_second_checksum )->by_default(0.0 )->as_number();
this->mm_per_arc_segment = this->kernel->config->value(mm_per_arc_segment_checksum )->by_default(0.5 )->as_number();
this->arc_correction = this->kernel->config->value(arc_correction_checksum )->by_default(5 )->as_number();
this->max_speeds[X_AXIS] = this->kernel->config->value(x_axis_max_speed_checksum )->by_default(60000 )->as_number();
@@ -258,9 +259,6 @@ void Robot::append_milestone( double target[], double rate ){
void Robot::append_line(Gcode* gcode, double target[], double rate ){
-
- // We cut the line into smaller segments. This is not usefull in a cartesian robot, but necessary for robots with rotational axes.
- // In cartesian robot, a high "mm_per_line_segment" setting will prevent waste.
gcode->millimeters_of_travel = sqrt( pow( target[X_AXIS]-this->current_position[X_AXIS], 2 ) + pow( target[Y_AXIS]-this->current_position[Y_AXIS], 2 ) + pow( target[Z_AXIS]-this->current_position[Z_AXIS], 2 ) );
if( gcode->call_on_gcode_execute_event_immediatly == true ){
@@ -274,7 +272,29 @@ void Robot::append_line(Gcode* gcode, double target[], double rate ){
return;
}
- uint16_t segments = ceil( gcode->millimeters_of_travel/ this->mm_per_line_segment);
+ // We cut the line into smaller segments. This is not usefull in a cartesian robot, but necessary for robots with rotational axes.
+ // In cartesian robot, a high "mm_per_line_segment" setting will prevent waste.
+ // In delta robots either mm_per_line_segment can be used OR delta_segments_per_second The latter is more efficient and avoids splitting fast long lines into very small segments, like initial z move to 0, it is what Johanns Marlin delta port does
+
+ uint16_t segments;
+
+ if(this->delta_segments_per_second > 1.0) {
+ // enabled if set to something > 1, it is set to 0.0 by default
+ // segment based on current speed and requested segments per second
+ // the faster the travel speed the fewer segments needed
+ // NOTE rate is mm/sec and we take into account any speed override
+ float seconds = 60.0/seconds_per_minute * gcode->millimeters_of_travel / rate;
+ segments= max(1, ceil(this->delta_segments_per_second * seconds));
+ // TODO if we are only moving in Z on a delta we don't really need to segment at all
+
+ }else{
+ if(this->mm_per_line_segment == 0.0){
+ segments= 1; // don't split it up
+ }else{
+ segments = ceil( gcode->millimeters_of_travel/ this->mm_per_line_segment);
+ }
+ }
+
// A vector to keep track of the endpoint of each segment
double temp_target[3];
//Initialize axes
@@ -22,6 +22,7 @@ using std::string;
#define default_seek_rate_checksum CHECKSUM("default_seek_rate")
#define default_feed_rate_checksum CHECKSUM("default_feed_rate")
#define mm_per_line_segment_checksum CHECKSUM("mm_per_line_segment")
+#define delta_segments_per_second_checksum CHECKSUM("delta_segments_per_second")
#define mm_per_arc_segment_checksum CHECKSUM("mm_per_arc_segment")
#define arc_correction_checksum CHECKSUM("arc_correction")
#define x_axis_max_speed_checksum CHECKSUM("x_axis_max_speed")
@@ -88,6 +89,7 @@ class Robot : public Module {
BaseSolution* arm_solution; // Selected Arm solution ( millimeters to step calculation )
double mm_per_line_segment; // Setting : Used to split lines into segments
double mm_per_arc_segment; // Setting : Used to split arcs into segmentrs
+ double delta_segments_per_second; // Setting : Used to split lines into segments for delta based on speed
// Number of arc generation iterations by small angle approximation before exact arc trajectory
// correction. This parameter maybe decreased if there are issues with the accuracy of the arc