I was going to link to the thread where I explained what "FF" is, and other relevant information (
https://www.eevblog.com/forum/projects/pid-motor-control/ ) but just now realized it's your thread but you haven't spent much effort in reading and trying to understand the replies. Start from there.
Lack of "training" in control theory does not matter because if you learned this stuff in university for example, you would completely lack the big picture and totally unable to do anything. Control theory is confusing, because it concentrates so much on explaining what PID is and then about zillion of esoteric ways of tuning and autotuning of the coefficients, to the point that you easily lose the big picture, which should be control, not the feedback loop in isolation. Feedforward is a great example of this phenomenon at work; its complete lack is a telltale sign that the book / whatever resource we are talking about is very limited and only for academic interest, not very useful for real world.
Similarly, choice of
which parameters are inputs, which are outputs is way more important than the exact tuning process of the coefficients. (Typical example being controlling voltage (roughly: PWM duty cycle), when you should be controlling current, if you want stable and quickly reacting loop.
The average motor current should simply be directly proportional to the PID output that's driving the PWM controller.
No, the idea is to remove the "should" here and make the motor current an actually controlled parameter: add feedback! Control is needed because if you just give PWM duty (or voltage) to a motor, current heavily depends on the voltage difference between applied and back-EMF.
PI loop is fine: (current setpoint - current measurement) -> PWM duty setting. Easy to tune, doesn't need to be exact. If this is brushed motor, then it's literally just that: current error (using shunt resistor etc.) -> PI -> PWM duty. (For a BLDC, you need to do the FOC trickery, i.e., measure phase currents, vector rotate them in sync with measured rotor position, then have two PI controllers for Iq and Id currents, then rotate the PWM duties back to the moving rotor.)
The current might be "average" yes but only during very short time. Usually with a lot of motor inductance and high enough PWM frequency, current ripple is small, and you can just sample the current always at the same point during the PWM period, no averaging needed or wanted. Response needs to be fast.
If I interpret what you said correctly I need to write a complete new set of test code for the PIC that only handles motor speed to determine PID coeefficients for the a motor speed PID.
Do it in this order:
1) Write a current controller. This basically creates a
torque controller. Setpoint is current, which is roughly torque, which for a freely rotating rotor (not much friction, no "resistive" mechanical load, just mass) is ~ acceleration.
Test it: change setpoints quickly, measure the actual current (for example, logging the current measurements in .csv file). Tune P, I for fastest possible reaction to setpoint change, without much overshoot. The idea is, with current = 0, motor freewheels i.e. slows down slowly only due to friction. With current > 0, positive torque is generated and motor accelerates. With current < 0, negative torque is generated and motor decelerates, regenerating into the DC bus. Acceleration, i.e. rate of speed change depends on magnitude of current.
2)
Now that you have this sorted out, start working with speed controller. Setpoint = speed command. Output = current command to the current controller you just did.
At this point, you should have whatever mechanical system you are tuning for already physically driven by the motor!
Contrary to feedback literature, I'd say start with FF from setpoint and another FF from setpoint's derivative. These are easy because you have the setpoint variable available. Just
current = F1 * speed_setpoint + F2 * (speed_setpoint - prev_speed_setpoint);
Adjust F1 and F2 until you get the ballpark right response. Not the exact speed, can't do that without feedback, but right type of response to speed setpoint changes, without huge overshoot. The idea is, you have just two parameters, you can do it. Make yourself a development environment where you can change these values in the fly, without reflashing the firmware. You quickly learn what I mean when you play around for 10 minutes!
And
now add P,I,D. Keep D=0 first, again only two parameters to tune at once. Make the motor run at constant speed you set without oscillating. Do quick changes on that setpoint and make it find the new speed quickly and without much overshoot.
Once done,
3) Only now start work on the position feedback.
I should then use the position based pid to output a speed value based on current position versus the position setpoint?
Exactly.
But it doesn't necessarily need to be exactly that way. It's just how it's usually done with proven track record. I don't know if it is intuitive, many things in engineering are not. Being such blockhead I am, I have once tried direct positional feedback (position error -> motor current) and ended up rewriting it later with this classic position -> speed cascade.