Revision: 7404
          http://playerstage.svn.sourceforge.net/playerstage/?rev=7404&view=rev
Author:   gerkey
Date:     2009-03-09 19:14:49 +0000 (Mon, 09 Mar 2009)

Log Message:
-----------
Added duplicate model-checking to the Load step. When loaded from a world
file, duplicates cause an abort; from factory, new model overwrites old
one.  Working on performance test client for webgazebo.

Modified Paths:
--------------
    code/branches/federation/gazebo/server/Model.cc
    code/branches/federation/gazebo/server/Model.hh
    code/branches/federation/gazebo/server/World.cc
    code/branches/federation/gazebo/server/World.hh
    code/branches/federation/gazebo/server/controllers/factory/Factory.cc
    code/branches/federation/gazebo/webgazebo/SConscript
    code/branches/federation/gazebo/webgazebo/WebGazebo.cc
    code/branches/federation/gazebo/webgazebo/WebGazebo.hh
    code/branches/federation/gazebo/webgazebo/main.cc
    code/branches/federation/gazebo/worlds/federation.world

Added Paths:
-----------
    code/branches/federation/gazebo/webgazebo/client.cc

Modified: code/branches/federation/gazebo/server/Model.cc
===================================================================
--- code/branches/federation/gazebo/server/Model.cc     2009-03-09 08:36:48 UTC 
(rev 7403)
+++ code/branches/federation/gazebo/server/Model.cc     2009-03-09 19:14:49 UTC 
(rev 7404)
@@ -117,12 +117,29 @@
 
 
////////////////////////////////////////////////////////////////////////////////
 // Load the model
-int Model::Load(XMLConfigNode *node)
+int Model::Load(XMLConfigNode *node, bool removeDuplicate)
 {
   XMLConfigNode *childNode;
   Pose3d pose;
+  Model* dup;
 
   this->nameP->Load(node);
+  // Look for existing models by the same name
+  if((dup = World::Instance()->GetModelByName(this->nameP->GetValue())) != 
NULL)
+  {
+    if(!removeDuplicate)
+    {
+      gzthrow("Duplicate model name" + this->nameP->GetValue() + "\n");
+    }
+    else
+    {
+      // Delete the existing one (this should only be reached when called
+      // via the factory interface).
+      printf("Queuing duplicate model %s (%p) for deletion\n", 
this->nameP->GetValue().c_str(), dup);
+      World::Instance()->DeleteEntity(this->nameP->GetValue().c_str());
+    }
+  }
+
   this->staticP->Load(node);
 
   this->canonicalBodyNameP->Load(node);
@@ -203,18 +220,18 @@
   // Import the python module
   if (this->pName)
   {
-    this->pModule.reset(PyImport_Import(this->pName));
-    Py_DECREF(this->pName);
+  this->pModule.reset(PyImport_Import(this->pName));
+  Py_DECREF(this->pName);
   }
 
   // Get the Update function from the module
   if (this->pModule)
   {
-    this->pFuncUpdate.reset(PyObject_GetAttrString(this->pModule, "Update"));
-    if (this->pFuncUpdate && !PyCallable_Check(this->pFuncUpdate))
-      this->pFuncUpdate = NULL;
+  this->pFuncUpdate.reset(PyObject_GetAttrString(this->pModule, "Update"));
+  if (this->pFuncUpdate && !PyCallable_Check(this->pFuncUpdate))
+  this->pFuncUpdate = NULL;
   }
-  */
+   */
 }
 
 
////////////////////////////////////////////////////////////////////////////////

Modified: code/branches/federation/gazebo/server/Model.hh
===================================================================
--- code/branches/federation/gazebo/server/Model.hh     2009-03-09 08:36:48 UTC 
(rev 7403)
+++ code/branches/federation/gazebo/server/Model.hh     2009-03-09 19:14:49 UTC 
(rev 7404)
@@ -63,7 +63,8 @@
     public: virtual ~Model();
   
     /// \brief Load the model
