Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

HeadPointerMC.cc

Go to the documentation of this file.
00001 #include <math.h>
00002 
00003 #include "HeadPointerMC.h"
00004 #include "Kinematics.h"
00005 #include "Shared/debuget.h"
00006 #include "Shared/WorldState.h"
00007 #include "MotionManager.h"
00008 #include "Shared/Config.h"
00009 #include "Wireless/Socket.h"
00010 
00011 HeadPointerMC::HeadPointerMC()
00012   : MotionCommand(), dirty(true), hold(true), tolerance(.05),
00013     targetReached(true), targetTimestamp(0), timeout(2000), 
00014     headkin(::config->motion.makePath(::config->motion.kinematics),"Camera")
00015 {
00016   setWeight(1);
00017   defaultMaxSpeed();
00018   takeSnapshot();
00019 }
00020 
00021 void HeadPointerMC::freezeMotion() {
00022   for(unsigned int i=0; i<NumHeadJoints; i++)
00023     headTargets[i]=headCmds[i].value;
00024   dirty=false;
00025 }
00026 
00027 void HeadPointerMC::takeSnapshot() {
00028   for(unsigned int i=0; i<NumHeadJoints; i++)
00029     headTargets[i]=headCmds[i].value=state->outputs[HeadOffset+i];
00030   dirty=true;
00031 }
00032 
00033 void HeadPointerMC::defaultMaxSpeed(float x/*=1*/) {
00034   maxSpeed[TiltOffset]=config->motion.max_head_tilt_speed*FrameTime*x/1000;
00035   maxSpeed[PanOffset]=config->motion.max_head_pan_speed*FrameTime*x/1000;
00036   maxSpeed[RollOffset]=config->motion.max_head_roll_speed*FrameTime*x/1000;
00037 }
00038 
00039 void HeadPointerMC::setWeight(float w) {
00040   for(unsigned int x=0; x<NumHeadJoints; x++)
00041     headCmds[x].weight=w;
00042   markDirty();
00043 }
00044 
00045 void HeadPointerMC::setJoints(float j1, float j2, float j3) {
00046   headTargets[TiltOffset]=clipAngularRange(HeadOffset+TiltOffset,j1);
00047   headTargets[PanOffset]=clipAngularRange(HeadOffset+PanOffset,j2);
00048   headTargets[RollOffset]=clipAngularRange(HeadOffset+RollOffset,j3);
00049   markDirty();
00050 }
00051 
00052 bool HeadPointerMC::lookAtPoint(float x, float y, float z) {
00053   NEWMAT::ColumnVector Pobj(4),Plink(4);
00054   Pobj(1)=x; Pobj(2)=y; Pobj(3)=z; Pobj(4)=1;
00055   Plink=0; Plink(3)=1;
00056   bool conv=false;
00057   NEWMAT::ColumnVector q=headkin.inv_kin_pos(Pobj,0,headkin.get_dof(),Plink,conv);
00058 
00059   NEWMAT::ColumnVector poE=headkin.convertLink(0,headkin.get_dof())*Pobj;
00060   poE=poE.SubMatrix(1,3,1,1);
00061   //  float theta = acos(poE(3)/sqrt(poE(1)*poE(1)+poE(2)*poE(2)+poE(3)*poE(3)));
00062   //  cout << "Computed:\n theta1: " << mathutils::rad2deg(theta) << " degrees\n";
00063   NEWMAT::ColumnVector plE=Plink.SubMatrix(1,3,1,1);
00064   float plE2=plE.SumSquare();
00065   float plE_len=sqrt(plE2);
00066   float obj_comp_link=NEWMAT::DotProduct(plE,poE)/plE_len;
00067   if(obj_comp_link<plE_len)
00068     obj_comp_link=obj_comp_link*.975; //.975 is a bit of fudge - accounts for joints moving Plink when adjusting
00069   else
00070     obj_comp_link=obj_comp_link/.975; //.975 is a bit of fudge - accounts for joints moving Plink when adjusting
00071   NEWMAT::ColumnVector obj_proj_link(4);
00072   obj_proj_link.SubMatrix(1,3,1,1)=obj_comp_link*plE/plE_len;
00073   obj_proj_link(4)=1;
00074   q=headkin.inv_kin_pos(Pobj,0,headkin.get_dof(),obj_proj_link,conv);
00075 
00076   for(unsigned int i=0; i<NumHeadJoints; i++)
00077     setJointValue(i,headkin.get_q(2+i));
00078 
00079   //  NEWMAT::ColumnVector poE2=headkin.convertLink(0,headkin.get_dof())*Pobj;
00080   //  float theta2 = acos(poE2(3)/sqrt(poE2(1)*poE2(1)+poE2(2)*poE2(2)+poE2(3)*poE2(3)));
00081   //  cout << " theta2: " << mathutils::rad2deg(theta2) << " degrees\n";
00082   return isReachable(Pobj);
00083 }
00084   
00085 bool HeadPointerMC::lookAtPoint(float x, float y, float z, float d) {
00086   NEWMAT::ColumnVector Pobj(4),Plink(4);
00087   Pobj(1)=x; Pobj(2)=y; Pobj(3)=z; Pobj(4)=1;
00088   Plink=0; Plink(3)=d; Plink(4)=1;
00089   bool conv=false;
00090   NEWMAT::ColumnVector q=headkin.inv_kin_pos(Pobj,0,headkin.get_dof(),Plink,conv);
00091   for(unsigned int i=0; i<NumHeadJoints; i++)
00092     setJointValue(i,headkin.get_q(2+i));
00093   //  return conv;
00094   return isReachable(Pobj);
00095 }
00096   
00097 bool HeadPointerMC::lookInDirection(float x, float y, float z) {
00098   NEWMAT::ColumnVector Pobj(4),Plink(4);
00099   Pobj(1)=x; Pobj(2)=y; Pobj(3)=z; Pobj(4)=0;
00100   Plink=0; Plink(3)=1;
00101   bool conv=false;
00102   NEWMAT::ColumnVector q=headkin.inv_kin_pos(Pobj,0,headkin.get_dof(),Plink,conv);
00103   for(unsigned int i=0; i<NumHeadJoints; i++)
00104     setJointValue(i,headkin.get_q(2+i));
00105   //  return conv;
00106   return isReachable(Pobj);
00107 }
00108 
00109 
00110 int HeadPointerMC::updateOutputs() {
00111   int tmp=isDirty();
00112   if(tmp || hold) {
00113     dirty=false;
00114     for(unsigned int i=0; i<NumHeadJoints; i++) {
00115       if(maxSpeed[i]<=0) {
00116         headCmds[i].value=headTargets[i];
00117         motman->setOutput(this,i+HeadOffset,headCmds[i]);
00118       } else { // we may be trying to exceeded maxSpeed
00119         unsigned int f=0;
00120         while(headTargets[i]>headCmds[i].value+maxSpeed[i] && f<NumFrames) {
00121           headCmds[i].value+=maxSpeed[i];
00122           motman->setOutput(this,i+HeadOffset,headCmds[i],f);
00123           f++;
00124         }
00125         while(headTargets[i]<headCmds[i].value-maxSpeed[i] && f<NumFrames) {
00126           headCmds[i].value-=maxSpeed[i];
00127           motman->setOutput(this,i+HeadOffset,headCmds[i],f);
00128           f++;
00129         }
00130         if(f<NumFrames) { //we reached target value, fill in rest of frames
00131           headCmds[i].value=headTargets[i];
00132           for(;f<NumFrames;f++)
00133             motman->setOutput(this,i+HeadOffset,headCmds[i],f);
00134         } else // we didn't reach target value, still dirty
00135           dirty=true;
00136       }
00137     }
00138     if(!dirty && !targetReached) {
00139       postEvent(EventBase(EventBase::motmanEGID,getID(),EventBase::statusETID));
00140       targetReached=true;
00141       targetTimestamp=get_time();
00142     }
00143   }
00144   return tmp;
00145 }
00146 
00147 int HeadPointerMC::isAlive() {
00148   if(dirty || !targetReached)
00149     return true;
00150   if(targetReached && (!hold || get_time()-targetTimestamp>timeout)) { //prevents a conflicted HeadPointerMC's from fighting forever
00151     if(get_time()-targetTimestamp>timeout && getAutoPrune())
00152       serr->printf("WARNING: HeadPointerMC (mcid %d) timed out - possible joint conflict or out-of-range target\n",getID());
00153     return false;
00154   }
00155   float maxdiff=0;
00156   for(unsigned int i=0; i<NumHeadJoints; i++) {
00157     float diff=fabsf(state->outputs[HeadOffset+i]-headTargets[i]);
00158     if(diff>maxdiff)
00159       maxdiff=diff;
00160   }
00161   return (maxdiff>tolerance);
00162 }
00163 
00164 void HeadPointerMC::markDirty() {
00165   dirty=true;
00166   targetReached=false;
00167   for(unsigned int i=0; i<NumHeadJoints; i++)
00168     headCmds[i].value=motman->getOutputCmd(HeadOffset+i).value; //not state->outputs[HeadOffset+i]; - see function documentation
00169 }
00170 
00171 bool HeadPointerMC::ensureValidJoint(unsigned int& i) {
00172   if(i<NumHeadJoints)
00173     return true;
00174   if(i>=HeadOffset && i<HeadOffset+NumHeadJoints) {
00175     i-=HeadOffset;
00176     serr->printf("WARNING: HeadPointerMC received a joint index of %d (HeadOffset+%d).\n",i+HeadOffset,i);
00177     serr->printf("         Since all parameters are assumed to be relative to HeadOffset,\n");
00178     serr->printf("         you should just pass %d directly.\n",i);
00179     serr->printf("WARNING: Assuming you meant %d...\n",i);
00180     return true;
00181   }
00182   serr->printf("ERROR: HeadPointerMC received a joint index of %d (HeadOffset%+d).\n",i,i-HeadOffset);
00183   serr->printf("ERROR: This does not appear to be a head joint.  HeadPointerMC only controls\n");
00184   serr->printf("       head joints, and assumes its arguments are relative to HeadOffset\n");
00185   return false;
00186 }
00187 
00188 /*! @file
00189  * @brief Implements HeadPointerMC, a class for various ways to control where the head is looking
00190  * @author ejt (Creator)
00191  *
00192  * $Author: ejt $
00193  * $Name: tekkotsu-3_0 $
00194  * $Revision: 1.25 $
00195  * $State: Exp $
00196  * $Date: 2006/08/31 21:42:02 $
00197  */
00198 
00199 

Tekkotsu v3.0
Generated Wed Oct 4 00:03:43 2006 by Doxygen 1.4.7