POV-Ray : Newsgroups : povray.binaries.images : Learner IK problems... (dull illustrations, 9+1kbu) Server Time
19 Nov 2024 00:35:59 EST (-0500)
  Learner IK problems... (dull illustrations, 9+1kbu) (Message 1 to 4 of 4)  
From: Mark Hanford
Subject: Learner IK problems... (dull illustrations, 9+1kbu)
Date: 14 Feb 2002 17:14:06
Message: <3c6c36ae@news.povray.org>
Dear gathered pro's...

I have been trying to create an IK system for positioning the fingers of my
robot hand, preferably without too much help, however the "Joy Of Discovery"
is rapidly loosing out to the "Frustration Of GetNowhere"

This is supposed to be a relatively simple case, but I am getting totally
stuffed somewhere:
I am trying to move the tip of Joint2 (blue) to the target.  The circle is
an exagerated tollerance boudary, anywhere within this circle will be
alright (bailout).

I am using a process described by
http://freespace.virgin.net/hugo.elias/models/m_ik.htm which uses the dot
product of the vector from the tip of the joint to the target and the
tangent to the "bone" of the joint to calculate how much to move the arm...

What I have is a situation where the last joint seems to move okay, so it
always "yearns" towards the target, wherever the target is, and if I
manually set the rotation angle for Joint1 (green), the tip still follows
the target - and a little anim seems to show this nicely.

Where I'm getting totally lost is when I'm trying to move two joints at
once, and I can't work out if I'm assuming something incorrectly about the
tangent vector R or
what.    AAAaaaarrrgghhh....

This should be simple, as the joint are only articulated in with one degree
of freedom, but I'm stumped.  I don't know a huge amount about vector maths,
and I think this may be holding me up :(

thanks,

Mark

(Source is in p.t.s-f)

Tip[] stores the tip coords for each joint
Length[] is the length of the joint
Rotate[] is the angle by which to move the joint
Right[] is supposed to be the bone-tangent (R in instructions)
Force[] is supposed to be the force-vector (F in instructions)

#macro ReorientTip2()
  #while (Torque[2]>TorqueBailout)
      CalcTipsFK()
      #declare Right[2]=vrotate(<0,1,0>, (Rotate[0]+Rotate[1]+Rotate[2])*z);
      #declare Force[2]=TargetLocation-Tip[1];
      #declare Torque[2]=vdot(Right[2], Force[2])*Delta;
      #declare Rotate[2]=Rotate[2]+Torque[2];
#end



Mark Hanford
http://www.mrhanford.com/povray


Post a reply to this message


Attachments:
Download 'ik-frame9.jpg' (10 KB) Download 'websample1.gif' (2 KB)

Preview of image 'ik-frame9.jpg'
ik-frame9.jpg

Preview of image 'websample1.gif'
websample1.gif


 

From: Mark Wagner
Subject: Re: Learner IK problems... (dull illustrations, 9+1kbu)
Date: 15 Feb 2002 02:58:31
Message: <3c6cbfa7@news.povray.org>
Mark Hanford wrote in message <3c6c36ae@news.povray.org>...
>Dear gathered pro's...

>I am trying to move the tip of Joint2 (blue) to the target.  The circle is
>an exagerated tollerance boudary, anywhere within this circle will be
>alright (bailout).

>Where I'm getting totally lost is when I'm trying to move two joints at
>once, and I can't work out if I'm assuming something incorrectly about the
>tangent vector R or
>what.    AAAaaaarrrgghhh....

What I did for my entry in the IRTC "Robots" round was to approximate the
section between Joint1 and the fingertip as a single segment of the finger,
using a formula to estimate the amount of bending of Joint2.  After figuring
out where Joint1 was, I used Joint1 as the base of a single-joint finger to
find out where exactly Joint2 would be.



Just in case you're interested, here's the macro I used to create a single
finger on my robot's left hand.  LeftWristUp is the "up" vector for the back
of the robot's left hand.

//Helper macro for Finger -- returns the joint position given two fixed
points and the lengths of the
// segments between them, with a value to multiply LeftWristUp by
#macro FindJoint(Start, End, R1, R2, Sign)
 #local _d = vlength(Start-End); //Distance between spheres
 #local _r = sqrt(-(_d+R2+R1)*(_d-R2+R1)*(_d+R2-R1)*(_d-R2-R1))/(2*_d);
//Radius of circle of intersection
 #local _q = ((_d*_d)+(R2*R2)-(R1*R1))/(2*_d);
 #local _v = vnormalize(End-Start) * _q; //The position along the line
between End and Start where the two spheres intersect.  This is also the
direction from End to Start
 #local _p = vcross(_v, (LeftWristUp-LeftWristPivot) * Sign); // Find the
vector perpendicular to the line between Start and End and LeftWristUp
 vnormalize(vcross(_p,_v)) * _r - _v + End //Find the vector perpendicular
to the previous vector and the line.
 // This is the absolute 3D space joint position
#end

// Creates a finger given a base point, a point for the tip, finger
thickness, and finger length
#macro Finger(Start, End, Length, Thick)
 #warning "Start and End:\n"
 #warning concat( Vstr(Start/in,2,2),"\n")
 #warning concat( Vstr(End/in,2,2),"\n")
 #local _Length = vlength(Start-End);
 //Lengths of sections of finger
 #local _Top = Length/2;
 #local _Middle = Length/3;
 #local _Tip = Length/6;
 #warning concat(str(Length/in,4,4),", ",str(_Length/in,4,4),"\n")
 //Approximate _Joint2 position from distance between Start and End
 #local _J2Theta = acos(_Length/Length)/2;  //Angle formed by joint
 #local _J2Length = _Tip*cos(_J2Theta)+_Middle*cos(_J2Theta); //Combined
length of finger tip
// #warning concat(str(_J2Theta,2,2),"\n")

 #local _handAxis = LeftWristFinger - LeftWristPivot;
    //Handle special case of Start-End being parallel to LeftWristUp
    #if(vdot(vnormalize(LeftWristUp-LeftWristPivot),vnormalize(Start-End)) =
1)
     #local __temp = LeftWristUp;
     #declare LeftWristUp = LeftWristFinger;
     #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, 1);
  #if((vdot((Start-_Joint1),_handAxis)/vlength(Start-_Joint1)) > 0 ) //If
