00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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;
00082
00083 LDEBUG("New target: %0.2f %0.2f %0.2f",
00084 desiredPos[0],
00085 desiredPos[1],
00086 desiredPos[2]);
00087
00088 }
00089
00090
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
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
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
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
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 int main(const int argc, const char **argv)
00225 {
00226 MYLOGVERB = LOG_INFO;
00227 LWPR_Model ik_model;
00228
00229 initRandomNumbers();
00230 mgr = new ModelManager("Test ObjRec");
00231 armSim = nub::soft_ref<ArmSim>(new ArmSim(*mgr));
00232 armControllerArmSim = nub::soft_ref<ArmController>(new ArmController(*mgr,
00233 "ArmControllerArmSim", "ArmControllerArmSim", armSim));
00234 mgr->addSubComponent(armControllerArmSim);
00235
00236 nub::soft_ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr));
00237 mgr->addSubComponent(ofs);
00238
00239 nub::soft_ref<GeneralGUI> armSimGUI(new GeneralGUI(*mgr));
00240 mgr->addSubComponent(armSimGUI);
00241
00242 mgr->exportOptions(MC_RECURSE);
00243
00244 if (mgr->parseCommandLine(
00245 (const int)argc, (const char**)argv, "", 0, 0) == false)
00246 return 1;
00247
00248 signal(SIGHUP, terminate); signal(SIGINT, terminate);
00249 signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00250 signal(SIGALRM, terminate);
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 int numWarnings = 0;
00266 lwpr_read_xml(&ik_model, "ik_model.xml", &numWarnings);
00267
00268 mgr->start();
00269
00270 initRandomNumbers();
00271
00272 armControllerArmSim->setMotorsOn(true);
00273 armControllerArmSim->setPidOn(true);
00274
00275
00276 ArmController::JointPos jointPos;
00277 jointPos.base = 3000;
00278 jointPos.sholder = 3000;
00279 jointPos.elbow = 2000;
00280 jointPos.wrist1 = 0;
00281 jointPos.wrist2 = 0;
00282 armControllerArmSim->setMaxJointPos(jointPos);
00283
00284 jointPos.base = -8000;
00285 jointPos.sholder = -1500;
00286 jointPos.elbow = -3000;
00287 jointPos.wrist1 = 0;
00288 jointPos.wrist2 = 0;
00289 armControllerArmSim->setMinJointPos(jointPos);
00290
00291
00292
00293 jointPos.base = 0;
00294 jointPos.sholder = 0;
00295 jointPos.elbow = 0;
00296 jointPos.wrist1 = 0;
00297 jointPos.wrist2 = 0;
00298 jointPos.gripper = 0;
00299 armControllerArmSim->setJointPos(jointPos);
00300
00301 bool reachComplete = true;
00302 int numReaches = 0;
00303 int numTries = 0;
00304 double desiredPos[3] = {0,0,0.4};
00305 while(1)
00306 {
00307 armSim->simLoop();
00308 Image<PixRGB<byte> > armCam = flipVertic(armSim->getFrame(-1));
00309
00310 ofs->writeRGB(armCam, "Output", FrameInfo("Output", SRC_POS));
00311
00312
00313
00314 {
00315 Point2D<int> clickLoc = getClick(ofs);
00316 if (clickLoc.isValid())
00317 {
00318
00319 armSim->getObjLoc(clickLoc.i, clickLoc.j, desiredPos);
00320 reachComplete = false;
00321 numTries = 0;
00322
00323
00324 ArmController::JointPos jointPos = getIK(ik_model, desiredPos);
00325
00326
00327 armControllerArmSim->setJointPos(jointPos);
00328 }
00329 }
00330
00331 numTries++;
00332
00333
00334 double *armPos = armSim->getEndPos();
00335 LDEBUG("Pos %f %f %f", armPos[0], armPos[1], armPos[2]);
00336
00337
00338 double err = getDistance(armPos, desiredPos);
00339 if (!reachComplete)
00340 LINFO("Err %f tries %i: reaches=%i", err, numTries, numReaches);
00341
00342 if (err > 0.01)
00343 {
00344
00345 jointPos = calcGradient(desiredPos);
00346
00347 armControllerArmSim->setJointPos(jointPos);
00348
00349 jointPos = armControllerArmSim->getJointPos();
00350 armPos = armSim->getEndPos();
00351
00352 trainArm(ik_model, armPos, jointPos);
00353 } else {
00354 reachComplete = true;
00355 numReaches++;
00356
00357
00358 }
00359
00360 }
00361 mgr->stop();
00362
00363 return 0;
00364
00365 }
00366