Single Link joint with more than one DOF


I’m trying to model some kind of Stewart platform. The closest I could find in the eCatalog were delta robots, for example Fanuc M-2iA_6HL and I’m trying to understand how the joints are defined for its moving platform which has 3DOF.

This robot has a moving platform that can jog in X, Y and Z direction, expressed by the component properties PX, PY and PZ. The Link element for the moving platform has a joint with JointType ‘Custom’. The joint property is set to ‘Tx(PX).Ty(PY).Tz(PZ)’. However, the only property that is defined here is PX and I have no idea, where PY and PZ are defined. In the Robot Controller settings of M-2iA_6HL it is possible to select as PX, PY, PZ (and J4) as joints, but I can’t find them anywhere in the geometry.

Can someone tell me how it is possible to create a single Joint that can move freely in 3DOF (or more) with one controller?

Try making a custom joint type and then write an expression to define its DOF.

Well, I can define the expression for the custom joints to be Tx(VALUE), Ty(VALUE) and Tz(VALUE). However, this requires me to create independent link elements for each of them and then cascade them in the Component Graph, because I can not assign more than one DOF to a link element. This won’t let me jog in all 3 directions like in the example though.

What I was referring to in the example is that there is a single link element with a joint named ‘PX’ which has the expression ‘Tx(PX).Ty(PY).Tz(PZ)’ and can jog in all 3 directions.

If I use the same expression, the following happens:

  • First I get an error that the variables PY and PZ are not defined. To work around this, I can create the component properties PX, PY and PZ. What's confusing is that these properties seem to exist in the M-2iA_6HL example as well, but are not visible and seemingly defined nowhere.
  • It's not possible to jog in any direction at all (It only works when I use the 'VALUE' parameter instead of fixed values like 'PX' in the expression).
  • It is not possible to add PY and PZ joints to the robot controller as opposed to the example component.
And one more question: In PythonKinematics, how can I assign kinobj.Target to a specific frame?

Attached is an example of using jacobian object with Python Kinematics.

If you look under the hood of one of the scara type robots in eCat, you might see something like this where a matrix object is created, modified and then assigned to the kinobj.Target.

def OnInverse(kinobj):
  if FirstCall:
  solutions = []
  px = kinobj.Target.P.X
  py = kinobj.Target.P.Y
  pz = kinobj.Target.P.Z 
  ox = kinobj.Target.O.X   
  oy = kinobj.Target.O.Y   
  # First we calculate the direction to the wrist center
  a13= atan2( py, px )*RAD_TO_DEG 
  d13 = sqrt( px*px + py*py )
  if( d13 > LL1 + LL2 ):
    t1 = 0.0
    t2 = 180.0
    if( d13 < abs(LL1 - LL2) ):
      t1 = 180.0
      t2 =   0.0
      t1 = sssa( LL2, LL1,  d13 )*RAD_TO_DEG
      t2 = sssa(  d13, LL1, LL2 )*RAD_TO_DEG
    #end if
  j3 = pz - ZeroHeight
  t4 = atan2(-ox, oy)*RAD_TO_DEG
  for iconf in range(CONFIG_COUNT):  
    if iconf == 1:
      sgn1 = -1
      sgn1 = 1
    j1 = a13 + sgn1*t1
    j2 = sgn1*(t2-180.0)
    j4 = t4 - j1 - j2
    solutions.append( [ warning, GetMappedJoints( [j1,j2,j3,j4] ) ] )
  # end for NUM_CONFIGS
  kinobj.Solutions = solutions
  return True

def OnForward(kinobj):
  if FirstCall:
  nominal = GetNominalJoints( kinobj.JointValues ) 
  m04 =
  m04.rotateRelZ( nominal[0] )
  m04.translateRel( LL1, 0.0, 0.0 )
  m04.rotateRelZ( nominal[1] )
  m04.translateRel( LL2, 0.0, nominal[2]+ZeroHeight )
  m04.rotateRelZ( nominal[3] )
  #m04.rotateRelY( 180.0 )
  kinobj.Target = m04
  if kinobj.JointValues[1] <= 0.0:
    kinobj.Configuration = GetConfigName(0)
    kinobj.Configuration = GetConfigName(1)
  return True


Test-PJK-with-1-Axis.vcmx (29.7 KB)

As for the expression, I don’t have a mechanics background, so best if someone else answers and has a good, clean equation.

Are you talking about this in the forward kinematics method?

kinobj.Target = m04

I was referring to the OnInverse(kinobj) method, where the target is given, and I want to calculate the joint values. However, when I try to extract coordinates from kinobj.Target like in the following, there are only empty values.

  px = kinobj.Target.P.X
  py = kinobj.Target.P.Y
  pz = kinobj.Target.P.Z
  ox = kinobj.Target.O.X
  oy = kinobj.Target.O.Y


Ok, I suppose that the OnForward() method is needed to provide kinobj.Target for OnInverse().

And I solved the joint problem by cascading 6 x 1 DOF joints like it is done in the Visual Components delta robot. I still don’t understand how the Fanuc robot works, but at least my application is working now.

HI, do you happen to have a working model for a stewart platform? Thanks

Hi, do you happen to have a working model of a stewart platform?