finger has "snapped through" and is pointing the wrong way, fix it
   #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, -1);
//   #warning "Special Case\n"
  #end
     #declare LeftWristUp = __temp;
 #else
  //Compute _Joint1 position by finding intersection point of 2 spheres for
which
  // length in either the positive or negative LeftWristUp direction is a
maximum
  #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, 1);
  #if((vdot((Start-_Joint1),_handAxis)/vlength(Start-_Joint1)) > 0 ) //If
finger has "snapped through" and is pointing the wrong way, fix it
   #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, -1);
//   #warning "Inv1\n"
  #end
 //  #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, -1);
 // #end
 #end
// #warning concat( str(vdot(_Joint1, z),3,3),"\n")
// #warning concat( vstr(_Joint1/in,2,2),"\n")

// #warning concat( vstr(_handAxis/in,2,2),"\n")

// #warning concat( "Vector
",str(abs(vdot((End-_Joint1),_handAxis)/vlength(End-_Joint1)),3,3),"\n")

 #if((vdot((End-_Joint1),_handAxis)/vlength(End-_Joint1)) < 0 ) //If
fingertip position is closer to hand along axis of hand than joint1 is,
  #local _Joint2 = FindJoint(_Joint1,End,_Middle,_Tip,-1); //invert
LeftWristUp for computing Joint2 position
//  #warning "Inverted\n"
 #else
  #local _Joint2 = FindJoint(_Joint1,End,_Middle,_Tip,1); //otherwise,
calculate it normally
 #end

 //Build finger
 union{
  //Finger
  cylinder{Start, _Joint1, Thick texture{ArmTexture}}
  cylinder{_Joint1, _Joint2, Thick texture{ArmTexture}}
  cylinder{_Joint2, End, Thick texture{ArmTexture}}
  sphere{End, Thick texture{ArmTexture}}
  //Joints
  sphere{Start, Thick*1.1 texture{JointTexture}}
  sphere{_Joint1, Thick*1.1 texture{JointTexture}}
  sphere{_Joint2, Thick*1.1 texture{JointTexture}}
 }
#end


Post a reply to this message

From: Mark Hanford
Subject: Re: Learner IK problems... (dull illustrations, 9+1kbu)
Date: 15 Feb 2002 08:26:30
Message: <3c6d0c86@news.povray.org>
Thanks.   It'll probably take me a while to understand that lot though...

--

Mark Hanford
http://www.mrhanford.com/povray


