Calling Joysticks from Command Group

My team is trying to make a Velocity-controlled Drive Train using PID systems; what we’ve done is created two separate PID subsystems and controllers, one for the Left Motor/Encoder and one for the Right Motor/Encoder. We then created two PID-Commands, one for the Left Side and one for the Right Side. These commands are called from a Command Group called TankDrive; the purpose is to call our Xbox axis values from the Command Group and pass them to the commands, so we can easily use the Group on non-test robots.

We plan to extend this to Arcade Drive, which is why we chose this structure; it minimizes the number of Commands we have to create, and is more easily ported to other bots.


The code for the Group looks something like this:

#include “TankDrive.h”
#include “…/Robot.h”
#include “LeftMotor.h”
#include “RightMotor.h”

TankDrive::TankDrive() {
double left = Robot:: oi->getXbox->getRawAxis(1); //Getting left axis’ Y
double right = Robot:: oi->getXbox->getRawAxis(3); //Getting right axis’ Y

AddParallel(new LeftMotor(left));
AddParallel(new RightMotor(right));

}


While the code for the Commands both look something like this:

#include “LeftMotor.h”
#include “…/Robot.h”

LeftMotor::LeftMotor(double point) {
Requires(Robot::leftPID);
setpoint = point; //setpoint defined in header
}

LeftMotor::Execute() {
Robot::leftPID->SetSetpoint(setpoint);
}

LeftMotor::IsFinished() {
return fabs(Robot::leftPID->getSetpoint() - Robot::leftPID->getPosition()) < 0.1;
}


The Command Group thus gets the value of the Xbox axes, sends them to the commands, and the command keeps resetting the setpoint so the velocity is controlled. However, when we upload this to the CRIO we get a fatal error, and we’ve narrowed it down to the actual calling of the Xbox axis in TankDrive::TankDrive()… when we call it in LeftMotor::Execute(), everything works fine.

My question is if there is anything we can do to make it work in the Command Group, or if we are going to have to call the Xbox in the commands themselves?

Check to make sure that you schedule the tank drive command after you create the controller object. (new OI() before new TankDrive()) Otherwise, you may by trying to de-reference a null pointer.

However, as you have your code right now, you will never change your speed from the initial value of the joysticks, since it is set in the constructor, which is only called once. (Unless you have the command group only execute once before finishing) To me it seems like it would be more efficient to make the tank drive class a command, and remove the two commands that set the left and right speeds separately. http://pastie.org/pastes/5980425/text is what my team has for a tank drive. The setSpeed(float,float) method would simply change the setpoints of the two PIDs.

PS: Something that my team has had trouble with is the integral term of the PIDs growing out of control. To fix this we simply reset the PIDs when the joysticks are in the ‘deadband’, or close to 0.