Hello CD. Due to the amount of people wanting to drive our robot this year I decided to make it easier for the drivers to be able to drive by allowing them to create their own custom joystick mappings with either Arcade Joysticks, xbox 360 or ps3 controller.
I think I may of figured out how to do that but I can not find anyone else who has done it the way I did, and since our robot is bagged currently I do not have access to a roborio to test the code. If you guys can look it over and give me your thoughts that would be great.
How it works:
In RobotInt: a smartdashboard string is put asking for the driver’s name
in OI: if and elseif statements check what name is in the textbox, then set the mappings to whoever it is.
In DisabledPeriodic, it constantly runs oi.reset(new OI()) so it is constantly checking for the driver’s input. I checked the source code and it says every time it creates a new OI it deletes the old, so there should not be any memory issues.
Any input is appreciated, also if you want to be extra helpful, could you look at the OI buttons and tell me if the way I created the buttons work, as the triggers for our controllers are only axis and not buttons. Same for the POV. Thanks!
oi.h:
// RobotBuilder Version: 2.0
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// C++ from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
#ifndef OI_H
#define OI_H
#include "WPILib.h"
class OI {
private:
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
std::shared_ptr<Joystick> joystickLeft;
std::shared_ptr<JoystickButton> eatBall;
std::shared_ptr<JoystickButton> intakeUpButton;
std::shared_ptr<Joystick> joystickRight;
std::shared_ptr<JoystickButton> lockBall;
std::shared_ptr<JoystickButton> frontArmDown;
std::shared_ptr<JoystickButton> frontArmUp;
std::shared_ptr<JoystickButton> launchBoulder;
std::shared_ptr<JoystickButton> fire;
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
std::shared_ptr<JoystickButton> mikayla;
public:
OI();
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=PROTOTYPES
std::shared_ptr<Joystick> getJoystickRight();
std::shared_ptr<Joystick> getJoystickLeft();
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=PROTOTYPES
};
#endif
robot.h
// RobotBuilder Version: 2.0
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// C++ from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
#ifndef _ROBOT_H
#define _ROBOT_H
#include "WPILib.h"
#include "Commands/Command.h"
#include "RobotMap.h"
#include "LiveWindow/LiveWindow.h"
#include "Commands/WaterBridge.h"
#include <cmath>
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INCLUDES
#include "Commands/AutonomousDriveForward.h"
#include "Subsystems/BoulderIntake.h"
#include "Subsystems/DriveTrain.h"
#include "Subsystems/FlipperSub.h"
#include "Subsystems/FrontArm.h"
#include "Subsystems/Launcher.h"
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INCLUDES
#include "OI.h"
class Robot : public IterativeRobot {
public:
std::unique_ptr<Command> autonomousCommand;
static std::unique_ptr<OI> oi;
LiveWindow *lw = LiveWindow::GetInstance();
CameraServer* datcam;
SendableChooser* choose;
//std::shared_ptr<USBCamera> spookycam;
std::shared_ptr<NetworkTable> visionTable;
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
static std::shared_ptr<DriveTrain> driveTrain;
static std::shared_ptr<FlipperSub> flipperSub;
static std::shared_ptr<Launcher> launcher;
static std::shared_ptr<BoulderIntake> boulderIntake;
static std::shared_ptr<FrontArm> frontArm;
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
virtual void RobotInit();
virtual void DisabledInit();
virtual void DisabledPeriodic();
virtual void AutonomousInit();
virtual void AutonomousPeriodic();
virtual void TeleopInit();
virtual void TeleopPeriodic();
virtual void TestPeriodic();
};
#endif
oi.ccp:
// RobotBuilder Version: 2.0
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// C++ from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
#include "OI.h"
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INCLUDES
#include "SmartDashboard/SmartDashboard.h"
#include "Commands/AutoLaunch.h"
#include "Commands/AutoPortcullis.h"
#include "Commands/AutoUltrasonicDrive.h"
#include "Commands/AutoUltrasonicDriveToTower.h"
#include "Commands/AutonomousDriveForward.h"
#include "Commands/ChevelTiltyThingies.h"
#include "Commands/Drawbridge.h"
#include "Commands/Flipper.h"
#include "Commands/IntakeDownandEat.h"
#include "Commands/IntakeUp.h"
#include "Commands/Launch.h"
#include "Commands/LockThatBall.h"
#include "Commands/LowWall.h"
#include "Commands/ManuiplateDown.h"
#include "Commands/ManuiplateUp.h"
#include "Commands/Ramparts.h"
#include "Commands/RockyWall.h"
#include "Commands/SallyPort.h"
#include "Commands/TankDrive.h"
#include "Commands/WaterBridge.h"
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INCLUDES
#include "Commands/MikaylaIntake.h"
#include "Commands/IntakeDown.h"
OI::OI() {
// Process operator interface input here.
if(SmartDashboard::GetString("Please enter name of driver: (first name lower case)", "default") == "default"){
joystickLeft.reset(new Joystick(1));
eatBall.reset(new JoystickButton(joystickLeft.get(), 2));
eatBall->WhileHeld(new IntakeDownandEat());
intakeUpButton.reset(new JoystickButton(joystickLeft.get(), 3));
intakeUpButton->WhileHeld(new IntakeUp());
joystickRight.reset(new Joystick(0));
lockBall.reset(new JoystickButton(joystickRight.get(), 4));
lockBall->WhenPressed(new LockThatBall());
frontArmDown.reset(new JoystickButton(joystickRight.get(), 3));
frontArmDown->WhileHeld(new ManuiplateDown());
frontArmUp.reset(new JoystickButton(joystickRight.get(), 5));
frontArmUp->WhileHeld(new ManuiplateUp());
launchBoulder.reset(new JoystickButton(joystickRight.get(), 2));
launchBoulder->WhileHeld(new Launch());
fire.reset(new JoystickButton(joystickRight.get(), 1));
fire->WhenPressed(new Flipper());
}else if(SmartDashboard::GetString("Please enter name of driver: (first name lower case)", "default") == "brandon"){
joystickRight.reset(new Joystick(0));
eatBall.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(180)));
eatBall->WhileHeld(new IntakeDownandEat());
launchBoulder.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(3) == 1.0));
launchBoulder->WhileHeld(new Launch());
intakeUpButton.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(0)));
intakeUpButton->WhileHeld(new IntakeUp());
lockBall.reset(new JoystickButton(joystickRight.get(), 3));
lockBall->WhenPressed(new LockThatBall());
frontArmDown.reset(new JoystickButton(joystickRight.get(), 1));
frontArmDown->WhileHeld(new ManuiplateDown());
frontArmUp.reset(new JoystickButton(joystickRight.get(), 4));
frontArmUp->WhileHeld(new ManuiplateUp());
fire.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(2) == 1.0));
fire->WhenPressed(new Flipper());
}else if(SmartDashboard::GetString("Please enter name of driver: (first name lower case)", "default") == "harrie"){
joystickRight.reset(new Joystick(0));
eatBall.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(180)));
eatBall->WhileHeld(new IntakeDownandEat());
launchBoulder.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(2) == 1.0));
launchBoulder->WhileHeld(new Launch());
intakeUpButton.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(0)));
intakeUpButton->WhileHeld(new IntakeUp());
lockBall.reset(new JoystickButton(joystickRight.get(), 3));
lockBall->WhenPressed(new LockThatBall());
frontArmDown.reset(new JoystickButton(joystickRight.get(), 5));
frontArmDown->WhileHeld(new ManuiplateDown());
frontArmUp.reset(new JoystickButton(joystickRight.get(), 6));
frontArmUp->WhileHeld(new ManuiplateUp());
fire.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(3) == 1.0));
fire->WhenPressed(new Flipper());
}else if(SmartDashboard::GetString("Please enter name of driver: (first name lower case)", "default") == "jacob"){
joystickLeft.reset(new Joystick(1));
eatBall.reset(new JoystickButton(joystickLeft.get(), 2));
eatBall->WhileHeld(new IntakeDownandEat());
launchBoulder.reset(new JoystickButton(joystickLeft.get(), 1));
launchBoulder->WhileHeld(new Launch());
intakeUpButton.reset(new JoystickButton(joystickLeft.get(), 3));
intakeUpButton->WhileHeld(new IntakeUp());
joystickRight.reset(new Joystick(0));
lockBall.reset(new JoystickButton(joystickRight.get(), 2));
lockBall->WhenPressed(new LockThatBall());
frontArmDown.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(180)));
frontArmDown->WhileHeld(new ManuiplateDown());
frontArmUp.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(0)));
frontArmUp->WhileHeld(new ManuiplateUp());
fire.reset(new JoystickButton(joystickRight.get(), 1));
fire->WhenPressed(new Flipper());
}else if(SmartDashboard::GetString("Please enter name of driver: (first name lower case)", "default") == "larry"){
joystickLeft.reset(new Joystick(1));
eatBall.reset(new JoystickButton(joystickLeft.get(), 5));
eatBall->WhileHeld(new IntakeDownandEat());
fire.reset(new JoystickButton(joystickLeft.get(), 1));
fire->WhenPressed(new Flipper());
joystickRight.reset(new Joystick(0));
intakeUpButton.reset(new JoystickButton(joystickRight.get(), 5));
intakeUpButton->WhileHeld(new IntakeUp());
lockBall.reset(new JoystickButton(joystickRight.get(), 3));
lockBall->WhenPressed(new LockThatBall());
frontArmDown.reset(new JoystickButton(joystickRight.get(), 4));
frontArmDown->WhileHeld(new ManuiplateDown());
frontArmUp.reset(new JoystickButton(joystickRight.get(), 6));
frontArmUp->WhileHeld(new ManuiplateUp());
launchBoulder.reset(new JoystickButton(joystickRight.get(), 2));
launchBoulder->WhileHeld(new Launch());
fire.reset(new JoystickButton(joystickRight.get(), 1));
fire->WhenPressed(new Flipper());
}else if(SmartDashboard::GetString("Please enter name of driver: (first name lower case)", "default") == "matthew"){
joystickRight.reset(new Joystick(0));
eatBall.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(180)));
eatBall->WhileHeld(new IntakeDownandEat());
launchBoulder.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(2) == 1.0));
launchBoulder->WhileHeld(new Launch());
intakeUpButton.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(0)));
intakeUpButton->WhileHeld(new IntakeUp());
lockBall.reset(new JoystickButton(joystickRight.get(), 2));
lockBall->WhenPressed(new LockThatBall());
frontArmDown.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(90)));
frontArmDown->WhileHeld(new ManuiplateDown());
frontArmUp.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(270)));
frontArmUp->WhileHeld(new ManuiplateUp());
fire.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(3) == 1.0));
fire->WhenPressed(new Flipper());
}else if(SmartDashboard::GetString("Please enter name of driver: (first name lower case)", "default") == "mikayla"){
/*
* a = 1 same for ps3: a = x b = o x = square y = triangle
* b = 2
* x = 3
* y = 4
* lb = 5
* rb = 6
* back = 7
* start = 8
* left anglog press = 9
* right anlog press = 10
* lt = axis 2
* rt = axis 3
*
* left analog = 1 y axis
* right analog = 5 y axis
* dpad is 45 degree increaments, nothing is pressed it is -1, up is 0 degrees use stick->GetPOV()
*/
joystickRight.reset(new Joystick(0));
eatBall.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(2) == 1.0));
eatBall->WhileHeld(new MikaylaIntake());
launchBoulder.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetRawAxis(3) == 1.0));
launchBoulder->WhileHeld(new Launch());
intakeUpButton.reset(new JoystickButton(joystickRight.get(), 2));
intakeUpButton->WhileHeld(new IntakeUp());
mikayla.reset(new JoystickButton(joystickRight.get(), 1));
mikayla->WhileHeld(new IntakeDown());
lockBall.reset(new JoystickButton(joystickRight.get(), 3));
lockBall->WhenPressed(new LockThatBall());
frontArmDown.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(180)));
frontArmDown->WhileHeld(new ManuiplateDown());
frontArmUp.reset(new JoystickButton(joystickRight.get(), joystickRight.get()->GetPOV(0)));
frontArmUp->WhileHeld(new ManuiplateUp());
fire.reset(new JoystickButton(joystickRight.get(), 4));
fire->WhenPressed(new Flipper());
}else{
SmartDashboard::PutString("Please enter name of driver: (first name lower case)", "Invalid Name");
}
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=CONSTRUCTORS
// SmartDashboard Buttons
SmartDashboard::PutData("LockThatBall", new LockThatBall());
SmartDashboard::PutData("IntakeDownandEat", new IntakeDownandEat());
SmartDashboard::PutData("ManuiplateDown", new ManuiplateDown());
SmartDashboard::PutData("ManuiplateUp", new ManuiplateUp());
SmartDashboard::PutData("IntakeUp", new IntakeUp());
SmartDashboard::PutData("TankDrive", new TankDrive());
SmartDashboard::PutData("Launch", new Launch());
SmartDashboard::PutData("Flipper", new Flipper());
SmartDashboard::PutData("LowWall", new LowWall());
SmartDashboard::PutData("RockyWall", new RockyWall());
SmartDashboard::PutData("SallyPort", new SallyPort());
SmartDashboard::PutData("Drawbridge", new Drawbridge());
SmartDashboard::PutData("Ramparts", new Ramparts());
SmartDashboard::PutData("WaterBridge", new WaterBridge());
SmartDashboard::PutData("ChevelTiltyThingies", new ChevelTiltyThingies());
SmartDashboard::PutData("AutoPortcullis", new AutoPortcullis());
SmartDashboard::PutData("AutoLaunch", new AutoLaunch());
SmartDashboard::PutData("AutoUltrasonicDriveToTower", new AutoUltrasonicDriveToTower());
SmartDashboard::PutData("AutoUltrasonicDrive", new AutoUltrasonicDrive());
SmartDashboard::PutData("AutonomousDriveForward", new AutonomousDriveForward());
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=CONSTRUCTORS
}
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=FUNCTIONS
std::shared_ptr<Joystick> OI::getJoystickRight() {
return joystickRight;
}
std::shared_ptr<Joystick> OI::getJoystickLeft() {
return joystickLeft;
}
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=FUNCTIONS
robot.ccp:
// RobotBuilder Version: 2.0
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// C++ from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
#include "Robot.h"
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INITIALIZATION
std::shared_ptr<DriveTrain> Robot::driveTrain;
std::shared_ptr<FlipperSub> Robot::flipperSub;
std::shared_ptr<Launcher> Robot::launcher;
std::shared_ptr<BoulderIntake> Robot::boulderIntake;
std::shared_ptr<FrontArm> Robot::frontArm;
std::unique_ptr<OI> Robot::oi;
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INITIALIZATION
void Robot::RobotInit() {
RobotMap::init();
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=CONSTRUCTORS
driveTrain.reset(new DriveTrain());
flipperSub.reset(new FlipperSub());
launcher.reset(new Launcher());
boulderIntake.reset(new BoulderIntake());
frontArm.reset(new FrontArm());
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=CONSTRUCTORS
// This MUST be here. If the OI creates Commands (which it very likely
// will), constructing it during the construction of CommandBase (from
// which commands extend), subsystems are not guaranteed to be
// yet. Thus, their requires() statements may grab null pointers. Bad
// news. Don't move it.
oi.reset(new OI());
// instantiate the command used for the autonomous period
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=AUTONOMOUS
autonomousCommand.reset(new AutonomousDriveForward());
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=AUTONOMOUS
//spookycam.get()->SetBrightness(5);
//spookycam.get()->UpdateSettings();
datcam = CameraServer::GetInstance();
datcam->SetQuality(50);
datcam->StartAutomaticCapture("cam1");
choose = new SendableChooser();
choose->AddDefault("Drive Forward", new AutonomousDriveForward());
choose->AddObject("WaterBridge", new WaterBridge());
SmartDashboard::PutData("Choose dat auto", choose);
SmartDashboard::PutNumber("Set Launcher Rate", 0.0);
SmartDashboard::PutString("!", "Please allow 3 seconds for flywheel to stabilize!");
SmartDashboard::PutString("Please enter name of driver: (first name lower case)", "default");
SmartDashboard::PutString("Too Close to Goal?", "false");
}
/**
* This function is called when the disabled button is hit.
* You can use it to reset subsystems before shutting down.
*/
void Robot::DisabledInit(){
}
void Robot::DisabledPeriodic() {
visionTable = NetworkTable::GetTable("GRIP/report");
oi.reset(new OI());
Scheduler::GetInstance()->Run();
}
void Robot::AutonomousInit() {
autonomousCommand.reset((Command *) choose->GetSelected());
if (autonomousCommand.get() != nullptr)
autonomousCommand->Start();
}
void Robot::AutonomousPeriodic() {
Scheduler::GetInstance()->Run();
}
void Robot::TeleopInit() {
//10.40.65, This makes sure that the autonomous stops running when
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// these lines or comment it out.
if (autonomousCommand.get() != nullptr)
autonomousCommand->Cancel();
}
void Robot::TeleopPeriodic() {
//std::vector<double> centerY = visionTable.get()->GetNumberArray("centerY", 1);
//std::vector<double> height = visionTable.get()->GetNumberArray("height", 1);
//std::vector<double> width = visionTable.get()->GetNumberArray("width", 1);
/*double y = -((2 * (centerY[1] / height[1])) - 1);
double distanceFromGoal = (RobotMap::TOP_TARGET_HEIGHT_INCHES - RobotMap::CAMERA_HEIGHT_INCHES) / tan(((y*RobotMap::VERTICAL_FOV_DEG/2.0 + RobotMap::CAMERA_PITCH_DEG)*3.14159265359/180.0));
SmartDashboard::PutNumber("Distance from target", distanceFromGoal);*/
//SmartDashboard::PutNumber("width0", width[0]);
//double newDistance = (1.67 * 240) / (2 * width[0]);
//SmartDashboard::PutNumber("Distance from target", newDistance);
SmartDashboard::PutNumber("Ultrasanic", Robot::launcher.get()->ultrasanicCalculation());
Scheduler::GetInstance()->Run();
}
void Robot::TestPeriodic() {
lw->Run();
}
START_ROBOT_CLASS(Robot);
Thank you for your time!::safety::