Motorized Hinge with Limits (using Joint Library)

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Motorized Hinge with Limits (using Joint Library)

Postby yorisimo » Tue Dec 08, 2009 2:16 pm

Hi,

In Newton 1.53 I made motorized hinges with limits using the built in hinge and callbacks using this method
Code: Select all
n_joint = NewtonConstraintCreateHinge(nworld, joint.pos, joint.axis), joint.follower, joint.base);
NewtonHingeSetUserCallback(n_joint, hingejoint_callback);

void hingejoint_callback(NewtonJoint* hinge, NewtonHingeSliderUpdateDesc* desc)
{
        ...
        if(angle > angleUB && desired_omega>=0) 
               desc.m_accel = NewtonHingeCalculateStopAlpha(hinge, desc, angleUB); //above upper limit
   else
        {
          if(angle < angleLB && desired_omega<=0) 
                      desc.m_accel = NewtonHingeCalculateStopAlpha(hinge, desc, angleLB); //below lower limit
      else
                      desc.m_accel = accelK * (desired_omega - actual_omega) / desc.m_timestep;    //between limits -> motorized
   }
 }
 


I want to update this to Newton 2, and use the joint library's CreateCustomHinge function. I managed to make a hinge with limits but I don't know how to motorize it. How do I apply callbacks to the CustomHinge. Do I use CustomSetSubmitContraintCallback?

and then use these functions in the callback? (or do these only work with the legacy joints):
NewtonUserJointAddAngularRow (nujoint, 0, pin);
NewtonUserJointSetRowAcceleration (nujoint, accel);

P.S. I'm using Newton 2.11 with GameStudio using the wrapper made by Vasilenko Vitaliy (VeT)
yorisimo
 
Posts: 7
Joined: Tue Dec 08, 2009 10:58 am

Re: Motorized Hinge with Limits (using Joint Library)

Postby aqnuep » Wed Dec 09, 2009 1:46 pm

I would be also interested in that how motorized joints work in the Joint Library...
aqnuep
 
Posts: 97
Joined: Sat Dec 22, 2007 4:14 pm

Re: Motorized Hinge with Limits (using Joint Library)

Postby Julio Jerez » Wed Dec 09, 2009 2:34 pm

if you look into teh FAQ http://newtondynamics.com/forum/viewtopic.php?f=15&t=3501

you can see that is is very simple, you can use the 6DOF or the basic hinge and derive your own joint from it.
The link have some examples of how to make diffrnet falover including a motorized hinge by teh end.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Motorized Hinge with Limits (using Joint Library)

Postby aqnuep » Wed Dec 09, 2009 2:59 pm

Thanks! So yorisimo was right, the UserJoint functions shall be used.
aqnuep
 
Posts: 97
Joined: Sat Dec 22, 2007 4:14 pm

Re: Motorized Hinge with Limits (using Joint Library)

Postby yorisimo » Thu Dec 10, 2009 11:44 am

So with the new joint library's custom joint there is no automatic way to get the joint angle and angular velocity like with the legacy hinges?
NewtonHingeGetJointAngle (hinge) and NewtonHingeGetJointOmega (hinge)

That is, i have to use the rotation matrixes of the bodies to calculate the joint angle as in the example at that link?

to aqnuep:
Did you get this working with the customhinge. The example Julio linked to used the custom6dof
yorisimo
 
Posts: 7
Joined: Tue Dec 08, 2009 10:58 am

Re: Motorized Hinge with Limits (using Joint Library)

Postby aqnuep » Thu Dec 10, 2009 1:35 pm

yorisimo wrote:Did you get this working with the customhinge. The example Julio linked to used the custom6dof

Yes, this part is working in the same fashion like custom6dof (if you meant the motorized joint).
About the parameter queries, well, I don't know how to do it btw.
aqnuep
 
Posts: 97
Joined: Sat Dec 22, 2007 4:14 pm

Re: Motorized Hinge with Limits (using Joint Library)

Postby yorisimo » Thu Dec 10, 2009 5:47 pm

