Dual Motor Slide Subsystem
This commit is contained in:
@ -0,0 +1,131 @@
|
|||||||
|
package org.firstinspires.ftc.teamcode.subsystem;
|
||||||
|
|
||||||
|
import static org.firstinspires.ftc.teamcode.PedroConstants.LIFT_SLIDE_LEFT_MOTOR;
|
||||||
|
import static org.firstinspires.ftc.teamcode.PedroConstants.LIFT_SLIDE_RIGHT_MOTOR;
|
||||||
|
|
||||||
|
import com.qualcomm.robotcore.hardware.DcMotor;
|
||||||
|
import com.qualcomm.robotcore.hardware.DcMotorEx;
|
||||||
|
import com.qualcomm.robotcore.hardware.HardwareMap;
|
||||||
|
import com.qualcomm.robotcore.util.ElapsedTime;
|
||||||
|
|
||||||
|
public class DualMotorSliderSubsystem {
|
||||||
|
|
||||||
|
/*
|
||||||
|
liftSlideLeft - Left Motor for Dual Linear Slide as a DcMotorEx object
|
||||||
|
Currently, the value of (liftSlideLeft) is null because we haven't assigned a value (object) to it yet.
|
||||||
|
It expects an object of type "DcMotorEx".
|
||||||
|
*/
|
||||||
|
private DcMotorEx liftSlideLeft;
|
||||||
|
|
||||||
|
/*
|
||||||
|
liftSlideRight - Right Motor for Dual Linear Slide as a DcMotorEx object
|
||||||
|
Currently, the value of (liftSlideRight) is null because we haven't assigned a value (object) to it yet.
|
||||||
|
It expects an object of type "DcMotorEx".
|
||||||
|
*/
|
||||||
|
private DcMotorEx liftSlideRight;
|
||||||
|
|
||||||
|
/*
|
||||||
|
targetPosition - Variable that holds target position of slides.
|
||||||
|
*/
|
||||||
|
private int targetPosition = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
getTargetPosition/setTargetPosition - Best practice to "hide" (private) targetPosition and,
|
||||||
|
instead, use a "setter" to set the target position value or
|
||||||
|
a "getter" to get the target position value.
|
||||||
|
*/
|
||||||
|
public void setTargetPosition(int value) {
|
||||||
|
targetPosition = value;
|
||||||
|
}
|
||||||
|
private int getTargetPosition() { return targetPosition; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
PID - Proportional/Integral/Derivative Values
|
||||||
|
|
||||||
|
For a dual motor linear slide, we only tune the P - Proportion.
|
||||||
|
The Proportion variable (kp) answers the question "how fast do we want to get to our destination?"
|
||||||
|
|
||||||
|
It's the only value we set because the variable ki and kd deal with how to handle when we're off the path.
|
||||||
|
Since we're going straight, we don't need to worry about.
|
||||||
|
*/
|
||||||
|
public final static double kp = 0.0015, ki = 0, kd = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
lastError/integralSum/timer - These 3 variables are placeholders in determining how much
|
||||||
|
power to send to both motors.
|
||||||
|
*/
|
||||||
|
private double lastError = 0;
|
||||||
|
private double integralSum = 0;
|
||||||
|
private ElapsedTime timer = new ElapsedTime();
|
||||||
|
|
||||||
|
public DualMotorSliderSubsystem(HardwareMap hardwareMap) {
|
||||||
|
/*
|
||||||
|
liftSlideLeft/liftSlideRight - Now, we are assigning a value of DcMotorEx to each variable
|
||||||
|
|
||||||
|
We "assign" the object DcMotorEx to liftSlideLeft and liftSlideRight and "link them" to the
|
||||||
|
driver hub configuration name that matches the motor on the slide.
|
||||||
|
*/
|
||||||
|
liftSlideLeft = hardwareMap.get(DcMotorEx.class, LIFT_SLIDE_LEFT_MOTOR);
|
||||||
|
liftSlideRight = hardwareMap.get(DcMotorEx.class, LIFT_SLIDE_RIGHT_MOTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
/*
|
||||||
|
Initialize the motors with the following settings (assuming slide is at the very bottom position):
|
||||||
|
|
||||||
|
- Reset the encoders to be zero
|
||||||
|
- When the motor stops moving (zero power), brake. This means we can't move the motors, not even gravity.
|
||||||
|
- Sets the motor to run without the encoder. This doesn't mean we won't use the encoder values (because we will).
|
||||||
|
It just means to not FULLY depend on them, we will just prefer to use motor power instead.
|
||||||
|
*/
|
||||||
|
liftSlideLeft.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
|
||||||
|
liftSlideLeft.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
|
||||||
|
liftSlideLeft.setMode(DcMotor.RunMode.RUN_WITHOUT_ENCODER);
|
||||||
|
|
||||||
|
liftSlideRight.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
|
||||||
|
liftSlideRight.setZeroPowerBehavior(DcMotor.ZeroPowerBehavior.BRAKE);
|
||||||
|
liftSlideRight.setMode(DcMotor.RunMode.RUN_WITHOUT_ENCODER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
To calculate power, we send the targetPosition value (how high we want the slider motors to
|
||||||
|
be based on motor 'ticks') to calculatePower function.
|
||||||
|
|
||||||
|
For every loop that occurs, it will constantly calculate power. So long as we're far away from
|
||||||
|
our "target" position, we will get as much power as possible. The closer we get, the lower the
|
||||||
|
power we will receive.
|
||||||
|
*/
|
||||||
|
public void update() {
|
||||||
|
double power = calculatePower();
|
||||||
|
liftSlideLeft.setPower(power);
|
||||||
|
liftSlideRight.setPower(power);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculating power - To calculate the power, we determine the proportion, derivative and
|
||||||
|
integral of our closed loop system.
|
||||||
|
|
||||||
|
For more information, please visit:
|
||||||
|
- Introduction to Closed Loop System:
|
||||||
|
- https://www.ctrlaltftc.com/introduction-to-closed-loop-control
|
||||||
|
- The PID controller:
|
||||||
|
- https://www.ctrlaltftc.com/the-pid-controller
|
||||||
|
*/
|
||||||
|
private double calculatePower() {
|
||||||
|
double error = getTargetPosition() - liftSlideLeft.getCurrentPosition();
|
||||||
|
integralSum += error * timer.seconds();
|
||||||
|
double derivative = (error - lastError) / timer.seconds();
|
||||||
|
lastError = error;
|
||||||
|
timer.reset();
|
||||||
|
return (error * kp) + (derivative * kd) + (integralSum * ki);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toLowBucketPosition() {
|
||||||
|
setTargetPosition(1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toHighBucketPosition() {
|
||||||
|
setTargetPosition(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user