Rope joint keeps getting pulled beyond its maximum length

Hi @exclaimteam,

Just curious, is there a reason why you couldn’t assemble your “chain” using pivot joints instead of rope joints? I’m almost certain that implementation has been proven to work. Also, it tends to create a more believeable chain, since you can limit the angle of rotation of each joint, thus preventing the segments from twisting around each other.

Brent

Ah, well, I actually tried using pivot joints originally, but it didn’t seem to work for me. I just gave it another try. It still breaks. Basically, when I start dragging the handle, the joints break and get pulled away by the force of gravity on the balloon.

Here’s some pictures of it happening:

Before drag (it’s behaving really elastically, but the connections are stable) - http://puu.sh/iEn6O/6c6a28a56d.jpg

After drag (it pulls apart completely) - http://puu.sh/iEn7L/17732ae663.jpg

What might I be doing wrong?

Attached is the code for creating the balloon & chain using pivot joints:

[lua]

    local function make_balloon( x, y, lw, lh, c )

        local prevs = {}

        balloon = display.newImage(“red_balloon_small.png”)

        physics.addBody(balloon, “dynamic”, {density=100, bounce=0, friction = 1})

        balloon.x, balloon.y = x, y

        balloon.dampingRatio = 1

        balloon.isSensor = true

        balloon.gravityScale = 0

        local balloonTop = display.newRect( x, y - balloon.contentHeight/2, lw, lh )

        physics.addBody(balloonTop, “dynamic”, {density=100, bounce=0, friction = 1})

        balloonTop:setFillColor(0,0,0)

        local linker = physics.newJoint(“pivot”, balloonTop, balloon, balloon.x, balloon.y - balloon.contentHeight/2)

        balloonTop.gravityScale = 100

        balloonTop.alpha = 0

        --balloonTop.isSensor = true

        local balloonBottom = display.newRect( x, y + balloon.contentHeight/2, lw, lh )

        physics.addBody(balloonBottom, “dynamic”, {density=100, bounce=0, friction = 1})

        balloonBottom:setFillColor(0,0,0)

        local linker = physics.newJoint(“pivot”, balloonBottom, balloon, balloon.x, balloon.y + balloon.contentHeight/2)

        balloonBottom.isSensor = true

        balloonBottom.alpha = 0

        --balloonBottom.gravityScale = 100

        handle = display.newCircle(0,0,25)

        handle:setFillColor(1,0.2,0.4)

        physics.addBody(handle,“static”, {isSensor = true})

        handle.gravityScale = 0

        handle:addEventListener( “touch”, handleDrag )

        prevs[0] = balloon

        for i = 1, c do 

                local link = display.newRect( x, balloon.y + balloon.contentHeight/2+(i*(lh) + 2), lw, lh )

                link:setFillColor(0,0,0)

                link.alpha = 0

                link.isSensor = true

                physics.addBody( link, “dynamic”,{ density=100.0} )  

                link.dampingRatio = 1

                link.gravityScale = 0

                if i == 1 then

                    local linker = physics.newJoint(“pivot”, link, prevs[i-1], prevs[i-1].x, prevs[i-1].y + (link.y - prevs[i-1].y)/2 + balloon.contentHeight/2)

                    linker.dampingRatio = 0

                    linker.isLimitEnabled = true

                    linker:setRotationLimits( -45, 45 )

                else

                    local linker = physics.newJoint(“pivot”, link, prevs[i-1], prevs[i-1].x, prevs[i-1].y + (link.y - prevs[i-1].y)/2)

                    linker.dampingRatio = 0

                    linker.isLimitEnabled = true

                    linker:setRotationLimits( -45, 45 )

                end

                prevs[i] = link

        end

        handle.x,handle.y = x, prevs[c].y + lh + handle.contentHeight/2

        local linker = physics.newJoint(“pivot”, handle, prevs[c], x, prevs[c].y + (prevs[c].y - handle.y)/2)

        linker.dampingRatio = 0

        linker.isLimitEnabled = true

        linker:setRotationLimits( -45, 45 )

    end 

    make_balloon(w/2, h/4, 5, 5, 30)

[/lua]

Hi @exclaimteam,

I did a little testing on my side, and basically, if you “pull” a joined series of objects fast enough… whether they be joined by “pivot”, “distance”, or “rope” joints… that chain will “break apart” momentarily and then, eventually, it will come back together as a joined chain again. The speed at which this happens is generally pretty fast, but basically, Box2D can’t compensate for a super-fast pull of one end of the chain and instantly transfer that force throughout all segments in the chain.

Is this what is happening for you? In my tests, the chain only “disassembled” temporarily when the handle was pulled very fast… but easily at a speed which the user could perform via a touch.

Now, if your chain is disassembling even on slower pulls of the handle, then there’s something else wrong with your setup. My chain retained its structure on slower pulls.

Brent

Well, my chain certainly “disassembles,” when I drag it. However, the “reassembling” part does not happen at a very fast pace.

I mean, in my code I have gravity pulling upwards constantly (and I drag downwards), so that likely slows the reassembling process?

At a certain threshold I’ve noticed, if the pull is strong enough, either from my drag, or from gravity, the chain will irreparably “disassemble” stretch out seemingly infinitely (and constantly bouncing around).

Here’s an example of it using rope joints in my current code: http://puu.sh/iJZD4/9226c05d31.jpg

When I use pivot joints the joints are not simply stretched out, but jittering around the screen.

Hi @exclaimteam,

I’m not sure if you’ll be able to solve this in your current setup. In my experience going way back, Box2D joints simply are prone to “falling apart” if too much stress is put upon them. This is especially true when assembling a chain of joints, where forces from one part are step-transferred up through a series of joints. In your most extreme case, where the rope absolutely disassembles beyond repair, that is where Box2D has really broken down (and that joint will not repair itself).

One final idea would be to create a chain of objects joined by pivot joints, as you’re doing. Then, in addition, join every other segment together using a distance joint with a slight amount of stretch. So, if you had 9 segments in the chain, you could join all of them together as normal: 1 to 2, 2 to 3, 3 to 4, etc. But then in addition, you could add distance joints from 1 to 3, 3 to 5, 5 to 7, etc. That may alleviate some of the stress on the overall chain, providing some pull on the next segment beyond, but with a little bit of elastic behavior, it wouldn’t pull as directly as the pivot joints.

Brent