Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calibrate Intake #153

Merged
merged 12 commits into from
Feb 6, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
root.append(LoggedMechanismLigament2d("ExtenderLigament", 0.569, 0.0))

private val tuningPositionMeters =
LoggedNetworkNumber("Tuning/Extender/Position", 0.0)
LoggedNetworkNumber("/Tuning/Extender/Position", 0.0)

val position: () -> Distance = { io.inputs.position }

Expand All @@ -44,7 +44,7 @@

private fun setPosition(position: Positions): Command =
runOnce { setpointName = position.getLoggingName() }
.andThen(setPosition({ position.position }))

Check notice on line 47 in src/main/kotlin/frc/robot/subsystems/intake/extender/Extender.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Lambda argument inside parentheses

Lambda argument should be moved out of parentheses
.withName("Extender/setPosition with enum")

private fun setVoltage(voltage: Voltage): Command =
Expand All @@ -54,7 +54,8 @@
)
.withName("Extender/setVoltage")

fun tuningPosition(): Command = run {
fun tuningPosition(): Command = runOnce {

Check warning on line 57 in src/main/kotlin/frc/robot/subsystems/intake/extender/Extender.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Function "tuningPosition" is never used
setpoint = Units.Meters.of(tuningPositionMeters.get())
io.setPosition(Units.Meters.of(tuningPositionMeters.get()))
}

Expand All @@ -63,7 +64,7 @@
fun retract() =
setPosition(Positions.RETRACTED).withName("Extender/retract")

fun reset(): Command {

Check warning on line 67 in src/main/kotlin/frc/robot/subsystems/intake/extender/Extender.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Function "reset" is never used
return setVoltage(RESET_VOLTAGE)
.alongWith(
runOnce {
Expand All @@ -81,7 +82,7 @@
.withName("Extender/reset")
}

fun returnToSetpoint(): Command = run {

Check warning on line 85 in src/main/kotlin/frc/robot/subsystems/intake/extender/Extender.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Function "returnToSetpoint" is never used
atSetpoint
.negate()
.debounce(SAFETY_DEBOUNCE)
Expand All @@ -105,7 +106,7 @@
}

@AutoLogOutput
val isComplicated = isRetracted.negate().and(isExtended.negate())

Check warning on line 109 in src/main/kotlin/frc/robot/subsystems/intake/extender/Extender.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Property "isComplicated" is never used

@AutoLogOutput
val isStuck = Trigger {
Expand All @@ -119,7 +120,7 @@
}

@AutoLogOutput
val finishedResetting =

Check warning on line 123 in src/main/kotlin/frc/robot/subsystems/intake/extender/Extender.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused symbol

Property "finishedResetting" is never used
Trigger { finishedResettingFlag }
.onTrue(runOnce { io.setSoftLimits(true) })

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package frc.robot.subsystems.intake.extender

import edu.wpi.first.units.Units
import edu.wpi.first.units.measure.Current
import edu.wpi.first.units.measure.Distance
import edu.wpi.first.units.measure.MomentOfInertia
import edu.wpi.first.units.measure.Voltage
import edu.wpi.first.units.measure.*
import frc.robot.lib.Gains
import frc.robot.lib.selectGainsBasedOnMode

Expand All @@ -13,15 +10,15 @@ val RESET_VOLTAGE: Voltage = Units.Volts.of(0.0)
val PINION_RADIUS: Distance = Units.Millimeters.of(15.22)
val MOMENT_OF_INERTIA: MomentOfInertia = Units.KilogramSquareMeters.of(0.003)
val RESET_CURRENT_THRESHOLD: Current = Units.Amps.of(0.0)
val POSITION_TOLERANCE: Distance = Units.Centimeters.of(0.7)
val MAX_EXTENSION: Distance = Units.Meters.of(0.0)
val MIN_EXTENSION: Distance = Units.Meters.of(0.0)
val POSITION_TOLERANCE: Distance = Units.Centimeters.of(0.1)
val MAX_EXTENSION: Angle = Units.Rotations.of(6.7)
val MIN_EXTENSION: Angle = Units.Rotations.of(-6.3)
Comment on lines +14 to +15
Copy link
Member

Choose a reason for hiding this comment

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

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Soft limits takes rotations and we calibrated this with Phoenix tuner x.

Copy link
Member

Choose a reason for hiding this comment

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

Sure, but you can still use centimeters here and convert the measured to rotations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If i use centimeters here i'll have to measure again. Since we measured in rotations via Tuner X i don't see why that is necessary

Copy link
Member

Choose a reason for hiding this comment

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

If i use centimeters here i'll have to measure again.

Maybe. But in this case you know the gear ratio and everything and you can calculate it. Or, you can take a tape and measure it. Or, you can check the position input in AdvantageScope which is in meters (which is another reason the min/max positions should be in meters). and take the value from there.
All of these solutions will take you less than a minute to implement, probably less time than it takes to discuss the matter.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, we can calculate it but there is no reason. We calibrated it through tuner x so the value will be in rotations. There is no need to convert it to a distance in the constants file and then right back to rotations

Copy link
Member

Choose a reason for hiding this comment

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

The reason to do so is to make it easier to change in the future, and to retain the same dimensions -- again, if position is measured as a distance (as it should), it doesn't make sense to write its min/max values in another dimension.

Copy link
Contributor

Choose a reason for hiding this comment

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

We are measuring the MAX & MIN Position via Phoenix x which measure in rotations.

Copy link
Member

@katzuv katzuv Feb 5, 2025

Choose a reason for hiding this comment

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

You both said that multiple times and I don't see how this is relevant. I don't want this to block the merge, but you shouldn't make decisions based on the specific measurement tool you used.

Copy link
Contributor Author

@rakrakon rakrakon Feb 6, 2025

Choose a reason for hiding this comment

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

So, by your logic, if we can only measure in inches for some reason and our code already works with inches, we should first measure in inches, convert to centimeters, put that in the code, and then convert back to inches in the code. How is that logical?

Just for clarification in situation above your code takes Inches and you can't change that, just like our situation.

const val SAFETY_DEBOUNCE = 1.0

val GAINS = selectGainsBasedOnMode(Gains(), Gains(kP = 0.5, kD = 0.2))
val GAINS = selectGainsBasedOnMode(Gains(2.0), Gains(kP = 0.5, kD = 0.2))

enum class Positions(val position: Distance) {
EXTENDED(Units.Meters.of(0.3)),
EXTENDED(Units.Meters.of(0.4)),
RETRACTED(Units.Meters.of(0.0));

fun getLoggingName() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.ctre.phoenix6.configs.MotorOutputConfigs
import com.ctre.phoenix6.configs.Slot0Configs
import com.ctre.phoenix6.configs.SoftwareLimitSwitchConfigs
import com.ctre.phoenix6.configs.TalonFXConfiguration
import com.ctre.phoenix6.controls.MotionMagicTorqueCurrentFOC
import com.ctre.phoenix6.controls.PositionVoltage
import com.ctre.phoenix6.controls.VoltageOut
import com.ctre.phoenix6.hardware.TalonFX
import com.ctre.phoenix6.signals.InvertedValue
Expand All @@ -20,19 +20,15 @@ import frc.robot.lib.toDistance
class ExtenderIOReal : ExtenderIO {
override val inputs = LoggedExtenderInputs()
private val motor = TalonFX(MOTOR_ID)
private val positionControl = MotionMagicTorqueCurrentFOC(0.0)
private val positionControl = PositionVoltage(0.0)
private val voltageRequest = VoltageOut(0.0)

private val softLimitsConfig =
SoftwareLimitSwitchConfigs().apply {
ForwardSoftLimitEnable = true
ReverseSoftLimitEnable = true
ForwardSoftLimitThreshold =
MAX_EXTENSION.toAngle(PINION_RADIUS, GEAR_RATIO)
.`in`(Units.Rotations)
ReverseSoftLimitThreshold =
MIN_EXTENSION.toAngle(PINION_RADIUS, GEAR_RATIO)
.`in`(Units.Rotations)
ForwardSoftLimitThreshold = MAX_EXTENSION.`in`(Units.Rotations)
ReverseSoftLimitThreshold = MIN_EXTENSION.`in`(Units.Rotations)
}

init {
Expand All @@ -41,7 +37,7 @@ class ExtenderIOReal : ExtenderIO {
MotorOutput =
MotorOutputConfigs().apply {
Inverted = InvertedValue.Clockwise_Positive
NeutralMode = NeutralModeValue.Coast
NeutralMode = NeutralModeValue.Brake
}

CurrentLimits =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package frc.robot.subsystems.intake.extender

const val MOTOR_ID = 0
const val MOTOR_ID = 11
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ import edu.wpi.first.units.Units
import edu.wpi.first.units.measure.*
import frc.robot.lib.getTranslation2d

val INTAKE_VOLTAGE: Voltage = Units.Volts.of(-0.7 * 12.0)
val OUTTAKE_VOLTAGE: Voltage = Units.Volts.of(0.8 * 12.0)
val CORAL_OUTTAKE_TRANSLATION: Translation2d =
getTranslation2d(Units.Meters.of(0.3))
val CORAL_OUTTAKE_HEIGHT: Distance = Units.Meter.of(0.4)
val CORAL_OUTTAKE_VELOCITY: LinearVelocity = Units.MetersPerSecond.of(3.0)
val CORAL_OUTTAKE_ANGLE: Angle = Units.Degrees.zero()
val INTAKE_WIDTH: Distance = Units.Meters.of(0.64)
val INTAKE_LENGTH_EXTENDED: Distance = Units.Meters.of(0.35)

val INTAKE_VOLTAGE: Voltage = Units.Volts.of(0.4 * 12.0)
val OUTTAKE_VOLTAGE: Voltage = Units.Volts.of(0.5 * 12.0)
val FAR_OUTTAKE_VOLTAGE: Voltage = Units.Volts.of(0.7 * 12.0)
const val GEAR_RATIO = 1.0
val MOMENT_OF_INERTIA: MomentOfInertia = Units.KilogramSquareMeters.of(0.003)
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package frc.robot.subsystems.intake.roller

const val MOTOR_ID = 0
const val MOTOR_ID = 12
Loading