POV-Ray : Newsgroups : povray.advanced-users : Inverse Kinematics Server Time
29 Jul 2024 04:23:15 EDT (-0400)
  Inverse Kinematics (Message 5 to 14 of 14)  
<<< Previous 4 Messages Goto Initial 10 Messages
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

From: Patrick Elliott
Subject: Re: Inverse Kinematics
Date: 22 Jul 2003 20:38:15
Message: <MPG.198785efdc47195b989841@news.povray.org>
In article <3f1d8d00@news.povray.org>, dar### [at] earthlinknet says...
> 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.
> 
Yes, but you can just as easily use an array to keep track of each 
rotation. However, in both cases you end up having to remember 'which' 
set up data belong to what item in such a case. Unless you have an 
external program that shows and and keep track of all these, you are 
better off having all leg motions in one array, arm motions in another, 
etc. If everything is stored this way you have a big bloody mess, 
especially if you drop the project for a few months and then come back 
and realize you haven't a clue what belongs where or why. ;) Maybe 
something in between would work better.

> 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.
> 

Not necessarily.. I think it is 'levels' of nesting that are an issue, 
not the total objects you nest. For a millipede you are looking at 
roughly 4 layers for the legs and a body segment. If the body itself is a 
spline, then you could use a surface trace or some other method to locate 
each pair of legs (which makes it exactly 4 levels, not including extra 
segments for antennae). Unless you are a total fool, you end up with a 
nesting level of no more than 4-5 levels maximum. I frankly can't think 
of anything that should require extreme amounts of nesting (though this 
won't stop someone from doing it). At worst you might have some object 
you don't want to move, but still be attached to a level above and that 
would add an extra sub group at 'that' nesting level. I could be wrong 
about how the limit works. But one thing I do know, it is a bad idea to u 
unnecessarily complicate a model by dumping the whole thing into an array 
where the most someone, who doesn't have graph paper and lots of 
patience, can say is 'well that object is located somewhere in the 
model...'. lol

-- 
void main () {

    call functional_code()
  else
    call crash_windows();
}


Post a reply to this message

From:
Subject: Re: Inverse Kinematics
Date: 22 Jul 2003 22:14:40
Message: <3f1def90$1@news.povray.org>
> I think it is 'levels' of nesting that are an issue

I've tried 1500 nested rhombododecahedrons: it works, but took
over 20 minutes of parsing time at 1 GHz because *all* objects
nested so far have to be transformed at every level, making the
time required for transformations proportional to the square of
the levels (when objects of comparable complexity at every level
are nested). 50 rhombododecahedrons take only 1 second, so very
complicated robot arms or even chains are easily possible with
the nesting method.

   Sputnik


Post a reply to this message

From: Lutz Kretzschmar
Subject: Re: Inverse Kinematics
Date: 3 Aug 2003 00:32:49
Message: <pj1hivgm1mngodtp408phj5inr34mt2pd3@4ax.com>
Hi Tim Nikias v2.0, you recently wrote in povray.advanced-users:

> Anyone got any reference links I could begin with?
I don't have the link, but Game Developer Magazine had an excellent
series (with basic source code) that illustrated the concepts very
nicely.... try www.gdmag.com and see if you can find it....

- Lutz
  email : lut### [at] stmuccom
  Web   : http://www.stmuc.com/moray


Post a reply to this message

From: Apache
Subject: Re: Inverse Kinematics
Date: 23 Aug 2003 10:06:40
Message: <3f4774f0@news.povray.org>
We did that with the rings animation (job 1) on the Internet Movie Project
(www.imp.org)
this method is very simple to get interesting results


Post a reply to this message

<<< Previous 4 Messages Goto Initial 10 Messages

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