Can you tell I’ve been playing around with sprint time simulations too much? Here’s a better description:

The force your robot can apply on the ground is limited by the friction force the wheels can apply. The force applied by the motors is equal to the torque they apply at the wheel divided by the wheel radius. So we get:

F=\text{min} \left[ \frac{\tau_w}{r};\ f \right]

We can then expand those terms. The motor torque on the wheels is (torque each motor applies) x (number of motors) x (gear ratio) x (efficiency). The friction force equals the normal force times the CoF.

\tau_w = \tau_m n G \eta

f = F_N \mu

We can then further expand the motor torque equation using the linear relationship between torque and angular velocity, adjusted for voltage. And we know the normal force is equal to the force from gravity times the driven wheel percentage.

\tau_m = \tau_s^* \left( 1- \frac{\omega}{\omega_f^*} \right)

F_N = mg\%

There’s one last set of expansions. The motor stall torque and free speed can both be adjusted for voltage by multiplying the spec value by the voltage ratio. The motor rotational velocity can be calculated by dividing the robot’s velocity by wheel radius (to get the wheel rotational velocity) and then multiplying by the gear ratio.

\tau_s^* = \tau_s V

\omega_f^* = \omega_f V

\omega = \frac{v G}{r}

Putting all of that back together gives the formula I originally wrote:

F = \text{min} \left[ \frac{1}{r} \tau_s V \left(1-\frac{v G}{\omega_f V r} \right) n G \eta;\ m g \% \mu \right]

If you want to calculate the force the robot can apply when it’s not moving (either as it’s starting up or when it’s pushing against another robot), you can substitute in v=0. Then the formula simplifies to:

F = \text{min} \left[ \frac{\tau_s V n G \eta}{r} ;\ m g \% \mu \right]