Torque flow in car differential spider gear system

Started by
18 comments, last by Vu Chi Thien 4 years, 10 months ago

Hi everyone.

I'm working on a vehicle (more specifically: cars) simulation in Unity3D with a complete drivetrain system of engine, gearbox, differential, and wheels as separate components. Each component will update itself with the torque passing through the system. More specifically:

The torque starts from the engine initially, then through the clutch and gearbox to the differential, where the torque is splinted appropriately to two sides (either active wheels or axle differentials). The wheels update themselves and pass the force to the rigidbody. The feedback torque from the wheels is then passed through the system back the the engine in the next step to determine engine torque for this next step.

Currently my system is at early step where the engine never stall, the clutch is permanently locked. So the engineRPM is a simple (wheelLeftRPM + wheelRightRPM) * 0.5f.

I'm trying to simulate the open differential  by splitting the torque 50-50 to both active wheels simply: wheelLeftTorque = wheelRightTorque = engineTorque * gear * 0.5f. 

 

This works OK when the torque comes from the engine. But in the case where the torque comes from one of the active wheel or outside, for example, when the car is jacked up and one wheel got spun when the engine is not running. In this case, the other wheel will spin the other way.

I've watched some videos about open diff to be able to understand this. When one wheel is spinning and the diff case is held static, the spider gear that sits in between the side gears of two wheel axle, would spin (because the sun gear that the spider gear is connected to is held static, so it can only spin on its own axis). This rotation of the spider gear transfer rotation of one side gear to the other, making the other wheel spins the other way.

Mathematically, since wheelSpeedLeft + wheelSpeedRight = 2.0f * CageSpeed, when CageSpeed is 0, then wheelSpeedLeft and wheelSpeedRight must have opposite sign, which illustrates the opposite rotations of the wheels.

However, that's in term of speed and power flow. Since I'm working with torque, I don't know how the flow of torque going from one wheel to the other in this case. What is the amount of torque that goes from one wheel to the other? How should I model or come up with a formula that covers both cases when torque comes from the engine or from one side, or rather, fully cover the full flow of torque in the diff? The final answer that I need is the amount of torque that will flow to each wheel.

Thank you very much.

Advertisement

In my vehicle physics engine, I use a simple model for the open differential. Basically, the torque from the driveshaft would go to the path of least resistance. In terms of wheels, resistance could be represented by wheel load (it's hard to turn loaded wheel) and wheel spin velocity (it's harder to turn stationary wheel than an already spinning one). So basically, you have to calculate the weighting factor for each wheel.

Here's the formula that I used:


float totalAngVel = 0;
float totalLoad = 0;

// both these coefficient define how much we regard one property
// over the other when calculating wheel's weighting factor. Both must sum to one
float coeffAngVel = 0.2f;
float coeffLoad = 0.8f;

// calculate sum
for (int i=0; i<wheelCount; i++) {
  totalAngVel += ABS(wheels[i].angVel);	// angular velocity has direction, we disregard that here
  totalLoad += wheels[i].load;			// load is normal force computed somewhere before
}

// if both totalAngVel and totalLoad is zero, that means our car is not grounded and the 
// wheel is not turning, in this case, I use equal weighting factor for all wheel
// AVOID DIVISION BY ZERO
if (totalLoad + totalAngVel < EPSILON) {
  float weightingFactor = 1.f / wheelCount;
  
  for (int i=0; i<wheelCount; i++) {
    wheels[i].weightFactor = weightingFactor;
  }
} else {
  // we can compute our weighting factor per wheel.
  float weightingFactor = 1.f / wheelCount;
  
  for (int i=0; i<wheelCount; i++) {
    float weightAngVel = 0;
    
    // first we compute weight from angular velocity
    // if the totalAngVel is zero, use default weightingFactor
    if (totalAngVel < EPSILON)
      weightAngVel = weightingFactor;
    else
      weightAngVel = wheels[i].angVel / totalAngVel;
    
    weightAngVel *= coeffAngVel;
    
    float weightLoad = 0;
    // next we compute weight from wheel load
    // if the totalLoad is zero, use default weightingFactor
    if (totalLoad < EPSILON)
      weightLoad = weightingFactor;
    else
      weightLoad = wheels[i].load / totalLoad;
    
    weightLoad *= coeffLoad;
    
    // add em
    wheels[i].weightFactor = weightAngVel + weightLoad;
  }
}

After that, whenever you apply torque to the driveshaft, just apply that torque to the wheel using the weight factor, so

for each wheel:

