Wheel joint

Trying to implement an axel joint and because the wheel joint does not provide the same limits and motor that the piston joint does I’m doing this with a pivot and a piston.

The two objects to be joined are connected via a middle object (the axel) and, unlike other joint types, this does not stop the two objects from colliding. This means that they need a collision filter or they will jitter all over the place.

Finally, because the two objects to be joined are joined via a third (the axel) the composite joint is now squishy.

Can anyone improve on this?

require("physics") physics.start() physics.setGravity( 0, 10 ) physics.setDrawMode("hybrid") local a = display.newRect( 400, 400, 800, 50 ) a.rotation = -35 local b = display.newRect( 600, 350, 50, 300 ) b.fill = {.5,.5,.5} physics.addBody(a,"static",{isSensor=false,density=.1, filter={ groupIndex=-1 }}) physics.addBody(b,"dynamic",{isSensor=false,density=.1, filter={ groupIndex=-1 }}) local ax, ay = a:localToContent( -400, 0 ) local bx, by = a:localToContent( 400, 0 ) local cx, cy = b:localToContent( 0, -150 ) local dx, dy = b:localToContent( 0, 150 ) local d = display.newGroup() d.x, d.y = 600, 260 physics.addBody( d, "dynamic", { radius=40, isSensor=true } ) local j = physics.newJoint( "piston", a, d, 600, 260, bx-a.x, by-a.y ) j.isLimitEnabled = true j:setLimits( -600, 200 ) local p = physics.newJoint( "pivot", d, b, 600, 260 )

just off the top of my head, haven’t run the code, but looks like your mass ratios might be wonky.  (a common cause of “squishy” joints)  try setting density of a and b to 1.0, and set d to 10.0 – just as experimental values to start from.  that ought to stiffen up the joints, but might be too extreme, maybe causing unwanted side-effects elsewhere, so experiment.

>> unlike other joint types, this does not stop the two objects from colliding

the non-collision of jointed bodies doesn’t “cascade” or “chain”, it’s only between the two explicit bodies involved.  so a doesn’t collide with d, nor does b collide with b, because they’re jointed.  but a will still collide with b because they’re not directly jointed.

>> require(“physics”)

>> physics.start()

argh!!  that SHOULDN’T work – it ONLY works because sloppy physics lib leaks a global (a personal pet peeve)

added:  OH!.. just saw it:  make d a proper circle, not an empty display group – THAT’S probably what’s causing wonky mass ratios!!

  • non-collision of jointed bodies doesn’t “cascade” or “chain”, it’s only between the two explicit bodies involved.

I don’t believe this to be the case - I’ve created multi-piece ropes or cables which have the upside of no piece colliding with any other piece. These are typically built with a series of pivot joints between, essentially, individual rectangles. That’s simple to build, so I won’t provide code, unless requested.

  • argh!!  that SHOULDN’T work

Totally. Unfortunately, I’ve made it a habit!

  • a doesn’t collide with d, nor does b collide with b,

Not sure what you mean, but if you’re saying that with 3 bodies jointed thusly: 1—2---3 then 1 and 3 would collide; As above, I have seen this break and it leads me to believe that there is a certain amount of cascading or inheritance.

  • make d a proper circle

I’m convinced (from experience) that (other than with outline shapes) all physics bodies can be constructed on completely empty display groups; An image or shape is not required.

Thank you for your advice about the body densities. I think that was the trick. This works for me - note the continued use of the group, not circle:

local physics = require("physics") physics.start() physics.setGravity( 0, 10 ) physics.setDrawMode("hybrid") local a = display.newRect( 400, 400, 800, 50 ) a.rotation = -35 local b = display.newRect( 600, 350, 50, 300 ) b.fill = {.5,.5,.5} physics.addBody(a,"static",{isSensor=false,density=.1, filter={ groupIndex=-1 }}) physics.addBody(b,"dynamic",{isSensor=false,density=.1, filter={ groupIndex=-1 }}) local ax, ay = a:localToContent( -400, 0 ) local bx, by = a:localToContent( 400, 0 ) local cx, cy = b:localToContent( 0, -150 ) local dx, dy = b:localToContent( 0, 150 ) local d = display.newGroup() d.x, d.y = 600, 260 physics.addBody( d, "dynamic", { density=2, radius=40, isSensor=true } ) local j = physics.newJoint( "piston", a, d, 600, 260, bx-a.x, by-a.y ) j.isLimitEnabled = true j:setLimits( -600, 200 ) local p = physics.newJoint( "pivot", d, b, 600, 260 )

Thanks for your help  :slight_smile:

My apologies. Having just written the cable code from scratch, I see you’re right; The various pieces do in fact collide with each other unless given a collision filter…

