PhysicsSimulate not being called

I’m working on a vehicle that will handle its own motion entirely on its own - as such I’m disabling gravity and using PhysicsSimulate. Two main questions arise from this:

  1. In running a few tests I’m finding that the PhysObj keeps being put to sleep when it stops moving - how can I prevent this? User input is handled in the physics function (currently), so should I just constantly wake the physics object in the think method or move the controls to the think function and wake it on input? Or is there a better way?

  2. How do the units work when returning linear force - the standard formula of F=m*a doesn’t seem to be valid here based on my initial tests (or else I don’t know how the source units relate). For example, I’d like to know how much force to apply to make a mass 100 object move 50 units vertically in 1 second - how would this be calculated?

I could post code but it’s pretty simple and I’ve already verified that the problem is the object falling asleep - both through querying if it’s asleep via console and by finding that it starts working correctly if I give it some velocity with the physics gun.

I’m not sure it will help, but take a look at this.

I don’t know about any of your fancy physics problems, but when I was messing around with PhysicsSimulate I had a similar problem of it not being called. All you need to do is in your ENT:Initialize(), use **[Entity.StartMotionController

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=Entity.StartMotionController)**.

Issue #1 is workable, as I’ve started waking the physObj when I expect motion. However, I’m having a lot more trouble with problem #2, the motion. Varying mass and desired time mess up the measured time (varying distance to travel is ok). Here’s my test code:

shared.lua
[lua]ENT.Type = “vehicle”//“anim”
ENT.Base = “base_anim”
ENT.PrintName = “Your Everyday Tank Tester”
ENT.Spawnable = true

ENT.Mass = 500 //In kg, the mass of the object
ENT.Dist = 100 //In source game units, the distance to travel
ENT.Time = 6 //In seconds, how long to take to travel that distance[/lua]
init.lua
[lua]AddCSLuaFile( “cl_init.lua” )
AddCSLuaFile( “shared.lua” )

include(‘shared.lua’)

//Standard spawn function, ignore it
function ENT:SpawnFunction( pl, tr )
if (!tr.Hit) then return end
local ent = ents.Create(“forceTest”)
ent:SetPos(tr.HitPos+Vector(0,0,20))
ent:Spawn()
ent:Activate()
return ent
end

function ENT:Initialize()
self.Entity:SetModel(“models/props_interiors/pot01a.mdl”)

self.Entity:PhysicsInit(SOLID_VPHYSICS)
//Todo: These two may be unecessary
self.Entity:SetMoveType(MOVETYPE_VPHYSICS)
self.Entity:SetSolid(SOLID_VPHYSICS)

self.Entity:SetUseType(SIMPLE_USE)

//Todo: Is there a better way to do this?
self.Entity:GetPhysicsObject():SetMass(self.Mass)
self.Entity:GetPhysicsObject():EnableGravity(false)
self.Entity:GetPhysicsObject():SetDamping(0,0)

//These two are currently unnecessary but
self.Entity:GetPhysicsObject():Wake()
self.Entity:GetPhysicsObject():EnableMotion(true)

//Enables custom physics
self.Entity:StartMotionController()

self.Active=false
self.DoPush=false
self.StartHeight=0
self.StartTime=CurTime()

end

function ENT:Think()
if (self.Active) then
if (self.Entity:GetPos().z>self.StartHeight+self.Dist) then
local diff = CurTime()-self.StartTime
print(“Travelled “…self.Dist…” units at “…CurTime()…”, in “…diff…”.”)
self.Active=false
end
end
end

function ENT:OnRemove()
//Todo: Confirm if this is necessary
self.Entity:StopMotionController()
end

function ENT:Use( activator, caller )
if (!self.Active) then
self.Active=true
self.DoPush=true
self.Entity:GetPhysicsObject():Wake() //Wake it up
self.StartHeight=self.Entity:GetPos().z
self.StartTime=CurTime()
print("Starting to ascend @ "…self.StartTime)
print(“Ascent should take “…self.Time…” if everything is correct!”)
end
end

function ENT:PhysicsSimulate(phys, deltatime)
if (self.DoPush) then
self.DoPush=false
local force = self.Mass * ((self.Dist*.75) / math.pow(self.Time,2)) //0.75 in = 1 hammer unit
print(“Pushing with force “…force…”!”)
return vector_origin,Vector(0,0,force),SIM_GLOBAL_ACCELERATION
else return vector_origin,vector_origin,SIM_GLOBAL_ACCELERATION end
end[/lua]
cl_init.lua is omitted as it’s just setting up the render group and including shared.lua.

The measurements from my testing are as follows:


	Mass	Dist	Time	Actual
	1000	100	5	2.31
	750	100	5	3.14
	500	100	5	4.63, 4.45,4.47,4.61,4.48
	100	100	5	22.305
	
	500	500	5	~4.55
	500	100	5	~4.5
	500	50	5	~4.5
	500	10	5	~4.5
	
	500	100	6	~6.5
	500	100	5	~4.5
	500	100	4	~2.95
	500	100	3	~1.66
	500	100	2	~.75
	500	100	1	~0.33

The most important line of all that is the calculation for force, which is “force = self.Mass * ((self.Dist*.75) / math.pow(self.Time,2))”. This should be correct- kg * in / s^2 is the formula given on the phys_thruster page, and the Dimensions page lists 1 unit being equal to 0.75 inches.

Varying mass and time make for inconsistent results. I’m still not sure how to fix this, as it’s required for my vehicle to be able to accurately calculate force to reach points in specific amounts of time (and I’m not using the shadowcontrol function as these forces vary between physics ticks, which don’t have an associated time to my knowledge). Any thoughts?

Definitely helpful, since it not only gave a units-to-inches conversion rate but also led to here which gives the force formula as F=kg·in/s^2.

I actually came across your topic earlier today while searching facepunch for info! While useful to note, in this particular case it’s definitely being enabled, the engine was just putting it to sleep due to non-motion. I’ve resolved that part of the issue, temporarily, by waking it when I expect it to move.

If you’re having trouble with getting the timing right for the physics, I would recommend using **[PhysObj.ComputeShadowControl

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=PhysObj.ComputeShadowControl)**. You can use the params to tell it exactly how long it should take to move to a particular position and angle, as well as applying damp and clamping the maximum velocity if need be.