applyTorque(driveTorque * wheels.weightFactor);

5 hours ago, Bow_vernon said:

Basically, the torque from the driveshaft would go to the path of least resistance

Actually that's incorrect though. The Power would go to the path of least resistance, not Torque. In an open diff, the Torque is always split 50:50 across 2 sides. Power is Torque * Speed, so while the Torque is the same at 2 wheels, the one spinning faster (higher speed) would have more power, thus Power goes to the path of least resistance.

For the "weight" you are talking about, I have that all taken care of with my tire model. That "weight" is the traction force/torque from the road that propel the car forward and oppose the rolling direction of the wheel (which is F = mu * load, hence heavy loaded wheel is harder to turn). 

So my current simple open diff model would be like this: Engine torque is split 50:50 between 2 wheels. That torque spins the 2 wheels, creating traction force from slip. This traction force is then added to the engine torque the wheel received to calculate the final wheel angular velocity (netTorque = engineTorque - roadTorque). Basically, throw torque at the wheel and the wheel takes care of itself using forces acting on it. This way, heavily loaded wheel would have lower angular velocity due to higher roadTorque, while the lightly loaded one would have higher angular velocity, taking all the power.


angularVelocity += engineTorque / Inertia * deltaTime; //The instantanious angular velocity of this frame after the wheel receive motor torque from engine
slip = CalSlip(angularVelocity, wheelHubSpeed); //the tire deforms/slip, creating force
roadForce = CalForce(slip, load); //the force the propel the car from the road
roadTorque = roadForce * radius; //turn force to reaction torque on the wheel
angularVelocity -= roadTorque / Inertia * deltaTime; //final angular velocity after factoring in reaction torque

For the torque split from engine to each wheel, it's an open diff, so just simple as engineTorque * 0.5f;


leftWheel.engineTorque = rightWheel.engineTorque = driveTorque * 0.5f;

What I'm curious about is that what is the extra torque that causes one wheel to rotate in opposite direction when the other is spun, in the case when the car is jacked up. Currently in my model, there are only roadTorque and engineTorque acting on the wheel, nothing else, so I don't understand where to have that "extra torque" mentioned above into.

The correct model would satisfy this equation: leftWheel.engineTorque  + rightWheel.engineTorque = engineDriveTorque. So when driveTorque is 0 but there is engineTorque at one wheel, then the other wheel would have a torque in opposite direction. However implementing this is something that I'm still confused about.

Thank you very much for the reply.

6 hours ago, Vu Chi Thien said:

What I'm curious about is that what is the extra torque that causes one wheel to rotate in opposite direction when the other is spun

Yes, it's an interesting question. As the engine is not running and the reaction torque going back to the engine tries to slow it down which result in a negative torque coming back to the wheels and goes to the one with less friction.

Also I wouldn't use wheel loads here, more like road/brake torques. And brakes are commonly "neglected", but they need some extra calculation as they can lock up the wheels, and without ABS you can lock one wheel while the other is happily spinning :)

I read about (and implemented) open diff quite a while ago, so I'm just trying to recall.

The torque coming from the engine is split 50:50.
Using those torques, do the traction calculations as normal.
Suppose one wheel has 20Nm and the other has 50Nm road reaction. The "common" fraction goes back to the engine, and the rest is to the wheel with less resistance.

In this case 40Nm (20Nm from each wheel) go back to the engine, and 30Nm goes to the "weaker" wheel.

And as I know about it Power is a derived value, you never have to calculate with it, only torques what you need :)

 

I hope it helps a little.

Thanks for the reply. That helped a lot.

1 hour ago, bmarci said:

Also I wouldn't use wheel loads here, more like road/brake torques

That's what I'm doing actually. I have brake, road and anything friction related torque summed as reaction friction torque.

1 hour ago, bmarci said:

Suppose one wheel has 20Nm and the other has 50Nm road reaction. The "common" fraction goes back to the engine, and the rest is to the wheel with less resistance

How do you calculate the "common" fraction? I though the sum of reaction torques from both wheels go back to the engine? So for this example:

- suppose the torque at the ring gear, fed from the engine, is 100Nm, split into 50Nm each wheel.

- The "strong wheel" put down all 50Nm and react 50Nm back, thus no acceleration. The "weak wheel" only put down 20Nm and react 20Nm back, the other 30Nm accelerate that wheel, thus wheel slipping.

So now the engine receives back 20Nm + 50Nm = 70Nm, the rest 100Nm - 70Nm = 30Nm accelerate the engine, thus increasing engine RPM. If this keeps on going, the engine would hit the rev limiter.

