Path Following

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
-=Magic=-
Posts: 41
Joined: Thu Jun 30, 2011 11:32 am

Path Following

Post by -=Magic=- »

Since I'm rewriting my "slot car" game from the beginning, I'm trying your suggestion here: viewtopic.php?f=4&t=1835#p10763

I implemented the path following, so now the "paddle" follow the rail slot path.

But I don't understand how to control the speed (stop, accelerate, decellerate).

I used a CardinalSpline3D and QuaternionSlerpCurve (with Wrap setting for pre/post loop).

Also, in the PathFollowingDemo, when building the CardinalSpline3D, the ControlPoints need a first parameter "time".
right now, I followed the demo and I passed an ordinal index.

but how this parameter affect the motion?

I don't now the "time", but it would be correct if I pass a % value (from 0 to 1) depending on the distance of that point from the end?

so that for a point X, the time would be (distanceX from the start point) / (total rail length).


Another question:
with this method, how may I "detect" when the speed is too high, so that I have to remove the EntityMover/EntityRotator from the Entity ?
(I suppose that in order to break the path following, I should remove EntityMover/EntityRotator from the space)


Here the video:
Last edited by -=Magic=- on Mon Nov 10, 2014 10:28 am, edited 1 time in total.
-=Magic=-
Posts: 41
Joined: Thu Jun 30, 2011 11:32 am

Re: Path Following

Post by -=Magic=- »

Ok, I changed the "speed time" of the controlpoints using the distance %, and it works a lot better :)
Now the movement is "linear" and independent from the point density (a lot higher for curves).

Also I have to multiply the distance % (0-1) by 100 in order to get a valid result (movingTimer += (float)gameTime.ElapsedGameTime.TotalSeconds)

Here the result: (but why youtube code doesn't works?)

-=Magic=-
Posts: 41
Joined: Thu Jun 30, 2011 11:32 am

Re: Path Following

Post by -=Magic=- »

Third step:
now I may accelerate/decelerate/brake :)

Just adding a multiplyer:

movingTimer += (float)gameTime.ElapsedGameTime.TotalSeconds * accelerationScale;


But I noticed that if the speed is too high, the entity "cut" the path, jumping some points.

Here the video:



Question reminder:
1) with this method, how may I "detect" when the speed is too high, so that I have to remove the EntityMover/EntityRotator from the Entity ?
(I suppose that in order to break the path following, I should remove EntityMover/EntityRotator from the space)

2) How may I force the Entity to doesn't jump any points?
-=Magic=-
Posts: 41
Joined: Thu Jun 30, 2011 11:32 am

Re: Path Following

Post by -=Magic=- »

^_^

Ok, I found a solution for the point-jump issue, but I don't know if it's the better one.

mover.LinearMotor.Settings.Servo.SpringSettings.Damping = 0;
mover.LinearMotor.Settings.Servo.SpringSettings.Stiffness = float.MaxValue;
rotator.AngularMotor.Settings.Servo.SpringSettings.Stiffness = float.MaxValue;
rotator.AngularMotor.Settings.Servo.SpringSettings.Damping = 0;


Here the video:




From all these videos, it is possilbe to see that the entities are moving with a little "frog" movement... the entities are following the path with little acceleration/deceleration. is there a way in order to better smooth this?


Question reminder:
1) with this method, how may I "detect" when the speed is too high, so that I have to remove the EntityMover/EntityRotator from the Entity ?
(I suppose that in order to break the path following, I should remove EntityMover/EntityRotator from the space)

2) How may I force the Entity to doesn't jump any points? Or a better solution than the one that I previously posted?

3) Is there a way in order to better smooth all the micro-acceleration/deceleration of the entities?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Path Following

Post by Norbo »

(but why youtube code doesn't works?)
If I remember correctly, the tag expects a full youtube.com url as opposed to a shortener.
1) with this method, how may I "detect" when the speed is too high, so that I have to remove the EntityMover/EntityRotator from the Entity ?
(I suppose that in order to break the path following, I should remove EntityMover/EntityRotator from the space)
One option would be to evaluate the path in two places around the car. Compute a direction from these two points. Remove all velocity parallel with that direction. If the length of the remaining velocity is beyond a threshold, then break the path following. Removing the entity mover (or whatever is doing the controlling) would indeed do the trick.

To remove all linear velocity along the path's direction, do this:
pathPerpendicularVelocity = linearVelocity - pathDirection * dot(linearVelocity, pathDirection)

This will keep the car in the slot if it's going fast down a straightaway, but it will launch the car if it takes a curve too quickly.
2) How may I force the Entity to doesn't jump any points? Or a better solution than the one that I previously posted?
That's an acceptable approach. This whole control scheme is a bit hacky at its core, so the occasional hacky implementation is expected :)

Another option would be to make the cars kinematic while attached to the track. When an entity mover operates on a kinematic object, the velocities are simply set to exactly the values needed to reach the goal in the next frame. When the car falls off the track, you'd need to turn it into a dynamic entity to allow it to tumble.
3) Is there a way in order to better smooth all the micro-acceleration/deceleration of the entities?
A ConstantLinearSpeedCurve can be used to resample an underlying curve so that movement is more consistent. With sufficient sampling density, the issue will be mitigated. The sample count is another parameter in the constructor.

