Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

robot/control/ManipulatorPIDPositionController.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2002 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: ManipulatorPIDPositionController.cpp 1037 2004-02-11 20:50:18Z jungd $
00019   $Revision: 1.9 $
00020   $Date: 2004-02-11 15:50:18 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <robot/control/ManipulatorPIDPositionController>
00026 
00027 using robot::control::ManipulatorPIDPositionController;
00028 using robot::ControlInterface;
00029 
00030 ManipulatorPIDPositionController::ManipulatorPIDPositionController(const robot::KinematicChain& chain)
00031   : chain(chain), Kp(10), Ki(0.1), Kd(0)
00032 {
00033   //!!! NB: creates a cyclic reference!
00034   positionInterface = ref<PositionInterface>(NewObj PositionInterface(ref<ManipulatorPIDPositionController>(this)));
00035 }
00036 
00037 
00038 
00039 void ManipulatorPIDPositionController::setControlInterface(ref<ControlInterface> controlInterface)
00040 {
00041   if (controlInterface->getType()=="JointVelocityControl") {
00042     manipInterface = controlInterface;
00043     Int inputSize = manipInterface->inputSize();
00044     lastInputSize = inputSize;
00045     if (inputSize > 0) {
00046       R.reset(zeroVector(inputSize));
00047       pe.reset(zeroVector(inputSize));
00048       s.reset(zeroVector(inputSize));
00049     }
00050   }
00051   else {
00052     Logln("Ignoring useless ControlInterface name:" << controlInterface->getName() << " type:" << controlInterface->getType());
00053   }
00054 }
00055 
00056 bool ManipulatorPIDPositionController::isConnected() const
00057 {
00058   return (manipInterface!=0);
00059 }
00060 
00061 bool ManipulatorPIDPositionController::iterate(const base::Time& time)
00062 {
00063   if (!isConnected()) return false;
00064 
00065   Int inputSize = manipInterface->inputSize();
00066   if (inputSize != lastInputSize) {
00067     pe.reset(zeroVector(inputSize));
00068     s.reset(zeroVector(inputSize));
00069     lastInputSize = inputSize;
00070   }
00071 
00072   Int outputSize = manipInterface->outputSize();
00073   if (outputSize != lastOutputSize) {
00074     R.reset(zeroVector(inputSize));
00075     lastOutputSize = outputSize;
00076   }
00077 
00078 
00079   for(Int i=0; i<inputSize; i++) {
00080 
00081     // perform discrete PID step
00082     Real Y = manipInterface->getInput(i); // actual position
00083     Real e;
00084     // if the joint is revolute and has no joint limits,
00085     //  take the shortest angular path, not the long way around
00086     bool angWrap = false;
00087     if (chain.linkOfVariable(i).type() == KinematicChain::Link::Revolute) 
00088       if (chain.variableMaxLimit(i) > consts::Pi)
00089         if (chain.variableMinLimit(i) < consts::Pi)
00090           angWrap=true;
00091     if (!angWrap)
00092       e = R[i]-Y; // error = reference - actual 
00093     else
00094       e = Math::angleDifference(R[i],Y); // error = reference - actual 
00095 
00096     s[i] += e;
00097     Real u = Kp*e + Ki*s[i] + Kd*(e - pe[i]); // PID
00098     manipInterface->setOutput(i, u);
00099 
00100     if (i==inputSize-1) {
00101       //Debugcln(DJ,"i::" << i << "  R=" << R[i] << " Y=" << Y << " e=" << e << " s[i]=" << s[i] << " e-pe[i]=" << (e-pe[i]) << " Kp*e=" << Kp*e << " Ki*s[i]=" << Ki*s[i] << " u=" << u);
00102     }
00103     pe[i] = e;
00104   }
00105 
00106   return false;
00107 }
00108 
00109 
00110 base::ref<ControlInterface> ManipulatorPIDPositionController::getControlInterface(String interfaceName) throw(std::invalid_argument)
00111 {
00112   if (!manipInterface)
00113     throw std::invalid_argument(Exception(String("unknown interface ")+interfaceName+" (not connected)"));
00114 
00115   if (interfaceName=="") interfaceName = positionInterface->getName();
00116 
00117   if (interfaceName == positionInterface->getName())
00118     return positionInterface;
00119 
00120   throw std::invalid_argument(Exception(String("unknown interface name:")+interfaceName));
00121 }
00122 
00123 
00124 
00125 
00126 Int ManipulatorPIDPositionController::PositionInterface::inputSize() const
00127 {
00128   return c->manipInterface->inputSize();
00129 }
00130 
00131 
00132 /// \todo implement properly (or is it OK?)
00133 base::String ManipulatorPIDPositionController::PositionInterface::inputName(Int i) const
00134 {
00135   return c->manipInterface->inputName(i);
00136 }
00137 
00138 
00139 Real ManipulatorPIDPositionController::PositionInterface::getInput(Int i) const 
00140 {
00141   return c->manipInterface->getInput(i);
00142 }
00143 
00144 
00145 const base::Vector& ManipulatorPIDPositionController::PositionInterface::getInputs() const 
00146 {
00147   return c->manipInterface->getInputs();
00148 }
00149 
00150 
00151 Int ManipulatorPIDPositionController::PositionInterface::outputSize() const
00152 {
00153   return c->manipInterface->outputSize();
00154 }
00155 
00156 
00157 /// \todo implement properly
00158 base::String ManipulatorPIDPositionController::PositionInterface::outputName(Int i) const
00159 {
00160   return c->manipInterface->outputName(i); //!!! fixme to subst force/torque;vel/ang.vel names for angle/dist names
00161 }
00162 
00163 
00164 void ManipulatorPIDPositionController::PositionInterface::setOutput(Int i, Real value) 
00165 {
00166   Int outputSize = c->manipInterface->outputSize();
00167   if (i >= outputSize)
00168     throw std::out_of_range(Exception("index out of range"));
00169 
00170   if (c->lastOutputSize != outputSize) {
00171     c->R.reset(zeroVector(outputSize));
00172     c->lastOutputSize = outputSize;
00173   }
00174 
00175   c->R[i] = value;
00176 }
00177 
00178 
00179 void ManipulatorPIDPositionController::PositionInterface::setOutputs(const Vector& values) 
00180 {
00181   Int outputSize = c->manipInterface->outputSize();
00182   if (values.size() != outputSize)
00183     throw std::invalid_argument(Exception("values Vector has wrong dimension"));
00184 
00185   if (c->lastOutputSize != outputSize) {
00186     c->R.reset(zeroVector(outputSize));
00187     c->lastOutputSize = outputSize;
00188   }
00189 
00190   c->R = values;
00191 }
00192 
00193 

Generated on Thu Jul 29 15:56:34 2004 for OpenSim by doxygen 1.3.6