Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Java (http://www.chiefdelphi.com/forums/forumdisplay.php?f=184)
-   -   Xbox Controller (http://www.chiefdelphi.com/forums/showthread.php?t=129846)

LFRobotics 20-06-2014 23:25

Xbox Controller
 
I got help earlier but I have tried to program one in and just cant figure it out. I am completely lost and need lots of help so if anyone out there is willing id be forever grateful.

THANKS!

ekapalka 20-06-2014 23:58

Re: Xbox Controller
 
Its just like any other controller, except with more axes and buttons. See the following post: http://www.chiefdelphi.com/forums/sh...51&postcount=4. Go to "Run" on your computer and type in "joy.cpl" (without quotes, with the controller plugged in). Then go to properties to see the button numbers.

cgmv123 21-06-2014 13:55

Re: Xbox Controller
 
https://github.com/team1306/Badgerbo...ontroller.java

LFRobotics 21-06-2014 16:49

Re: Xbox Controller
 
I sorry but I have tried for hours now and just cant seem to figure out how to implement both your ways. Like how do I use buttons - because the regular "button.whenPressed(new exampleCommand());" isn't working. How do I make it work with tankdrive when there are not two joysticks connected but rather one controller. I am sooooo confused and I tried to figure it out on my own but I have gotten nowhere.

THANKS for the help.

NWChen 21-06-2014 20:52

Re: Xbox Controller
 
Can we see the code you have so far?

Assuming you're using a RobotDrive object to control your drivetrain, and the tankDrive method, your Xbox controller (like ekapalka said) should behave much like a pair of joysticks in tank drive - with each Xbox stick controlling one side of the drivetrain.
Code:

drive.tankDrive(gamepad.getLeftStickY(), gamepad.getRightStickY();

LFRobotics 22-06-2014 14:54

Re: Xbox Controller
 
Okay - im still confused about how to implement it in my DriveTele command and how to make buttons work.

Here's is the Chassis subsystem - I think I have this figured out:

Code:

package edu.wpi.first.XBoxBot2014.subsystems;

import edu.wpi.first.XBoxBot2014.OI;
import edu.wpi.first.XBoxBot2014.RobotMap;
import edu.wpi.first.XBoxBot2014.commands.DriveTele;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.command.Subsystem;

/**
 *
 * @author FrankyMonezz
 */
public class Chassis extends Subsystem {
    // Put methods for controlling this subsystem
    // here. Call these from Commands.
    RobotDrive drive;
   
    OI oi = new OI();

    public void initDefaultCommand() {
        // Set the default command for a subsystem here.
        setDefaultCommand(new DriveTele());
    }
   
    public Chassis(){
        drive = new RobotDrive(RobotMap.leftMotorPort, RobotMap.rightMotorPort);
        drive.setSafetyEnabled(false);
    }
   
    public void driveTele(Joystick leftStick, Joystick rightStick){
      drive.tankDrive(oi.xcon2.getLeftJoyY(), oi.xcon2.getRightJoyY());
    }
   
    public void setSpeed(double speed){
        drive.setMaxOutput(speed);
    }
   
    public void driveAuton(double speed, double turnRate)
{
        drive.arcadeDrive(speed, turnRate);
}

   
}

Here is the XBoxController class that im using - kindly given to me by cgmv123:

Code:

package edu.wpi.first.XBoxBot2014.subsystems;

import edu.wpi.first.wpilibj.DriverStation;

/**
 *
 * @author Jon Morton
 */
public class XBoxController {
   
   
    private DriverStation _ds;
    private final int _port;

    public XBoxController(int port) {
        _ds = DriverStation.getInstance();
        _port = port;
    }

    public double getRawAxis(final int axis) {
        return _ds.getStickAxis(_port, axis);
    }

    public boolean getRawButton(final int button) {
        return ((0x1 << (button - 1)) & _ds.getStickButtons(_port)) != 0;
    }

    /**
    * Warning! getRightTrigger() and getLeftTrigger() both use getRawAxis(3).
    * As getRawAxis(3) goes below zero, getRightTrigger() increases, and as
    * getRawAxis(3) goes above zero, getLeftTrigger() increases. If both
    * triggers are pressed, both of them will be treated as zero. You can only
    * use one trigger at a time.
    *
    * @return
    */
    public double getRightTrigger() {
        return -Math.min(getRawAxis(3), 0);
    }

    public double getLeftTrigger() {
        return Math.max(getRawAxis(3), 0);
    }

    public double getRightJoyX() {
        return getRawAxis(4);
    }

    public double getRightJoyY() {
        return getRawAxis(5);
    }

    public double getLeftJoyX() {
        return getRawAxis(1);
    }

    public double getLeftJoyY() {
        return getRawAxis(2);
    }

    public boolean getButtonA() {
        return getRawButton(1);
    }

    public boolean getButtonB() {
        return getRawButton(2);
    }

    public boolean getButtonX() {
        return getRawButton(3);
    }

    public boolean getButtonY() {
        return getRawButton(4);
    }

    public boolean getButtonBack() {
        return getRawButton(7);
    }

    public boolean getButtonStart() {
        return getRawButton(8);
    }

    public boolean getButtonRB() {
        return getRawButton(6);
    }

    public boolean getButtonLB() {
        return getRawButton(5);
    }

    public boolean getButtonLS() {
        return getRawButton(9);
    }

    public boolean getButtonRS() {
        return getRawButton(10);
    }
   
}

I instantiate XBoxController here(conPort is an integer value of 1 stored in RobotMap) - I have the
Code:

boolean button = xcon2.getWHATEVER()
figured out - but how do I use that to turn say a motor on - because for example
Code:

button.whenPressed or button.when released
does not work with boolean values:

Code:

package edu.wpi.first.XBoxBot2014;

import edu.wpi.first.XBoxBot2014.subsystems.XBoxController;

public class OI {
   
    public XBoxController xcon2 = new XBoxController(RobotMap.conPort);
   
   

public OI() {
       
        boolean button = xcon2.getButtonA();
    }   

 }


NWChen 23-06-2014 02:13

Re: Xbox Controller
 
Quote:

Originally Posted by LFRobotics (Post 1390696)
Code:

button.whenPressed or button.when released
does not work with boolean values

whenPressed() and whenReleased() are methods of the Button class, not of booleans. As a result, if you want to perform a command when a button is being pressed or released you need to call the method on a Button object, not a boolean.

The JoystickButton constructor takes a human interface device (Xbox controller object) and a button number as parameters. In your code, you could do the following:

Code:

package edu.wpi.first.XBoxBot2014;

import edu.wpi.first.XBoxBot2014.subsystems.XBoxController;

public class OI {
    public XBoxController xcon2 = new XBoxController(RobotMap.conPort);
    private Button button = new JoystickButton(xcon2, 1); //Button A = 1

    public OI() {
        button.whenPressed(doThing());
  }   
}

As for driveTele(), you don't need to take a leftStick and a rightStick as parameters if you don't use them in the method. Instead, drive.tankDrive() takes values from the xcon2 object in oi:
Code:

public void driveTele(Joystick leftStick, Joystick rightStick){
    drive.tankDrive(oi.xcon2.getLeftJoyY(), oi.xcon2.getRightJoyY());
}

I don't have much expertise with command-based programming (sorry), but here's what I'd do to fix that problem with your current setup:
Replace the parameters with doubles, and take advantage of the fact that tankDrive() will also take a leftValue and rightValue as input:
Code:

public void driveTele(double leftValue, double rightValue){
    drive.tankDrive(leftValue, rightValue);
}

Your DriveTele() command will then look something like this.

Hope it works!

LFRobotics 23-06-2014 11:38

Re: Xbox Controller
 
Thanks soooo much. It all worked except for the

Code:

private Button button = new JoystickButton(xcon2, 1);
Netbeans gets all mad and says

Quote:

incompatible types: XBoxController cannot be converted to GenericHID

notmattlythgoe 23-06-2014 13:14

Re: Xbox Controller
 
Quote:

Originally Posted by LFRobotics (Post 1390793)
Thanks soooo much. It all worked except for the

Code:

private Button button = new JoystickButton(xcon2, 1);
Netbeans gets all mad and says

What I would do in your case is scrap the use of the XBoxController class and use the provided Joystick class with these button/joystick mappings.

So for the A button it would be:

Code:

Joystick joystick = new Joystick(1);
private Button button = new JoystickButton(joystick, 0);

And to access the left and right sticks for tank drive it would be:

Code:

oi.joystick.getRawAxis(7); //Left stick
oi.joystick.getRawAxis(5); //Rightstick

The best way to do this would be to create a class that extends the Joystick class then:
-create getter methods for each of the buttons and axis
-create static constants that hold the mapped button numbers and axis

If you'd like more information on how to do this I can assist you there too.

NWChen 23-06-2014 14:43

Re: Xbox Controller
 
Quote:

Originally Posted by LFRobotics (Post 1390793)
Netbeans gets all mad and says

incompatible types: XBoxController cannot be converted to GenericHID

You can have the XBoxController class extend GenericHID and have NetBeans implement all abstract methods:
Code:

public class XBoxController extends GenericHID{
...
}

and that should allow you to cast XBoxController to a GenericHID.

notmattlythgoe's suggestion is much better, but for a quick fix right now this should work.

LFRobotics 23-06-2014 14:43

Re: Xbox Controller
 
Okay I get it - but why cant I just continue to use

Code:

Joystick joystick = new Joystick(1);
private Button button = new JoystickButton(joystick, 0);

to assign my buttons or even

Code:

private Button button = new JoystickButton(joystick, joystick.getRawButton(0));
instead of having to create a whole new class.

And if it is completely necessary to do so I would need some help - I have an idea of what to do but I would still need some guidance.

THANKS!

notmattlythgoe 23-06-2014 14:49

Re: Xbox Controller
 
Quote:

Originally Posted by LFRobotics (Post 1390818)
Okay I get it - but why cant I just continue to use

Code:

Joystick joystick = new Joystick(1);
private Button button = new JoystickButton(joystick, 0);

to assign my buttons or even

Code:

private Button button = new JoystickButton(joystick, joystick.getRawButton(0));
instead of having to create a whole new class.

And if it is completely necessary to do so I would need some help - I have an idea of what to do but I would still need some guidance.

THANKS!

You don't need a whole new class. Writing the new class will just make it easier in the future to write code using the xbox controller, but they literally do the exact same thing.

Just using the JoystickButton along with the Joystick class is a perfectly fine way to do it. So for you I'd suggest you stick with the below for now.
Code:

Joystick joystick = new Joystick(1);
private Button button = new JoystickButton(joystick, 0);


LFRobotics 23-06-2014 14:54

Re: Xbox Controller
 
@NWChen I tried that but it didn't work - THANKS though!

@notmattlythgoe In that case id like to do it - wouldn't it be a lot like the XBoxController class other than the fact that it extends the Joystick class - at least the getters would be the same

notmattlythgoe 23-06-2014 15:11

Re: Xbox Controller
 
Quote:

Originally Posted by LFRobotics (Post 1390822)
@NWChen I tried that but it didn't work - THANKS though!

@notmattlythgoe In that case id like to do it - wouldn't it be a lot like the XBoxController class other than the fact that it extends the Joystick class - at least the getters would be the same

Yes the getters would be similar.

You'll want to get rid of the getRaw...() methods from the XBoxController class because you get those automatically from extending the Joystick class. Also remove the port and driver station fields since the Joystick class takes care of that communication for you.

Don't forget to include a single parameter constructor that calls the Joystick constructor.

Then what you'll want to do is create a list of static final variables that hold the mapping values for the buttons, this way you don't have to memorize what button maps to what value. I would also suggest using these static fields as the values in the getter methods, this way if you ever have to change the value you only have to change it in one place.

Example:
Code:

public static final int A_BUTTON = 0;
public static final int B_BUTTON = 1;
etc...

Code:

public boolean getButtonA() {
        return getRawButton(A_BUTTON);
}

Then you can use it like so:
Code:

XBoxController joystick = new XBoxController(1);
private Button button = new JoystickButton(joystick, XBoxController.A_BUTTON);


LFRobotics 23-06-2014 15:53

Re: Xbox Controller
 
Ok AWESOME - now this may seem like a dumb question to you but im a beginner programmer so here it is

How exactly do I extend the Joystick class - I tried it like this:

Code:

public class XBox extends Joystick {
}

but Netbeans doesn't like that

When you say

Quote:

include a single parameter constructor that calls the Joystick constructor
do you want that in the class and would that just look like

Quote:

Joystick stick = new Joystick();
THANKS for all your help!


All times are GMT -5. The time now is 10:42.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi