Libbarrett  1.2.4
include/barrett/systems/haptic_path.h
00001 /*
00002         Copyright 2012 Barrett Technology <support@barrett.com>
00003 
00004         This file is part of libbarrett.
00005 
00006         This version of libbarrett is free software: you can redistribute it
00007         and/or modify it under the terms of the GNU General Public License as
00008         published by the Free Software Foundation, either version 3 of the
00009         License, or (at your option) any later version.
00010 
00011         This version of libbarrett is distributed in the hope that it will be
00012         useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License along
00017         with this version of libbarrett.  If not, see
00018         <http://www.gnu.org/licenses/>.
00019 
00020         Further, non-binding information about licensing is available at:
00021         <http://wiki.barrett.com/libbarrett/wiki/LicenseNotes>
00022 */
00023 
00024 /*
00025  * haptic_path.h
00026  *
00027  *  Created on: Jun 21, 2012
00028  *      Author: dc
00029  */
00030 
00031 #ifndef BARRETT_SYSTEMS_HAPTIC_PATH_H_
00032 #define BARRETT_SYSTEMS_HAPTIC_PATH_H_
00033 
00034 
00035 #include <cmath>
00036 #include <cassert>
00037 #include <vector>
00038 
00039 #include <Eigen/Core>
00040 
00041 #include <barrett/detail/ca_macro.h>
00042 #include <barrett/units.h>
00043 #include <barrett/math.h>
00044 #include <barrett/systems/abstract/haptic_object.h>
00045 
00046 
00047 namespace barrett {
00048 namespace systems {
00049 
00050 
00051 class HapticPath : public HapticObject {
00052         BARRETT_UNITS_FIXED_SIZE_TYPEDEFS;
00053 
00054         static const double COARSE_STEP = 0.01;
00055         static const double FINE_STEP = 0.0001;
00056 
00057 public:         System::Output<cp_type> tangentDirectionOutput;
00058 protected:      System::Output<cp_type>::Value* tangentDirectionOutputValue;
00059 
00060 public:
00061         HapticPath(const std::vector<cp_type>& path,
00062                         const std::string& sysName = "HapticPath") :
00063                 HapticObject(sysName),
00064                 tangentDirectionOutput(this, &tangentDirectionOutputValue),
00065                 nearestIndex(0), spline(NULL)
00066         {
00067                 // Sample the path
00068                 cp_type prev = path[0];
00069                 for (size_t i = 0; i < path.size(); ++i) {
00070                         if ((path[i] - prev).norm() > COARSE_STEP) {
00071                                 coarsePath.push_back(path[i]);
00072                                 prev = path[i];
00073                         }
00074                 }
00075                 spline = new math::Spline<cp_type>(coarsePath);
00076         }
00077 
00078         virtual ~HapticPath() {
00079                 mandatoryCleanUp();
00080                 delete spline;
00081         }
00082 
00083 protected:
00084         virtual void operate() {
00085                 const cp_type& cp = input.getValue();
00086 
00087                 // Coarse search
00088                 minDist = (coarsePath[nearestIndex] - cp).norm();
00089                 for (size_t i = 0; i < coarsePath.size(); ++i) {
00090                         double dist = (coarsePath[i] - cp).norm();
00091                         if (dist < minDist) {
00092                                 minDist = dist;
00093                                 nearestIndex = i;
00094                         }
00095                 }
00096 
00097                 // Fine search
00098                 // TODO(dc): Can we do this without relying on Spline's implementation?
00099                 double sNearest = spline->getImplementation()->ss[nearestIndex];
00100                 double sLow = sNearest - COARSE_STEP;
00101                 double sHigh = sNearest + COARSE_STEP;
00102                 for (double s = sLow; s <= sHigh; s += FINE_STEP) {
00103                         double dist = (spline->eval(s) - cp).norm();
00104                         if (dist < minDist) {
00105                                 minDist = dist;
00106                                 sNearest = s;
00107                         }
00108                 }
00109 
00110                 dir = (spline->eval(sNearest) - cp).normalized();
00111                 tangentDir = spline->evalDerivative(sNearest).normalized();
00112 
00113                 depthOutputValue->setData(&minDist);
00114                 directionOutputValue->setData(&dir);
00115                 tangentDirectionOutputValue->setData(&tangentDir);
00116         }
00117 
00118         double minDist;
00119         size_t nearestIndex;
00120         cf_type dir;
00121         cp_type tangentDir;
00122 
00123         std::vector<cp_type> coarsePath;
00124         math::Spline<cp_type>* spline;
00125 
00126 private:
00127         DISALLOW_COPY_AND_ASSIGN(HapticPath);
00128 
00129 public:
00130         EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00131 };
00132 
00133 
00134 }
00135 }
00136 
00137 
00138 #endif /* BARRETT_SYSTEMS_HAPTIC_PATH_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Defines