Vertical Arm PID Tuning

Hi all,

Looking forward to this season! We are using a velocity controlled, 2 motor (Talon 500) vertical arm, but are struggling with finding information on how to PID tune it. Any help would be greatly appreciated!

Thank you in advance!

PID tuning is about the same on anything. Start with a small amount of p, increase until light oscillation, and add d until oscillation goes away. Because your arm is fighting gravity, you’ll want to start with arbitrary feedforwards, but beyond that it’s about the same as anything.

Tuning a Vertical Arm Position Controller — FIRST Robotics Competition documentation is a recently added resource that explains how to design and tune a control algorithm for this situation. Check it out if you haven’t and ask away if you have questions!

1 Like

Hi, thanks for the fast response!

Just to clarify, I meant to say we’re using ControlMode.PercentOutput to control our talon motors. Do we need feed forwards in this case?

Yes absolutely. Precise control of an arm is going to be much easier with arbitrary feedforwards. Without it, your control loop is going to be constantly fighting gravity which will make it unstable. Can you describe your arm in simple terms to me? Like degrees of freedom and such.

Also if you’re doing PIDF tuning I assume you’re going to be using ControlMode.MotionMagic correct?

We’re using a vertical arm with motion from 0-90 degrees and are using ControlMode.PercentOuput. We have a potentiometer that tracks the motion of our arm, which we use to stop the arm at the correct position.

I’m not familiar with ControlMode.MotionMagic; how does it work?

Is there a falcon motor config function that allows us to input custom feedforwards when using ControlMode.PercentOutput?

Trust me, you don’t want to use percent output for this (unless you are using a profiled pid controller). You need more precise control. Motion magic is a control mode that generates trapezoidal motion profiles given acceleration and cruise velocity. This makes smooth motion very easy because it will decelerate smoothly to arrive at a position at zero velocity.

feedforwards is just another percent output, so if you intended to use it with % output you could just add it to your input.

the math you need is something like

feedforwards % output = (center of mass * mass * cosine arm angle * gravity)/ stall torque of your system

Why can’t we use ControlMode.PercentOutput. Won’t the motors stop at the desired angle simply using simple if-statements. We’ve set our motors to run at a relatively slow speed, so I do not believe overshooting will occur.

Also, where can we find more information on ControlMode.MagicMotion? Is it simply a trapezoidal motion profiled velocity controller? Also, do you have some example code for a motor set function using motion magic?

How can we tune an arbitrary feedforward?

Percent output is very rudimentary control. Your velocity is proportional to your resistance so it will vary throughout a motion, and you won’t be able to run it very fast or you will overshoot.

information on motion magic can be foundhere

arbitrary feedforwards should require very little tuning. Its goal is counter gravity so that your arm is “weightless”. So you can calculate that value by finding the amount of torque done by gravity on your arm as a function of theta.

Once again, thanks so much for your help!

Is there a specific equation we could use to calculate the arbitrary feed forward? If so, where can I find this?

This example is provided in the documentation:
motorcontroller.set(ControlMode.MotionMagic, targetPos, DemandType.ArbitraryFeedForward, maxGravityFF * cosineScalar);
Do we ever pass cruise velocity and accleration into the function?

You are trying to change your motors angular position. A way to do that would be with Position. PercentOutput simply outputs a voltage/speed to your motor. You would need to use a PID controllers output if you were using PercentOutput

1 Like

I assume youre referring to the components of the trapezoidal motion profile. If so, no, those are generated for you by MotionMagic (thus the “magic”). Instead you simply tell it where it is (via sensor) and where you want it to be, and it will figure out the rest.


We want to use motion magic, but want to restrict our motor movement between 0 and 90 degrees. How can we cap the internal encoder to a range between 0 and 90 degrees?

with motion magic, your argument is a position. As long as that position is within your range you shouldn’t exceed it. However, for safety setting soft limits on the motor is good practice.

the equation is just the same equation you learned in physics to compute torque. It should look something like this.

feedforwards % output = (center of mass * mass * cosine arm angle * gravity)/ stall torque of your system

you only set cruise velocity and acceleration once on startup (unless you want to change them for whatever reason) the motor object should have methods for both.

Is the targetPosition parameter that we pass into the motor set function in falcon ticks?


How do we calculate/find the maxGravityFF value?

motorcontroller.set(ControlMode.MotionMagic, targetPos, DemandType.ArbitraryFeedForward, maxGravityFF * cosineScalar);

Think about when you are holding a weight with your arm extended. At what angle is hardest to hold the weight?