Libbarrett  1.2.4
include/barrett/systems/tool_orientation_controller.h
00001 /*
00002         Copyright 2009, 2010 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  * tool_orientation_controller.h
00026  *
00027  *  Created on: Jan 22, 2010
00028  *      Author: dc
00029  */
00030 
00031 #ifndef BARRETT_SYSTEMS_TOOL_ORIENTATION_CONTROLLER_H_
00032 #define BARRETT_SYSTEMS_TOOL_ORIENTATION_CONTROLLER_H_
00033 
00034 
00035 #include <libconfig.h++>
00036 #include <Eigen/Geometry>
00037 #include <gsl/gsl_blas.h>
00038 
00039 #include <barrett/detail/ca_macro.h>
00040 #include <barrett/detail/libconfig_utils.h>
00041 #include <barrett/math/utils.h>
00042 #include <barrett/units.h>
00043 #include <barrett/systems/abstract/controller.h>
00044 #include <barrett/systems/kinematics_base.h>
00045 
00046 
00047 namespace barrett {
00048 namespace systems {
00049 
00050 
00051 template<size_t DOF>
00052 class ToolOrientationController : public Controller<Eigen::Quaterniond,
00053                                                                                                         units::CartesianTorque::type>,
00054                                                                   public KinematicsInput<DOF> {
00055 
00056         BARRETT_UNITS_TEMPLATE_TYPEDEFS(DOF);
00057 
00058 public:
00059         explicit ToolOrientationController(const std::string& sysName = "ToolOrientationController") :
00060                 Controller<Eigen::Quaterniond, ct_type>(sysName), KinematicsInput<DOF>(this),
00061                 kp(0.0), kd(0.0) {}
00062         explicit ToolOrientationController(const libconfig::Setting& setting,
00063                         const std::string& sysName = "ToolOrientationController") :
00064                 Controller<Eigen::Quaterniond, ct_type>(sysName), KinematicsInput<DOF>(this),
00065                 kp(0.0), kd(0.0)
00066         {
00067                 setFromConfig(setting);
00068         }
00069         virtual ~ToolOrientationController() { mandatoryCleanUp(); }
00070 
00071 
00072         void setFromConfig(const libconfig::Setting& setting) {
00073                 setKp(barrett::detail::numericToDouble(setting["kp"]));
00074                 setKd(barrett::detail::numericToDouble(setting["kd"]));
00075         }
00076         void setKp(double proportionalGain) { kp = proportionalGain; }
00077         void setKd(double derivitiveGain) { kd = derivitiveGain; }
00078 
00079         double getKp() const { return kp; }
00080         double getKd() const { return kd; }
00081 
00082 protected:
00083         double kp;
00084         double kd;
00085 
00086         Eigen::AngleAxisd error;
00087         ct_type ct;
00088 
00089         virtual void operate() {
00090 //              error = this->referenceInput.getValue() * this->feedbackInput.getValue().inverse();  // I think it should be this way
00091                 error = this->feedbackInput.getValue() * this->referenceInput.getValue().inverse();  // but CD's math (that works, BTW) does it this way
00092 
00093                 double angle = error.angle();
00094                 // TODO(dc): I looked into Eigen's implementation and noticed that angle will always be between 0 and 2*pi. We should test for this so if Eigen changes, we notice.
00095                 if (angle > M_PI) {
00096                         angle -= 2.0*M_PI;
00097                 }
00098 
00099                 if (math::abs(angle) > 3.13) {  // a little dead-zone near the discontinuity at +/-180 degrees
00100                         ct.setZero();
00101                 } else {
00102                         ct = this->referenceInput.getValue().inverse() * (error.axis() * angle * kp);
00103                 }
00104 
00105                 gsl_blas_daxpy( -kd, this->kinInput.getValue().impl->tool_velocity_angular, ct.asGslType());
00106 
00107                 this->controlOutputValue->setData(&ct);
00108         }
00109 
00110 private:
00111         DISALLOW_COPY_AND_ASSIGN(ToolOrientationController);
00112 
00113 public:
00114         EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00115 };
00116 
00117 
00118 }
00119 }
00120 
00121 
00122 #endif /* BARRETT_SYSTEMS_TOOL_ORIENTATION_CONTROLLER_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Defines