Revision: 4469
          http://playerstage.svn.sourceforge.net/playerstage/?rev=4469&view=rev
Author:   robotos
Date:     2008-04-02 05:07:33 -0700 (Wed, 02 Apr 2008)

Log Message:
-----------

Two changes:
Controller plugins: Patch 1909966 by David Olsen 
Simplify Gazebo error (gzthrow) usage

Modified Paths:
--------------
    code/gazebo/trunk/SConstruct
    code/gazebo/trunk/server/GazeboError.hh
    code/gazebo/trunk/server/Model.cc
    code/gazebo/trunk/server/SConscript
    code/gazebo/trunk/server/Simulator.cc
    code/gazebo/trunk/server/XMLConfig.cc
    code/gazebo/trunk/server/controllers/ControllerFactory.cc
    code/gazebo/trunk/server/controllers/ControllerFactory.hh
    code/gazebo/trunk/server/controllers/SConscript
    code/gazebo/trunk/server/gui/SConscript
    code/gazebo/trunk/server/physics/SConscript
    code/gazebo/trunk/server/rendering/SConscript
    code/gazebo/trunk/server/sensors/SConscript
    code/gazebo/trunk/server/sensors/Sensor.cc

Modified: code/gazebo/trunk/SConstruct
===================================================================
--- code/gazebo/trunk/SConstruct        2008-04-01 22:53:29 UTC (rev 4468)
+++ code/gazebo/trunk/SConstruct        2008-04-02 12:07:33 UTC (rev 4469)
@@ -56,6 +56,7 @@
     
   #LIBS=Split('gazebo boost_python')
   LIBS=Split('gazebo'),
+  LINKFLAGS=Split('-export-dynamic'),
 
   TARFLAGS = '-c -z',
   TARSUFFIX = '.tar.gz',
@@ -134,6 +135,13 @@
   if not conf.CheckCHeader('ode/ode.h'):
     print "  Error: Install ODE (http://www.ode.org)"
     Exit(1)
+    
+  if not conf.CheckLibWithHeader('ltdl','ltdl.h','CXX'):
+    print "  Warning: Failed to find ltdl, no plugin support will be included"
+    env["HAVE_LTDL"]=False
+  else:
+    env["HAVE_LTDL"]=True
+    env["CCFLAGS"].append("-DHAVE_LTDL")
    
   # Check for trimesh support in ODE
   if not conf.CheckODELib():

