Go to Post Am I the only one who thinks robots are the main attraction of a regional, and there isn't a need for more distraction? - Adam Richards [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
 
 
Thread Tools Rating: Thread Rating: 43 votes, 5.00 average. Display Modes
Prev Previous Post   Next Post Next
  #1   Spotlight this post!  
Unread 15-03-2015, 15:00
Dan5190 Dan5190 is offline
Registered User
FRC #5190
 
Join Date: Feb 2015
Location: Cary, NC
Posts: 5
Dan5190 is an unknown quantity at this point
Talon SRX Position PID Control Issue

We have a crane style arm on our robot operated by two motors hooked up to 2 Talon SRXs. One of the talons is set in follow the other 'master' talon. We have a analog pot wired into the master talon data port to get the angle of the arm.

In the default state when the arm is not moving we have the master talon in position PID mode to hold the arm at it's current angle. When the arm is carrying a load it will sag down otherwise. We're using talon profile 0 for this PID control state. We want to move the arm to a specific angle we switch to profile 1 with a different set of PID parameters to move it.

The problem is that when we switch to profile 1 and then set the angle we want to go to the Talon seems to be in an invalid state and jerks the arm for split second before picking up the PID parameters and the arm angle setpoint we gave. I think what is happening is that during that split second it's trying to move the arm to position '0' on the analog pot. I don't think it's derivative kick or something with the I accum because I'm only setting a P for the PID parameters and also because when I set the setpoint to an angle higher than what the arm is currently at, the arm shoots down in the opposite direction for that split second then moves in the right direction.

Additional details in case it's relevant:
The valid range for the arm is 308-696 out of the pot's 0-1024 range which we have set as soft limits. When the operator moves the joystick to operate the arm we switch to PercentVBus mode then switch back to profile 0 position PID when they let go.


Here is the code that moves the arm to a new angle (uses pid profile 1):
setPID parameters:
P: 5.0 I: 0 D: 0 F: 0 Izone: 0 RampRate: 0 Profile: 1

Code:
public void startArmSetAngle() {
			if (controlMode != ControlMode.Position) {
				armCANTalonLeft.changeControlMode(ControlMode.Position);
				controlMode = ControlMode.Position;
			}
			configureSetAnglePID();
			armCANTalonLeft.set(angle);
		}
		// called every 20ms
		public void execute() {
			armCANTalonLeft.set(angle);
		}

private void configureSetAnglePID() {
		double p = prefs.getDouble("arm.set.angle.p", ARM_SET_ANGLE_P);
		double i = prefs.getDouble("arm.set.angle.i", ARM_SET_ANGLE_I);
		double d = prefs.getDouble("arm.set.angle.d", ARM_SET_ANGLE_D);
		double rampRate = prefs.getDouble("arm.set.angle.ramp.rate",
				ARM_SET_ANGLE_RAMP_RATE);
		int izone = prefs.getInt("arm.set.angle.izone", ARM_SET_ANGLE_IZONE);
		int profile = prefs.getInt("arm.set.angle.profile",
				ARM_SET_ANGLE_PROFILE);
		armCANTalonLeft.setPID(p, i, d, 0, izone, rampRate, profile);
	}

Here is the method that the default joystick command calls every 20ms to move the arm. If the joystick doesn't apply any power then it switch to position PID profile 0 to hold the arm at the current angle:
setPID parameters:
P: 1.8 I: 0 D: 0 F: 0 Izone: 0 RampRate: 0 Profile: 0

Code:
	public void moveArm(double power) {
		if (power > 0.05 || power < -0.05) {
			if (controlMode != ControlMode.PercentVbus) {
				armCANTalonLeft.changeControlMode(ControlMode.PercentVbus);
				controlMode = ControlMode.PercentVbus;
			}
			armCANTalonLeft.set(power);
		} else {
			if (controlMode != ControlMode.Position) {
				configureHoldPID();
				armCANTalonLeft.changeControlMode(ControlMode.Position);
				armCANTalonLeft.set(armCANTalonLeft.getPosition());
				controlMode = ControlMode.Position;
			}
		}
	}

	private void configureHoldPID() {
		double p = prefs.getDouble("arm.hold.p", ARM_HOLD_P);
		double i = prefs.getDouble("arm.hold.i", ARM_HOLD_I);
		double d = prefs.getDouble("arm.hold.d", ARM_HOLD_D);
		double rampRate = prefs.getDouble("arm.hold.ramp.rate",
				ARM_HOLD_RAMP_RATE);
		int izone = prefs.getInt("arm.hold.izone", ARM_HOLD_IZONE);
		int profile = prefs.getInt("arm.hold.profile", ARM_HOLD_PROFILE);
		armCANTalonLeft.setPID(p, i, d, 0, izone, rampRate, profile);
	}

Last edited by Dan5190 : 15-03-2015 at 15:03.
 


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 03:47.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi