experiments/src/neuroninterfaces.cpp

00001 /********************************************************************************
00002  *  FARSA Experiments Library                                                   *
00003  *  Copyright (C) 2007-2012                                                     *
00004  *  Gianluca Massera <emmegian@yahoo.it>                                        *
00005  *  Stefano Nolfi <stefano.nolfi@istc.cnr.it>                                   *
00006  *  Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it>                         *
00007  *                                                                              *
00008  *  This program is free software; you can redistribute it and/or modify        *
00009  *  it under the terms of the GNU General Public License as published by        *
00010  *  the Free Software Foundation; either version 2 of the License, or           *
00011  *  (at your option) any later version.                                         *
00012  *                                                                              *
00013  *  This program is distributed in the hope that it will be useful,             *
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00016  *  GNU General Public License for more details.                                *
00017  *                                                                              *
00018  *  You should have received a copy of the GNU General Public License           *
00019  *  along with this program; if not, write to the Free Software                 *
00020  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00021  ********************************************************************************/
00022 
00023 #include "neuroninterfaces.h"
00024 #include "evonet.h"
00025 #include "configurationhelper.h"
00026 #include "logger.h"
00027 
00028 namespace farsa {
00029 
00030 Sensor::Sensor( ConfigurationParameters& params, QString prefix ) :
00031     ParameterSettableInConstructor(params, prefix),
00032     allNeededResourcesExist(false)
00033 {
00034     setName( ConfigurationHelper::getString( params, prefix+"name", "unnamed" ) );
00035 }
00036 
00037 Sensor::~Sensor() {
00038 }
00039 
00040 void Sensor::save( ConfigurationParameters& params, QString prefix ) {
00041     params.startObjectParameters( prefix, "Sensor", this );
00042     // if Sensor name startsWith "Sensor:" means that the name has been
00043     // configured by EvoRobotExperiment automatically
00044     if ( sensorName != "unnamed" || !sensorName.startsWith("Sensor:") ) {
00045         params.createParameter( prefix, "name", sensorName );
00046     }
00047 }
00048 
00049 void Sensor::describe( QString type ) {
00050     Descriptor d = addTypeDescription( type, "Base class for all Sensors" );
00051     d.describeString( "name" ).help( "The name of the sensor" );
00052 }
00053 
00054 QString Sensor::name() {
00055     return sensorName;
00056 }
00057 
00058 void Sensor::setName( QString name ) {
00059     sensorName = name;
00060 }
00061 
00062 void Sensor::checkAllNeededResourcesExist() {
00063     if (allNeededResourcesExist) {
00064         return;
00065     }
00066 
00067     // We do the check only if allNeededResourcesExist is false, if it is true we already did the
00068     // check and we will be notified when a resource gets deleted
00069     QStringList nonExistingResources;
00070     if (!usedResourcesExist(&nonExistingResources)) {
00071         ConfigurationHelper::throwUserMissingResourceError(nonExistingResources.join(", "), "Some required resource do not exist, cannot use " + sensorName + " anymore");
00072     }
00073 
00074     allNeededResourcesExist = true;
00075 }
00076 
00077 void Sensor::resetNeededResourcesCheck()
00078 {
00079     allNeededResourcesExist = false;
00080 }
00081 
00082 Motor::Motor( ConfigurationParameters& params, QString prefix ) :
00083     ParameterSettableInConstructor(params, prefix),
00084     allNeededResourcesExist(false)
00085 {
00086     setName( ConfigurationHelper::getString( params, prefix+"name", "unnamed" ) );
00087 }
00088 
00089 Motor::~Motor() {
00090 }
00091 
00092 void Motor::save( ConfigurationParameters& params, QString prefix ) {
00093     params.startObjectParameters( prefix, "Motor", this );
00094     // if Motor name startsWith "Motor:" means that the name has been
00095     // configured by EvoRobotExperiment automatically
00096     if ( motorName != "unnamed" || !motorName.startsWith("Motor:") ) {
00097         params.createParameter( prefix, "name", motorName );
00098     }
00099 }
00100 
00101 void Motor::describe( QString type ) {
00102     Descriptor d = addTypeDescription( type, "Base class for all Motors" );
00103     d.describeString( "name" ).help( "The name of the motor" );
00104 }
00105 
00106 QString Motor::name() {
00107     return motorName;
00108 }
00109 
00110 void Motor::setName( QString name ) {
00111     motorName = name;
00112 }
00113 
00114 void Motor::checkAllNeededResourcesExist() {
00115     if (allNeededResourcesExist) {
00116         return;
00117     }
00118 
00119     // We do the check only if allNeededResourcesExist is false, if it is true we already did the
00120     // check and we will be notified when a resource gets deleted
00121     QStringList nonExistingResources;
00122     if (!usedResourcesExist(&nonExistingResources)) {
00123         ConfigurationHelper::throwUserMissingResourceError(nonExistingResources.join(", "), "Some required resource do not exist, cannot use " + motorName + " anymore");
00124     }
00125 
00126     allNeededResourcesExist = true;
00127 }
00128 
00129 void Motor::resetNeededResourcesCheck()
00130 {
00131     allNeededResourcesExist = false;
00132 }
00133 
00134 EvonetIterator::EvonetIterator() :
00135     blocks(),
00136     currLayer(InputLayer),
00137     currStartIndex(-1),
00138     currEndIndex(0),
00139     currIndex(0),
00140     evonet(NULL) {
00141 }
00142 
00143 EvonetIterator::~EvonetIterator() {
00144     /* nothing to do */
00145 }
00146 
00147 void EvonetIterator::setEvonet( Evonet* evonet ) {
00148     this->evonet = evonet;
00149     blocks.clear();
00150     currStartIndex = -1;
00151     currEndIndex = 0;
00152     currIndex = 0;
00153 }
00154 
00155 void EvonetIterator::defineBlock( QString name, layer_t layer, int startIndex, int size ) {
00156     BlockInfo binfo;
00157     binfo.layer = layer;
00158     binfo.startIndex = startIndex;
00159     binfo.endIndex = startIndex + size;
00160     blocks[name] = binfo;
00161 }
00162 
00163 bool EvonetIterator::setCurrentBlock( QString blockName ) {
00164     if ( !blocks.contains( blockName ) ) {
00165         Logger::error( QString("EvonetIterator - the block %1 does not exist").arg(blockName) );
00166         return false;
00167     }
00168     BlockInfo binfo = blocks[blockName];
00169     currLayer = binfo.layer;
00170     currStartIndex = binfo.startIndex;
00171     currEndIndex = binfo.endIndex;
00172     currIndex = currStartIndex;
00173     return true;
00174 }
00175 
00176 bool EvonetIterator::nextNeuron() {
00177     checkCurrentStatus( "nextNeuron" );
00178 
00179     currIndex++;
00180     if ( currIndex >= currEndIndex ) {
00181         return false;
00182     }
00183     return true;
00184 }
00185 
00186 void EvonetIterator::setInput( double value ) {
00187     checkCurrentStatus( "setInput" );
00188 
00189     evonet->setInput( currIndex, value );
00190 }
00191 
00192 double EvonetIterator::getOutput() {
00193     checkCurrentStatus( "getOutput" );
00194 
00195     return evonet->getOutput( currIndex );
00196 }
00197 
00198 void EvonetIterator::setGraphicProperties( QString label, double minValue, double maxValue, QColor color ) {
00199     checkCurrentStatus( "setGraphicProperties" );
00200 
00201     label.truncate( 9 );
00202     int offsetIndex = 0;
00203     if ( currLayer == OutputLayer ) {
00204         offsetIndex = evonet->getNoInputs() + evonet->getNoHiddens();
00205     }
00206     sprintf( evonet->neuronl[ offsetIndex+currIndex ], "%s", label.toAscii().data() );
00207     evonet->neuronrange[ offsetIndex+currIndex ][0]  = 0.0;
00208     evonet->neuronrange[ offsetIndex+currIndex ][1]  = 1.0;
00209     // FIXME: need to change how the color are handled into Evonet
00210     evonet->neurondcolor[ offsetIndex+currIndex ] = color;
00211 }
00212 
00213 void EvonetIterator::checkCurrentStatus( const QString& funcName ) const {
00214     if ( !evonet ) {
00215         throw EvonetIteratorInvalidStatusException( funcName.toAscii().data(), "no Evonet object has ben set");
00216     }
00217     if ( currStartIndex < 0 ) {
00218         throw EvonetIteratorInvalidStatusException( funcName.toAscii().data(), "you should call setCurrentBlock first");
00219     }
00220     if ( currIndex >= currEndIndex ) {
00221         throw EvonetIteratorInvalidStatusException( funcName.toAscii().data(), "attempt to access beyond the size of the current block");
00222     }
00223 }
00224 
00225 } // end namespace farsa