docs: def theory(
          cls,
          motor_config: MotorModelConfig,
          robot_mass: units.Quantity,
          gearing: float,
          nmotors: int = 1,
          x_wheelbase: units.Quantity = _kitbot_wheelbase,
          robot_width: units.Quantity = _kitbot_width,
          robot_length: units.Quantity = _kitbot_length,
          wheel_diameter: units.Quantity = 6 * units.inch,
          vintercept: units.volts = 1.3 * units.volts,
          timestep: int = 5 * units.ms,
      ):
          r"""
              Use this to create the drivetrain model when you haven't measured
              ``kv`` and ``ka`` for your robot.
              
              :param motor_config:    Specifications for your motor
              :param robot_mass:      Mass of the robot
              :param gearing:         Gear ratio .. so for a 10.74:1 ratio, you would pass 10.74
              :param nmotors:         Number of motors per side
              :param x_wheelbase:     Wheelbase of the robot
              :param robot_width:     Width of the robot
              :param robot_length:    Length of the robot
              :param wheel_diameter:  Diameter of the wheel
              :param vintercept:      The minimum voltage required to generate enough
                                      torque to overcome steady-state friction (see the
                                      paper for more details)
              :param timestep_ms:     Model computation timestep
              
              Computation of ``kv`` and ``ka`` are done as follows:
              
              * :math:`\omega_{free}` is the free speed of the motor
              * :math:`\tau_{stall}` is the stall torque of the motor
              * :math:`n` is the number of drive motors
              * :math:`m_{robot}` is the mass of the robot
              * :math:`d_{wheels}` is the diameter of the robot's wheels
              * :math:`r_{gearing}` is the total gear reduction between the motors and the wheels
              * :math:`V_{max}` is the nominal max voltage of the motor
              
              .. math::
              
                  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}}
          """
  
          # Check input units
          # -> pint doesn't seem to support default args in check()
          Helpers.ensure_mass(robot_mass)
          Helpers.ensure_length(x_wheelbase)
          Helpers.ensure_length(robot_width)
          Helpers.ensure_length(robot_length)
          Helpers.ensure_length(wheel_diameter)
  
          max_velocity = (motor_config.freeSpeed * math.pi * wheel_diameter) / gearing
          max_acceleration = (2.0 * nmotors * motor_config.stallTorque * gearing) / (
              wheel_diameter * robot_mass
          )
  
          Helpers.ensure_velocity(max_velocity)
          Helpers.ensure_acceleration(max_acceleration)
  
          kv = motor_config.nominalVoltage / max_velocity
          ka = motor_config.nominalVoltage / max_acceleration
  
          kv = units.tm_kv.from_(kv, name="kv")
          ka = units.tm_ka.from_(ka, name="ka")
  
          logger.info(
              "Motor config: %d %s motors @ %.2f gearing with %.1f diameter wheels",
              nmotors,
              motor_config.name,
              gearing,
              wheel_diameter.m,
          )
  
          logger.info(
              "- Theoretical: vmax=%.3f ft/s, amax=%.3f ft/s^2, kv=%.3f, ka=%.3f",
              max_velocity.m_as(units.foot / units.second),
              max_acceleration.m_as(units.foot / units.second ** 2),
              kv.m,
              ka.m,
          )
  
          return cls(
              motor_config,
              robot_mass,
              x_wheelbase,
              robot_width,
              robot_length,
              kv,
              ka,
              vintercept,
              kv,
              ka,
              vintercept,
              timestep,
          )