Does my understanding have any problem? I think I'm missing something here. Can you help me out?

Also this is still just an open diff. Later on dealing with internal friction inside the diff (say Limited Slip Diff, or a locked/spool), things are going to be a lot more crazy.

2 hours ago, Vu Chi Thien said:

How do you calculate the "common" fraction? I though the sum of reaction torques from both wheels go back to the engine? So for this example:

It's pretty simple, the "common" part is the smallest value.

In case of 50Nm and 20Nm from the wheels, the common amount is 20Nm from both wheels (that goes back to the engine), so the weaker wheel's torque entirely goes back to the engine, and only 20Nm from the other, and the rest (30Nm) is not "leaving" the differential, but goes to the other side. The wheels are only affecting the spider gears so as long as they are equal, those torques "cancel" each other and are transferred to the ring gear thus resisting the engine, the remaining is going through the spider gears towards the less resistance.

 

3 hours ago, Vu Chi Thien said:

The "strong wheel" put down all 50Nm and react 50Nm back, thus no acceleration

That's a weird thing but it must have acceleration in order to generate any resistance torque, if the wheel doesn't roll, the traction will be 0 :)

 

3 hours ago, Vu Chi Thien said:

the rest 100Nm - 70Nm = 30Nm accelerate the engine, thus increasing engine RPM

Actually the engine accelerates itself, the torques coming back are just slowing it down :)
This part was very foggy to me, but I found out I don't really have to calculate the engine acceleration (not always at least).

As long as the drivetrain is connected, it's enough to calculate the wheels, and derive the engine speed from there.
And as soon as the clutch is pressed they get separated, so accelerate the engine by its own, and calculate the gearbox speed from the wheels, and depending on the clutch add the friction torques to both the engine and gearbox, until they match speed.

 

But first I'd suggest (what helped me a lot) to implement a locked diff, just to see if torques and accelerations are working out.

In case of locked/spool, the torque going back to the engine is indeed the sum of their resistance torques.

My biggest headache here was the mess around inertia's. You probably know about this: http://www.racer.nl/tech/effinertia.htm
What I was not sure about how to use the torques, as the one comes from the engine has different inertia than what comes from the wheels, and I had hard time combining them into one calculation.

But before I confuse you, I'd save this topic for later :) 

 

Thanks a bunch and sorry for any confusion, English is not my first language, so I have a bit of difficulty explaining myself :).

8 hours ago, bmarci said:

It's pretty simple, the "common" part is the smallest value.

So put it in a formula, it would be like this?


engineDriveTorque = 100f;
leftWheel.feedback = 50f;
rightWheel.feedback = 20f;

//engine torque split 50:50 to each wheel
//this happens in the Drivetrain class
leftWheel.motorTorque = engineDriveTorque * 0.5f; //50Nm
rightWheel.motorTorque = engineDriveTorque * 0.5f; //50Nm

//take the motorTorque and wheelhub speed to calculate slip, then forces from slip and load
//this happens in the Wheel class
angularVelo += motorTorque / inertia * deltaTime;
slip = CalSlip(angularVelo, wheelhubSpeed);
forces = CalForces(slip, load);
//then this result in 
//leftWheel.feedback = 50f;
//rightWheel.feedback = 20f;
//then integrate into final angular velocity
angularVelo -= feedback / inertia * deltaTime;

//back to drivetrain

//now the torque flow gets crazy
//get the extra torque in the system
//right wheel have an extra 30Nm, leftFeedback - rightFeedback = 50Nm - 20Nm;
extraTorque = max(leftWheel.feedback, rightWheel.feedback) - min(leftWheel.feedback, rightWheel.feedback);
//however, where do I put this torque to? The angular velocity of the wheel is already taken care of using feedback and motorTorque, what function does the extra torque serve in this case?

//now the engine part
//torque back to engine
//is the min of the 2 sides
torqueFeedback = min(leftwheel.feedback, rightwheel.feedback);
netEngineTorque = combustionTorque - torqueFeedback;

//take the feedback torque to push the car forward
//note that this is super simplified, feedback torque is the final torque after taking in motor and brake and other friction torque.
carbody.AddForce(leftwheel.feedback, rightwheel.feedback);

 

11 hours ago, bmarci said:

Actually the engine accelerates itself, the torques coming back are just slowing it down

Sorry my bad, that's what I meant actually. I was going to say that the engine just drives itself, but the feedback from the wheels slows it down. The net torque is positive, so the engine accelerate instead of decelerate.