Modified: code/gazebo/trunk/server/GazeboError.hh
===================================================================
--- code/gazebo/trunk/server/GazeboError.hh     2008-04-01 22:53:29 UTC (rev 
4468)
+++ code/gazebo/trunk/server/GazeboError.hh     2008-04-02 12:07:33 UTC (rev 
4469)
@@ -34,27 +34,32 @@
 
 namespace gazebo
 {
-  
   /// \addtogroup gazebo_server
   /// \brief Gazebo error class
   /// \{
 
+  //TODO: global variable, static in the class would be better, if only the 
linker didn't oppose to it ...
+  static std::ostringstream throwStream;
   /// Throw an error
-  #define gzthrow(msg) throw 
gazebo::GazeboError(__FILE__,__LINE__,std::string(msg))
+  #define gzthrow(msg) throwStream << "Exception: " << msg << std::endl << 
std::flush;\
+                       throw 
gazebo::GazeboError(__FILE__,__LINE__,throwStream.str())
+
   
   /// \brief Class to handle errors
   ///
   /**
-   Use <tt>gzthrow(std::string)</tt> to throw errors.
+   Use <tt>gzthrow(data1 << data2)</tt> to throw errors.
 
    Example:
    
    \verbatim
+   Recommended new way:
+   gzthrow("This is an error message of type[" << type << "]");
+   Old way:
    std::ostringstream stream;
    stream << "This is an error message of type[" << type << "]\n";
    gzthrow(stream.str());
-   or if type is a string, simply:
-   gzthrow("This is an error message of type[" + type + "]\n");
+   The final "\n" is not needed anymore, the code should be changed to the new 
type.
    \endverbatim
 
   */
@@ -86,7 +91,7 @@
     /// \brief Return the error string
     /// \return The error string
     public: std::string GetErrorStr() const; 
-  
+
     /// \brief The error function
     private: std::string file;
   

Modified: code/gazebo/trunk/server/Model.cc
===================================================================
--- code/gazebo/trunk/server/Model.cc   2008-04-01 22:53:29 UTC (rev 4468)
+++ code/gazebo/trunk/server/Model.cc   2008-04-02 12:07:33 UTC (rev 4469)
@@ -544,6 +544,11 @@
 
   // Get the unique name of the controller
   std::string controllerName = node->GetString("name",std::string(),1);
+  
+  // See if the controller is in a plugin
+  std::string pluginName = node->GetString("plugin","",0);
+  if (pluginName != "")
+         ControllerFactory::LoadPlugin(pluginName, controllerType);
 
   // Create the controller based on it's type
   controller = ControllerFactory::NewController(controllerType, this);

Modified: code/gazebo/trunk/server/SConscript
===================================================================
--- code/gazebo/trunk/server/SConscript 2008-04-01 22:53:29 UTC (rev 4468)
+++ code/gazebo/trunk/server/SConscript 2008-04-02 12:07:33 UTC (rev 4469)
@@ -24,20 +24,23 @@
            ]
 
 headers.append( 
-          ['#/server/Global.hh',
-           '#/server/Vector3.hh', 
+          ['#/server/Entity.hh',
+           '#/server/GazeboError.hh',
+           '#/server/GazeboMessage.hh',
+           '#/server/Global.hh',
+           '#/server/Model.hh',
+           '#/server/Pose3d.hh',
            '#/server/Quatern.hh',
-           '#/server/Pose3d.hh',
-           '#/server/World.hh',
-           '#/server/XMLConfig.hh',
+           '#/server/Simulator.hh',
+           '#/server/SingletonT.hh',
+           '#/server/StaticPluginRegister.hh',
+           '#/server/StringValue.hh',
            '#/server/Time.hh',
-           '#/server/Entity.hh',
-           '#/server/GazeboError.hh',
            '#/server/UpdateParams.hh',
-           '#/server/GazeboMessage.hh',
-           '#/server/Model.hh',
-           '#/server/Simulator.hh', 
-           '#/server/StringValue.hh'
+           '#/server/Vector2.hh', 
+           '#/server/Vector3.hh',
+           '#/server/World.hh',
+           '#/server/XMLConfig.hh'
            ] )
 
 staticObjs.append( env.StaticObject(sources) )

Modified: code/gazebo/trunk/server/Simulator.cc
===================================================================
--- code/gazebo/trunk/server/Simulator.cc       2008-04-01 22:53:29 UTC (rev 
4468)
+++ code/gazebo/trunk/server/Simulator.cc       2008-04-02 12:07:33 UTC (rev 
4469)
@@ -101,17 +101,13 @@
 
   // Load the world file
   this->xmlFile=new gazebo::XMLConfig();
-
   try
   {
     xmlFile->Load(worldFileName);
   }
   catch (GazeboError e)
   {
-    std::ostringstream stream;
-    stream << "The XML config file can not be loaded, please make sure is a 
correct file\n"
-    << e << "\n";
-    gzthrow(stream.str());
+    gzthrow("The XML config file can not be loaded, please make sure is a 
correct file\n" << e); 
   }
 
   XMLConfigNode *rootNode(xmlFile->GetRootNode());
@@ -126,10 +122,7 @@
   }
   catch (GazeboError e)
   {
-    std::ostringstream stream;
-    stream << "Error loading the GUI\n"
-    << e << "\n";
-    gzthrow(stream.str());
+    gzthrow( "Error loading the GUI\n" << e);
   }
 
   //Initialize RenderingEngine
@@ -139,11 +132,8 @@
   }
   catch (gazebo::GazeboError e)
   {
-    std::ostringstream stream;
-    stream << "Failed to Initialize the OGRE Rendering system\n"
-    << e << "\n";
-    gzthrow(stream.str());
-  }
+    gzthrow("Failed to Initialize the OGRE Rendering system\n" << e );
+ }
 
   //Preload basic shapes that can be used anywhere
   OgreCreator::CreateBasicShapes();
@@ -155,10 +145,7 @@
   }
   catch (GazeboError e)
   {
-    std::ostringstream stream;
-    stream << "Error loading the GUI\n"
-    << e << "\n";
-    gzthrow(stream.str());
+    gzthrow("Failed to load the GUI\n"  << e);
   }
 
   this->loaded=true;
@@ -178,10 +165,8 @@
 
   if (xmlFile->Save(filename)<0)
   {
-    std::ostringstream stream;
-    stream << "The XML file coult not be written back to " << filename << 
std::endl;
-    gzthrow(stream.str());
-  }
+   gzthrow("The XML file could not be written back to " << filename );
+   }
 }
 
 
