Correction of a crooked cylinder

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
bdellal
 
Posts: 51
Joined: Tue Jun 10, 2014 6:00 pm

Re: Correction of a crooked cylinder

Post by bdellal »

Hi,
I ran into a problem with the while loop:
The actuators are moving too fast for the electronics to react. I wonder if this is just because of inefficient programming or if the arduino hits its borders here.

This is (one of) my while loop(s):

Code: Select all

while (vectorChange < 0.05) { // while the length is decreasing
                    
                      //TAKE MEASUREMENTS
                      int i;
                      for(i = 0; i<filter; i++)  {
                      analog_read_value_1 += analogRead(sensor_1);
                      }
                      analog_read_value_1 /=(filter+1);
                      
                      sensor_voltage_1 = analog_read_value_1/1023*5;
                      distance_1 = -0.117190880571932 * pow(sensor_voltage_1, 0) +  0.543037208594546 * pow(sensor_voltage_1, 1) +  0.233122218845504 * pow(sensor_voltage_1, 2) + -0.0743638185159096 * pow(sensor_voltage_1, 3) +  0.00956562734274045 * pow(sensor_voltage_1, 4);
                      
                      int j;
                      for(j = 0; j<filter; j++)  {
                      analog_read_value_2 += analogRead(sensor_2);
                      }
                      analog_read_value_2 /=(filter+1);
                      
                      sensor_voltage_2 = analog_read_value_2/1023*5;
                      distance_2 = -0.117190880571932 * pow(sensor_voltage_2, 0) +  0.543037208594546 * pow(sensor_voltage_2, 1) +  0.233122218845504 * pow(sensor_voltage_2, 2) + -0.0743638185159096 * pow(sensor_voltage_2, 3) +  0.00956562734274045 * pow(sensor_voltage_2, 4);
                      
                      int k;
                      for(k = 0; k<filter; k++)  {
                      analog_read_value_3 += analogRead(sensor_3);
                      }
                      analog_read_value_3 /=(filter+1);
                      
                      sensor_voltage_3 = analog_read_value_3/1023*5;
                      distance_3 = -0.117190880571932 * pow(sensor_voltage_3, 0) +  0.543037208594546 * pow(sensor_voltage_3, 1) +  0.233122218845504 * pow(sensor_voltage_3, 2) + -0.0743638185159096 * pow(sensor_voltage_3, 3) +  0.00956562734274045 * pow(sensor_voltage_3, 4); 
                      
                      int l;
                      for(l = 0; l<filter; l++)  {
                      analog_read_value_4 += analogRead(sensor_4);
                      }
                      analog_read_value_4 /=(filter+1);
                      sensor_voltage_4 = analog_read_value_4/1023*5;
                      distance_4 = -0.117190880571932 * pow(sensor_voltage_4, 0) +  0.543037208594546 * pow(sensor_voltage_4, 1) +  0.233122218845504 * pow(sensor_voltage_4, 2) + -0.0743638185159096 * pow(sensor_voltage_4, 3) +  0.00956562734274045 * pow(sensor_voltage_4, 4);
                      
                       y_1 = distance_1 + r + sensor_2_y_position;
                       y_2 = distance_2 + r + sensor_2_y_position;
                       x_1 = distance_3 + r;
                       x_2 = distance_4 + r;
                       
                       vector_length = sqrt( sq(x_2-x_1) + sq(y_2-y_1));
                        
                       x_1_center = x_1 - 114.08;
                       x_2_center = x_2 - 114.08;
                        
                       direct = atan2((y_2 - y_1),(x_2_center - x_1_center));
        
        
        
                      //ACTUATE CYLINDER
                      digitalWrite..... ACTUATION
        
                      vectorChange = vector_length - oldLength;
                      oldLength = vector_length;
                      
                      if (vector_length < max_tolerance)  {        
                        break;
                      }
                    }

So, what my intention was:
Image

What is happening most of the time:
Image

Any suggestions? I cannot slow the actuators down more.

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: Correction of a crooked cylinder

Post by adafruit_support_bill »

Not sure what you are intending there. But the code looks like it is trying to do straight on/off control. I think what you may need is some PID control.

