Search Unity

Can anyone help me understand how AddForceAtPosition works?

Discussion in 'Physics' started by BongMcPuffin, Nov 16, 2017.

  1. BongMcPuffin

    BongMcPuffin

    Joined:
    Oct 16, 2017
    Posts:
    26
    If anyone out there has any experience with AddForceAtPosition, I'd really appreciate a little clarity on something. Even though the images are in 2D, the game I'm making is in 3D but the same principle should apply.

    The following two images pretty much lay out my entire question...





    I know, my MSPaint skills are just off the charts.
     
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    AddForceAtPosition expects the position in world coordinates. Thus, if AddForceAtPosition is called with the same parameters then the force would be applied at the Red arrow but separated the distance traveled by the object after the first application.

    In this case, you may better use AddRelativeForce instead. With AddRelativeForce the answer would be the Green arrow.
     
  3. BongMcPuffin

    BongMcPuffin

    Joined:
    Oct 16, 2017
    Posts:
    26
    Hmm, that may be problematic if what you're saying is that the red arrow won't follow the object.

    If the force is applied at the green arrow in the second picture it would probably cause the object to bounce, assuming its rolling forward and is an object that can bounce. I would like the force to be applied at the red arrow but follow the object and always hit it at that spot.

    Think of a hoop-and-stick. You would hit the hoop over and over again in roughly the same spot to keep it rolling along smoothly.
     
  4. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Then it's all about vector math and reference frames. You should compute the force application point based on the object's position and orientation, then apply the force there.

    However, as the object is rotating, the object's orientation wouldn't be a valid reference frame for computing the application point. You should define some reference frame at the object's position that doesn't rotate with it, but still gets oriented in the "forward direction".

    I'm not sure on the best way to do this though. A possible way would be to use the vector the object rotates around (transform.right in the Unity convention) for defining the "forward" direction. The "up" direction would be the world's "up" direction (Vector3.up), so a cross product with transform.right would return a valid forward vector. You may then use this reference frame for computing the world position for the force application point.
     
  5. BongMcPuffin

    BongMcPuffin

    Joined:
    Oct 16, 2017
    Posts:
    26
    I think I may have come up with a novel, if sloppy, solution to this problem... basically make a capsule with a collider, extend it into a baton shape, disable the displayed mesh to make it invisible, parent it to the tire so it follows it, and then when "forward" key is pressed whack the tire with the collider using a scripted in movement. I haven't tested it yet, so I have no idea how the performance impact will be with this second component going into the mix though so that will be interesting to check out.

    Its amazing how complicated this idea has become to get right. It was a just simple idea in my head when I first thought of it... I mean how hard can it be to hit a hoop with a stick, right? RIGHT? *bangs head on desk*

    Imagine you have a basketball pinched between opposite points like a lathe and the lathe is turned off. This means you can't "AddForce" to the ball to make it rotate (as in push it along the ground wit a strong fan) because the lathe is holding the ball still. There are two ways left to rotate this ball as its pinched. You can turn the lathe on and that will "AddTorque" spinning it around its axis. The remaining way is to "AddForceAtPosition" where you apply a force to the edge of the ball... in my head I'm using an air compressor aimed at the edge of the ball to create a straight line of force that moves in a tangent to the circumfrence of the ball. Take the ball off the lathe balance it on your finger and now it can wobble as it spins, to keep it spinning and stable you have to take your hand and keep hitting the ball and imparting a little force and torque to keep the system stable. If the ball slows down it wobbles and falls off your finger. Squash the ball into a cylinder and you pretty much have what I'm trying to do.

    I have one more route I might try as well that is a combination of two methods I tried earlier if the baton thing doesn't work out that doesn't involve actually hitting the tire with another object.
     
  6. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    If all you want is a spinning tire I'm not exactly sure why adding torque isn't the solution. Regardless, if you truly want that "forward force applied at the top of a hoop" affect the math is not very complex. You simply need to take the rigidbody.worldCenterOfMass + Vector3.up * hoopRadius and you have your world position.

    This does assume the hoop cannot fall over but there's math you can google to solve for the most upward vector restricted to a rotation axis (the one which rolls). Any kind of "invisible stick collider" is going to be super wasteful, difficult to control, and will possibly collide with other objects (or waste a layer just to avoid these unwanted collisions).
     
    sean244 likes this.
  7. BongMcPuffin

    BongMcPuffin

    Joined:
    Oct 16, 2017
    Posts:
    26
    I don't just want a spinning tire, and I agree if thats all I needed, that would be very easy to do. I want the tire to roll under its own weight and inertia, but be helped along by an occasional bonk, just like in a hoop and stick example. The challenge here being keeping the hoop rolling, where if you slow down your input too much or you just stop inputting altogether, it will fall over. Give the hoop really huge whacks and you (assuming the hoop and/or stick can't be broken) will send the hoop flying unpredictably/uncontrollably. Managing how hard/often you hit the hoop and the direction the hit is delivered are key.

    I tried AddForce at first and it gives me the closest control that I'm looking for, but its not perfect for two reasons, first being that it applies force uniformly across the whole object as if it was caught in a hurricane (minus the concept of aerodynamics), and secondly it causes the hoop to wobble more and more at high speeds, which is exactly opposite of realistic.. technically the faster a tire is rolling the more stable it should be. Next I tried AddRelativeTorque and it has three problems, it made my tire skip and bounce like crazy because its not attached to anything and being held down like if it was part of a bicycle or a car, and it also has a very rigid gyroscope effect that basically locks the tire upright when the torque is being applied even at slow speeds, and there is no motor attached to this tire, so applying a constant torque to it isn't realistic anyways. To work like this, it would need to be operated basically like a unicycle, where you have a frame that clamps the wheel into rotating around a particular axis and a rider that applies a downward force due to their weight, so when they torque the wheel around with their feet on the pedals the wheel maintains its contact/friction with the ground. Not to mention that steering a unicycle is very awkward even at rest and is especially difficult if you are traveling quickly. As odd as it sounds, even though I only have one wheel, I'm not trying to create a unicycle.

    The other problem with plain old AddForce that makes it an unrealistic option is that it applies force through the center of the object, which isn't possible with a hoop, because a hoop is hollow, there isn't anything to push on in the middle. To "prove" this, if you take your hand and place it in the center of a tire that is standing upright, then attempt to push the tire onto its side, your arm will go straight through to the other side because there is nothing to push on. To push the tire onto its side you'll have to move your hand upwards and rest it against the side of the tire near the top, and then push, which will cause the tire to fall over on its side.

    I don't want the tire locked into any axis of rotation or to apply a constant uniform force to it because that unrealistically affects its rolling behavior.

    This is what makes a hoop and stick the game that it is.... It rolls under its own weight and intertia. It also requires constant correctional input from the user, and managing the force, timing, and direction of each bonk makes the hoop roll and with enough skill you can keep the hoop upright and steer it around fairly smoothly. In my example for the game, the force and timing are applied by tapping the forward key, and the direction is supplied by an orbit camera, so you look in the direction you want to whack the wheel, give the forward key a tap and it gets a nudge in that direction, and tap the forward key again (and again, and again) to build up speed/maintain balance.

    I might try inputting AddForce and AddRelativeTorque at the same time in a burst or impulse to try and mimic a bonk from behind, but the AddForce is still being applied to the wrong part of the object, so it feels like a compromise.
     
  8. KeithKong

    KeithKong

    Joined:
    May 31, 2015
    Posts:
    73
    Well first off you have a major problem if you want stable, realistic rolling behavior out of PhysX. There's a reason WheelCollider was added (which won't work for you either). PhysX has low precision resolving this kind of movement, not to mention it works with "Rigid" bodies, meaning they don't flex like a hoop (a huge part of what smooths out the motion when hitting the hoop repeatedly in real life).

    That being said, my second paragraph outlined how to properly use AddForceAtPosition, so I'm not sure why you're still addressing AddForce solutions. What I described is your best bet at creating the behavior you want. You're going to need a lot more complicated math to balance out something as thin as a hoop rolling though.
     
    Last edited: Nov 20, 2017
  9. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,079
    I'd go with AddForceAtPosition like KeithKong and Edy suggested. If you start doing AddForce and AddRelativeTorque or similar at the same time you're going to end up with goofy combinations of mismatched forces and torques trying to act like stick whackings that are not like real stick whackings at all. That'll just add weirdness into all of it and you'll just end up more frustrated.

    When you whack a hoop with a stick you are doing an AddForceAtPosition. That results in a certain force on the object and a torque that is correct based on the position and direction of that force on the hoop, something you won't have by using the other two functions separately and trying to figure out how the forces and torque should work separately. A physically correct model for hoops like you're doing indeed would be with AddForceAtPosition.

    Don't get too worried conceptually about AddForce being in the middle of the object. AddForce really means you're adding a force without imparting any torque to the object, which means the force point could be anywhere (not just the middle), it's just pointing directly through the center of the hoop which would give 0 torque. So don't let it bother you too much that you're effectively applying the force at the center of the hoop, but do keep in mind that the physical meaning of that would be that the force location is effectively moving around the perimeter of the hoop in such a way that the force direction points through the center, and therefore has no physical bearing on what your stick whackings would really be doing.

    If that hurts to think about, just go with AddForceAtPosition as suggested, think about a stick hitting the hoop "here" and "in this direction" and call it a day. :p Then you're just left with figuring out where to apply the whack force on the hoop and in what direction. Stability might be helped by making sure those stick whackings are lined up with the hoop's plane. If they aren't, then each whack is going to introduce a wobble.

    After seeing this and a few of your other threads on the hoop experiments, I want to point something out: I'm writing a replacement for PhysX for some higher end car simulation I'm tinkering with. One thing that immediately became obvious when comparing the two systems is that PhysX does not model gyroscopic effects in the absence of forces and torques correctly. While PhysX is pretty good (super fast too), there's no gyroscopic precession or nutation present. I'm not sure why they didn't model that correctly because it's not very expensive to do so, but they didn't. This is where the angular velocity vector rotates around the angular momentum vector. In the absence of forces/torques, the angular velocity vector in PhysX stays fixed in space which is only correct in some limited situations, and one of those situations is not a hoop rolling on the ground at some roll angle, unfortunately.

    So no matter what you do it's not going to be perfectly accurate using PhysX. This may or may not matter a whole lot with your hoops getting batted along the ground, but it may be something to keep in mind when/if you see differences between real hoops and your simulated one. It may not be too terrible though, some of your videos in other threads actually looked pretty good so I may be making a bigger deal of this than it really is. Just keep in the back of your mind that PhysX is not used by NASA for a reason.
     
    Last edited: Nov 24, 2017
  10. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,079
    Regarding your other threads and videos on hoop stability and so forth:

    Those videos looked pretty good, really, even though they aren't quite what you want yet. A couple things come to mind:

    First is the vertical force from the hoop/ground contact. If your hoop is lined up perfectly vertically and the hoop/ground contact force is pointing directly up through the center and situated exactly at the middle of the contact, the hoop should just sit there and not fall over. However, the instant the hoop tips even the slightest amount, the center of gravity (CG) of the hoop is no longer lined up with that vertical force and it's going to tend to fall over on its side. If the thing is spinning really fast while it does this, you're going to end up with a wobble instead because the hoop/ground point is translating left/right to opposite sides of the CG with every rotation (or maybe it's every half rotation, something like that) of the hoop.

    In other words, it starts falling over to the left, but the rotation of the hoop moves the ground contact point over to the left side well beyond the CG position, so the vertical contact force stands the hoop back upright before the hoop has fallen all the way over and it starts falling to the right instead. Rotate it another x degrees and it's reversed. Left, right, left, right. The wobble is really the hoop falling over first in one direction, then the other. Unless you're controlling that hoop/ground contact position really precisely in a certain way when it's near 0 tip angle, it's kind of unavoidable, especially if you whack the thing with a stick off axis here and there. That's how reality works too.

    This can be made better or worse depending on how that contact point is calculated. If you're using a Unity cylinder collider there's no reason at all why that force position isn't simply flipping from the left to right edges of the cylinder all the time as the hoop's vertical alignment changes from left to right and back. I'm not sure how PhysX computes cylinder/ground triangle or plane collision contact points, but there is more than one way to do it and they'll give you different results. The thinner your hoop collider is, the less it'll matter though because the contact won't be moving as much. If it's infinitely thin then the force will stay in just one position along the width of the hoop and then you've got the situation in the previous paragraph.

    If you're trying to keep the hoop vertical, one thing that may help this is to compute that contact position manually and make sure it moves laterally more than the hoop's CG, at least at small enough tilt angles where it makes sense. For example, if you start with a perfectly vertical hoop, as it begins to tip over to the left, you want that contact position to also move to the left, but it must move further than the CG moves to remain dynamically stable. That'd give it a restoring moment that would tend to return the hoop to vertical. So if your hoop is rolling along vertically it might tend to stay that way a little more than it does now instead of degrading into a wobble even though you haven't hit it with your stick yet.

    A simpler way in the beginning would be to experiment with the width of the cylinder collider and watch the effect that has on all this. Take it all the way down to almost 0 width and then start increasing it from there.

    I'm reminded of chine walk dynamics in high performance boating. It's the same principle of stability and lateral motion of CG and the contact's vertical force at play as in the hoop case:

    http://www.speedboatsim.com/chine-walk-tech/


    In the little video clips, replace the vee hull with a cross section of your hoop at the ground. It's the same deal.

    With a cylinder collider who knows what that force position turns out to be? It could be jumping between the left/right edges, sitting dead the middle, or end up being some weighted average that blends it nicely between the edges as it tips to greater angles. If the collider is done at the triangle level you could end up with strobing effects at high speeds where the force is on the left of center most of the time at one range of speeds, then it flips to right of center at another range of speeds. In that case increasing the physics rate could help, but the way I'd go about it if that's the case is to write my own contact model and forget the Unity collider.

    Just as important as all that is the direction of the friction force in the ground plane. If you can't get the results you want with Unity/PhysX, you might need to write your own ground/contact model and AddForceAtPosition there yourself and not allow Unity to apply any forces there somehow. Point being that some attention may need to be paid to that point location and how it moves and what direction the forces at the contact are pointing.

    Another thing to experiment with is the inertia tensor of the hoop. Objects spinning like that tend to align their orientations toward the axis with either (I forget which) the highest or lowest polar moment of inertia. So try experimenting with the inertia tensor by setting it manually and computing it according to how a real hoop's inertia tensor would work. I.e., maybe your y and z inertia tensor components are identical to each other while the x (spin axis) is either greater or less than the y/z. That might help it a bit, but I'm not sure how much since PhysX doesn't model precession correctly (see previous post). Google can take you there, but if you need help with that just shout.
     
    Last edited: Nov 24, 2017
  11. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    1,081
    Todd can you please explain how to model the gyroscopic precession and consequently the gyroscopic couple affecting on a vehicle? Im stuck on finding the axis of precession or better the radius R of the turn, which seems to be necessary to calc the angular velocity of the precession (Wp = v*R, where v is the linear velocity of the vehicle and R is the turning radius). Im following this tutorial:



    upload_2021-11-19_12-51-59.png
     
  12. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    1,081