@@ -376,7 +361,7 @@
     int x = childNode->GetTupleInt("pos",0,0);
     int y = childNode->GetTupleInt("pos",1,0);
     std::string type = childNode->GetString("type","fltk",1);
-
+ 
     gzmsg(1) << "Creating GUI:\n\tType[" << type << "] Pos[" << x << " " << y 
<< "] Size[" << width << " " << height << "]\n";
     if (type != "fltk")
     {
@@ -393,7 +378,7 @@
   else
   {
     // Create a dummy GUI
-    gzmsg(1) << "Creating a dummy GUI\n";
+    gzmsg(1) <<"Creating a dummy GUI";
     this->gui = GuiFactory::NewGui(std::string("dummy"), 0, 0, 0, 0, 
std::string());
   }
 }

Modified: code/gazebo/trunk/server/XMLConfig.cc
===================================================================
--- code/gazebo/trunk/server/XMLConfig.cc       2008-04-01 22:53:29 UTC (rev 
4468)
+++ code/gazebo/trunk/server/XMLConfig.cc       2008-04-02 12:07:33 UTC (rev 
4469)
@@ -65,7 +65,6 @@
 // Load world from file
 void XMLConfig::Load( const std::string &filename )
 {
-  std::ostringstream stream;
   this->filename = filename;
 
   // Enable line numbering
@@ -75,8 +74,7 @@
   this->xmlDoc = xmlParseFile( this->filename.c_str() );
   if (xmlDoc == NULL)
   {
-    stream << "Unable to parse xml file: " << this->filename;
-    gzthrow(stream.str());
+    gzthrow( "Unable to parse xml file: " << this->filename);
   }
 
   // Create xpath evaluation context
@@ -97,8 +95,7 @@
   this->root = this->CreateNodes( NULL, xmlDocGetRootElement(this->xmlDoc) );
   if (this->root == NULL)
   {
-    stream << "Empty document [" << this->filename << "]";
-    gzthrow(stream.str());
+    gzthrow( "Empty document [" << this->filename << "]");
   }
 }
 
@@ -111,9 +108,7 @@
   this->xmlDoc = xmlParseDoc( (xmlChar*)(str.c_str()) );
   if (xmlDoc == NULL)
   {
-    std::ostringstream stream;
-    stream << "unable to parse [" << str << "]";
-    gzthrow(stream.str());
+    gzthrow("unable to parse [" << str << "]");
   }
 
   // Create wrappers for all the nodes (recursive)
@@ -122,9 +117,7 @@
 
   if (this->root == NULL)
   {
-    std::ostringstream stream;
-    stream << "Empty document [" << str << "\n";
-    gzthrow(stream.str());
+    gzthrow( "Empty document [" << str<< "]") ;
   }
 }
 