http://brettbeauregard.com/blog/2011/04 ... roduction/

User avatar
bdellal
 
Posts: 51
Joined: Tue Jun 10, 2014 6:00 pm

Re: Correction of a crooked cylinder

Post by bdellal »

Like I said earlier, I am intending to to catch the moment when my measured value switches from decreasing to increasing again.

If I understood it right, a PID controller would keep my system close to a desired setpoint. I am not sure how to use that for my problem.

User avatar
bdellal
 
Posts: 51
Joined: Tue Jun 10, 2014 6:00 pm

Re: Correction of a crooked cylinder

Post by bdellal »

Like I said earlier, I am intending to to catch the moment when my measured value switches from decreasing to increasing again.

If I understood it right, a PID controller would keep my system close to a desired setpoint. I am not sure how to use that for my problem.

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: Correction of a crooked cylinder

Post by adafruit_support_bill »

I don't know what mode of 'actuation' you are using. But mechanical systems follow physical laws and don't start and stop instantaneously. You need to slow down as you approach the desired position or you will overshoot.

You want your actuation force to be proportional (the P in PID) to the error (distance from the minimum point).

User avatar
bdellal
 
Posts: 51
Joined: Tue Jun 10, 2014 6:00 pm

Re: Correction of a crooked cylinder

Post by bdellal »

I am using an hydraulic cylinder to push on a part to straighten it. I understand that I will overshoot maybe but I want to keep the overshoot as small as possible and with my current method, the misalignment jumps from:
0.51
0.48
0.40
0.22
1.15

I would like it to look like:
0.51
0.48
0.40
0.22
0.30

I think my control loop would be fine, if my measurement resolution would be high enough.

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: Correction of a crooked cylinder

Post by adafruit_support_bill »

Can you slow down the actuators?

User avatar
bdellal
 
Posts: 51
Joined: Tue Jun 10, 2014 6:00 pm

Re: Correction of a crooked cylinder

Post by bdellal »

No, unfortunately not. I already slowed them down as much as possible.

User avatar
bdellal
 
Posts: 51
Joined: Tue Jun 10, 2014 6:00 pm

Re: Correction of a crooked cylinder

Post by bdellal »

What do you think about that?

Code: Select all

//PID 
//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

int WindowSize = 100;
unsigned long windowStartTime;


void setup() {
  //Variables used for PID
  //initialize the variables we're linked to
  
  windowStartTime = millis();
  Setpoint = 0;

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  
  myPID.SetSampleTime(50);

}
void loop() {
                      //PID
                      Input= vectorChange;
                      myPID.Compute();
        
                      /************************************************
                       * turn the output pin on/off based on pid output
                      ************************************************/
                      unsigned long now = millis();
                      if(now - windowStartTime>WindowSize)
                          { //time to shift the Relay Window
                          windowStartTime += WindowSize;
                          }
                      if(Output > now - windowStartTime)   {
                      
                          //ACTUATE CYLINDER
                          digitalWrite(valve_2_push, HIGH);
                          digitalWrite(valve_3_push, HIGH);
                          digitalWrite(valve_4_push, HIGH);
                          digitalWrite(valve_5_push, HIGH);
                          digitalWrite(valve_6_push, HIGH);
                          
                          digitalWrite(valve_2_pull, LOW);
                          digitalWrite(valve_3_pull, LOW);
                          digitalWrite(valve_4_pull, LOW);
                          digitalWrite(valve_5_pull, LOW);
                          digitalWrite(valve_6_pull, LOW);
                          
                          digitalWrite(valve_1_push, LOW);
                          digitalWrite(valve_1_pull, HIGH);
                          
                          
                          pullback = 1;
                          
                          }
                      

                      vectorChange = vector_length - oldLength;
                      oldLength = vector_length;

User avatar
adafruit_support_bill
 
Posts: 88142
Joined: Sat Feb 07, 2009 10:11 am

Re: Correction of a crooked cylinder

Post by adafruit_support_bill »

The real question is how does it work? I don't know how well your actuators respond to time-proportional-outputs or pulse-width modulation.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”