From: <ge...@us...> - 2009-03-09 19:15:05
|
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. |