Our team’s robot design is a pink arm with a linear slider for the arm. I was wondering for pid would I need different values for when the linear Slider is extended vs not extended? Because most of the weight is on intake and when the arm is extended its about twice as long as before extending.
If I need another set of PID values when the arm is extended how would I implement it and whats the easiest way? I am the sole programmer for our team and this is my first year programming so I have been really struggling. Also our competition is this Saturday and our team is still working on electrical so Ill have less than 5 hours tommorow tot test on the robot assuming we dont do drive practice. So really hoping to get this code done first try. Here is the current code Sorry its a bit messy because i have not got the time to organize stuff yet.
With 5 hours, I’d see if you can get away without even extending the arm. Maybe come back to this after your competition. That way you can just ziptie it down and just focus on making the arm work. I highly doubt this robot will work with that little time. Similarly, I would also forgo the wrist.
You should measure your kG feedforward with the arm extended and retracted. Then you should be able to avoid retuning your PID gains. Just scale how much kG you apply based on how far it has been extended.
what you talking about is a feedforward based on angle of the arm pivot and arm extension. the feed forward is the amount of power required to hold position against gravity in a certain position.
also we will be at the event this weekend if you wanna come by our pit and ask for help. Im assuming you’re going to GRITS?
Yes, thats what Im talking about. Is there a team with like an example code I can look at or something. Cause Ill be able to have tonight and tommorow night to try and code it at home. Just wont have access to robot. Yes we are going to GRITS.
read up on motion magic and you can most likely get the system up and running with a low acceleration and top speed without the need for a feed forward. its by no means the optimal solution but as many others have said. “perfection is the enemy of good enough”
ArmFeedforward is the class you want to use to calculate the output. The ArmFeedforward takes come constants that describe the physical properties of the arm. It will use the desired velocity of the arm in radians per second to calculate a voltage.
You can use sysid to get the constants needed for the feedforward.
You will want to have your PID (or preferably profiled pid) to output radians per second to feed into the feed forward.
You’re likely to have better luck with ReCalc than with SysId at the moment. Check back in a couple months once the api integration is done and the generated robot projects are gone.
What we ended up doing was having a rotate command that did the feedforwad, the command that controlled the arm ran the PID you can do it other ways.
Declare the feed forward calculator and PID
private final ArmFeedforward m_rotationFeedForward = new ArmFeedforward(RotationGains.kS, RotationGains.kG, RotationGains.kV);
private final PIDController m_rotationPIDController = new PIDController(RotationGains.kP, RotationGains.kI, RotationGains.kD);`
Then the command looked like this but you could also do the newer inline command
public class ArmRotate extends CommandBase {
private Arm m_arm;
private double m_angleRadians;
/** Creates a new ArmRotate. */
public ArmRotate(Arm arm, double angleRadians) {
addRequirements(arm);
m_arm = arm;
m_angleRadians = angleRadians;
}
// Called when the command is initially scheduled.
@Override
public void initialize() {
m_arm.getRotationPIDController().reset();
}
// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute() {
PIDController rotationController = m_arm.getRotationPIDController();
rotationController.setSetpoint(m_angleRadians);
m_arm.rotateClosedLoop(rotationController.calculate(m_arm.getArmAngleRadians()));
}
// Called once the command ends or is interrupted.
@Override
public void end(boolean interrupted) {
m_arm.hold();
}
// Returns true when the command should end.
@Override
public boolean isFinished() {
return m_arm.getRotationPIDController().atSetpoint();
}
}
Thank you so much! I found your teams code on the github and was looking it over and it was very helpful. But I had a question: How do you obtain all the constants in your ArmConstants class. Like which ones do I have to test for myself and how would I do that and which ones I do not have to test for? Thanks!
Don’t get too much into our arm, it really needs cleaned up, there are some artifacts left over from abandoned ideas. That is why I posted it pared down to a simpler example.
For the feed forward constants we used the sysid program, but @oblarg pointed out that it is not currently in a good state if you use the older version that was the last season release you may be ok. recalc can give you some of the numbers.
As of the PID it is experimental, at least when we do it. The thing to remember is what units you are using for in and out, and start your p lower than takes to saturate your output for about half the distance you want to travel. Then bump it up and see.
Also you may want a profiled PID we did not use one. WE had one but were having other issues and in the diagnosis by dissection we removed it and we haven’t had time to put it back.