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