A question when using the Robot Characterization

  • If l want to characterize my drivetrain and l want to get the parameters which are needed in the autonomous period .

  • How should l set the Units and the Units per Rotation:

  • l use 4 Talon FX as my drivetrain’s motor, is these three sections set right?

image

  • Should l enter the motorport ? And how to choose that l use the Talon FX? In controllertypes? And what is the CTRE Mag Encoder , if l use 4 Talon FX , how much will it be? Is the Encoder port necessary?
{
    # Ports for motors
    # If doing drive test, treat this as the left side of the drivetrain
    "motorPorts": [],
    # Only if you are doing drive (leave empty "[]" if not)
    "rightMotorPorts": [],
    # Class names of motor controllers used.
    # 'WPI_TalonSRX'
    # 'WPI_VictorSPX'
    # 'WPI_TalonFX'
    # If doing drive test, treat this as the left side of the drivetrain
    "controllerTypes": [],
    # Only if you are doing drive (leave empty "[]" if not)
    "rightControllerTypes": [],
    # Set motors to inverted or not
    # If doing drive test, treat this as the left side of the drivetrain
    "motorsInverted": [],
    # Only if you are doing drive (leave empty "[]" if not)
    "rightMotorsInverted": [],
    # Encoder edges-per-revolution (*NOT* cycles per revolution!)
    # For the CTRE Mag Encoder, use 4096 (4 * 1024 = 4096)
    "encoderEPR": 4096,
    # Gearing accounts for the gearing between the encoder and the output shaft
    "gearing": 1,
    # Encoder ports (leave empty "[]" if not needed)
    # Specifying encoder ports indicates you want to use Rio-side encoders
    # If doing drive test, treat this as the left side of the drivetrain
    "encoderPorts": [],
    # Only if you are doing drive (leave empty "[]" if not)
    "rightEncoderPorts": [],
    # Set to True if encoders need to be inverted
    # If doing drive test, treat this as the left side of the drivetrain
    "encoderInverted": False,
    # Only if you are doing drive (set to False if not needed)
    "rightEncoderInverted": False,
    # ** The following is only if you are using a gyro for the DriveTrain test**
    # Gyro type (one of "NavX", "Pigeon", "ADXRS450", "AnalogGyro", or "None")
    "gyroType": "None",
    # Whatever you put into the constructor of your gyro
    # Could be:
    # "SPI.Port.kMXP" (MXP SPI port for NavX or ADXRS450),
    # "SerialPort.Port.kMXP" (MXP Serial port for NavX),
    # "I2C.Port.kOnboard" (Onboard I2C port for NavX),
    # "0" (Pigeon CAN ID or AnalogGyro channel),
    # "new WPI_TalonSRX(3)" (Pigeon on a Talon SRX),
    # "" (NavX using default SPI, ADXRS450 using onboard CS0, or no gyro)
    "gyroPort": "",
}
  • After generating the file , where should l enter the trackwidth? Or will it be measured automatically? And how can l get the parameters which will be used in an autonomous period?

  • The last question is , if l use a swerve drive , how should l characterize my robot ?

Any help is appreciated!

“Meters” is your best bet since it’s the default for the rest of the trajectory stuff. What you’ll do from there is convert your wheel diameter to meters and then multiply it by pi to get the circumference of the wheel, which will be your units per rotation.

That appears to be correct.

“Ports” in this case would refer to the CAN ID of each motor, you’ll want to assign all four of them in their respective spots with WPI_TalonFX controllers. The CTRE Mag Encoder and encoder ports aren’t relevant here, assuming you’re using the built-in Falcon encoders, which you’ll want to enter 2048 EPR for. Make sure to assign the gearing constant correctly though.

Trackwidth is entered into PathWeaver (I believe under “Drive Base” in the current version but it might be fixed by now) and your DifferentialDriveKinematics class in your robot code.

I’m not quite sure on that. The characterization tool is more intended for standard skid-steer drive trains, so it probably won’t work with a swerve as-is. I know there’s a new version of the tool coming next year that may have swerve support, but one of the WPILib devs will have to weigh in on that.

It doesn’t really need anything dedicated to swerve drives. You can use the simple motor project type to do both module rotation and linear motion.

1 Like

Thanks .

