Turret Code 101 Help

Hey everyone, how u doing? As you know the regionals are near, and my team is planning to use a turret. The thing is that Im the lead programmer and I’ve never made a code for a turren. Is there any base code or a tutorial so I can start by there.

So if someone could help us with this we’ll be so gratefull, thank you all guys!! Any doubt just tell us, thx.

PS: We’re using only one Neo and a throughbore encoder, our turret has a 270° rotation angle.

PS2: We are also using a Limelight 3.5 and we’ll also like to have autoposition to the apriltag, so if our robot moves our turrent still be pointing at the apriltag.

I hope this can help:

In your subsystem constructor you need to create your SparkMax class and setup the sparkmax to use the throughbore encoder as an alternate encoder. I am assuming you know whats going on below.

You also need to make some sort of PID controller. You can do it integrated on the SparkMax, or you can use a PIDController.

Im doing it on the sparkmax because im copying it from here

private static final int kCanID = 1; // your CAN ID
private static final MotorType kMotorType = MotorType.kBrushless;
private static final SparkMaxAlternateEncoder.Type kAltEncType = SparkMaxAlternateEncoder.Type.kQuadrature;
private static final int kCPR = 8192;

private CANSparkMax m_motor;
private RelativeEncoder m_alternateEncoder;
private SparkPIDController m_pidController;

// This is the subsystem constructor 
public Turret() {
    m_motor = new CANSparkMax(kCanID, kMotorType);
    m_motor.restoreFactoryDefaults();

    m_alternateEncoder = m_motor.getAlternateEncoder(kAltEncType, kCPR);

    m_pidController.setFeedbackDevice(m_alternateEncoder);

   /**
    * Here you got to set your PID constants. I am going to assume that
    * you know whats going on here. kP is the only constant you rly need 
    * to make a good turret. 
    * 
    * The best way to tune a kP is by setting to 1 and then if its too slow then *= 10
    * and if its too fast then /= 10. Lets say at kP=10 its too slow and kP=100 its too fast,
    * then you split the difference and set that. Now you basically binary search to an
    * optimal kP.
    *
    * Set everything else to 0. Except min and max
    * output which you just set to the min and max volts. You should start
    * them at a smaller number, like 4, and increment if its too slow.
    **/
    m_pidController.setP(kP); // kP = some positive constant

    // set the following to 0
    m_pidController.setI(0); 
    m_pidController.setD(0);
    m_pidController.setIZone(0);
    m_pidController.setFF(0);

    // start at small volts and increase as needed
    m_pidController.setOutputRange(-4, 4); 

}

Now we got to jump to your periodic loop. Im just going to call the method void periodic(). Basically we got to

  • get angle to goal
  • convert it from degrees to motor rotations cos thats what the sparkmax wants
  • set to the PID controller

In your periodic loop you must read tx from limelight for the apriltag under the speaker. I dont use limelight but these docs should give more info

// Fill this number in with your gear ratio. 
// This is the amount of times the encoder will spin for every time the
// turret spins. 
//
// Ex: if the turret spins 270 degrees that is .75 rotations. 
// If the encoder spins 30 times in that motion.
// Then (1/.75) * 30 = 40 encoder rotations per one rotation of turret.
// Therefore gear ratio = 40. 
// Disclaimer I think the math is mathing but im tired so I couldve f'ed up.

private static final double gearRatio = 12.34; 

// You also need to find a minimum and maximum encoder rotation that the turret can be at.
// The following should set the min and max angle less then 
private static final double maxAngle = ((270.0 / 2.0 - 10.0) / 360.0) * gearRatio;
private static final double minAngle = -maxAngle;

void periodic() {
  // tx ranges from (-hfov/2) to (hfov/2) in degrees. If your target is on the rightmost edge of 
  // your limelight 3 feed, tx should return roughly 31 degrees.
  double tx = LimelightHelpers.getTX("");
  // ^ copied above from limelight docs
  // We need to get the tx of only the specific tag under the speaker.
  // I dont know how to do this but it cant be too hard to figure out.

  // Now we convert to rotations to set our encoder to.
  double setpoint = (tx / 360.0) * gearRatio.

  // Now before we set it we need to check our max and min.
  // If we are outside the allowed bounds we can just set it back to 0 or something.
  double currentPosition = m_alternateEncoder.getPosition();
  if (currentPosition > maxAngle || currentPosition < minAngle) {
    setpoint = 0;
  } 

  // we want to set the PID controller to go to our desired setpoint.
  m_pidController.setReference(setpoint, CANSparkMax.ControlType.kPosition);
}

Cool that should be the basics. When you turn the bot on you want the turret to be aligned in the middle so that the middle position is 0 to the encoder.

One problem you could have is that it just goes off to one direction and keeps going. If this happens you just need to negate your kP b/c you entered whats called a positive feedback loop. It was going the wrong direction but since it was getting further from where it wanted to be it just kept going more in the wrong direction b/c it was wrong and didnt know that it was backwards LOL.

I hope this points you guys in the right direction towards your goal. Get it turret joke. I know its not funny but please laugh.

1 Like

I just made a post about this. Angled Shooter Math Analysis

Hey! Thank you so much for giving me some help, im just waiting for my mechanics team to finish building turret so I can try it, but I have some questions about the maths that u use. My turret spins a total of 270° but I want it to be at the middle front so it could be 135 degrees to the right and the same to the left, at the Max angle should i put 135 degrees or still 270°?

My second question, how do i get the gear ratio, I mean I got kindah confused with the example you gave, that you said “gear ratio = 40”, and then you declared it as “gearRatio = 12.34”, could you explain me better how it works pls?

My last question at the maxAngle you made some math, how does it work?

I’m making this questions 'cause I really believe that’s going to work, but I want to understad the process behind the math. If you could help me with this i’ll be so grateful, thnx!!

PS: I really loved your joke HAHAHHAHA.

The max angle should be <= +135. Sometimes it is good to make it a little less for safety.
The min angle is just negative max angle.

gear ratio

Yea my examples were bad LOL

Basically the gear ratio is how many times the encoder spins a full rotation for the turret rotates around once.

So what you can do is move the turret some degrees, well say N.

Now convert that degrees to rotations by dividing by 360, that gives us R. (R = N/360)

Then you take the amount of rotations the encoder spun, we can say E.

Gear Ratio = E / R

Example:

we spin the turret 180° and the encoder spins 10 times

N = 180 and E = 10

R = N / 360 = 180 / 360 = 0.5

Gear Ratio = E / R = 10 / 0.5 = 20

Then your gear ratio is 20. 

My last question at the maxAngle you made some math, how does it work?

Dont worry about the math I did, just basically set that number to +135 or less.
And then minAngle to -maxAngle.

1 Like

Thanks! One last question, do you need to make a command so the turret works or with that its enough?

I lowkey don’t know anything about command based.

We might need someone else to help with this one.

I see, and when you mean to move the turret is it literally just move it in person, and print the through bore encoder values to see the value it gives you. Or is it another way to do it.

I’m sorry if im making dumb questions but i really want to be sure at doing this things.

Remember that Code is the tool - the question is not dissimilar from “Can someone show me a hammer which can build a house?”

Read the examples for meaning.

Tuning a Turret Position Controller — FIRST Robotics Competition documentation may also be of interest.

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