Merge remote-tracking branch 'upstream/edge' into use-pendsv-handler-for-ticker
[clinton/Smoothieware.git] / src / modules / robot / Robot.cpp
index 4390c16..8397039 100644 (file)
@@ -114,7 +114,6 @@ using std::string;
 
 // The Robot converts GCodes into actual movements, and then adds them to the Planner, which passes them to the Conveyor so they can be added to the queue
 // It takes care of cutting arcs into segments, same thing for line that are too long
-#define max(a,b) (((a) > (b)) ? (a) : (b))
 
 Robot::Robot()
 {
@@ -212,17 +211,17 @@ void Robot::on_config_reload(void *argument)
 
     // TODO: delete or detect old steppermotors
     // Make our 3 StepperMotors
-    this->alpha_stepper_motor  = THEKERNEL->step_ticker->add_stepper_motor( new StepperMotor(alpha_step_pin, alpha_dir_pin, alpha_en_pin) );
-    this->beta_stepper_motor   = THEKERNEL->step_ticker->add_stepper_motor( new StepperMotor(beta_step_pin,  beta_dir_pin,  beta_en_pin ) );
-    this->gamma_stepper_motor  = THEKERNEL->step_ticker->add_stepper_motor( new StepperMotor(gamma_step_pin, gamma_dir_pin, gamma_en_pin) );
+    this->alpha_stepper_motor  = new StepperMotor(alpha_step_pin, alpha_dir_pin, alpha_en_pin);
+    this->beta_stepper_motor   = new StepperMotor(beta_step_pin,  beta_dir_pin,  beta_en_pin );
+    this->gamma_stepper_motor  = new StepperMotor(gamma_step_pin, gamma_dir_pin, gamma_en_pin);
 
     alpha_stepper_motor->change_steps_per_mm(steps_per_mm[0]);
     beta_stepper_motor->change_steps_per_mm(steps_per_mm[1]);
     gamma_stepper_motor->change_steps_per_mm(steps_per_mm[2]);
 
-    alpha_stepper_motor->max_rate = THEKERNEL->config->value(alpha_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F;
-    beta_stepper_motor->max_rate  = THEKERNEL->config->value(beta_max_rate_checksum )->by_default(30000.0F)->as_number() / 60.0F;
-    gamma_stepper_motor->max_rate = THEKERNEL->config->value(gamma_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F;
+    alpha_stepper_motor->set_max_rate(THEKERNEL->config->value(alpha_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F);
+    beta_stepper_motor->set_max_rate(THEKERNEL->config->value(beta_max_rate_checksum )->by_default(30000.0F)->as_number() / 60.0F);
+    gamma_stepper_motor->set_max_rate(THEKERNEL->config->value(gamma_max_rate_checksum)->by_default(30000.0F)->as_number() / 60.0F);
     check_max_actuator_speeds(); // check the configs are sane
 
     actuators.clear();
@@ -245,21 +244,21 @@ void Robot::on_config_reload(void *argument)
 // we will override the actuator max_rate if the combination of max_rate and steps/sec exceeds base_stepping_frequency
 void Robot::check_max_actuator_speeds()
 {
-    float step_freq= alpha_stepper_motor->max_rate * alpha_stepper_motor->get_steps_per_mm();
+    float step_freq= alpha_stepper_motor->get_max_rate() * alpha_stepper_motor->get_steps_per_mm();
     if(step_freq > THEKERNEL->base_stepping_frequency) {
-        alpha_stepper_motor->max_rate= floorf(THEKERNEL->base_stepping_frequency / alpha_stepper_motor->get_steps_per_mm());
+        alpha_stepper_motor->set_max_rate(floorf(THEKERNEL->base_stepping_frequency / alpha_stepper_motor->get_steps_per_mm()));
         THEKERNEL->streams->printf("WARNING: alpha_max_rate exceeds base_stepping_frequency * alpha_steps_per_mm: %f, setting to %f\n", step_freq, alpha_stepper_motor->max_rate);
     }
 
-    step_freq= beta_stepper_motor->max_rate * beta_stepper_motor->get_steps_per_mm();
+    step_freq= beta_stepper_motor->get_max_rate() * beta_stepper_motor->get_steps_per_mm();
     if(step_freq > THEKERNEL->base_stepping_frequency) {
-        beta_stepper_motor->max_rate= floorf(THEKERNEL->base_stepping_frequency / beta_stepper_motor->get_steps_per_mm());
+        beta_stepper_motor->set_max_rate(floorf(THEKERNEL->base_stepping_frequency / beta_stepper_motor->get_steps_per_mm()));
         THEKERNEL->streams->printf("WARNING: beta_max_rate exceeds base_stepping_frequency * beta_steps_per_mm: %f, setting to %f\n", step_freq, beta_stepper_motor->max_rate);
     }
 
-    step_freq= gamma_stepper_motor->max_rate * gamma_stepper_motor->get_steps_per_mm();
+    step_freq= gamma_stepper_motor->get_max_rate() * gamma_stepper_motor->get_steps_per_mm();
     if(step_freq > THEKERNEL->base_stepping_frequency) {
-        gamma_stepper_motor->max_rate= floorf(THEKERNEL->base_stepping_frequency / gamma_stepper_motor->get_steps_per_mm());
+        gamma_stepper_motor->set_max_rate(floorf(THEKERNEL->base_stepping_frequency / gamma_stepper_motor->get_steps_per_mm()));
         THEKERNEL->streams->printf("WARNING: gamma_max_rate exceeds base_stepping_frequency * gamma_steps_per_mm: %f, setting to %f\n", step_freq, gamma_stepper_motor->max_rate);
     }
 }
@@ -400,17 +399,17 @@ void Robot::on_gcode_received(void *argument)
                 if (gcode->has_letter('Z'))
                     this->max_speeds[Z_AXIS] = gcode->get_value('Z');
                 if (gcode->has_letter('A'))
-                    alpha_stepper_motor->max_rate = gcode->get_value('A');
+                    alpha_stepper_motor->set_max_rate(gcode->get_value('A'));
                 if (gcode->has_letter('B'))
-                    beta_stepper_motor->max_rate = gcode->get_value('B');
+                    beta_stepper_motor->set_max_rate(gcode->get_value('B'));
                 if (gcode->has_letter('C'))
-                    gamma_stepper_motor->max_rate = gcode->get_value('C');
+                    gamma_stepper_motor->set_max_rate(gcode->get_value('C'));
 
                 check_max_actuator_speeds();
 
                 gcode->stream->printf("X:%g Y:%g Z:%g  A:%g B:%g C:%g ",
                                       this->max_speeds[X_AXIS], this->max_speeds[Y_AXIS], this->max_speeds[Z_AXIS],
-                                      alpha_stepper_motor->max_rate, beta_stepper_motor->max_rate, gamma_stepper_motor->max_rate);
+                                      alpha_stepper_motor->get_max_rate(), beta_stepper_motor->get_max_rate(), gamma_stepper_motor->get_max_rate());
                 gcode->add_nl = true;
                 gcode->mark_as_taken();
                 break;
@@ -419,8 +418,6 @@ void Robot::on_gcode_received(void *argument)
                 gcode->mark_as_taken();
 
                 if (gcode->has_letter('S')) {
-                    // TODO for safety so it applies only to following gcodes, maybe a better way to do this?
-                    THEKERNEL->conveyor->wait_for_empty_queue();
                     float acc = gcode->get_value('S'); // mm/s^2
                     // enforce minimum
                     if (acc < 1.0F)
@@ -428,8 +425,6 @@ void Robot::on_gcode_received(void *argument)
                     THEKERNEL->planner->acceleration = acc;
                 }
                 if (gcode->has_letter('Z')) {
-                    // TODO for safety so it applies only to following gcodes, maybe a better way to do this?
-                    THEKERNEL->conveyor->wait_for_empty_queue();
                     float acc = gcode->get_value('Z'); // mm/s^2
                     // enforce positive
                     if (acc < 0.0F)
@@ -438,7 +433,7 @@ void Robot::on_gcode_received(void *argument)
                 }
                 break;
 
-            case 205: // M205 Xnnn - set junction deviation, Z - set Z junction deviation, Snnn - Set minimum planner speed
+            case 205: // M205 Xnnn - set junction deviation, Z - set Z junction deviation, Snnn - Set minimum planner speed, Ynnn - set minimum step rate
                 gcode->mark_as_taken();
                 if (gcode->has_letter('X')) {
                     float jd = gcode->get_value('X');
@@ -461,6 +456,9 @@ void Robot::on_gcode_received(void *argument)
                         mps = 0.0F;
                     THEKERNEL->planner->minimum_planner_speed = mps;
                 }
+                if (gcode->has_letter('Y')) {
+                    alpha_stepper_motor->default_minimum_actuator_rate = gcode->get_value('Y');
+                }
                 break;
 
             case 220: // M220 - speed override percentage
@@ -487,10 +485,10 @@ void Robot::on_gcode_received(void *argument)
             case 503: { // M503 just prints the settings
                 gcode->stream->printf(";Steps per unit:\nM92 X%1.5f Y%1.5f Z%1.5f\n", actuators[0]->steps_per_mm, actuators[1]->steps_per_mm, actuators[2]->steps_per_mm);
                 gcode->stream->printf(";Acceleration mm/sec^2:\nM204 S%1.5f Z%1.5f\n", THEKERNEL->planner->acceleration, THEKERNEL->planner->z_acceleration);
-                gcode->stream->printf(";X- Junction Deviation, Z- Z junction deviation, S - Minimum Planner speed:\nM205 X%1.5f Z%1.5f S%1.5f\n", THEKERNEL->planner->junction_deviation, THEKERNEL->planner->z_junction_deviation, THEKERNEL->planner->minimum_planner_speed);
+                gcode->stream->printf(";X- Junction Deviation, Z- Z junction deviation, S - Minimum Planner speed mm/sec:\nM205 X%1.5f Z%1.5f S%1.5f\n", THEKERNEL->planner->junction_deviation, THEKERNEL->planner->z_junction_deviation, THEKERNEL->planner->minimum_planner_speed);
                 gcode->stream->printf(";Max feedrates in mm/sec, XYZ cartesian, ABC actuator:\nM203 X%1.5f Y%1.5f Z%1.5f A%1.5f B%1.5f C%1.5f\n",
                                       this->max_speeds[X_AXIS], this->max_speeds[Y_AXIS], this->max_speeds[Z_AXIS],
-                                      alpha_stepper_motor->max_rate, beta_stepper_motor->max_rate, gamma_stepper_motor->max_rate);
+                                      alpha_stepper_motor->get_max_rate(), beta_stepper_motor->get_max_rate(), gamma_stepper_motor->get_max_rate());
 
                 // get or save any arm solution specific optional values
                 BaseSolution::arm_options_t options;
@@ -524,10 +522,17 @@ void Robot::on_gcode_received(void *argument)
                     arm_solution->set_optional(options);
                 }
 
-                // set delta segments per second, not saved by M500
-                if(gcode->has_letter('S')) {
+
+                if(gcode->has_letter('S')) { // set delta segments per second, not saved by M500
                     this->delta_segments_per_second = gcode->get_value('S');
+                    gcode->stream->printf("Delta segments set to %8.4f segs/sec\n", this->delta_segments_per_second);
+
+                }else if(gcode->has_letter('U')) { // or set mm_per_line_segment, not saved by M500
+                    this->mm_per_line_segment = gcode->get_value('U');
+                    this->delta_segments_per_second = 0;
+                    gcode->stream->printf("mm per line segment set to %8.4f\n", this->mm_per_line_segment);
                 }
+
                 break;
             }
         }
@@ -673,8 +678,8 @@ void Robot::append_milestone( float target[], float rate_mm_s )
     for (int actuator = 0; actuator <= 2; actuator++) {
         float actuator_rate  = fabs(actuator_pos[actuator] - actuators[actuator]->last_milestone_mm) * rate_mm_s / millimeters_of_travel;
 
-        if (actuator_rate > actuators[actuator]->max_rate)
-            rate_mm_s *= (actuators[actuator]->max_rate / actuator_rate);
+        if (actuator_rate > actuators[actuator]->get_max_rate())
+            rate_mm_s *= (actuators[actuator]->get_max_rate() / actuator_rate);
     }
 
     // Append the block to the planner
@@ -713,14 +718,14 @@ void Robot::append_line(Gcode *gcode, float target[], float rate_mm_s )
         // the faster the travel speed the fewer segments needed
         // NOTE rate is mm/sec and we take into account any speed override
         float seconds = gcode->millimeters_of_travel / rate_mm_s;
-        segments = max(1, ceil(this->delta_segments_per_second * seconds));
+        segments = max(1.0F, ceilf(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.0F) {
             segments = 1; // don't split it up
         } else {
-            segments = ceil( gcode->millimeters_of_travel / this->mm_per_line_segment);
+            segments = ceilf( gcode->millimeters_of_travel / this->mm_per_line_segment);
         }
     }
 
@@ -787,7 +792,7 @@ void Robot::append_arc(Gcode *gcode, float target[], float offset[], float radiu
     this->distance_in_gcode_is_known( gcode );
 
     // Figure out how many segments for this gcode
-    uint16_t segments = floor(gcode->millimeters_of_travel / this->mm_per_arc_segment);
+    uint16_t segments = floorf(gcode->millimeters_of_travel / this->mm_per_arc_segment);
 
     float theta_per_segment = angular_travel / segments;
     float linear_per_segment = linear_travel / segments;