Forces, impulses, acceleration and creating a simple harmonic oscillator

0

Hello, in the past couple of days I've been trying to create a simple harmonic oscillator in accordance to basic physics with the help of @REDACTEDUSER

We've been trying different approaches to the problem but none seem to work fine.

Right now we're trying to determine how to get the combined force acting on a rigid body using:

pe_status_dynamics physicsStatus;
EBUS_EVENT_ID(GetEntityId(), LmbrCentral::CryPhysicsComponentRequestBus, GetPhysicsStatus, physicsStatus);

but it seems to be too high - if we set an impulse action:

pe_action_impulse impulseToApply;
impulseToApply.impulse = -1 * physicsStatus.a * m_mass * deltaTime; EBUS_EVENT_ID(GetEntityId(), LmbrCentral::CryPhysicsComponentRequestBus, ApplyPhysicsAction, impulseToApply, false); // Apply the impulse to the object.

that should be enough to have the body be at rest (no total acting forces per time step since F = a*m and the total change in momentum at the time would be deltaT * F thus cancelling out)

but it seems like that's not the case, physicsStatus.a reports a value of 0.0 , 0.0 , -13.0 after converted to AZ::Vector3 while in free fall and around -5.45 when on the ground. This is obviously wrong and thus brings me to my question - is there a way to know the total acceleration or sum of forces on a rigidbody with accuracy, and if so how should one get it?

P.S if anyone wants the piece of code that calculates the force required for the oscillator:


m_oscillationOffset = (m_originationPoint.GetPosition() + (m_oscillationRadius * AZ::Vector3(0, 0, 1)));
forceToApply = ((m_entityTransform.GetPosition() - m_oscillationOffset) * -1 * (m_mass / pow(m_oscillationPeriod, 2) ) * 4.f * pow(AZ::Constants::Pi, 2));
impulseToApply.impulse = AZVec3ToLYVec3(forceToApply * deltaTime - LYVec3ToAZVec3(physicsStatus.a) * m_mass * deltaTime); // LYVec3ToAZVec3 converts an AZ Vector3 to a CryEngine Vec3_tpl
asked 7 years ago167 views
7 Answers
0
Accepted Answer

One last update!

Finally it works, apparently there's a simulation variable called "dampingFreefall" on each physical entity, if you set it to 0 you'll get no damping on it which means accurate physics! if you do want some damping you should set this to no more than 0.01 and preferable 0.001 or around that.

Do note I also changed the values of "gravity" , "gravityFreefall" and "damping" to 0 (or the zero vector) which means there's no gravity and no damping at all, even when colliding.

Added is the updated source of this future GEM that encapsulates the physics engine and lets programmers in both C++ and Lua to add their own force components (the ones that apply forces) with ease.

Copal v0.1.0 Download

answered 7 years ago
0

Hello everyone, I'm posting here once more with the findings from the experiments I ran today:

1.) Rigidbodies and Buoyancy -

When using a rigidbody the default values in the buoyancy tab apply to "air" as well, that means that having a very low density object (like a 1m sphere with a mass of 10 and below) will cause the body to experience a big buoyant force which is comparable to it's weight - I suggest that the name will be changed to "Air Density" or "Medium Density" such as to avoid further confusion.

2.) Connecting to the PhysicsSystemEventBus -

In the YourClass.h file:

  • Add the following line at the top of the file:
#include "..\..\..\Code\Engine\LmbrCentral\include\LmbrCentral\Physics\PhysicsSystemComponentBus.h"
  • Make your class to be a child of the PhysicsSystemEventBus :
	class YourClass
: public LmbrCentral::PhysicsSystemEventBus::Handler
  • Add following function declarations to the fie:
void OnPrePhysicsUpdate() override;
void OnPostPhysicsUpdate() override;

In the YourClass.cpp file:

  • Connect to the bus when you need to - for example, on activation:
	void YourClass::Activate()
{
LmbrCentral::PhysicsSystemEventBus::Handler::BusConnect();
... }
  • Implement the functions we declared earlier:
	void YourClass::OnPrePhysicsUpdate()
{
...
}
void YourClass::OnPostPhysicsUpdate()
{
...
}