I'm sorry but I still don't get this. I am using Game Studio's Lite-C and VeT's wrapper so I am not able to use classes. Therefore I have a hard time understanding these examples (because I don't have a good understanding of classes and subclasses).

Here's what I am doing

In my main function I have defined the hinge as follows
Code: Select all
   //HINGE
   //about x axis
   //float pinPivotMatrix[16] = {1, 0, 0, 0,   0, 1, 0, 0,   0, 0, 1, 0,   0, 0, 0, 1};
   //about y axis
   float pinPivotMatrix[16] = {0, 1, 0, 0,   1, 0, 0, 0,   0, 0, 1, 0,   0, 0, 0, 1};
   //about z axis
   //float pinPivotMatrix[16] = {0, 0, 1, 0,   1, 0, 0, 0,   0, 1, 0, 0,   0, 0, 0, 1};
   
   pinPivotMatrix[12] =   0*QUANTTOMETER;
   pinPivotMatrix[13] = 147*QUANTTOMETER;
   pinPivotMatrix[14] = 400*QUANTTOMETER;
   
   float ub = 45*DEG2RAD;
   float lb = -45*DEG2RAD;
   nujoint = CreateCustomHinge(pinPivotMatrix, nbody[0], nbody[1]); //matrix/follower/base
   HingeEnableLimits (nujoint, 1);
   HingeSetLimis (nujoint, lb, ub);
   CustomSetSubmitContraintCallback(nujoint, (void*)CustomHinge_callback);


My Callback looks like this:
Code: Select all
void CustomHinge_callback(const NewtonUserJoint* nuj, dFloat timestep, int threadIndex)
{
   static float accel;
   accel+=mickey.y*time_step*100;
   //NewtonUserJointAddAngularRow (nuj, 0, vectorf(0,1,0));
   NewtonUserJointSetRowAcceleration  (nuj, accel);   
   NewtonUserJointSetRowStiffness  (nuj, 1);
}


The commented line in the callback causes a crash. In the wiki, it says NewtonUserAddAngularRow can only be called in a NewtonUserBilateralCallBack callback, but I've tried that and that doesn't seem to work either.

Please explain how what I am doing is wrong and what I am supposed to do instead, keeping in mind that I can't use classes, and I would like to use built-in functionality.

Julio: I really like Newton 1.53...I know that Newton 2 is still in Beta and that Newton2 specific documentation is limited, but to me it seems the new joint library is less intuitive to use if i want a motor. Would it not be simple to incorporate the motor as part of the Hinge in the joint library (like the limits were implemented) and provide a function to access the joint angle?

Thanks, and I apologize if I am missing something obvious.
yorisimo
 
Posts: 7
Joined: Tue Dec 08, 2009 10:58 am

Re: Motorized Hinge with Limits (using Joint Library)

Postby Julio Jerez » Thu Dec 10, 2009 6:39 pm

yorisimo wrote:I'm sorry but I still don't get this. I am using Game Studio's Lite-C and VeT's wrapper so I am not able to use classes. Therefore I have a hard time understanding these examples (because I don't have a good understanding of classes and subclasses).

I see teh problem, well the joint library also have a c interface that exposes the DOF joint, is is very eassy you make a motorized hinge using the inteface.
does the wraper exposes the joint library from the C script?
if it does I can post the code you needd for a motorized Hinge using the joint library in C.

but it you can not use the joint library then it will not do any good, does that sound fair?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Motorized Hinge with Limits (using Joint Library)

Postby yorisimo » Fri Dec 11, 2009 3:57 pm

Julio,

Wow, thanks.
Yes, VeT's wrapper does expose the joint library.
I was able to use the joint library to make the customhinge with limits...just need a motor and the ability to read the joint's current angle and angular velocity.

-Joris
yorisimo
 
Posts: 7
Joined: Tue Dec 08, 2009 10:58 am

Re: Motorized Hinge with Limits (using Joint Library)

Postby Julio Jerez » Sat Dec 12, 2009 9:37 pm

Ok I think I added what you need to make the motor hinge, you can do two things
One is download 2.12 so that you get the new function added to the joint library,
Or you can add the functions yourself to the joint library and re compiler it with visual studio.
These are the functions.

In file JointLibrary.h
Code: Select all
JOINTLIBRARY_API NewtonJoint* CustomGetNewtonJoint (const NewtonUserJoint *joint);
JOINTLIBRARY_API dFloat HingeGetJointAngle (const NewtonUserJoint* hingeJoint);
JOINTLIBRARY_API void HingeGetPinAxis (const NewtonUserJoint* hingeJoint, dFloat* pin);
JOINTLIBRARY_API dFloat HingeCalculateJointOmega (const NewtonUserJoint* hingeJoint);

In file JointLibrary.cpp
Code: Select all
NewtonJoint* CustomGetNewtonJoint (const NewtonUserJoint *joint)
{
   return  (NewtonJoint*) (((NewtonCustomJoint*)joint)->GetJoint ());
}


class CustomUserHinge: public CustomHinge 
{
public:
   CustomUserHinge (const dMatrix& pinsAndPivoChildFrame, const NewtonBody* child, const NewtonBody* parent)
      :CustomHinge (pinsAndPivoChildFrame, child, parent)
   {
   }

   dFloat GetJointAngle () const
   {
      return m_curJointAngle.m_angle;
   }

   void GetPin (dFloat* pin) const
   {
      dMatrix matrix;
      NewtonBodyGetMatrix (m_body0, &matrix[0][0]);

      dVector dir (matrix.RotateVector (m_localMatrix0.m_front));
      pin[0] = dir.m_x;
      pin[1] = dir.m_y;
      pin[2] = dir.m_z;
   }

   dFloat CalculateJointOmega () const
   {
      dMatrix matrix0;
      dMatrix matrix1;
      dVector omega0(0.0f, 0.0f, 0.0f, 0.0f);
      dVector omega1(0.0f, 0.0f, 0.0f, 0.0f);
      CalculateGlobalMatrix (m_localMatrix0, m_localMatrix1, matrix0, matrix1);

      NewtonBodyGetOmega(m_body0, &omega0[0]);
      if (m_body1) {
         NewtonBodyGetOmega(m_body1, &omega1[0]);
      }
      return (omega0 - omega1) % matrix0.m_front;;
   }
};

// Generic Hinge Joint spin along the first axis on pinsAndPivoChildFrame
NewtonUserJoint *CreateCustomHinge (const dFloat* pinsAndPivoChildFrame, const NewtonBody* child, const NewtonBody* parent)
{
   return (NewtonUserJoint *) new CustomUserHinge (*(dMatrix*) pinsAndPivoChildFrame, child, parent);
}

void HingeEnableLimits(NewtonUserJoint* hingeJoint, int state)
{
   ((CustomUserHinge*)hingeJoint)->EnableLimits(state ? true : false);
}

void HingeSetLimis (NewtonUserJoint* hingeJoint, dFloat minAngle, dFloat maxAngle)
{
   ((CustomUserHinge*)hingeJoint)->SetLimis (minAngle, maxAngle);
}

dFloat HingeGetJointAngle (const NewtonUserJoint* hingeJoint)
{
   return ((CustomUserHinge*)hingeJoint)->GetJointAngle();
}

void HingeGetPinAxis (const NewtonUserJoint* hingeJoint, dFloat* pin)
{
   return ((CustomUserHinge*)hingeJoint)->GetPin (pin);
}

dFloat HingeCalculateJointOmega (const NewtonUserJoint* hingeJoint)
{
   return ((CustomUserHinge*)hingeJoint)->CalculateJointOmega();
}


Then you can make any kind or motorized hinge with or without limits. Here is an example of an object you can control by setting the joint angle
Code: Select all
struct HingeLocalInfo
{
//   dFloat m_minLimit;
//   dFloat m_maxLimit;
//   dFloat m_desiredVelocity;
   dFloat m_desiredAngle;
};

static void HingeMotorDestructorCallback (const NewtonUserJoint* me)
{
   free (CustomGetUserData (me));
}

static void HingeControlledByAngle (const NewtonUserJoint* me, dFloat timestep, int threadIndex)
{
   dFloat errorAngle;
   dFloat jointAngle;
   dVector pin;
   HingeLocalInfo* info;
   NewtonJoint* newJoint;
      

   info = (HingeLocalInfo*) CustomGetUserData (me);
   jointAngle = HingeGetJointAngle (me);
   HingeGetPinAxis (me, &pin[0]);
   newJoint = CustomGetNewtonJoint (me);

   errorAngle =  jointAngle - info->m_desiredAngle;
   NewtonUserJointAddAngularRow (newJoint, errorAngle, &pin[0]);

}


void MakeControlJoint()
{
      HingeLocalInfo* info;
      NewtonUserJoint* joint;
      joint = CreateCustomHinge (&pinAndPivot[0][0], bar, NULL);
      HingeEnableLimits(joint, 1);
      HingeSetLimis (joint, -200.0, 200.0f);
      CustomSetSubmitContraintCallback (joint, HingeControlledByAngle);
      CustomSetDestructorCallback (joint, HingeMotorDestructorCallback);

      info =(HingeLocalInfo*) malloc (sizeof (HingeLocalInfo));
//      info->m_minLimit = -200.0;
//      info->m_maxLimit =  200.0f;
//      info->m_desiredVelocity = 5.0;
      info->m_desiredAngle = 30.0f * 3.1416f/180.0f;
      CustomSetUserData (joint, info);
}

Then you can control the body by setting an angle into info->m_desiredAngle.
in this example is a act like a rigid joint so it will not meve fast, but there are many other types you can make by setting you own user function
NewtonUserJointSetRowAcceleration (joint, accel);
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Motorized Hinge with Limits (using Joint Library)

Postby yorisimo » Mon Dec 14, 2009 11:57 am

Thanks again Julio. It works great!

just a minor note: It looks like the new function HingeCalculateJointOmega returns the wrong sign (the joint angle decreases when angular velocity is positive)
yorisimo
 
Posts: 7
Joined: Tue Dec 08, 2009 10:58 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 0 guests