CarSuspensionDemo and tank movement

Discuss any questions about BEPUphysics or problems encountered.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: CarSuspensionDemo and tank movement

Post by Norbo »

For a back wheel in the SuspensionCarDemo:
1) PointOnLineJoint keeps the wheel's center aligned with the suspension line, which is attached to the body.
2) LinearAxisLimit stops the wheel from traveling too high or too low along the suspension axis.
3) LinearAxisMotor, configured in servo mode, tries to move the wheel away from the body along the suspension axis. It is the suspension's spring.
4) RevoluteAngularJoint constrains the rotation of the wheel entity to be around the proper axis perpendicular to the suspension.

For a front wheel with steering, 1, 2, and 3 are the same, but the angular joint is different:
4) Instead of a RevoluteAngularJoint, a SwivelHingeAngularJoint is used to constrain the wheel. A RevoluteAngularJoint constrains 2 angular degrees of freedom and leaves one free. A SwivelHingeAngularJoint constrains 1 degree of freedom and leaves two free. Imagine a fancy laptop with a screen that can open and close like usual, but can also rotate to face backward. A visualization can be found in the Joints and Constraints documentation under the name SwivelHingeJoint (a SwivelHingeJoint is a BallSocketJoint and SwivelHingeAngularJoint).
5) A RevoluteMotor with a powered axis pointing out of the side of the wheel makes the wheel spin.
6) A RevoluteMotor with axis aligned with the suspension controls the facing direction of the wheel.
7) A RevoluteLimit stops the wheel from rotating outside of its maximum turn angles. This is sort of redundant with the steering RevoluteMotor, but it's useful because the RevoluteMotor alone tends to have issues holding the wheels straight when at full speed and subjected to large forces.
8) Finally, the two front wheels are constrained together with a RevoluteAngularJoint. It permits the wheels to rotate at different speeds, but otherwise strives to keep them attached to the car with the same rotation. This helps stability in some cases. (Fun note: you could change this to a NoRotationJoint if you detect traction loss on one of the wheels to enable something like traction control. Instead of one wheel spinning out, its motor would power the other wheel. You wouldn't want to have this on all the time, though, because the wheels should rotate at different speeds in normal situations like turning)
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

Thanks - this is very informative.

Back to the gun and turret, RevoluteJoin works as you suggested. What would be the best option for motor mode, considering that I want it rotate as user presses the botton and then button is released gun should remain at current position?

I red several post here regarding constant speed motor and it looks that it all refering to Servo motor - how then I can get current "goal" so to stop motor and current rotation?

Also, when I set Stiffness to 0 on gun servo motor it acts kind of weird - normally, with default stiffness when I set goal to some part of the PI motor drives gun as it reached it. With stiffness set to 0 it looks like it drives just some bit and then stops, not reaching goal?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: CarSuspensionDemo and tank movement

Post by Norbo »

Back to the gun and turret, RevoluteJoin works as you suggested. What would be the best option for motor mode, considering that I want it rotate as user presses the botton and then button is released gun should remain at current position?
If you have a joint limit active, using a motor in velocity mode would work. In this case, you'd want the joint limit to be stronger than the motor to avoid limit violation or constraint fighting, so making the motor softer or lowering its maximum force would be a good idea.

If you don't have a joint limit to catch the motor, then a servo mode motor would be needed.

Either servo or velocity mode can be used to accomplish the 'move while holding down, stop when let go' behavior. A servo motor would tend to have a goal slightly ahead of where the turret currently is, but with a nonzero BaseCorrectiveVelocity the servo motor could probably catch up within about a frame or two. (On the other hand, a velocity motor will tend to not stop instantly unless it has very high relative rigidity, so it might end up overshooting for a frame or two.)

I red several post here regarding constant speed motor and it looks that it all refering to Servo motor - how then I can get current "goal" so to stop motor and current rotation?
Usually, when using a servo motor to control something like a turret, a goal is set based on user input. So, to 'stop' the turret, the goal is just not be changed anymore.

If you want to stop where the turret currently is rather than where the goal is (because, say, the servo motor was configured to be very slow and the goal moves rapidly so the two states diverge), then you would need to recompute the goal to match the turret's current state.

With a velocity motor, just set the goal velocity to 0.
Also, when I set Stiffness to 0 on gun servo motor it acts kind of weird - normally, with default stiffness when I set goal to some part of the PI motor drives gun as it reached it. With stiffness set to 0 it looks like it drives just some bit and then stops, not reaching goal?
With regards to stiffness and damping, constraints behave like springs. Consider a spring with a high damping but no stiffness. If you pulled on it, it would resist your motion, but it would not return to its previous state.

Similarly, with zero stiffness but a nonzero damping, any motion that goes 'against' the constraint will still be damped, but the constraint will make no active effort to reach its goal.
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

OK, refering to motor rigidity you mean motor's spring settings?

Servo goal accepts only PI value, so I need some wraping to get 360 degree rotation?

I'm just thinking that for the purpose of the gameplay I don't need physics driven motion of the turret or gun (there are there just for collisions) - does it make sense then just to use WorldTransform of the gun or turret to rotate them?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: CarSuspensionDemo and tank movement

Post by Norbo »

OK, refering to motor rigidity you mean motor's spring settings?
Yup. Maximum force also contributes, but that defaults to float.MaxValue- usually the spring settings are the relevant bits.
Servo goal accepts only PI value, so I need some wraping to get 360 degree rotation?
I'm not sure what you mean- angular goals should be able to handle any angle supplied (in radians).

Servos will, however, take the shortest path possible to reach the goal. If you want to spin 360 degrees, the current rotation + 360 degrees is just the current rotation, so the servo won't make anything move. If you want to make it spin all the way around you'll need to specify intermediate goals.
I'm just thinking that for the purpose of the gameplay I don't need physics driven motion of the turret or gun (there are there just for collisions) - does it make sense then just to use WorldTransform of the gun or turret to rotate them?
That's an option, but then collision response will not work properly in general. For example, if you drive into a wall and the turret is sticking into it, the tank will not be 'aware' of the collision. If the tank rolls over, the turret will not support the tank at all.

If you take this route, be sure to set the velocity of the turrets to match their motion at least roughly. That will at least allow dynamic objects hit by the turret to move in a roughly correct fashion, though it still won't work quite right.
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

Norbo wrote:Servos will, however, take the shortest path possible to reach the goal. If you want to spin 360 degrees, the current rotation + 360 degrees is just the current rotation, so the servo won't make anything move. If you want to make it spin all the way around you'll need to specify intermediate goals.
That's what I thought, thanks for confirmation. Just to make sure I'm on on good track:

a) get local current turrent rotation (turret orientation multipled by inverse orientation of the body - "parent" of the turret)
b) get current angle from the resulting quartenion
c) increase it by some intermediate goal or set it as a goal if user release rotation key
d) set incresed value as the goal if user wants turret to rotate more

