How to work with PID controller / OpenCV for A.R Drone 2.0?
I have been looking at codes for autonomous drones and encountered this one on this repository: https://github.com/puku0x/cvdrone . 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.
if (contour_index >= 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));
// Tracking
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 << "(vx, vy, vz, vr)" << "(" << vx << "," << vy << "," << vz << "," << vr << ")" << std::endl;
std::cout << "Altitude = " << ardrone.getAltitude() << "%" << 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 > 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 > 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);
}
Link broken.
Link Fixed.