Save arm specific options with M500 disspaly with M503
authorJim Morris <morris@wolfman.com>
Mon, 21 Apr 2014 06:40:09 +0000 (23:40 -0700)
committerJim Morris <morris@wolfman.com>
Mon, 21 Apr 2014 06:41:44 +0000 (23:41 -0700)
change the arm solution options to a map, and optimize how they are set and get
add delta knowledge to z probe so deltas can be probed

src/modules/robot/Robot.cpp
src/modules/robot/arm_solutions/BaseSolution.h
src/modules/robot/arm_solutions/JohannKosselSolution.cpp
src/modules/robot/arm_solutions/JohannKosselSolution.h
src/modules/tools/zprobe/ZProbe.cpp
src/modules/tools/zprobe/ZProbe.h

index 7890a43..1be517a 100644 (file)
@@ -397,38 +397,52 @@ void Robot::on_gcode_received(void * argument){
                 break;
 
             case 500: // M500 saves some volatile settings to config override file
-            case 503: // M503 just prints the settings
+            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\n", THEKERNEL->planner->acceleration);
                 gcode->stream->printf(";X- Junction Deviation, S - Minimum Planner speed:\nM205 X%1.5f S%1.5f\n", THEKERNEL->planner->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);
+
+                // get or save any arm solution specific optional values
+                BaseSolution::arm_options_t options;
+                if(arm_solution->get_optional(options) && !options.empty()) {
+                    gcode->stream->printf(";Optional arm solution specific settings:\nM665");
+                    for(auto& i : options) {
+                        gcode->stream->printf(" %c%1.4f", i.first, i.second);
+                    }
+                    gcode->stream->printf("\n");
+                }
                 gcode->mark_as_taken();
                 break;
+            }
 
-            case 665: // M665 set optional arm solution variables based on arm solution. NOTE these are not saved with M500
+            case 665: { // M665 set optional arm solution variables based on arm solution.
                 gcode->mark_as_taken();
-                // the parameter args could be any letter except S so try each one
-                for(char c='A';c<='Z';c++) {
-                    if(c == 'S') continue; // used for segments per second
-                    float v;
-                    bool supported= arm_solution->get_optional(c, &v); // retrieve current value if supported
-
-                    if(supported && gcode->has_letter(c)) { // set new value if supported
-                        v= gcode->get_value(c);
-                        arm_solution->set_optional(c, v);
-                    }
-                    if(supported) { // print all current values of supported options
-                        gcode->stream->printf("%c %8.3f ", c, v);
+                // the parameter args could be any letter except S so ask solution what options it supports
+                BaseSolution::arm_options_t options;
+                if(arm_solution->get_optional(options)) {
+                    for(auto& i : options) {
+                        // foreach optional value
+                        char c= i.first;
+                        if(gcode->has_letter(c)) { // set new value
+                            i.second= gcode->get_value(c);
+                        }
+                        // print all current values of supported options
+                        gcode->stream->printf("%c: %8.4f ", i.first, i.second);
                         gcode->add_nl = true;
                     }
+                    // set the new options
+                    arm_solution->set_optional(options);
                 }
-                // set delta segments per second
+
+                // set delta segments per second, not saved by M500
                 if(gcode->has_letter('S')) {
                     this->delta_segments_per_second= gcode->get_value('S');
                 }
                 break;
+            }
         }
     }
 
index 07fdb93..eecdd13 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef BASESOLUTION_H
 #define BASESOLUTION_H
 
