-
Notifications
You must be signed in to change notification settings - Fork 0
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
Feature/intake phx6 alon #6
base: main
Are you sure you want to change the base?
Changes from 4 commits
3919d2b
1e831bc
721eaa5
a51c911
1d09951
903dce0
48cee81
d6f81c5
12fe8b5
3d809ce
a250571
3b00257
00e3cf8
fda897a
5495eb3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,46 @@ | ||
package frc.robot.subsystems.intake; | ||
|
||
import com.ctre.phoenix.motorcontrol.ControlMode; | ||
katzuv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import com.ctre.phoenix.motorcontrol.NeutralMode; | ||
import com.ctre.phoenix.motorcontrol.StatorCurrentLimitConfiguration; | ||
import com.ctre.phoenix.motorcontrol.can.TalonFX; | ||
import com.ctre.phoenix6.configs.TalonFXConfiguration; | ||
import com.ctre.phoenix6.configs.TalonFXConfigurator; | ||
import com.ctre.phoenix6.controls.PositionVoltage; | ||
import com.ctre.phoenix6.hardware.TalonFX; | ||
import com.revrobotics.CANSparkMax; | ||
import com.revrobotics.CANSparkMaxLowLevel; | ||
import edu.wpi.first.math.util.Units; | ||
import frc.robot.Constants; | ||
import frc.robot.Ports; | ||
import utils.Utils; | ||
import utils.units.UnitModel; | ||
|
||
|
||
public class IntakeIOReal implements IntakeIO { | ||
private final CANSparkMax spinMotor = new CANSparkMax(Ports.Intake.INTAKE_MOTOR, CANSparkMaxLowLevel.MotorType.kBrushless); | ||
private final TalonFX angleMotor = new TalonFX(Ports.Intake.ANGLE_MOTOR); | ||
|
||
private final TalonFX angleMotorPhx = new TalonFX(0); | ||
katzuv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private final TalonFXConfigurator angleConfigurator; | ||
private final TalonFXConfiguration angleConfiguration = new TalonFXConfiguration(); | ||
|
||
private final UnitModel unitModel = new UnitModel(IntakeConstants.TICKS_PER_DEGREE); | ||
|
||
private double currentAngle; | ||
|
||
public IntakeIOReal() { | ||
angleMotor.configFactoryDefault(); | ||
spinMotor.restoreFactoryDefaults(); | ||
angleConfigurator = angleMotorPhx.getConfigurator(); | ||
angleConfiguration.Slot0.kP = IntakeConstants.kP; | ||
angleConfiguration.Slot0.kI = IntakeConstants.kI; | ||
angleConfiguration.Slot0.kD = IntakeConstants.kD; | ||
angleConfigurator.apply(angleConfiguration.Slot0); | ||
|
||
spinMotor.restoreFactoryDefaults(); | ||
spinMotor.setIdleMode(CANSparkMax.IdleMode.kCoast); | ||
spinMotor.enableVoltageCompensation(Constants.NOMINAL_VOLTAGE); | ||
spinMotor.setInverted(Ports.Intake.POWER_INVERTED); | ||
for (int i = 1; i <= 6; i++) { | ||
spinMotor.setPeriodicFramePeriod(CANSparkMaxLowLevel.PeriodicFrame.fromId(i), 50000); | ||
} | ||
spinMotor.burnFlash(); | ||
|
||
angleMotor.setNeutralMode(NeutralMode.Brake); | ||
angleMotor.enableVoltageCompensation(true); | ||
angleMotor.configVoltageCompSaturation(Constants.NOMINAL_VOLTAGE); | ||
angleMotor.setInverted(Ports.Intake.ANGLE_INVERTED); | ||
angleMotor.config_kP(0, IntakeConstants.kP); | ||
angleMotor.config_kI(0, IntakeConstants.kI); | ||
angleMotor.config_kD(0, IntakeConstants.kD); | ||
angleMotor.config_kF(0, IntakeConstants.kF); | ||
angleMotor.configStatorCurrentLimit(new StatorCurrentLimitConfiguration( | ||
true, 30, 0, 0 | ||
)); | ||
angleMotor.configClosedLoopPeakOutput(0, 0.4); | ||
spinMotor.burnFlash(); | ||
} | ||
|
||
@Override | ||
|
@@ -48,27 +50,30 @@ public void setSpinMotorPower(double power) { | |
|
||
@Override | ||
public void setAngleMotorAngle(double angle) { | ||
angleMotor.set(ControlMode.Position, angle); | ||
var motorRequest = new PositionVoltage(Units.radiansToRotations(angle)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the Phoenix 6 documentation:
You can create the request object as a class member and change the value as needed with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really, you still create the request every time this function is called. You should create it once and only once. |
||
angleMotorPhx.setControl(motorRequest); | ||
} | ||
|
||
@Override | ||
public void setAngleMotorPower(double power) { | ||
angleMotor.set(ControlMode.PercentOutput, power); | ||
angleMotorPhx.setVoltage(power*12); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not simply use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, but still, create the request once. |
||
} | ||
|
||
@Override | ||
public void resetEncoder(double angle) { | ||
angleMotor.setSelectedSensorPosition( | ||
unitModel.toTicks(angle) | ||
); | ||
} | ||
public void resetEncoder(double angle) {} | ||
|
||
@Override | ||
public void updateInputs(IntakeLoggedInputs inputs) { | ||
angleConfigurator.apply(angleConfiguration.Slot0); | ||
AlonSchwierz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inputs.spinMotorPower = spinMotor.getAppliedOutput(); | ||
inputs.angleMotorAngle = unitModel.toUnits(angleMotor.getSelectedSensorPosition()); | ||
inputs.angleMotorVelocity = unitModel.toVelocity(angleMotor.getSelectedSensorVelocity()); | ||
inputs.angleMotorcurrent = angleMotor.getSupplyCurrent(); | ||
inputs.angleMotorPower = angleMotor.getMotorOutputPercent(); | ||
//inputs.setpointSpinMotorPower | ||
//inputs.setpointAngleMotorPower | ||
//inputs.setpointAngleMotorAngle | ||
katzuv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inputs.angleMotorPower = angleMotorPhx.getMotorVoltage().getValue()/12; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The battery's voltage is not stable (especially during a match) and will not always be 12V. You have two options:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I will do both - thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! |
||
inputs.angleMotorAngle = angleMotorPhx.getRotorPosition().getValue(); | ||
currentAngle = inputs.angleMotorAngle; | ||
inputs.angleMotorcurrent = angleMotorPhx.getSupplyCurrent().getValue(); | ||
inputs.spinMotorCurrent = spinMotor.getOutputCurrent(); | ||
inputs.angleMotorVelocity = angleMotorPhx.getRotorVelocity().getValue(); | ||
AlonSchwierz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,60 @@ | ||
package frc.robot.subsystems.intake; | ||
|
||
import edu.wpi.first.math.controller.PIDController; | ||
import edu.wpi.first.math.system.plant.DCMotor; | ||
import edu.wpi.first.math.system.plant.LinearSystemId; | ||
import edu.wpi.first.wpilibj.simulation.FlywheelSim; | ||
import edu.wpi.first.wpilibj.simulation.SingleJointedArmSim; | ||
import com.ctre.phoenix6.configs.TalonFXConfiguration; | ||
import com.ctre.phoenix6.configs.TalonFXConfigurator; | ||
import com.ctre.phoenix6.controls.DutyCycleOut; | ||
import com.ctre.phoenix6.controls.PositionVoltage; | ||
import com.ctre.phoenix6.hardware.TalonFX; | ||
import com.ctre.phoenix6.sim.TalonFXSimState; | ||
import edu.wpi.first.math.util.Units; | ||
import utils.motors.TalonFXSim; | ||
|
||
public class IntakeIOSim implements IntakeIO { | ||
private final FlywheelSim spinMotor; | ||
private final SingleJointedArmSim angleMotor; | ||
private final PIDController angleFeedback; | ||
private final TalonFXSim angleMotorSim; | ||
private final TalonFXSim powerMotorSim; | ||
private final TalonFXConfiguration angleConfiguration; | ||
|
||
public IntakeIOSim() { | ||
spinMotor = new FlywheelSim(DCMotor.getNEO(1), IntakeConstants.SPIN_GEAR_RATIO, 1); | ||
angleMotor = new SingleJointedArmSim(LinearSystemId.createSingleJointedArmSystem( | ||
DCMotor.getFalcon500(1), 2, IntakeConstants.ANGLE_GEAR_RATIO | ||
), DCMotor.getFalcon500(1), IntakeConstants.ANGLE_GEAR_RATIO, 0.7, -Math.PI * 2, Math.PI * 2, false, 0); //could be wrong type of motor or max/min angle | ||
angleFeedback = new PIDController(IntakeConstants.kP, IntakeConstants.kI, IntakeConstants.kD); | ||
angleConfiguration = new TalonFXConfiguration(); | ||
|
||
angleMotorSim = new TalonFXSim(0, IntakeConstants.ANGLE_GEAR_RATIO, 1); | ||
katzuv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
powerMotorSim = new TalonFXSim(1, IntakeConstants.SPIN_GEAR_RATIO, 1); | ||
|
||
angleConfiguration.Slot0.kP = IntakeConstants.kP_SIM; | ||
angleConfiguration.Slot0.kI = IntakeConstants.kI_SIM; | ||
angleConfiguration.Slot0.kD = IntakeConstants.kD_SIM; | ||
angleMotorSim.configure(angleConfiguration); | ||
} | ||
|
||
@Override | ||
public void updateInputs(IntakeLoggedInputs inputs) { | ||
katzuv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
inputs.spinMotorPower = inputs.setpointSpinMotorPower; | ||
inputs.spinMotorCurrent = spinMotor.getCurrentDrawAmps(); | ||
inputs.angleMotorAngle = angleMotor.getAngleRads(); | ||
inputs.angleMotorcurrent = angleMotor.getCurrentDrawAmps(); | ||
|
||
spinMotor.update(0.02); | ||
angleMotor.update(0.02); | ||
inputs.angleMotorPower = angleMotorSim.getAppliedVoltage() / 12; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, better to log the voltage directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You write OK but change nothing, and resolve the thread? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes but this is a simulation and the BatterySim Class is private for some reason. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WDYM private? It's very much public https://github.wpilib.org/allwpilib/docs/release/java/edu/wpi/first/wpilibj/simulation/BatterySim.html There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand your problem, you're trying to instantiate |
||
inputs.angleMotorcurrent = angleMotorSim.getAppliedCurrent(); | ||
inputs.angleMotorVelocity = angleMotorSim.getRotorVelocity(); | ||
inputs.angleMotorAngle = angleMotorSim.getRotorPosition() * Math.PI * 2 % Math.PI * 2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you mean? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Modify this constant so |
||
inputs.spinMotorCurrent = powerMotorSim.getAppliedVoltage(); | ||
inputs.spinMotorPower = powerMotorSim.getAppliedVoltage() / 12; | ||
} | ||
|
||
@Override | ||
public void setSpinMotorPower(double power) { | ||
spinMotor.setInputVoltage(power * 12); | ||
var motorRequest = new DutyCycleOut(power); | ||
powerMotorSim.setControl(motorRequest); | ||
} | ||
|
||
@Override | ||
public void setAngleMotorAngle(double angle) { | ||
double angleMotorAppliedVoltage = angleFeedback.calculate(angleMotor.getAngleRads(), angle); | ||
angleMotor.setInputVoltage(angleMotorAppliedVoltage); | ||
var motorRequest = new PositionVoltage(Units.radiansToRotations(angle)); | ||
angleMotorSim.setControl(motorRequest); | ||
} | ||
|
||
@Override | ||
public void setAngleMotorPower(double power) { | ||
angleMotor.setInputVoltage(power * 12); | ||
var motorRequest = new DutyCycleOut(power); | ||
angleMotorSim.setControl(motorRequest); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, you should reuse control requests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, you still create it in each function call.
katzuv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
|
||
@Override | ||
public void resetEncoder(double angle) { | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls no
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK sorry