Gravity Feedforward
The constant that holds an arm up on its own, so the PID only has to correct what is unpredictable.
Inputs
The arm
The drive
If you have measured it
Raise the output until the arm stops falling. Leave at 0 if you have not measured it.
The gap between these two is friction, and it is worth knowing.
Results
Feedforward constant, kG
—% of full output
As a voltage
—V
As an 8-bit command
—of 127
As millivolts
—mV
Torque to hold, arm level
—lb·in
Torque at full output
—lb·in
Command at the angle below
—%
Friction, from your measurements
—% of output
—%
A measured hold that is lower than computed is friction helping. Much higher and one of the weights is wrong.
Feedforward through the sweep
The bar shows what feedforward alone commands at this angle. It is largest with the arm level, where gravity has the most leverage, and falls to nothing straight up or straight down.
Show the numbers behind this chart
The feedforward command at each angle, which is the table you would put in code if you preferred a lookup to a cosine.
How this is calculated
A PID controller works by being wrong first. It waits for error to build, then reacts to it. That is the right way to handle things you could not have known about: a game object landing in the intake, a partner robot shoving you.
Gravity is not one of those things. If you know the arm's angle, you know exactly what gravity is doing to it, and you knew it before the error existed. Holding an arm up with the P term means choosing to be surprised by the same entirely predictable force, several hundred times a second.
command = kG × cos(angle)Add that to the loop's output and the arm holds itself at any angle. The PID is then left with only what is unpredictable, which is a much smaller job and a far easier one to tune.
With your numbers
Why cosine
Torque is force times the perpendicular distance to the pivot. With the arm level the whole of its length is perpendicular to gravity, so the leverage is at its maximum. Straight up or straight down the weight pulls along the arm rather than across it, and the torque is zero. A vertical arm needs no holding at all.
Why the command scales with torque
At zero speed a motor's torque is proportional to the current through it, and current is proportional to the voltage you command. So a stationary arm needing a third of the motor's stall torque needs a third of full output, and the constant is just a ratio.
This is only true while the arm is holding still. Once it moves, back-EMF enters and the relationship changes, which is what the velocity feedforward term is for, and a separate constant.
Measure it if you can
The computed figure depends on weights you estimated and a gear ratio you hopefully got right. The measured one depends on nothing but the arm. Raise the output slowly until the arm stops falling: that command is kG, directly.
If measured and computed disagree by a lot, the interesting question is which. A measured value well below computed usually means friction is holding some of the weight for you. Well above, and something is heavier than you think, or the gearing is not what you believe it is.
The gap between holding and lifting is friction
Friction resists whichever way the arm is trying to go. Holding still it helps you, so the command that holds is less than gravity alone would need. Starting to rise it opposes you, so that command is more. The difference between the two measurements is twice the friction, and knowing it is worth more than most tuning.
A large gap means a mechanism that will behave differently going up than coming down, and no single feedforward constant will suit both.
Code for these numbers
Only the numbers come from this page. How your program uses them is up to you, so read each line before you paste it.
Make a notebook page
Turns this calculation into a dated engineering notebook page: the setup, data, results, figures, working and sources, numbered and cited. You add the goal, the decision and the reflection in your own words, plus photos and sketches. Print it, paste it into Google Docs, or download a Word file or slides.
Save this run, and compare
Keeps what is on screen so you can change something and see both sides of the change. Saved in this browser only, never uploaded.
Sources & assumptions
Cartridge stall torques are VEX figures. Everything else is the arm you described.
The proportionality between holding torque and commanded voltage is the standard model for a brushed DC motor at zero speed, where back-EMF is zero and current is set by the applied voltage against winding resistance. It is a model: a V5 motor's controller limits current near stall, so a computed constant above roughly 60% should be treated as an estimate and checked on the robot.
- Purdue SIGBots Wiki: VEX Motors — checked August 2026
Where this goes next
Explore further on the full mapWhere the answers on this page can be used, and which tools could have given you the numbers it asks for.
Comes after
Feedforward CharacterizationYou are here
Gravity Feedforward
Where your answer goes
PID Error Analyzerrecord the arm moving with kG on and tune whatever error is leftRubber Band Assist Calculatorsee how much rubber bands could take the holding load off your motorsbrings your lift load with itMotor Diagnostics Dashboardcheck that holding the arm up all match is not overheating the motorsa number carries across the next question it raises