"Mark Wagner" <mar### [at] gtenet> wrote in message
news:3c6cbfa7@news.povray.org...
> Mark Hanford wrote in message <3c6c36ae@news.povray.org>...
> >Dear gathered pro's...
>
> >I am trying to move the tip of Joint2 (blue) to the target.  The circle
is
> >an exagerated tollerance boudary, anywhere within this circle will be
> >alright (bailout).
>
> >Where I'm getting totally lost is when I'm trying to move two joints at
> >once, and I can't work out if I'm assuming something incorrectly about
the
> >tangent vector R or
> >what.    AAAaaaarrrgghhh....
>
> What I did for my entry in the IRTC "Robots" round was to approximate the
> section between Joint1 and the fingertip as a single segment of the
finger,
> using a formula to estimate the amount of bending of Joint2.  After
figuring
> out where Joint1 was, I used Joint1 as the base of a single-joint finger
to
> find out where exactly Joint2 would be.
>
>
>
> Just in case you're interested, here's the macro I used to create a single
> finger on my robot's left hand.  LeftWristUp is the "up" vector for the
back
> of the robot's left hand.
>
> //Helper macro for Finger -- returns the joint position given two fixed
> points and the lengths of the
> // segments between them, with a value to multiply LeftWristUp by
> #macro FindJoint(Start, End, R1, R2, Sign)
>  #local _d = vlength(Start-End); //Distance between spheres
>  #local _r = sqrt(-(_d+R2+R1)*(_d-R2+R1)*(_d+R2-R1)*(_d-R2-R1))/(2*_d);
> //Radius of circle of intersection
>  #local _q = ((_d*_d)+(R2*R2)-(R1*R1))/(2*_d);
>  #local _v = vnormalize(End-Start) * _q; //The position along the line
> between End and Start where the two spheres intersect.  This is also the
> direction from End to Start
>  #local _p = vcross(_v, (LeftWristUp-LeftWristPivot) * Sign); // Find the
> vector perpendicular to the line between Start and End and LeftWristUp
>  vnormalize(vcross(_p,_v)) * _r - _v + End //Find the vector perpendicular
> to the previous vector and the line.
>  // This is the absolute 3D space joint position
> #end
>
> // Creates a finger given a base point, a point for the tip, finger
> thickness, and finger length
> #macro Finger(Start, End, Length, Thick)
>  #warning "Start and End:\n"
>  #warning concat( Vstr(Start/in,2,2),"\n")
>  #warning concat( Vstr(End/in,2,2),"\n")
>  #local _Length = vlength(Start-End);
>  //Lengths of sections of finger
>  #local _Top = Length/2;
>  #local _Middle = Length/3;
>  #local _Tip = Length/6;
>  #warning concat(str(Length/in,4,4),", ",str(_Length/in,4,4),"\n")
>  //Approximate _Joint2 position from distance between Start and End
>  #local _J2Theta = acos(_Length/Length)/2;  //Angle formed by joint
>  #local _J2Length = _Tip*cos(_J2Theta)+_Middle*cos(_J2Theta); //Combined
> length of finger tip
> // #warning concat(str(_J2Theta,2,2),"\n")
>
>  #local _handAxis = LeftWristFinger - LeftWristPivot;
>     //Handle special case of Start-End being parallel to LeftWristUp
>     #if(vdot(vnormalize(LeftWristUp-LeftWristPivot),vnormalize(Start-End))
=
> 1)
>      #local __temp = LeftWristUp;
>      #declare LeftWristUp = LeftWristFinger;
>      #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, 1);
>   #if((vdot((Start-_Joint1),_handAxis)/vlength(Start-_Joint1)) > 0 ) //If
> finger has "snapped through" and is pointing the wrong way, fix it
>    #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, -1);
> //   #warning "Special Case\n"
>   #end
>      #declare LeftWristUp = __temp;
>  #else
>   //Compute _Joint1 position by finding intersection point of 2 spheres
for
> which
>   // length in either the positive or negative LeftWristUp direction is a
> maximum
>   #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, 1);
>   #if((vdot((Start-_Joint1),_handAxis)/vlength(Start-_Joint1)) > 0 ) //If
> finger has "snapped through" and is pointing the wrong way, fix it
>    #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, -1);
> //   #warning "Inv1\n"
>   #end
>  //  #local _Joint1 = FindJoint(Start, End, _Top, _J2Length, -1);
>  // #end
>  #end
> // #warning concat( str(vdot(_Joint1, z),3,3),"\n")
> // #warning concat( vstr(_Joint1/in,2,2),"\n")
>
> // #warning concat( vstr(_handAxis/in,2,2),"\n")
>
> // #warning concat( "Vector
> ",str(abs(vdot((End-_Joint1),_handAxis)/vlength(End-_Joint1)),3,3),"\n")
>
>  #if((vdot((End-_Joint1),_handAxis)/vlength(End-_Joint1)) < 0 ) //If
> fingertip position is closer to hand along axis of hand than joint1 is,
>   #local _Joint2 = FindJoint(_Joint1,End,_Middle,_Tip,-1); //invert
> LeftWristUp for computing Joint2 position
> //  #warning "Inverted\n"
>  #else
>   #local _Joint2 = FindJoint(_Joint1,End,_Middle,_Tip,1); //otherwise,
> calculate it normally
>  #end
>
>  //Build finger
>  union{
>   //Finger
>   cylinder{Start, _Joint1, Thick texture{ArmTexture}}
>   cylinder{_Joint1, _Joint2, Thick texture{ArmTexture}}
>   cylinder{_Joint2, End, Thick texture{ArmTexture}}
>   sphere{End, Thick texture{ArmTexture}}
>   //Joints
>   sphere{Start, Thick*1.1 texture{JointTexture}}
>   sphere{_Joint1, Thick*1.1 texture{JointTexture}}
>   sphere{_Joint2, Thick*1.1 texture{JointTexture}}
>  }
> #end
>
>
>


Post a reply to this message

From: Ben Birdsey
Subject: Re: Learner IK problems... (dull illustrations, 9+1kbu)
Date: 18 Feb 2002 03:16:20
Message: <3C70B9A0.3DEA73BE@mail.com>
Mark -

I just posted some code in your ptsf question.  I hope it helps.

- Ben


Post a reply to this message

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