아두이노

Delta robot

내동 2023. 10. 22. 17:31

 #include <Servo.h>
  Servo  m1,m2, m3;
  double sP= 76,  Len=524,  len= 1244;
  double wB=164,  wP=22,  uP=44;
  double QHori1=0, QHori2=0, QHori3=0;
  double Pi= 3.141592;

   void setup() {
  m1.attach(3);
  m2.attach(6);
  m3.attach(9);
  Serial.begin(9600);
  Serial.setTimeout(0);
   }

  void loop() {
  
      MoveToXYZ(0,0,-1064.25, 1000);  // Len 이 수평일때의 위치임
       MoveToXYZ(0,0,-1064.30,1000);  
      MoveToXYZ(0,0,-1064.15,1000);
   while (true);
  }

  //주어진 end점 이송후 대기
   void MoveToXYZ(double x, double y, double z, double msec)
   { double Q1Deg, Q2Deg, Q3Deg;
      bool  success = InverseKin(x,y,z, Q1Deg, Q2Deg, Q3Deg);
       if( !success) return;
      double QMotor1Deg, QMotor2Deg, QMotor3Deg;
      MotorDegFromInverKIn(Q1Deg, Q2Deg, Q3Deg, QMotor1Deg, QMotor2Deg, QMotor3Deg);
      m1.write(QMotor1Deg);
      m2.write(QMotor2Deg);
      m3.write(QMotor3Deg);
 String str= "QMotor1Deg="+String(QMotor1Deg)+"   QMotor2Deg =" + String(QMotor2Deg)
                +"   QMotor3Deg:=   "+String(QMotor3Deg);
    Serial.println(str);
      delay(msec);
    }

  //역기구학 풀이 각도를 모터 명령 각도로 전환
    void  MotorDegFromInverKIn(double Q1Deg, double Q2Deg, double Q3Deg,  
          double& QMotor1Deg, double& QMotor2Deg, double& QMotor3Deg)
          { QMotor1Deg= -Q1Deg + QHori1;
            QMotor2Deg= -Q2Deg + QHori2;
            QMotor3Deg= -Q3Deg + QHori3;
          }
    //DeltaRobot의 역기구학 풀이
     bool InverseKin(double x, double y, double z, double& Q1Deg, double& Q2Deg, double& Q3Deg)
       { double a= wB-uP;
         double b= sP/2.0- sqrt(3)/2.0*wB;
         double c= wP- wB/2.0;
         double x2=x*x,  y2= y*y, z2=z*z;
         double a2= a*a, b2= b*b, c2= c*c;
         double Len2 = Len*Len,  len2= len*len;

         double E1= 2 * Len*(y+a);
         double F1= 2*z* Len;
         double G1= x2+y2+z2+a2+Len2+2*y*a-len2;

         double E2= -Len*(sqrt(3)*(x+b)+y+c);
         double F2= 2*z*Len;
         double G2= x2+y2+z2+b2+c2+Len2+2*(x*b+y*c)-len2;

         double E3= Len*(sqrt(3)*(x-b)-y-c);
         double F3= 2*z*Len;
         double G3= x2+y2+z2+b2+c2+Len2+2*(-x*b+y*c)-len2;

         double D1= E1*E1+ F1*F1-G1*G1;
         double D2= E2*E2+ F2*F2-G2*G2;
         double D3= E3*E3+F3*F3-G3*G3;
       //음수이면 허근이다
         if(D1<0 || D2<0 || D3<0) {Q1Deg=  Q2Deg = Q3Deg= 0;  return;}
         double t11= (-F1+sqrt(D1))/(G1-E1);
         double t12= (-F1-sqrt(D1))/(G1-E1); 

         double t21= (-F2+sqrt(D2))/(G2-E2);
         double t22= (-F2-sqrt(D2))/(G2-E2);

         double t31= (-F3+sqrt(D3))/(G3-E3);
         double t32= (-F3-sqrt(D3))/(G3-E3);

         double Q1Rad1= 2*atan(t11);
         double Q1Rad2= 2*atan(t12);
         double Q2Rad1= 2*atan(t21);
         double Q2Rad2= 2*atan(t22);
         double Q3Rad1= 2*atan(t31);
         double Q3Rad2= 2*atan(t32);

         //Q1Deg   팔이 밖으로 벌어질때 해을 얻는다(최소값 선택)
         if(abs(Q1Rad1) <= abs(Q1Rad2)) Q1Deg= Q1Rad1*180/Pi;
         else Q1Deg= Q1Rad2 *180/Pi;
         //Q2Deg
         if(abs(Q2Rad1) <= abs(Q2Rad2)) Q2Deg= Q2Rad1*180/Pi;
         else Q2Deg= Q2Rad2 *180/Pi;
         //Q3Deg
         if(abs(Q3Rad1) <= abs(Q3Rad2)) Q3Deg= Q3Rad1*180/Pi;
         else Q3Deg= Q3Rad2 *180/Pi;
          return true;
       }     

'아두이노' 카테고리의 다른 글

inverse kinematics  (0) 2023.11.13
Forward Kinematics(순운동학)  (0) 2023.11.10
cutter_5  (0) 2022.04.11
1-wire 통신(온습도측정)  (0) 2022.03.13
세탁기1  (0) 2022.01.28