Help Setting Up PID System for Tank Drive Train

My team is making 4 motor drive train that has two on each side with a jaguar attached to each motor. I have a basic understanding of the CommandBase structure included in the library, but I’m not sure what I would use for the pid loop when it comes to values, constants, and to do with returnPIDInput(). I’m not entirely sure what sort of input the jaguars can have, and that’s the source of my problem. I keep seeing that they have built in encoders? Here’s my code so far. I hope that once I figure out how to use PID here I’ll be able to use a similar format to control our “arm.”

/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package edu.wpi.first.wpilibj.templates.subsystems;

import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.command.PIDSubsystem;
import edu.wpi.first.wpilibj.templates.RobotMap;

/**
*

  • @author l0stboy
    */
    public class DriveTrain extends PIDSubsystem {

    private static final double Kp = 0.0;
    private static final double Ki = 0.0;
    private static final double Kd = 0.0;

    //declare objects

    RobotDrive zombieDrive;

    // Initialize your subsystem here
    public DriveTrain() {
    super(“DriveTrains”, Kp, Ki, Kd);

     // Use these to get going:
     // setSetpoint() -  Sets where the PID controller should move the system
     //                  to
     // enable() - Enables the PID controller.
     zombieDrive = new RobotDrive(RobotMap.leftBackMotor,    RobotMap.leftFrontMotor, 
                                  RobotMap.rightBackMotor, RobotMap.rightFrontMotor);
    

    }

    public void initDefaultCommand() {
    // Set the default command for a subsystem here.
    //setDefaultCommand(new MySpecialCommand());d
    setDefaultCommnad(JoystickDrive);
    }

    protected double returnPIDInput() {
    // Return your input value for the PID loop
    // e.g. a sensor, like a potentiometer:
    // yourPot.getAverageVoltage() / kYourMaxVoltage;
    return zombieDrive.get;
    }

    protected void usePIDOutput(double output) {
    // Use output to drive your system, like a motor
    // e.g. yourMotor.set(output);
    }
    }

An encoder is a sensor that must be mounted on/near the device whose rotary speed/position it is sensing. So no, there is no encoder built-in to the Jag.

The Jag does have a built-in encoder interface however, to receive a signal from an encoder.

And the Jag also has a microcontroller with firmware which which can use the encoder signal as an input to a PID algorithm in the firmware.
*
*

That makes sense. Would there be link anywhere for some sample code of that?

I don’t have the FRC Java installed here. I’ll let a Java guru answer that.

You must use CAN bus (instead of PWM) to control the Jags if you want to use their built-in PID.

Depending on what you want to accomplish with the encoders, you may be better off connecting them to the cRIO rather than the Jag, and run your controller in the cRIO (either home-brew or the PID in WPILib library).
*
*

If you look at the GearsBot sample program included with the Netbeans install it should serve as an example. There are a few differences, it uses an ultrasonic rangefinder to drive its PID loop. And it uses 2 motors.

You can modify the RobotDrive constructor to take all 4 of your motors. one you do that, the rest will be unchanged.

And you only need to use a PID subsystem if you intend to use encoders. If you aren’t installing encoders change the PIDSubsystem to a Subsystem and remove all the methods and code that pertain to the PID loop stuff (returnPIDInput and usePIDOutput).

If you do have encoders, then instead of using rangefinder.getVoltage() as the feedback element, you’ll read the encoder value and use that. The PID constants (Kp, Ki, and Kd) will have to be adjusted to account for the range of values the encoders will return. And the set point will be in the same units that the encoder is returning, such as encoder count that represents the distance you need to drive.

Brad

Ether,

how about a code sample to connect the cRIO to the internal PID of the Jaguar? The WindRiver user’s guide has no text in the serial interface section, and nothing for digital control of a Jaguar. Also, is there code for the SmartDashboard to monitor and control the PID parameters and monitor the speed and drive voltage outputs? We would like to use the internal Jaguar PID, but have not yet found a way to control it through the robot.

Mike

I’m not a Java programmer so I can’t give you authoritative advice in this area.

According to Page 32 of this document, the Jaguar class of the WPILib library supports CAN on the Jaguar. As I mentioned in the earlier post in this thread, I don’t have access to an FRC Java installation so I can’t confirm whether this class supports the serial-to-CAN interface.

According to the C++ WPILib reference from 2011, there’s a CANJaguar class which might have what you need (assuming there’s an equivalent class in Java).
*
*

You can look at our team’s 2011 code for an example if you like - it’s available at http://code.google.com/p/robovikings-2607/. In particular look at the LogomotionDriveTrain class.

Basically, in robotInit() you would do something similar to this:


public void robotInit() {
   try {
      m = new CANJaguar(2);    // change 2 to match the CAN id of the Jag
      m.changeControlMode(CANJaguar.ControlMode.kSpeed);
      m.setSpeedReference(CANJaguar.SpeedReference.kEncoder);
      m.configEncoderCodesPerRev(240);  // change 240 to match your encoder
      m.setPID(.350, .004, .001);  // change gains to whatever you need based on tuning
      m.enableControl();
   } catch (Exception e) {
       ...
   }
}

Then in the autonomous or teleop methods use the m.setX() to set the speed you want the motor to run at.

The WPILib classes for CAN support in Java and C++ (and Labview for that matter) are all independent of the type of CAN interface used (serial or 2CAN). The actual comms are handled via the “plugin” (BlackJag plugin for serial, or 2CAN plugin for the 2CAN) and the WPILib routines communicate through those plugins.

Hope this helps!

  • Ron
    Team #2607 controls mentor