POV-Ray : Newsgroups : povray.binaries.images : Learner IK problems... (dull illustrations, 9+1kbu) : Re: Learner IK problems... (dull illustrations, 9+1kbu) Server Time
16 Aug 2024 10:26:18 EDT (-0400)
  Re: Learner IK problems... (dull illustrations, 9+1kbu)  
From: Mark Wagner
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

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