Robô Deep Space 2019
O jogo FRC de 2019, Deep Space, tinha alvos de visão acima de muitos dos objetivos. Abaixo você pode encontrar programas de exemplo completos em Java e Labview que implementam um método simples para dirigir automaticamente em direção a um objetivo no Deep Space.
Estes são programas muito simples e destinados apenas a mostrar o conceito de usar dados de rastreamento do Limelight para controlar seu robô. Em cada programa, você pode dirigir seu robô com um gamepad. Se você mantiver o botão 'A' pressionado, e o Limelight detectar um alvo válido (dependendo das configurações em seu pipeline), o robô irá automaticamente dirigir em direção ao alvo. Tenha cuidado para ajustar as várias constantes no código para o seu robô específico. Alguns robôs viram ou dirigem mais facilmente que outros, então o ajuste das constantes de controle proporcional deve ser feito caso a caso. Certifique-se de que o robô dirige corretamente usando o controle gamepad antes de habilitar o comportamento de busca do Limelight.
- Java
- LabView
package frc.robot;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj.VictorSP;
import edu.wpi.first.wpilibj.SpeedControllerGroup;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj.GenericHID.Hand;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.networktables.*;
public class Robot extends TimedRobot {
private static final String kDefaultAuto = "Padrão";
private static final String kCustomAuto = "Meu Auto";
private String m_autoSelected;
private final SendableChooser<String> m_chooser = new SendableChooser<>();
private VictorSP m_Left0 = new VictorSP(0);
private VictorSP m_Left1 = new VictorSP(1);
private VictorSP m_Right0 = new VictorSP(2);
private VictorSP m_Right1 = new VictorSP(3);
private SpeedControllerGroup m_LeftMotors = new SpeedControllerGroup(m_Left0,m_Left1);
private SpeedControllerGroup m_RightMotors = new SpeedControllerGroup(m_Right0,m_Right1);
private DifferentialDrive m_Drive = new DifferentialDrive(m_LeftMotors,m_RightMotors);
private XboxController m_Controller = new XboxController(0);
private boolean m_LimelightHasValidTarget = false;
private double m_LimelightDriveCommand = 0.0;
private double m_LimelightSteerCommand = 0.0;
@Override
public void robotInit() {
m_chooser.setDefaultOption("Auto Padrão", kDefaultAuto);
m_chooser.addOption("Meu Auto", kCustomAuto);
SmartDashboard.putData("Escolhas Auto", m_chooser);
}
@Override
public void robotPeriodic() {
}
@Override
public void autonomousInit() {
m_autoSelected = m_chooser.getSelected();
}
@Override
public void autonomousPeriodic() {
}
@Override
public void teleopPeriodic() {
Update_Limelight_Tracking();
double steer = m_Controller.getX(Hand.kRight);
double drive = -m_Controller.getY(Hand.kLeft);
boolean auto = m_Controller.getAButton();
steer *= 0.70;
drive *= 0.70;
if (auto)
{
if (m_LimelightHasValidTarget)
{
m_Drive.arcadeDrive(m_LimelightDriveCommand,m_LimelightSteerCommand);
}
else
{
m_Drive.arcadeDrive(0.0,0.0);
}
}
else
{
m_Drive.arcadeDrive(drive,steer);
}
}
@Override
public void testPeriodic() {
}
/**
* Esta função implementa um método simples de gerar comandos de direção e esterçamento
* baseados nos dados de rastreamento de uma câmera Limelight.
*/
public void Update_Limelight_Tracking()
{
// Estes números devem ser ajustados para o seu Robô! Seja cuidadoso!
final double STEER_K = 0.03; // quão forte virar em direção ao alvo
final double DRIVE_K = 0.26; // quão forte dirigir para frente em direção ao alvo
final double DESIRED_TARGET_AREA = 13.0; // Área do alvo quando o robô atinge a parede
final double MAX_DRIVE = 0.7; // Limite de velocidade simples para não dirigirmos muito rápido
double tv = NetworkTableInstance.getDefault().getTable("limelight").getEntry("tv").getDouble(0);
double tx = NetworkTableInstance.getDefault().getTable("limelight").getEntry("tx").getDouble(0);
double ty = NetworkTableInstance.getDefault().getTable("limelight").getEntry("ty").getDouble(0);
double ta = NetworkTableInstance.getDefault().getTable("limelight").getEntry("ta").getDouble(0);
if (tv < 1.0)
{
m_LimelightHasValidTarget = false;
m_LimelightDriveCommand = 0.0;
m_LimelightSteerCommand = 0.0;
return;
}
m_LimelightHasValidTarget = true;
// Comece com esterçamento proporcional
double steer_cmd = tx * STEER_K;
m_LimelightSteerCommand = steer_cmd;
// tente dirigir para frente até que a área do alvo atinja nossa área desejada
double drive_cmd = (DESIRED_TARGET_AREA - ta) * DRIVE_K;
// não deixe o robô dirigir muito rápido em direção ao objetivo
if (drive_cmd > MAX_DRIVE)
{
drive_cmd = MAX_DRIVE;
}
m_LimelightDriveCommand = drive_cmd;
}
}
Aqui está um diagrama de blocos para um VI LabView que lê dados de rastreamento de um Limelight e gera comandos de direção e esterçamento. Esta imagem é um "Snippet LabView". Basta salvar o arquivo de imagem em seu computador e depois arrastá-lo para um VI LabView e o diagrama de blocos será reproduzido.
Você também pode baixar todo o código-fonte do LabView a partir deste link