So , what’s the steps if l want to get the parameters which will be used in the autonomous period? From the code, l find some parameters which may not be got from the Robot characterization , such as

      public static final class AutoConstants {
        public static final double kMaxSpeedMetersPerSecond = 3;
        public static final double kMaxAccelerationMetersPerSecondSquared = 3;
        public static final double kMaxAngularSpeedRadiansPerSecond = Math.PI;
        public static final double kMaxAngularSpeedRadiansPerSecondSquared = Math.PI;
    
        public static final double kPXController = 1;
        public static final double kPYController = 1;
        public static final double kPThetaController = 1;
    
        // Constraint for the motion profilied robot angle controller
        public static final TrapezoidProfile.Constraints kThetaControllerConstraints =
            new TrapezoidProfile.Constraints(
                kMaxAngularSpeedRadiansPerSecond, kMaxAngularSpeedRadiansPerSecondSquared);
      }
        public static final double kTurningEncoderDistancePerPulse =
            // Assumes the encoders are on a 1:1 reduction with the module shaft.
            (2 * Math.PI) / (double) kEncoderCPR;
    
        public static final double kPModuleTurningController = 1;
    
        public static final double kPModuleDriveController = 1;
        public static final double kMaxModuleAngularSpeedRadiansPerSecond = 2 * Math.PI;
        public static final double kMaxModuleAngularAccelerationRadiansPerSecondSquared = 2 * Math.PI;

So , how to deal with these parameters?

Hello , when l do the Robot Characterization on the swerve, should l separate the four Talon FX motors in a group(the four motors control the forward speed) . And characterize these four motors. Then , put the other four motors which control the strafe speed of the module in a group .Then characterize these four motors . Is it right? Or what is the right solution?

A swerve module has a motor for forward speed and a motor for rotating the module. Therefore, “forward” and “strafe” are the same thing with the module rotated 90 degrees. Characterize rotation first so you have a module rotation controller tuned, then do the linear motion test. If you don’t have module rotation controllers, the drivetrain won’t be able to go anywhere. :wink:

Whether the motors are in “groups” or not doesn’t matter.

So , l just need to enter the all the ports of my swerve in the robot characterization.

If my ports are below:

        public static final int kFrontLeftDriveMotorPort = 1;
        public static final int kFrontRightDriveMotorPort = 3;
        public static final int kBackLeftDriveMotorPort = 5;
        public static final int kBackRightDriveMotorPort = 7;
    
        public static final int kFrontLeftTurningMotorPort = 2;
        public static final int kFrontRightTurningMotorPort = 4;
        public static final int kBackLeftTurningMotorPort = 6;
        public static final int kBackRightTurningMotorPort = 8;

l just need to enter [1,5,2,6] in the leftmotorports(It seems that it lacks “left” in the photo , do l need to add it myself?) and enter [3,7,4,8] in the rightmotorports?

motorPorts is for left. The template this generates won’t work for linear velocity characterization though because you need module turning control. For module turning characterization, use the simple motor template, not the drivetrain template.

By the way, we’re replacing frc-characterization with GitHub - wpilibsuite/sysid: System identification for robot mechanisms for 2022.

1 Like

Thanks, the drivetrain template is not needed in the swerve drive characterization? l need to change it to the “simple” template? But if l characterize two times , l will get two parameters , which one should l choose to enter? Where should l enter?

Yes. One set of constants will be from driving the robot in a straight line, and the other set will be from rotating a swerve module. Those are the feedforwards for the module ground speed and module rotation respectively. (The ground speed and module rotation are driven by separate PID controllers.)

But if l use a trajectory , it seems that it only has one set of constants. So , how can l rotate while driving in a straight line?

Hello , l have another question .

  private static final double kWheelRadius = 0.0508;
public static final double kWheelDiameterMeters = 0.15

Is there any difference between these two parameters?

Does the m_driveEncoder.getRate() has the same effect with mDriveMotor.getSelectedSensorVelocity() * Constants.ModuleConstants.kDriveEncoderDistancePerPulse * 10;?

And l should enter the ks , kv ,ka from the robot characterization to the method?

You realize your swerve drive has more than one feedback controller, right? There’s a set of constants for each. There’s the module rotation PID controller, the module velocity PID controller, and the position/heading controller (for example, HolonomicDriveController). Each module has its own copy of the module rotation and velocity controllers.

