Encoder function to TalonSRX -- need to lock motor in absence of input

Our team is using a TalonSRX and we can move it, but it droops whenever the input is released. How can we use the mag encoder to ensure the position locks whenever we let go of the button? Thanks!

If you’re not that familiar with closed-loop controls, you can ‘cheat’ by doing something like this :

public class SetMotorOutput extends Command {
double input;

public SetClimberOutput(double input) {
    requires(Robot.mechanism);
    this.input= input;
}

// Called just before this Command runs the first time
@Override
protected void initialize() {
}

// Called repeatedly when this Command is scheduled to run
@Override
protected void execute() {

    // Read Joystick input with this to avoid deadzones
    if(Math.abs(Robot.m_oi.getJoystickInput()) > 0.05)
    Robot.mechanism.talonSRX.set(ControlMode.PercentOutput, input);
    else // Cheat -  Get the current position from the encoder and sue that as your sepoint
    Robot.mechanism.talonSRX.set(ControlMode.Position, talonSRX.getSelectedSensorPosition());
}

@Override
protected boolean isFinished() {
    return false;
}

// Called once after isFinished returns true
@Override
protected void end() {
}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
@Override
protected void interrupted() {
    end();
}
}

Before you do this, make sure your sensor works and is in the coirrect phase (moving the motor forward means your sensor reading is also positive). You would probably need to configure some PID values for that talon for it to hold, but it should be so inconsequential where you can just configure the P value to any value around 0.0-0.2 and it will hold, since you’re not really moving it through setpoints anywhere else (assuming you don’t plan on doing this). If you do this and your mechanism ‘jutters’ adjust your P-value up/down until it stops and you should be good.

1 Like

How is this to be done? Where do PID’s factor in?

Be careful the motor doesn’t overheat. You’re providing electrical energy to the motor, usually it would be converted to kinetic energy (motion). If the motor isn’t moving, the electrical energy has to go somewhere, and turns into heat.

If the motor (over)heats, you will want to mount a fan to blow onto/into the motor to cool it. Fan choices are limited , please see R34 of the Game Manual.

You can use the Talon’s closed loop control mode with the arbitrary feed-forward that just holds the position you’re looking for.

Then how should I calculate both proportional and integral gain to match the inactive state?

1 Like

So the point of the code I gave you was that you can control the mechanism normally in ‘open-loop’ without the need to know anything about PID or closed-loop control. The second you stop giving an input to the mechanism through the joystick, the code tells the TalonSRX to go into position control mode using its current read position as its setpoint. Since you’re telling it to go to where it is currently positioned, the Talon will use its internal PID calculations to provide enough power to hold the motor in place, provided your P value isn’t too high (otherwise your mechanism will oscillate). Using this method, you probably don’t need any of the other PID values other than P.

1 Like

I used the example you provided, yet I still found that the motor drooped in the absence of input and would not lock into position. My code can be found here. Just in case you can give me any pointers from there. I appreciate the help, today is the last build day and it is frantic!

So you never initialize your talon to use a Mag Encoder or configure a P value to the motor controller. You should add this to your robotInit()

talonsrx_roller.configSelectedFeedbackSensor(FeedbackDevice.CTRE_MagEncoder_Absolute);
talonsrx_roller.(0, kP, 30); // Change kP to an actual value

Then, add this to TeleOpPeriodic:

System.out.println("Mag Encoder Position: " +  talonsrx_roller.getSelectedSensorPosition());

Have this always print out instead of on a button temporarily.

Once you do that, check that when you move your arm, the output of the sensor connected to your TalonSRX is in phase with its movement (When the arm goes up, the encoder position is positive, down is negative)

After that, change your last else statement to use this function:

talonsrx_roller.set(ControlMode.Position, talonsrx_roller.getSelectedSensorPosition());

Once you do that the arm should either stay in place, slowly droop down, or oscillate. If it slowly droops down, increase the kP value, if it oscillates, decrease kP.

As @NewtonCrosby said, your motor can heat up significantly/burn out if you’re not careful. This will be especially true if your arm is not driven by a CIM motor or not geared properly. If you find that your arm motor heats up significantly, consider using a passive mechanism to help hold it up, like surgical tubing that pulls the arm up and down from a rotation point above the arm.

You are a godsend, thanks much!

Actually, what is the method called in the line talonsrx_roller.(0, kP, 30); // Change kP to an actual value ?

Oh sorry, that should be:

talonsrx_roller.config_kP(0, kP, 30); // Change kP to an actual value ?

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.