Tank Drive Model Support

Note

The equations used in our TankModel is derived from Noah Gleason and Eli Barnett’s motor characterization whitepaper. It is recommended that users of this model read the paper so they can more fully understand how this works.

In the interest of making progress, this API may receive backwards-incompatible changes before the start of the 2019 FRC season.

class MotorModel(motorConfig, kv, ka, vintercept)

Motor model used by the TankModel. You should not need to create this object if you’re using the TankModel class.

Arguments:
  • motorConfig (Object) – The specification data for your motor
  • kv (tm_kv) – Computed kv for your robot
  • ka (tm_ka) – Computed ka for your robot
  • vintercept (volt) – The minimum voltage required to generate enough torque to overcome steady-state friction (see the paper for more details)
MotorModel.compute(motorPct, tmDiff)
Arguments:
  • motorPct (*) – Percentage of power for motor in range [1..-1]
  • tmDiff (*) – Time elapsed since this function was last called
class TankModel(motorConfig, robotMass, xWheelbase, robotWidth, robotLength, lKv, lKa, lVi, rKv, rKa, rVi)

This is a model of a FRC tankdrive-style drivetrain that will provide vaguely realistic motion for the simulator.

This drivetrain model makes a number of assumptions:

  • N motors per side
  • Constant gearing
  • Motors are geared together
  • Wheels do not ‘slip’ on the ground
  • Each side of the robot moves in unison

There are two ways to construct this model. You can use the theoretical model via TankModel.theory() and provide robot parameters such as gearing, total mass, etc.

Alternatively, if you measure kv, ka, and vintercept as detailed in the paper mentioned above, you can plug those values in directly instead using the TankModel constructor instead. For more information about measuring your own values, see the paper and this thread on ChiefDelphi.

Note

You can use whatever units you would like to specify the input parameter for your robot, the websim will convert them all to the correct units for computation.

Output units for velocity and acceleration are in ft/s and ft/s^2

Example usage for a 40kg robot with 2 CIM motors on each side with 6 inch wheels:

class MyUserPhysics extends UserPhysics {

  createRobotModel(robotConfig) {
    let math = this.Math;

    let model = this.Models.TankModel.theory(
      this.Models.MotorConfigs.MOTOR_CFG_CIM,
      math.unit(40, 'kg'),
      10.71,
      2,
      math.unit(2, 'ft'),
      math.unit(6, 'inch')
    );

    return model;
  }

  updateSim(halData, dt) {

    const dataOut = halData.out;
    const pwm = dataOut.pwm;

    let lrMotor = pwm[1].value;
    let rrMotor = pwm[2].value;

    let {rcw, fwd} = this.model.getVector(lrMotor, rrMotor, dt);

    let xSpeed = fwd * Math.cos(this.robot.angle);
    let ySpeed = fwd * Math.sin(this.robot.angle);

    this.Matter.Body.setVelocity(this.robot, { x: xSpeed, y: ySpeed });
    this.Matter.Body.setAngularVelocity(this.robot, rcw);
  }
}

Use the constructor if you have measured kv, ka, and Vintercept for your robot. Use the theory() function if you haven’t.

Vintercept is the minimum voltage required to generate enough torque to overcome steady-state friction (see the paper for more details).

The robot width/length is used to compute the moment of inertia of the robot. Don’t forget about bumpers!

Arguments:
  • motorConfig (Object) – Motor specification
  • robotMass (Quantity) – Mass of robot
  • xWheelbase (Quantity) – Wheelbase of the robot
  • robotWidth (Quantity) – Width of the robot
  • robotLength (Quantity) – Length of the robot
  • lKv (Quantity) – Left side kv
  • lKa (Quantity) – Left side ka
  • lVi (volt) – Left side Vintercept
  • rKv (Quantity) – Right side kv
  • rKa (Quantity) – Right side ka
  • rVi (Quantity) – Right side Vintercept
TankModel.getVector(lMotor, rMotor, tmDiff)

Given motor values and the amount of time elapsed since this was last called, retrieves the velocity and anglular velocity of the robot.

To update your encoders, use the lPosition and rPosition attributes of this object.

Note

If you are using more than 2 motors, it is assumed that all motors on each side are set to the same speed. Only pass in one of the values from each side

Arguments:
  • lMotor (Number) – Left motor value (-1 to 1); -1 is forward
  • rMotor (Number) – Right motor value (-1 to 1); 1 is forward
  • tmDiff (Number) – Elapsed time since last call to this function
TankModel.inertia

The model computes a moment of inertia for your robot based on the given mass and robot width/length. If you wish to use a different moment of inertia, set this property after constructing the object

Units are [mass] * [length] ** 2

TankModel.lPosition

The linear position of the left side wheel (in feet)

TankModel.lVelocity

The velocity of the left side (in ft/s)

TankModel.rPosition

The linear position of the right side wheel (in feet)

TankModel.rVelocity

The velocity of the left side (in ft/s)

TankModel.theory(motorConfig, robotMass, gearing, nmotors, xWheelbase, robotWidth, robotLength, wheelDiameter, vintercept)

Use this to create the drivetrain model when you haven’t measured kv and ka for your robot.

Computation of kv and ka are done as follows:

  • \(\omega_{free}\) is the free speed of the motor
  • \(\tau_{stall}\) is the stall torque of the motor
  • \(n\) is the number of drive motors
  • \(m_{robot}\) is the mass of the robot
  • \(d_{wheels}\) is the diameter of the robot’s wheels
  • \(r_{gearing}\) is the total gear reduction between the motors and the wheels
  • \(V_{max}\) is the nominal max voltage of the motor
\[ \begin{align}\begin{aligned}velocity_{max} = \frac{\omega_{free} \cdot \pi \cdot d_{wheels} }{r_{gearing}}\\acceleration_{max} = \frac{2 \cdot n \cdot \tau_{stall} \cdot r_{gearing} }{d_{wheels} \cdot m_{robot}}\\k_{v} = \frac{V_{max}}{velocity_{max}}\\k_{a} = \frac{V_{max}}{acceleration_{max}}\end{aligned}\end{align} \]
Arguments:
  • motorConfig (Object) – Specifications for your motor
  • robotMass (Quantity) – Mass of the robot
  • gearing (Number) – Gear ratio .. so for a 10.74:1 ratio, you would pass 10.74
  • nmotors (Number) – Number of motors per side
  • xWheelbase (Quantity) – Wheelbase of the robot
  • robotWidth (Quantity) – Width of the robot
  • robotLength (Quantity) – Length of the robot
  • wheelDiameter (Quantity) – Diameter of the wheel
  • vintercept (Volt) – The minimum voltage required to generate enough torque to overcome steady-state friction (see the paper for more details)