"Is it possible to control the output torque of a brushed DC motor using PWM?"
Yes - torque is proportional to current.
If the PWM source is a micro-controller then you need to measure the current (consider ACS712 or similar which will output a voltage: V=Voffset + k*Imotor), capture with an ADC and then write a PI control loop to adjust the PWM duty cycle.
Here is a example control loop that might be called in an interrupt (of course removing the while(1) then)
while(1) {
Ierr = Idesired - Imeasured;
err_sum += Ierr;
PWMcommand = Kp * Ierr + Ki * err_sum;
}
You'll need need to scale the variables, work out units, and signs, etc - but that is the basic structure.
For tuning, set Ki to near zero, lock the rotor and apply a step in Idesired and look at the response. The step current needs to be similar to that which you'll drive the motor. I'll assume its 1amp. Increase Kp until the step response has overshoot then back off a bit. With Kp alone, there will always be an error in Imeasured - esp once the motor starts during. To correct this you need the integral term.
With the rotor locked, continue your ~1amp current step and increase Ki. Again you want Ki large - but not so large as to cause oscillation. If Ki is too small the PWM response will be slow when the motor speed changes - and thus the torque will change.
The PWM frequency also effects the control loop coefficients (Esp the Ki) So use a constant PWM frequency. The frequency is typical at least 20Khz to not be audible, but ultimately it more about the motor inductance, current ripple and the rotor inertia.
There are countless university classes dedicated to the topic of control theory. These are needed to make a surgical robot - but what I said will get your first torque controller working!