the fast move end bug is fixed, re-working the stepper system once again
authorArthur Wolf <wolf.arthur@gmail.com>
Sun, 28 Oct 2012 19:10:50 +0000 (20:10 +0100)
committerArthur Wolf <wolf.arthur@gmail.com>
Sun, 28 Oct 2012 19:10:50 +0000 (20:10 +0100)
src/libs/SlowTicker.cpp
src/libs/StepTicker.cpp
src/libs/StepperMotor.cpp
src/libs/StepperMotor.h
src/main.cpp
src/modules/robot/Stepper.cpp
src/modules/tools/extruder/Extruder.cpp

index 7427458..c5326df 100644 (file)
@@ -45,9 +45,15 @@ void SlowTicker::tick(){
 }
 
 extern "C" void TIMER2_IRQHandler (void){
+
+    LPC_GPIO1->FIOSET = 1<<21;
+
     if((LPC_TIM2->IR >> 0) & 1){  // If interrupt register set for MR0
         LPC_TIM2->IR |= 1 << 0;   // Reset it 
         global_slow_ticker->tick(); 
     }
+
+    LPC_GPIO1->FIOCLR = 1<<21;
+
 }
 
index 58de83a..f0162dc 100644 (file)
@@ -86,8 +86,8 @@ inline void StepTicker::reset_tick(){
     while(current != NULL ){
         current->step_pin->set(0);
         if( current->exit_tick ){
-            if( current->dont_remove_from_active_list_yet ){
-                current->dont_remove_from_active_list_yet = false;
+            if( current->remove_from_active_list_next_tick ){
+                current->remove_from_active_list_next_tick = false;
             }else{
                 this->remove_motor_from_active_list(current); 
                 current_id--;
@@ -105,7 +105,9 @@ extern "C" void TIMER1_IRQHandler (void){
 
 // The actual interrupt handler where we do all the work
 extern "C" void TIMER0_IRQHandler (void){
-    
+
+    LPC_GPIO1->FIOSET = 1<<18;
+
     uint32_t start_time = LPC_TIM0->TC;
    
     LPC_TIM0->IR |= 1 << 0;
@@ -114,7 +116,10 @@ extern "C" void TIMER0_IRQHandler (void){
 
     // If no axes enabled, just ignore for now 
     if( !global_step_ticker->has_axes ){ 
+   
+        LPC_GPIO1->FIOCLR = 1<<18;
         return; 
+    
     } 
 
     // Do not get out of here before everything is nice and tidy
@@ -173,6 +178,7 @@ extern "C" void TIMER0_IRQHandler (void){
     }
 
 
+    LPC_GPIO1->FIOCLR = 1<<18;
 
 }
 
index bddb49b..b2d9a2f 100644 (file)
@@ -18,7 +18,7 @@ StepperMotor::StepperMotor(){
     this->direction_bit = 0;
     this->step_bit = 0;
     this->update_exit_tick();
-    this->dont_remove_from_active_list_yet = false;
+    this->remove_from_active_list_next_tick = false;
     this->exit_tick = true;
 }
 
@@ -32,7 +32,7 @@ StepperMotor::StepperMotor(Pin* step, Pin* dir, Pin* en) : step_pin(step), dir_p
     this->direction_bit = 0;
     this->step_bit = 0;
     this->update_exit_tick();
-    this->dont_remove_from_active_list_yet = false;
+    this->remove_from_active_list_next_tick = false;
     this->exit_tick = true;
 }
 
@@ -96,18 +96,19 @@ bool StepperMotor::tick(){
 // This is just a way not to check for ( !this->moving || this->paused || this->fx_ticks_per_step == 0 ) at every tick()
 inline void StepperMotor::update_exit_tick(){
     //printf("try update list %u %u %u\r\n", this->moving, this->paused, this->fx_ticks_per_step == 0 );
-    if( !this->moving || this->paused || this->fx_ticks_per_step == 0 || this->steps_to_move == 0 ){
+    if( !this->moving || this->paused || this->steps_to_move == 0 ){
         // We must exit tick() after setting the pins, no bresenham is done 
         if( this->exit_tick == false ){
-            //printf("set for removal %p \r\n", this);
             this->exit_tick = true;
-            this->dont_remove_from_active_list_yet = true; 
+            this->remove_from_active_list_next_tick = true; 
         }
     }else{
         // We must do the bresenham in tick()
         if( this->exit_tick == true ){ 
+            // We have to do this or there could be a bug where the removal still happens when it doesn't need to
+            this->remove_from_active_list_next_tick = false;
+
             this->exit_tick = false;
-            //printf("adding motor %p \r\n", this);
             this->step_ticker->add_motor_to_active_list(this);
         }
     }
@@ -130,7 +131,11 @@ void StepperMotor::move( bool direction, unsigned int steps ){
     this->stepped = 0;
 
     // Starting now we are moving
-    if( steps > 0 ){ this->moving = true; }else{ this->moving = false; }
+    if( steps > 0 ){ 
+        this->moving = true; 
+    }else{ 
+        this->moving = false; 
+    }
     this->update_exit_tick(); 
 
 }
@@ -143,7 +148,11 @@ void StepperMotor::set_speed( double speed ){
         this->fx_ticks_per_step = 1>>63;
         return; 
     }
-    
+   
+    //if( speed < this->steps_per_second ){
+        LPC_GPIO1->FIOSET = 1<<19;
+    //}
+
     // How many steps we must output per second
     this->steps_per_second = speed;
 
@@ -151,10 +160,19 @@ void StepperMotor::set_speed( double speed ){
     double ticks_per_step = (double)( (double)this->step_ticker->frequency / speed );
     double double_fx_ticks_per_step = (double)(1<<16) * ( (double)(1<<16) * ticks_per_step );
     this->fx_ticks_per_step = (uint64_t)( floor(double_fx_ticks_per_step) );
-    this->update_exit_tick(); 
+
+    LPC_GPIO1->FIOCLR = 1<<19;
 
 }
 
+void StepperMotor::pause(){
+    this->paused = true;
+    this->update_exit_tick();
+}
 
+void StepperMotor::unpause(){
+    this->paused = false;
+    this->update_exit_tick();
+}
 
 
index 6a50af4..09f86ef 100644 (file)
@@ -21,6 +21,8 @@ class StepperMotor {
         void move( bool direction, unsigned int steps );
         void set_speed( double speed );
         void update_exit_tick();
+        void pause();
+        void unpause();
 
         template<typename T> void attach( T *optr, uint32_t ( T::*fptr )( uint32_t ) ){
             Hook* hook = new Hook(); 
@@ -49,7 +51,7 @@ class StepperMotor {
         uint64_t fx_ticks_per_step;
         
         bool exit_tick;
-        bool dont_remove_from_active_list_yet;
+        bool remove_from_active_list_next_tick;
 
 };
 
index 1cb6095..9783b02 100644 (file)
@@ -61,7 +61,7 @@ int main() {
     message.stream = kernel->serial;
     kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message ); 
    
-
+    /*
     int i = 0;
     while( i <= 60 ){
         // Debug : launch file on startup
@@ -86,15 +86,41 @@ int main() {
     
         i++;
     }
+    */
+    
+   /* 
+    int i = 0;
+    while( i <= 60 ){
+        // Debug : launch file on startup
+        
+        message.message = "G1 X40 Y0 F9000";
+        message.stream = kernel->serial;
+        kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message ); 
+     
+        message.message = "G1 X40 Y1 F9000";
+        message.stream = kernel->serial;
+        kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message ); 
+   
+
+        message.message = "G1 X0 Y1 F9000";
+        message.stream = kernel->serial;
+        kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message ); 
+   
+
+        message.message = "G1 X0 Y0 F9000";
+        message.stream = kernel->serial;
+        kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message );
+    
+        i++;
+    }
+    */
 
-    /*
     // Debug : launch file on startup
-    struct SerialMessage message; 
+    //struct SerialMessage message; 
     //message.message = "G1 X1000 F2000";
-    message.message = "play /sd/victor.g -q";
+    message.message = "play /sd/laurana.g -q";
     message.stream = kernel->serial;
     kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message ); 
-    */
 
     while(1){
         kernel->call_event(ON_MAIN_LOOP);
index 5693c67..cf0f895 100644 (file)
@@ -64,19 +64,18 @@ void Stepper::on_config_reload(void* argument){
 // When the play/pause button is set to pause, or a module calls the ON_PAUSE event
 void Stepper::on_pause(void* argument){
     this->paused = true;
-    this->kernel->robot->alpha_stepper_motor->paused = true;
-    this->kernel->robot->beta_stepper_motor->paused  = true;
-    this->kernel->robot->gamma_stepper_motor->paused = true;
-
+    this->kernel->robot->alpha_stepper_motor->pause();
+    this->kernel->robot->beta_stepper_motor->pause();
+    this->kernel->robot->gamma_stepper_motor->pause();
 }
 
 // When the play/pause button is set to play, or a module calls the ON_PLAY event
 void Stepper::on_play(void* argument){
     // TODO: Re-compute the whole queue for a cold-start
     this->paused = false;
-    this->kernel->robot->alpha_stepper_motor->paused = false;
-    this->kernel->robot->beta_stepper_motor->paused  = false;
-    this->kernel->robot->gamma_stepper_motor->paused = false;
+    this->kernel->robot->alpha_stepper_motor->unpause();
+    this->kernel->robot->beta_stepper_motor->unpause();
+    this->kernel->robot->gamma_stepper_motor->unpause();
 }
 
 
@@ -126,7 +125,6 @@ void Stepper::on_block_begin(void* argument){
 
     //block->debug(this->kernel);
 
-         LPC_GPIO1->FIOCLR = 1<<18;
 
     // We can't move with the enable pins off 
     if( this->enable_pins_status == false ){
@@ -163,8 +161,11 @@ void Stepper::on_block_end(void* argument){
 
 }
 
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+
 // When a stepper motor has finished it's assigned movement
-inline uint32_t Stepper::stepper_motor_finished_move(uint32_t dummy){
+uint32_t Stepper::stepper_motor_finished_move(uint32_t dummy){
 
     // We care only if none is still moving
     if( this->kernel->robot->alpha_stepper_motor->moving || this->kernel->robot->beta_stepper_motor->moving || this->kernel->robot->gamma_stepper_motor->moving ){ return 0; }
@@ -172,7 +173,6 @@ inline uint32_t Stepper::stepper_motor_finished_move(uint32_t dummy){
     // This block is finished, release it
     if( this->current_block != NULL ){
 
-         LPC_GPIO1->FIOSET = 1<<18;
 
         this->current_block->release(); 
 
@@ -185,18 +185,21 @@ inline uint32_t Stepper::step_events_completed(){
     return this->main_stepper->stepped;
 }
 
+
 // This is called ACCELERATION_TICKS_PER_SECOND times per second by the step_event
 // interrupt. It can be assumed that the trapezoid-generator-parameters and the
 // current_block stays untouched by outside handlers for the duration of this function call.
 uint32_t Stepper::trapezoid_generator_tick( uint32_t dummy ) {
 
+
     if(this->current_block && !this->paused && this->main_stepper->moving ) {
 
         uint32_t current_steps_completed = this->main_stepper->stepped;
-       
-        speed_ticks_counter++;
-        
-        if( previous_step_count == current_steps_completed && previous_step_count != 0  ){
+    
+    if( current_steps_completed >= this->main_stepper->steps_to_move - 3 ){
+    }
+      
+        if( previous_step_count == current_steps_completed && previous_step_count != 0 ){
             // We must skip this step update because no step has happened
             skipped_speed_updates++;
             return 0;
@@ -209,35 +212,44 @@ uint32_t Stepper::trapezoid_generator_tick( uint32_t dummy ) {
           this->set_step_events_per_minute(this->trapezoid_adjusted_rate);
         }
         
-        if(current_steps_completed < this->current_block->accelerate_until) {
-
-
+        if(current_steps_completed <= this->current_block->accelerate_until + 1) {
 
+             /*
               if( this->current_block->initial_rate == 0 && 0 ){
                   __disable_irq();uint32_t start_tc0 = LPC_TIM0->TC; uint32_t start_tc2 = LPC_TIM2->TC;
                  this->kernel->streams->printf("acc{%u<%u} tar:%f im:%u sps:%f pos:%u/%u cnt:%u delta:%f \r\n", current_steps_completed, this->current_block->accelerate_until, this->trapezoid_adjusted_rate, this->main_stepper->moving, this->main_stepper->steps_per_second, this->main_stepper->stepped, this->main_stepper->steps_to_move, (uint32_t)(this->main_stepper->fx_ticks_per_step>>32), this->current_block->rate_delta );
                    LPC_TIM0->TC = start_tc0; LPC_TIM2->TC = start_tc2; __enable_irq();
               }
+            */
 
-
-              this->trapezoid_adjusted_rate += this->current_block->rate_delta + ( this->current_block->rate_delta * skipped_speed_updates );
+              this->trapezoid_adjusted_rate += ( skipped_speed_updates + 1 ) * this->current_block->rate_delta;
+              
               if (this->trapezoid_adjusted_rate > this->current_block->nominal_rate ) {
-                  //this->kernel->streams->printf("reached after %u when it should be %u\r\n", current_steps_completed, this->current_block->accelerate_until);
+                  
+                  //this->kernel->streams->printf("reached after %u with au %u and da %u \r\n", current_steps_completed, this->current_block->accelerate_until, this->current_block->decelerate_after);
+
                   this->trapezoid_adjusted_rate = this->current_block->nominal_rate;
+
               }
+
               this->set_step_events_per_minute(this->trapezoid_adjusted_rate);
+
+
         }else if (current_steps_completed > this->current_block->decelerate_after + 1) {
 
+            LPC_GPIO1->FIOSET = 1<<20;
+             /*
               if( this->current_block->final_rate == 0 && 0 ){
                   __disable_irq();uint32_t start_tc0 = LPC_TIM0->TC; uint32_t start_tc2 = LPC_TIM2->TC;
                  this->kernel->streams->printf("dec{%u>=%u} tar:%f im:%u sps:%f pos:%u/%u cnt:%u delta:%f\r\n", current_steps_completed, this->current_block->decelerate_after, this->trapezoid_adjusted_rate, this->main_stepper->moving, this->main_stepper->steps_per_second, this->main_stepper->stepped, this->main_stepper->steps_to_move, (uint32_t)(this->main_stepper->fx_ticks_per_step>>32), this->current_block->rate_delta );
                    LPC_TIM0->TC = start_tc0; LPC_TIM2->TC = start_tc2; __enable_irq();
               }
+            */
 
               // NOTE: We will only reduce speed if the result will be > 0. This catches small
               // rounding errors that might leave steps hanging after the last trapezoid tick.
               if(this->trapezoid_adjusted_rate > this->current_block->rate_delta * 1.5) {
-                  this->trapezoid_adjusted_rate -= this->current_block->rate_delta + ( this->current_block->rate_delta * skipped_speed_updates );
+                  this->trapezoid_adjusted_rate -= ( skipped_speed_updates + 1 ) * this->current_block->rate_delta;
               }else{
                   //this->kernel->streams->printf("delta reached after %u when it should be %u\r\n", current_steps_completed, this->main_stepper->steps_to_move);
                   this->trapezoid_adjusted_rate = this->current_block->rate_delta * 1.5;
@@ -248,18 +260,30 @@ uint32_t Stepper::trapezoid_generator_tick( uint32_t dummy ) {
                   this->trapezoid_adjusted_rate = this->current_block->final_rate;
               } 
               this->set_step_events_per_minute(this->trapezoid_adjusted_rate);
-          }else {
+
+
+               LPC_GPIO1->FIOCLR = 1<<20;
+
+        }else {
               // Make sure we cruise at exactly nominal rate
               if (this->trapezoid_adjusted_rate != this->current_block->nominal_rate) {
                   this->trapezoid_adjusted_rate = this->current_block->nominal_rate;
                   this->set_step_events_per_minute(this->trapezoid_adjusted_rate);
               }
           }
+
+
+
     }
 
     skipped_speed_updates = 0; 
+
+
 }
 
+#pragma GCC pop_options
+
+
 // Initializes the trapezoid generator from the current block. Called whenever a new
 // block begins.
 inline void Stepper::trapezoid_generator_reset(){
index 7f54730..2313bd3 100644 (file)
@@ -79,11 +79,13 @@ void Extruder::on_config_reload(void* argument){
 // When the play/pause button is set to pause, or a module calls the ON_PAUSE event
 void Extruder::on_pause(void* argument){
     this->paused = true;
+    this->stepper_motor->pause();
 }
 
 // When the play/pause button is set to play, or a module calls the ON_PLAY event
 void Extruder::on_play(void* argument){
     this->paused = false;
+    this->stepper_motor->unpause();
 }
 
 
@@ -174,7 +176,7 @@ void Extruder::on_block_begin(void* argument){
 
         int old_steps = this->current_steps;
         int target_steps = int( floor(this->steps_per_millimeter*this->target_position) );
-        int steps_to_step = abs( target_steps - old_steps );
+        int steps_to_step = target_steps - old_steps ;
         this->current_steps = target_steps;
         
         
@@ -186,7 +188,7 @@ void Extruder::on_block_begin(void* argument){
             
             //printf("spm:%f td:%f steps:%d ( %f - %f ) \r\n", this->steps_per_millimeter, this->travel_distance,  steps_to_step, this->target_position, this->current_position  );
 
-            this->stepper_motor->move( ( this->travel_distance > 0 ), steps_to_step ); 
+            this->stepper_motor->move( ( steps_to_step > 0 ), abs(steps_to_step) ); 
 
 
 
@@ -219,19 +221,13 @@ uint32_t Extruder::acceleration_tick(uint32_t dummy){
     uint32_t current_rate = this->stepper_motor->steps_per_second;
     uint32_t target_rate = int(floor((this->feed_rate/60)*this->steps_per_millimeter));
   
-    //printf("update extruder speed in acceleration tick \r\n");
-
-    //if( LPC_TIM0->TC % 7 == 2 ){ 
-    //    printf("speed:{current: %u target: %u} position:{stepped:%u total:%u} \r\n", current_rate, target_rate, this->stepper_motor->stepped, this->stepper_motor->steps_to_move);
-    //}
-
     if( current_rate < target_rate ){
         uint32_t rate_increase = int(floor((this->acceleration/this->kernel->stepper->acceleration_ticks_per_second)*this->steps_per_millimeter));
         current_rate = min( target_rate, current_rate + rate_increase );
     }
     if( current_rate > target_rate ){ current_rate = target_rate; }
 
-    this->stepper_motor->set_speed(current_rate); 
+    this->stepper_motor->set_speed(max(current_rate, this->kernel->stepper->minimum_steps_per_minute/60)); 
        
     return 0;
 }
@@ -242,8 +238,6 @@ void Extruder::on_speed_change( void* argument ){
     // Avoid trying to work when we really shouldn't ( between blocks or re-entry )
     if( this->current_block == NULL ||  this->paused || this->mode != FOLLOW || this->stepper_motor->moving != true ){ return; }
 
-    uint32_t adjusted_rate = max( this->kernel->stepper->trapezoid_adjusted_rate, this->kernel->stepper->minimum_steps_per_minute );
-
     /*
      * nominal block duration = current block's steps / ( current block's nominal rate / 60 )
      * nominal extruder rate = extruder steps / nominal block duration
@@ -252,8 +246,8 @@ void Extruder::on_speed_change( void* argument ){
      * or simplified : ( extruder steps * ( stepper's steps per minute / 60 ) ) / current block's steps
      * or even : ( stepper steps per minute / 60 ) * ( extruder steps / current block's steps )
     */
-   // printf("update extruder speed in speed change \r\n");
-    this->stepper_motor->set_speed( (adjusted_rate/60L) * ( (double)this->stepper_motor->steps_to_move / (double)this->current_block->steps_event_count ) ); 
+    
+    this->stepper_motor->set_speed( max( ( this->kernel->stepper->trapezoid_adjusted_rate /60L) * ( (double)this->stepper_motor->steps_to_move / (double)this->current_block->steps_event_count ), this->kernel->stepper->minimum_steps_per_minute/60 ) ); 
 
 }