should work?
That's an option, but then collision response will not work properly in general. For example, if you drive into a wall and the turret is sticking into it, the tank will not be 'aware' of the collision. If the tank rolls over, the turret will not support the tank at all.

If you take this route, be sure to set the velocity of the turrets to match their motion at least roughly. That will at least allow dynamic objects hit by the turret to move in a roughly correct fashion, though it still won't work quite right.
Well, I think I'll pass on this idea at the moment - I'll see how bepu will perform with serveral tank setups running on the map.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: CarSuspensionDemo and tank movement

Post by Norbo »

Just to make sure I'm on on good track:

a) get local current turrent rotation (turret orientation multipled by inverse orientation of the body - "parent" of the turret)
b) get current angle from the resulting quartenion
c) increase it by some intermediate goal or set it as a goal if user release rotation key
d) set incresed value as the goal if user wants turret to rotate more

should work?
I'm not entirely clear on the behavior you desire. It sounds like you might be trying to do something pretty specific.

If you're just trying to get a straightforward aiming scheme running, then that's more complicated then it needs to be.

For example, I would probably just have two angles dependent on user input- "yaw" and "pitch". Those values are increased and decreased by user input and used directly as goals. No re-measurement is necessary.

I went ahead and added more stuff to the TankDemo to show as an example.
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

Image
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

Norbo, general question - if I want to get entity rotation around specific axis, just like in pic below: I want to get roll angle (rotation around yellow origin)
bepu2.jpg
bepu2.jpg (21.37 KiB) Viewed 11115 times
where to look for those? I suppose I could also get those from joints properties, like ConnectionB etc., but what property?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: CarSuspensionDemo and tank movement

Post by Norbo »

:D
where to look for those? I suppose I could also get those from joints properties, like ConnectionB etc., but what property?
In general, constraints are not required to provide any information about the constraint which is not fundamentally required by the functionality of the constraint. In the case of the RevoluteMotor, it does happen to be the case that an angle is computed using the basis internally when servo mode is used, but this is only indirectly exposed through the Error property.

However, because the wheels are controlled by velocity motors, the Error property will always be zero- no 'position level' error is computed because no angle is computed.

So, to get the angle, you'll have to compute it directly. One option would be to take the Entity.OrientationMatrix.Forward of the tread segment and compare it against some measurement basis. The tank body is a convenient option: take the dot product of the wheel's measurement axis with the tank Body.OrientationMatrix.Forward and Body.OrientationMatrix.Up, and use the two results as parameters into the Math.Atan2 function.
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

Great.

How to get on following scenario:

a) detect a collision between projectile and arbitrary entity - collision rules?
b) custom game logic would allow projectile to penetrate through entity, changing it's direction, and on the next collision do again a) and so on

?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: CarSuspensionDemo and tank movement

Post by Norbo »

a) detect a collision between projectile and arbitrary entity - collision rules?
Collision rules are used to control which objects can collide. You could set up rules such that specific objects can or can't collide, if that's what you mean.
b) custom game logic would allow projectile to penetrate through entity, changing it's direction, and on the next collision do again a) and so on
It sounds like it would be easiest to set up relevant NoSolver rules to prevent collision response. Then, the contact (deferred) collision events can be used to perform relevant game logic. For example, if its an object which should be 'hit', remove the projectile and cause an explosion. If it's supposed to pass through, let it keep going. If it's supposed to change direction, change the velocity.

It's technically possible to change the collision rules from within an immediate collision event if you wanted to do that, but the event is running in a multithreaded context and modifying anything outside of specific properties of the current pair is unsafe. Unless there's a strong need for it, I usually advise against inviting threading errors.
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

OK, can I breake joints? On max force or torque?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: CarSuspensionDemo and tank movement

Post by Norbo »

Yup. 'Breaking' is not specifically built-in, but every constraint has a TotalImpulse property. For every 'breakable' constraint, check the magnitude of this impulse. If it's greater than a threshold, then remove the constraint or set its IsActive to false.
sergiusz308
Posts: 49
Joined: Mon Oct 08, 2012 4:57 pm

Re: CarSuspensionDemo and tank movement

Post by sergiusz308 »

When you recommend to check this: after Space.Update completed, so that next "physics" frame will react to the change? What will happen to entities after joint would brake - will them retain any momentum they had on the time of the break?
Post Reply