-    public: int Load(XMLConfigNode *node);
+    /// \param removeDuplicate Remove existing model of same name
+    public: int Load(XMLConfigNode *node, bool removeDuplicate);
   
     /// \brief Save the model
     public: void Save(std::string &prefix, std::ostream &stream);

Modified: code/branches/federation/gazebo/server/World.cc
===================================================================
--- code/branches/federation/gazebo/server/World.cc     2009-03-09 08:36:48 UTC 
(rev 7403)
+++ code/branches/federation/gazebo/server/World.cc     2009-03-09 19:14:49 UTC 
(rev 7404)
@@ -136,7 +136,7 @@
 
   this->physicsEngine = new ODEPhysics(); //TODO: use exceptions here
 
-  this->LoadEntities(rootNode, NULL);
+  this->LoadEntities(rootNode, NULL, false);
 
   /*std::vector<Model*>::iterator miter;
   for (miter = this->models.begin(); miter != this->models.end(); miter++)
@@ -302,7 +302,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 // Load a model
-int World::LoadEntities(XMLConfigNode *node, Model *parent)
+int World::LoadEntities(XMLConfigNode *node, Model *parent, bool 
removeDuplicate)
 {
   XMLConfigNode *cnode;
   Model *model = NULL;
@@ -312,14 +312,14 @@
     // Check for model nodes
     if (node->GetNSPrefix() == "model")
     {
-      model = this->LoadModel(node, parent);
+      model = this->LoadModel(node, parent, removeDuplicate);
     }
   }
 
   // Load children
   for (cnode = node->GetChild(); cnode != NULL; cnode = cnode->GetNext())
   {
-    if (this->LoadEntities( cnode, model ) != 0)
+    if (this->LoadEntities( cnode, model, removeDuplicate ) != 0)
       return -1;
   }
 
@@ -343,14 +343,14 @@
 
 
////////////////////////////////////////////////////////////////////////////////
 // Load a model
-Model *World::LoadModel(XMLConfigNode *node, Model *parent)
+Model *World::LoadModel(XMLConfigNode *node, Model *parent, bool 
removeDuplicate)
 {
   Pose3d pose;
   Model *model = new Model(parent);
 
   //model->SetParent(parent);
   // Load the model
-  if (model->Load( node ) != 0)
+  if (model->Load( node, removeDuplicate ) != 0)
     return NULL;
 
   // Set the model's pose (relative to parent)

Modified: code/branches/federation/gazebo/server/World.hh
===================================================================
--- code/branches/federation/gazebo/server/World.hh     2009-03-09 08:36:48 UTC 
(rev 7403)
+++ code/branches/federation/gazebo/server/World.hh     2009-03-09 19:14:49 UTC 
(rev 7404)
@@ -95,8 +95,9 @@
   /// \brief Load all entities
   /// \param node XMLConfg node pointer
   /// \param parent Parent of the model to load
+  /// \param removeDuplicate Remove existing model of same name
   /// \return 0 on success
-  public: int LoadEntities(XMLConfigNode *node, Model *parent);
+  public: int LoadEntities(XMLConfigNode *node, Model *parent, bool 
removeDuplicate);
 
   /// \brief Delete an entity by name
   /// \param name The name of the entity to delete
@@ -156,8 +157,9 @@
   /// \brief Load a model
   /// \param node Pointer to the XMLConfig node
   /// \param parent The parent model
+  /// \param removeDuplicate Remove existing model of same name
   /// \return The model that was created
-  private: Model *LoadModel(XMLConfigNode *node, Model *parent);
+  private: Model *LoadModel(XMLConfigNode *node, Model *parent, bool 
removeDuplicate);
 
   /// \brief Set the model pose and the pose of it's attached children 
   /// \param model The model to set

Modified: code/branches/federation/gazebo/server/controllers/factory/Factory.cc
===================================================================
--- code/branches/federation/gazebo/server/controllers/factory/Factory.cc       
2009-03-09 08:36:48 UTC (rev 7403)
+++ code/branches/federation/gazebo/server/controllers/factory/Factory.cc       
2009-03-09 19:14:49 UTC (rev 7404)
@@ -112,7 +112,7 @@
     }
 
     // Add the new models into the World
-    World::Instance()->LoadEntities( xmlConfig->GetRootNode(), NULL );
+    World::Instance()->LoadEntities( xmlConfig->GetRootNode(), NULL, true );
 
     // Cleanup
     delete xmlConfig;

Modified: code/branches/federation/gazebo/webgazebo/SConscript
===================================================================
--- code/branches/federation/gazebo/webgazebo/SConscript        2009-03-09 
08:36:48 UTC (rev 7403)
+++ code/branches/federation/gazebo/webgazebo/SConscript        2009-03-09 
19:14:49 UTC (rev 7404)
@@ -49,6 +49,7 @@
 )
 
 webgazebo = exeEnv.Program('webgazebo', 'main.cc')
+client = exeEnv.Program('client', 'client.cc')
 
 env.Install(install_prefix+'/lib', sharedLib)
 #env.Install(install_prefix+'/lib', staticLib)

Modified: code/branches/federation/gazebo/webgazebo/WebGazebo.cc
===================================================================
--- code/branches/federation/gazebo/webgazebo/WebGazebo.cc      2009-03-09 
08:36:48 UTC (rev 7403)
+++ code/branches/federation/gazebo/webgazebo/WebGazebo.cc      2009-03-09 
19:14:49 UTC (rev 7404)
@@ -1,14 +1,50 @@
+/*
+ *  Gazebo - Outdoor Multi-Robot Simulator
+ *  Copyright (C) 2003  
+ *     Nate Koenig & Andrew Howard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/* Desc: HTTP portal to libgazebo
+ * Author: Brian Gerkey
+ * Date: 9 March 2009
+ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $
+ */
+
 #include "WebGazebo.hh"
 
