POV-Ray : Newsgroups : povray.advanced-users : Inverse Kinematics Server Time
25 Nov 2024 05:26:10 EST (-0500)
  Inverse Kinematics (Message 1 to 10 of 14)  
Goto Latest 10 Messages Next 4 Messages >>>
From: Tim Nikias v2 0
Subject: Inverse Kinematics
Date: 18 Jul 2003 18:49:09
Message: <3f187965@news.povray.org>
I've been googling a little, but so far couldn't find any
useful results. Maybe I'm not looking in the right
direction, so I thought I'd ask here.

I'm trying to search for some documents which might
give me some insight into how Inverse Kinematics may
be achieved, especially if I want to change amount of
joints and their freedom of rotation. I guess I could
easily cook something which would work for a "standard"
human arm and leg, but I'd rather like it if I can at least
learn about how I might attack multi-joint arms...

Anyone got any reference links I could begin with?

Regards,
Tim

-- 
Tim Nikias v2.0
Homepage: http://www.digitaltwilight.de/no_lights



---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.501 / Virus Database: 299 - Release Date: 15.07.2003


Post a reply to this message

From: Ken
Subject: Re: Inverse Kinematics
Date: 18 Jul 2003 22:19:30
Message: <3F18ABC6.A5A23CA1@pacbell.net>
"Tim Nikias v2.0" wrote:
> 
> I've been googling a little, but so far couldn't find any
> useful results. Maybe I'm not looking in the right
> direction, so I thought I'd ask here.
> 
> I'm trying to search for some documents which might
> give me some insight into how Inverse Kinematics may
> be achieved, especially if I want to change amount of
> joints and their freedom of rotation. I guess I could
> easily cook something which would work for a "standard"
> human arm and leg, but I'd rather like it if I can at least
> learn about how I might attack multi-joint arms...
> 
> Anyone got any reference links I could begin with?

http://runevision.com/3d/include/include.asp

-- 
Ken Tyler


Post a reply to this message

From: Doug Eichenberg
Subject: Re: Inverse Kinematics
Date: 18 Jul 2003 23:41:06
Message: <3f18bdd2@news.povray.org>
This looked promising, if you're willing to puzzle through it:

http://www.cis.upenn.edu/~badler/gmod/0528a.pdf


Post a reply to this message

From: Tim Nikias v2 0
Subject: Re: Inverse Kinematics
Date: 19 Jul 2003 06:43:16
Message: <3f1920c4$1@news.povray.org>
I had seen this, but it doesn't give me a general
solution with which I could model a three-jointed
leg or such. Additionally, it's already implemented,
and I like to understand the underlying formula
to create a more versatile set of macros.

Thanks anyways,
Tim

-- 
Tim Nikias v2.0
Homepage: http://www.digitaltwilight.de/no_lights


>
>
> "Tim Nikias v2.0" wrote:
> >
> > I've been googling a little, but so far couldn't find any
> > useful results. Maybe I'm not looking in the right
> > direction, so I thought I'd ask here.
> >
> > I'm trying to search for some documents which might
> > give me some insight into how Inverse Kinematics may
> > be achieved, especially if I want to change amount of
> > joints and their freedom of rotation. I guess I could
> > easily cook something which would work for a "standard"
> > human arm and leg, but I'd rather like it if I can at least
> > learn about how I might attack multi-joint arms...
> >
> > Anyone got any reference links I could begin with?
>
> http://runevision.com/3d/include/include.asp
>
> -- 
> Ken Tyler


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.501 / Virus Database: 299 - Release Date: 14.07.2003


Post a reply to this message

From: Tim Nikias v2 0
Subject: Re: Inverse Kinematics
Date: 19 Jul 2003 06:44:20
Message: <3f192104$1@news.povray.org>
It does sound interesting, but also a little above
my head at the moment... Nontheless, thanks
for link, perhaps I can make something of it when
having more time to spend on it...

Regards,
Tim

-- 
Tim Nikias v2.0
Homepage: http://www.digitaltwilight.de/no_lights


> This looked promising, if you're willing to puzzle through it:
>
> http://www.cis.upenn.edu/~badler/gmod/0528a.pdf
>
>


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.501 / Virus Database: 299 - Release Date: 14.07.2003


Post a reply to this message

From: Johannes Dahlstrom
Subject: Re: Inverse Kinematics
Date: 19 Jul 2003 17:13:52
Message: <oprsktbing70w29m@news.povray.org>
On Sat, 19 Jul 2003 00:46:01 +0200, Tim Nikias v2.0 <tim### [at] gmxde> 
wrote:
> Anyone got any reference links I could begin with?

Here's a fairly nice, easy-to-understand one:

http://freespace.virgin.net/hugo.elias/models/m_ik.htm

I recommend checking out the rest of his site as well,
if you're not already familiar with it. Lots of nice
stuff there.

-Johannes


Post a reply to this message

From: Patrick Elliott
Subject: Re: Inverse Kinematics
Date: 19 Jul 2003 17:41:51
Message: <MPG.19836835a2284e4b98983c@news.povray.org>
In article <3f192104$1@news.povray.org>, tim### [at] gmxde says...
> It does sound interesting, but also a little above
> my head at the moment... Nontheless, thanks
> for link, perhaps I can make something of it when
> having more time to spend on it...
> 

Simplest definition is that Inverse Kinematics uses some sort of nesting 
of objects. In SDL this is easy:

union {
  Object1
  Object {
    Object2
    rotate <x2,y2,z2>
  }
  rotate <x1,y1,z1>
}

Rotating by x1, y1, z1 will automatically move both objects, while x2, 
y2, z2 only move the nested one. The trick here is positioning. Each 
objects rotation 'must' be at the origin (or specifically the point 
around which you want to rotate it). Thus for a cylinder you want to 
position the end you want to be the 'center' so it is at <0,0,0>. Example 
(ignoring any syntax errors I made... lol):


#declare x1 = 0; //Segment 1 (upper arm perhaps?)
#declare y1 = 0;
#declare z1 = 0;
#declare x2 = 0; //Segment 2 and joint (lower arm)
#declare y2 = 90;
#declare z2 = 0;

union {
  cylinder{<0,0,0>,<1,1,1>,2} //First segment.
  union {
    sphere {<0,0,0),2} //Joint
    cylinder {<0,0,0>,<1,1,1>,2} //Second Segment.
    rotate <x2 ,y2, z2> //Rotate them around 0,0,0 'first' to position.
    translate <1,1,1> //Move them to the end of the first segment.
  }
  rotate <x1,y1,z1> //Rotate the first 'and' linked second segment.
  translate ... //Move to where ever you need the entire chain.
}

For a complex object like a robot you would start with some the fingers 
and work backward toward the body, attaching each new part to it in this 
way, by first rotating it to the direction you want it pointed, then 
moving it to the correct place in relation to the next object. As long as 
all objects are properly nested, moving the torso of the robot will also 
move the arms and legs, but rotating the left arm will only effect the 
lower arm, the hand, fingers and what ever else is attached to that chain 
of objects. The critical thing is as I said, to make sure that the point 
you want the object to move around 'starts' at the center of the 
rendering world, before you move it. Then it is just a matter of changing 
the rotation of each of these objects to put them where you need them. 
Then all you do is change the values of the variable you used and 
everything will move properly.

It is really quite simple, but definitely easier in the SDL than other 
programs. Trying to do the same thing in a modeller is a pain, since 
unless it specifically supports Inverse Kinematics or 'IK chains' getting 
all the objects tied together properly and working can be a pain. It is 
much easier to fix something when you can specifically define the order 
rotation and translation happen, than to fiddle with a modeller that may 
force a specific order on those actions.

The Raytracing Worlds book on POV-Ray had an explanation of how all this 
worked, going through the process step by step. However, I think it was a 
tutorial on using Moray to construct it. Moray has built in features to 
limit the amount and direction you can rotate stuff, so you won't rotate 
the arm into the middle of the body and stuff like that. In the SDL you 
have to be a bit more careful.

-- 
void main () {

    call functional_code()
  else
    call crash_windows();
}


Post a reply to this message

From: David Wallace
Subject: Re: Inverse Kinematics
Date: 21 Jul 2003 06:05:08
Message: <3f1bbad4@news.povray.org>
"Patrick Elliott" <sha### [at] hotmailcom> wrote in message
news:MPG.19836835a2284e4b98983c@news.povray.org...
> In article <3f192104$1@news.povray.org>, tim### [at] gmxde says...
> > It does sound interesting, but also a little above
> > my head at the moment... Nontheless, thanks
> > for link, perhaps I can make something of it when
> > having more time to spend on it...
> >
>
> Simplest definition is that Inverse Kinematics uses some sort of nesting
> of objects. In SDL this is easy:
>
> union {
>   Object1
>   Object {
>     Object2
>     rotate <x2,y2,z2>
>   }
>   rotate <x1,y1,z1>
> }
>
An array-based approach works too.

#declare ataObjs = array[8] { ataBase, ataSectB, ataSectM, ataSectM,
ataSectM, ataSectH, ataHandL, ataHandR }
#declare ataLens = array[8] { atabHgtB, atasH, atasH, atasH, atasH, atasH,
0, 0 }
#declare atArmAng = array[1][3]
#declare atArmAng[0][0] = array[7] { <-40, 20,-35>, x*26, x*30 , x*28, x*33,
x* 5,-x*10 }
#declare atArmAng[0][1] = array[7] { < 10, 70,  5>, x* 6, x* 4 , x* 8, x*13,
x*10,-x*20 }
#declare atArmAng[0][2] = array[7] { <- 3,-90,-15>, x*10, x* 8 , x*14, x*11,
x*15,-x*30 }
#declare ataMoves = array[7]

#macro ManipArm(Objects, Lengths, Joints, Moves)
 #local aSiz = dimension_size(Joints,1);
 #debug concat(str(aSiz,0,0), " objects.\n")
 #local ps = 0;
 #while (ps<aSiz)
  #local rt = ps;
  #declare Moves[ps] = transform {
   #while (rt>=0)
    rotate Joints[rt]
    translate y*Lengths[rt]
    #local rt = rt - 1;
   #end
  }
  #local ps = ps + 1;
 #end
 union {
  #set ps = 0;
  object { Objects[ps] }
  #while (ps<aSiz)
   #local ps = ps + 1;
   object { Objects[ps] transform { Moves[ps-1] } }
  #end
 }
#end

#macro atArm(obn, arn) object { ManipArm(ataObjs, ataLens,
atArmAng[obn][arn], ataMoves) } #end

The idea is to set up the transforms for each object first so that nesting
becomes unnecessary:

If you want the object definitions check out my "Manipulator arm" thread.


Post a reply to this message

From: Patrick Elliott
Subject: Re: Inverse Kinematics
Date: 21 Jul 2003 16:03:01
Message: <MPG.1985f4069895ed27989840@news.povray.org>
In article <3f1bbad4@news.povray.org>, dar### [at] earthlinknet says...
> 
> "Patrick Elliott" <sha### [at] hotmailcom> wrote in message
> news:MPG.19836835a2284e4b98983c@news.povray.org...
> > In article <3f192104$1@news.povray.org>, tim### [at] gmxde says...
> > > It does sound interesting, but also a little above
> > > my head at the moment... Nontheless, thanks
> > > for link, perhaps I can make something of it when
> > > having more time to spend on it...
> > >
> >
> > Simplest definition is that Inverse Kinematics uses some sort of nesting
> > of objects. In SDL this is easy:
> >
> > union {
> >   Object1
> >   Object {
> >     Object2
> >     rotate <x2,y2,z2>
> >   }
> >   rotate <x1,y1,z1>
> > }
> >
> An array-based approach works too.
> 
> #declare ataObjs = array[8] { ataBase, ataSectB, ataSectM, ataSectM,
> ataSectM, ataSectH, ataHandL, ataHandR }
> #declare ataLens = array[8] { atabHgtB, atasH, atasH, atasH, atasH, atasH,
> 0, 0 }
> #declare atArmAng = array[1][3]
> #declare atArmAng[0][0] = array[7] { <-40, 20,-35>, x*26, x*30 , x*28, x*33,
> x* 5,-x*10 }
> #declare atArmAng[0][1] = array[7] { < 10, 70,  5>, x* 6, x* 4 , x* 8, x*13,
> x*10,-x*20 }
> #declare atArmAng[0][2] = array[7] { <- 3,-90,-15>, x*10, x* 8 , x*14, x*11,
> x*15,-x*30 }
> #declare ataMoves = array[7]
> 
> #macro ManipArm(Objects, Lengths, Joints, Moves)
>  #local aSiz = dimension_size(Joints,1);
>  #debug concat(str(aSiz,0,0), " objects.\n")
>  #local ps = 0;
>  #while (ps<aSiz)
>   #local rt = ps;
>   #declare Moves[ps] = transform {
>    #while (rt>=0)
>     rotate Joints[rt]
>     translate y*Lengths[rt]
>     #local rt = rt - 1;
>    #end
>   }
>   #local ps = ps + 1;
>  #end
>  union {
>   #set ps = 0;
>   object { Objects[ps] }
>   #while (ps<aSiz)
>    #local ps = ps + 1;
>    object { Objects[ps] transform { Moves[ps-1] } }
>   #end
>  }
> #end
> 
> #macro atArm(obn, arn) object { ManipArm(ataObjs, ataLens,
> atArmAng[obn][arn], ataMoves) } #end
> 
> The idea is to set up the transforms for each object first so that nesting
> becomes unnecessary:
> 
> If you want the object definitions check out my "Manipulator arm" thread.
> 

Yes, such an approach 'is' possible, but far more complex, especially for 
very complex mechanisms. Nesting has the advantage of providing a clear 
structure for the objects relationships within the SDL code itself. You 
can see immediately where you screwed something up by incorrectly nesting 
it. Using an array system requires, for one thing keeping track of the 
current position of 'both' ends, since sub objects do not automatically 
move to match to position and location of their parent in such a system. 
It isn't something I would attempt to make adjustments to by hand. ;)

-- 
void main () {

    call functional_code()
  else
    call crash_windows();
}


Post a reply to this message

From: David Wallace
Subject: Re: Inverse Kinematics
Date: 22 Jul 2003 15:14:08
Message: <3f1d8d00@news.povray.org>
> > An array-based approach works too.
> >
> > #declare ataObjs = array[8] { ataBase, ataSectB, ataSectM, ataSectM,
> > ataSectM, ataSectH, ataHandL, ataHandR }
> > #declare ataLens = array[8] { atabHgtB, atasH, atasH, atasH, atasH,
atasH,
> > 0, 0 }
> > #declare atArmAng = array[1][3]
> > #declare atArmAng[0][0] = array[7] { <-40, 20,-35>, x*26, x*30 , x*28,
x*33,
> > x* 5,-x*10 }
> > #declare atArmAng[0][1] = array[7] { < 10, 70,  5>, x* 6, x* 4 , x* 8,
x*13,
> > x*10,-x*20 }
> > #declare atArmAng[0][2] = array[7] { <- 3,-90,-15>, x*10, x* 8 , x*14,
x*11,
> > x*15,-x*30 }
> > #declare ataMoves = array[7]
> >
> > #macro ManipArm(Objects, Lengths, Joints, Moves)
> >  #local aSiz = dimension_size(Joints,1);
> >  #debug concat(str(aSiz,0,0), " objects.\n")
> >  #local ps = 0;
> >  #while (ps<aSiz)
> >   #local rt = ps;
> >   #declare Moves[ps] = transform {
> >    #while (rt>=0)
> >     rotate Joints[rt]
> >     translate y*Lengths[rt]
> >     #local rt = rt - 1;
> >    #end
> >   }
> >   #local ps = ps + 1;
> >  #end
> >  union {
> >   #set ps = 0;
> >   object { Objects[ps] }
> >   #while (ps<aSiz)
> >    #local ps = ps + 1;
> >    object { Objects[ps] transform { Moves[ps-1] } }
> >   #end
> >  }
> > #end
> >
> > #macro atArm(obn, arn) object { ManipArm(ataObjs, ataLens,
> > atArmAng[obn][arn], ataMoves) } #end
> >
> > The idea is to set up the transforms for each object first so that
nesting
> > becomes unnecessary:
> >
> > If you want the object definitions check out my "Manipulator arm"
thread.
> >
>
> Yes, such an approach 'is' possible, but far more complex, especially for
> very complex mechanisms. Nesting has the advantage of providing a clear
> structure for the objects relationships within the SDL code itself. You
> can see immediately where you screwed something up by incorrectly nesting
> it. Using an array system requires, for one thing keeping track of the
> current position of 'both' ends, since sub objects do not automatically
> move to match to position and location of their parent in such a system.
> It isn't something I would attempt to make adjustments to by hand. ;)
>

What the ataLens array does is position each object onto the meeting point
of its parent.  This only has to be done when (re)designing the object.  The
ataArmAng array "poses" the structure.  The ManipArm macro takes the
individual positioning and posing transforms and combines them in reverse
order.  My macro is a bit basic in that it assumes the connecting sections
pile up vertically.  ataLens could just as easily contain 3D vectors,
matrices, or transforms.

In your nested structure you still have to pose each item and position it
onto the end of its parent.  The result is an object which you then
transform again, etc.  All I did was use a macro to combine the transforms
in ataLens into a single transform in ataMoves for each arm segment.  You
don't have to "make adjustments by hand"-- the ManipArm macro makes them for
you.  The posing transforms need to be watched in both systems, however.

The issue I have with nesting comes from what I suspect are limits within
POV-Ray on the number of nested levels you can have.  It's not that nesting
is inherently wrong; it actually works for simple models.  But heaven help
you if you want to build a millipede using nesting.


Post a reply to this message

Goto Latest 10 Messages Next 4 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.