Comments and answers for "Stopping a rigidbody at target"
http://answers.unity.com/questions/195698/stopping-a-rigidbody-at-target.html
The latest comments and answers for the question "Stopping a rigidbody at target"Comment by aldonaletto on aldonaletto's comment
http://answers.unity.com/comments/1450869/view.html
@petey made an [interesting testing scene][1] that allows us to adjust the parameters and quickly see the result - good for developing a better notion of what does what.<br>
This implementation is easier to adjust than the conventional PD/PID controller because the Proportional and Derivative "error" signals are separated: it uses the distance to the target (P) to estimate the desired velocity, and the difference from current to target velocity (D) to estimate the force. Traditional PD estimates force directly from a weighted sum of P and D error signals, what's more complicated to adjust.
[1]: http://www.peterleary.com/ForumFiles/Attract/index.htmlFri, 05 Jan 2018 17:23:20 GMTaldonalettoComment by ijidau on ijidau's comment
http://answers.unity.com/comments/1450749/view.html
If anyone else is interested, this tutorial expands on the concept: http://www.matthewpeterkelly.com/tutorials/pdControl/index.html
JavaScript source can be found here: https://github.com/MatthewPeterKelly/website/tree/master/tutorials/pdControlFri, 05 Jan 2018 11:31:07 GMTijidauComment by ijidau on ijidau's comment
http://answers.unity.com/comments/1450629/view.html
Thanks for the explanation! I did end up finding some articles about PID Controllers, but had no idea what to search for initially. To experiment further, I've implemented [this example][1] with poor results (oscillation and crazyness).
I'll try to think through your PD approach more. It's very interesting and works a treat, I just have to sit down and write out the maths to properly wrap my head around it. Maths does not come naturally to me.
From there I think your PD algorithm could be encapsulated into a class/library and then used across several applications.
[1]: http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/Fri, 05 Jan 2018 04:21:23 GMTijidauComment by aldonaletto on aldonaletto's comment
http://answers.unity.com/comments/1450614/view.html
This code implements a kind of *Proportional Derivative Control*, where the force applied is proportional to the distance to the target and also to its current velocity (velocity is the derivative of distance over time, hence the name Proportional Derivative). This algorithm first calculates the velocity needed proportionally to the current distance to the target position, then estimates the force necessary to reach the desired velocity - this way it automatically accelerates during most of the time and decelerates when getting near to the target.<br>
I've kind of invented this algorithm based on previous experiences with real world servo controllers, but you can obtain more technical information from Wikipedia ([PID controller][1])<br>
NOTE: PID stands for Proportional Integral Derivative, and it's a little more complex than PD (Proportional Derivative). The Integral (I) term helps to zero the difference to the target due to friction in the real world, but in Unity we definitely don't need it - the simpler PD control does the job.
[1]: https://en.wikipedia.org/wiki/PID_controllerFri, 05 Jan 2018 03:12:44 GMTaldonalettoComment by ijidau on ijidau's answer
http://answers.unity.com/comments/1450015/view.html
@aldonaletto Thanks so much for your answer, this solved my problem. I'd like to understand it more though, where did you learn about this technique?Wed, 03 Jan 2018 23:56:26 GMTijidauComment by goutham12 on goutham12's answer
http://answers.unity.com/comments/1320022/view.html
@aldonaletto
iam doing a game(drone type). in that i have to stop the player at some target position. and one more condition it should not stop by calculating the distance. it should consider the mass of the object. apply force(up) also should consider mass after gets mass zero it should stop.
"theoretically if a object is going up and up and up their mass will reduse. how can we come to know here"Wed, 01 Mar 2017 06:07:16 GMTgoutham12Comment by petey on petey's answer
http://answers.unity.com/comments/1295423/view.html
Hiya @aldonaletto,
I was messing around with this a bit and decided to make a little scene to test different values out quickly. Here's a webplayer link if anyone else wants to have a play.
http://www.peterleary.com/ForumFiles/Attract/index.htmlSat, 07 Jan 2017 03:04:37 GMTpeteyComment by x70x on x70x's answer
http://answers.unity.com/comments/810145/view.html
I'm using this basic functionality to create a sort of gravity gun for a first person game, but the objects I'm controlling seem to have a bit of a jittery movement when moving quickly. Is there something that is missing from this script that might improve the smoothness?Wed, 15 Oct 2014 20:43:55 GMTx70xComment by greel on greel's answer
http://answers.unity.com/comments/195893/view.html
Thanks a lot!
I've implemented your approach and it works like a charm :)
To further prevent the oscillation I've also added a distance check that will make the avatar simply look ahead of himself instead of at the target position once he is close enough.
Very helpful. Thank you again :DFri, 16 Dec 2011 10:23:07 GMTgreelAnswer by aldonaletto
http://answers.unity.com/answers/195790/view.html
Applying a force to reach some position is hard to control: the distance is a complicated function (integral) of force intensity, time and mass.
A simple solution is to just zero rigidbody.velocity when the target is reached, but this produces a very weird and unnatural result - the rigidbody just stops at the target position.
A better alternative is to use a feedback control algorithm, where the force is applied to reach a target velocity, and this velocity (clamped to some max value) is proportional to the distance to the target point - this way it will fall to zero when the target point is reached, stopping the rigidbody:
public float toVel = 2.5f;
public float maxVel = 15.0f;
public float maxForce = 40.0f;
public float gain = 5f;
Rigidbody rbody;
void Start(){
rbody = GetComponent<Rigidbody>();
}
void FixedUpdate(){
Vector3 dist = targetPos - transform.position;
dist.y = 0; // ignore height differences
// calc a target vel proportional to distance (clamped to maxVel)
Vector3 tgtVel = Vector3.ClampMagnitude(toVel * dist, maxVel);
// calculate the velocity error
Vector3 error = tgtVel - rbody.velocity;
// calc a force proportional to the error (clamped to maxForce)
Vector3 force = Vector3.ClampMagnitude(gain * error, maxForce);
rbody.AddForce(force);
}
This controller makes the rigidbody go in the *targetPos* direction - just set *targetPos* to the desired position, and the rigidbody goes there. It doesn't rotate the rigidbody to the target direction, however - you may do it at Update.
The parameters *maxVel, maxForce, toVel* and *gain* adjust the controller characteristics, and may be tweaked to reach a stable and precise operation: *maxVel* is the max speed the rigidbody will reach when moving; *maxForce* limits the force applied to the rigidbody in order to avoid excessive acceleration (and instability); *toVel* converts the distance remaining to the target velocity - if too low, the rigidbody slows down early and takes a long time to stop; if too high, it may overshoot; the last parameter, *gain*, sets the feedback amount: if too low, the rigidbody stops before the target point; if too high, it may overshoot and oscillate (like your current algorithm).Fri, 16 Dec 2011 01:29:56 GMTaldonaletto