2
$\begingroup$

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
IMU and PID output

$\endgroup$
1
$\begingroup$

The forces used to control the quad act around its center of mass, causing it to pitch, roll or yaw. Changes in the roll angle are induced by contrary variation of speeds in propellers A and C. Same effect with motors B and D can produce a change in the pitch angle and you will get lateral translation.

  • First of all, make sure that your IMU gives you an accurate estimated angle. Have you validated these angles while motors were spinning?

    Then, define the control error as the difference between the desired angular position, y_des = 0° for example, and the actual measurement at time t, y(t). The y(t) value is the one computed by your IMU so that y(t)€[-1;1]. The error equation for your roll angle will be:

E_roll(t) = roll_des - roll(t)

  • The input to you Roll pid controller should be the error E_roll(t). And use the output, rollPid, in your equation to adjust motor angular velocities as shown below. These speed alterations contribute to the generation of torques in each of the three axis.

a = throttle + rollpid - yawpid;

b = throttle + pitchpid + yawpid;

c = throttle - rollpid - yawpid;

d = throttle - pitchpid + yawpid;

How do you feed your pid and what does steering.roll - gyro.roll is?

From the informations provided by your model description, I don't understand how your axis are oriented in space. Use the equations above if you are using the following reference system

Body reference system

For more details about the pid action see this link, and this.

Hope this helps.

$\endgroup$
  • $\begingroup$ The micro controller & periphery are mounted on sorbothane pads, I've seen, at most 0.001 noise when I tested it strapped down. steering.roll - gyro.roll well I have data object that represents steering, and roll would be the desired roll, and gyro.roll is the actual current roll angle. But I see that wouldn't make much sense. $\endgroup$ – Aage Torleif Dec 9 '14 at 2:38
  • $\begingroup$ Usually, accelrometers are really sensitive to vibrations. 0.001 is the value I get when motors are turned off. When they start spinning measurements are useless untill you apply low pass filters. What's the output of the pid? (thanks for the sorbothane solution, i'll try it!) $\endgroup$ – UserK Dec 9 '14 at 2:53
  • $\begingroup$ I thought that the axis Pitch(I've arbitrarily called X all over my code) would be between two blades. Which is what my little text representation was trying to show. But yea, I thought that the two rotational axis, Pitch and Roll were between two blades, and that yaw was just the translation of the two. $\endgroup$ – Aage Torleif Dec 9 '14 at 5:49
  • 1
    $\begingroup$ @MatUtter Ok, you are free to choose the orientation of the body reference system in the inertial frame. This choise will affect the theory behind equations. But first check whether the arrows drawn on the IMU are directed along your beloved axis. $\endgroup$ – UserK Dec 9 '14 at 9:16
  • 1
    $\begingroup$ @MatUtter if the axis x,y and z of the IMU are not aligned with the Xb, Yb and Zb axis of the body frame respectively you will need extra calculations to compute projections on the axis... usually the IMU is positioned in order to avoid this situation. $\endgroup$ – UserK Dec 9 '14 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.