Without context (like where that code is from), all I can tell you is that yes, those values are in fact not identical.

Characterization just wants a velocity. It doesn’t care where it comes from.

Yes. Feedforward Control in WPILib — FIRST Robotics Competition documentation

It seems that the parameters like ks,kv,ka will also be needed in the teleoperated period. So , if my motor ports are below:

        public static final int kFrontLeftDriveMotorPort = 1;
        public static final int kFrontRightDriveMotorPort = 3;
        public static final int kBackLeftDriveMotorPort = 5;
        public static final int kBackRightDriveMotorPort = 7;
    
        public static final int kFrontLeftTurningMotorPort = 2;
        public static final int kFrontRightTurningMotorPort = 4;
        public static final int kBackLeftTurningMotorPort = 6;
        public static final int kBackRightTurningMotorPort = 8;
  • l should enter like this?

Also ,it seems that a swerve drive doesn’t need to invert any motor. Is that right?

  • Besides , it seems that l have two channels of each encoder , channel A and channel B. So, how to enter them in the robot characterization?

After doing this , how should l test the two sets of constants. It seems that the robot characterization can only get the set of constants which will be used in driving a robot in a straight line.

It only have forward and backward button . So , how can l get the set of constants which will be used in a rotation part?

So, what is kwheelDiameterMeters and what is kWheelRadius, just from the common situation.

My whole code is below , can you help me check it if l use them or one of them right?

2021Swerve.zip (25.4 MB)

l mean that does the getRate() method has the same function with the getSelectedSensorVelocity() * Constants.ModuleConstants.kDriveEncoderDistancePerPulse * 10;

It seems that this isn’t about robot characterization ? But l wonder which one l will use in my swerve drive controller ? l wonder whether the WPILIB has used its official lib (maybegetRate() ) to replace the getSelectedSensorVelocity() * Constants.ModuleConstants.kDriveEncoderDistancePerPulse * 10;

Any answers will be appreciated!

If l use the 775 pro and talon ( talon SRX in code ?) as a turning motor, how should l use its encoder?

I don’t know. I haven’t used the characterization tool in months. I’ve been working on SysId instead because the old tool is so error-prone.

That depends entirely on your specific drivetrain’s wiring.

You do two separate tests. They’ll have their own project configs. If you make the motors just the rotation, a forward command will make it spin in place.

The only use of kWheelRadius is commented out.

[tav@myriad 6940Swerve]$ rg kWheelDia
src/main/java/frc/robot/Constants.java
106:        public static final double kWheelDiameterMeters = 0.15;
109:            (kWheelDiameterMeters * Math.PI) / (double) kEncoderCPR;
[tav@myriad 6940Swerve]$ rg kWheelRadius
src/main/java/frc/robot/subsystems/SwerveModule.java
24:  private static final double kWheelRadius = 0.0508;
91:    //m_driveEncoder.setDistancePerPulse(2 * Math.PI * kWheelRadius / kEncoderResolution);

I don’t know how to get an encoder velocity using the CTRE API. That’s a question for CTRE’s docs. You might be able to find what you need on Welcome to Phoenix’s documentation! — Phoenix documentation.

So , l should put 2 drive motors in one test. Then test forward and backward. Then , put the other 2 turning motors in one test . Then test forward and backward . At last , write down the two sets of parameters? But , it seems that l will get two set of PID parameters. How and where should l use them? Is that right?

But how will l deal with the constants that will be used in the autonomous period.
Maybe the parameters like below:

        public static final double kPXController = 1;
        public static final double kPYController = 1;
        public static final double kPThetaController = 1;
    
  • They are used in the code below:
    var thetaController =
        new ProfiledPIDController(
            AutoConstants.kPThetaController, 0, 0, AutoConstants.kThetaControllerConstraints);
    thetaController.enableContinuousInput(-Math.PI, Math.PI);

    SwerveControllerCommand swerveControllerCommand =
        new SwerveControllerCommand(
            trajectory,
            m_swerve::getPose, // Functional interface to feed supplier
            DriveConstants.kDriveKinematics,

            // Position controllers
            new PIDController(AutoConstants.kPXController, 0, 0),
            new PIDController(AutoConstants.kPYController, 0, 0),
            thetaController,
            m_swerve::setModuleStates,
            m_swerve);