diff --git a/doc/additionalDoc/package.h b/doc/additionalDoc/package.h index 70c1f683a3c8fdc3ca35d3cc10c6d4af981aa588..5376aae9802b190f2eaab0638d96fcd3a4864c73 100644 --- a/doc/additionalDoc/package.h +++ b/doc/additionalDoc/package.h @@ -11,12 +11,10 @@ having high level software capabilities, like plugins and scripts. The code is based on the dynamic-graph package, which provides the framework from which sot-core relies. Hence most of the code in sot-core consists of classes that derive from entities. These entities are usually -compiled and linked in their own dynamic library, as a "plugin"; hence -you may choose to include (load) in your program only the ones you -need. +compiled and linked in their own dynamic library, as a python module Aside from the entities, there is a code base to the library, libsot-core, -that provides functions and code common to all modules. All plugins +that provides functions and code common to all modules. All python modules developed here link with libsot-core. For example, common mathematical entities, definitions and functions are in that library's base. See \ref sot_core_base for a list of what's in this code base. @@ -37,7 +35,7 @@ alone is insufficient to simulate and control a robot. The following packages are recommended* in that case: \li sot-dynamic \li sot-pattern-generator -\li sot-openhrp (openhrp plugin) +\li sot-openhrp (openhrp python module) \li sot-openhrp-scripts * These packages are in development at the time of writing and may @@ -66,12 +64,12 @@ This package is centered around a base library that implements the basic classes needed for operation of the stack of tasks. For more information, see \ref sot_core_base. -\section sot_plugins Plugins +\section sot_plugins Python Modules While the main library provides a basic framework for computation of a control law using the Stack of Tasks, it is not expressive enough for typical usage scenarios (for example, controlling the humanoid robot HRP-2). Hence, several "specialized" features and tasks have been developed, -and can be used in the Stack of Tasks. For a list of plugins and a short +and can be used in the Stack of Tasks. For a list of python modules and a short description, see \ref plugins_list. \section operation Operation of the stack of tasks @@ -145,13 +143,13 @@ the dynamic-graph package). \subsection subsec_Features Features The class sot::FeatureAbstract is the base class for features. -all other classes are in entity \ref sot_plugins "plugins". +all other classes are in entity \ref sot_plugins "python modules". For more information on what is a feature, see \ref features. \subsection subsec_Tasks Tasks They are a certain number of pre-written tasks that can be used. They all derive from the task sot::TaskAbstract; specific tasks -are defined as \ref sot_plugins "plugins". +are defined as \ref sot_plugins "python modules". \subsection subsec_tools Mathematical base The following classes encapsulate common mathematical objects, and @@ -169,8 +167,8 @@ See \ref factory for additional information. -\defgroup plugins_list List of plugins -These plugins are linked with the base library. +\defgroup plugins_list List of python modules +These python modules are linked with the base library. sot/sot-qr sot/weighted-sot @@ -234,26 +232,18 @@ This code implements the factory design pattern, making creation of features, tasks and other objects available. Objects, which are derived from Entities, Tasks, or Features, can be - declared within the code and compiled to shared librairies (.so/.dll files). -These librairies can be loaded at run-time using the sotPluginLoader methods, -and at the same time register their class names to the Factory (see the -sotFactory documentation to learn how). + declared within the code and compiled to C++ python modules. These + modules can be imported at run-time and register their class names to + the Factory (see the sotFactory documentation to learn how). The Factory can then create instances of these objects and subsequently register them in the Pool, where they can be listed, accessed, and acted upon -(see sotPoolStorage documentation). Basic commands defined by entities include +(see sot::PoolStorage documentation). Basic commands defined by entities include signal connection graph file generation, help and name print, and signals. -Finally, a shell (command-line) interface is made available thanks to the -sotInterpretor class (see the file test_shell.cpp). Objects deriving from -Entity can expose their own commands by overriding the Entity's default -commandLine() method. It is possible to load a plugin to register custom -shell commands; see sotShellFunctions and sotShellProcedure for an example. - The public static objects (singletons) made available by including the corresponding headers in this module are: -\li sotFactory: sotFactoryStorage -\li sotPool: sotPoolStorage +\li sot::PoolStorage, accessed by method getInstance. \image html schema_plugin.png diff --git a/include/sot/core/pool.hh b/include/sot/core/pool.hh index 542fa79018658473ce7e8027dcda0c4e9ba02078..959c4b9d9f22e28ded73aa90e81a2a6713bceb7b 100644 --- a/include/sot/core/pool.hh +++ b/include/sot/core/pool.hh @@ -48,7 +48,7 @@ class TaskAbstract; /*! @ingroup factory - \brief This class keep tracks of all the objects in the stack of Tasks. + \brief This singleton class keep tracks of all features and tasks. Three kinds of objects are handled: \li The controllers, i.e. the tasks which inherits from TaskAbstract. @@ -99,6 +99,12 @@ class SOT_CORE_EXPORT PoolStorage /*! \brief Default destructor */ ~PoolStorage( void ); + /// \brief Get unique instance of the class + static PoolStorage* getInstance(); + + /// \brief destroy unique instance of the class + static void destroy(); + /*! \name Methods related to the handling of the features @{ */ @@ -134,9 +140,11 @@ class SOT_CORE_EXPORT PoolStorage /*! \brief This method write a graph description on the file named FileName. */ void writeGraph(const std::string &aFileName); void writeCompletionList(std::ostream& os); -}; -SOT_CORE_EXPORT extern sot::PoolStorage sotPool; + private: + PoolStorage(); + static PoolStorage* instance_; +}; } /* namespace sot */} /* namespace dynamicgraph */ diff --git a/src/factory/pool.cpp b/src/factory/pool.cpp index 87521decb1652ab62227cfa31cee65337e13dcfe..1840d6aaee8d8c617d94a4f92ef13dc15e61ed52 100644 --- a/src/factory/pool.cpp +++ b/src/factory/pool.cpp @@ -38,18 +38,18 @@ namespace dynamicgraph { /* --------------------------------------------------------------------- */ /* --- CLASS ----------------------------------------------------------- */ /* --------------------------------------------------------------------- */ - + PoolStorage:: ~PoolStorage( void ) { sotDEBUGIN(15); - - + + sotDEBUGOUT(15); return; } - - + + /* --------------------------------------------------------------------- */ void PoolStorage:: registerTask( const std::string& entname,TaskAbstract* ent ) @@ -69,7 +69,7 @@ namespace dynamicgraph { task[entname] = ent; } } - + TaskAbstract& PoolStorage:: getTask( const std::string& name ) { @@ -82,9 +82,9 @@ namespace dynamicgraph { } return *entPtr->second; } - - - + + + /* --------------------------------------------------------------------- */ void PoolStorage:: registerFeature( const std::string& entname,FeatureAbstract* ent ) @@ -104,7 +104,7 @@ namespace dynamicgraph { feature[entname] = ent; } } - + FeatureAbstract& PoolStorage:: getFeature( const std::string& name ) { @@ -117,7 +117,7 @@ namespace dynamicgraph { } return *entPtr->second; } - + void PoolStorage:: writeGraph(const std::string &aFileName) { @@ -129,7 +129,7 @@ namespace dynamicgraph { GenericName = tmp1.substr(IdxSeparatorFound,tmp1.length()); else GenericName = tmp1; - + /* Reading local time */ time_t ltime; ltime = time(NULL); @@ -139,7 +139,7 @@ namespace dynamicgraph { #else localtime_r(<ime,<imeformatted); #endif /*WIN32*/ - + /* Opening the file and writing the first comment. */ std::ofstream GraphFile; GraphFile.open(aFileName.c_str(),std::ofstream::out); @@ -158,7 +158,7 @@ namespace dynamicgraph { "fillcolor = gold1, style=filled, shape=box ] ; " << std::endl; GraphFile << "\tsubgraph cluster_Tasks { " << std::endl; GraphFile << "\t\t color=blue; label=\"Tasks\";" << std::endl; - + for( Tasks::iterator iter=task.begin(); iter!=task.end();iter++ ) { @@ -168,27 +168,43 @@ namespace dynamicgraph { <<"\t\t fontcolor = black, color = black, " "fillcolor = magenta, style=filled, shape=box ]" << std::endl; } - - + + GraphFile << "}"<< std::endl; - + GraphFile.close(); } - + void PoolStorage:: writeCompletionList(std::ostream& /*os*/ ) { } - - + + void PoolStorage:: - commandLine( const std::string& objectName,const std::string& functionName, - std::istringstream& cmdArg, std::ostream& os ) + commandLine( const std::string&,const std::string&, + std::istringstream&, std::ostream& ) { } - - /// The global sotPool object - - PoolStorage sotPool; + + + PoolStorage* PoolStorage::getInstance() + { + if (instance_ == 0) { + instance_ = new PoolStorage; + } + return instance_; + } + void PoolStorage::destroy() + { + delete instance_; + instance_ = 0; + } + + PoolStorage::PoolStorage() + { + } + + PoolStorage* PoolStorage::instance_ = 0; } // namespace sot } // namespace dynamicgraph diff --git a/src/feature/feature-abstract.cpp b/src/feature/feature-abstract.cpp index 3d93e4d20a0fee6b679a7684b28fa3f9bc1d801c..dc1f0cdcc907f8f899ed3493fc48a63da1cbba5a 100644 --- a/src/feature/feature-abstract.cpp +++ b/src/feature/feature-abstract.cpp @@ -57,7 +57,7 @@ FeatureAbstract( const std::string& name ) void FeatureAbstract:: featureRegistration( void ) { - sotPool.registerFeature(name,this); + PoolStorage::getInstance()->registerFeature(name,this); } diff --git a/src/signal/signal-cast.cpp b/src/signal/signal-cast.cpp index 8aefab6fa37a76b2c8e435dc659996f9e866da6e..07875ae929aa004decb854e74c3868412fe826d0 100644 --- a/src/signal/signal-cast.cpp +++ b/src/signal/signal-cast.cpp @@ -76,7 +76,7 @@ namespace dynamicgraph std::string name; iss >> name; if( name.length()) { - ref = &sotPool.getFeature(name); + ref = &dynamicgraph::sot::PoolStorage::getInstance()->getFeature(name); } else { ref = NULL; } return ref; diff --git a/src/sot/sot-command.h b/src/sot/sot-command.h index 10803d9def3f0c6a797c7229da78c446d778761a..ad127fa3d4265609a1d5f44ed55c5940cd5a1e8e 100644 --- a/src/sot/sot-command.h +++ b/src/sot/sot-command.h @@ -51,7 +51,8 @@ namespace dynamicgraph { namespace sot { std::string constraintName = values[0].value(); Constraint& constraint = - dynamic_cast<Constraint&>(sotPool.getTask(constraintName)); + dynamic_cast<Constraint&>(PoolStorage::getInstance()-> + getTask(constraintName)); sot.addConstraint(constraint); sot.constraintSOUT.setReady(); // return void @@ -77,7 +78,7 @@ namespace dynamicgraph { namespace sot { std::vector<Value> values = getParameterValues(); std::string taskName = values[0].value(); - TaskAbstract& task = sotPool.getTask(taskName); + TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName); sot.push(task); // return void return Value(); @@ -102,7 +103,7 @@ namespace dynamicgraph { namespace sot { std::vector<Value> values = getParameterValues(); std::string taskName = values[0].value(); - TaskAbstract& task = sotPool.getTask(taskName); + TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName); sot.remove(task); // return void return Value(); @@ -127,7 +128,7 @@ namespace dynamicgraph { namespace sot { std::vector<Value> values = getParameterValues(); std::string taskName = values[0].value(); - TaskAbstract& task = sotPool.getTask(taskName); + TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName); sot.up(task); // return void return Value(); @@ -152,7 +153,7 @@ namespace dynamicgraph { namespace sot { std::vector<Value> values = getParameterValues(); std::string taskName = values[0].value(); - TaskAbstract& task = sotPool.getTask(taskName); + TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName); sot.down(task); // return void return Value(); diff --git a/src/sot/sot-qr.cpp b/src/sot/sot-qr.cpp index d09aaed193377bbbf76db6088fbdbe2e681796cf..f7a74e42b8b220ac1418060fa3ff4db544e40cb7 100644 --- a/src/sot/sot-qr.cpp +++ b/src/sot/sot-qr.cpp @@ -992,128 +992,6 @@ void SotQr:: commandLine( const std::string& cmdLine,std::istringstream& cmdArgs, std::ostream& os ) { - sotDEBUGIN(15); - - if( cmdLine == "help") - { - os << "Stack of Tasks: "<<endl - << " - push <task>"<< endl - << " - pop"<< endl - << " - down <task>"<< endl - << " - up <task>"<< endl - << " - rm <task>"<< endl - << " - clear"<< endl - << " - display"<< endl - - << " - addConstraint <constraint> "<<endl - << " - rmConstraint <constraint> "<<endl - << " - clearConstraint"<<endl - << " - printConstraint "<<endl - - << " - nbJoints <nb> "<<endl; - Entity::commandLine( cmdLine,cmdArgs,os ); - } - else if( cmdLine == "clear") - { - clear(); - } - else if( cmdLine == "push") - { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - push(task); - } - else if( cmdLine == "gradient") - { - std::string tname; cmdArgs >> std::ws; - if( cmdArgs.good() ) - { - cmdArgs >> tname; - if( ( "0"==tname )||( "rm"==tname ) ) - { taskGradient = 0; } - else - { - TaskAbstract & task = sotPool.getTask( tname ); - taskGradient = &task; - } - } - else - { - os << "gradient = "; - if( taskGradient ) os << (*taskGradient) << std::endl; - else os << "undef. " << std::endl; - } - controlSOUT.setReady(); - } - else if( cmdLine == "up") - { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - up(task); - } - else if( cmdLine == "down") - { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - down(task); - } - else if( cmdLine == "rm") - { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - remove(task); - } - else if( cmdLine == "pop") - { - TaskAbstract& task = pop(); - os << "Remove : "<< task << std::endl; - } - - else if( cmdLine == "addConstraint" ) - { - std::string cstname; cmdArgs >> cstname; - Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname )); - addConstraint( cs ); - constraintSOUT.setReady(); - } - else if( cmdLine == "rmConstraint" ) - { - std::string cstname; cmdArgs >> cstname; - Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname )); - removeConstraint( cs ); - constraintSOUT.setReady(); - } - else if( cmdLine == "clearConstraint" ) - { - clearConstraint( ); - constraintSOUT.setReady(); - } - else if( cmdLine == "printConstraint" ) - { - os<< "Constraints: "<<std::endl; - for( ConstraintListType::iterator it = constraintList.begin(); - it!=constraintList.end();++it ) - { os<< " - "<< (*it)->getName() << endl; } - } - else if( cmdLine == "nbJoints") - { - cmdArgs>>ws; - if( cmdArgs.good() ) - { - cmdArgs >> nbJoints; - } else { os << "nbJoints = "<< nbJoints <<endl; } - constraintSOUT.setReady(); - controlSOUT.setReady(); - } - else if( cmdLine == "display") - { - display(os); - } - else - Entity::commandLine( cmdLine,cmdArgs,os ); - - - sotDEBUGOUT(15); } std::ostream& SotQr:: diff --git a/src/sot/sot.cpp b/src/sot/sot.cpp index 4f41c1d212ddcb825ba3c5065f327547f52450ec..2fd0f793596fcab710ffd783cd27ae80999faf6a 100644 --- a/src/sot/sot.cpp +++ b/src/sot/sot.cpp @@ -899,9 +899,6 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs, } else if( cmdLine == "push") { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - push(task); } else if( cmdLine == "gradient") { @@ -913,8 +910,6 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs, { taskGradient = 0; } else { - TaskAbstract & task = sotPool.getTask( tname ); - taskGradient = &task; } } else @@ -927,21 +922,12 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs, } else if( cmdLine == "up") { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - up(task); } else if( cmdLine == "down") { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - down(task); } else if( cmdLine == "rm") { - std::string tname; cmdArgs >> tname; - TaskAbstract & task = sotPool.getTask( tname ); - remove(task); } else if( cmdLine == "pop") { @@ -951,17 +937,9 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs, else if( cmdLine == "addConstraint" ) { - std::string cstname; cmdArgs >> cstname; - Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname )); - addConstraint( cs ); - constraintSOUT.setReady(); } else if( cmdLine == "rmConstraint" ) { - std::string cstname; cmdArgs >> cstname; - Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname )); - removeConstraint( cs ); - constraintSOUT.setReady(); } else if( cmdLine == "clearConstraint" ) { diff --git a/src/task/task-abstract.cpp b/src/task/task-abstract.cpp index 28581d03d61a0b57e8af6dfcbcae3c62041cc925..2dca7ba69425c784aeb039dd36cbd0c1e0daf2ce 100644 --- a/src/task/task-abstract.cpp +++ b/src/task/task-abstract.cpp @@ -52,7 +52,7 @@ TaskAbstract( const std::string& n ) void TaskAbstract:: taskRegistration( void ) { - sotPool.registerTask(name,this); + PoolStorage::getInstance()->registerTask(name,this); } diff --git a/src/task/task-command.h b/src/task/task-command.h index 0ed72515ebb5a1a8a906fdc918a794eab6f63bc4..806b7d4694b8b24dab5e7f8bc4ea9502a9254fb8 100644 --- a/src/task/task-command.h +++ b/src/task/task-command.h @@ -49,7 +49,8 @@ namespace dynamicgraph { namespace sot { Task& task = static_cast<Task&>(owner()); std::vector<Value> values = getParameterValues(); std::string featureName = values[0].value(); - FeatureAbstract& feature = sotPool.getFeature(featureName); + FeatureAbstract& feature = + PoolStorage::getInstance()->getFeature(featureName); task.addFeature(feature); // return void return Value(); diff --git a/src/task/task.cpp b/src/task/task.cpp index f9cc07f50c55a83b0bb841f48a73809e2864befe..9bc5cc28020d0f39115f68abb786c9dff50b3145 100644 --- a/src/task/task.cpp +++ b/src/task/task.cpp @@ -370,9 +370,6 @@ commandLine( const std::string& cmdLine } else if( cmdLine=="add" ) { - std::string f; cmdArgs >> f; - FeatureAbstract& feat = sotPool.getFeature( f ); - addFeature( feat ); } else if( cmdLine=="selec" ) {