+#include <fstream>
+
 #include <stdio.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <time.h>
+#include <string.h>
 
 #include <boost/lexical_cast.hpp>
 
 #include "../server/Quatern.hh"
 
+// TODO:
+//   - make ghost models not collide, fall, etc.
+//   - add SetState
+//   - expose URI command to run for 1 tick
+//   - do performance test
+
 WebGazebo::WebGazebo(std::string _host, int _port, double dtol, double atol) :
         host(_host), port(_port), sq_dist_tol(dtol*dtol), sq_ang_tol(atol*atol)
 {
@@ -29,9 +65,11 @@
   fflush(stdout);
   this->client = new gazebo::Client();
   this->simIface = new gazebo::SimulationIface();
+  this->factoryIface = new gazebo::FactoryIface();
   this->client->ConnectWait(0, GZ_CLIENT_ID_USER_FIRST);
   // Open the Simulation Interface; let exceptions leak out
   this->simIface->Open(this->client, "default");
+  this->factoryIface->Open(this->client, "factory_iface");
   // Get the list of models
   if(!GetModelList())
     throw("Failed to get list of models from Gazebo");
@@ -58,23 +96,37 @@
 
 bool WebGazebo::HasModel(const std::string& name)
 {
-  std::map<std::string,int>::const_iterator it = models.find(name);
-  return it != models.end();
+  // TODO
+  //std::map<std::string,int>::const_iterator it = models.find(name);
+  //return it != models.end();
+  return true;
 }
 
 bool
 WebGazebo::GetPose(std::string model, gazebo::Pose& pose)
 {
-  // Discard any leftover responses;
+  // Discard any leftover responses
   this->simIface->data->responseCount = 0;
 
   // Ask Gazebo
   this->simIface->GetPose3d(model.c_str());
   
   // Wait for the response
+  double timeout = 3.0;
+  struct timeval t0, t1;
+  gettimeofday(&t0, NULL);
   struct timespec sleeptime = {0, 10000000};
   while(this->simIface->data->responseCount == 0)
+  {
+    gettimeofday(&t1, NULL);
+    if(((t1.tv_sec + t1.tv_usec/1e6) - (t0.tv_sec + t0.tv_usec/1e6)) 
+       > timeout)
+    {
+      puts("Timeout");
+      return false;
+    }
     nanosleep(&sleeptime, NULL);
+  }
 
   assert(this->simIface->data->responseCount == 1);
   pose = this->simIface->data->responses[0].modelPose;
@@ -152,170 +204,255 @@
 }
 
 bool
-WebGazebo::HandleURI(const std::string& model,
-                     const std::string& prop,
-                     const std::string& action,
-                     struct evkeyvalq* kv,
-                     std::string& response)
+WebGazebo::GetModel(const std::string& name,
+                    const std::string& type,
+                    std::string& xmldata,
+                    std::string& response)
 {
-  // The special simulation model
-  if(model == "sim")
+  // Search GAZEBO_MODEL_PATH for a matching .model file
+  const char* gmpath = getenv("GAZEBO_MODEL_PATH");
+  if(!gmpath)
   {
-    // The special factory property
-    if(prop == "factory")
+    response = "ERROR: GAZEBO_MODEL_PATH is not set";
+    return false;
+  }
+
+  std::vector<std::string> gmpath_parts;
+  StringSplit(gmpath, gmpath_parts, ":");
+  for(unsigned int i=0; i<gmpath_parts.size(); i++)
+  {
+    std::string p = gmpath_parts[0] + "/" + type + ".model";
+    if(access(p.c_str(), F_OK) == 0)
     {
-      if(action == "create")
-      {
-        std::string name, type;
-        if(!GetValue(name, kv, "name") ||
-           !GetValue(type, kv, "type"))
-        {
-          response = "ERROR: Missing name and/or type argument for 
sim/factor/create";
-          return false;
-        }
+      std::ifstream ifs(p.c_str());
+      xmldata = std::string((std::istreambuf_iterator<char>(ifs)), 
+                            std::istreambuf_iterator<char>());
 
-        printf("[webgazebo] Creating model %s of type %s\n",
-               name.c_str(), type.c_str());
-        response = "[webgazebo] Creating model " + name + " of type " + type;
-        return true;
-      }
-      else
+      // HACK: rename with a VERY crude textual replacement
+      std::string tag1 = "<model:physical";
+      std::string tag2 = "name=\"";
+      int i = xmldata.find(tag1);
+      if(i < 0)
+        return false;
+      i = xmldata.find(tag2, i);
+      if(i < 0)
+        return false;
+      int j = xmldata.find("\"", i+tag2.length());
+      xmldata.replace(i,j-i+1,std::string("name=\"" + name + "\""));
+      return true;
+    }
+  }
+
+  response = "ERROR: Could not find file " + type + ".model";
+  return false;
+}
+
+bool
+WebGazebo::CreateModel(const std::string& xmldata,
+                       std::string& response)
+{
+  struct timespec sleeptime = {0, 10000000};
+  for(;;)
+  {
+    this->factoryIface->Lock(1);
+    if(!strcmp((const char*)this->factoryIface->data->newModel,""))
+    {
+      strcpy((char*)this->factoryIface->data->newModel, xmldata.c_str());
+      factoryIface->Unlock();
+      return true;
+    }
+    else
+    {
+      factoryIface->Unlock();
+      nanosleep(&sleeptime, NULL);
+    }
+  }
+}
+
+bool
+WebGazebo::HandleSimRequest(const std::string& prop,
+                            const std::string& action,
+                            struct evkeyvalq* kv,
+                            std::string& response)
+{
+  // The special factory property
+  if(prop == "factory")
+  {
+    if(action == "create")
+    {
+      std::string name, type;
+      if(!GetValue(name, kv, "name") ||
+         !GetValue(type, kv, "type"))
       {
-        response = "ERROR: Unknown action " + action + " for sim/factory";
+        response = "ERROR: Missing name and/or type argument for 
sim/factor/create";
         return false;
       }
+
+      std::string xmldata;
+      if(!GetModel(name, type, xmldata, response))
+        return false;
+      if(!CreateModel(xmldata, response))
+        return false;
+      response = std::string("Created model of type ") + type;
+      return true;
     }
     else
     {
-      response = "ERROR: Unknown property " + prop + " for sim";
+      response = "ERROR: Unknown action " + action + " for sim/factory";
       return false;
     }
   }
-  // Everything else must be an existing model
   else
   {
-    printf("[webgazebo] got request for %s:%s:%s\n",
-           model.c_str(),
-           prop.c_str(),
-           action.c_str());
-    if(HasModel(model))
+    response = "ERROR: Unknown property " + prop + " for sim";
+    return false;
+  }
+}
+
+bool
+WebGazebo::HandleModelRequest(const std::string& model,
+                              const std::string& prop,
+                              const std::string& action,
+                              struct evkeyvalq* kv,
+                              std::string& response)
+{
+  printf("[webgazebo] got request for %s:%s:%s\n",
+         model.c_str(),
+         prop.c_str(),
+         action.c_str());
+  if(HasModel(model))
+  {
+    if(action == "get")
     {
-      if(action == "get")
+      if(prop == "pose")
       {
-        if(prop == "pose")
+        gazebo::Pose p;
+        if(GetPose(model, p))
         {
-          gazebo::Pose p;
-          if(GetPose(model, p))
-          {
-            char buf[1024];
-            snprintf(buf, sizeof(buf), 
-                     "Got %s's pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)",
-                      model.c_str(),
-                      p.pos.x, p.pos.y, p.pos.z,
-                      p.roll, p.pitch, p.yaw);
-            response = buf;
-            return true;
-          }
-          else
-          {
-            response = "ERROR: Failed to get pose for model " + model;
-            return false;
-          }
+          char buf[1024];
+          snprintf(buf, sizeof(buf), 
+                   "Got %s's pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)",
+                   model.c_str(),
+                   p.pos.x, p.pos.y, p.pos.z,
+                   p.roll, p.pitch, p.yaw);
+          response = buf;
+          return true;
         }
         else
         {
-          response = "ERROR: Unknown property " + prop + " for model " + model;
+          response = "ERROR: Failed to get pose for model " + model;
           return false;
         }
       }
-      else if(action == "set")
+      else
       {
-        if(prop == "pose")
+        response = "ERROR: Unknown property " + prop + " for model " + model;
+        return false;
+      }
+    }
+    else if(action == "set")
+    {
+      if(prop == "pose")
+      {
+        std::string sx, sy, sz, sroll, spitch, syaw;
+
+        // Get pose first, fill in what the caller provided
+        gazebo::Pose p, q;
+        if(!GetPose(model, p))
         {
-          std::string sx, sy, sz, sroll, spitch, syaw;
+          response = "Failed to get pose before setting it";
+          return false;
+        }
+        try
+        {
+          q = p;
+          if(GetValue(sx, kv, "x"))
+            p.pos.x = boost::lexical_cast<float>(sx);
+          if(GetValue(sy, kv, "y"))
+            p.pos.y = boost::lexical_cast<float>(sy);
+          if(GetValue(sz, kv, "z"))
+            p.pos.z = boost::lexical_cast<float>(sz);
+          if(GetValue(sroll, kv, "roll"))
+            p.roll = boost::lexical_cast<float>(sroll);
+          if(GetValue(spitch, kv, "pitch"))
+            p.pitch = boost::lexical_cast<float>(spitch);
+          if(GetValue(syaw, kv, "yaw"))
+            p.yaw = boost::lexical_cast<float>(syaw);
+        }
+        catch(boost::bad_lexical_cast e)
+        {
+          response = std::string("Failed to parse input value(s): ") + 
+                  e.what();
+          return false;
+        }
 
-          // Get pose first, fill in what the caller provided
-          gazebo::Pose p, q;
-          if(!GetPose(model, p))
-          {
-            response = "Failed to get pose before setting it";
-            return false;
-          }
-          try
-          {
-            q = p;
-            if(GetValue(sx, kv, "x"))
-              p.pos.x = boost::lexical_cast<float>(sx);
-            /*
-               if(GetValue(sy, kv, "y"))
-               p.pos.y = boost::lexical_cast<float>(sy);
-             */
-            if(GetValue(sz, kv, "z"))
-              p.pos.z = boost::lexical_cast<float>(sz);
-            if(GetValue(sroll, kv, "roll"))
-              p.roll = boost::lexical_cast<float>(sroll);
-            if(GetValue(spitch, kv, "pitch"))
-              p.pitch = boost::lexical_cast<float>(spitch);
-            if(GetValue(syaw, kv, "yaw"))
-              p.yaw = boost::lexical_cast<float>(syaw);
-          }
-          catch(boost::bad_lexical_cast e)
-          {
-            response = std::string("Failed to parse input value(s): ") + 
-                    e.what();
-            return false;
-          }
+        if(SetPose(model, p))
+        {
+          char buf[1024];
+          snprintf(buf, sizeof(buf), 
+                   "Set %s's pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)",
+                   model.c_str(),
+                   p.pos.x, p.pos.y, p.pos.z,
+                   p.roll, p.pitch, p.yaw);
+          response = buf;
 
-          if(SetPose(model, p))
-          {
-            char buf[1024];
-            snprintf(buf, sizeof(buf), 
-                     "Set %s's pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)",
-                      model.c_str(),
-                      p.pos.x, p.pos.y, p.pos.z,
-                      p.roll, p.pitch, p.yaw);
-            response = buf;
+          // Check tolerances, and complain if they're exceeded
+          if(!CheckTolerances(p,q))
+            response += "\nWARNING: Pose change exceeded tolerance";
 
-            // Check tolerances
-            if(!CheckTolerances(p,q))
-              response += "\nWARNING: Pose change exceeded tolerance";
-
-            return true;
-          }
-          else
-          {
-            response = "ERROR: Failed to get pose for model " + model;
-            return false;
-          }
+          return true;
         }
         else
         {
-          response = "ERROR: Unknown property " + prop + " for model " + model;
+          response = "ERROR: Failed to get pose for model " + model;
           return false;
         }
       }
       else
       {
-        response = "ERROR: Unknown action " + action;
+        response = "ERROR: Unknown property " + prop + " for model " + model;
         return false;
       }
     }
     else
     {
-      response = "ERROR: No such model " + model;
+      response = "ERROR: Unknown action " + action;
       return false;
     }
   }
+  else
+  {
+    response = "ERROR: No such model " + model;
+    return false;
+  }
 }
 
+bool
+WebGazebo::HandleURI(const std::string& model,
+                     const std::string& prop,
+                     const std::string& action,
+                     struct evkeyvalq* kv,
+                     std::string& response)
+{
+  // The special simulation model
+  if(model == "sim")
+  {
+    return HandleSimRequest(prop, action, kv, response);
+  }
+  // Everything else must be an existing model
+  else
+  {
+    return HandleModelRequest(model, prop, action, kv, response);
+  }
+}
+
+// Handle all incoming URI requests
 void
 WebGazebo::EventCallback(evhttp_request* req, void* arg)
 {
   WebGazebo* obj = (WebGazebo*)arg;
 
   printf("[webgazebo] Got request:%s:\n", req->uri);
-  printf("[webgazebo] Decoded:%s:\n", evhttp_decode_uri(req->uri));
-
   
   // Pull out query args
   struct evkeyvalq query_args;
@@ -324,36 +461,29 @@
   struct evbuffer* eb = evbuffer_new();
   assert(eb);
 
+  int response_code;
+  std::string response_string;
   std::string model, prop, action, response;
   if(!obj->ParseURI(model, prop, action, req->uri, response))
   {
-    evbuffer_add_printf(eb, "%s\n", response.c_str());
-    evhttp_send_reply(req, 400, "Invalid request", eb);
-    return;
+    response_code = 400;
+    response_string = "Invalid request";
   }
-
-  if(!obj->HandleURI(model, prop, action, &query_args, response))
+  else if(!obj->HandleURI(model, prop, action, &query_args, response))
   {
-    evbuffer_add_printf(eb, "%s\n", response.c_str());
-    evhttp_send_reply(req, 400, "Invalid request", eb);
-    return;
+    response_code = 400;
+    response_string = "Invalid request";
   }
+  else
+  {
+    response_code = 200;
+    response_string = "OK";
+  }
 
-  /*
-  std::string model = "pioneer2dx_model1";
-  gazebo::Pose p;
-  assert(obj->GetPose(&p, model));
-  evbuffer_add_printf(eb, "<html><head><title>WebGazebo</title></head><body>");
-  evbuffer_add_printf(eb, "<h1>WebGazebo!</h1>");
-  evbuffer_add_printf(eb, "%s's pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)",
-                      model.c_str(),
-                      p.pos.x, p.pos.y, p.pos.z,
-                      p.roll, p.pitch, p.yaw);
-  evbuffer_add_printf(eb, "</body></html>");
-  */
-
   evbuffer_add_printf(eb, "%s\n", response.c_str());
-  evhttp_send_reply(req, 200, "OK", eb);
+  printf("[webgazebo] Sending reply: %d %s\n",
+         response_code, response_string.c_str());
+  evhttp_send_reply(req, response_code, response_string.c_str(), eb);
   evbuffer_free(eb);
 }
 

Modified: code/branches/federation/gazebo/webgazebo/WebGazebo.hh
===================================================================
--- code/branches/federation/gazebo/webgazebo/WebGazebo.hh      2009-03-09 
08:36:48 UTC (rev 7403)
+++ code/branches/federation/gazebo/webgazebo/WebGazebo.hh      2009-03-09 
19:14:49 UTC (rev 7404)
@@ -1,3 +1,30 @@
+/*
+ *  Gazebo - Outdoor Multi-Robot Simulator
+ *  Copyright (C) 2003  
+ *     Nate Koenig & Andrew Howard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/* Desc: HTTP portal to libgazebo
+ * Author: Brian Gerkey
+ * Date: 9 March 2009
+ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $
+ */
+
 #include <string>
 #include <vector>
 #include <map>
@@ -32,6 +59,7 @@
 
     gazebo::Client *client;
     gazebo::SimulationIface *simIface;
+    gazebo::FactoryIface *factoryIface;
 
     // Available models
     std::map<std::string,int> models;
@@ -42,6 +70,8 @@
     bool CheckTolerances(gazebo::Pose p, gazebo::Pose q);
     bool GetModelList();
     bool HasModel(const std::string& name);
+    bool CreateModel(const std::string& xmldata,
+                     std::string& response);
     bool GetPose(std::string model, gazebo::Pose& pose);
     bool SetPose(std::string model, const gazebo::Pose& pose);
     void StringSplit(const std::string &s, 
@@ -50,11 +80,24 @@
     bool GetValue(std::string& value,
                   struct evkeyvalq* query_args, 
                   const std::string& key);
+    bool GetModel(const std::string& name,
+                  const std::string& type,
+                  std::string& xmldata,
+                  std::string& response);
     bool HandleURI(const std::string& model,
                    const std::string& prop,
                    const std::string& action,
                    struct evkeyvalq* kv,
                    std::string& response);
+    bool HandleSimRequest(const std::string& prop,
+                          const std::string& action,
+                          struct evkeyvalq* kv,
+                          std::string& response);
+    bool HandleModelRequest(const std::string& model,
+                            const std::string& prop,
+                            const std::string& action,
+                            struct evkeyvalq* kv,
+                            std::string& response);
     bool ParseURI(std::string& model,
                   std::string& prop,
                   std::string& action,

Added: code/branches/federation/gazebo/webgazebo/client.cc
===================================================================
--- code/branches/federation/gazebo/webgazebo/client.cc                         
(rev 0)
+++ code/branches/federation/gazebo/webgazebo/client.cc 2009-03-09 19:14:49 UTC 
(rev 7404)
@@ -0,0 +1,89 @@
+/*
+ *  Gazebo - Outdoor Multi-Robot Simulator
+ *  Copyright (C) 2003  
+ *     Nate Koenig & Andrew Howard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/* Desc: Performance test for HTTP portal to libgazebo
+ * Author: Brian Gerkey
+ * Date: 9 March 2009
+ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+// These headers must be included prior to the libevent headers
+#include <sys/types.h>
+#include <sys/queue.h>
+
+// libevent
+#include <event.h>
+#include <evhttp.h>
+
+struct timeval g_t0, g_t1;
+
+// Callback that's invoked when the request is done and we have the
+// response
+void
+cb(evhttp_request* req, void* arg)
+{
+  gettimeofday(&g_t1, NULL);
+  if(req->response_code != 200)
+    printf("Got non-OK response code: %d\n", req->response_code);
+
+  printf("Response:\n%s", req->input_buffer->buffer);
+  
+  double dt = ((g_t1.tv_sec + g_t1.tv_usec/1e6) - 
+               (g_t0.tv_sec + g_t0.tv_usec/1e6));
+  printf("Elapsed time: %.6f\n", dt);
+  exit(0);
+}
+
+#define USAGE "USAGE: client <URI>"
+
+int
+main(int argc, char** argv)
+{
+  const char* uri;
+
+  if(argc != 2)
+  {
+    puts(USAGE);
+    exit(1);
+  }
+
+  uri = argv[1];
+
+  struct evhttp_connection* ec;
+  struct evhttp_request* er;
+
+  event_init();
+
+  ec = evhttp_connection_new("localhost", 8000);
+  assert(ec);
+
+  gettimeofday(&g_t0, NULL);
+  er = evhttp_request_new(cb, NULL);
+  int ret = evhttp_make_request(ec, er, EVHTTP_REQ_GET, uri);
+  event_dispatch();
+
+  return 0;
+}

Modified: code/branches/federation/gazebo/webgazebo/main.cc
===================================================================
--- code/branches/federation/gazebo/webgazebo/main.cc   2009-03-09 08:36:48 UTC 
(rev 7403)
+++ code/branches/federation/gazebo/webgazebo/main.cc   2009-03-09 19:14:49 UTC 
(rev 7404)
@@ -1,3 +1,30 @@
+/*
+ *  Gazebo - Outdoor Multi-Robot Simulator
+ *  Copyright (C) 2003  
+ *     Nate Koenig & Andrew Howard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/* Desc: HTTP portal to libgazebo
+ * Author: Brian Gerkey
+ * Date: 9 March 2009
+ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $
+ */
+
 #include "webgazebo/WebGazebo.hh"
 
 #include <stdlib.h>

Modified: code/branches/federation/gazebo/worlds/federation.world
===================================================================
--- code/branches/federation/gazebo/worlds/federation.world     2009-03-09 
08:36:48 UTC (rev 7403)
+++ code/branches/federation/gazebo/worlds/federation.world     2009-03-09 
19:14:49 UTC (rev 7404)
@@ -48,6 +48,12 @@
     <shadowTechnique>stencilAdditive</shadowTechnique>
   </rendering:ogre>
 
+  <model:empty name="factory_model">
+    <controller:factory name="factory_controller">
+      <interface:factory name="factory_iface"/>
+    </controller:factory>
+  </model:empty>
+
    <!-- Ground Plane -->
   <model:physical name="plane1_model">
     <xyz>0 0 0</xyz>


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

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to