Hinge joint can't beat gravity [SOLVED]

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Hinge joint can't beat gravity [SOLVED]

Postby JoeWright » Mon Mar 09, 2009 6:26 am

I'm trying to do a motor hinge joint (based on the custom hinge joint code) but I can't get it to beat gravity.

I've got a collection of bodies that are connected with hinge joints and the code is asking Newton to force the hinge angle to a fixed value (0.0). The problem is, gravity has a bigger effect on the hinges - I just can't get them stiff enough.

Any ideas?

Joe
Last edited by JoeWright on Tue Mar 10, 2009 6:26 am, edited 1 time in total.
JoeWright
 
Posts: 69
Joined: Sat Apr 30, 2005 1:42 pm

Re: Hinge joint can't beat gravity

Postby JoeWright » Mon Mar 09, 2009 9:15 am

Image

This is my person lying collapsed on the floor. I don't have collision between body parts by design. All hinge joints are trying to contrain to a default zero angle. This means the left leg and arm (green) should be straight but they're actually hanging towards the floor (into the other body parts as I have no collision).

My modification to the hinge code is as follows:

Code: Select all
   desired_angle=0.0;

   if (angle < desired_angle) {
      dFloat relAngle;

      relAngle = angle - desired_angle;

      // tell joint error will minimize the exceeded angle error
      NewtonUserJointAddAngularRow (mpNewtonJoint, relAngle, &global_pin_pivot0.m_front[0]);

      // need high stiffness here
      NewtonUserJointSetRowStiffness (mpNewtonJoint, 1.0f);

      // allow the joint to move back freely
      NewtonUserJointSetRowMaximumFriction (mpNewtonJoint, 0.0f);


   } else if (angle > desired_angle) {
      dFloat relAngle;

      relAngle = angle - desired_angle;
      
      // tell joint error will minimize the exceeded angle error
      NewtonUserJointAddAngularRow (mpNewtonJoint, relAngle, &global_pin_pivot0.m_front[0]);

      // need high stiffness here
      NewtonUserJointSetRowStiffness (mpNewtonJoint, 1.0f);

      // allow the joint to move back freely
      NewtonUserJointSetRowMinimumFriction (mpNewtonJoint, 0.0f);

   }


Joe
JoeWright
 
Posts: 69
Joined: Sat Apr 30, 2005 1:42 pm

Re: Hinge joint can't beat gravity

Postby JoeWright » Tue Mar 10, 2009 6:26 am

I've solved this by switing to linear rows instead of the angular row:

Code: Select all
   q0=global_pin_pivot0[1].Scale(cos(desired_angle))+global_pin_pivot0[2].Scale(sin(desired_angle));
   q0=q0.Scale(MIN_JOINT_PIN_LENGTH);
   q0+=global_pin_pivot0.m_posit ;
   q1=global_pin_pivot1.m_posit + global_pin_pivot1[1].Scale(MIN_JOINT_PIN_LENGTH);

    NewtonUserJointAddLinearRow (mpNewtonJoint, &q0[0], &q1[0], &global_pin_pivot0.m_up[0]);
   NewtonUserJointAddLinearRow (mpNewtonJoint, &q0[0], &q1[0], &global_pin_pivot0.m_right[0]);


Julio, I think you've mentioned in the past that angular rows are not as powerful as linear rows. That's what I'm finding here. Why is that?

Cheers, Joe
JoeWright
 
Posts: 69
Joined: Sat Apr 30, 2005 1:42 pm

Re: Hinge joint can't beat gravity [SOLVED]

Postby JoeWright » Tue Mar 10, 2009 8:58 am

I've found that the above code doesn't always work. I've cured it by changing the constraint to be along the tangent to the child moving axis, in the moving plane. This is the cross of the child moving axis and the hinge axis:

Code: Select all
   q0=global_pin_pivot0[1].Scale(cos(desired_angle))+global_pin_pivot0[2].Scale(sin(desired_angle));
   q0=q0.Scale(MIN_JOINT_PIN_LENGTH);
   q0+=global_pin_pivot0.m_posit ;
   q1=global_pin_pivot1.m_posit + global_pin_pivot1[1].Scale(MIN_JOINT_PIN_LENGTH);

   dVector tangent(q1 * global_pin_pivot0[0]);
    NewtonUserJointAddLinearRow (mpNewtonJoint, &q0[0], &q1[0], &tangent[0]);


Its also useful to avoid stuck conditions at the limits. For example, I use this code that makes sure the desired angle is only clamped if the acceleration is trying to make it more extreme:

Code: Select all
   desired_angle=mLastHingeAngle+mHingeAcceleration*kTimeStep*TWO_PI;
   if (desired_angle<min_angle && mHingeAcceleration<0.0)
      desired_angle=min_angle;
   if (desired_angle>max_angle && mHingeAcceleration>0.0)
      desired_angle=max_angle;
JoeWright
 
Posts: 69
Joined: Sat Apr 30, 2005 1:42 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 18 guests

cron