Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Question about applyForce and applyTorque

in Codea Craft Posts: 1,305

What is the time interval over which the force or torque is applied? Is it a fixed interval, or one physics frame, or what?

Since the change in velocity of a moving object receiving a force is a function of the amplitude of the force and the time interval over which it's applied, one kind of needs to know

Should there be a way to specify the time? If it's variable, is there some way to read out the time?

Thanks!

Comments

  • dave1707dave1707 Mod
    Posts: 9,813

    @RonJeffries I think it’s applied each frame if it is on that frame and not if it’s off. I have a program where I apply force using the touch function. As long as I’m touching the screen, force is being applied.

  • dave1707dave1707 Mod
    edited November 2021 Posts: 9,813

    @RonJeffries Heres an example to show sleeping allowed and apply force. The apply force seems to work the way it should. The sleeping allowed also seems to work the way it should. The problem is the awake variable. It shows awake if it’s awake, sleeping when it’s sleeping, but it doesn’t change from sleeping to awake when it should. Run the code. Tap or hold the screen above the middle to apply an upward force. When the falling ball is allowed to rest on the fixed ball for about 2 seconds, it will sleep. Applying a force will not move it. Tap the screen below the middle and sleeping allowed is set to false, but the awake variable will still show sleeping even though tapping above the middle will apply force to move the ball.

    viewer.mode=FULLSCREEN
    
    function setup()
        fill(0,0,255)
        scene = craft.scene()
        skyMaterial=scene.sky.material
        skyMaterial.sky=color(0, 62, 255, 255)
        skyMaterial.horizon=color(99, 255, 0, 255)
        scene.surotation=quat.eulerAngles(20,45,-30)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 60, 0, 1000)
    
        a=scene:entity()
        s1=a:add(craft.rigidbody,DYNAMIC)
        s1.sleepingAllowed=true
        a.position=vec3(0,20,0)
        a:add(craft.shape.sphere,1)
        a.model = craft.model.icosphere(1,2)
        a.material = craft.material(asset.builtin.Materials.Specular)
        a.material.diffuse=color(255,0,0)
    
        b=scene:entity()
        s2=b:add(craft.rigidbody,STATIC)
        b.position=vec3(0,-15,0)
        b:add(craft.shape.sphere,1)
        b.model = craft.model.icosphere(1,2)
        b.material = craft.material(asset.builtin.Materials.Specular)
        b.material.diffuse=color(255,0,0)
    end
    
    function draw()
        update(DeltaTime)
        scene:draw() 
        a.material.diffuse=color(255,0,0)
        if apply then
            s1:applyForce(vec3(0,20,0))
            a.material.diffuse=color(0,0,255)
        end
        if s1.awake==false then
            text("sleeping",WIDTH/2,HEIGHT/2)
        else
            text("awake",WIDTH/2,HEIGHT/2)
        end
        text("tap or hold screen to apply an up force ",WIDTH/2,HEIGHT/2+50)
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function touched(t)
        if t.state==BEGAN then
            if t.y<HEIGHT/4 then
                s1.sleepingAllowed=false
            else
                apply=true
            end
        end
        if t.state==ENDED then
            apply=false
        end
    end
    
  • Posts: 1,305

    since physics is probably framed somehow, there's some implicit time in there. to make things work on all hardware, i think knowing what the code actually does is of value.

  • dave1707dave1707 Mod
    Posts: 9,813

    @RonJeffries For me, I think things are working OK except the awake variable. When an object is awake, I can move it. When sleeping I can’t. I can wake it up and then move it again. The awake variable isn’t showing what it should.

  • Posts: 1,629

    The entity.add documentation says that added members will have both update() and fixedUpdate() called, with fixedUpdate() called at each update of the physics engine. Does that help?

  • Posts: 1,305

    @dave1707 yes. sometimes i get no response to an apply, as some of the vids show in my latest article.

    @UberGoober i noticed that, and wonder it it might be useful for getting the impulse time. i'm like to see the physics code ...

  • dave1707dave1707 Mod
    edited November 2021 Posts: 9,813

    @RonJeffries Heres a demo showing some force values. It looks like a force value of 1 is equal to deltaTime. Tap the screen once to start. Each time you tap the screen, you increase the force.

    viewer.mode=STANDARD
    
    function setup()
        fill(0,0,255)
        scene = craft.scene()
        scene.physics.gravity=vec3(0,0,0)
        skyMaterial=scene.sky.material
        skyMaterial.sky=color(0, 62, 255, 255)
        skyMaterial.horizon=color(99, 255, 0, 255)
        scene.surotation=quat.eulerAngles(20,45,-30)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 60, 0, 1000)
    
        a=scene:entity()
        s1=a:add(craft.rigidbody,DYNAMIC)
        s1.sleepingAllowed=false
        a.position=vec3(0,-10,0)
        a:add(craft.shape.sphere,1)
        a.model = craft.model.icosphere(1,2)
        a.material = craft.material(asset.builtin.Materials.Specular)
        a.material.diffuse=color(255,0,0)
        cnt=0
        v=0
        force=1
    end
    
    function draw()
        update(DeltaTime)
        scene:draw() 
        cnt=cnt+v
        text("tap screen to apply an UP force ",WIDTH/2,HEIGHT-50)
        text(s1.linearVelocity.y.."  (force) units per sec",WIDTH/2,HEIGHT-100)
        text(10+a.position.y.."  units moved since force started",WIDTH/2,HEIGHT-150)
        text((cnt/60).."  seconds since force started",WIDTH/2,HEIGHT-200)
        scene.debug:line(vec3(-10,-11,0,0),vec3(10,-11,0),color(255))  
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function touched(t)
        if t.state==BEGAN then
            s1:applyForce(vec3(0,force,0))
            v=1
        end
    end
    
  • Posts: 1,305

    interesting. if i understand your understanding :smile: the force is applied for a period delta t? except ... on this ipad, on the first tap, the ball doesn't move at all. on the second, it starts moving. the distance moved, though, is displaying some small number of pixels moved. when the ball is one ball width up, it says 1.57 pixels moved, so i don't understand that.

  • edited November 2021 Posts: 1,305

    and what is scene.debug?? and when i tap, the force value does not always change to be higher.

  • Posts: 1,305

    oh?? those really are pixels somehow? or whatever craft units are?

  • dave1707dave1707 Mod
    Posts: 9,813

    @RonJeffries if you tap once, the ball is given a force of 1 which is a value of deltaTime. If you don’t tap again, that’s it’s speed each draw cycle. If you wait long enough, it will eventually move enough to see.

    Each time you tap the screen, it increases the force on the ball. So it’s speed should be x2. If you tap again, x3, etc.

    If you change the code so the force is 2, you’ll get a force of 2 x deltaTime.

    The scene.debug just allows me to draw a line in Craft. I drew it across the screen so you can see where the ball started and if you wait long enough, you’ll see it moving up from it.

  • edited November 2021 Posts: 1,305

    when i tap the screen one time, it still shows 0, and the time counts but nothing else. Often, not always.

  • dave1707dave1707 Mod
    edited November 2021 Posts: 9,813

    @RonJeffries Are you running at 60 or 120 FPS. Try changing the force variable to either 60 or 120. That should increase the force to 1 pixel per second.

    PS. I have to look at this more. I don’t think it’s pixels per second but units per second. I’m getting confused on this between Craft physics and regular physics.

  • Posts: 1,305

    My iPads run at 120 sometimes, 60 other times. I've seen the speed number be 0.0083 sometimes, when it's running at 120.

    Yes, it's not pixels, it's Craft units per second, I'm rather sure. "Newtons" according to typical physics documentation.

    Very important: it is an impulse, that is a force applied for a finite time and then turned off, not a continuous application of power that goes on forever. If it were, the object would accelerate without bound, as if propelled by a rocket.

    I think your test above is quite enlightening. I'll play with it today in an article. One thing that I want to check is the physics update cycle time, which might be the thing that controls the time, i.e. it might be that applyForce uses one physics tick rather than a draw tick.

    Very useful experiment. Thanks!

  • dave1707dave1707 Mod
    Posts: 9,813

    @RonJeffries Heres a physics version that uses pixel instead of unit.

    viewer.mode=STANDARD
    
    function setup()
        s1=physics.body(CIRCLE,10)
        s1.x=WIDTH/2
        s1.y=100
        s1.gravityScale=0
        cnt,v=0,0
        force=1
        stroke(255)
        strokeWidth(1)
    end
    
    function draw()
        background(40,40,50)
        fill(255)
        ellipse(s1.x,s1.y,20)
        cnt=cnt+v
        text("tap screen to apply an UP force ",WIDTH/2,HEIGHT-50)
        text(s1.linearVelocity.y.."  (force) pixels per sec",WIDTH/2,HEIGHT-100)
        text((s1.position.y-100).."  pixels moved since force started",WIDTH/2,HEIGHT-150)
        text((cnt/60).."  seconds since force started",WIDTH/2,HEIGHT-200)
        line(0,90,WIDTH,90)
    end
    
    function touched(t)
        if t.state==BEGAN then
            v=1
            s1:applyForce(vec2(0,force))
        end
    end
    
  • edited November 2021 Posts: 1,305

    Interesting. I get a velocity of 1.738 per touch, which isn't any kind of time that I recognize. Of course this is 2D physics. I'm not sure whether that's the same engine or not.

    And the numbers don't add up: I've got a pic showing
    1.738 pixels/sec, 76.68 seconds, and 100.02 total pixels moved, after one touch.

    Oh. that is probably because the program assumes 1/60th. Hm, no, accumulating DeltaTime still doesn't foot. Weird.

    I sure wish we could get some facts here. It's hard to document what seems to be action by spirits. :smile:

  • dave1707dave1707 Mod
    edited November 2021 Posts: 9,813

    @RonJeffries I’m running at 60 fps and my times are

    1.73839 -> velocity
    100.345 -> pixels moved
    57.72 -> seconds

    So velocity x seconds = pixels moved turns out to be close enough. Not sure what’s happening on your device.

    Are you running at 60 or 120 fps. Can your device be varying the fps.

    PS. I’m waiting to watch the Ohio State / Michigan game coming on soon. I’ll be playing with Codea while I’m watching it.

  • Posts: 1,305

    it does vary, but when i accumulate delta time it still doesn't add up. maybe i have to use elapsed. my ipads update at 1/120 sometimes, 1/60 more often, and i think it can change in either direction, but not sure.

    M Go Blue!

  • Posts: 1,305

    I have a program, which I'll try to clean up as a real bug report if needed, that seems to be telling me these things:

    1. When `applyForce is used inside an added object's update, it seems to have no effect at all, almost always. (But possibly sometimes.)
    2. When applyForce is used in the draw event, it has effect almost always. If scaled by 1/DeltaTime, it is about 2x what it would need to be to provide the expected change in momentum. Sometimes, however, it has no effect.

    I am becoming more and more certain that something is funky with it. I suspect that what is funky has to do with the time interval over which it is applied. I further suspect that the effect is worse on faster equipment, but that's just based on the fact that @Dave1707 's programs work on his hardware more reliably than they do on mine.

    As it stands, I have not yet devised a reliable way to use the famous F = M*a equations to move things in Craft. I have not quite given up, but it's starting to look as if I might just as well change velocity directly as try to adjust it using force.

    Is this interesting enough to try to produce a simple bug report program? (I probably will anyway.)

Sign In or Register to comment.