Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions Evlib/src/main/java/ftc/evlib/hardware/control/NotLinearLift.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package ftc.evlib.hardware.control

import ftc.electronvolts.util.AnalogInputEdgeDetector
import ftc.electronvolts.util.PIDController
import ftc.evlib.hardware.motors.MotorEncEx
import ftc.evlib.hardware.sensors.AnalogSensor

//PLEASE ONLY USE THIS IN THE SCORER CLASS IF YOU KNOW WHAT YOU ARE DOING!!!!!
//OR ELSE DEAD BODY WILL BE FOUND
//AND EMERGENCY MEETING WILL BE CALLED

class NotLinearLift(
val motor: MotorEncEx,
private val extensionPID: PIDController,
private var maxExtensionPosition: Double = 3.02, //these are now all in potentiometer units
private var minExtensionPosition: Double = 0.992,
private val tolerance: Double = 0.0,
var maxCorrectionPower: Double = 1.0,
val controlExtensionScale: ControlFn,
val potentiometer: AnalogSensor
) {

init {
assert(maxExtensionPosition > minExtensionPosition) { "maxExtensionPosition must be greater than minExtensionPosition" }
assert(maxCorrectionPower > 0 && maxCorrectionPower < 1.0) { "maxExtensionPower must be between 0 and 1"}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be <= 1.0

assert(tolerance >= 0) { "tolerance must be greater than or equal to 0" }
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be > 0

}

//NOTES: if the lower limit is triggered, we can only put 10% power to the motor
//make sure there are enough stuff in the log to properly tune it.
//record the power that are sent to the motor

val extensionCurrentPos: Double = 0.0
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You never assigned this variable with the potentiometer voltage.

var extensionSetPoint = 0.0
var extensionPower = 0.0

fun pre_act() {

}

fun act() {
extensionSetPoint = extensionSetPoint.coerceIn(minExtensionPosition, maxExtensionPosition)
extensionPower = extensionPID.computeCorrection(extensionSetPoint, potentiometer.value)

if (extensionCurrentPos <= minExtensionPosition) //wow dont go too fast if ur below the min
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need a different number. minExtensionPosition is the lowest value it can take. It's not the beginning of the stop zone. Need to add like 0.1 to get the beginning of the stop zone in each direction.

extensionPower *= 0.1
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong. It should clamp the output of the PID to between {-0.1, maxCorrectionPower}, not scale it.


motor.setSpeed(extensionPower * maxCorrectionPower) //scale the actual power with maxExtensionPower
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, don't scale it. Scaling = gain = hiding proportional gain terms all over the place.

Also you have to use motor.SetPower to set the power.

motor.update()
}

fun controlExtension(x: Double) {
extensionSetPoint += controlExtensionScale.rescale(x, extensionCurrentPos, extensionPower)
}

fun stopExtension() {
extensionSetPoint = extensionCurrentPos
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We ought to come up with something better than this but I"m not sure what yet.

}

val isDone: Boolean
get() {
val difference = extensionSetPoint - extensionCurrentPos
return difference in (-tolerance..tolerance)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ import ftc.electronvolts.util.AnalogInputEdgeDetector
import ftc.electronvolts.util.DigitalInputEdgeDetector
import ftc.electronvolts.util.Functions
import ftc.electronvolts.util.OptionsFile
import ftc.electronvolts.util.PIDController
import ftc.evlib.hardware.control.LinearSlide
import ftc.evlib.hardware.control.NotLinearLift
import ftc.evlib.hardware.motors.MotorEncEx
import ftc.evlib.hardware.sensors.AnalogSensor
import ftc.evlib.hardware.sensors.DigitalSensor
import ftc.evlib.hardware.servos.ServoControl
import ftc.evlib.util.FileUtil
import org.firstinspires.ftc.robotcore.external.Telemetry
import java.util.Comparator
import java.util.PriorityQueue
import kotlin.math.cos

const val LIFT_MAX_EXTENSION = 900
const val LIFT_MAX_EXTENSION = 3.02
const val LIFT_MIN_EXTENSION = 0.992
const val LIFT_SENSITIVITY = 16.0
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the max range of the lift changed from 900 counts to 2.0 volts, make sure this was scaled down similarly.

const val FETCHER_SENSITIVITY = 44.0
const val FETCHER_MAX_EXTENSION = 900
const val LINEAR_SLIDE_TOLERANCE = 5
const val LINEAR_SLIDE_TOLERANCE = 5.0
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the max range of the lift changed from 900 counts to 2.0 volts, make sure this was scaled down similarly.

const val FETCHER_MAX_ENC_FOR_SAFE_LIFT_HOMING = 30.0


Expand All @@ -31,6 +33,15 @@ enum class FetcherPresets(val height: Double) {
FETCHER_HOME(-50.0)
}

object LiftPIDCoefficients {

const val kP = 20.0
const val kI = 0.3
const val kD = 6.0
const val kF = 0.0

}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the max range of the lift changed from 900 counts to 2.0 volts, the gains probably need to be scaled up so that more power is generated from a small difference in positions.

object FetcherAutoPIDCoefficients {
const val kP = 50.0
const val kI = 0.2
Expand All @@ -52,7 +63,7 @@ data class ScorerHardware(
val placer: ServoControl,
val dropper: ServoControl,

val lift: LinearSlide,
val lift: NotLinearLift,
val fetcher: LinearSlide,
val dropperLimitSwitch: DigitalInputEdgeDetector,
val liftEncoder: AnalogSensor,
Expand All @@ -68,7 +79,8 @@ data class ScorerHardware(

lift: MotorEncEx,
fetcher: MotorEncEx,
liftLimitSwitch: DigitalSensor,
liftLimitSwitch: DigitalSensor, //haha we dont need this anymore
//tom if you're reading this, lets add foam at where the limit switch is, for both sides ofc
fetchLimitSwitch: DigitalSensor,
dropperLimitSwitch: DigitalSensor,
LiftEncoder: AnalogSensor,
Expand All @@ -77,16 +89,16 @@ data class ScorerHardware(
liftLowThreshold: Double, liftHighThreshold: Double
) : this(
grabber = grabber, lever = lever, placer = placer, dropper = dropper,
lift = LinearSlide(lift,
null,
lift = NotLinearLift(lift,
PIDController(LiftPIDCoefficients.kI, LiftPIDCoefficients.kI, LiftPIDCoefficients.kD, LiftPIDCoefficients.kF),
LIFT_MAX_EXTENSION,
LIFT_MIN_EXTENSION,
LINEAR_SLIDE_TOLERANCE,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to make this Lift-specific. It's only used in the lift (fetcher tolerance is a literal constant now)

liftLimitSwitch,
true,
1.0,
{ control, _, _ -> LIFT_SENSITIVITY * Functions.eBased(1.5).f(-control) },
false),
liftPotentiometer),
fetcher = LinearSlide(fetcher,
null,
with (FetcherTelePIDCoefficients){PIDController(kP, kI, kD, kF)},
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait what? Fetcher was not supposed to change in the PR!!!!

FETCHER_MAX_EXTENSION,
25,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a constant for FETCHER_TOLERANCE

fetchLimitSwitch,
Expand All @@ -100,9 +112,9 @@ data class ScorerHardware(
)

init {
lift.maxCorrectionPower = 1.0
lift.setDownPower(0.11)
fetcher.maxCorrectionPower = 1.00
// lift.maxCorrectionPower = 1.0 now in the constructor
// lift.setDownPower(0.11) slow descent no longer needed
// fetcher.maxCorrectionPower = 1.00 now in the constructor
}

fun pre_update() {
Expand Down Expand Up @@ -152,10 +164,12 @@ class Scorer(val hardware: ScorerHardware, val telemetry: Telemetry) {

init {
// hardware.lift.extension.setVelocityPIDFCoefficients(20.0, 2.0, 5.0, 0.0)
hardware.lift.extension.setVelocityPIDFCoefficients(20.0, 0.3, 6.0, 0.0)
hardware.lift.extension.setPositionPIDCoefficients(15.0)
with(LiftPIDCoefficients){
hardware.lift.motor.setVelocityPIDFCoefficients(kP, kI, kD, kF)
hardware.lift.motor.setPositionPIDCoefficients(15.0)
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be deleted. We are not using the internal lift PID anymore

hardware.fetcher.extension.setVelocityPIDFCoefficients(45.0,0.2,25.0, 0.0)
hardware.lift.slowEncDelta = 0.5
// hardware.lift.slowEncDelta = 0.5 why do we need this???
hardware.lift.maxCorrectionPower = LIFT_UP_SPEED.toDouble()
hardware.lever.setDefaultSpeed(ScorerConstants.LEVER_SPEED) //so that it doesn't go all the way to the target value
hardware.placer.setDefaultSpeed(ScorerConstants.PLACER_SPEED)
Expand Down Expand Up @@ -207,11 +221,21 @@ class Scorer(val hardware: ScorerHardware, val telemetry: Telemetry) {
telemetry.addData("Fetcher encoder value: ", hardware.fetcher.extensionEncoder)
telemetry.addData("Fetcher set point: ", hardware.fetcher.extensionSetPoint)
// telemetry.addData("Fetcher power", hardware.fetcher.extensionPower)
telemetry.addData("Lift encoder value: ", hardware.lift.extensionEncoder)
// telemetry.addData("Lift encoder value: ", hardware.lift.extensionEncoder)
telemetry.addData("Lift encoder value: ", hardware.lift.motor.encoderPosition)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this entry, made redundant below.

telemetry.addData("Lift set point: ", hardware.lift.extensionSetPoint)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this entry, made redundant below.

telemetry.addData("Grabber Servo Position: ", hardware.grabber.currentPosition)
telemetry.addData("Grabber State: ", grabberState.name)
// telemetry.addData("Lift power", hardware.lift.extensionPower)

//new NotLinearLift logging
telemetry.addData("Lift power", hardware.lift.motor.power)
telemetry.addData("Lift velocity", hardware.lift.motor.velocity)
telemetry.addData("Lift position", hardware.lift.motor.encoderPosition)
telemetry.addData("Lift target position", hardware.lift.extensionSetPoint)
telemetry.addData("Lift is done", hardware.lift.isDone)
telemetry.addData("Lift potentiometer", hardware.lift.potentiometer)

}

fun getFetcherOffset(leverPosition: Double): Double {
Expand Down Expand Up @@ -369,13 +393,10 @@ class Scorer(val hardware: ScorerHardware, val telemetry: Telemetry) {

fun liftToPreset(preset: LiftPresets) {
liftGoingToPreset = true
hardware.lift.setExtension(
if (liftDynamicMode){
hardware.lift.extensionSetPoint =
if (liftDynamicMode)
GenericOptions.dynamicLiftPreset(optionsFile, preset)
} else {
preset.height
}
)
else preset.height
}

fun fetcherToPreset(preset: FetcherPresets) {
Expand Down Expand Up @@ -404,11 +425,11 @@ class Scorer(val hardware: ScorerHardware, val telemetry: Telemetry) {

fun liftToValue(value: Double) {
liftGoingToPreset = true
if(value > LIFT_MAX_EXTENSION) {
hardware.lift.setExtension(LIFT_MAX_EXTENSION.toDouble())
} else {
hardware.lift.setExtension(value)
}

hardware.lift.extensionSetPoint =
if (value > LIFT_MAX_EXTENSION) LIFT_MAX_EXTENSION
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to also clamp to LIFT_MIN_EXTENSION

else value

}

fun runDropper(power: DropperPresets) {
Expand Down