PID with Elevator programming

Our team this year is using an elevator to transport the balls and hatches to the goals. From a programming standpoint, I figured from reading a lot of posts on this forum that PID control is the proper way to go in controlling the elevator. Right now I’m a little lost with the overall process of programming the mechanism, given that it’s my first time doing such a thing.

My original plan would be to have a default command for the elevator that simply keeps the elevator at a raised set point, where it can also listen to button presses or joystick commands to lift or lower the elevator. From then on I can use a different command that sets the lift to a desired setpoint, which after the command ends I’ll keep track of the current position so that the original default command would be able maintain the height of the elevator.

I was thinking of using velocity control for the manual movement to move the lift at a desire speed and position control for when I want to set a position as a parameter. Are there any drawback to using two different types of control? Would it be best just to use position control?

If I was using, say position control and buttons as a manual for raising the elevator, would I just simply add a constant to the desired height as long as the button is pressed and feed that into the talonsrx?

By position/velocity control I mean the control modes on the talonsrx

I can’t say I completely understand what your proposed strategy, but I think I understand the problem.

PID is the way to go, at least the P. Basically, you set the power lower the closer you get to your set point. This will eventually stall out and give you a natural hold a that position.

If your default elevator subsystem command is built with a set point, where the elevator is always trying to get to that set point and result it in holding slightly below that setpoint.

You can set the setpoint of the command externally to pre-defined positions and it will automatically adjust to that position. You can additionally, program the joystick up/down to update the setpoint up or down by small increments to manually adjust it and it should automatically adjust to those updates.

Good luck.

I would recommend P and D with Motion Magic for the elevator to make sure you can get to your set point. The higher P gets, the closer you’ll get but you may oscillate more. To fix that, add some D.

Here are some resources that might help. The TalonSRX motor training course PDF is a great resource and has several guides near the end (the last 6 slides or so) on tuning systems like yours. On the resources page, there are links to several GitHub repositories (Grapher and Telemetry Utility) that are incredibly helpful when tuning systems with talons.

1 Like

I get the overall theory behind PID and the tuning, I was just wondering how I could apply it in the context of java in VSCode. My question was more about the logistics of command-based programming and how I could apply my idea within that framework.

Would position control suffice? I’m still fairly new to using PID on the talon SRX and I’m not sure if I would have time to fully test the motion magic option. Would using both position and velocity control work or would that have issues in controlling the elevator?

Using both in conjunction would be best. Since you’ll probably be moving a load up and down that’s going to move while the elevator goes up, you want a constant velocity. The position loop ensures that we stay at the goal.

We used the control system you describe on our elevator last year, and it worked well enough that we plan to use it on our elevator this year. You can see that particular bit of logic on lines 66-82 here. The commented-out section above it is the “jump to a specific point” logic, which we used last year, but we haven’t yet computed those for this year’s robot.

We debugged our position control system on a standalone motor with an encoder plugged into it. This really helped work out the kinks. We got to a set of PID constants with it that wouldn’t go wild, before ever running it on the real robot.

One practical side note: remember an elevator’s a big mechanism, and if it runs out of control, it’s relatively easy to hurt someone, or more likely, damage some mechanism. Just remember your normal safety procedures and you’ll be fine. Make sure people are clear before activating, and make sure someone has their finger on the disable switch, and you’re good.

Here are some specific things to watch out for:

  • Polarity of the encoder. If the robot is disabled and you push the elevator up, your encoder value should go up too. This bit me the other day.
  • Polarity of the motor. If either the motor or the encoder is driving backwards you can get a runaway feedback loop. Drive very slow when you start!

Hope that helps!

Here is an example of what our team did last year, as you can see it’s a mix of motion profilling and PID. If the distance is large enough, a path is generated until it reaches a close enough point.

Yeah, I would recommend using position control with buttons for different heights. One thing you should be able to do is set a command that only changes the height while you have the default command just constantly refreshing the PID loop. Just make sure when you are making commands for changing the desired value, that command doesn’t require the subsystem. This was something that we found while rebuilding code(although we were using manual PID just for practice sake so it might work differently with Talon PID) for offseason competition because if the command for changing the value requires the same subsystem as the PID loop, it will put a stop on PID loop.

We used the control system you describe on our elevator last year, and it worked well enough that we plan to use it on our elevator this year. You can see that particular bit of logic on lines 66-82 here . The commented-out section above it is the “jump to a specific point” logic, which we used last year, but we haven’t yet computed those for this year’s robot.

When you used speed did you use the talon SRX PID version for velocity control? If not, how were you able to account for gravity when moving down?

I strongly suggest pushing values (such as your kP value and target position) when you initialize to smart dashboard and then getting those values on a loop so you can tune your PID via SmartDashboard. This cuts down on the number of deploys and take a lot of pain out of this kind of system.

We used Motion Magic this year for our 6 bar lift and wrist. it’s holding position quite well and the motion is exceptional. Granted I spend two months of preseason struggling with it on the drivetrain. If you’re interested in looking at our unfinished lift and wrist code at present, to see how we use SmartDashboard, feast your eyes:

WPILib Preferences are an alternative. Then you can use the OutlineViewer to view and edit all the entries. It’s very similar to the SmartDashboard but I personally prefer it because it’s great at handling preferences and settings like tuning parameters.

Preferences preferences = Preferences.getInstance();
preferences.putInt(String someKey, value);
int x = preferences.getInt(KEY, defaultValue);

1 Like

We just used PercentOutput mode. I hadn’t even thought about how it goes faster down than up until you mentioned it - it never seemed to be a usability issue. Maybe it’d be a usability improvement to account for that. On the other hand, last year, going down was just a “reset to the floor so we can pick up another cube” situation, so the drivers wanted to get it over with fast.

This year for my own students, I have identified this video from “FRCSim 2016” on PID Tuning as a very good introduction on the workings of each gain value. There is at least a second video in this series too, but this one especially highlights how P & D can overcome some directional and non-linear challenges.

Thank you for sharing! I will look into that.

On another vein, I noticed you have a section for calculating the feed forward. Is this for the kF value for velocity control, or is this for arbitrary feed forward? If arbitrary, how would you go about calculating it? I’m predicting that I’m going to run into issues with gravity with position control, and posts on Chief Delphi seem to have a general consensus that applying an arbitrary feedforward is the way to go.

This is for calculating feed forward with motion magic, not kF. Please note, the code referenced above is in development. It still has some bugs and isn’t final!

For a PID loop, afaik, you can simply add the Feed Forward calculation to the PID output. I wouldn’t apply a kF if you’re doing arbitrary feed forward, but I’m no final authority.

For an elevator, I would create a command that allows you to lift the elevator with a joystick. Output the joystick value to a tool like SmartDashboard. What you’re looking for is the minium power needed to lift the elevator. This output (range from 0 to 1) is what you’d add to the PID in order to always have enough voltage to overcome gravity.

Here’s a quick method that should work in the execute method of a Command in a Command Based Robot Project:

protected void execute() {
  double move = -Robot.oi.stick.getY();
  SmartDashboard.putNumber("Power Applied To Elevator", move);

I’m making assumptions on your code, but I hope you get the gist. Move the joystick, when the elevator starts to lift, note the value (0-1) required to lift it.

That’s it.

Arms are more difficult because of the rotation, but this should be simple enough.