00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef FARSA_USE_YARP_AND_ICUB
00021
00022 #include "worldcontroller.h"
00023 #include "phybox.h"
00024 #include "physphere.h"
00025 #include "phycylinder.h"
00026 #include "wcamera.h"
00027 #include "phyicub.h"
00028 #include <QCoreApplication>
00029 #include <QTimerEvent>
00030
00031 using namespace yarp::os;
00032
00033 namespace farsa {
00034
00035 ServerWorldController::ServerWorldController( WorldController* ctrl ) : QThread() {
00036 wctrl = ctrl;
00037
00038 asyn_cmds["start"] = &ServerWorldController::startCmd;
00039 asyn_cmds["pause"] = &ServerWorldController::pauseCmd;
00040 asyn_cmds["stop"] = &ServerWorldController::stopCmd;
00041 asyn_cmds["advance"] = &ServerWorldController::advanceCmd;
00042
00043 syn_cmds["mk"] = &ServerWorldController::makeCmd;
00044 syn_cmds["set"] = &ServerWorldController::setCmd;
00045 setTerminationEnabled( true );
00046 }
00047
00048 ServerWorldController::~ServerWorldController() {
00049
00050 }
00051
00052 void ServerWorldController::applyQueuedCommands() {
00053 Port* port = wctrl->outPort();
00054 while( !queue_cmds.isEmpty() ) {
00055 Bottle cmd = queue_cmds.dequeue();
00056 Bottle res;
00057 QString cmd0( cmd.get(0).toString().c_str() );
00058
00059
00060 res = (this->*(syn_cmds[cmd0]))( cmd );
00061 port->write(res);
00062 }
00063 }
00064
00065 void ServerWorldController::run() {
00066 Port* inport = wctrl->inPort();
00067 Port* outport = wctrl->outPort();
00068 while( true ) {
00069 Bottle cmd;
00070 Bottle res;
00071
00072 inport->read( cmd, false );
00073
00074 QString cmd0( cmd.get(0).asString().c_str() );
00075 if ( asyn_cmds.contains( cmd0 ) ) {
00076 res = (this->*(asyn_cmds[cmd0]))( cmd );
00077 } else if ( syn_cmds.contains( cmd0 ) ) {
00078 res.addString( "Command Queued" );
00079 queue_cmds.enqueue( cmd );
00080 } else {
00081 res.addString( "Unsupported Command: " );
00082 res.addString( cmd.get(0).toString() );
00083 }
00084
00085 outport->write(res);
00086 }
00087 }
00088
00089 yarp::os::Bottle ServerWorldController::startCmd( const yarp::os::Bottle& ) {
00090 QCoreApplication::postEvent( wctrl->world(), new QEvent( (QEvent::Type)(World::E_Play) ) );
00091 Bottle res;
00092 res.addString("World Running");
00093 return res;
00094 }
00095
00096 yarp::os::Bottle ServerWorldController::pauseCmd( const yarp::os::Bottle& ) {
00097 QCoreApplication::postEvent( wctrl->world(), new QEvent( (QEvent::Type)(World::E_Pause) ) );
00098 Bottle res;
00099 res.addString("World Paused");
00100 return res;
00101 }
00102
00103 yarp::os::Bottle ServerWorldController::stopCmd( const yarp::os::Bottle& ) {
00104 QCoreApplication::postEvent( wctrl->world(), new QEvent( (QEvent::Type)(World::E_Stop) ) );
00105 Bottle res;
00106 res.addString("World Stopped");
00107 return res;
00108 }
00109
00110 yarp::os::Bottle ServerWorldController::advanceCmd( const yarp::os::Bottle& ) {
00111 Bottle res;
00112 if ( wctrl->world()->status() == World::playingS ) {
00113 res.addString("World is currently running, pause it before use advance command");
00114 } else {
00115 QCoreApplication::postEvent( wctrl->world(), new QEvent( (QEvent::Type)(World::E_Advance) ) );
00116 res.addString("World Advanced");
00117 }
00118 return res;
00119 }
00120
00121 yarp::os::Bottle ServerWorldController::makeCmd( const yarp::os::Bottle& cmd ) {
00122 Bottle res;
00123
00124 QString objtype = cmd.get(1).toString().c_str();
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 if ( objtype == "box" ) {
00137
00138 real x_dim = 1.0;
00139 real y_dim = 1.0;
00140 real z_dim = 1.0;
00141 wMatrix tm = wMatrix::identity();
00142 Value v = cmd.get(2);
00143 if ( v.isNull() ) {
00144 res.addString( "You must specify a name for the object" );
00145 return res;
00146 }
00147 QString name = v.toString().c_str();
00148 x_dim = cmd.get(3).asDouble();
00149 y_dim = cmd.get(4).asDouble();
00150 z_dim = cmd.get(5).asDouble();
00151 if ( x_dim == 0 || y_dim == 0 || z_dim == 0 ) {
00152 res.addString( "Dimension of the object must be greater than zero" );
00153 return res;
00154 }
00155 wVector pos( cmd.get(6).asDouble(), cmd.get(7).asDouble(), cmd.get(8).asDouble() );
00156 tm = tm * wMatrix::pitch( toRad( cmd.get(9).asDouble() ) );
00157 tm = tm * wMatrix::yaw( toRad( cmd.get(10).asDouble() ) );
00158 tm = tm * wMatrix::roll( toRad( cmd.get(11).asDouble() ) );
00159 tm.w_pos = pos;
00160 new PhyBox( x_dim, y_dim, z_dim, wctrl->world(), name, tm );
00161 } else if ( objtype == "sphere" ) {
00162
00163 real radius = 1.0;
00164 wMatrix tm = wMatrix::identity();
00165 Value v = cmd.get(2);
00166 if ( v.isNull() ) {
00167 res.addString( "You must specify a name for the object" );
00168 return res;
00169 }
00170 QString name = v.toString().c_str();
00171 radius = cmd.get(3).asDouble();
00172 if ( radius == 0 ) {
00173 res.addString( "Dimension of the object must be greater than zero" );
00174 return res;
00175 }
00176 wVector pos( cmd.get(4).asDouble(), cmd.get(5).asDouble(), cmd.get(6).asDouble() );
00177 tm = tm * wMatrix::pitch( toRad( cmd.get(7).asDouble() ) );
00178 tm = tm * wMatrix::yaw( toRad( cmd.get(8).asDouble() ) );
00179 tm = tm * wMatrix::roll( toRad( cmd.get(9).asDouble() ) );
00180 tm.w_pos = pos;
00181 new PhySphere( radius, wctrl->world(), name, tm );
00182 } else if ( objtype == "cylinder" ) {
00183
00184 real radius = 1.0;
00185 real len = 1.0;
00186 wMatrix tm = wMatrix::identity();
00187 Value v = cmd.get(2);
00188 if ( v.isNull() ) {
00189 res.addString( "You must specify a name for the object" );
00190 return res;
00191 }
00192 QString name = v.toString().c_str();
00193 radius = cmd.get(3).asDouble();
00194 len = cmd.get(4).asDouble();
00195 if ( radius == 0 || len == 0 ) {
00196 res.addString( "Dimension of the object must be greater than zero" );
00197 return res;
00198 }
00199 wVector pos( cmd.get(5).asDouble(), cmd.get(6).asDouble(), cmd.get(7).asDouble() );
00200 tm = tm * wMatrix::pitch( toRad(cmd.get(8).asDouble()) );
00201 tm = tm * wMatrix::yaw( toRad(cmd.get(9).asDouble()) );
00202 tm = tm * wMatrix::roll( toRad(cmd.get(10).asDouble()) );
00203 tm.w_pos = pos;
00204 new PhyCylinder( radius, len, wctrl->world(), name, tm );
00205 } else if ( objtype == "icub" ) {
00206
00207 wMatrix tm = wMatrix::identity();
00208 Value v = cmd.get(2);
00209 if ( v.isNull() ) {
00210 res.addString( "You must specify a name for the object" );
00211 return res;
00212 }
00213 QString name = v.toString().c_str();
00214 wVector pos( cmd.get(3).asDouble(), cmd.get(4).asDouble(), cmd.get(5).asDouble() );
00215 tm = tm * wMatrix::pitch( toRad(cmd.get(6).asDouble()) );
00216 tm = tm * wMatrix::yaw( toRad(cmd.get(7).asDouble()) );
00217 tm = tm * wMatrix::roll( toRad(cmd.get(8).asDouble()) );
00218 tm.w_pos = pos;
00219 PhyiCub* icub = new PhyiCub( wctrl->world(), name, tm );
00220 icub->blockTorso0( true );
00221 } else if ( objtype == "camera" ) {
00222
00223 wMatrix tm = wMatrix::identity();
00224 Value v = cmd.get(2);
00225 if ( v.isNull() ) {
00226 res.addString( "You must specify a name for the object" );
00227 return res;
00228 }
00229 QString name = v.toString().c_str();
00230 wVector pos( cmd.get(3).asDouble(), cmd.get(4).asDouble(), cmd.get(5).asDouble() );
00231 tm = tm * wMatrix::pitch( toRad(cmd.get(6).asDouble()) );
00232 tm = tm * wMatrix::yaw( toRad(cmd.get(7).asDouble()) );
00233 tm = tm * wMatrix::roll( toRad(cmd.get(8).asDouble()) );
00234 tm.w_pos = pos;
00235 unsigned int width = cmd.get(9).asInt();
00236 unsigned int height = cmd.get(10).asInt();
00237 if ( width == 0 || height == 0 ) {
00238 res.addString( "Dimension of the frame must be greater than zero" );
00239 return res;
00240 }
00241 new WCamera( wctrl->world(), name, width, height, tm );
00242 }
00243 res.addString("Make Command executed");
00244 return res;
00245 }
00246
00247 yarp::os::Bottle ServerWorldController::setCmd( const yarp::os::Bottle& cmd ) {
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 QString objname = cmd.get(1).toString().c_str();
00260 if ( objname == "world" ) {
00261 return setWorldCmd( cmd );
00262 } else {
00263 WObject* obj = wctrl->world()->getObject( objname );
00264 if ( obj != NULL ) {
00265 return setObjectCmd( cmd, obj );
00266 }
00267 }
00268 Bottle res;
00269 res.addString( "Object not found" );
00270 return res;
00271 }
00272
00273 yarp::os::Bottle ServerWorldController::setWorldCmd( const yarp::os::Bottle& cmd ) {
00274
00275 Bottle res;
00276 QString propname = cmd.get(2).toString().c_str();
00277 if ( propname == "size" ) {
00278 real x_dim = fabs( cmd.get(3).asDouble()/2.0 );
00279 real y_dim = fabs( cmd.get(4).asDouble()/2.0 );
00280 real z_dim = fabs( cmd.get(5).asDouble() );
00281 if ( x_dim == 0 || y_dim == 0 || z_dim == 0 ) {
00282 res.addString( "Dimension of the world must be greater than zero" );
00283 return res;
00284 }
00285 wctrl->world()->setSize( wVector( -x_dim, -y_dim, 0 ), wVector( +x_dim, +y_dim, +z_dim ) );
00286 res.addString( "World Re-Sized" );
00287 } else if ( propname == "timestep" ) {
00288 real newtimestep = fabs( cmd.get(3).asDouble() );
00289 if ( newtimestep == 0 ) {
00290 res.addString( "TimeStep of the world must be greater than zero" );
00291 return res;
00292 }
00293 wctrl->world()->setTimeStep( newtimestep );
00294 res.addString( "New TimeStep setted" );
00295 } else if ( propname == "threads" ) {
00296 real numThreads = fabs( (float)(cmd.get(3).asInt()) );
00297 if ( numThreads == 0 ) {
00298 res.addString( "Threads of the world must be greater than zero" );
00299 return res;
00300 }
00301 wctrl->world()->setMultiThread( numThreads );
00302 res.addString( "Multi-Thread setted" );
00303 } else if ( propname == "realtime" ) {
00304 bool ison = ( QString(cmd.get(3).toString().c_str()) == "on" );
00305 wctrl->world()->setIsRealTime( ison );
00306 if ( ison ) {
00307 res.addString( "RealTime Activated" );
00308 } else {
00309 res.addString( "RealTime De-Activated" );
00310 }
00311 }
00312 return res;
00313 }
00314
00315 yarp::os::Bottle ServerWorldController::setObjectCmd( const yarp::os::Bottle& , WObject* ) {
00316
00317 Bottle res;
00318 res.addString( "Not Yet Implemented" );
00319 return res;
00320 }
00321
00322 WorldController::WorldController( World* w, QString name )
00323 : YarpObject( w, name ) {
00324 inport = new Port();
00325 outport = new Port();
00326 inport->open( QString( "/%1/%2:i" ).arg( world()->name() ).arg( name ).toAscii().data() );
00327 outport->open( QString( "/%1/%2:o" ).arg( world()->name() ).arg( name ).toAscii().data() );
00328 w->pushObject( this );
00329 srv = new ServerWorldController( this );
00330 srv->start();
00331 }
00332
00333 WorldController::~WorldController() {
00334 srv->terminate();
00335 inport->close();
00336 outport->close();
00337 delete srv;
00338
00339
00340
00341 }
00342
00343 void WorldController::update() {
00344 srv->applyQueuedCommands();
00345 }
00346
00347 }
00348
00349 #endif //FARSA_USE_YARP_AND_ICUB