local function touch(e) if (e.phase == "began") then e.target.hasFocus = true display.currentStage:setFocus(e.target) e.target.touchjoint = physics.newJoint( "touch", e.target, e.x, e.y ) if (e.target.touch) then e.target:touch(e) end return true elseif (e.target.hasFocus) then e.target.touchjoint:setTarget( e.x, e.y ) if (e.phase == "moved") then else e.target.hasFocus = nil display.currentStage:setFocus(nil) e.target.touchjoint:removeSelf() e.target.touchjoint = nil end if (e.target.touch) then e.target:touch(e) end return true end return false end local function testCable() local physics = require("physics") physics.start() physics.setGravity( 0, 0 ) physics.setDrawMode("hybrid") local group = display.newGroup() for i=1, 10 do local rect = display.newRoundedRect( group, 100+i\*50, 100, 50, 20, 10 ) physics.addBody( rect, "dynamic", { density=1 } ) if (i \> 1) then physics.newJoint( "pivot", group[i-1], group[i], 100+i\*50-25, 100 ) end rect:addEventListener( "touch", touch ) end end testCable()

just off the top of my head, haven’t run the code, but looks like your mass ratios might be wonky.  (a common cause of “squishy” joints)  try setting density of a and b to 1.0, and set d to 10.0 – just as experimental values to start from.  that ought to stiffen up the joints, but might be too extreme, maybe causing unwanted side-effects elsewhere, so experiment.

>> unlike other joint types, this does not stop the two objects from colliding

the non-collision of jointed bodies doesn’t “cascade” or “chain”, it’s only between the two explicit bodies involved.  so a doesn’t collide with d, nor does b collide with b, because they’re jointed.  but a will still collide with b because they’re not directly jointed.

>> require(“physics”)

>> physics.start()

argh!!  that SHOULDN’T work – it ONLY works because sloppy physics lib leaks a global (a personal pet peeve)

added:  OH!.. just saw it:  make d a proper circle, not an empty display group – THAT’S probably what’s causing wonky mass ratios!!

  • non-collision of jointed bodies doesn’t “cascade” or “chain”, it’s only between the two explicit bodies involved.

I don’t believe this to be the case - I’ve created multi-piece ropes or cables which have the upside of no piece colliding with any other piece. These are typically built with a series of pivot joints between, essentially, individual rectangles. That’s simple to build, so I won’t provide code, unless requested.

  • argh!!  that SHOULDN’T work

Totally. Unfortunately, I’ve made it a habit!

  • a doesn’t collide with d, nor does b collide with b,

Not sure what you mean, but if you’re saying that with 3 bodies jointed thusly: 1—2---3 then 1 and 3 would collide; As above, I have seen this break and it leads me to believe that there is a certain amount of cascading or inheritance.

  • make d a proper circle

I’m convinced (from experience) that (other than with outline shapes) all physics bodies can be constructed on completely empty display groups; An image or shape is not required.

Thank you for your advice about the body densities. I think that was the trick. This works for me - note the continued use of the group, not circle:

local physics = require("physics") physics.start() physics.setGravity( 0, 10 ) physics.setDrawMode("hybrid") local a = display.newRect( 400, 400, 800, 50 ) a.rotation = -35 local b = display.newRect( 600, 350, 50, 300 ) b.fill = {.5,.5,.5} physics.addBody(a,"static",{isSensor=false,density=.1, filter={ groupIndex=-1 }}) physics.addBody(b,"dynamic",{isSensor=false,density=.1, filter={ groupIndex=-1 }}) local ax, ay = a:localToContent( -400, 0 ) local bx, by = a:localToContent( 400, 0 ) local cx, cy = b:localToContent( 0, -150 ) local dx, dy = b:localToContent( 0, 150 ) local d = display.newGroup() d.x, d.y = 600, 260 physics.addBody( d, "dynamic", { density=2, radius=40, isSensor=true } ) local j = physics.newJoint( "piston", a, d, 600, 260, bx-a.x, by-a.y ) j.isLimitEnabled = true j:setLimits( -600, 200 ) local p = physics.newJoint( "pivot", d, b, 600, 260 )

Thanks for your help  :slight_smile:

My apologies. Having just written the cable code from scratch, I see you’re right; The various pieces do in fact collide with each other unless given a collision filter…

local function touch(e) if (e.phase == "began") then e.target.hasFocus = true display.currentStage:setFocus(e.target) e.target.touchjoint = physics.newJoint( "touch", e.target, e.x, e.y ) if (e.target.touch) then e.target:touch(e) end return true elseif (e.target.hasFocus) then e.target.touchjoint:setTarget( e.x, e.y ) if (e.phase == "moved") then else e.target.hasFocus = nil display.currentStage:setFocus(nil) e.target.touchjoint:removeSelf() e.target.touchjoint = nil end if (e.target.touch) then e.target:touch(e) end return true end return false end local function testCable() local physics = require("physics") physics.start() physics.setGravity( 0, 0 ) physics.setDrawMode("hybrid") local group = display.newGroup() for i=1, 10 do local rect = display.newRoundedRect( group, 100+i\*50, 100, 50, 20, 10 ) physics.addBody( rect, "dynamic", { density=1 } ) if (i \> 1) then physics.newJoint( "pivot", group[i-1], group[i], 100+i\*50-25, 100 ) end rect:addEventListener( "touch", touch ) end end testCable()