@@ -409,8 +402,7 @@
 {
   XMLConfigNode *node;
 
-  std::cout << "name = [" << (const char*) this->xmlNode->name
-  << "]\n";
+  gzmsg(2) << "name = [" << (const char*) this->xmlNode->name << "]\n";
 
   // Recurse
   for (node = this->childFirst; node != NULL; node = node->next)
@@ -482,9 +474,7 @@
 
   if (!value && require)
   {
-    std::ostringstream stream;
-    stream << "unable to find required string attribute[" << key << "] in 
world file node[" << this->GetName() << "]";
-    gzthrow(stream.str());
+    gzthrow( "unable to find required string attribute[" << key << "] in world 
file node[" << this->GetName() << "]");
   }
   else if ( !value )
     return def;
@@ -501,9 +491,7 @@
 
   if (!value && require)
   {
-    std::ostringstream stream;
-    stream << "unable to find required char attribute[" << key << "] in world 
file node[" << this->GetName() << "]";
-    gzthrow(stream.str());
+    gzthrow("unable to find required char attribute[" << key << "] in world 
file node[" << this->GetName() << "]");
   }
   else if ( !value )
     return def;
@@ -553,9 +541,7 @@
 
   if (!value && require)
   {
-    std::ostringstream stream;
-    stream << "unable to find required int attribute[" << key << "] in world 
file node[" << this->GetName() << "]";
-    gzthrow(stream.str());
+    gzthrow ("unable to find required int attribute[" << key << "] in world 
file node[" << this->GetName() << "]");
   }
   else if ( !value )
     return def;
@@ -572,9 +558,7 @@
 
   if (!value && require)
   {
-    std::ostringstream stream;
-    stream << "unable to find required double attribute[" << key << "] in 
world file node[" << this->GetName() << "]";
-    gzthrow(stream.str());
+    gzthrow( "unable to find required double attribute[" << key << "] in world 
file node[" << this->GetName() << "]");
   }
   else if ( !value )
     return def;
@@ -590,9 +574,7 @@
 
   if (!value && require)
   {
-    std::ostringstream stream;
-    stream << "unable to find required float attribute[" << key << "] in world 
file node[" << this->GetName() << "]";
-    gzthrow(stream.str());
+    gzthrow( "unable to find required float attribute[" << key << "] in world 
file node[" << this->GetName() << "]");
   }
   else if ( !value )
     return def;
@@ -611,9 +593,7 @@
   if (!value && require)
   {
     xmlFree(value);
-    std::ostringstream stream;
-    stream << "unable to find required bool attribute[" << key << "] in world 
file node[" << this->GetName() << "]";
-    gzthrow(stream.str());
+    gzthrow( "unable to find required bool attribute[" << key << "] in world 
file node[" << this->GetName() << "]");
   }
   else if ( !value )
   {
@@ -925,9 +905,7 @@
     newNode = xmlNewNode(0, (xmlChar*) key); //I hope we don't need namespaces 
here
     if (!newNode)
     {
-      std::ostringstream stream;
-      stream << "unable to create an element [" << key << "] in world file 
node[" << this->GetName() << "]";
-      gzthrow(stream.str());
+      gzthrow( "unable to create an element [" << key << "] in world file 
node[" << this->GetName() << "]");
     }
     xmlNodeSetContent(newNode, (xmlChar*) value);
     xmlAddChild(this->xmlNode, newNode);

Modified: code/gazebo/trunk/server/controllers/ControllerFactory.cc
===================================================================
--- code/gazebo/trunk/server/controllers/ControllerFactory.cc   2008-04-01 
22:53:29 UTC (rev 4468)
+++ code/gazebo/trunk/server/controllers/ControllerFactory.cc   2008-04-02 
12:07:33 UTC (rev 4469)
@@ -30,6 +30,9 @@
 #include "gazebo.h"
 #include "Controller.hh"
 #include "ControllerFactory.hh"
+#ifdef HAVE_LTDL
+#include <ltdl.h>
+#endif // HAVE_LTDL
 
 using namespace gazebo;
 
@@ -60,3 +63,52 @@
 
   return NULL;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// Load a controller plugin. Used by Model and Sensor when creating 
controllers.
+void ControllerFactory::LoadPlugin(const std::string &plugin, const 
std::string &classname)
+{
+#ifdef HAVE_LTDL
+       
+       static bool init_done = false;
+
+       if (!init_done)
+       {
+               int errors = lt_dlinit();
+               if (errors)
+               {
+                       std::ostringstream stream;
+                   stream << "Error(s) initializing dynamic loader (" << 
errors << ", " << lt_dlerror() << ")";
+                   gzthrow(stream.str());
+               }
+               else
+                       init_done = true;
+       }
+       
+       lt_dlhandle handle = lt_dlopenext(plugin.c_str());
+       
+       if (!handle)
+       {
+               std::ostringstream stream;
+               stream << "Failed to load " << plugin << ": " << lt_dlerror();
+               gzthrow(stream.str());
+       }
+       
+       std::string registerName = "RegisterPluginController";
+       void *(*registerFunc)() = (void *(*)())lt_dlsym(handle, 
registerName.c_str());
+       if(!registerFunc)
+       {
+       std::ostringstream stream;
+       stream << "Failed to resolve " << registerName << ": " << lt_dlerror();
+       gzthrow(stream.str());
+       }
+       
+       // Register the new controller.
+       registerFunc();
+       
+#else // HAVE_LTDL
+       
+    gzthrow("Cannot load plugins as libtool is not installed.");
+       
+#endif // HAVE_LTDL
+}

Modified: code/gazebo/trunk/server/controllers/ControllerFactory.hh
===================================================================
--- code/gazebo/trunk/server/controllers/ControllerFactory.hh   2008-04-01 
22:53:29 UTC (rev 4468)
+++ code/gazebo/trunk/server/controllers/ControllerFactory.hh   2008-04-02 
12:07:33 UTC (rev 4469)
@@ -58,6 +58,9 @@
   /// \brief Create a new instance of a controller.  Used by the world when
   /// reading the world file.
   public: static Controller *NewController(const std::string &classname, 
Entity *parent);
+  
+  /// \brief Load a controller plugin. Used by Model and Sensor when creating 
controllers.
+  public: static void LoadPlugin(const std::string &plugin, const std::string 
&classname);
 
   // A list of registered controller classes
   private: static std::map<std::string, ControllerFactoryFn> controllers;
@@ -81,6 +84,22 @@
 }\
 StaticPluginRegister Registered##classname (Register##classname);
 
+/// \brief Dynamic controller registration macro
+///
+/// Use this macro to register plugin controllers with the server.
+/// \param name Controller type name, as it appears in the world file.
+/// \param classname C++ class name for the controller.
+#define GZ_REGISTER_DYNAMIC_CONTROLLER(name, classname) \
+Controller *New##classname(Entity *entity) \
+{ \
+  return new classname(entity); \
+} \
+extern "C" void RegisterPluginController(); \
+void RegisterPluginController() \
+{\
+  ControllerFactory::RegisterController("dynamic", name, New##classname);\
+}
+
 /// \}
 }
 

Modified: code/gazebo/trunk/server/controllers/SConscript
===================================================================
--- code/gazebo/trunk/server/controllers/SConscript     2008-04-01 22:53:29 UTC 
(rev 4468)
+++ code/gazebo/trunk/server/controllers/SConscript     2008-04-02 12:07:33 UTC 
(rev 4469)
@@ -1,5 +1,5 @@
 #Import variable
-Import('env staticObjs sharedObjs')
+Import('env staticObjs sharedObjs headers')
 
 dirs = Split('position2d laser camera factory gripper actarray ptz')
 
@@ -11,5 +11,11 @@
 
 sources = Split('Controller.cc ControllerFactory.cc')
 
+headers.append( 
+          ['#/server/controllers/ControllerFactory.hh',
+           '#/server/controllers/ControllerStub.hh',
+           '#/server/controllers/Controller.hh'
+           ] )
+
 staticObjs.append(env.StaticObject(sources))
 sharedObjs.append(env.SharedObject(sources))

Modified: code/gazebo/trunk/server/gui/SConscript
===================================================================
--- code/gazebo/trunk/server/gui/SConscript     2008-04-01 22:53:29 UTC (rev 
4468)
+++ code/gazebo/trunk/server/gui/SConscript     2008-04-02 12:07:33 UTC (rev 
4469)
@@ -1,5 +1,5 @@
 #Import variable
-Import('env staticObjs sharedObjs')
+Import('env staticObjs sharedObjs headers')
 
 #sources = Split('Gui.cc GuiFactory.cc GLWindow.cc MainMenu.cc Toolbar.cc 
StatusBar.cc')
 
@@ -8,7 +8,16 @@
 #if conf.CheckCHeader('GL/glx.h'):
 sources = Split('Gui.cc DummyGui.cc GuiFactory.cc GLWindow.cc MainMenu.cc 
Toolbar.cc StatusBar.cc')
 #env = conf.Finish()
-    
 
+headers.append( 
+          ['server/gui/DummyGui.hh',
+           'server/gui/GLWindow.hh',
+           'server/gui/GuiFactory.hh',
+           'server/gui/Gui.hh',
+           'server/gui/MainMenu.hh',
+           'server/gui/StatusBar.hh',
+           'server/gui/Toolbar.hh'
+           ] )
+
 staticObjs.append(env.StaticObject(sources))
 sharedObjs.append(env.SharedObject(sources))

Modified: code/gazebo/trunk/server/physics/SConscript
===================================================================
--- code/gazebo/trunk/server/physics/SConscript 2008-04-01 22:53:29 UTC (rev 
4468)
+++ code/gazebo/trunk/server/physics/SConscript 2008-04-02 12:07:33 UTC (rev 
4469)
@@ -1,5 +1,5 @@
 #Import variable
-Import('env staticObjs sharedObjs')
+Import('env staticObjs sharedObjs headers')
 
 dirs = Split('ode')
 
@@ -8,5 +8,25 @@
 
 sources = Split('BallJoint.cc Body.cc BoxGeom.cc ContactParams.cc 
CylinderGeom.cc Geom.cc Hinge2Joint.cc HingeJoint.cc Joint.cc PhysicsEngine.cc 
PlaneGeom.cc SliderJoint.cc SphereGeom.cc UniversalJoint.cc RayGeom.cc 
TrimeshGeom.cc HeightmapGeom.cc')
 
+headers.append( 
+          ['server/physics/BallJoint.hh',
+           'server/physics/Body.hh',
+           'server/physics/BoxGeom.hh',
+           'server/physics/ContactParams.hh',
+           'server/physics/CylinderGeom.hh',
+           'server/physics/Geom.hh',
+           'server/physics/HeightmapGeom.hh',
+           'server/physics/Hinge2Joint.hh',
+           'server/physics/HingeJoint.hh',
+           'server/physics/Joint.hh',
+           'server/physics/PhysicsEngine.hh',
+           'server/physics/PlaneGeom.hh',
+           'server/physics/RayGeom.hh',
+           'server/physics/SliderJoint.hh',
+           'server/physics/SphereGeom.hh',
+           'server/physics/TrimeshGeom.hh',
+           'server/physics/UniversalJoint.hh'
+           ] )
+
 staticObjs.append( env.StaticObject(sources) )
 sharedObjs.append( env.SharedObject(sources) )

Modified: code/gazebo/trunk/server/rendering/SConscript
===================================================================
--- code/gazebo/trunk/server/rendering/SConscript       2008-04-01 22:53:29 UTC 
(rev 4468)
+++ code/gazebo/trunk/server/rendering/SConscript       2008-04-02 12:07:33 UTC 
(rev 4469)
@@ -1,7 +1,19 @@
 #Import variable
-Import('env staticObjs sharedObjs')
+Import('env staticObjs sharedObjs headers')
 
 sources = Split('OgreCreator.cc OgreAdaptor.cc OgreFrameListener.cc 
OgreDynamicRenderable.cc OgreDynamicLines.cc OgreSimpleShape.cc OgreHUD.cc 
MovableText.cc OgreVisual.cc')
 
+headers.append( 
+          ['#/server/rendering/MovableText.hh',
+           '#/server/rendering/OgreAdaptor.hh',
+           '#/server/rendering/OgreCreator.hh',
+           '#/server/rendering/OgreDynamicLines.hh',
+           '#/server/rendering/OgreDynamicRenderable.hh',
+           '#/server/rendering/OgreFrameListener.hh',
+           '#/server/rendering/OgreHUD.hh',
+           '#/server/rendering/OgreSimpleShape.hh',
+           '#/server/rendering/OgreVisual.hh'
+           ] )
+
 staticObjs.append( env.StaticObject(sources) )
 sharedObjs.append( env.SharedObject(sources) )

Modified: code/gazebo/trunk/server/sensors/SConscript
===================================================================
--- code/gazebo/trunk/server/sensors/SConscript 2008-04-01 22:53:29 UTC (rev 
4468)
+++ code/gazebo/trunk/server/sensors/SConscript 2008-04-02 12:07:33 UTC (rev 
4469)
@@ -1,5 +1,5 @@
 #Import variable
-Import('env staticObjs sharedObjs')
+Import('env staticObjs sharedObjs headers')
 
 dirs = Split('camera ray')
 
@@ -8,5 +8,11 @@
 
 sources = Split('Sensor.cc SensorFactory.cc')
 
+headers.append( 
+          ['server/sensors/SensorFactory.hh',
+           'server/sensors/SensorStub.hh',
+           'server/sensors/Sensor.hh'
+           ] )
+
 staticObjs.append( env.StaticObject(sources) )
 sharedObjs.append( env.SharedObject(sources) )

Modified: code/gazebo/trunk/server/sensors/Sensor.cc
===================================================================
--- code/gazebo/trunk/server/sensors/Sensor.cc  2008-04-01 22:53:29 UTC (rev 
4468)
+++ code/gazebo/trunk/server/sensors/Sensor.cc  2008-04-02 12:07:33 UTC (rev 
4469)
@@ -127,6 +127,11 @@
     stream << "No interface defined for " << controllerName << "controller";
     gzthrow(stream.str());
   }*/
+  
+  // See if the controller is in a plugin
+  std::string pluginName = node->GetString("plugin","",0);
+  if (pluginName != "")
+    ControllerFactory::LoadPlugin(pluginName, controllerType);
 
   // Create the controller based on it's type
   this->controller = ControllerFactory::NewController(controllerType, this);


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to