I've been reading this very interesting article on gamedev.net
http://www.gamedev.net/page/resources/_ ... dies-r3885
It's about applying natural movement and turning to your in-game entities, using box2D as the physics engine, in order to preserve the collision detection but also have smooth movement. I found out that using :setPosition() and :setAngle() doesn't work well for collisions.
My question is: does anyone know of a PID controller implemented in lua floating around? Or will I have to translate the PID in the article above from C++ to Lua?
PID controller for Box2D movement/turning
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: PID controller for Box2D movement/turning
Interesting. I suppose this is somewhat related to path following.
Reynolds has a nice path following algorithm and is not too hard to port it to Lua.
"setPosition" and "setAngle" basically teleport or instantly rotate the body which makes the physics look less realistic.
Reynolds has a nice path following algorithm and is not too hard to port it to Lua.
"setPosition" and "setAngle" basically teleport or instantly rotate the body which makes the physics look less realistic.
Re: PID controller for Box2D movement/turning
I would say it's even worse than less realistic. When using forces, the collision detection and, most importantly, the collision feedback work out of the box and your entities behave naturally. When using :setPosition() and :setAngle(), collision detection still works but you can teleport one entity inside another and have all sorts of weird behavior, because (I guess) the system can't calculate where your body will end up in the next frame and apply the necessary forces to deny an invalid state.
In the best case scenario, with teleporting, you need to write your own code to keep entities from glitching. In the worst case scenario, collisions will simply not work properly.
In the best case scenario, with teleporting, you need to write your own code to keep entities from glitching. In the worst case scenario, collisions will simply not work properly.
Re: PID controller for Box2D movement/turning
True but it depends on the gameplay 'feel' you are going for.
Also note that if you override the linear of angular velocity (using SetLinearVelocity or SetAngularVelocity) of a body then the collision response will not look realistic.
Collisions modify the velocity of bodies so you rarely want to change them to a constant value.
For example:
Will not only make the object freeze in the air but it will make it non-responsive to collisions.
Under the hood, forces and impulses basically add acceleration to the current velocity, something along the lines of:
Also note that if you override the linear of angular velocity (using SetLinearVelocity or SetAngularVelocity) of a body then the collision response will not look realistic.
Collisions modify the velocity of bodies so you rarely want to change them to a constant value.
For example:
Code: Select all
body:setLinearVelocity(-gravity) -- assuming linear damping is off
Under the hood, forces and impulses basically add acceleration to the current velocity, something along the lines of:
Code: Select all
acceleration = force / body.mass
body.velocity = body.velocity + acceleration
Re: PID controller for Box2D movement/turning
Well I guess the system was meant to be used by applying forces to it's bodies (i.e. applyAngularImpulse()/applyForce()/etc.) and letting it manage the outcome.
I'm looking to use this for a top-down shooter, so the gravity is basically 0; I need to figure out what the restitution is and find a way to apply forces for natural movement and turning, but no wall glitching . If you're wondering why use love.physics at all, it's because I'm currently using it for raycasting (bullets), point testing (mouse clicks and other tests), rotation matrix related stuff (body.getWorldPoints()) and am looking to add some physics effects like walls blowing up and people flying around in grenade blasts (although I haven't yet defined the finer details and have no idea if it's doable in 2D without investing a lot in art and FX).
And by the activity on this topic it seems I'm going to have to implement that PID in Lua myself and see how it works
I'm looking to use this for a top-down shooter, so the gravity is basically 0; I need to figure out what the restitution is and find a way to apply forces for natural movement and turning, but no wall glitching . If you're wondering why use love.physics at all, it's because I'm currently using it for raycasting (bullets), point testing (mouse clicks and other tests), rotation matrix related stuff (body.getWorldPoints()) and am looking to add some physics effects like walls blowing up and people flying around in grenade blasts (although I haven't yet defined the finer details and have no idea if it's doable in 2D without investing a lot in art and FX).
And by the activity on this topic it seems I'm going to have to implement that PID in Lua myself and see how it works
Re: PID controller for Box2D movement/turning
I appreciate this is a 7 year old thread but it is perfectly relevant. I have a top-down 2D zero-g box2D project and I need to apply force in a way that is smooth and then hold force at a certain value before slowing reducing to zero again.
Thinking some pid algorithm might be useful - just like the op. Google provides very little. Has anyone done a pid controller before?
Thinking some pid algorithm might be useful - just like the op. Google provides very little. Has anyone done a pid controller before?
Last project:
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/pad-and-pencil-gridiron
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/pad-and-pencil-gridiron
Re: PID controller for Box2D movement/turning
I've worked with PIDs in industrial PLCs and implemented Proportional control myself (the P in PID). Your description is too vague - maybe you can open a new thread with more details on what you need.togFox wrote: ↑Fri Sep 02, 2022 9:39 am I appreciate this is a 7 year old thread but it is perfectly relevant. I have a top-down 2D zero-g box2D project and I need to apply force in a way that is smooth and then hold force at a certain value before slowing reducing to zero again.
Thinking some pid algorithm might be useful - just like the op. Google provides very little. Has anyone done a pid controller before?
- zorg
- Party member
- Posts: 3470
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: PID controller for Box2D movement/turning
From discord by Keyslam:
"Stolen from Stormworks steam community"
"Stolen from Stormworks steam community"
Code: Select all
function pid(p,i,d)
return{p=p,i=i,d=d,E=0,D=0,I=0,
run=function(s,sp,pv)
local E,D,A
E = sp-pv
D = E-s.E
A = math.abs(D-s.D)
s.E = E
s.D = D
s.I = A<E and s.I +E*s.i or s.I*0.5
return E*s.p +(A<E and s.I or 0) +D*s.d
end
}
end
-- example
pid1 = pid(0.01,0.0005, 0.05)
pid2 = pid(0.1,0.00001, 0.005)
function onTick()
setpoint = input.getNumber(1)
pv1 = input.getNumber(2)
pv2 = input.getNumber(3)
output.setNumber(1,pid1:run(setpoint,pv1))
output.setNumber(2,pid2:run(setpoint,pv2))
end
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: PID controller for Box2D movement/turning
I said:
Since you haven't opened a new thread, let me elaborate:
Force is mass times acceleration, so for an object of constant mass, if you keep force at a constant value, you'll apply a constant acceleration, i.e. the velocity will keep growing and growing. And while the force gets slowly reduced to zero, the velocity will still keep growing until it's zero, and then it will remain at the last value (that's unless there's drag, but drag needs to be applied separately by the user in box2d in most cases).
If it's for a spaceship in space, where there's no drag, then yes, it's correct that the velocity constantly grows as the engine applies force, but typically it's an on-off situation, i.e. the engine is either on (and you accelerate) or off (and you don't accelerate). The engine may take a little bit to get to full throttle (not too realistic, but plausible if it's fast) but to me it looks quite unrealistic for it to reduce power very slowly.
Even if that's really the situation you want, I don't see any need for a PID. You just use Body:applyForce(x, y) using a unit vector for the direction, multiplied by the magnitude of the force you want to apply; so if you want it to slowly rise, you can use a timer. Just remember that Body:applyForce() applies only to the next World:update(), so you need to keep calling it while you want to apply the force. It doesn't harm if you apply it every update, using a zero vector when you don't want to apply anything.
If you want the acceleration to follow a curve rather than be a straight line, you can use several strategies, e.g. tween or damp.
Since you haven't opened a new thread, let me elaborate:
I have my doubts that this is what you actually want.
Force is mass times acceleration, so for an object of constant mass, if you keep force at a constant value, you'll apply a constant acceleration, i.e. the velocity will keep growing and growing. And while the force gets slowly reduced to zero, the velocity will still keep growing until it's zero, and then it will remain at the last value (that's unless there's drag, but drag needs to be applied separately by the user in box2d in most cases).
If it's for a spaceship in space, where there's no drag, then yes, it's correct that the velocity constantly grows as the engine applies force, but typically it's an on-off situation, i.e. the engine is either on (and you accelerate) or off (and you don't accelerate). The engine may take a little bit to get to full throttle (not too realistic, but plausible if it's fast) but to me it looks quite unrealistic for it to reduce power very slowly.
Even if that's really the situation you want, I don't see any need for a PID. You just use Body:applyForce(x, y) using a unit vector for the direction, multiplied by the magnitude of the force you want to apply; so if you want it to slowly rise, you can use a timer. Just remember that Body:applyForce() applies only to the next World:update(), so you need to keep calling it while you want to apply the force. It doesn't harm if you apply it every update, using a zero vector when you don't want to apply anything.
If you want the acceleration to follow a curve rather than be a straight line, you can use several strategies, e.g. tween or damp.
Re: PID controller for Box2D movement/turning
I did some reading and realised PID is a science in itself so I paused and re-considered. Tuning specifically is a black art.
For completeness, my vessel rotates in zero-g and the player can say "turn to face east" (x-axis). Assuming the vessel is pointing north then it needs to apply enough force to reach east but then to apply counter-force at the right time so that it 'settles' in a roughly easterly facing. So, the applyforce does indeed work - but it's when to apply the counter-force and the strength of the counterforce where I thought a PID might be useful, so much so it can even return to "east" if it overshot.
For completeness, my vessel rotates in zero-g and the player can say "turn to face east" (x-axis). Assuming the vessel is pointing north then it needs to apply enough force to reach east but then to apply counter-force at the right time so that it 'settles' in a roughly easterly facing. So, the applyforce does indeed work - but it's when to apply the counter-force and the strength of the counterforce where I thought a PID might be useful, so much so it can even return to "east" if it overshot.
Last project:
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/pad-and-pencil-gridiron
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/pad-and-pencil-gridiron
Who is online
Users browsing this forum: Ahrefs [Bot] and 9 guests