arm-cp.C

00001 /*! @file ArmControl/train-cp.C  Test Ijspeert et.al cps */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Lior Elazary <elazary@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ArmControl/arm-cp.C $
00035 // $Id: arm-cp.C 10794 2009-02-08 06:21:09Z itti $
00036 //
00037 
00038 
00039 #include "Component/ModelManager.H"
00040 #include "Image/Image.H"
00041 #include "Image/Transforms.H"
00042 #include "Image/DrawOps.H"
00043 #include "Image/Rectangle.H"
00044 #include "Image/MathOps.H"
00045 #include "Image/MatrixOps.H"
00046 #include "Image/Layout.H"
00047 #include "Media/FrameSeries.H"
00048 #include "Transport/FrameInfo.H"
00049 #include "Raster/GenericFrame.H"
00050 #include "Raster/Raster.H"
00051 #include "Neuro/BeoHeadBrain.H"
00052 #include "Util/Timer.H"
00053 #include "GUI/GeneralGUI.H"
00054 #include "GUI/ImageDisplayStream.H"
00055 #include "GUI/DebugWin.H"
00056 #include "GUI/XWinManaged.H"
00057 #include "RCBot/Motion/MotionEnergy.H"
00058 #include "ArmControl/ArmSim.H"
00059 #include "ArmControl/RobotArm.H"
00060 #include "ArmControl/ArmController.H"
00061 #include "Devices/DeviceOpts.H"
00062 #include "Util/MathFunctions.H"
00063 #include <unistd.h>
00064 #include <stdio.h>
00065 #include <signal.h>
00066 
00067 #define USE_EXPAT
00068 #include <lwpr/lwpr.h>
00069 #include <lwpr/lwpr_xml.h>
00070 
00071 
00072 ModelManager *mgr;
00073 nub::soft_ref<ArmSim> armSim;
00074 nub::soft_ref<ArmController> armControllerArmSim;
00075 
00076 //generate a random target location
00077 void getTargetPos(double* desiredPos)
00078 {
00079   desiredPos[0] = -1.214/2+0.145 + randomDouble()*0.20;
00080   desiredPos[1] = -0.75/2+0.12 + randomDouble()*0.20;
00081   desiredPos[2] = 0.05; //0.60207 + randomDouble()*0.10;
00082 
00083   LDEBUG("New target: %0.2f %0.2f %0.2f",
00084       desiredPos[0],
00085       desiredPos[1],
00086       desiredPos[2]);
00087 
00088 }
00089 
00090 //Predict the joint angle required for this position
00091 ArmController::JointPos getIK(LWPR_Model& ik_model, const double* desiredPos)
00092 {
00093   double joints[5];
00094   lwpr_predict(&ik_model, desiredPos, 0.001, joints, NULL, NULL);
00095 
00096   ArmController::JointPos jointPos;
00097 
00098   jointPos.base = (int)joints[0];
00099   jointPos.sholder = (int)joints[1];
00100   jointPos.elbow = (int)joints[2];
00101   jointPos.wrist1 = (int)joints[3];
00102   jointPos.wrist2 = (int)joints[4];
00103   jointPos.gripper = 0;
00104 
00105   LDEBUG("Mapping %0.2f %0.2f %0.2f => %i %i %i %i %i",
00106       desiredPos[0], desiredPos[1], desiredPos[2],
00107       jointPos.base, jointPos.sholder, jointPos.elbow,
00108       jointPos.wrist1, jointPos.wrist2);
00109   return jointPos;
00110 }
00111 
00112 double getDistance(const double* pos, const double* desiredPos)
00113 {
00114   double sum=0;
00115   for(int i=0; i<3; i++)
00116     sum += (pos[i]-desiredPos[i])*(pos[i]-desiredPos[i]);
00117   return sqrt(sum);
00118 
00119 }
00120 
00121 
00122 void trainArm(LWPR_Model& ik_model, const double* armPos, const ArmController::JointPos& jointPos)
00123 {
00124 
00125   double joints[5];
00126   double pJoints[5];
00127   LDEBUG("Training => %0.2f,%0.2f,%0.2f => %i %i %i %i %i",
00128       armPos[0], armPos[1], armPos[2],
00129       jointPos.base, jointPos.sholder, jointPos.elbow,
00130       jointPos.wrist1, jointPos.wrist2);
00131 
00132   joints[0] = jointPos.base;
00133   joints[1] = jointPos.sholder;
00134   joints[2] = jointPos.elbow;
00135   joints[3] = jointPos.wrist1;
00136   joints[4] = jointPos.wrist2;
00137 
00138   lwpr_update(&ik_model, armPos, joints, pJoints, NULL);
00139 
00140 }
00141 
00142 ArmController::JointPos calcGradient(const double* desiredPos)
00143 {
00144 
00145   ArmController::JointPos jointPos = armControllerArmSim->getJointPos();
00146   ArmController::JointPos tmpJointPos = jointPos;
00147 
00148   double dist1, dist2;
00149   double baseGrad, sholderGrad, elbowGrad;
00150   double err = getDistance(armSim->getEndPos(), desiredPos);
00151 
00152   //get the base gradient
00153   tmpJointPos.base = jointPos.base + 100;
00154   armControllerArmSim->setJointPos(tmpJointPos);
00155   dist1 = getDistance(armSim->getEndPos(), desiredPos);
00156 
00157   tmpJointPos.base = jointPos.base - 100;
00158   armControllerArmSim->setJointPos(tmpJointPos);
00159   dist2 = getDistance(armSim->getEndPos(), desiredPos);
00160   baseGrad = dist1 - dist2;
00161   tmpJointPos.base = jointPos.base;
00162 
00163   //get the base gradient
00164   tmpJointPos.sholder = jointPos.sholder + 100;
00165   armControllerArmSim->setJointPos(tmpJointPos);
00166   dist1 = getDistance(armSim->getEndPos(), desiredPos);
00167   tmpJointPos.sholder = jointPos.sholder - 100;
00168   armControllerArmSim->setJointPos(tmpJointPos);
00169   dist2 = getDistance(armSim->getEndPos(), desiredPos);
00170   sholderGrad = dist1 - dist2;
00171   tmpJointPos.sholder = jointPos.sholder;
00172 
00173   //get the elbow gradient
00174   tmpJointPos.elbow = jointPos.elbow + 100;
00175   armControllerArmSim->setJointPos(tmpJointPos);
00176   dist1 = getDistance(armSim->getEndPos(), desiredPos);
00177   tmpJointPos.elbow = jointPos.elbow - 100;
00178   armControllerArmSim->setJointPos(tmpJointPos);
00179   dist2 = getDistance(armSim->getEndPos(), desiredPos);
00180   elbowGrad = dist1 - dist2;
00181   tmpJointPos.elbow = jointPos.elbow;
00182 
00183   int moveThresh = (int)(err*100000);
00184   jointPos.base -= (int)(randomUpToIncluding(moveThresh)*baseGrad);
00185   jointPos.sholder -= (int)(randomUpToIncluding(moveThresh)*sholderGrad);
00186   jointPos.elbow -= (int)(randomUpToIncluding(moveThresh)*elbowGrad);
00187 
00188   return jointPos;
00189 }
00190 
00191 
00192 //! Signal handler (e.g., for control-C)
00193 void terminate(int s)
00194 {
00195         LERROR("*** INTERRUPT ***");
00196         exit(0);
00197 }
00198 
00199 Point2D<int> getClick(nub::soft_ref<OutputFrameSeries> &ofs)
00200 {
00201   const nub::soft_ref<ImageDisplayStream> ids =
00202     ofs->findFrameDestType<ImageDisplayStream>();
00203 
00204   const rutz::shared_ptr<XWinManaged> uiwin =
00205     ids.is_valid()
00206     ? ids->getWindow("Output")
00207     : rutz::shared_ptr<XWinManaged>();
00208   return uiwin->getLastMouseClick();
00209 }
00210 
00211 
00212 int getKey(nub::soft_ref<OutputFrameSeries> &ofs)
00213 {
00214   const nub::soft_ref<ImageDisplayStream> ids =
00215     ofs->findFrameDestType<ImageDisplayStream>();
00216 
00217   const rutz::shared_ptr<XWinManaged> uiwin =
00218     ids.is_valid()
00219     ? ids->getWindow("Output")
00220     : rutz::shared_ptr<XWinManaged>();
00221   return uiwin->getLastKeyPress();
00222 }
00223 
00224 void updateDataImg(Image<PixRGB<byte> > &img, ArmController::JointPos &jointPos)
00225 {
00226   static int x = 0;
00227 
00228   if (x < img.getWidth())
00229   {
00230     if (!x)
00231       img.clear();
00232 
00233     int basePos = (int)(-1.0*((float)jointPos.base/2000.0F)*256.0F);
00234     //drawCircle(img,Point2D<int>(x,basePos), 2, PixRGB<byte>(255,0,0));
00235     img.setVal(x,basePos, PixRGB<byte>(255,0,0));
00236 
00237     x++; // = (x+1)%img.getWidth();
00238   }
00239 
00240 }
00241 
00242 int main(const int argc, const char **argv)
00243 {
00244   MYLOGVERB = LOG_INFO;
00245   LWPR_Model ik_model;
00246 
00247   initRandomNumbers();
00248   mgr = new ModelManager("Test ObjRec");
00249   armSim = nub::soft_ref<ArmSim>(new ArmSim(*mgr));
00250   armControllerArmSim = nub::soft_ref<ArmController>(new ArmController(*mgr,
00251         "ArmControllerArmSim", "ArmControllerArmSim", armSim));
00252   mgr->addSubComponent(armControllerArmSim);
00253 
00254   nub::soft_ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr));
00255   mgr->addSubComponent(ofs);
00256 
00257   nub::soft_ref<GeneralGUI> armSimGUI(new GeneralGUI(*mgr));
00258   mgr->addSubComponent(armSimGUI);
00259 
00260   mgr->exportOptions(MC_RECURSE);
00261 
00262   if (mgr->parseCommandLine(
00263         (const int)argc, (const char**)argv, "", 0, 0) == false)
00264     return 1;
00265   // catch signals and redirect them to terminate for clean exit:
00266   signal(SIGHUP, terminate); signal(SIGINT, terminate);
00267   signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00268   signal(SIGALRM, terminate);
00269 
00270 
00271   ////INit the lwpr model
00272   //lwpr_init_model(&ik_model,3,5,"Arm_IK");
00273 
00274   ///* Set initial distance metric to 50*(identity matrix) */
00275   //lwpr_set_init_D_spherical(&ik_model,50);
00276 
00277   ///* Set init_alpha to 250 in all elements */
00278   //lwpr_set_init_alpha(&ik_model,250);
00279 
00280   ///* Set w_gen to 0.2 */
00281   //ik_model.w_gen = 0.2;
00282 
00283   int numWarnings = 0;
00284   lwpr_read_xml(&ik_model, "ik_model.xml", &numWarnings);
00285 
00286   mgr->start();
00287 
00288   initRandomNumbers();
00289 
00290   Image<PixRGB<byte> > dataImg(512, 256, ZEROS);
00291 
00292   armSimGUI->startThread(ofs);
00293 
00294   armSimGUI->addImage(&dataImg);
00295 
00296 
00297 
00298   armControllerArmSim->setMotorsOn(true);
00299   armControllerArmSim->setPidOn(true);
00300 
00301   //set The min-max joint pos
00302   ArmController::JointPos jointPos;
00303   jointPos.base = 3000;
00304   jointPos.sholder = 3000;
00305   jointPos.elbow = 2000;
00306   jointPos.wrist1 = 0;
00307   jointPos.wrist2 = 0;
00308   armControllerArmSim->setMaxJointPos(jointPos);
00309 
00310   jointPos.base = -8000;
00311   jointPos.sholder = -1500;
00312   jointPos.elbow = -3000;
00313   jointPos.wrist1 = 0;
00314   jointPos.wrist2 = 0;
00315   armControllerArmSim->setMinJointPos(jointPos);
00316 
00317 
00318   //Move the arm to 0 pos
00319   jointPos.base = 0;
00320   jointPos.sholder = 0;
00321   jointPos.elbow = 0;
00322   jointPos.wrist1 = 0;
00323   jointPos.wrist2 = 0;
00324   jointPos.gripper = 0;
00325   armControllerArmSim->setJointPos(jointPos);
00326 
00327   float dt=.01;
00328   //float alpha_x=8; // canonical alpha
00329   //float beta_x=0.5; // canonical beta
00330   float alpha_z=8; // transformation alpha
00331   float beta_z=4;  // transformation beta
00332   float y=0; // position
00333   float y_vel=0; // velocity
00334   float goal=0;
00335   //float x=0, x_0=0; //canonical system
00336   //float x_vel=0; // canonical system velocity
00337   //float x_acc=0; // canonical system acceleration
00338   float z=0; // transformation system
00339   float z_vel=0; // transformation system velocity
00340 
00341   getchar();
00342   goal = -1000;
00343   //x_0 = x;
00344   while(1)
00345   {
00346     armSim->simLoop();
00347     Image<PixRGB<byte> > armCam = flipVertic(armSim->getFrame(-1));
00348 
00349     //x_acc = alpha_x*(beta_x*(goal-x)-x_vel);
00350     //x_vel += dt*x_acc;
00351     //x += dt*x_vel;
00352 
00353     z_vel = alpha_z*(beta_z*(goal-y)-z);
00354     z+= dt*z_vel;
00355 
00356     //float x_tilde=(x-x_0)/(goal-x_0);
00357     float f = 0;
00358     y_vel= z+f;
00359     y+= dt*y_vel;
00360 
00361     jointPos.base = (int)y;
00362     armControllerArmSim->setJointPos(jointPos, false);
00363     ArmController::JointPos currentJointPos = armControllerArmSim->getJointPos();
00364     updateDataImg(dataImg, currentJointPos);
00365 
00366     ofs->writeRGB(armCam, "Output", FrameInfo("Output", SRC_POS));
00367   }
00368   mgr->stop();
00369 
00370   return 0;
00371 
00372 }
00373 
Generated on Sun May 8 08:40:11 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3