this is my first time using Java and I seem to be stuck. I'm trying to access a method (getHeading) from a subsystem (DriveTrain) in a command (DriveStraight), but I keep getting the error that "the type getHeading(double) is undefined for the type Subsystem" when I try heading = Robot.DriveTrain.getHeading();
. This is the command:
public class DriveStraight extends Command {
private double speed;
private double duration;
private double heading;
public DriveStraight(float driveSpeed, float duration) {
requires(Robot.DriveTrain);
**heading = Robot.DriveTrain.getHeading();**
}
// Called just before this Command runs the first time
protected void initialize() {
setTimeout(duration);
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
**float currentheading = Robot.DriveTrain.getHeading();**
Robot.DriveTrain.arcadeDrive(speed, (heading - currentheading) * 0.08);
}
And this is the subsystem:
public class DriveTrain extends Subsystem {
AnalogGyro gyro;
RobotDrive drive;
VictorSP frontLeftMotor, rearLeftMotor, frontRightMotor, rearRightMotor;
public DriveTrain() {
frontLeftMotor = new VictorSP(RobotMap.frontLeftMotor);
rearLeftMotor = new VictorSP(RobotMap.rearLeftMotor);
frontRightMotor = new VictorSP(RobotMap.frontRightMotor);
rearRightMotor = new VictorSP(RobotMap.rearRightMotor);
gyro = new AnalogGyro(RobotMap.analogGyro);
gyro.setSensitivity(0.00666);
gyro.calibrate();
}
public void arcadeDrive(float speed, float turn) {
drive.arcadeDrive(OI.joy.getRawAxis(OI.LEFT_Y_AXIS),
OI.joy.getRawAxis(OI.RIGHT_X_AXIS), true);
}
public void tankDrive(float leftValue, float rightValue) {
drive.tankDrive(OI.joy.getRawAxis(OI.LEFT_Y_AXIS),
OI.joy.getRawAxis(OI.RIGHT_Y_AXIS), true);
}
public double getHeading() {
return gyro.getAngle();
}
protected void initDefaultCommand() {
arcadeDrive(0, 0);
}
}
I just came from using C++ so I think I might be trying to use pointers, but I'm not sure. So what's the right way to call a method from a subsystem?
Thanks, Sethra53
You're not managing an instance of Robot.DriveTrain anywhere - all your method calls on the DriveTrain class are being seen by the compiler as calls to static
methods (which don't relate to an object, only to the class). The nearest matching method you have defined anywhere is public double getHeading() {
, which is an instance method and so should be called on an instance. There are 4 places in your code which are referring to Robot.DriveTrain
and I'm not sure what your requires
method is doing so it's tricky to know what you should be passing to it. The other three places, however, should be referring to instances of Robot.DriveTrain
.
e.g.
public class DriveStraight extends Command {
private double speed;
private double duration;
private double heading;
private Robot.DriveTrain driveTrain;
public DriveStraight(float driveSpeed, float duration) {
requires(Robot.DriveTrain);
driveTrain = new Robot.DriveTrain() // create new shared instance
heading = driveTrain.getHeading(); // use instance.
}
// Called just before this Command runs the first time
protected void initialize() {
setTimeout(duration);
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
float currentheading = driveTrain.getHeading(); // use instance created in constructor.
driveTrain.arcadeDrive(speed, (heading - currentheading) * 0.08);
}
...
I can't guarantee any of that will 'work' however, without understanding how the requires
method call works.
A better approach would be to pass the instance in to the DriveStraight
constructor...
public class DriveStraight extends Command {
private Robot.DriveTrain driveTrain;
public DriveStraight(float driveSpeed, float duration, DriveTrain driveTrain) {
this.driveTrain = driveTrain; // use instance created elsewhere
...