How to counter angular momentum with torque

I’m trying to apply torque in such a way that the rotating cube (forward red arrow) arrives at the target (pink) and has its rotation completely arrested, without overshooting too much or excessive oscillations. I’m applying constant torque. As we build up angular velocity, at some point we must start producing counter-torque in order to slow down and come to a full stop.

How do I detect that moment? What’s the math behind it? I feel I need to take advantage of the Inertia Tensor here but I’m not sure how :expressionless:

I can solve it with a PID controller or even employ a dumb dampened spring. Is the math so complex that controllers are a much better solution here?

  • the cube may already be rotating when we start applying torque
  • this has to be fully dynamic, on tick
  • this must respect mass
  • constant torque is used for simplicity, it can be modulated if necessary - but that’s what a PID’s errors correction does

Hoping the answer is obvious and I just skipped a critical math class.


Project link if someone feels like experimenting:

1 Like

Like this?

  1. the higher the tolerance, the earlier it starts braking. Play with it a little to get that little overshoot.

  1. deceleration is acceleration in reverse, so if I can know from current speed where I want to stop, I just have to flip the acceleration.

1 Like

This has to be done with physics. With torque. I solved it. Will post a bit later.

Working on dampening and quaternions in order to account for 6 dof now.

F for me then… :sweat:

1 Like

F for me then…

What you posted looks pretty spot on - impressive - but this is not physics… I mean, it is and isn’t because you’re simulating it without simulating it, right?

Boiled it down to:

Essentially, the fastest way to arrive at a rotation using torque. A couple of known issues are present.

3 Likes

Do you have article or solution to this problem but more general way. I tired to do it for 3dof movement (linear speed/steering and angular). And i failed, horribly (some time ago), that may be because of my mistakes in solving physics of this, or unreal physics is not quite accurate.

So do you have solution for linear and angular steering with just force?

ps.
Looking on solutions here, i think it was not me (or me somehow), i did not compensate for delta seconds.

Cool stuff :smiley:

It’s just some of the math behind it.

What I meant is that if I were to add forces to it, it wouldn’t work. It has to be torque.

more general way.

I believe it would revolve around a PID controller:

This works in 3d but (!) you need to tune the PID controller. Far from ideal. And it does not really give you the fastest possible arrival. Also, at the top of that thread there is a solution that works well for something arcady.


While researching it, I run into several books that deal with this issue professionally and a NASA paper but that went over my head way too fast :expressionless:

It seems that doing it properly really IS complicated. What I posted is still a rough approximation because this is not real life and we’re dealing with frame time.

I may be doing things incorrectly, too.

Lolz that was also my case. :smiley:

I wanted to do Asteroids prototype game with full physics in space ie inertia, only physics steering etc.

Problem/task was like this:

  • only linear acceleration on single axis (to simplify it all), no angular steering yet not looking for optimal solution for speed or fuel. Angular problem should be almost identical.
  • object (space ship) had maximum thrust (for gameplay later/upgrades etc)
  • question is, when to start engines at maximum thrust to stop exactly at desired location.

I had several solutions (some years ago, so i do not remember all details now), but they were kind of unstable, i never had solid code for this.

I think culprit was that i did not compensate for delta seconds (but as i wrote above, it might be just my derp or unreal physics not being accurate enough).

I had a version of this once that also took into account the time it takes to rotate a ship around.

  • we’re going from A->B using max allowed acceleration (I also had g limits)
  • keep accelerating towards destination, flip the thruster 180, start burning in the opposite direction to come to a stop at destination
  • the tricky part was to incorporate the time it takes to do the 180 flip and fit it into the other formula; you need to slot it in between the acceleration and deceleration phases

There is chance I’ll be working on this again in a less half-arsed way this time round, soon-ish™.

1 Like

You can solve all those problems with angle by calculating it always as local rotation, this way you never have more than 180 deg to rotate, and that can be cheated with always rotating some way when you in range of 175-185 or so.

I think because of this topic i will try once again make that code for at least linear move.

I have no issue with angles, I had issues reserving time for how long it takes to rotate with torque as we’re still moving towards destination in a linear fashion while we’re turning.

We’re holding (or moving slowly) left → right.

  • accelerate first
  • stop accelerating and turn around
  • decelerate

Do it all as quickly as possible, with gameplay implied limits but with no human input.

The green bit is the time you need to exclude from the acceleration and deceleration. Quite doable.

Things get more complicated when you have something like correction thrusters that can still provide extra deceleration while turning, variable main thruster, you’re already in motion and not traversing towards the target yet.

This is very solvable with multiple PID controllers. But they need tuning - the error correction capabilities are not error-free in all circumstances.


Things get out of hand when the mass is off-centre and / or you have many thrusters. You can pretty much throw it all out of the airlock. You’d need controllers for your controllers :expressionless:

The ISS corrects errors by short additive bursts. Both human and computer assisted. But that’s cheating! :crazy_face:


It’s all good fun but I’m looking for less complicated math. Seems it’s not really feasible without PID controllers.

On the other hand, some of it will end up as smoke & mirrors and only look believable; I’m fine with that. Essentially, revisiting this old thing with the hope of finding better, simplified solutions.

Problem with unreal (and godot for eg.) is that you cannot mix physics and non physics (infinite inertia) bodies and expect no weird collisions and artifacts.

So my ultimate goal is to make some “ai” script that can drive inertial spaceship (for now asteroids like in 2d only). And indeed it is very tricky.

To make any ai logic later first i need some solid code for movement that is stable (ie. always gives same results, and spaceship always stops where it should etc.)

Any chance you could share the rest of that graph? Specifically where the “Average Angular Acceleration” and “Cross Product To Target Normalized” comes from.

2 Likes

Hello, sorry for reviving this thread, but this looks like it’s really close to what I’m trying to achieve (and struggling with) and seeing that some other people also had unanswered questions, is there any chance you are willing to share that ‘TorquePredict’ demo, or add some more details to your blueprint?

Trying very hard to understand it:

What is 'average angular acceleration? Is that the difference between the angular velocities in the last 2 frames? the last second?

Degrees to target = AcosD(DotProduct(ForwardVector, DirectionVector))… so the shortest angle over which to rotate to the target ?

Then DegDelta… I think that’ll be a hardcoded angle (e.g. 5 degrees, to tweak) where you start to ‘counter’ the torque… and that’s basically the angle where you end with some wobble there and back… ?

Why do you square the physics angular velocity… I’m thinking velocity is in degrees per second, and by squaring you’ll get it in deg/(sec*sec), so it’s the same units as the angular acceleration… but what does the difference between those two values actually represent (the >0) check?

And crossproducttotargetnormalize… That’s the crossproduct between the current normalized ForwardVector and the normalized DirectionVector (i.e. targetpos-objectpos) ?

Thank you in advance!

Okay, so an attempt to recreate the above, filling in the missing details:

  1. For the acceleration, “AverageAngularAcceleration” seems to imply that it’s over a longer period (last few frames?). Going for the most simple approach by fetching the previous frame angDelDeg, current AngVelDeg and divide by the elapsed time. One more Fix: Add another vec3 variable to store the result of GetPhysicsAngularVelocity and before that set AngVelDegPrev to AngVelDeg (to remember the previous), that avoids the difference being a zero-vector.

  2. For the DegDelta, my first guess that it is a constant can’t be correct - because then the switch would never toggle. So it’s a difference between some angles. Maybe the difference between the current “angle-to-target” and the previous one, but that doesn’t seem to match because when we approach the target angle and overshoot, the sign doesn’t change and it probably should… looking closely at the movie confirms that.
    So… taking the dotproduct of the right-vector, and the targetvector will tell us if we are looking “to the left” of our target or "to the right… And since the actual value of DegDelta isn’t used that at least resembles the functionality. Probably will break if our vehicle turns ‘upside down’ (something to worry about later)

  3. For DegreesToTarget, taking this Get Angle to Actor | Unreal engine Code Snippet with some minor modifications (input worldpos, instead of actor)

So that’s still wrong because it overshoots and then spins faster and faster. So the switches are not triggering to countersteer in the correct moment… so hmm…

… and with all changes applied we get something like this:

It’s starting to somewhat work:

  • If the target is left it works (slows down, aimed at target)
  • If the target is right it doesn’t - but we can “fix” it by using the other select based on the angle… So something in our AngleToTargetSigned is broken.
  • If the target is “high up behind us” (in such a way that our object flips upside down while trying to aim at the target), probably the “Get Right Vector” flips and we get overshoot & out of control spinning (kind of expected).

Getting closer at least.

So another observation. In the cube video

  • the cube on the left center rotates from the left to the right. DegDelta is positive, and when it overshoots (on the right side) it briefly turns negative.
  • the cube in the very center rotates from the right to the left. DegDelta is also positive(!) and when it overshoots (on the right side) it briefly turns into negative.

So… it’s not just a “are we on the right or left side”… It’s something with “are we moving towards or away (overshooting)”… or rather is the new angle towards the target (irrelevant on which side we are) smaller than the previous one…

So then we end up with this:

With low torquepower overshoots a bit, but doesn’t compensate back. I suspect in that case the input for the last select is identical, while it shouldn’t be… So probably the acceleration toggle isn’t good enough (should have taken the other value).

Looking at the original video, this implementation is certainly not as good, but without at least some additional thoughts on how that works, this is how far I’ll go.

1 Like