Wheel Joint Problems!

Hello community!

I’ve been banging my head against the wall for almost half a year now. The problems i’m having with are objects that have to move around a pivot point to specific limits and then return into original position.

Below is a sample code and video so you can try it out.

I tried to achieve the result by combining pivot and wheel joints. It works almost like it should. There’s no problems if you quickly drag and release upper body so it rotates for a few degrees and then wobbles back to it’s original position. The problem is when you drag/rotate upper body and than don’t release immediately. The wheel joints starts to pull upper body back into original position. And to make things worse, when you decide to release body who has now already returned into original position, the touch joint “kicks” upper body into opposite direction.

The effect i would like to achieve is that you drag/rotate upper body to a certain limit/degree and than only when you release, the body wobbles back to it’s original position.

Here’s the video I made, explaining the problem and the sample code below.
http://www.youtube.com/watch?v=y1Jb14pUrwU

Thank you very much for your time and help!!!

display.setStatusBar( display.HiddenStatusBar )
local \_W=display.contentWidth;
local \_H=display.contentHeight;

local physics = require ("physics")
physics.start ()
physics.setScale( 60 )
physics.setDrawMode ("hybrid")

----OBJECTS
local legs = display.newRect(0,0,80,140);
legs.x, legs.y = \_W\*0.5, 860;

local body = display.newRect(0,0,160,300)
body.x, body.y = \_W\*0.5, 695;

----------------------------------------------------------
------------------------- ANCHORES -----------------------
---------------------------------------------------------- 
local anchor = display.newCircle(510, 500, 4); --Anchor above body's body

----------------------------------------------------------
------------------- PHYSICS BODIES -----------------------
----------------------------------------------------------
physics.addBody( anchor, "static");
physics.addBody( body, "dinamic" );
body.isSleepingAllowed = false;
physics.addBody( legs, "static");

----------------------------------------------------------
------- PHYSICS JOINTS BETWEEN ANCHOR AND BODIES --------
----------------------------------------------------------
local bodyWheelJoint = physics.newJoint("wheel", body, anchor, anchor.x, anchor.y, 1, 1);
bodyWheelJoint.isLimitEnabled = true;
bodyWheelJoint:setLimits( 100, 100 )

local bodyPivotJoint = physics.newJoint("pivot", legs, body, body.x, body.y+102 );
bodyPivotJoint.isLimitEnabled = true;
bodyPivotJoint:setRotationLimits( -30, 30 );

----------------------------------------------------------
------------------- ROTATE UPPER BODY --------------------
----------------------------------------------------------
local function rotatebody(e)
 local body = e.target;
 local phase = e.phase;
 local stage = display.getCurrentStage();

 if (phase == "began") then
 stage:setFocus(body, e.id);
 body.tempJoint = physics.newJoint("touch", body, e.x, e.y)
 body.tempJoint.dampingRatio = 0.8
 body.tempJoint.frequency = 400
 body.tempJoint.maxForce = 400

 elseif (phase == "moved") then
 body.tempJoint:setTarget(e.x, e.y);

 elseif (phase == "ended" or phase == "cancelled") then 
 stage:setFocus(body, nil);
 body.tempJoint:removeSelf();
 end
 return true
end
body:addEventListener("touch", rotatebody);

[import]uid: 77183 topic_id: 27283 reply_id: 327283[/import]

@optionniko, here’s my version. The values for the last 2 parameters (the axis direction/vector) in the newJoint for wheel were too small. I’ve got a TODO to investigate why that matters, but increasing them seems to do the trick.

Note also that you misspelled “dynamic”. BTW, I think you have a misconception on how wheel joints are supposed to operate. The joint only stretches in the same direction. It should not rotate; the only thing that rotates is the wheel itself.

Anyway, the weird behavior is gone in this snippet, though you’ll have to try some other joint combination to achieve the effect you’re trying to achieve. Good luck!

[code]
display.setStatusBar( display.HiddenStatusBar )
local _W=display.contentWidth;
local _H=display.contentHeight;

local physics = require (“physics”)
physics.start ()
physics.setScale( 60 )
physics.setDrawMode (“hybrid”)

----OBJECTS
local legs = display.newRect(0,0,80,140);
legs.x, legs.y = _W*0.5, 860;

local body = display.newRect(0,0,160,300)
body.x, body.y = _W*0.5, 695;


------------------------- ANCHORES -----------------------

local anchor = display.newCircle(510, 500, 4); --Anchor above body’s body


------------------- PHYSICS BODIES -----------------------

physics.addBody( anchor, “static”);
physics.addBody( body, “dynamic” );
body.isSleepingAllowed = false;
physics.addBody( legs, “static”);


------- PHYSICS JOINTS BETWEEN ANCHOR AND BODIES --------

local bodyWheelJoint = physics.newJoint(“wheel”, body, anchor, anchor.x, anchor.y, 50, 50);
bodyWheelJoint.isLimitEnabled = true;
bodyWheelJoint:setLimits( -100, 100 )

local bodyPivotJoint = physics.newJoint(“pivot”, legs, body, body.x, body.y+102 );
bodyPivotJoint.isLimitEnabled = true;
bodyPivotJoint:setRotationLimits( -30, 30 );


------------------- ROTATE UPPER BODY --------------------

local function rotatebody(e)
local body = e.target;
local phase = e.phase;
local stage = display.getCurrentStage();

if (phase == “began”) then
stage:setFocus(body, e.id);
body.tempJoint = physics.newJoint(“touch”, body, e.x, e.y)
body.tempJoint.dampingRatio = 0.8
body.tempJoint.frequency = 400
body.tempJoint.maxForce = 400

elseif (phase == “moved”) then
body.tempJoint:setTarget(e.x, e.y);

elseif (phase == “ended” or phase == “cancelled”) then
stage:setFocus(body, nil);
body.tempJoint:removeSelf();
end
return true
end
body:addEventListener(“touch”, rotatebody);
[/code] [import]uid: 26 topic_id: 27283 reply_id: 110916[/import]