I've built a quadcopter and a rig to safely test it on. I'm working on the PID for controlling the roll pitch and yaw. I understand how a PID works on a more simple plant like say a robot with wheels and I'm just really in the dark ( i believe ) with controlling and stabilizing a quad.
My question, how do I make these sensor readings effectively alter the motors' throttle?
Firstly, my approach is based on this model,
CW motors A,C
CCW motors D,B
Front
+1 pitch
C D
-1 roll \-/ +1 roll right
/-\
B A
-1 pitch
My IMU calculates the roll and pitch as a value between +-1.0 where being perfect balance will read as 0.0. Now a degree of +-1.0 means approximately 90 degrees from the original axis.
A normal input to the pitch to go forward would be something like 0.33, meaning tilt 30 degrees forward.
Now my motors take some value between 0 and 100. Originally I thought this would mean i would have to modify my motor values like so.
c = throttle - roll + pitch + yaw
d = throttle + roll + pitch - yaw
b = throttle - roll - pitch - yaw
a = throttle + roll - pitch + yaw
Finally, I'm taking those floating point numbers, from the IMU and computing them like with this method, which appears to be the normal way as far as I've found.
RollPId.Compute( steering.roll - gyro.roll );
// pid_t is either #define pid_t float or double, I know its a reserved type but, a pre-processor definition will change that before it would matter.
pid_t Compute(pid_t input) {
uint64_t now = millis();
if( ( now - last_time ) >= sample_time ) {
pid_t error = set_point - input;
error_sum += error;
pid_t d_error = error - error_last;
*output = kp * error + ki * error_sum + kd * d_error;
error_last = error;
last_time = now;
}
}
I don't know where to go from here? Also I have angular rate calculated from my IMU i just haven't encountered a solution that called for it.
EDIT. Below is a graph of roughly 300 readings (20ms apart) so roughly six seconds where i hold it in one hand and roll it roughly 45degrees right. with kp=1 ki=0 kd=0