experiments/icubsimulator/src/icubsimulator.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 #ifdef FARSA_USE_YARP_AND_ICUB
00024 
00025 #include "icubsimulator.h"
00026 #include "configurationhelper.h"
00027 #include "randomgenerator.h"
00028 #include "icubsimulatorviewer.h"
00029 #include <QStringList>
00030 
00031 namespace farsa {
00032 
00033 iCubSimulator::iCubSimulator() :
00034     Component(),
00035     world(NULL),
00036     icub(NULL) {
00037     // the world and the icub will be created in the configure
00038 }
00039 
00040 iCubSimulator::~iCubSimulator() {
00041     delete icub;
00042     delete world;
00043 }
00044 
00045 ComponentUI* iCubSimulator::getUIManager() {
00046     return new iCubSimulatorViewer( this );
00047 }
00048 
00049 void iCubSimulator::configure( ConfigurationParameters& params, QString prefix) {
00050     // eliminate any previous world, icub and objects created
00051     if ( world ) {
00052         delete icub;
00053         delete world;
00054     }
00055     // retrieve data about the world
00056     QString name = ConfigurationHelper::getString( params, prefix+"/WORLD/name", "world" );
00057     QVector<double> worldsize = ConfigurationHelper::getVector( params, prefix+"/WORLD/size" );
00058     // defaul min and max point for the dimension of the world
00059     wVector min( -2, -2, 0 );
00060     wVector max( +2, +2, 2 );
00061     // the min and max point are calculated from the size in the following way:
00062     //  - the X and Y dimension are divided in two in order to spawn in both direction from the center
00063     //  - the Z dimension start always from zero and spawn only in positive direction
00064     if ( worldsize.size() == 3 ) {
00065         min[0] = -worldsize[0]/2.0;
00066         min[1] = -worldsize[1]/2.0;
00067         min[2] = 0.0f;
00068         max[0] = +worldsize[0]/2.0;
00069         max[1] = +worldsize[1]/2.0;
00070         max[2] = worldsize[2];
00071     }
00072     world = new World( name );
00073     double timestep = ConfigurationHelper::getDouble( params, prefix+"/WORLD/timestep", 0.05 );
00074     bool realtime = ConfigurationHelper::getBool( params, prefix+"/WORLD/realTime", true );
00075     world->setSize( min, max );
00076     world->setTimeStep( timestep );
00077     world->setIsRealTime( realtime );
00078     markParameterAsRuntime( "/WORLD/timestep", world, &World::setTimeStep, &World::timeStep );
00079     markParameterAsRuntime( "/WORLD/realTime", world, &World::setIsRealTime, &World::isRealTime );
00080     // retrieve data about the iCub
00081     name = ConfigurationHelper::getString( params, prefix+"/ICUB/name", "icub" );
00082     QVector<double> icubpos = ConfigurationHelper::getVector( params, prefix+"/ICUB/position" );
00083     wMatrix icubtm = wMatrix::identity();
00084     if ( icubpos.size() == 3 ) {
00085         icubtm.w_pos[0] = icubpos[0];
00086         icubtm.w_pos[1] = icubpos[1];
00087         icubtm.w_pos[2] = icubpos[2];
00088     }
00089     icub = new PhyiCub( world, name, icubtm );
00090     // TODO: the OBJECT groups are now ignored
00091 
00092     setStatus( "Ready to Start" );
00093 }
00094 
00095 void iCubSimulator::save( ConfigurationParameters& params, QString prefix ) {
00096     QString worldGroup = params.createSubGroup( prefix, "WORLD" );
00097     params.createParameter( worldGroup, "name", world->name() );
00098     params.createParameter( worldGroup, "timestep", QString::number(world->timeStep()) );
00099     wVector min, max;
00100     world->size( min, max );
00101     params.createParameter( worldGroup, "size", QString::number(max[0]-min[0]) + " " + QString::number(max[1]-min[1]) + " " + QString::number(max[2]) );
00102     params.createParameter( worldGroup, "realTime", world->isRealTime() ? "true" : "false" );
00103     
00104     QString icubGroup = params.createSubGroup( prefix, "ICUB" );
00105     params.createParameter( icubGroup, "name", icub->name() );
00106     wMatrix tm = icub->matrix();
00107     params.createParameter( icubGroup, "position", QString::number(tm.w_pos[0]) + " " + QString::number(tm.w_pos[1]) + " " + QString::number(tm.w_pos[2]) );
00108     // TODO: OBJECTs are not saved
00109     
00110 }
00111 
00112 void iCubSimulator::postConfigureInitialization() {
00113 }
00114 
00115 void iCubSimulator::describe( QString type ) {
00116     Descriptor d = addTypeDescription( type, "iCub Simulator" );
00117     SubgroupDescriptor sub = d.describeSubgroup( "WORLD" ).props( IsMandatory ).help( "This group contains all parameters regarding the simulated world" );
00118         sub.describeString( "name" ).def( "world" ).props( IsMandatory ).help( "The name of the world - this will also correspond to the root of all yarp port created" );
00119         sub.describeReal( "timestep" ).def( 0.05 ).props( IsMandatory ).limits( 0.001, 0.1 ).help( "Number of seconds of a single step of simulation - for the best stability keep it below 0.1 (100 milliseconds)" );
00120         sub.describeReal( "size" ).props( IsList ).help( "The X, Y and Z dimension of the world in meters" );
00121         sub.describeBool( "realTime" ).def( true ).help( "If the advance of the simulation is real time or as fast as possible" );
00122     sub = d.describeSubgroup( "ICUB" ).props( IsMandatory ).help( "This group contains all parameters regarding the iCub robot");
00123         sub.describeString( "name" ).def( "icub" ).props( IsMandatory ).help( "The name of the iCub - this will also correspond to the root of all yarp port for controlling the robot" );
00124         sub.describeString( "position" ).props( IsList ).help( "The x, y and z position of the iCub in the world" );
00125     sub = d.describeSubgroup( "OBJECT" ).props( AllowMultiple ).help( "This group specifies the type and the parameters of an object to be inserted into the simulated world" );
00126         sub.describeString( "name" ).props( IsMandatory ).help( "The name of the object - this is necessary to access the object" );
00127         sub.describeEnum( "shape" ).props( IsMandatory ).values( QStringList() << "cube" << "sphere" << "cylinder" ).help( "The shape of the object to create: cube, sphere or cylinder" );
00128         sub.describeReal( "position" ).props( IsList ).help( "The x, y and z position of the object in the world" );
00129         sub.describeReal( "rotation" ).props( IsList ).help( "The three Euler angles representing the rotation of the object respect to the world" );
00130 }
00131 
00132 void iCubSimulator::start() {
00133     setStatus("Simulator Running");
00134 }
00135 
00136 void iCubSimulator::suspend() {
00137     setStatus("Simulator Suspended");
00138 }
00139 
00140 void iCubSimulator::step() {
00141     setStatus("Simulator in step-by-step mode");
00142 }
00143 
00144 } // end namespace farsa
00145 
00146 #endif // FARSA_USE_YARP_AND_ICUB