11 hours ago, bmarci said:

As long as the drivetrain is connected, it's enough to calculate the wheels, and derive the engine speed from there

In my current early model, that's exactly what I'm doing. I just take the average wheel speed as the engine speed.


engineSpeed = (leftwheel.speed + rightwheel.speed) * 0.5f; //* gears also of course

 

11 hours ago, bmarci said:

But first I'd suggest (what helped me a lot) to implement a locked diff, just to see if torques and accelerations are working out.

Well actually the locked diff is what I'm having difficulty on, so I'm still stuck with the simple 50:50 open diff split :). I don't know how the torque flow in the locked system. My model uses torque flow implementation, so I can't manually "set" the speed of the wheel. If you don't mind, can you help me out with this too? I really need to understand this to implement Limited Slip Differential later on.

 

11 hours ago, bmarci said:

What I was not sure about how to use the torques, as the one comes from the engine has different inertia than what comes from the wheels, and I had hard time combining them into one calculation.

And... This is what I'm working on also :). I'm stuck with just using wheel speed for engine speed exactly because of this reason. I tried looking around for resources on angular momentum conservation, but still can't find the one fits what I'm trying to do.

 

Again thank you very much for the help. I would love it if you continue this discussion as I still have quite a lot of confusions and questions to ask (like the one above in the code)

8 hours ago, Vu Chi Thien said:

English is not my first language

No worries, not mine either :)

 

Some thoughts about the code:

I'd change the term MotorTorque to something like InputTorque, that would consist of EngineTorque and torque from the other wheel, and everything else that could drive the wheels.

Adding the extra torque is not that tricky, just use the value from the last iteration like:
T_WheelInput = T_Engine * 0.5 + T_ExtraTorqueFromTheOtherWheel

And the T_Engine would also be a calculated value -> torque coming from the engine + the resistance torques from last frame.

This approach will be useful when trying to add limited slip diffs, you will only need to add the diff's internal torques to the WheelInputs, and that's it.

I also calculate angular velocity in 2 steps as you do, but only because of brakes;
1. Accelerate with input torque + road resistance
2. Decelerate with brake/handbrake torque.

Step 2 is mandatory because the brakes can lock up the wheels, and no matter how much negative torque it adds, the wheel would never spin backwards :)

8 hours ago, Vu Chi Thien said:

I don't know how the torque flow in the locked system

It works like you had only one wheel attached to the gearbox. You can calculate the wheels separately as usual, and later you can average their angular velocities, so they will spin with the same speed. If you want LSD you will not get away without being able to set their speed. At least you'll need some manual override for locking conditions.

I better separated my components;
1. Engine
2. Clutch + gearbox
3. Diffs
4. Wheels

And all of them have their own angular velocity and input/output torques and inertias...etc.

And I only needed to update them in one way (in the order above), and derive values in the way back (opposite order as above).
The derived values are only angular velocities, as you have the wheel speeds their average is the diff's input shaft speed (*inv_ratio). The gearbox velocity is the diff's speed *inv_gearbox_ratio...etc, until you arrive to the engine speed.

The only trick is when the clutch is slipping, but that's for later :)

And whatever value you need that you haven't calculated yet, the one from the previous frame is perfectly fine.
 

On 3/28/2019 at 9:25 PM, bmarci said:

I'd change the term MotorTorque to something like InputTorque, that would consist of EngineTorque and torque from the other wheel, and everything else that could drive the wheels.

That's the intention of motorTorque, it means all torques that drive the wheel, backward or forward. Other torques that depend on angular velocity, i.e oppose motorTorque, but must not drive it the opposite way, I put into frictionTorque. This includes braking, rollingResistance, roadTorque. Sort of like how friction would be applied.

On 3/28/2019 at 9:25 PM, bmarci said:

T_WheelInput = T_Engine * 0.5 + T_ExtraTorqueFromTheOtherWheel

I'm actually using this formula to implement a simple vicious diff:


lockingTorque = (rightRPM - leftRPM) * lockingCoeff; //assume right wheel is slipping
leftWheel.motorTorque = engineTorque * 0.5f + lockingTorque;
rightWheel.motorTorque = engineTorque * 0.5f - lockingTorque;

And I'm going to use this formula later on for implementing locking and other types of limited slip diff. So basically the diff is open until there is a change in wheel speed or feedback torque.

 

On 3/28/2019 at 9:25 PM, bmarci said:

Step 2 is mandatory because the brakes can lock up the wheels, and no matter how much negative torque it adds, the wheel would never spin backwards

This brings another question: How should I integrate engine friction and limited slip diff torque? Since they are friction torque, should I treat them similar to brake/handbrake torque? For engine friction, most (if not all) implementation I've seen just apply a constant negative torque: netTorque = combustionTorque - engineFrictionTorque. However, what would happen in low wheel speed case when the frictionTorque is so large that it causes the wheel to spin backward, just like applying a negative torque for reverse gear? Should this engineFrictionTorque be treated as brake friction Torque? Same thing with limited slip diff locking torque.

On 3/28/2019 at 9:25 PM, bmarci said:

The derived values are only angular velocities, as you have the wheel speeds their average is the diff's input shaft speed (*inv_ratio). The gearbox velocity is the diff's speed *inv_gearbox_ratio...etc, until you arrive to the engine speed.

I tried not to do this and instead, treat everything separately and control using only input torque. That way I don't mess up later on because both torques and velocities are used and I got confused what uses what as input :). However I can be wrong :)

On 3/28/2019 at 9:25 PM, bmarci said:

If you want LSD you will not get away without being able to set their speed. At least you'll need some manual override for locking conditions.

Currently my idea of implementing LSD/locking is to just use the difference in roadTorque between wheels, then distribute that torque between wheels so that the net torques of the two wheels are equal, leading to equal angular velocity. I haven't actually tested this in runtime yet, only constructed as a simple steady state formula and punching in numbers to get result for an instantaneous frame:


torqueDiff = leftWheel.frictionTorque - rightWheel.frictionTorque; //assume leftwheel has more grip.
//friction torque includes brake and road torque, basically all feedback torques.
appliedLocking = min(torqueDiff, lsdMaxLocking); //the maximum amount of locking depends on how strong the lsd can hold. 
//For locked diff locking torque is infinity, so 2 wheels will always have equal velocity.
//For lsd, the locking reaches a threadhold, after that 2 wheels will accelerate away from each other.
lockingTorque = appliedLocking * 0.5f; //distribute the difference evenly
//so that net torques are equal, leading to equal angular velocity
//since netTorque is motorTorque - frictionTorque;
leftWheel.motorTorque = engineTorque * 0.5f + lockingTorque;
rightWheel.motorTorque = engineTorque * 0.5f - lockingTorque;

Not sure if this would work, but that's what I have in mind right now. I'm coming back to this after fully understanding how torques run inside the open diff.

Sorry for the long post, but let's go back to the case of jacking the open diff up and spinning one wheel. There is no road torque going back from both wheels, so how can the standing still wheel can receive torque to spin backward when the other is spun?

Again thank you so so much for continuing this discussion with me. The few replies in this forum enlightened me a lot :)

 

On 4/5/2019 at 10:42 AM, Vu Chi Thien said:

I'm actually using this formula to implement a simple vicious diff:

Yes, I'm doing the same too :)

 

On 4/5/2019 at 10:42 AM, Vu Chi Thien said:

This brings another question: How should I integrate engine friction and limited slip diff torque? Since they are friction torque, should I treat them similar to brake/handbrake torque? For engine friction, most (if not all) implementation I've seen just apply a constant negative torque: netTorque = combustionTorque - engineFrictionTorque. However, what would happen in low wheel speed case when the frictionTorque is so large that it causes the wheel to spin backward, just like applying a negative torque for reverse gear? Should this engineFrictionTorque be treated as brake friction Torque? Same thing with limited slip diff locking torque.

With the engine you don't have to worry about it. The negative torque will not result in instant speed reversal, first it slows down the whole drivetrain, including the engine. And at one point the engine RPM drops so much that is stalls. Like below 600RPM the engine stops.

Also, a more common way is to have 2 torque curves. One for the on-throttle, and one for the off-throttle (engine brake) and blend them using the current throttle position.

For the locking diffs, I use a locked-state variable. The locking always depends on the torque difference of the wheels. If they don't overcome the preload/locking torque they behave like a fixed axle (locked), as the torques grow at one point the locking torque will be less, and you can apply it again (not-locked).

 

On 4/5/2019 at 10:42 AM, Vu Chi Thien said:

then distribute that torque between wheels so that the net torques of the two wheels are equal, leading to equal angular velocity

This is not 100% true. Equal torques mean equal acceleration, but not equal speed. Somehow you can do tricks with torques to equalize the speed, but if you had access to the angular velocity and just override them... that would be the easiest way.

This topic is closed to new replies.

Advertisement