Our team has a motor driven arm mechanism that rotates around an axis and has a potentiometer for feedback.
The arm is fairly heavy and unbalanced, and it's range of motion is significant (180deg, give or take a bit). Since the torque required to counteract gravity varies with the angle of the arm, it seems like the simplest form of PID control is not appropriate (ie: directly driving the motor from the PID constants and potentiometer input).
I've kicked around a few different ideas, but I'm not experienced enough with controls to know a good solution when I see one. All of my ideas hinge on the idea that the torque needed to counter-act gravity at a given angle is the cosine of the angle multiplied by the torque required at 0deg (please correct me if this is wrong

)
So here are the different approaches I have considered:
1) Multiplying the output of a PID loop tuned for the 0deg position before it is sent to the motor. Either
motor_output = PID_output * cos(theta) //working against gravity
motor_output = PID_output - (PID_output * cos(theta)) //when assisted by gravity
(We will likely have special cases to handle angles close to 90deg when the setpoint is not 90deg, these can be ignored)
2) Using the feed-forward (F) term of the PID loop, where the reference F(0deg) is the force required to maintain a position of 0deg, and constantly updating the F term based on the current position (or possibly target position):
F = F(0deg) * cos(theta) //Different PID values would remain unchanged with angle
3) Use discrete sets of PID constants at different angles, each tuned for operating within a particular range of the full swing of the arm, for each direction, and each load requirement.
Which of these approaches makes the most sense? Is there a better method that I haven't thought of?
I've implemented case 1 (but cannot test yet), although I'm beginning to consider case 2 after learning how the F term is used.
I'm also a little curious what the best method for minimizing I-term wind-up, my plan is to simply disable the I term until we've approached the set-point, but I'm curious how others typically handle this.