+#include <map>
 class Config;
 
 class BaseSolution {
@@ -11,9 +12,9 @@ class BaseSolution {
         virtual ~BaseSolution() {};
         virtual void cartesian_to_actuator( float[], float[] ) = 0;
         virtual void actuator_to_cartesian( float[], float[] ) = 0;
-
-        virtual bool set_optional(char parameter, float  value) { return false; };
-        virtual bool get_optional(char parameter, float *value) { return false; };
+        typedef std::map<char, float> arm_options_t;
+        virtual bool set_optional(const arm_options_t& options) { return false; };
+        virtual bool get_optional(arm_options_t& options) { return false; };
 };
 
 #endif
index 3db88a9..d4c401b 100644 (file)
@@ -92,35 +92,25 @@ void JohannKosselSolution::actuator_to_cartesian( float actuator_mm[], float car
     cartesian_mm[2] = ROUND(cartesian[2], 4);
 }
 
-bool JohannKosselSolution::set_optional(char parameter, float value) {
-
-    switch(parameter) {
-        case 'L': // sets arm_length
-            arm_length= value;
-            break;
-        case 'R': // sets arm_radius
-            arm_radius= value;
-            break;
-        default:
-            return false;
+bool JohannKosselSolution::set_optional(const arm_options_t& options) {
+
+    arm_options_t::const_iterator i;
+
+    i= options.find('L');
+    if(i != options.end()) {
+        arm_length= i->second;
+
+    }
+    i= options.find('R');
+    if(i != options.end()) {
+        arm_radius= i->second;
     }
     init();
     return true;
 }
 
-bool JohannKosselSolution::get_optional(char parameter, float *value) {
-    if(value == NULL) return false;
-
-    switch(parameter) {
-        case 'L': // get arm_length
-            *value= this->arm_length;
-            break;
-        case 'R': // get arm_radius
-            *value= this->arm_radius;
-            break;
-        default:
-            return false;
-    }
-
+bool JohannKosselSolution::get_optional(arm_options_t& options) {
+    options['L']= this->arm_length;
+    options['R']= this->arm_radius;
     return true;
 };
index 28cdd34..1820876 100644 (file)
@@ -16,8 +16,8 @@ class JohannKosselSolution : public BaseSolution {
         void cartesian_to_actuator( float[], float[] );
         void actuator_to_cartesian( float[], float[] );
 
-        bool set_optional(char parameter, float value);
-        bool get_optional(char parameter, float *value);
+        bool set_optional(const arm_options_t& options);
+        bool get_optional(arm_options_t& options);
 
     private:
         void init();
index 5ef476a..0a343f3 100644 (file)
@@ -27,6 +27,8 @@
 #define debounce_count_checksum  CHECKSUM("debounce_count")
 #define feedrate_checksum        CHECKSUM("feedrate")
 
+#define delta_homing_checksum    CHECKSUM("delta_homing")
+
 #define alpha_steps_per_mm_checksum      CHECKSUM("alpha_steps_per_mm")
 #define beta_steps_per_mm_checksum       CHECKSUM("beta_steps_per_mm")
 #define gamma_steps_per_mm_checksum      CHECKSUM("gamma_steps_per_mm")
@@ -71,6 +73,10 @@ void ZProbe::on_config_reload(void *argument)
     this->steps_per_mm[2] =  THEKERNEL->config->value(gamma_steps_per_mm_checksum)->as_number();
 
     this->feedrate = THEKERNEL->config->value(zprobe_checksum, feedrate_checksum)->by_default(5)->as_number()*this->steps_per_mm[Z_AXIS]; // feedrate in steps/sec
+
+    // see what type of arm solution we need to use
+    this->is_delta =  THEKERNEL->config->value(delta_homing_checksum)->by_default(false)->as_bool();
+
 }
 
 bool ZProbe::wait_for_probe(int steps[])
@@ -118,10 +124,17 @@ bool ZProbe::run_probe(int *steps)
     THEKERNEL->stepper->turn_enable_pins_on();
 
     // move Z down
-    // TODO for delta need to move all three actuators
     this->running= true;
     this->steppers[Z_AXIS]->set_speed(0); // will be increased by acceleration tick
     this->steppers[Z_AXIS]->move(true, 100*this->steps_per_mm[Z_AXIS]); // always probes down, no more than 100mm
+    if(this->is_delta) {
+        // for delta need to move all three actuators
+        this->steppers[X_AXIS]->set_speed(0);
+        this->steppers[X_AXIS]->move(true, 100*this->steps_per_mm[X_AXIS]);
+        this->steppers[Y_AXIS]->set_speed(0);
+        this->steppers[Y_AXIS]->move(true, 100*this->steps_per_mm[Y_AXIS]);
+    }
+
     bool r= wait_for_probe(steps);
     this->running= false;
     return r;
@@ -152,13 +165,21 @@ void ZProbe::on_gcode_received(void *argument)
                     THEKERNEL->robot->reset_axis_position(gcode->get_value('Z'), Z_AXIS);
                 }else{
                     // move probe back to where it was
+                    this->running= true;
                     this->steppers[Z_AXIS]->set_speed(0); // will be increased by acceleration tick
                     this->steppers[Z_AXIS]->move(false, steps[Z_AXIS]);
-                    this->running= true;
-                    while(this->steppers[Z_AXIS]->moving) { // wait for it to complete
+                    if(this->is_delta) {
+                        this->steppers[X_AXIS]->set_speed(0);
+                        this->steppers[X_AXIS]->move(false, steps[X_AXIS]);
+                        this->steppers[Y_AXIS]->set_speed(0);
+                        this->steppers[Y_AXIS]->move(false, steps[Y_AXIS]);
+                    }
+                    while(this->steppers[X_AXIS]->moving || this->steppers[Y_AXIS]->moving || this->steppers[Z_AXIS]->moving) {
+                        // wait for it to complete
                         THEKERNEL->call_event(ON_IDLE);
                     }
-                    this->running= true;
+
+                    this->running= false;
                 }
             }else{
                 gcode->stream->printf("ZProbe not triggered\n");
@@ -183,7 +204,7 @@ uint32_t ZProbe::acceleration_tick(uint32_t dummy)
     if(!this->running) return(0); // nothing to do
 
     // foreach stepper that is moving
-    for ( int c = 0; c <= 2; c++ ) {
+    for ( int c = X_AXIS; c <= Z_AXIS; c++ ) {
         if( !this->steppers[c]->moving ) continue;
 
         uint32_t current_rate = this->steppers[c]->steps_per_second;
index 538365e..d8dbbc5 100644 (file)
@@ -36,6 +36,7 @@ private:
     Pin            pin;
     unsigned int   debounce_count;
     bool           running;
+    bool           is_delta;
 };
 
 #endif /* ZPROBE_H_ */