If the sampling density required to smooth things out sufficiently is just too high, a different approach may be needed. For example, a constraint which just tries to keep the car's position somewhere on the path does not require any speed control sampling and would allow speed to be controlled more physically. Unfortunately, such a path and constraint formulation does not exist in the engine by default, so it would take more work and familiarity with the engine.
-=Magic=-
Posts: 41
Joined: Thu Jun 30, 2011 11:32 am

Re: Path Following

Post by -=Magic=- »

Norbo wrote:
(but why youtube code doesn't works?)
If I remember correctly, the tag expects a full youtube.com url as opposed to a shortener.
My fault. I haven't turned off "ActiveX filtering for this website :P

I finished the path following engine. I have implemented change-lane too.

I "cut" the track lane in Sector (in presence of a change lane), so that a path is a link of sub-path, and I navgate through the "graph" of path which represents the track :)

Here the video: (changing track lane is done on user request)

-=Magic=-
Posts: 41
Joined: Thu Jun 30, 2011 11:32 am

Re: Path Following

Post by -=Magic=- »

Ok, I've build a slot car with a box, 4 cylinders (wheels) and a paddle (deformed cylinder).

the wheels are joined to the box with a RevoluteJoint.
the paddle is joined with a RevoluteJoint and it isn't affected by gravity.

the paddle/track collision are disabled.

But my first result isn't as expected :P




Right now, I've no idea about it....
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Path Following

Post by Norbo »

It looks like two or more constraints (including contact constraints) are trying to control the same degrees of freedom but have incompatible goals. In this situation, when constraints are stiff and the time step duration is long, things can start oscillating or even exploding in the worst case.

Wheel-carbody and paddle-carbody collisions are primary suspects.

It may also be related to other aspects of constraint configuration. For example, it's possible to configure a structure such that it has very long lever arms relative to the involved objects. As a result, slight motion tends to cause large effects, which is more difficult to solve. This sort of problem can often be resolved without changing the desired behavior or increasing the simulation cost by shortening time steps/increasing iterations- it's usually just caused by a poorly placed anchor in a BallSocketJoint or something similar.

As always with things like this, creating a minimal reproducing simulation in the BEPUphysicsDemos would be helpful both in isolating issues and allowing me to take a look if needed.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Path Following

Post by Norbo »

Continuing from the PM:
- How to properly activate/deactivate the entitymover, so that I may release the paddle from the constraint.
Add/remove the EntityMover and EntityRotator from the space.
- How may I stop the car to fly, with the back (it should be easy, I'm working on it)
- How may I do to prevent the car to stay horizontal, even if the back of the car is outside the track (the car should stay slightly inclinated, until the body touch the track). to see this issue, just shot some balls on the back in order to rotate the car, out of the track)
A few things:
-Re-enable the _paddleRevoluteJoint.AngularJoint. Keep the damping and stiffness of the _paddleRevoluteJoint.AngularJoint at the defaults. This will keep the car horizontal relative to the paddle.
-Increase the mass of the paddle relative to the car body. This is important to avoid high stress mass ratio-related instability. Increasing it to 2 instead of 0.2 helps a lot.
-Keep the paddle's up vector aligned with the surface of the track so that the revolute joint constrains the proper world axis.
-Increase gravity so that it's closer to the proper scale for the object to make the body fall faster (though perhaps don't push it all the way to realistic, since that could be quite high relative to the time step).
-=Magic=-
Posts: 41
Joined: Thu Jun 30, 2011 11:32 am

Re: Path Following

Post by -=Magic=- »

I tried to remove entitymover from the Space but I get an exception.
I tried to null Entity property but I get an exception.
I tried to deactivate entitymover.linearmotor but it reenable itself since Entity is a dynamic object.

Could you explain the mass-ratio potential issue?
I'm writing from the phone, but if I remember well the car has a mass of 0.9 and the paddle 0.2.
Should I increase the paddle mass from 0.2 to 2?
Those values are then multiplied by the world scale factor that currently is 10.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Path Following

Post by Norbo »

I tried to remove entitymover from the Space but I get an exception.
I'm guessing that exception was caused by trying to remove an object from the space that no longer belonged to the space. Make sure adds and removes are not issued redundantly. You can check the Space property; if it's null, it doesn't belong to a space.
Could you explain the mass-ratio potential issue?
When an object or set of objects with a high mass depends on an object with low mass, the solver has a much harder time finding a solution to the involved constraints. This can manifest as instability. In collisions, this usually looks like squishing and wobbling. In joints, it tends to look like oscillations, or in worse cases, explosions.

The car's unscaled mass is 0.9 + 0.4 * 4 when including the wheels if I remember correctly. This is 12.5 times the paddle's unscaled mass of 0.2. In addition, the car-paddle constraint is very rigid and there's an enormous amount of force being applied to it. This is a very hard situation for the solver, and the mass ratio issue just pushes it into unsolvability.

For best stability, avoid large mass ratios. I sometimes recommend staying below 1:10 for normal simulations, but very hard simulations can require closer to 1:1 for good behavior without tons of solver iterations. This particular case is a hard one, and there is no apparent downside to bumping the paddle's mass up- hence the recommendation to bump it up by a factor of 10.

(Note that a very light object depending on a heavy object is very stable. There is no problem at all with placing a tiny mouse on top of a tank. Just avoid putting the tank on the mouse.)
Post Reply