Ropes falling apart - HELP - SOLVED

Hi Guys!

I was making some tests trying to simulate rope/chain (started from rope toy example I got from a post from @KMEB)and something very strange happened. First I noticed that objects hanging in ropes never become stable although I set linear dumping on the objects and the joints are stiff. Then the strangest thing I can’t seem to understand is that after a while, like 15-20 seconds, everything falls apart. Also tried fixedRotation=false and density=0 and other tweaking.

Could someone take a look and help me figure out what’s wrong with that?

Thank you all !

function setup()
    physics.iterations(20,20)
    noSmooth()
    sprites = {"Documents:a", "Documents:b","Documents:c", "Documents:d"}
    --sprite()
    for i = 1, #sprites do
        local pin = physics.body(CIRCLE,50)
        pin.type = STATIC
        pin.position = vec2( i*150,HEIGHT)
        
        local dyn = physics.body(CIRCLE,20)
        --dyn.mass = 1
        dyn.linearDamping = math.floor(math.random(1,7)*10)/100
        
        local rope = Rope(pin,dyn,math.random(50,150))
        sprites[i] = {s=sprites[i],a=pin,b=dyn,r = rope, size=math.random(50,150)}
    end
end


function draw()
    if #sprites > 0 then
    background(25, 25, 44, 255)
    strokeWidth(1.5)
    fill(29, 64, 36, 195)
    stroke(7, 252, 56, 255)
    for j = 1, #sprites do
        local sp = sprites[j]
        for i = 2,#sp.r do
            local ropey = sp.r
            line(ropey[i].x,ropey[i].y,ropey[i-1].x,ropey[i-1].y)
            if i < #ropey then
                ellipse(ropey[i].x,ropey[i].y,5)
                line(ropey[i].x,ropey[i].y,
                    ropey[i].x,ropey[i].y+ropey[i].radius)
            end
        end
        fill(255, 0, 0, 138)
        ellipse(sp.b.x,sp.b.y,sp.b.radius)
        --sprite(sp.s,sp.b.x,sp.b.y,sp.size,sp.size)
    end
    end
    font("Futura-Medium")
    fontSize(20)
    fill(255, 255, 255, 255)
    text(math.floor(ElapsedTime*10)/10,WIDTH-300,HEIGHT-200)
end

function Rope(aa,bb,size)
    local rope = {}
    local joints = {}
    --fixme: log
    --calculates len as 1/10 of size - number of segments
    local len = math.ceil(size/10)
    -- body A (pin)
    rope[1] = aa
    --body B (hanging obj)
    rope[len] = bb
    -- calculates rope segment size
    local segSize = math.floor(size/len)
    -- positions intermediate bodies to serve as links to joints
    for i = 2,len-1 do
        local me = physics.body(CIRCLE, 1)
        -- Sets position relative to static body A 
        me.position = aa.position+vec2(0,-(segSize*i))
        me.density = 0.5
        me.fixedRotation = true
        rope[i] = me
    end
    -- positions second body to the right/down of first body
    bb.position = aa.position + vec2(30,-20)
    for i = 1,len-1 do
        local cc = rope[i]
        local dd = rope[i+1]
        joints[i] = physics.joint(ROPE,dd,cc,dd.position,cc.position,segSize)
        joints[i].reactionForce = 30
        joints[i].frequency = 0
        joints[i].dampingRatio = 0
    end
    return rope
end

I’ve been doing some more tests and tweaking – and got some of the code fixed also, because there were some wrong calculations for segment positions and size, but still got the same problems.The only difference is now it takes about 70 seconds for the whole thing to fall apart… can’t really get what’s going on… Probably something silly I can’t see… :frowning:

FINALLY! It all comes down to garbage collector.

The problem was that my joints table was local, and since there were no references to joints, it was garbage collected. The symptoms I could see was that at some random point in time, #body.joints became ZERO. But my answer was here:

http://twolivesleft.com/Codea/Talk/discussion/1967/breaking-joints/p1

Thanks @tnlogy.

But I have a question on this: Why does this happen, since the joints ARE INDEED referenced in body objects? Any thoughts on this @Simeon?

Thanks

:wink:

Are you sure the joints are referenced in body objects?
I think that the body objects are referenced in the joint object, which is not the same at all (the inverse in fact). So there is nothing referencing to the joint, except your table…

well, I’m not sure, I assumed this because the doc exposes the joints properties for bodies. So if there is a table of joints in bodies, this should count as a reference, shouldn’t it? When I say I’m not sure, is because I did not look into how this table is implemented in Codea source code.

@jpolito I couldn’t figure out what was happening in your code, so I thought I’d write my own rope code for you to compare to yours to find the problem. Since you figured out your problem already, I wasn’t going to show you my code. But since I took the time to write it, here it is anyways.


supportedOrientations(PORTRAIT)
displayMode(FULLSCREEN)

function setup()
    tab={}
    j={}
    c=100
    for z=1,c do
        table.insert(tab,rope(WIDTH/2+z*5,900+z,z))
    end    
    for z=1,c-1 do
        j[z] = physics.joint(DISTANCE,tab[z].a,tab[z+1].a,
            vec2(tab[z].a.x,tab[z].a.y),
            vec2(tab[z+1].a.x,tab[z+1].a.y))
    end 
end

function draw()
    background(40, 40, 50)
    for z=1,#tab do
        tab[z]:draw(z)
    end
end

rope=class()

function rope:init(x,y,z)
    self.a = physics.body(CIRCLE,1)
    self.a.x = x
    self.a.y = y
    if z==1 then
        self.a.type=STATIC
    end
end

function rope:draw(z)
    stroke(255)
    strokeWidth(2)
    if z>1 then
        line(self.a.x,self.a.y,tab[z-1].a.x,tab[z-1].a.y)
    end
end

hey @dave1707! thank you for taking the time to help me out! In your solution the problem will not happen because you’re using globals for your joints table. I could not see this at first.

removed