3.) Physics Inaccuracies / Reporting Inaccuracies -

While testing various scenarios I've found that the reporting of acceleration using some methods is misleading, I've tested objects with a wide range of densities and with a wide range of "water density" and "water resistance" values - from objects that fall without much interference to objects that float upwards as a result of buoyancy. The measurements of the acceleration were taken in a couple of ways, first there's the acceleration calculated by the change in velocities between frames:


pe_status_dynamics physicsStatus;
EBUS_EVENT_ID(GetEntityId(), LmbrCentral::CryPhysicsComponentRequestBus, GetPhysicsStatus, physicsStatus);
PrintVector3 (" acceleration = " , (LYVec3ToAZVec3(physicsStatus.v) - lastV )/deltaTime

this metric seemed to be reporting the correct acceleration at each frame, even when the object was still, but it is not useful for measuring specific forces like gravity.

The 2 ways I found unreliable in reporting acceleration were:


EBUS_EVENT_ID_RESULT(m_acc, GetEntityId(), LmbrCentral::PhysicsComponentRequestBus, GetAcceleration);
and:
m_acc_2 = physicsStatus.a

These 2 methods both report the same values- (0.0,0.0,-13.0) at free fall and (0.0,0.0,-5.45) while on a stable platform, these values are reported even if the object itself is floating upwards because of buoyancy or hovering because of an AddImpulse event called on the object.

4.) Suggestions -

a.) Adding an "ApplyInstantaneousForce" event to the PhysicsComponentRequestBus that will change the acceleration and velocity of the object. can be easily implemented by using the AddImpulse event and just multiplying by a time factor behind the scenes.

b.) Adding "GetCurrentForces" and "GetCurrentImpulses"events to the PhysicsComponentRequestBus that will give the user the ability to counteract specific forces and Impulses on the rigidbody.

c.) Moving towards a more Force-centered physics system. In most everyday uses physicists tend to use forces more than Impulses and so do most everyday people, moving to a force-centered physics system will make the system more accessible and flexible.

I hope you can see that this subject is close to my heart, I'll be very happy to answer questions about physics and the possibilities of implementation if asked and I hope to help and make Lumberyard a better, more flexible and accessible engine.

answered 7 years ago
0

Ok so a small update, apparenly the "(0.0,0.0,-5.45) while on a stable platform" was only true for a small part of possible cases - when the mass was around 10 and with water density at 1 and it scales inversely with mass, at high densities/masses or low water densities it would drop to 0.

At the start it made me think that it was showing the largest acceleration but that didnt seem to change from -13 even when it wasnt on solid ground and floating up with considerable acceleration due to high water density values.

This is all around weird, I'd love if some people from the Lumberyard team would come in and help us understand the overall system.

seems like even when I'm trying to cancel out gravity it leaves it with a small upwards force and then it invalidates all my other calculations that assumes 0 natural acceleration

answered 7 years ago
0

Hey @REDACTEDUSER

answered 7 years ago
0

Ok so further developments!

I have spend the last couple of days creating a wrapper to the current physics engine using components, every physical entity will get a ForceAggregator Component and every source will get it's own component (of the appropriate type).

The core is complete and I have created a simple oscillator component to tug on an entity towards the position of the component entity but for some reason the while the forces are correct in their direction and the magnitude to achieve the correct oscillation radius and period the entity is slower than desired, up to 2 m/s after the first pass through the position of the oscillator component.

I'll add the code for the components with all the appropriate waf, core files and level files to help you debug this issue, needless to say I've been setting the water resistance and density to 0 on the rigid body.

The Files of the new components (future GEM)

answered 7 years ago
0

So awesome! I shared this with our leadership team and they were super impressed as well! Excellent!

answered 7 years ago
0

What is the replacement for ApplyPhysicsAction in the new build

EBUS_EVENT_ID(GetEntityId(),LmbrCentral::CryPhysicsComponentRequestBus,ApplyPhysicsAction, impulseToApply,false);// Apply the impulse to the object.

I have LmbrCentral::PhysicsComponentRequestBus instead of LmbrCentral::CryPhysicsComponentRequestBus

answered 6 years ago

This post is closed: Adding new answers, comments, and votes is disabled.