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

robot/control/ControllableAdaptor.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: ControllableAdaptor.cpp 1037 2004-02-11 20:50:18Z jungd $
00019   $Revision: 1.6 $
00020   $Date: 2004-02-11 15:50:18 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <robot/control/ControllableAdaptor>
00026 
00027 using robot::control::ControllableAdaptor;
00028 using robot::ControlInterface;
00029 
00030 
00031 ControllableAdaptor::ControllableAdaptor(AdaptorType type, ref<Controllable> controllable, 
00032                                          const String& interfaceName, const String& adaptedInterfaceName,
00033                                          const String& adaptedInterfaceType)
00034   : type(type), rangesSet(false), stridesSet(false), controllable(controllable), 
00035     newInterfaceName(adaptedInterfaceName), newInterfaceType(adaptedInterfaceType)
00036 {
00037   adaptedInterface = controllable->getControlInterface(interfaceName);
00038   if (newInterfaceName=="") newInterfaceName=adaptedInterface->getName();
00039   if (newInterfaceType=="") newInterfaceType=adaptedInterface->getType();
00040   // create an instance of the ControlInterface.  By storing the ref and passing a ref to ourself
00041   //  we create a cyclic reference - which we break in onUnreference() when appropriate
00042   adaptorInterface = ref<AdaptorControlInterface>(NewObj AdaptorControlInterface(ref<ControllableAdaptor>(this)));
00043   enableOnUnreferenceCall(true);
00044 
00045   if (type == PassThrough) {
00046     adaptorInterface->inputs.resize(adaptedInterface->inputSize());
00047     adaptorInterface->outputsSize = adaptedInterface->outputSize();
00048   }
00049 }
00050 
00051 
00052 ControllableAdaptor::ControllableAdaptor(const ControllableAdaptor& c)
00053   : type(c.type), rangesSet(c.rangesSet), 
00054     inputStart(c.inputStart), outputStart(c.outputStart),
00055     inputEnd(c.inputEnd), outputEnd(c.outputEnd),
00056     stridesSet(c.stridesSet), inputStride(c.inputStride), outputStride(c.outputStride),
00057     controllable(c.controllable), adaptedInterface(c.adaptedInterface), adaptorInterface(c.adaptorInterface),
00058     newInterfaceName(c.newInterfaceName)
00059 {
00060   // NB: this shares the adaptorInterface, so if this class is ever modified to be mutable after
00061   //  construction, the adaptorInterface will been a NewObj
00062 }
00063 
00064 
00065 void ControllableAdaptor::onUnreference() const
00066 {
00067   if ((referenceCount()==1) && (adaptorInterface->referenceCount()==1)) {
00068     // if the only references are to each other, then break the cyclic link
00069     Release(adaptorInterface);
00070   }
00071 }
00072 
00073 
00074 
00075 
00076 void ControllableAdaptor::setRanges(Int inputStart, Int outputStart, SInt inputEnd, SInt outputEnd)
00077 {
00078   if ((inputStart >= adaptedInterface->inputSize()) || (outputStart >= adaptedInterface->outputSize()))
00079     throw std::out_of_range(Exception("inputStart or outputStart out of range"));
00080 
00081   this->inputStart = inputStart;
00082   this->outputStart = outputStart;
00083   this->inputEnd = inputEnd;
00084   this->outputEnd = outputEnd;
00085   if (inputEnd == End)
00086     this->inputEnd = adaptedInterface->inputSize()-1;
00087   if (outputEnd == End)
00088     this->outputEnd = adaptedInterface->inputSize()-1;
00089   rangesSet = true;
00090   adaptorInterface->inputs.resize(this->inputEnd-inputStart+1);
00091   adaptorInterface->outputsSize = this->outputEnd-outputStart+1;
00092 }
00093 
00094 void ControllableAdaptor::setStrides(Int inputStart, Int outputStart, Int inputStride, Int outputStride)
00095 {
00096   this->inputStart = inputStart;
00097   this->outputStart = outputStart;
00098   this->inputStride = inputStride;
00099   this->outputStride = outputStride;
00100   stridesSet = true;
00101   adaptorInterface->inputs.resize( (adaptedInterface->inputSize()-inputStart)/inputStride );
00102   adaptorInterface->outputsSize = (adaptedInterface->outputSize()-outputStart)/outputStride;
00103 }
00104 
00105 
00106 
00107 
00108 void ControllableAdaptor::setControlInterface(ref<ControlInterface> controlInterface)
00109 {
00110   // ignore (constructor uses interfaceName of Controllable)
00111 }
00112 
00113 bool ControllableAdaptor::iterate(const base::Time& time)
00114 {
00115   return false;
00116 }
00117 
00118 
00119 ref<ControlInterface> ControllableAdaptor::getControlInterface(String interfaceName) throw(std::invalid_argument)
00120 {
00121   if ( ((type==Range)&&!rangesSet) || ((type==Stride)&&!stridesSet))
00122     throw std::invalid_argument(Exception(String("unknown interface ")+interfaceName+" (adaptor parameters not set)"));
00123 
00124   if ((interfaceName != "") && (interfaceName != adaptorInterface->getName()))
00125     throw std::invalid_argument(Exception(String("unknown interface ")+interfaceName));
00126 
00127   return adaptorInterface;
00128 }
00129 
00130 
00131 
00132 inline Int ControllableAdaptor::adaptInputIndex(Int i) const
00133 {
00134   Int ai;
00135   switch (type) {
00136   case PassThrough: ai=i; break;
00137   case Range: ai = i + inputStart; break;
00138   case Stride: ai = inputStart + i*inputStride; break;
00139   default:
00140     throw std::runtime_error(Exception("AdaptorType not handled"));    
00141   }
00142 
00143   if (ai >= adaptedInterface->inputSize()) indexOutOfRange();
00144   return ai;
00145 }
00146 
00147 inline Int ControllableAdaptor::adaptOutputIndex(Int i) const
00148 {
00149   Int ai = 0;
00150   switch (type) {
00151   case PassThrough: ai=i; break;
00152   case Range: ai = i + outputStart; break;
00153   case Stride: ai = outputStart + i*outputStride; break;
00154   default:
00155     throw std::runtime_error(Exception("AdaptorType not handled"));    
00156   }
00157 
00158   if (ai >= adaptedInterface->outputSize()) indexOutOfRange();
00159   return ai;
00160 }
00161 
00162 
00163 
00164 
00165 // class AdaptorControlInterface
00166 
00167 base::Int ControllableAdaptor::AdaptorControlInterface::inputSize() const
00168 {
00169   return inputs.size();
00170 }
00171 
00172 base::String ControllableAdaptor::AdaptorControlInterface::inputName(Int i) const
00173 {
00174   return c->adaptedInterface->inputName(c->adaptInputIndex(i));
00175 }
00176 
00177 inline base::Real ControllableAdaptor::AdaptorControlInterface::getInput(Int i) const
00178 {
00179   return c->adaptedInterface->getInput(c->adaptInputIndex(i));
00180 }
00181 
00182 const base::Vector& ControllableAdaptor::AdaptorControlInterface::getInputs() const
00183 {
00184   ref<ControlInterface> adaptedInterface(c->adaptedInterface);
00185   for(Int i=0; i<inputs.size(); i++)
00186     inputs[i] = adaptedInterface->getInput(c->adaptInputIndex(i));
00187 
00188   return inputs;
00189 }
00190 
00191 base::Int ControllableAdaptor::AdaptorControlInterface::outputSize() const
00192 {
00193   return outputsSize;
00194 }
00195 
00196 base::String ControllableAdaptor::AdaptorControlInterface::outputName(Int i) const
00197 {
00198   return c->adaptedInterface->outputName(c->adaptOutputIndex(i));
00199 }
00200 
00201 inline void ControllableAdaptor::AdaptorControlInterface::setOutput(Int i, Real value) 
00202 {
00203   c->adaptedInterface->setOutput(c->adaptOutputIndex(i),value);
00204 }
00205 
00206 void ControllableAdaptor::AdaptorControlInterface::setOutputs(const Vector& values)
00207 {
00208   ref<ControlInterface> adaptedInterface(c->adaptedInterface);
00209   for(Int i=0; i<values.size(); i++)
00210     adaptedInterface->setOutput(c->adaptOutputIndex(i), values[i]);
00211 }
00212 
00213  
00214 

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