Hey everyone,
I’m running into an issue setting up a Limelight vision system where it’s always returning the default value, and I’m not sure what’s causing it. I’ve attached some screenshots to give you a clearer picture of what’s going on.
The goal is to align the bot with an apriltag when the 9 button is held down. Here is the code.
package frc.robot.commands.LimeLightVision;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.subsystems.CANDrivetrain;
public class AlignWithTag extends Command {
private final CANDrivetrain drivetrain;
private final NetworkTable table;
private static final double Kp = -0.1;
private static final double min_command = 0.05;
// Constructor
public AlignWithTag(CANDrivetrain drivetrain) {
this.drivetrain = drivetrain;
table = NetworkTableInstance.getDefault().getTable("limelight");
addRequirements(drivetrain);
}
// Called when the command is initially scheduled.
@Override
public void initialize() {
// Initialization code, if any
}
// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute() {
NetworkTableEntry tx = table.getEntry("tx");
double x = tx.getDouble(0.0);
double heading_error = -x;
System.out.println("Executing with error " + heading_error);
double steering_adjust = 0.0;
if (Math.abs(heading_error) > 1.0) {
steering_adjust = Kp * heading_error + (heading_error > 0 ? -min_command : min_command);
}
drivetrain.arcadeDrive(0, steering_adjust);
}
// Called once the command ends or is interrupted.
@Override
public void end(boolean interrupted) {
drivetrain.arcadeDrive(0, 0); //Stop the drivetrain when the command ends
}
// Returns true when the command should end.
@Override
public boolean isFinished() {
return false; // Modify this as needed based on your command's ending condition
}
}
package frc.robot;
import java.lang.reflect.Method;
import java.util.Arrays;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.InstantCommand;
import edu.wpi.first.wpilibj2.command.RunCommand;
import edu.wpi.first.wpilibj2.command.button.JoystickButton;
import frc.robot.commands.Autos;
import frc.robot.commands.LimeLightVision.AlignWithTag;
import frc.robot.subsystems.CANDrivetrain;
//import frc.robot.subsystems.CANLauncher;
public class RobotContainer {
private final CANDrivetrain m_drivetrain = new CANDrivetrain();
private final SendableChooser<Command> autoChooser = new SendableChooser<>();
private final AlignWithTag m_align = new AlignWithTag(m_drivetrain);
//private final CANLauncher m_launcher = new CANLauncher();
// Assuming these port numbers are correct for your setup.
private final Joystick m_driver = new Joystick(Constants.OperatorConstants.kDriverControllerPort);
//private final Joystick m_operator = new Joystick(Constants.OperatorConstants.kOperatorControllerPort);
public RobotContainer() {
configureBindings();
populateAutoCommands();
}
private void configureBindings() {
m_drivetrain.setDefaultCommand(
new RunCommand(
() -> m_drivetrain.arcadeDrive(
-m_driver.getY() * Constants.OperatorConstants.kDriverSpeedMultiplier,
-m_driver.getX() * Constants.OperatorConstants.kDriverSpeedMultiplier),
m_drivetrain));
// Create a JoystickButton object for the button
JoystickButton alignButton = new JoystickButton(m_driver, 9);
// Bind align command to the button
alignButton.onTrue(m_align);
}
// Commented out the following as we do not have a launcher yet.
/*
m_operatorController
.a()
.whileTrue(
new PrepareLaunch(m_launcher)
.withTimeout(LauncherConstants.kLauncherDelay)
.andThen(new LaunchNote(m_launcher))
.handleInterrupt(() -> m_launcher.stop()));
m_operatorController.leftBumper().whileTrue(m_launcher.getIntakeCommand());
*/
private void populateAutoCommands() {
Method[] methods = Autos.class.getDeclaredMethods();
Arrays.stream(methods)
.filter(method -> Command.class.isAssignableFrom(method.getReturnType()) && method.getParameterCount() == 1)
.forEach(method -> {
try {
Command command = (Command) method.invoke(null, m_drivetrain);
autoChooser.addOption(method.getName(), command);
} catch (Exception e) {
e.printStackTrace();
}
});
SmartDashboard.putData("Auto Mode", autoChooser);
}
public Command getAutonomousCommand() {
return autoChooser.getSelected();
}
public String getSelectedAutoName() {
return autoChooser.getSelected().getName();
}
}