title: How to work with PID controller for A.R Drone 2.0?
body: <p>I have been looking at codes for autonomous drones and encountered this one on this repository:<a href="https://github.com/puku0x/cvdrone" rel="nofollow noreferrer">https://github.com/puku0x/cvdrone</a> . Im trying to understand the code, I am new to controller algorithms and OpenCV. I tried going on the OpenCV website and understand functions but it didn't help very much. Any help would be appreciated.</p>
  
  <pre><code>        // Tracking
  
      if (contour_index &gt;= 0) {
          // Moments
          cv::Moments moments = cv::moments(contours[contour_index], true);
          double marker_y = (int)(moments.m01 / moments.m00);
          double marker_x = (int)(moments.m10 / moments.m00);
  
          // Show result
          cv::Rect rect = cv::boundingRect(contours[contour_index]);
          cv::rectangle(image, rect, cv::Scalar(0, 255, 0));
  
          if (track) {
              const double kp = 0.005;
              vx = kp * (binalized.rows / 2 - marker_y);;
              vy = 0.0;
              vz = kp; 
              vr = kp * (binalized.cols / 2 - marker_x);
              std::cout &lt;&lt; "(vx, vy, vz, vr)" &lt;&lt; "(" &lt;&lt; vx &lt;&lt; "," &lt;&lt; vy &lt;&lt; "," &lt;&lt; vz &lt;&lt; "," &lt;&lt; vr &lt;&lt; ")" &lt;&lt; std::endl;
              std::cout &lt;&lt; "Altitude = " &lt;&lt; ardrone.getAltitude() &lt;&lt; "%" &lt;&lt; std::endl;
          }
                // Marker tracking
      if (track) {
          // PID gains
          const double kp = 0.001;
          const double ki = 0.000;
          const double kd = 0.000;
  
          // Errors
          double error_x = (binalized.rows / 2 - marker.y);   // Error front/back
          double error_y = (binalized.cols / 2 - marker.x);   // Error left/right
  
          // Time [s]
          static int64 last_t = 0.0;
          double dt = (cv::getTickCount() - last_t) / cv::getTickFrequency();
          last_t = cv::getTickCount();
  
          // Integral terms
          static double integral_x = 0.0, integral_y = 0.0;
          if (dt &gt; 0.1) {
              // Reset
              integral_x = 0.0;
              integral_y = 0.0;
          }
          integral_x += error_x * dt;
          integral_y += error_y * dt;
  
          // Derivative terms
          static double previous_error_x = 0.0, previous_error_y = 0.0;
          if (dt &gt; 0.1) {
              // Reset
              previous_error_x = 0.0;
              previous_error_y = 0.0;
          }
          double derivative_x = (error_x - previous_error_x) / dt;
          double derivative_y = (error_y - previous_error_y) / dt;
          previous_error_x = error_x;
          previous_error_y = error_y;
  
          // Command velocities
          vx = kp * error_x + ki * integral_x + kd * derivative_x;
          vy = 0.0;//kp * error_y + ki * integral_y + kd * derivative_y;
          vz = 0.0;
          vr = 0.0;
  
      }
      }
  
      // Display the image
      cv::putText(image, (track) ? "track on" : "track off", cv::Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 0.5, (track) ? cv::Scalar(0, 0, 255) : cv::Scalar(0, 255, 0), 1, cv::LINE_AA);
      cv::imshow("camera", image);
      ardrone.move3D(vx, vy, vz, vr);
  }
  </code></pre>