Controlling the position of the drone is a very high level task, so you're coming at this from a top-down direction. I would recommend going bottom-up instead.
In order of simplicity, I'd make a PID controller for:
- Rate / acro mode: This is what "drone racers" fly with. Stabilization is based on a gyroscope (or angular velocity from your physics system). The PID controller trying to reduce the error between a requested angular velocity (from the pilot's sticks) and the measured angular velocity. When you let go of the sticks, the drone should remain at the current orientation (i.e. it should make it appear that angular momentum doesn't exist).
- Angle / level mode: This is what most "toy drones" fly with. Stabilization is based on an accelerometer (or orientation from your physics system). The PID controller is trying to reduce the error between the requested orientation (from the pilot's sticks) and the measured orientation. When you let go of the sticks, the drone should return to 0º pitch/roll. Yaw is actually processed the same way as in #1.
- Hover -- this can be added on top of either of the above. A second layer of stabilization is based on an altimeter (or Y position from the physics system). An additional PID controller is trying to maintain the requested altitude. At middle throttle this PID controller is in full effect, or at negative/positive throttle stick positions this PID controller is attenuated to allow the drone to gain/lose altitude.
- Positional movement from waypoint to waypoint.
Unless you already know how to fly an acrobatic drone and are interested in it, you can probably skip #1 and just do #2 instead (they are mutually exclusive controllers anyway). #3 is a secondary PID controller that is layered over the top of #2.
For doing autonomous flying (move from position to position), you would then add another PID controller on top (#4) which controls the virtual "pilot's sticks", which are fed into the PID controllers from step #2 and step #3. This layer probably doesn't even need to be a PID controller -- you can just get the direction to the target and directly feed that value to the "sticks" without any filtering at all.
So that gives:
Layer #2 -- converts the throttle/yaw and pitch/roll stick commands into motor outputs. Throttle inputs are not stabilized, but pitch/roll are converted into a target absolute orientation, and yaw is converted into a target angular velocity.
Layer #3 -- generates throttle stick movements based on a requested altitude.
Layer #4 -- generates yaw/pitch/roll stick movements based on a requested position/speed.
You should be able to disable layer 3/4 and fly it manually.
So for your questions --
2) don't. The waypoint (#4) layer just needs to know what direction it wants to fly in and how fast. It then pushes the pitch/roll stick on that direction with a magnitude proportional to the speed that it wants. The angle stabilization layer (#2) then converts that stick position into a desired pitch/roll angle, and its PID controller adjusts the motor speeds until the drone's actual pitch/roll converges to the desired one. The conversion from stick position to angle can be as simple as:
float StickToAngle( float stick ) { /*stick is from -1 to +1*/ return stick * 30; }//at full stick movement, the drone will rotate 30 degrees.
When the drone rotates 30º, it will start to move sideways and also begin to lose altitude. The hovering layer's PID controller (#3) will then kick in due to the change in altitude, and will increase the throttle stick in order to increase thrust an maintain altitude. Layer #2 will read the throttle/yaw stick at the same time as it reads the pitch/roll stick, and adjust the motor speeds accordingly.
3) Make a map of which axis requests affect each motor. e.g. a pitch request (nose up please) will have +1 for the front two motors and -1 for the back two motors // a roll request (right wing down) will have +1 for the left two motors and -1 for the right two motors.
Make a sum for each motor and initialize it to zero. For each angular velocity output, add it to each motor based on the map.
e.g. if the request is pitch=0.5, roll=0.3
front-left = 0.5+0.3 = 0.7
front-right = 0.5-0.3 = 0.2
back-left = -0.5+0.3 = -0.2
back-right = -0.5-0.3 = -0.7
If any of these numbers go above 1.0 (100%), then you can divide all of them by the largest value to avoid loss of control during harsh manouvres. You make sure that the motors responses are not too high or too low by tweaking the P value in your Layer#2 PID.
4) Layer #2 needs 3 PIDs, Layer #3 needs 1 PID, Layer #4 needs 4 PIDs.