icubsimulator.cpp
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2012 *
4  * Gianluca Massera <emmegian@yahoo.it> *
5  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
6  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
21  ********************************************************************************/
22 
23 #ifdef FARSA_USE_YARP_AND_ICUB
24 
25 #include "icubsimulator.h"
26 #include "configurationhelper.h"
27 #include "randomgenerator.h"
28 #include "icubsimulatorviewer.h"
29 #include <QStringList>
30 
31 namespace farsa {
32 
34  Component(),
35  world(NULL),
36  icub(NULL) {
37  // the world and the icub will be created in the configure
38 }
39 
41  delete icub;
42  delete world;
43 }
44 
46  return new iCubSimulatorViewer( this );
47 }
48 
49 void iCubSimulator::configure( ConfigurationParameters& params, QString prefix) {
50  // eliminate any previous world, icub and objects created
51  if ( world ) {
52  delete icub;
53  delete world;
54  }
55  // retrieve data about the world
56  QString name = ConfigurationHelper::getString( params, prefix+"/WORLD/name", "world" );
57  QVector<double> worldsize = ConfigurationHelper::getVector( params, prefix+"/WORLD/size" );
58  // defaul min and max point for the dimension of the world
59  wVector min( -2, -2, 0 );
60  wVector max( +2, +2, 2 );
61  // the min and max point are calculated from the size in the following way:
62  // - the X and Y dimension are divided in two in order to spawn in both direction from the center
63  // - the Z dimension start always from zero and spawn only in positive direction
64  if ( worldsize.size() == 3 ) {
65  min[0] = -worldsize[0]/2.0;
66  min[1] = -worldsize[1]/2.0;
67  min[2] = 0.0f;
68  max[0] = +worldsize[0]/2.0;
69  max[1] = +worldsize[1]/2.0;
70  max[2] = worldsize[2];
71  }
72  world = new World( name );
73  double timestep = ConfigurationHelper::getDouble( params, prefix+"/WORLD/timestep", 0.05 );
74  bool realtime = ConfigurationHelper::getBool( params, prefix+"/WORLD/realTime", true );
75  world->setSize( min, max );
76  world->setTimeStep( timestep );
77  world->setIsRealTime( realtime );
78  // retrieve data about the iCub
79  name = ConfigurationHelper::getString( params, prefix+"/ICUB/name", "icub" );
80  QVector<double> icubpos = ConfigurationHelper::getVector( params, prefix+"/ICUB/position" );
81  wMatrix icubtm = wMatrix::identity();
82  if ( icubpos.size() == 3 ) {
83  icubtm.w_pos[0] = icubpos[0];
84  icubtm.w_pos[1] = icubpos[1];
85  icubtm.w_pos[2] = icubpos[2];
86  }
87  icub = new PhyiCub( world, name, icubtm );
88  // TODO: the OBJECT groups are now ignored
89 
90  setStatus( "Ready to Start" );
91 }
92 
93 void iCubSimulator::save( ConfigurationParameters& params, QString prefix ) {
94  QString worldGroup = params.createSubGroup( prefix, "WORLD" );
95  params.createParameter( worldGroup, "name", world->name() );
96  params.createParameter( worldGroup, "timestep", QString::number(world->timeStep()) );
97  wVector min, max;
98  world->size( min, max );
99  params.createParameter( worldGroup, "size", QString::number(max[0]-min[0]) + " " + QString::number(max[1]-min[1]) + " " + QString::number(max[2]) );
100  params.createParameter( worldGroup, "realTime", world->isRealTime() ? "true" : "false" );
101 
102  QString icubGroup = params.createSubGroup( prefix, "ICUB" );
103  params.createParameter( icubGroup, "name", icub->name() );
104  wMatrix tm = icub->matrix();
105  params.createParameter( icubGroup, "position", QString::number(tm.w_pos[0]) + " " + QString::number(tm.w_pos[1]) + " " + QString::number(tm.w_pos[2]) );
106  // TODO: OBJECTs are not saved
107 
108 }
109 
111 }
112 
113 void iCubSimulator::describe( QString type ) {
114  Descriptor d = addTypeDescription( type, "iCub Simulator" );
115  SubgroupDescriptor sub = d.describeSubgroup( "WORLD" ).props( IsMandatory ).help( "This group contains all parameters regarding the simulated world" );
116  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" );
117  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)" );
118  sub.describeReal( "size" ).props( IsList ).help( "The X, Y and Z dimension of the world in meters" );
119  sub.describeBool( "realTime" ).def( true ).help( "If the advance of the simulation is real time or as fast as possible" );
120  sub = d.describeSubgroup( "ICUB" ).props( IsMandatory ).help( "This group contains all parameters regarding the iCub robot");
121  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" );
122  sub.describeString( "position" ).props( IsList ).help( "The x, y and z position of the iCub in the world" );
123  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" );
124  sub.describeString( "name" ).props( IsMandatory ).help( "The name of the object - this is necessary to access the object" );
125  sub.describeEnum( "shape" ).props( IsMandatory ).values( QStringList() << "cube" << "sphere" << "cylinder" ).help( "The shape of the object to create: cube, sphere or cylinder" );
126  sub.describeReal( "position" ).props( IsList ).help( "The x, y and z position of the object in the world" );
127  sub.describeReal( "rotation" ).props( IsList ).help( "The three Euler angles representing the rotation of the object respect to the world" );
128 }
129 
131  setStatus("Simulator Running");
132 }
133 
135  setStatus("Simulator Suspended");
136 }
137 
139  setStatus("Simulator in step-by-step mode");
140 }
141 
142 } // end namespace farsa
143 
144 #endif // FARSA_USE_YARP_AND_ICUB