From: <ge...@us...> - 2009-03-10 02:23:07
|
Revision: 7412 http://playerstage.svn.sourceforge.net/playerstage/?rev=7412&view=rev Author: gerkey Date: 2009-03-10 02:04:52 +0000 (Tue, 10 Mar 2009) Log Message: ----------- first cut at websim Added Paths: ----------- code/websim/CMakeLists.txt code/websim/src/ code/websim/src/websim.cc code/websim/src/websim.h Added: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt (rev 0) +++ code/websim/CMakeLists.txt 2009-03-10 02:04:52 UTC (rev 7412) @@ -0,0 +1,13 @@ +project(WebSim) + +cmake_minimum_required( VERSION 2.4 FATAL_ERROR ) + +include_directories(${PROJECT_SOURCE_DIR}) +add_library(websim SHARED src/websim.cc) +add_library(websim-static STATIC src/websim.cc) +# Set output name to be the same as shared lib (may not work on Windows) +set_target_properties(websim-static PROPERTIES OUTPUT_NAME websim) +# Prevent deletion of existing lib of same name +set_target_properties(websim-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) + +target_link_libraries(websim event) Added: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc (rev 0) +++ code/websim/src/websim.cc 2009-03-10 02:04:52 UTC (rev 7412) @@ -0,0 +1,109 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; 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 "websim.h" + +#include <assert.h> +#include <stdlib.h> + +WebSim::WebSim(const std::string& _fedfile, + const std::string& _host, + int _port) : + fedfile(_fedfile), host(_host), port(_port) +{ + // Set up the HTTP server + // Not sure whether it's safe to do this more that once in one process + event_init(); + + printf("[websim] Starting HTTP server listening on %s:%d...", + this->host.c_str(), this->port); + fflush(stdout); + this->eh = evhttp_start(this->host.c_str(), this->port); + assert(eh); + evhttp_set_gencb(eh, &WebSim::EventCallback, (void*)this); + puts("Done."); + + puts("[websim] Ready"); +} + + +WebSim::~WebSim() +{ + // No event_fini() to call... +} + +void +WebSim::Update() +{ + event_dispatch(); +} + +void +WebSim::StringSplit(const std::string &s, + std::vector<std::string> &t, + const std::string &d) +{ + t.clear(); + size_t start = 0, end; + while ((end = s.find_first_of(d, start)) != std::string::npos) + { + t.push_back(s.substr(start, end-start)); + start = end + 1; + } + t.push_back(s.substr(start)); +} + +// Strange that libevent doesn't provide a way to free the evkeyvalq +// structure. +void +WebSim::DeleteKeyVal(struct evkeyvalq* query_args) +{ + struct evkeyval* kv; + TAILQ_FOREACH(kv, query_args, next) + { + free(kv->key); + free(kv->value); + TAILQ_REMOVE(query_args, kv, next); + } +} + +bool +WebSim::GetValue(std::string& value, + struct evkeyvalq* query_args, + const std::string& key) +{ + struct evkeyval* kv; + TAILQ_FOREACH(kv, query_args, next) + { + if(key == kv->key) + { + value = std::string(kv->value); + return true; + } + } + return false; +} Added: code/websim/src/websim.h =================================================================== --- code/websim/src/websim.h (rev 0) +++ code/websim/src/websim.h 2009-03-10 02:04:52 UTC (rev 7412) @@ -0,0 +1,86 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; 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> + +// 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> + +class WebSim +{ + public: + WebSim(const std::string& _fedfile, + const std::string& _host, + int _port); // TODO: 3 callbacks + ~WebSim(); + + void Update(); + + private: + std::string fedfile; + std::string host; + int port; + + struct evhttp* eh; + + // Static, so that it can be passed as a callback to libevent + static void EventCallback(evhttp_request* req, void* arg); + + void StringSplit(const std::string &s, + std::vector<std::string> &t, + const std::string &d); + bool GetValue(std::string& value, + struct evkeyvalq* query_args, + const std::string& key); + 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, + std::string uri, + std::string& response); + void DeleteKeyVal(struct evkeyvalq* query_args); +}; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ge...@us...> - 2009-03-10 03:15:30
|
Revision: 7422 http://playerstage.svn.sourceforge.net/playerstage/?rev=7422&view=rev Author: gerkey Date: 2009-03-10 03:15:15 +0000 (Tue, 10 Mar 2009) Log Message: ----------- rearranged Added Paths: ----------- code/websim/include/ code/websim/include/websim/ code/websim/include/websim/websim.h Removed Paths: ------------- code/websim/src/websim.h Copied: code/websim/include/websim/websim.h (from rev 7421, code/websim/src/websim.h) =================================================================== --- code/websim/include/websim/websim.h (rev 0) +++ code/websim/include/websim/websim.h 2009-03-10 03:15:15 UTC (rev 7422) @@ -0,0 +1,157 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; 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> + +// 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> + +namespace websim +{ + +class Pose; +class Velocity; +class Acceleration; + +class WebSim +{ + public: + WebSim(const std::string& _fedfile, + const std::string& _host, + int _port); + ~WebSim(); + + void Update(); + + // Interface to be implemented by simulators + virtual bool CreateModel(const std::string& name, + const std::string& type, + std::string& error) = 0; + virtual bool DeleteModel(const std::string& name, + std::string& error) = 0; + virtual bool SetModelState(const std::string& name, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& error) = 0; + virtual bool GetModelState(const std::string& name, + Pose& p, + Velocity& v, + Acceleration& a, + std::string& error) = 0; + + private: + std::string fedfile; + std::string host; + int port; + + struct evhttp* eh; + + // Static, so that it can be passed as a callback to libevent + static void EventCallback(evhttp_request* req, void* arg); + + void StringSplit(const std::string &s, + std::vector<std::string> &t, + const std::string &d); + bool GetValue(std::string& value, + struct evkeyvalq* query_args, + const std::string& key); + 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, + std::string uri, + std::string& response); + void DeleteKeyVal(struct evkeyvalq* query_args); +}; + +class Pose +{ +public: + double x,y,z,r,p,a; + + Pose() : + x(0), y(0), z(0), r(0), p(0), a(0) + { + // nothing to do + } + + Pose( double x, double y, double z, + double r, double p, double a ) : + x(x), y(y), z(z), r(r), p(p), a(a) + { + // nothing to do + } + +}; + +class Velocity : public Pose +{ +public: + Velocity() : Pose() + {} + + Velocity( double x, double y, double z, + double r, double p, double a ) : + Pose( x, y, z, r, p, a ) + {} +}; + +class Acceleration : public Pose +{ +public: + Acceleration() : Pose() + {} + + Acceleration( double x, double y, double z, + double r, double p, double a ) : + Pose( x, y, z, r, p, a ) + {} +}; + + +} Property changes on: code/websim/include/websim/websim.h ___________________________________________________________________ Added: svn:mergeinfo + Deleted: code/websim/src/websim.h =================================================================== --- code/websim/src/websim.h 2009-03-10 03:14:32 UTC (rev 7421) +++ code/websim/src/websim.h 2009-03-10 03:15:15 UTC (rev 7422) @@ -1,157 +0,0 @@ -/* - * WebSim - Library for web-enabling and federating simulators. - * Copyright (C) 2009 - * Richard Vaughan, Brian Gerkey, and Nate Koenig - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; 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> - -// 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> - -namespace websim -{ - -class Pose; -class Velocity; -class Acceleration; - -class WebSim -{ - public: - WebSim(const std::string& _fedfile, - const std::string& _host, - int _port); - ~WebSim(); - - void Update(); - - // Interface to be implemented by simulators - virtual bool CreateModel(const std::string& name, - const std::string& type, - std::string& error) = 0; - virtual bool DeleteModel(const std::string& name, - std::string& error) = 0; - virtual bool SetModelState(const std::string& name, - const Pose& p, - const Velocity& v, - const Acceleration& a, - std::string& error) = 0; - virtual bool GetModelState(const std::string& name, - Pose& p, - Velocity& v, - Acceleration& a, - std::string& error) = 0; - - private: - std::string fedfile; - std::string host; - int port; - - struct evhttp* eh; - - // Static, so that it can be passed as a callback to libevent - static void EventCallback(evhttp_request* req, void* arg); - - void StringSplit(const std::string &s, - std::vector<std::string> &t, - const std::string &d); - bool GetValue(std::string& value, - struct evkeyvalq* query_args, - const std::string& key); - 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, - std::string uri, - std::string& response); - void DeleteKeyVal(struct evkeyvalq* query_args); -}; - -class Pose -{ -public: - double x,y,z,r,p,a; - - Pose() : - x(0), y(0), z(0), r(0), p(0), a(0) - { - // nothing to do - } - - Pose( double x, double y, double z, - double r, double p, double a ) : - x(x), y(y), z(z), r(r), p(p), a(a) - { - // nothing to do - } - -}; - -class Velocity : public Pose -{ -public: - Velocity() : Pose() - {} - - Velocity( double x, double y, double z, - double r, double p, double a ) : - Pose( x, y, z, r, p, a ) - {} -}; - -class Acceleration : public Pose -{ -public: - Acceleration() : Pose() - {} - - Acceleration( double x, double y, double z, - double r, double p, double a ) : - Pose( x, y, z, r, p, a ) - {} -}; - - -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ge...@us...> - 2009-03-10 03:16:11
|
Revision: 7423 http://playerstage.svn.sourceforge.net/playerstage/?rev=7423&view=rev Author: gerkey Date: 2009-03-10 03:16:00 +0000 (Tue, 10 Mar 2009) Log Message: ----------- more rearranging Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/websim.cc Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-03-10 03:15:15 UTC (rev 7422) +++ code/websim/CMakeLists.txt 2009-03-10 03:16:00 UTC (rev 7423) @@ -2,7 +2,7 @@ cmake_minimum_required( VERSION 2.4 FATAL_ERROR ) -include_directories(${PROJECT_SOURCE_DIR}) +include_directories(include) add_library(websim SHARED src/websim.cc) add_library(websim-static STATIC src/websim.cc) # Set output name to be the same as shared lib (may not work on Windows) Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-10 03:15:15 UTC (rev 7422) +++ code/websim/src/websim.cc 2009-03-10 03:16:00 UTC (rev 7423) @@ -25,7 +25,7 @@ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ */ -#include "websim.h" +#include "websim/websim.h" #include <boost/lexical_cast.hpp> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ge...@us...> - 2009-03-10 05:38:48
|
Revision: 7425 http://playerstage.svn.sourceforge.net/playerstage/?rev=7425&view=rev Author: gerkey Date: 2009-03-10 05:38:39 +0000 (Tue, 10 Mar 2009) Log Message: ----------- updated to work with webgazebo Modified Paths: -------------- code/websim/include/websim/websim.h code/websim/src/websim.cc Modified: code/websim/include/websim/websim.h =================================================================== --- code/websim/include/websim/websim.h 2009-03-10 03:19:57 UTC (rev 7424) +++ code/websim/include/websim/websim.h 2009-03-10 05:38:39 UTC (rev 7425) @@ -50,7 +50,7 @@ WebSim(const std::string& _fedfile, const std::string& _host, int _port); - ~WebSim(); + virtual ~WebSim(); void Update(); @@ -60,17 +60,22 @@ std::string& error) = 0; virtual bool DeleteModel(const std::string& name, std::string& error) = 0; - virtual bool SetModelState(const std::string& name, - const Pose& p, - const Velocity& v, - const Acceleration& a, - std::string& error) = 0; - virtual bool GetModelState(const std::string& name, - Pose& p, - Velocity& v, - Acceleration& a, - std::string& error) = 0; + virtual bool SetModelPVA(const std::string& name, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& error) = 0; + virtual bool GetModelPVA(const std::string& name, + Pose& p, + Velocity& v, + Acceleration& a, + std::string& error) = 0; + protected: + void StringSplit(const std::string &s, + std::vector<std::string> &t, + const std::string &d); + private: std::string fedfile; std::string host; @@ -81,9 +86,6 @@ // Static, so that it can be passed as a callback to libevent static void EventCallback(evhttp_request* req, void* arg); - void StringSplit(const std::string &s, - std::vector<std::string> &t, - const std::string &d); bool GetValue(std::string& value, struct evkeyvalq* query_args, const std::string& key); Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-10 03:19:57 UTC (rev 7424) +++ code/websim/src/websim.cc 2009-03-10 05:38:39 UTC (rev 7425) @@ -190,7 +190,7 @@ Pose p; Velocity v; Acceleration a; - if(GetModelState(model, p, v, a, response)) + if(GetModelPVA(model, p, v, a, response)) { char buf[1024]; snprintf(buf, sizeof(buf), @@ -218,7 +218,7 @@ } else if(action == "set") { - if(prop == "pose") + if(prop == "pva") { std::string sx, sy, sz, sroll, spitch, syaw; @@ -226,24 +226,24 @@ Pose p; Velocity v; Acceleration a; - if(!GetModelState(model, p, v, a, response)) + if(!GetModelPVA(model, p, v, a, response)) { response = "Failed to get pose before setting it"; return false; } try { - if(GetValue(sx, kv, "x")) + if(GetValue(sx, kv, "px")) p.x = boost::lexical_cast<float>(sx); - if(GetValue(sy, kv, "y")) + if(GetValue(sy, kv, "py")) p.y = boost::lexical_cast<float>(sy); - if(GetValue(sz, kv, "z")) + if(GetValue(sz, kv, "pz")) p.z = boost::lexical_cast<float>(sz); - if(GetValue(sroll, kv, "r")) + if(GetValue(sroll, kv, "pr")) p.r = boost::lexical_cast<float>(sroll); - if(GetValue(spitch, kv, "p")) + if(GetValue(spitch, kv, "pp")) p.p = boost::lexical_cast<float>(spitch); - if(GetValue(syaw, kv, "a")) + if(GetValue(syaw, kv, "pa")) p.a = boost::lexical_cast<float>(syaw); if(GetValue(sx, kv, "vx")) @@ -279,7 +279,7 @@ return false; } - return(SetModelState(model, p, v, a, response)); + return(SetModelPVA(model, p, v, a, response)); } else { @@ -293,3 +293,74 @@ return false; } } + +void +WebSim::EventCallback(evhttp_request* req, void* arg) +{ + WebSim* obj = (WebSim*)arg; + + // Pull out query args + struct evkeyvalq query_args; + evhttp_parse_query(req->uri, &query_args); + + 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)) + { + response_code = 400; + response_string = "Invalid request"; + } + else if(!obj->HandleURI(model, prop, action, &query_args, response)) + { + response_code = 400; + response_string = "Invalid request"; + } + else + { + response_code = 200; + response_string = "OK"; + } + + evbuffer_add_printf(eb, "%s\n", response.c_str()); + /* + 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); + + obj->DeleteKeyVal(&query_args); +} + +bool +WebSim::ParseURI(std::string& model, + std::string& prop, + std::string& action, + std::string uri, + std::string& response) +{ + // Remove the query args + std::vector<std::string> uri_parts; + StringSplit(uri, uri_parts, "?"); + assert(uri_parts.size() > 0); + std::string bare_uri = uri_parts[0]; + + // We require 3 path components: model/property/action + StringSplit(bare_uri, uri_parts, "/"); + // There should be 4 parts, with the first one empty + if(uri_parts.size() != 4) + { + response = "Must be 3 slash-separated parts in the URI"; + return false; + } + + model = uri_parts[1]; + prop = uri_parts[2]; + action = uri_parts[3]; + + return true; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ge...@us...> - 2009-03-10 05:43:44
|
Revision: 7426 http://playerstage.svn.sourceforge.net/playerstage/?rev=7426&view=rev Author: gerkey Date: 2009-03-10 05:43:37 +0000 (Tue, 10 Mar 2009) Log Message: ----------- Reorg for installation Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/websim.cc Added Paths: ----------- code/websim/src/websim.h Removed Paths: ------------- code/websim/include/ Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-03-10 05:38:39 UTC (rev 7425) +++ code/websim/CMakeLists.txt 2009-03-10 05:43:37 UTC (rev 7426) @@ -11,3 +11,8 @@ set_target_properties(websim-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) target_link_libraries(websim event) + +install(TARGETS websim websim-static + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) +install(FILES src/websim.h DESTINATION include/websim) Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-10 05:38:39 UTC (rev 7425) +++ code/websim/src/websim.cc 2009-03-10 05:43:37 UTC (rev 7426) @@ -25,7 +25,7 @@ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ */ -#include "websim/websim.h" +#include "websim.h" #include <boost/lexical_cast.hpp> Copied: code/websim/src/websim.h (from rev 7425, code/websim/include/websim/websim.h) =================================================================== --- code/websim/src/websim.h (rev 0) +++ code/websim/src/websim.h 2009-03-10 05:43:37 UTC (rev 7426) @@ -0,0 +1,159 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; 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> + +// 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> + +namespace websim +{ + +class Pose; +class Velocity; +class Acceleration; + +class WebSim +{ + public: + WebSim(const std::string& _fedfile, + const std::string& _host, + int _port); + virtual ~WebSim(); + + void Update(); + + // Interface to be implemented by simulators + virtual bool CreateModel(const std::string& name, + const std::string& type, + std::string& error) = 0; + virtual bool DeleteModel(const std::string& name, + std::string& error) = 0; + virtual bool SetModelPVA(const std::string& name, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& error) = 0; + virtual bool GetModelPVA(const std::string& name, + Pose& p, + Velocity& v, + Acceleration& a, + std::string& error) = 0; + + protected: + void StringSplit(const std::string &s, + std::vector<std::string> &t, + const std::string &d); + + private: + std::string fedfile; + std::string host; + int port; + + struct evhttp* eh; + + // Static, so that it can be passed as a callback to libevent + static void EventCallback(evhttp_request* req, void* arg); + + bool GetValue(std::string& value, + struct evkeyvalq* query_args, + const std::string& key); + 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, + std::string uri, + std::string& response); + void DeleteKeyVal(struct evkeyvalq* query_args); +}; + +class Pose +{ +public: + double x,y,z,r,p,a; + + Pose() : + x(0), y(0), z(0), r(0), p(0), a(0) + { + // nothing to do + } + + Pose( double x, double y, double z, + double r, double p, double a ) : + x(x), y(y), z(z), r(r), p(p), a(a) + { + // nothing to do + } + +}; + +class Velocity : public Pose +{ +public: + Velocity() : Pose() + {} + + Velocity( double x, double y, double z, + double r, double p, double a ) : + Pose( x, y, z, r, p, a ) + {} +}; + +class Acceleration : public Pose +{ +public: + Acceleration() : Pose() + {} + + Acceleration( double x, double y, double z, + double r, double p, double a ) : + Pose( x, y, z, r, p, a ) + {} +}; + + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-10 07:00:08
|
Revision: 7434 http://playerstage.svn.sourceforge.net/playerstage/?rev=7434&view=rev Author: rtv Date: 2009-03-10 07:00:05 +0000 (Tue, 10 Mar 2009) Log Message: ----------- added rtv federation client side stuff Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/websim.cc Added Paths: ----------- code/websim/src/websim.hh Removed Paths: ------------- code/websim/src/websim.h Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-03-10 06:53:56 UTC (rev 7433) +++ code/websim/CMakeLists.txt 2009-03-10 07:00:05 UTC (rev 7434) @@ -2,17 +2,32 @@ cmake_minimum_required( VERSION 2.4 FATAL_ERROR ) +include(FindPkgConfig) + +pkg_search_module( GLIB REQUIRED glib-2.0 ) +IF( GLIB_FOUND ) + MESSAGE( STATUS ${INDENT} "Glib version ${GLIB_VERSION} detected at ${GLIB_PREFIX}" ) + MESSAGE( STATUS " GLIB_CFLAGS = ${GLIB_CFLAGS}" ) + MESSAGE( STATUS " GLIB_LDFLAGS = ${GLIB_LDFLAGS}" ) +ELSE( GLIB_FOUND ) + MESSAGE( ${INDENT} "Glib not detected" ) +ENDIF( GLIB_FOUND ) + +include_directories( ${GLIB_INCLUDE_DIRS} ) +link_directories(${GLIB_LIBRARY_DIRS} ) + include_directories(include) -add_library(websim SHARED src/websim.cc) -add_library(websim-static STATIC src/websim.cc) +add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc ) +add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc ) # Set output name to be the same as shared lib (may not work on Windows) set_target_properties(websim-static PROPERTIES OUTPUT_NAME websim) # Prevent deletion of existing lib of same name set_target_properties(websim-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) -target_link_libraries(websim event) +target_link_libraries(websim event ${GLIB_LIBRARIES} ) install(TARGETS websim websim-static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) -install(FILES src/websim.h DESTINATION include/websim) +install(FILES src/websim.hh DESTINATION include/websim) + Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-10 06:53:56 UTC (rev 7433) +++ code/websim/src/websim.cc 2009-03-10 07:00:05 UTC (rev 7434) @@ -25,7 +25,7 @@ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ */ -#include "websim.h" +#include "websim.hh" #include <boost/lexical_cast.hpp> @@ -34,15 +34,24 @@ using namespace websim; +const std::string WebSim::package = "WebSim"; +const std::string WebSim::version = "0.1"; + WebSim::WebSim(const std::string& _fedfile, const std::string& _host, - int _port) : + unsigned short _port) : fedfile(_fedfile), host(_host), port(_port), tick_count_expected(0) { // Set up the HTTP server // Not sure whether it's safe to do this more that once in one process event_init(); + printf( "%s %s\n", package.c_str(), version.c_str() ); + + char buf[512]; + snprintf( buf, 512, "%s:%u", host.c_str(), port ); + hostportname = buf; + printf("[websim] Starting HTTP server listening on %s:%d...", this->host.c_str(), this->port); fflush(stdout); @@ -50,7 +59,12 @@ assert(eh); evhttp_set_gencb(eh, &WebSim::EventCallback, (void*)this); puts("Done."); - + + // if a federation file was specified, we parse it to populate the + // WebSim with confederates and puppets. + if( fedfile != "" ) + Parser p( this, _fedfile.c_str() ); + puts("[websim] Ready"); } Deleted: code/websim/src/websim.h =================================================================== --- code/websim/src/websim.h 2009-03-10 06:53:56 UTC (rev 7433) +++ code/websim/src/websim.h 2009-03-10 07:00:05 UTC (rev 7434) @@ -1,164 +0,0 @@ -/* - * WebSim - Library for web-enabling and federating simulators. - * Copyright (C) 2009 - * Richard Vaughan, Brian Gerkey, and Nate Koenig - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; 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> - -// 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> - -namespace websim -{ - -class Pose; -class Velocity; -class Acceleration; - -class WebSim -{ - public: - WebSim(const std::string& _fedfile, - const std::string& _host, - int _port); - virtual ~WebSim(); - - void Update(); - - // Interface to be implemented by simulators - virtual bool CreateModel(const std::string& name, - const std::string& type, - std::string& response) = 0; - virtual bool DeleteModel(const std::string& name, - std::string& response) = 0; - virtual bool SetModelPVA(const std::string& name, - const Pose& p, - const Velocity& v, - const Acceleration& a, - std::string& response) = 0; - virtual bool GetModelPVA(const std::string& name, - Pose& p, - Velocity& v, - Acceleration& a, - std::string& response) = 0; - - protected: - void StringSplit(const std::string &s, - std::vector<std::string> &t, - const std::string &d); - - private: - std::string fedfile; - std::string host; - int port; - - // Number of ticks we require before exiting Update() - int tick_count_expected; - // Number of ticks we've received since the last Update() - int tick_count; - - struct evhttp* eh; - - // Static, so that it can be passed as a callback to libevent - static void EventCallback(evhttp_request* req, void* arg); - - bool GetValue(std::string& value, - struct evkeyvalq* query_args, - const std::string& key); - 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, - std::string uri, - std::string& response); - void DeleteKeyVal(struct evkeyvalq* query_args); -}; - -class Pose -{ -public: - double x,y,z,r,p,a; - - Pose() : - x(0), y(0), z(0), r(0), p(0), a(0) - { - // nothing to do - } - - Pose( double x, double y, double z, - double r, double p, double a ) : - x(x), y(y), z(z), r(r), p(p), a(a) - { - // nothing to do - } - -}; - -class Velocity : public Pose -{ -public: - Velocity() : Pose() - {} - - Velocity( double x, double y, double z, - double r, double p, double a ) : - Pose( x, y, z, r, p, a ) - {} -}; - -class Acceleration : public Pose -{ -public: - Acceleration() : Pose() - {} - - Acceleration( double x, double y, double z, - double r, double p, double a ) : - Pose( x, y, z, r, p, a ) - {} -}; - - -} Added: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh (rev 0) +++ code/websim/src/websim.hh 2009-03-10 07:00:05 UTC (rev 7434) @@ -0,0 +1,285 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* Desc: HTTP interface to simulators + * Author: Brian Gerkey, Richard Vaughan + * Date: 9 March 2009 + * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ + */ + +#include <string> +#include <vector> +#include <map> + +// 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> + +// GLib-2.0 +#include <glib.h> + +// YAML +#include <yaml.h> + +namespace websim +{ + +class Pose; +class Velocity; +class Acceleration; + +class WebSim +{ + public: + WebSim(const std::string& _fedfile, + const std::string& _host, + unsigned short _port); + virtual ~WebSim(); + + void Update(); + + // Interface to be implemented by simulators + virtual bool CreateModel(const std::string& name, + const std::string& type, + std::string& response) = 0; + virtual bool DeleteModel(const std::string& name, + std::string& response) = 0; + virtual bool SetModelPVA(const std::string& name, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& response) = 0; + virtual bool GetModelPVA(const std::string& name, + Pose& p, + Velocity& v, + Acceleration& a, + std::string& response) = 0; + + protected: + void StringSplit(const std::string &s, + std::vector<std::string> &t, + const std::string &d); + + + // Number of ticks we require before exiting Update() + int tick_count_expected; + // Number of ticks we've received since the last Update() + int tick_count; + + private: + std::string fedfile; + std::string host; + std::string hostportname; // format "host:port" to uniquely identify this instance + unsigned short port; + + struct evhttp* eh; + + // Static, so that it can be passed as a callback to libevent + static void EventCallback(evhttp_request* req, void* arg); + + bool GetValue(std::string& value, + struct evkeyvalq* query_args, + const std::string& key); + 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, + std::string uri, + std::string& response); + void DeleteKeyVal(struct evkeyvalq* query_args); + + + // forward decare + class Confederate; + + // manage an object we control on some federated simulators + class Puppet + { + private: + WebSim* ws; + + public: + Puppet( WebSim* ws, const char* name ); + + // unique ID used as a system-widel handle for this puppet, used as + // hash table key + const char* name; + + bool created; + + // the remote servers that are hosting an instance of this puppet + GList* confederates; + + // sends the current physical state of the puppet to all + // confederates + void Push( Pose p, Velocity v, Acceleration a ); + + // create an instance of the puppet on this confederate, using the + // named puppet prototype (defined locally at the conferderate) + void AddConfederate( Confederate* conf, + const char* prototype ); + }; + + // manage a federated simulator + class Confederate + { + typedef struct + { + const char* name; + Confederate* conf; + } cb_chunk_t; + + private: + // connection to a remote http simulation server + struct evhttp_connection* http_con; + struct evhttp_request* http_req; + + static void PuppetCreationCallback( evhttp_request* req, void* arg ); + static void PuppetPushCallback( evhttp_request* req, void* arg ); + + // counts the number of status messages sent and replies not yet received + unsigned int unacknowledged_pushes; + + WebSim* ws; + + public: + Confederate( WebSim* ws, const char* host, unsigned short port ); + ~Confederate(); + + void AddPuppet( Puppet* puppet, + const char* prototype ); + + int Push( const char* name, Pose p, Velocity v, Acceleration a ); + + int RunStep(); + + // list of pointers to Puppet objects that are hosted on this + // connection - can iterate over these to update all puppets + GList* puppet_list; + + // unique ID for this confederate in format "hostname:port", used as + // hash table key + const char* name; + }; + + class Parser + { + private: + yaml_event_t event; + yaml_parser_t parser; + WebSim* ws; + + void parse_failed( const char* message ); + yaml_event_t next_event( const char* msg ); + void expect( yaml_event_type_t event_type, const char* msg ); + bool test( yaml_event_type_t event_type, const char* msg ); + Confederate* GetConfederate( const char* host, unsigned short port ); + Confederate* GetConfederate( const char* hostandport ); + void parse_puppet_mapping( Puppet* pup ); + void parse_puppet_mapping_sequence( Puppet* pup ); + void parse_model_mapping( std::string host ); + void parse_model_mapping_sequence( std::string host ); + void parse_host_mapping(); + void parse_document(); + void parse_stream(); + + public: + Parser( WebSim* ws, const char* filename ); + }; + + private: + // static const unsigned short DEFAULT_PORT; + static const std::string package; + static const std::string version; + + GHashTable* puppets; + GHashTable* confederates; + + /** Get a puppet by name */ + Puppet* GetPuppet( const char* name ); + + /** Get a confederate by name in format "host:port" */ + Confederate* GetConfederate( const char* name ); +}; + +class Pose +{ +public: + double x,y,z,r,p,a; + + Pose() : + x(0), y(0), z(0), r(0), p(0), a(0) + { + // nothing to do + } + + Pose( double x, double y, double z, + double r, double p, double a ) : + x(x), y(y), z(z), r(r), p(p), a(a) + { + // nothing to do + } + +}; + +class Velocity : public Pose +{ +public: + Velocity() : Pose() + {} + + Velocity( double x, double y, double z, + double r, double p, double a ) : + Pose( x, y, z, r, p, a ) + {} +}; + +class Acceleration : public Pose +{ +public: + Acceleration() : Pose() + {} + + Acceleration( double x, double y, double z, + double r, double p, double a ) : + Pose( x, y, z, r, p, a ) + {} +}; + + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-10 07:45:59
|
Revision: 7437 http://playerstage.svn.sourceforge.net/playerstage/?rev=7437&view=rev Author: rtv Date: 2009-03-10 07:45:57 +0000 (Tue, 10 Mar 2009) Log Message: ----------- fixed warnings Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/confederate.cc code/websim/src/parser.cc code/websim/src/puppet.cc code/websim/src/websim.cc Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-03-10 07:30:23 UTC (rev 7436) +++ code/websim/CMakeLists.txt 2009-03-10 07:45:57 UTC (rev 7437) @@ -17,8 +17,8 @@ link_directories(${GLIB_LIBRARY_DIRS} ) include_directories(include) -add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc ) -add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc ) +add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) +add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) # Set output name to be the same as shared lib (may not work on Windows) set_target_properties(websim-static PROPERTIES OUTPUT_NAME websim) # Prevent deletion of existing lib of same name Modified: code/websim/src/confederate.cc =================================================================== --- code/websim/src/confederate.cc 2009-03-10 07:30:23 UTC (rev 7436) +++ code/websim/src/confederate.cc 2009-03-10 07:45:57 UTC (rev 7437) @@ -1,3 +1,30 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* Desc: Confederate object mananges client connections with other WebSim servers + * Author: Richard Vaughan + * Date: 9 March 2009 + * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ + */ + #include <stdio.h> #include <assert.h> @@ -5,8 +32,8 @@ using namespace websim; WebSim::Confederate::Confederate( WebSim* ws, const char* host, unsigned short port ) : - puppet_list( NULL ), - unacknowledged_pushes( 0 ) + unacknowledged_pushes( 0 ), + puppet_list( NULL ) { if(! (http_con = evhttp_connection_new( host, port )) ) printf( "Error: Confederate object failed to connect to server at %s:%d\n", @@ -139,6 +166,8 @@ while( unacknowledged_pushes ) event_loop( EVLOOP_NONBLOCK ); // loops until the request has completed + + return 0; } int WebSim::Confederate::RunStep() Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-03-10 07:30:23 UTC (rev 7436) +++ code/websim/src/parser.cc 2009-03-10 07:45:57 UTC (rev 7437) @@ -1,4 +1,30 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +/* Desc: Federation file parser + * Author: Richard Vaughan + * Date: 9 March 2009 + * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ + */ + #include <stdio.h> #include <assert.h> #include <string> @@ -64,7 +90,7 @@ char hostnoport[256]; // parse out port number from hostname - sscanf( hostandport, "%s %u", &hostnoport, &port ); + sscanf( hostandport, "%s %u", hostnoport, &port ); return GetConfederate( hostnoport, port ); } Modified: code/websim/src/puppet.cc =================================================================== --- code/websim/src/puppet.cc 2009-03-10 07:30:23 UTC (rev 7436) +++ code/websim/src/puppet.cc 2009-03-10 07:45:57 UTC (rev 7437) @@ -1,4 +1,30 @@ +/* + * WebSim - Library for web-enabling and federating simulators. + * Copyright (C) 2009 + * Richard Vaughan, Brian Gerkey, and Nate Koenig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +/* Desc: Puppets are proxies for remote slave models + * Author: Richard Vaughan + * Date: 9 March 2009 + * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ + */ + #include <string.h> //for strdup() #include <stdio.h> @@ -7,9 +33,9 @@ WebSim::Puppet::Puppet( WebSim* ws, const char* name ) : + ws( ws ), name( strdup(name) ), - created( false ), - ws( ws ) + created( false ) { g_hash_table_insert( ws->puppets, (void*)this->name, this ); } Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-10 07:30:23 UTC (rev 7436) +++ code/websim/src/websim.cc 2009-03-10 07:45:57 UTC (rev 7437) @@ -40,7 +40,10 @@ WebSim::WebSim(const std::string& _fedfile, const std::string& _host, unsigned short _port) : - fedfile(_fedfile), host(_host), port(_port), tick_count_expected(0) + tick_count_expected(0), + fedfile(_fedfile), + host(_host), + port(_port) { // Set up the HTTP server // Not sure whether it's safe to do this more that once in one process This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-10 09:41:07
|
Revision: 7447 http://playerstage.svn.sourceforge.net/playerstage/?rev=7447&view=rev Author: rtv Date: 2009-03-10 09:40:49 +0000 (Tue, 10 Mar 2009) Log Message: ----------- working on examples and client Modified Paths: -------------- code/websim/src/confederate.cc code/websim/src/parser.cc code/websim/src/websim.cc code/websim/src/websim.hh Added Paths: ----------- code/websim/examples/ code/websim/examples/Makefile code/websim/examples/simple.cc code/websim/examples/world.fed Added: code/websim/examples/Makefile =================================================================== --- code/websim/examples/Makefile (rev 0) +++ code/websim/examples/Makefile 2009-03-10 09:40:49 UTC (rev 7447) @@ -0,0 +1,3 @@ + +simple: simple.cc + g++ -g -W -Wall -I/home/vaughan/gzfed/include `pkg-config --cflags glib-2.0` simple.cc -o $@ `pkg-config --libs glib-2.0` -L/home/vaughan/gzfed/lib -lwebsim -lyaml -lstdc++ \ No newline at end of file Added: code/websim/examples/simple.cc =================================================================== --- code/websim/examples/simple.cc (rev 0) +++ code/websim/examples/simple.cc 2009-03-10 09:40:49 UTC (rev 7447) @@ -0,0 +1,71 @@ +#include "websim/websim.hh" + +class MinWebSim : public websim::WebSim +{ +public: + MinWebSim(const std::string& fedfile, + const std::string& host, int port ) : + websim::WebSim( fedfile, host, port ) + { + } + + virtual ~MinWebSim() + {} + + // Interface to be implemented by simulators + virtual bool CreateModel(const std::string& name, + const std::string& type, + std::string& error) + { + printf( "create model name:%s type:%s\n", name.c_str(), type.c_str() ); + return true; + } + + virtual bool DeleteModel(const std::string& name, + std::string& error) + { + printf( "deletee model name:%s \n", name.c_str() ); + return true; + } + + virtual bool SetModelPVA(const std::string& name, + const websim::Pose& p, + const websim::Velocity& v, + const websim::Acceleration& a, + std::string& error) + { + printf( "set model PVA name:%s\n", name.c_str() ); + return true; + } + + virtual bool GetModelPVA(const std::string& name, + websim::Pose& p, + websim::Velocity& v, + websim::Acceleration& a, + std::string& error) + { + printf( "get model name:%s\n", name.c_str() ); + return true; + } +}; + + +int main( int argc, char** argv ) +{ + MinWebSim mws( argv[1], argv[2], atoi(argv[3]) ); + + while( 1 ) + { + websim::Pose p( 0,0,0,0,0,0 ); + websim::Velocity v( 0,0,0,0,0,0 ); + websim::Acceleration a( 0,0,0,0,0,0 ); + + //sleep(1); + + mws.SetPuppetPVA( "monkey", p, v, a ); + + mws.Update(); + + puts( "websim update returned" ); + } +} Added: code/websim/examples/world.fed =================================================================== --- code/websim/examples/world.fed (rev 0) +++ code/websim/examples/world.fed 2009-03-10 09:40:49 UTC (rev 7447) @@ -0,0 +1,30 @@ +# sourcehost: +# - modelname1: +# - desthost: prototype + +gort: + - monkey: + - "localhost 8001": pioneer2dx + +# - punky: +# - localhost: pioneer2dx +# - chunky: +# - localhost: pioneer2dx +# - funky: +# - localhost: pioneer2dx + + +# - roy: pioneer +# - "priss 8888": pioneer +# - pioneer2dx_model2: +# - deckard: pioneer +# - pioneer2dx_model3: +# - deckard: pioneer + +#"tenner 9999": +# - pr2_1: +# - deckard: pr2 + +#priss: +# - pr2_1: +# - "deckard 1234": pr2 Modified: code/websim/src/confederate.cc =================================================================== --- code/websim/src/confederate.cc 2009-03-10 09:40:23 UTC (rev 7446) +++ code/websim/src/confederate.cc 2009-03-10 09:40:49 UTC (rev 7447) @@ -32,7 +32,7 @@ using namespace websim; WebSim::Confederate::Confederate( WebSim* ws, const char* host, unsigned short port ) : - unacknowledged_pushes( 0 ), + ws(ws), puppet_list( NULL ) { if(! (http_con = evhttp_connection_new( host, port )) ) @@ -84,6 +84,9 @@ // name, // prototype ); + // the server needs to wait for ticks from this connected server + ++ws->tick_count_expected; + struct evhttp_request* er = evhttp_request_new( PuppetCreationCallback, puppet ); assert(er); @@ -116,9 +119,9 @@ if( req->response_code == 200 ) { - --ch->conf->unacknowledged_pushes; + --ch->conf->ws->unacknowledged_pushes; printf( "puppet push for \"%s\" acked OK. Outstanding pushes %u\n", - ch->name, ch->conf->unacknowledged_pushes ); + ch->name, ch->conf->ws->unacknowledged_pushes ); } else { @@ -155,7 +158,7 @@ printf( "Emitting: http://%s%s\n", this->name, buf ); - ++unacknowledged_pushes; // decremented when reply is received + ++ws->unacknowledged_pushes; // decremented when reply is received int ret = evhttp_make_request( http_con, er, EVHTTP_REQ_GET, buf ); if( ret != 0 ) @@ -164,17 +167,50 @@ exit(0); } - while( unacknowledged_pushes ) - event_loop( EVLOOP_NONBLOCK ); // loops until the request has completed - return 0; } -int WebSim::Confederate::RunStep() + +void WebSim::Confederate::TickReplyCb( evhttp_request* req, void* arg ) { + WebSim* ws = (WebSim*)arg; + + if( req->response_code == 200 ) + { + --ws->unacknowledged_pushes; + printf( "tick acked OK. Outstanding pushes %u\n", + ws->unacknowledged_pushes ); + } + else + { + printf( "bad response regarding tick\n" ); + printf( "code: %d\n", req->response_code ); + printf( "response: %s\n", req->input_buffer->buffer ); + } +} + + +int WebSim::Confederate::Tick() +{ // construct and send a tick message printf( "Confederate %s clock tick\n", name ); + + ++ws->unacknowledged_pushes; + + struct evhttp_request* er = + evhttp_request_new( PuppetPushCallback, ws ); + assert(er); + + int ret = evhttp_make_request( http_con, er, EVHTTP_REQ_GET, "/sim/clock/tick" ); + if( ret != 0 ) + { + printf( "send tick returned error %d\n", ret ); + exit(0); + } + + + return 0; } Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-03-10 09:40:23 UTC (rev 7446) +++ code/websim/src/parser.cc 2009-03-10 09:40:49 UTC (rev 7447) @@ -74,6 +74,9 @@ char lookup[256]; snprintf( lookup, 256, "%s:%u", host, port ); + assert( ws ); + assert( ws->confederates ); + Confederate* conf = (Confederate*) g_hash_table_lookup( ws->confederates, lookup ); @@ -138,7 +141,8 @@ string model = (char*)event.data.scalar.value; Puppet* pup = NULL; - + + cout << "host " << host << " hostportname " << ws->hostportname << endl; if( host == ws->hostportname ) pup = new Puppet( ws, model.c_str() ); @@ -180,7 +184,7 @@ { string host = (const char*)event.data.scalar.value; - // cout << "HOST " << host << endl; + cout << "HOST " << host << endl; Confederate* conf = GetConfederate( host.c_str() ); parse_model_mapping_sequence( conf->name ); Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-10 09:40:23 UTC (rev 7446) +++ code/websim/src/websim.cc 2009-03-10 09:40:49 UTC (rev 7447) @@ -43,7 +43,10 @@ tick_count_expected(0), fedfile(_fedfile), host(_host), - port(_port) + port(_port), + puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), + confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), + unacknowledged_pushes(0) { // Set up the HTTP server // Not sure whether it's safe to do this more that once in one process @@ -66,7 +69,10 @@ // if a federation file was specified, we parse it to populate the // WebSim with confederates and puppets. if( fedfile != "" ) - Parser p( this, _fedfile.c_str() ); + { + printf( "[websim] Loading federation file %s\n", _fedfile.c_str() ); + Parser p( this, _fedfile.c_str() ); + } puts("[websim] Ready"); } @@ -77,13 +83,21 @@ // No event_fini() to call... } +void WebSim::Confederate::TickCb( const char* name, Confederate* conf, void* arg ) +{ + conf->Tick(); +} + void WebSim::Update() { + // tick all my confederates + ForEachConfederate( Confederate::TickCb, NULL ); + tick_count = 0; do { - if(tick_count_expected) + if(tick_count_expected || unacknowledged_pushes ) event_loop(EVLOOP_ONCE); else event_loop(EVLOOP_NONBLOCK); @@ -399,3 +413,46 @@ return true; } + +WebSim::Puppet* WebSim::GetPuppet( const char* name ) +{ + return( (Puppet*)g_hash_table_lookup( WebSim::puppets, name ) ); +} + +WebSim::Confederate* WebSim::GetConfederate( const char* name ) +{ + return( (Confederate*)g_hash_table_lookup( WebSim::confederates, name ) ); +} + +bool +WebSim::SetPuppetPVA( const std::string& name, + Pose& p, + Velocity& v, + Acceleration& a ) +{ + Puppet* pup = GetPuppet( name.c_str() ); + + if( pup ) + { + pup->Push( p,v,a ); + return true; + } + + printf( "[websim] warning: attempt to set puppet PVA on non-existent puppet \"%s\"\n", + name.c_str() ); + return false; +} + + void WebSim::ForEachConfederate( void(*cb)(const char*, WebSim::Confederate*, void*), void* arg ) +{ + g_hash_table_foreach( WebSim::confederates, + (GHFunc)cb, + arg ); +} + +void WebSim::ForEachPuppet( void(*cb)(const char*, WebSim::Puppet*, void*), void* arg ) +{ + g_hash_table_foreach( WebSim::puppets, + (GHFunc)cb, + arg ); +} Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-03-10 09:40:23 UTC (rev 7446) +++ code/websim/src/websim.hh 2009-03-10 09:40:49 UTC (rev 7447) @@ -77,6 +77,11 @@ Acceleration& a, std::string& response) = 0; + bool SetPuppetPVA( const std::string& name, + Pose& p, + Velocity& v, + Acceleration& a ); + protected: void StringSplit(const std::string &s, std::vector<std::string> &t, @@ -154,7 +159,7 @@ void AddConfederate( Confederate* conf, const char* prototype ); }; - + // manage a federated simulator class Confederate { @@ -172,9 +177,6 @@ static void PuppetCreationCallback( evhttp_request* req, void* arg ); static void PuppetPushCallback( evhttp_request* req, void* arg ); - // counts the number of status messages sent and replies not yet received - unsigned int unacknowledged_pushes; - WebSim* ws; public: @@ -186,7 +188,12 @@ int Push( const char* name, Pose p, Velocity v, Acceleration a ); - int RunStep(); + static void TickCb( const char* name, Confederate* conf, void* arg ); + static void TickReplyCb( evhttp_request* req, void* arg ); + + + // send a tick request to this host + int Tick(); // list of pointers to Puppet objects that are hosted on this // connection - can iterate over these to update all puppets @@ -230,11 +237,20 @@ GHashTable* puppets; GHashTable* confederates; + // counts the number of status messages sent and replies not yet received + unsigned int unacknowledged_pushes; + /** Get a puppet by name */ Puppet* GetPuppet( const char* name ); /** Get a confederate by name in format "host:port" */ Confederate* GetConfederate( const char* name ); + + /** For each confederate, call the callback function */ + void ForEachConfederate( void(*cb)(const char*, Confederate*, void*), void* arg ); + + /** For each puppet, call the callback function */ + void ForEachPuppet( void(*cb)(const char*, Puppet*, void*), void* arg ); }; class Pose This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ge...@us...> - 2009-03-10 18:36:31
|
Revision: 7452 http://playerstage.svn.sourceforge.net/playerstage/?rev=7452&view=rev Author: gerkey Date: 2009-03-10 18:36:28 +0000 (Tue, 10 Mar 2009) Log Message: ----------- Added test infrastructure, using gtest Modified Paths: -------------- code/websim/CMakeLists.txt Added Paths: ----------- code/websim/test/ code/websim/test/uritest.cc Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-03-10 18:30:28 UTC (rev 7451) +++ code/websim/CMakeLists.txt 2009-03-10 18:36:28 UTC (rev 7452) @@ -1,6 +1,10 @@ project(WebSim) +add_definitions(-g -Wall) cmake_minimum_required( VERSION 2.4 FATAL_ERROR ) +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +endif(COMMAND cmake_policy) include(FindPkgConfig) @@ -16,7 +20,7 @@ include_directories( ${GLIB_INCLUDE_DIRS} ) link_directories(${GLIB_LIBRARY_DIRS} ) -include_directories(include) +include_directories(src) add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) # Set output name to be the same as shared lib (may not work on Windows) @@ -31,3 +35,70 @@ ARCHIVE DESTINATION lib) install(FILES src/websim.hh DESTINATION include/websim) +# Everything below is test infrastructure +link_directories(gtest/lib) +include_directories(${PROJECT_BINARY_DIR}/gtest/include) +add_executable(uritest EXCLUDE_FROM_ALL test/uritest.cc) +target_link_libraries(uritest websim gtest yaml event) +add_dependencies(uritest fetch_and_build) + +add_custom_target(test + COMMAND uritest + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS uritest) + +############################################################################### +# Macro to dequote a string, in order to properly construct a command line. +# There must be an easier way to do this. +macro(_dequote_string _out _in) + set(${_out}) + string(REGEX REPLACE " " ";" tmp "${_in}") + foreach(_item ${tmp}) + string(LENGTH "${${_out}}" _len) + if(${_len} GREATER 0) + set(${_out} ${${_out}} ${_item}) + else(${_len} GREATER 0) + set(${_out} ${_item}) + endif(${_len} GREATER 0) + endforeach(_item) +endmacro(_dequote_string) + +# A macro to pull in an build gtest +macro(wget_and_build tarball tarball_url tarball_dir unpack_cmd configure_cmd make_cmd install_cmd) + find_package(Wget REQUIRED) + + _dequote_string(_unpack_cmd ${unpack_cmd}) + _dequote_string(_configure_cmd ${configure_cmd}) + _dequote_string(_make_cmd ${make_cmd}) + _dequote_string(_install_cmd ${install_cmd}) + + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/${tarball} + COMMAND ${WGET_EXECUTABLE} -r ${tarball_url} -O ${tarball} + COMMAND touch -c ${PROJECT_BINARY_DIR}/${tarball} + VERBATIM) + + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/${tarball_dir} + COMMAND ${_unpack_cmd} ${tarball} + COMMAND touch -c ${tarball_dir} + DEPENDS ${PROJECT_BINARY_DIR}/${tarball} + VERBATIM) + + add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/installed + COMMAND cmake -E chdir ${PROJECT_BINARY_DIR}/${tarball_dir} ${_configure_cmd} + COMMAND cmake -E chdir ${PROJECT_BINARY_DIR}/${tarball_dir} ${_make_cmd} + COMMAND cmake -E chdir ${PROJECT_BINARY_DIR}/${tarball_dir} ${_install_cmd} + COMMAND touch ${PROJECT_BINARY_DIR}/installed + DEPENDS ${PROJECT_BINARY_DIR}/${tarball_dir} + VERBATIM) + + add_custom_target(fetch_and_build + DEPENDS ${PROJECT_BINARY_DIR}/installed) +endmacro(wget_and_build) + +wget_and_build(gtest-1.0.1.tar.gz + http://pr.willowgarage.com/downloads/gtest-1.0.1.tar.gz + gtest-1.0.1 + "tar xzf" + "./configure --prefix=${PROJECT_BINARY_DIR}/gtest" + "make" + "make install") Added: code/websim/test/uritest.cc =================================================================== --- code/websim/test/uritest.cc (rev 0) +++ code/websim/test/uritest.cc 2009-03-10 18:36:28 UTC (rev 7452) @@ -0,0 +1,87 @@ +#include "websim.hh" + +#include <gtest/gtest.h> + +// These headers must be included prior to the libevent headers +#include <sys/types.h> +#include <sys/queue.h> +#include <event.h> + +#include <sys/time.h> +#include <time.h> + +const char* g_host = "localhost"; +const unsigned short g_port = 8000; +bool g_success; +bool g_failure; +struct timeval t0; +std::string g_response; + +void Mark() { gettimeofday(&t0, NULL); } +double +ElapsedTime() +{ + struct timeval t1; + gettimeofday(&t1, NULL); + return (t1.tv_sec + t1.tv_usec / 1e6) - (t0.tv_sec + t0.tv_usec / 1e6); +} + +void +Loop(double dt) +{ + struct timespec sleeptime = {0, 1000000}; + g_success = false; + g_failure = false; + Mark(); + while(!g_success && !g_failure && (ElapsedTime() < dt)) + { + event_loop(EVLOOP_NONBLOCK); + nanosleep(&sleeptime, NULL); + } +} + +void +RequestCallback(evhttp_request* req, void* arg) +{ + if(req->input_buffer->buffer) + g_response = std::string((const char*)req->input_buffer->buffer); + else + g_response = ""; + if(req->response_code == 200) + g_success = true; + else + g_failure = true; +} + +TEST(URITest, createGetSetGet) +{ + struct evhttp_connection* http_con; + struct evhttp_request* er; + ASSERT_TRUE((http_con = evhttp_connection_new(g_host, g_port))); + + ASSERT_TRUE((er = evhttp_request_new(RequestCallback, NULL))); + ASSERT_FALSE(evhttp_make_request(http_con, er, EVHTTP_REQ_GET, + "/sim/factory/create?name=foo&type=pioneer2dx")); + Loop(5.0); + if(!g_success) + FAIL(); + + ASSERT_TRUE((er = evhttp_request_new(RequestCallback, NULL))); + ASSERT_FALSE(evhttp_make_request(http_con, er, EVHTTP_REQ_GET, "/foo/pva/get")); + Loop(5.0); + if(!g_success) + FAIL(); + + ASSERT_TRUE((er = evhttp_request_new(RequestCallback, NULL))); + ASSERT_FALSE(evhttp_make_request(http_con, er, EVHTTP_REQ_GET, "/foo/pva/set?pz=2.0")); + Loop(5.0); + if(!g_success) + FAIL(); +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + event_init(); + return RUN_ALL_TESTS(); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-10 19:02:58
|
Revision: 7455 http://playerstage.svn.sourceforge.net/playerstage/?rev=7455&view=rev Author: rtv Date: 2009-03-10 19:02:49 +0000 (Tue, 10 Mar 2009) Log Message: ----------- adding logical host mapping Modified Paths: -------------- code/websim/examples/Makefile code/websim/examples/world.fed code/websim/src/confederate.cc code/websim/src/parser.cc code/websim/src/puppet.cc code/websim/src/websim.cc code/websim/src/websim.hh Modified: code/websim/examples/Makefile =================================================================== --- code/websim/examples/Makefile 2009-03-10 18:50:16 UTC (rev 7454) +++ code/websim/examples/Makefile 2009-03-10 19:02:49 UTC (rev 7455) @@ -1,3 +1,8 @@ -simple: simple.cc +all: clean minwebsim + +clean: + rm -f minwebsim + +minwebsim: simple.cc g++ -g -W -Wall -I/home/vaughan/gzfed/include `pkg-config --cflags glib-2.0` simple.cc -o $@ `pkg-config --libs glib-2.0` -L/home/vaughan/gzfed/lib -lwebsim -lyaml -lstdc++ \ No newline at end of file Modified: code/websim/examples/world.fed =================================================================== --- code/websim/examples/world.fed 2009-03-10 18:50:16 UTC (rev 7454) +++ code/websim/examples/world.fed 2009-03-10 19:02:49 UTC (rev 7455) @@ -1,30 +1,11 @@ -# sourcehost: -# - modelname1: -# - desthost: prototype -gort: - - monkey: - - "localhost 8001": pioneer2dx -# - punky: -# - localhost: pioneer2dx -# - chunky: -# - localhost: pioneer2dx -# - funky: -# - localhost: pioneer2dx +federation: + - "gort 8000": minwebsim + - "gort 8001": webgazebo +minwebsim: + - monkey: + - webgazbo: pioneer2dx -# - roy: pioneer -# - "priss 8888": pioneer -# - pioneer2dx_model2: -# - deckard: pioneer -# - pioneer2dx_model3: -# - deckard: pioneer -#"tenner 9999": -# - pr2_1: -# - deckard: pr2 - -#priss: -# - pr2_1: -# - "deckard 1234": pr2 Modified: code/websim/src/confederate.cc =================================================================== --- code/websim/src/confederate.cc 2009-03-10 18:50:16 UTC (rev 7454) +++ code/websim/src/confederate.cc 2009-03-10 19:02:49 UTC (rev 7455) @@ -31,13 +31,13 @@ #include "websim.hh" using namespace websim; -WebSim::Confederate::Confederate( WebSim* ws, const char* host, unsigned short port ) : +WebSim::Confederate::Confederate( WebSim* ws, std::string host, unsigned short port ) : ws(ws), puppet_list( NULL ) { - if(! (http_con = evhttp_connection_new( host, port )) ) + if(! (http_con = evhttp_connection_new( host.c_str(), port )) ) printf( "Error: Confederate object failed to connect to server at %s:%d\n", - host, port ); + host.c_str(), port ); char* remote_host = NULL; unsigned short remote_port = 0; @@ -53,8 +53,9 @@ name = strdup(buf); - g_hash_table_insert( ws->confederates, (void*)name, this ); - //printf( "\t\tConfederate %s constructed \n", name ); + g_hash_table_insert( ws->confederates, (void*)name.c_str(), this ); + + printf( "\t\tConfederate %s constructed \n", name.c_str() ); } WebSim::Confederate::~Confederate() @@ -69,14 +70,14 @@ pup->created = true; else { - printf( "bad response regarding puppet creation \"%s\"\n", pup->name ); + printf( "bad response regarding puppet creation \"%s\"\n", pup->name.c_str() ); printf( "code: %d\n", req->response_code ); printf( "response: %s\n", req->input_buffer->buffer ); } } void WebSim::Confederate::AddPuppet( Puppet* puppet, - const char* prototype ) + std::string prototype ) { // send a create message //printf( "Creating puppet \"%s\" on %s using prototype \"%s\"\n", @@ -93,10 +94,10 @@ char buf[512]; snprintf( buf, 512, "/sim/factory/create?name=%s&type=%s", - puppet->name, - prototype ); + puppet->name.c_str(), + prototype.c_str() ); - printf( "Emitting: http://%s%s\n", name, buf ); + printf( "Emitting: http://%s%s\n", name.c_str(), buf ); int ret = evhttp_make_request( http_con, er, EVHTTP_REQ_GET, buf ); if( ret != 0 ) @@ -121,21 +122,21 @@ { --ch->conf->ws->unacknowledged_pushes; printf( "puppet push for \"%s\" acked OK. Outstanding pushes %u\n", - ch->name, ch->conf->ws->unacknowledged_pushes ); + ch->name.c_str(), ch->conf->ws->unacknowledged_pushes ); } else { - printf( "bad response regarding puppet push \"%s\"\n", ch->name ); + printf( "bad response regarding puppet push \"%s\"\n", ch->name.c_str() ); printf( "code: %d\n", req->response_code ); printf( "response: %s\n", req->input_buffer->buffer ); } } -int WebSim::Confederate::Push( const char* name, Pose p, Velocity v, Acceleration a ) +int WebSim::Confederate::Push( std::string name, Pose p, Velocity v, Acceleration a ) { printf( "\tconfederate %s pushing state of \"%s\"\n", - this->name, - name ); + this->name.c_str(), + name.c_str() ); // compose a struct to send into the callback cb_chunk_t ch; @@ -151,12 +152,12 @@ "px=%.6f&py=%.6f&pz=%.6f&pr=%.6f&pp=%.6f&pa=%.6f&" "vx=%.6f&vy=%.6f&vz=%.6f&vr=%.6f&vp=%.6f&va=%.6f&" "ax=%.6f&ay=%.6f&az=%.6f&ar=%.6f&ap=%.6f&aa=%.6f", - name, + name.c_str(), p.x, p.y, p.z, p.r, p.p, p.a, v.x, v.y, v.z, v.r, v.p, v.a, a.x, a.y, a.z, a.r, a.p, a.a ); - printf( "Emitting: http://%s%s\n", this->name, buf ); + printf( "Emitting: http://%s%s\n", this->name.c_str(), buf ); ++ws->unacknowledged_pushes; // decremented when reply is received @@ -194,12 +195,12 @@ { // construct and send a tick message printf( "Confederate %s clock tick\n", - name ); + name.c_str() ); ++ws->unacknowledged_pushes; struct evhttp_request* er = - evhttp_request_new( PuppetPushCallback, ws ); + evhttp_request_new( TickReplyCb, ws ); assert(er); int ret = evhttp_make_request( http_con, er, EVHTTP_REQ_GET, "/sim/clock/tick" ); Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-03-10 18:50:16 UTC (rev 7454) +++ code/websim/src/parser.cc 2009-03-10 19:02:49 UTC (rev 7455) @@ -41,38 +41,43 @@ cout << "\t" << req << endl; } -void WebSim::Parser::parse_failed( const char* message ) +void WebSim::Parser::parse_failed( std::string message ) { printf( "federation file parse failed at line: %u column: %u type %u %s\n", event.start_mark.line, event.start_mark.column, event.type, - message ); + message.c_str() ); exit(0); } -yaml_event_t WebSim::Parser::next_event( const char* msg ) +void WebSim::Parser::next_event( std::string msg ) { - yaml_event_delete( &event ); + //yaml_event_delete( &event ); + //cout << "next_event msg " << msg << endl; + if (!yaml_parser_parse( &parser, &event)) parse_failed( msg ); - - return event; } -void WebSim::Parser::expect( yaml_event_type_t event_type, const char* msg ) +void WebSim::Parser::expect( yaml_event_type_t expected_type, std::string msg ) { - //printf( "expecting %s\n", msg ); - - if( next_event( "" ).type != event_type ) - parse_failed( msg ); + //cout << "expecting " << msg << endl; + + next_event( "IN EXPECTING" ); + if( event.type != expected_type ) + { + printf( "Expecting type %d, got type %d\n", + expected_type, event.type ); + parse_failed( msg ); + } } -WebSim::Confederate* WebSim::Parser::GetConfederate( const char* host, unsigned short port ) +WebSim::Confederate* WebSim::Parser::GetConfederate( std::string host, unsigned short port ) { char lookup[256]; - snprintf( lookup, 256, "%s:%u", host, port ); + snprintf( lookup, 256, "%s:%u", host.c_str(), port ); assert( ws ); assert( ws->confederates ); @@ -87,13 +92,13 @@ } -WebSim::Confederate* WebSim::Parser::GetConfederate( const char* hostandport ) +WebSim::Confederate* WebSim::Parser::GetConfederate( std::string hostandport ) { unsigned int port = ws->port; char hostnoport[256]; // parse out port number from hostname - sscanf( hostandport, "%s %u", hostnoport, &port ); + sscanf( hostandport.c_str(), "%s %u", hostnoport, &port ); return GetConfederate( hostnoport, port ); } @@ -101,10 +106,10 @@ void WebSim::Parser::parse_puppet_mapping( Puppet* pup ) { expect( YAML_SCALAR_EVENT, "puppet host" ); - const char* host = strdup((const char*)event.data.scalar.value); + std::string host = (const char*)event.data.scalar.value; expect( YAML_SCALAR_EVENT, "puppet type" ); - const char* prototype = strdup((const char*)event.data.scalar.value); + std::string prototype = (const char*)event.data.scalar.value; expect( YAML_MAPPING_END_EVENT, "puppet mapping" ); @@ -138,11 +143,11 @@ void WebSim::Parser::parse_model_mapping( string host ) { expect( YAML_SCALAR_EVENT, "model name" ); - string model = (char*)event.data.scalar.value; + string model = (const char*)event.data.scalar.value; Puppet* pup = NULL; - cout << "host " << host << " hostportname " << ws->hostportname << endl; + // cout << "host " << host << " hostportname " << ws->hostportname << endl; if( host == ws->hostportname ) pup = new Puppet( ws, model.c_str() ); @@ -171,26 +176,77 @@ } } + +void WebSim::Parser::parse_logical_host() +{ + expect( YAML_SCALAR_EVENT, "host and port" ); + + string hostandport = (const char*)event.data.scalar.value; + //cout << "[websim] host mapping \"" << hostandport << "\"" << endl; + + expect( YAML_SCALAR_EVENT, "logical name" ); + + string logicalname = (const char*)event.data.scalar.value; + cout << "[websim] " << hostandport << " -> " << logicalname << endl; + + expect( YAML_MAPPING_END_EVENT, "end of model mapping" ); +} + +void WebSim::Parser::parse_logical_host_sequence() +{ + expect( YAML_SEQUENCE_START_EVENT, "start of logical host mappings" ); + + while( 1 ) + { + next_event( "barf" ); + switch( event.type ) + { + case YAML_MAPPING_START_EVENT: + // cout << "parsing logical host" << endl; + parse_logical_host(); + break; + case YAML_SEQUENCE_END_EVENT: + cout << "[websim] host mapping done." << endl; + return; + default: + parse_failed( "expecting a logical host mapping or end of sequence" ); + } + } +} + void WebSim::Parser::parse_host_mapping() { - expect( YAML_MAPPING_START_EVENT, "host mapping start" ); + expect( YAML_MAPPING_START_EVENT, "host sequence start" ); while( 1 ) { - next_event( "" ); + next_event( "start of host sequence" ); switch( event.type ) { case YAML_SCALAR_EVENT: { string host = (const char*)event.data.scalar.value; - cout << "HOST " << host << endl; - - Confederate* conf = GetConfederate( host.c_str() ); - parse_model_mapping_sequence( conf->name ); + if( host == "federation" ) + { + cout << "[websim] mapping hosts..." << endl; + parse_logical_host_sequence(); + cout << "[websim] mapping hosts done." << endl; + } + else + { + cout << "[websim] host: " << host << " hostportname: " << ws->hostportname << endl; + + Confederate* conf = GetConfederate( host.c_str() ); + assert(conf); + + cout << "[websim] conf->host: " << conf->name << " hostportname: " << ws->hostportname << endl; + + parse_model_mapping_sequence( conf->name ); + } } break; - case YAML_MAPPING_END_EVENT: + case YAML_SEQUENCE_END_EVENT: return; default: parse_failed( "expecting a host scalar or a end of mapping" ); @@ -198,47 +254,26 @@ } } -void WebSim::Parser::parse_document() -{ - expect( YAML_DOCUMENT_START_EVENT, "document start" ); - parse_host_mapping(); - expect( YAML_DOCUMENT_END_EVENT, "document end" ); -} - -void WebSim::Parser::parse_stream() -{ - expect( YAML_STREAM_START_EVENT, "stream start" ); - parse_document(); - expect( YAML_STREAM_END_EVENT, "stream end" ); -} - -WebSim::Parser::Parser( WebSim* ws, const char* filename ) : +WebSim::Parser::Parser( WebSim* ws, std::string filename ) : ws( ws ) { -// char hst[256]; -// if( gethostname( hst, 256 ) ) -// { -// perror( "failed to get hostname" ); -// exit( 0 ); -// } - -// char buf[256]; -// snprintf( buf, 256, "%s:%u", hst, WebSim::DEFAULT_PORT ); - -// // copy the c string into a std:string -// ws->hostportname = buf; - - /* Create the Parser object. */ + /* Create the Parser object. */ yaml_parser_initialize(&parser); /* Set a file input. */ - FILE *input = fopen( filename, "rb"); + FILE *input = fopen( filename.c_str(), "rb"); assert( input ); yaml_parser_set_input_file(&parser, input); - parse_stream(); + expect( YAML_STREAM_START_EVENT, "stream start" ); + expect( YAML_DOCUMENT_START_EVENT, "document start" ); + parse_host_mapping(); + + expect( YAML_DOCUMENT_END_EVENT, "document end" ); + expect( YAML_STREAM_END_EVENT, "stream end" ); + /* The application is responsible for destroying the event object. */ yaml_event_delete(&event); Modified: code/websim/src/puppet.cc =================================================================== --- code/websim/src/puppet.cc 2009-03-10 18:50:16 UTC (rev 7454) +++ code/websim/src/puppet.cc 2009-03-10 19:02:49 UTC (rev 7455) @@ -25,19 +25,20 @@ * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ */ -#include <string.h> //for strdup() +//#include <string.h> //for strdup() #include <stdio.h> #include "websim.hh" using namespace websim; -WebSim::Puppet::Puppet( WebSim* ws, const char* name ) : +WebSim::Puppet::Puppet( WebSim* ws, std::string name ) : ws( ws ), - name( strdup(name) ), + name( name ), created( false ) { - g_hash_table_insert( ws->puppets, (void*)this->name, this ); + g_hash_table_insert( ws->puppets, (void*)this->name.c_str(), this ); + printf( "Puppet \"%s\" constructed\n", this->name.c_str() ); } void WebSim::Puppet::Push( Pose p, Velocity v, Acceleration a ) @@ -52,7 +53,7 @@ } void WebSim::Puppet::AddConfederate( Confederate* conf, - const char* prototype ) + std::string prototype ) { conf->AddPuppet( this, prototype ); confederates = g_list_append( confederates, conf ); Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-10 18:50:16 UTC (rev 7454) +++ code/websim/src/websim.cc 2009-03-10 19:02:49 UTC (rev 7455) @@ -46,18 +46,23 @@ port(_port), puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), + logical_hosts( g_hash_table_new( g_str_hash, g_str_equal ) ), unacknowledged_pushes(0) { + + char buf[512]; + snprintf( buf, 512, "%s %u", host.c_str(), port ); + hostportname = buf; + + printf( "[websim] %s %s ID \"%s\"\n", + package.c_str(), + version.c_str(), + hostportname.c_str() ); + // Set up the HTTP server // Not sure whether it's safe to do this more that once in one process event_init(); - printf( "%s %s\n", package.c_str(), version.c_str() ); - - char buf[512]; - snprintf( buf, 512, "%s:%u", host.c_str(), port ); - hostportname = buf; - printf("[websim] Starting HTTP server listening on %s:%d...", this->host.c_str(), this->port); fflush(stdout); @@ -83,16 +88,26 @@ // No event_fini() to call... } -void WebSim::Confederate::TickCb( const char* name, Confederate* conf, void* arg ) +void WebSim::Confederate::TickCb( std::string name, Confederate* conf, void* arg ) { - conf->Tick(); + WebSim* ws = (WebSim*)arg; + + std::string confname = conf->name; + + if( confname != ws->hostportname ) // don't tick myself + { + printf( "ticking conf %s\n", conf->name.c_str() ); + conf->Tick(); + } + else + printf( "NOT ticking myself %s\n", conf->name.c_str() ); } void WebSim::Update() { // tick all my confederates - ForEachConfederate( Confederate::TickCb, NULL ); + ForEachConfederate( Confederate::TickCb, this ); tick_count = 0; do @@ -414,14 +429,14 @@ return true; } -WebSim::Puppet* WebSim::GetPuppet( const char* name ) +WebSim::Puppet* WebSim::GetPuppet( std::string name ) { - return( (Puppet*)g_hash_table_lookup( WebSim::puppets, name ) ); + return( (Puppet*)g_hash_table_lookup( WebSim::puppets, name.c_str() ) ); } -WebSim::Confederate* WebSim::GetConfederate( const char* name ) +WebSim::Confederate* WebSim::GetConfederate( std::string name ) { - return( (Confederate*)g_hash_table_lookup( WebSim::confederates, name ) ); + return( (Confederate*)g_hash_table_lookup( WebSim::confederates, name.c_str() ) ); } bool @@ -443,14 +458,14 @@ return false; } - void WebSim::ForEachConfederate( void(*cb)(const char*, WebSim::Confederate*, void*), void* arg ) + void WebSim::ForEachConfederate( void(*cb)(std::string, WebSim::Confederate*, void*), void* arg ) { g_hash_table_foreach( WebSim::confederates, (GHFunc)cb, arg ); } -void WebSim::ForEachPuppet( void(*cb)(const char*, WebSim::Puppet*, void*), void* arg ) +void WebSim::ForEachPuppet( void(*cb)(std::string, WebSim::Puppet*, void*), void* arg ) { g_hash_table_foreach( WebSim::puppets, (GHFunc)cb, Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-03-10 18:50:16 UTC (rev 7454) +++ code/websim/src/websim.hh 2009-03-10 19:02:49 UTC (rev 7455) @@ -139,11 +139,11 @@ WebSim* ws; public: - Puppet( WebSim* ws, const char* name ); + Puppet( WebSim* ws, std::string name ); // unique ID used as a system-widel handle for this puppet, used as // hash table key - const char* name; + std::string name; bool created; @@ -157,7 +157,7 @@ // create an instance of the puppet on this confederate, using the // named puppet prototype (defined locally at the conferderate) void AddConfederate( Confederate* conf, - const char* prototype ); + std::string prototype ); }; // manage a federated simulator @@ -165,7 +165,7 @@ { typedef struct { - const char* name; + std::string name; Confederate* conf; } cb_chunk_t; @@ -180,15 +180,15 @@ WebSim* ws; public: - Confederate( WebSim* ws, const char* host, unsigned short port ); + Confederate( WebSim* ws, std::string host, unsigned short port ); ~Confederate(); void AddPuppet( Puppet* puppet, - const char* prototype ); + std::string prototype ); - int Push( const char* name, Pose p, Velocity v, Acceleration a ); + int Push( std::string name, Pose p, Velocity v, Acceleration a ); - static void TickCb( const char* name, Confederate* conf, void* arg ); + static void TickCb( std::string name, Confederate* conf, void* arg ); static void TickReplyCb( evhttp_request* req, void* arg ); @@ -201,7 +201,7 @@ // unique ID for this confederate in format "hostname:port", used as // hash table key - const char* name; + std::string name; }; class Parser @@ -211,22 +211,22 @@ yaml_parser_t parser; WebSim* ws; - void parse_failed( const char* message ); - yaml_event_t next_event( const char* msg ); - void expect( yaml_event_type_t event_type, const char* msg ); - bool test( yaml_event_type_t event_type, const char* msg ); - Confederate* GetConfederate( const char* host, unsigned short port ); - Confederate* GetConfederate( const char* hostandport ); + void parse_failed( std::string message ); + void next_event( std::string msg ); + void expect( yaml_event_type_t event_type, std::string msg ); + Confederate* GetConfederate( std::string host, unsigned short port ); + Confederate* GetConfederate( std::string hostandport ); void parse_puppet_mapping( Puppet* pup ); void parse_puppet_mapping_sequence( Puppet* pup ); void parse_model_mapping( std::string host ); void parse_model_mapping_sequence( std::string host ); - void parse_host_mapping(); - void parse_document(); - void parse_stream(); + void parse_host_mapping(); + void parse_logical_host(); + void parse_logical_host_sequence(); + public: - Parser( WebSim* ws, const char* filename ); + Parser( WebSim* ws, std::string filename ); }; private: @@ -236,21 +236,22 @@ GHashTable* puppets; GHashTable* confederates; + GHashTable* logical_hosts; // counts the number of status messages sent and replies not yet received unsigned int unacknowledged_pushes; /** Get a puppet by name */ - Puppet* GetPuppet( const char* name ); + Puppet* GetPuppet( std::string name ); /** Get a confederate by name in format "host:port" */ - Confederate* GetConfederate( const char* name ); + Confederate* GetConfederate( std::string name ); /** For each confederate, call the callback function */ - void ForEachConfederate( void(*cb)(const char*, Confederate*, void*), void* arg ); + void ForEachConfederate( void(*cb)(std::string, Confederate*, void*), void* arg ); /** For each puppet, call the callback function */ - void ForEachPuppet( void(*cb)(const char*, Puppet*, void*), void* arg ); + void ForEachPuppet( void(*cb)(std::string, Puppet*, void*), void* arg ); }; class Pose This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <na...@us...> - 2009-03-11 20:22:59
|
Revision: 7462 http://playerstage.svn.sourceforge.net/playerstage/?rev=7462&view=rev Author: natepak Date: 2009-03-11 20:22:49 +0000 (Wed, 11 Mar 2009) Log Message: ----------- Added simple pkgconfig Modified Paths: -------------- code/websim/CMakeLists.txt Added Paths: ----------- code/websim/pkgconfig.cmake Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-03-11 16:19:22 UTC (rev 7461) +++ code/websim/CMakeLists.txt 2009-03-11 20:22:49 UTC (rev 7462) @@ -1,5 +1,27 @@ project(WebSim) +############################################################################### +# WEBSIM_MAKE_PKGCONFIG +# Make a pkg-config file for a library +MACRO (WEBSIM_MAKE_PKGCONFIG _name _desc _extDeps _intDeps _cFlags _libFlags) + SET (PKG_NAME ${_name}) + SET (PKG_DESC ${_desc}) + SET (PKG_CFLAGS ${_cFlags}) + SET (PKG_LIBFLAGS ${_libFlags}) + SET (PKG_EXTERNAL_DEPS ${_extDeps}) + SET (PKG_INTERNAL_DEPS "") + IF (${_intDeps}) + FOREACH (A ${_intDeps}) + SET (PKG_INTERNAL_DEPS "${PKG_INTERNAL_DEPS} -l${A}") + ENDFOREACH (A ${_intDeps}) + ENDIF (${_intDeps}) + + CONFIGURE_FILE (pkgconfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/${_name}.pc @ONLY) + INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/${_name}.pc DESTINATION lib/pkgconfig/ COMPONENT pkgconfig) +ENDMACRO (WEBSIM_MAKE_PKGCONFIG) + +WEBSIM_MAKE_PKGCONFIG("websim" "Websim library" "glib-2.0" "" "" "") + add_definitions(-g -Wall) cmake_minimum_required( VERSION 2.4 FATAL_ERROR ) if(COMMAND cmake_policy) @@ -102,3 +124,5 @@ "./configure --prefix=${PROJECT_BINARY_DIR}/gtest" "make" "make install") + + Added: code/websim/pkgconfig.cmake =================================================================== --- code/websim/pkgconfig.cmake (rev 0) +++ code/websim/pkgconfig.cmake 2009-03-11 20:22:49 UTC (rev 7462) @@ -0,0 +1,12 @@ +# This file was generated by CMake for @PROJECT_NAME@ library @PKG_NAME@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: @PKG_NAME@ +Description: @PKG_DESC@ +Version: @WEBSIM_VERSION@ +Requires: @PKG_EXTERNAL_DEPS@ +Libs: -L${libdir} -l@PKG_NAME@ @PKG_LIBFLAGS@ @PKG_INTERNAL_DEPS@ +Cflags: -I${includedir}/websim @PKG_CFLAGS@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-13 00:47:18
|
Revision: 7468 http://playerstage.svn.sourceforge.net/playerstage/?rev=7468&view=rev Author: rtv Date: 2009-03-13 00:46:58 +0000 (Fri, 13 Mar 2009) Log Message: ----------- completely reworked parser Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/examples/Makefile code/websim/examples/world.fed code/websim/src/confederate.cc code/websim/src/parser.cc code/websim/src/websim.cc code/websim/src/websim.hh Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-03-12 23:37:08 UTC (rev 7467) +++ code/websim/CMakeLists.txt 2009-03-13 00:46:58 UTC (rev 7468) @@ -61,7 +61,7 @@ link_directories(gtest/lib) include_directories(${PROJECT_BINARY_DIR}/gtest/include) add_executable(uritest EXCLUDE_FROM_ALL test/uritest.cc) -target_link_libraries(uritest websim gtest yaml event) +target_link_libraries(uritest websim gtest event) add_dependencies(uritest fetch_and_build) add_custom_target(test Modified: code/websim/examples/Makefile =================================================================== --- code/websim/examples/Makefile 2009-03-12 23:37:08 UTC (rev 7467) +++ code/websim/examples/Makefile 2009-03-13 00:46:58 UTC (rev 7468) @@ -1,8 +1,14 @@ -all: clean minwebsim +# set this to the directory that you installed websim +WSPREFIX=/Users/vaughan/Stage-3.0 +WSLDFLAGS=-L${WSPREFIX}/lib -lwebsim `pkg-config --libs glib-2.0` +WSCFLAGS=-g -W -Wall -I${WSPREFIX}/include `pkg-config --cflags glib-2.0` + +all: clean websimple + clean: - rm -f minwebsim + rm -f websimple -minwebsim: simple.cc - g++ -g -W -Wall -I/home/vaughan/gzfed/include `pkg-config --cflags glib-2.0` simple.cc -o $@ `pkg-config --libs glib-2.0` -L/home/vaughan/gzfed/lib -lwebsim -lyaml -lstdc++ \ No newline at end of file +websimple: simple.cc + g++ ${WSCFLAGS} simple.cc -o $@ ${WSLDFLAGS} \ No newline at end of file Modified: code/websim/examples/world.fed =================================================================== --- code/websim/examples/world.fed 2009-03-12 23:37:08 UTC (rev 7467) +++ code/websim/examples/world.fed 2009-03-13 00:46:58 UTC (rev 7468) @@ -1,11 +1,11 @@ +[federation] +deckard:8000=websimple +gort:8000=webgazebo -federation: - - "gort 8000": minwebsim - - "gort 8001": webgazebo +[websimple] +chunky=webgazebo:pioneer2dx +punky=webgazebo:pioneer2dx -minwebsim: - - monkey: - - webgazbo: pioneer2dx Modified: code/websim/src/confederate.cc =================================================================== --- code/websim/src/confederate.cc 2009-03-12 23:37:08 UTC (rev 7467) +++ code/websim/src/confederate.cc 2009-03-13 00:46:58 UTC (rev 7468) @@ -27,17 +27,29 @@ #include <stdio.h> #include <assert.h> +#include <iostream> #include "websim.hh" using namespace websim; -WebSim::Confederate::Confederate( WebSim* ws, std::string host, unsigned short port ) : +WebSim::Confederate::Confederate( WebSim* ws, + std::string uri ) : + name(uri), ws(ws), puppet_list( NULL ) { - if(! (http_con = evhttp_connection_new( host.c_str(), port )) ) + + size_t pos = uri.find( ":" ); // find the start of the port number + std::string portstr = uri.substr( pos+1 ); // set to the port number + + std::string hoststr = uri.substr( 0, pos ); + unsigned short portnum = atoi(portstr.c_str() ); + + std::cout << "Conf constructing connection: " << hoststr << " : " << portstr << std::endl; + + if(! (http_con = evhttp_connection_new( hoststr.c_str(), portnum )) ) printf( "Error: Confederate object failed to connect to server at %s:%d\n", - host.c_str(), port ); + hoststr.c_str(), portnum ); char* remote_host = NULL; unsigned short remote_port = 0; @@ -48,13 +60,10 @@ &remote_port ); // build the canonical name for this confederate - char buf[512]; - snprintf( buf, 512, "%s:%u", remote_host, remote_port ); - - name = strdup(buf); - - g_hash_table_insert( ws->confederates, (void*)name.c_str(), this ); - + //char buf[512]; + //snprintf( buf, 512, "%s:%u", remote_host, remote_port ); + //name = strdup(buf); + printf( "\t\tConfederate %s constructed \n", name.c_str() ); } Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-03-12 23:37:08 UTC (rev 7467) +++ code/websim/src/parser.cc 2009-03-13 00:46:58 UTC (rev 7468) @@ -30,255 +30,129 @@ #include <string> #include <iostream> -#include <yaml.h> // YAML parser +// we#include <yaml.h> // YAML parser using namespace std; #include "websim.hh" using namespace websim; -void httprequest( string req ) -{ - cout << "\t" << req << endl; -} -void WebSim::Parser::parse_failed( std::string message ) +WebSim::Parser::Parser( WebSim* ws, std::string filename ) : + ws( ws ) { - printf( "federation file parse failed at line: %u column: %u type %u %s\n", - event.start_mark.line, - event.start_mark.column, - event.type, - message.c_str() ); - exit(0); -} - -void WebSim::Parser::next_event( std::string msg ) -{ - //yaml_event_delete( &event ); - - //cout << "next_event msg " << msg << endl; - - if (!yaml_parser_parse( &parser, &event)) - parse_failed( msg ); -} - -void WebSim::Parser::expect( yaml_event_type_t expected_type, std::string msg ) -{ - //cout << "expecting " << msg << endl; - next_event( "IN EXPECTING" ); - if( event.type != expected_type ) + GError* err = NULL; + GKeyFile* keyfile = g_key_file_new(); + g_key_file_load_from_file( keyfile, + filename.c_str(), + G_KEY_FILE_NONE, + &err ); + + if( ! g_key_file_has_group( keyfile, "federation" ) ) { - printf( "Expecting type %d, got type %d\n", - expected_type, event.type ); - parse_failed( msg ); + printf( "[websim] Can't find the required [federation] section in federation file %s.\n", + filename.c_str() ); + exit( 0 ); } -} -WebSim::Confederate* WebSim::Parser::GetConfederate( std::string host, unsigned short port ) -{ - char lookup[256]; - snprintf( lookup, 256, "%s:%u", host.c_str(), port ); - - assert( ws ); - assert( ws->confederates ); - - Confederate* conf = (Confederate*) - g_hash_table_lookup( ws->confederates, lookup ); - - if( ! conf ) - conf = new Confederate( ws, host, port ); - - return conf; -} - - -WebSim::Confederate* WebSim::Parser::GetConfederate( std::string hostandport ) -{ - unsigned int port = ws->port; - char hostnoport[256]; - - // parse out port number from hostname - sscanf( hostandport.c_str(), "%s %u", hostnoport, &port ); - - return GetConfederate( hostnoport, port ); -} - -void WebSim::Parser::parse_puppet_mapping( Puppet* pup ) -{ - expect( YAML_SCALAR_EVENT, "puppet host" ); - std::string host = (const char*)event.data.scalar.value; - - expect( YAML_SCALAR_EVENT, "puppet type" ); - std::string prototype = (const char*)event.data.scalar.value; - - expect( YAML_MAPPING_END_EVENT, "puppet mapping" ); - - if( pup ) - pup->AddConfederate( GetConfederate( host ), - prototype ); - else - GetConfederate( host ); // federate for time sync only -} - -void WebSim:: Parser::parse_puppet_mapping_sequence( Puppet* pup ) -{ - expect( YAML_SEQUENCE_START_EVENT, "start of sequence of puppet mappings" ); - - while( 1 ) + // get an array of confederate hosts + gchar** fedkeys = g_key_file_get_keys( keyfile, + "federation", + NULL, + &err ); + // for each host + for( char** fedkeyp = fedkeys; + *fedkeyp; + fedkeyp++ ) { - next_event( "" ); - switch( event.type ) - { - case YAML_MAPPING_START_EVENT: - parse_puppet_mapping( pup ); - break; - case YAML_SEQUENCE_END_EVENT: - return; - default: - parse_failed( "expecting a puppet mapping or end of sequence" ); - } + // get the logical name + gchar* logicalname = g_key_file_get_string( keyfile, + "federation", + *fedkeyp, + &err ); + printf( "[websim] host %s is %s\n", + *fedkeyp, logicalname ); + + string hosturi = *fedkeyp; + Confederate* conf = new Confederate( ws, hosturi ); + assert(conf); + + // copy the hash table key so we can delete the original below + g_hash_table_insert( ws->confederates, strdup(logicalname), conf ); } -} - -void WebSim::Parser::parse_model_mapping( string host ) -{ - expect( YAML_SCALAR_EVENT, "model name" ); - string model = (const char*)event.data.scalar.value; - Puppet* pup = NULL; - - // cout << "host " << host << " hostportname " << ws->hostportname << endl; - if( host == ws->hostportname ) - pup = new Puppet( ws, model.c_str() ); + cout << "Looking up logical name for myself " << ws->hostportname << endl; - parse_puppet_mapping_sequence( pup ); + // now we have made all the confederates. + // Let's look up the confederate for this instance + // read the array of entries for this host + gchar* mylogicalname = g_key_file_get_string( keyfile, + "federation", + ws->hostportname.c_str(), + &err ); - expect( YAML_MAPPING_END_EVENT, "end of model mapping" ); -} + cout << "my logical name is " << mylogicalname << endl; -void WebSim::Parser::parse_model_mapping_sequence( string host ) -{ - expect( YAML_SEQUENCE_START_EVENT, "start of sequence of model mappings" ); - - while( 1 ) + // now we look up all the models listed under my logical name + // get an array of confederate hosts + gchar** models = g_key_file_get_keys( keyfile, + mylogicalname, + NULL, + &err ); + + if( models == NULL ) + printf( "[websim] No models to export.\n" ); + else { - next_event( "" ); - switch( event.type ) - { - case YAML_MAPPING_START_EVENT: - parse_model_mapping( host ); - break; - case YAML_SEQUENCE_END_EVENT: - return; - default: - parse_failed( "expecting a model mapping or end of sequence" ); - } - } -} + // for each model + for( char** modelp = models; + *modelp; + modelp++ ) + { + printf( "[websim] model %s\n", *modelp ); + + // get the puppet instructions + gchar** puppets = g_key_file_get_string_list( keyfile, + mylogicalname, + *modelp, + NULL, + &err ); + + if( puppets == NULL ) + printf( "[websim] No puppets specified for model \"%s\".\n", + *modelp ); + else + { + Puppet* pup = new Puppet( ws, *modelp ); + + // for each puppet + for( char** puppetp = puppets; + *puppetp; + puppetp++ ) + { + cout << " creating remote puppet " << *puppetp << endl; + + // split the name + string pupstr = *puppetp; + size_t pos = pupstr.find( ":" ); + std::string confstr = pupstr.substr( 0, pos ); + std::string typestr = pupstr.substr( pos+1 ); -void WebSim::Parser::parse_logical_host() -{ - expect( YAML_SCALAR_EVENT, "host and port" ); - - string hostandport = (const char*)event.data.scalar.value; - //cout << "[websim] host mapping \"" << hostandport << "\"" << endl; - - expect( YAML_SCALAR_EVENT, "logical name" ); - - string logicalname = (const char*)event.data.scalar.value; - cout << "[websim] " << hostandport << " -> " << logicalname << endl; - - expect( YAML_MAPPING_END_EVENT, "end of model mapping" ); -} - -void WebSim::Parser::parse_logical_host_sequence() -{ - expect( YAML_SEQUENCE_START_EVENT, "start of logical host mappings" ); - - while( 1 ) - { - next_event( "barf" ); - switch( event.type ) - { - case YAML_MAPPING_START_EVENT: - // cout << "parsing logical host" << endl; - parse_logical_host(); - break; - case YAML_SEQUENCE_END_EVENT: - cout << "[websim] host mapping done." << endl; - return; - default: - parse_failed( "expecting a logical host mapping or end of sequence" ); + Confederate* conf = ws->GetConfederate( confstr ); + assert( conf ); + + pup->AddConfederate( conf, typestr ); + } + } } } -} - -void WebSim::Parser::parse_host_mapping() -{ - expect( YAML_MAPPING_START_EVENT, "host sequence start" ); - while( 1 ) - { - next_event( "start of host sequence" ); - switch( event.type ) - { - case YAML_SCALAR_EVENT: - { - string host = (const char*)event.data.scalar.value; - - if( host == "federation" ) - { - cout << "[websim] mapping hosts..." << endl; - parse_logical_host_sequence(); - cout << "[websim] mapping hosts done." << endl; - } - else - { - cout << "[websim] host: " << host << " hostportname: " << ws->hostportname << endl; - - Confederate* conf = GetConfederate( host.c_str() ); - assert(conf); - - cout << "[websim] conf->host: " << conf->name << " hostportname: " << ws->hostportname << endl; - - parse_model_mapping_sequence( conf->name ); - } - } - break; - case YAML_SEQUENCE_END_EVENT: - return; - default: - parse_failed( "expecting a host scalar or a end of mapping" ); - } - } -} - -WebSim::Parser::Parser( WebSim* ws, std::string filename ) : - ws( ws ) -{ - /* Create the Parser object. */ - yaml_parser_initialize(&parser); + // XX + exit( 0 ); - /* Set a file input. */ - FILE *input = fopen( filename.c_str(), "rb"); - assert( input ); - - yaml_parser_set_input_file(&parser, input); - - expect( YAML_STREAM_START_EVENT, "stream start" ); - expect( YAML_DOCUMENT_START_EVENT, "document start" ); - - parse_host_mapping(); - - expect( YAML_DOCUMENT_END_EVENT, "document end" ); - expect( YAML_STREAM_END_EVENT, "stream end" ); - - /* The application is responsible for destroying the event object. */ - yaml_event_delete(&event); - - /* Destroy the Parser object. */ - yaml_parser_delete(&parser); + // free the key array + g_strfreev( fedkeys ); } Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-12 23:37:08 UTC (rev 7467) +++ code/websim/src/websim.cc 2009-03-13 00:46:58 UTC (rev 7468) @@ -40,18 +40,18 @@ WebSim::WebSim(const std::string& _fedfile, const std::string& _host, unsigned short _port) : - tick_count_expected(0), - fedfile(_fedfile), - host(_host), - port(_port), - puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), - confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), - logical_hosts( g_hash_table_new( g_str_hash, g_str_equal ) ), - unacknowledged_pushes(0) + tick_count_expected(0), + fedfile(_fedfile), + host(_host), + port(_port), + puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), + confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), + logical_hosts( g_hash_table_new( g_str_hash, g_str_equal ) ), + unacknowledged_pushes(0) { char buf[512]; - snprintf( buf, 512, "%s %u", host.c_str(), port ); + snprintf( buf, 512, "%s:%u", host.c_str(), port ); hostportname = buf; printf( "[websim] %s %s ID \"%s\"\n", Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-03-12 23:37:08 UTC (rev 7467) +++ code/websim/src/websim.hh 2009-03-13 00:46:58 UTC (rev 7468) @@ -41,7 +41,7 @@ #include <glib.h> // YAML -#include <yaml.h> +// #include <yaml.h> namespace websim { @@ -141,7 +141,7 @@ public: Puppet( WebSim* ws, std::string name ); - // unique ID used as a system-widel handle for this puppet, used as + // unique ID used as a system-wide handle for this puppet, used as // hash table key std::string name; @@ -180,7 +180,7 @@ WebSim* ws; public: - Confederate( WebSim* ws, std::string host, unsigned short port ); + Confederate( WebSim* ws, std::string uri ); ~Confederate(); void AddPuppet( Puppet* puppet, @@ -207,23 +207,23 @@ class Parser { private: - yaml_event_t event; - yaml_parser_t parser; + //yaml_event_t event; + //yaml_parser_t parser; WebSim* ws; - void parse_failed( std::string message ); - void next_event( std::string msg ); - void expect( yaml_event_type_t event_type, std::string msg ); - Confederate* GetConfederate( std::string host, unsigned short port ); - Confederate* GetConfederate( std::string hostandport ); - void parse_puppet_mapping( Puppet* pup ); - void parse_puppet_mapping_sequence( Puppet* pup ); - void parse_model_mapping( std::string host ); - void parse_model_mapping_sequence( std::string host ); - void parse_host_mapping(); - void parse_logical_host(); - void parse_logical_host_sequence(); + // void parse_failed( std::string message ); +// void next_event( std::string msg ); +// void expect( yaml_event_type_t event_type, std::string msg ); +// void parse_puppet_mapping( Puppet* pup ); +// void parse_puppet_mapping_sequence( Puppet* pup ); +// void parse_model_mapping( std::string host ); +// void parse_model_mapping_sequence( std::string host ); +// void parse_host_mapping(); +// void parse_logical_host(); +// void parse_logical_host_sequence(); + + // Confederate* GetConfederate( std::string name, std::string uri); public: Parser( WebSim* ws, std::string filename ); @@ -244,7 +244,7 @@ /** Get a puppet by name */ Puppet* GetPuppet( std::string name ); - /** Get a confederate by name in format "host:port" */ + /** Get a confederate by its logical name */ Confederate* GetConfederate( std::string name ); /** For each confederate, call the callback function */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-13 02:49:10
|
Revision: 7469 http://playerstage.svn.sourceforge.net/playerstage/?rev=7469&view=rev Author: rtv Date: 2009-03-13 02:49:05 +0000 (Fri, 13 Mar 2009) Log Message: ----------- parsing and clock sync now working Modified Paths: -------------- code/websim/examples/simple.cc code/websim/examples/world.fed code/websim/src/confederate.cc code/websim/src/parser.cc code/websim/src/puppet.cc code/websim/src/websim.cc code/websim/src/websim.hh Modified: code/websim/examples/simple.cc =================================================================== --- code/websim/examples/simple.cc 2009-03-13 00:46:58 UTC (rev 7468) +++ code/websim/examples/simple.cc 2009-03-13 02:49:05 UTC (rev 7469) @@ -34,7 +34,8 @@ const websim::Acceleration& a, std::string& error) { - printf( "set model PVA name:%s\n", name.c_str() ); + printf( "set model PVA name:%s\n", name.c_str() ); + return true; } @@ -52,20 +53,24 @@ int main( int argc, char** argv ) { - MinWebSim mws( argv[1], argv[2], atoi(argv[3]) ); + std::string filename = argv[1]; + std::string host = argv[2]; + unsigned short port = atoi( argv[3] ); + + MinWebSim mws( filename, host, port ); while( 1 ) { - websim::Pose p( 0,0,0,0,0,0 ); - websim::Velocity v( 0,0,0,0,0,0 ); - websim::Acceleration a( 0,0,0,0,0,0 ); - - //sleep(1); - - mws.SetPuppetPVA( "monkey", p, v, a ); - - mws.Update(); - - puts( "websim update returned" ); + if( port == 8000 ) + { + websim::Pose p( 0,0,0,0,0,0 ); + websim::Velocity v( 0,0,0,0,0,0 ); + websim::Acceleration a( 0,0,0,0,0,0 ); + + //usleep(100); + + mws.SetPuppetPVA( "monkey", p, v, a ); + } + mws.Update(); } } Modified: code/websim/examples/world.fed =================================================================== --- code/websim/examples/world.fed 2009-03-13 00:46:58 UTC (rev 7468) +++ code/websim/examples/world.fed 2009-03-13 02:49:05 UTC (rev 7469) @@ -1,11 +1,14 @@ [federation] -deckard:8000=websimple -gort:8000=webgazebo +deckard:8000=master +deckard:8001=slave1 +deckard:8002=slave2 +deckard:8003=slave3 -[websimple] -chunky=webgazebo:pioneer2dx -punky=webgazebo:pioneer2dx +[master] +monkey=slave1:pioneer2dx;slave2:pioneer2dx;slave3:pioneer2dx +chunky=slave1:pioneer2dx;slave2:pioneer2dx;slave3:pioneer2dx +punky=slave1:pioneer2dx;slave2:pioneer2dx;slave3:pioneer2dx Modified: code/websim/src/confederate.cc =================================================================== --- code/websim/src/confederate.cc 2009-03-13 00:46:58 UTC (rev 7468) +++ code/websim/src/confederate.cc 2009-03-13 02:49:05 UTC (rev 7469) @@ -59,12 +59,10 @@ &remote_host, &remote_port ); - // build the canonical name for this confederate - //char buf[512]; - //snprintf( buf, 512, "%s:%u", remote_host, remote_port ); - //name = strdup(buf); + printf( "\t\tConfederate %s constructed \n", name.c_str() ); - printf( "\t\tConfederate %s constructed \n", name.c_str() ); + if( uri != ws->hostportname ) + ws->tick_count_expected++; } WebSim::Confederate::~Confederate() @@ -88,15 +86,6 @@ void WebSim::Confederate::AddPuppet( Puppet* puppet, std::string prototype ) { - // send a create message - //printf( "Creating puppet \"%s\" on %s using prototype \"%s\"\n", - // puppet->name, - // name, - // prototype ); - - // the server needs to wait for ticks from this connected server - ++ws->tick_count_expected; - struct evhttp_request* er = evhttp_request_new( PuppetCreationCallback, puppet ); assert(er); @@ -117,7 +106,7 @@ // a successful response sets puppet->created to true while( ! puppet->created ) - event_loop( EVLOOP_NONBLOCK ); // loops until the request has completed + event_loop( EVLOOP_ONCE ); // loops until the request has completed puppet_list = g_list_append( puppet_list, puppet ); @@ -125,13 +114,21 @@ void WebSim::Confederate::PuppetPushCallback( evhttp_request* req, void* arg ) { + if( req == NULL ) + { + puts( "[websim] warning: broken connection waiting for push reply." ); + return; + } + cb_chunk_t* ch = (cb_chunk_t*)arg; - + assert(ch); + if( req->response_code == 200 ) { - --ch->conf->ws->unacknowledged_pushes; - printf( "puppet push for \"%s\" acked OK. Outstanding pushes %u\n", - ch->name.c_str(), ch->conf->ws->unacknowledged_pushes ); + ch->conf->ws->unacknowledged_pushes--; + + //printf( "puppet push for \"%s\" acked OK. Outstanding pushes %u\n", + // ch->name.c_str(), ch->conf->ws->unacknowledged_pushes ); } else { @@ -139,6 +136,8 @@ printf( "code: %d\n", req->response_code ); printf( "response: %s\n", req->input_buffer->buffer ); } + + delete ch; } int WebSim::Confederate::Push( std::string name, Pose p, Velocity v, Acceleration a ) @@ -148,12 +147,12 @@ name.c_str() ); // compose a struct to send into the callback - cb_chunk_t ch; - ch.name = name; - ch.conf = this; + cb_chunk_t* ch = new cb_chunk_t(); + ch->name = name; + ch->conf = this; struct evhttp_request* er = - evhttp_request_new( PuppetPushCallback, &ch ); + evhttp_request_new( PuppetPushCallback, ch ); assert(er); char buf[512]; @@ -166,7 +165,7 @@ v.x, v.y, v.z, v.r, v.p, v.a, a.x, a.y, a.z, a.r, a.p, a.a ); - printf( "Emitting: http://%s%s\n", this->name.c_str(), buf ); + // printf( "Emitting: http://%s%s\n", this->name.c_str(), buf ); ++ws->unacknowledged_pushes; // decremented when reply is received @@ -183,13 +182,19 @@ void WebSim::Confederate::TickReplyCb( evhttp_request* req, void* arg ) { + if( req == NULL ) + { + puts( "[websim] warning: broken connection waiting for tick reply." ); + return; + } + WebSim* ws = (WebSim*)arg; if( req->response_code == 200 ) { - --ws->unacknowledged_pushes; - printf( "tick acked OK. Outstanding pushes %u\n", - ws->unacknowledged_pushes ); + --ws->unacknowledged_ticks; + //printf( "tick ACK. Outstanding ticks %u\n", + // ws->unacknowledged_ticks ); } else { @@ -203,15 +208,15 @@ int WebSim::Confederate::Tick() { // construct and send a tick message - printf( "Confederate %s clock tick\n", - name.c_str() ); + //printf( "Confederate %s clock tick\n", + // name.c_str() ); - ++ws->unacknowledged_pushes; - struct evhttp_request* er = evhttp_request_new( TickReplyCb, ws ); assert(er); + ++ws->unacknowledged_ticks; // decremented when reply is received + int ret = evhttp_make_request( http_con, er, EVHTTP_REQ_GET, "/sim/clock/tick" ); if( ret != 0 ) { Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-03-13 00:46:58 UTC (rev 7468) +++ code/websim/src/parser.cc 2009-03-13 02:49:05 UTC (rev 7469) @@ -30,17 +30,14 @@ #include <string> #include <iostream> -// we#include <yaml.h> // YAML parser +#include "websim.hh" + using namespace std; - -#include "websim.hh" using namespace websim; -WebSim::Parser::Parser( WebSim* ws, std::string filename ) : - ws( ws ) -{ - +void WebSim::LoadFederationFile( std::string filename ) +{ GError* err = NULL; GKeyFile* keyfile = g_key_file_new(); g_key_file_load_from_file( keyfile, @@ -74,21 +71,21 @@ *fedkeyp, logicalname ); string hosturi = *fedkeyp; - Confederate* conf = new Confederate( ws, hosturi ); + Confederate* conf = new Confederate( this, hosturi ); assert(conf); // copy the hash table key so we can delete the original below - g_hash_table_insert( ws->confederates, strdup(logicalname), conf ); + g_hash_table_insert( confederates, strdup(logicalname), conf ); } - cout << "Looking up logical name for myself " << ws->hostportname << endl; + cout << "Looking up logical name for myself " << hostportname << endl; // now we have made all the confederates. // Let's look up the confederate for this instance // read the array of entries for this host gchar* mylogicalname = g_key_file_get_string( keyfile, "federation", - ws->hostportname.c_str(), + hostportname.c_str(), &err ); cout << "my logical name is " << mylogicalname << endl; @@ -123,7 +120,7 @@ *modelp ); else { - Puppet* pup = new Puppet( ws, *modelp ); + Puppet* pup = new Puppet( this, *modelp ); // for each puppet for( char** puppetp = puppets; @@ -139,18 +136,21 @@ std::string confstr = pupstr.substr( 0, pos ); std::string typestr = pupstr.substr( pos+1 ); - Confederate* conf = ws->GetConfederate( confstr ); - assert( conf ); - - pup->AddConfederate( conf, typestr ); + Confederate* conf = GetConfederate( confstr ); + if( conf == NULL ) + { + printf( "[websim] error: request to export %s/%s to unspecified server %s\n", + mylogicalname, *modelp, confstr.c_str() ); + } + else + { + pup->AddConfederate( conf, typestr ); + } } } } } - // XX - exit( 0 ); - // free the key array g_strfreev( fedkeys ); } Modified: code/websim/src/puppet.cc =================================================================== --- code/websim/src/puppet.cc 2009-03-13 00:46:58 UTC (rev 7468) +++ code/websim/src/puppet.cc 2009-03-13 02:49:05 UTC (rev 7469) @@ -35,7 +35,8 @@ WebSim::Puppet::Puppet( WebSim* ws, std::string name ) : ws( ws ), name( name ), - created( false ) + created( false ), + confederates( NULL ) { g_hash_table_insert( ws->puppets, (void*)this->name.c_str(), this ); printf( "Puppet \"%s\" constructed\n", this->name.c_str() ); Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-13 00:46:58 UTC (rev 7468) +++ code/websim/src/websim.cc 2009-03-13 02:49:05 UTC (rev 7469) @@ -40,6 +40,7 @@ WebSim::WebSim(const std::string& _fedfile, const std::string& _host, unsigned short _port) : + ticks_remaining(0), tick_count_expected(0), fedfile(_fedfile), host(_host), @@ -47,7 +48,9 @@ puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), logical_hosts( g_hash_table_new( g_str_hash, g_str_equal ) ), - unacknowledged_pushes(0) + unacknowledged_pushes(0), + unacknowledged_ticks(0), + total_ticks(0) { char buf[512]; @@ -76,7 +79,7 @@ if( fedfile != "" ) { printf( "[websim] Loading federation file %s\n", _fedfile.c_str() ); - Parser p( this, _fedfile.c_str() ); + LoadFederationFile( _fedfile.c_str() ); } puts("[websim] Ready"); @@ -96,11 +99,11 @@ if( confname != ws->hostportname ) // don't tick myself { - printf( "ticking conf %s\n", conf->name.c_str() ); + // printf( "ticking conf %s\n", conf->name.c_str() ); conf->Tick(); } - else - printf( "NOT ticking myself %s\n", conf->name.c_str() ); + //else + // printf( "NOT ticking myself %s\n", conf->name.c_str() ); } void @@ -108,16 +111,22 @@ { // tick all my confederates ForEachConfederate( Confederate::TickCb, this ); + + ticks_remaining = tick_count_expected; + do + { +// printf( "Update: ticks pending %d/%d ACKS( tick %u push %u)\n", +// ticks_remaining, tick_count_expected, +// unacknowledged_ticks, +// unacknowledged_pushes ); + + if(tick_count_expected || unacknowledged_pushes ) + event_loop(EVLOOP_ONCE); + else + event_loop(EVLOOP_NONBLOCK); + } while( ticks_remaining ); - tick_count = 0; - do - { - if(tick_count_expected || unacknowledged_pushes ) - event_loop(EVLOOP_ONCE); - else - event_loop(EVLOOP_NONBLOCK); - } while(tick_count < tick_count_expected); - tick_count = 0; + printf( "STEP %lu\n", total_ticks++ ); } void @@ -227,7 +236,7 @@ { if(action == "tick") { - tick_count++; + ticks_remaining--; response = "Ticked the clock"; return true; } Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-03-13 00:46:58 UTC (rev 7468) +++ code/websim/src/websim.hh 2009-03-13 02:49:05 UTC (rev 7469) @@ -52,92 +52,95 @@ class WebSim { - public: - WebSim(const std::string& _fedfile, - const std::string& _host, - unsigned short _port); - virtual ~WebSim(); +public: + WebSim(const std::string& _fedfile, + const std::string& _host, + unsigned short _port); - void Update(); - - // Interface to be implemented by simulators - virtual bool CreateModel(const std::string& name, - const std::string& type, - std::string& response) = 0; - virtual bool DeleteModel(const std::string& name, - std::string& response) = 0; - virtual bool SetModelPVA(const std::string& name, - const Pose& p, - const Velocity& v, - const Acceleration& a, - std::string& response) = 0; - virtual bool GetModelPVA(const std::string& name, - Pose& p, - Velocity& v, - Acceleration& a, - std::string& response) = 0; - + virtual ~WebSim(); + + void LoadFederationFile( std::string filename ); + + void Update(); + + // Interface to be implemented by simulators + virtual bool CreateModel(const std::string& name, + const std::string& type, + std::string& response) = 0; + virtual bool DeleteModel(const std::string& name, + std::string& response) = 0; + virtual bool SetModelPVA(const std::string& name, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& response) = 0; + virtual bool GetModelPVA(const std::string& name, + Pose& p, + Velocity& v, + Acceleration& a, + std::string& response) = 0; + bool SetPuppetPVA( const std::string& name, Pose& p, Velocity& v, Acceleration& a ); - - protected: - void StringSplit(const std::string &s, - std::vector<std::string> &t, - const std::string &d); - - + +protected: + void StringSplit(const std::string &s, + std::vector<std::string> &t, + const std::string &d); + + // Number of ticks we require before exiting Update() int tick_count_expected; - // Number of ticks we've received since the last Update() - int tick_count; + // Number of ticks remaining before we can quit update + int ticks_remaining; - private: - std::string fedfile; - std::string host; - std::string hostportname; // format "host:port" to uniquely identify this instance - unsigned short port; - - struct evhttp* eh; - - // Static, so that it can be passed as a callback to libevent - static void EventCallback(evhttp_request* req, void* arg); - - bool GetValue(std::string& value, - struct evkeyvalq* query_args, - const std::string& key); - 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, - std::string uri, - std::string& response); - void DeleteKeyVal(struct evkeyvalq* query_args); - - - // forward decare +private: + std::string fedfile; + std::string host; + std::string hostportname; // format "host:port" to uniquely identify this instance + unsigned short port; + + struct evhttp* eh; + + // Static, so that it can be passed as a callback to libevent + static void EventCallback(evhttp_request* req, void* arg); + + bool GetValue(std::string& value, + struct evkeyvalq* query_args, + const std::string& key); + 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, + std::string uri, + std::string& response); + void DeleteKeyVal(struct evkeyvalq* query_args); + + + // forward decare class Confederate; - + // manage an object we control on some federated simulators class Puppet { private: WebSim* ws; - + public: Puppet( WebSim* ws, std::string name ); @@ -159,7 +162,7 @@ void AddConfederate( Confederate* conf, std::string prototype ); }; - + // manage a federated simulator class Confederate { @@ -198,37 +201,12 @@ // list of pointers to Puppet objects that are hosted on this // connection - can iterate over these to update all puppets GList* puppet_list; - + // unique ID for this confederate in format "hostname:port", used as // hash table key std::string name; }; - class Parser - { - private: - //yaml_event_t event; - //yaml_parser_t parser; - WebSim* ws; - - // void parse_failed( std::string message ); -// void next_event( std::string msg ); -// void expect( yaml_event_type_t event_type, std::string msg ); -// void parse_puppet_mapping( Puppet* pup ); -// void parse_puppet_mapping_sequence( Puppet* pup ); -// void parse_model_mapping( std::string host ); -// void parse_model_mapping_sequence( std::string host ); -// void parse_host_mapping(); -// void parse_logical_host(); -// void parse_logical_host_sequence(); - - - // Confederate* GetConfederate( std::string name, std::string uri); - - public: - Parser( WebSim* ws, std::string filename ); - }; - private: // static const unsigned short DEFAULT_PORT; static const std::string package; @@ -241,6 +219,11 @@ // counts the number of status messages sent and replies not yet received unsigned int unacknowledged_pushes; + // counts the number of clock ticks sent and replies not yet received + unsigned int unacknowledged_ticks; + + unsigned long total_ticks; + /** Get a puppet by name */ Puppet* GetPuppet( std::string name ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-13 07:37:50
|
Revision: 7474 http://playerstage.svn.sourceforge.net/playerstage/?rev=7474&view=rev Author: rtv Date: 2009-03-13 07:37:13 +0000 (Fri, 13 Mar 2009) Log Message: ----------- working webstage demo Modified Paths: -------------- code/websim/examples/Makefile code/websim/examples/simple.cc code/websim/src/parser.cc Modified: code/websim/examples/Makefile =================================================================== --- code/websim/examples/Makefile 2009-03-13 07:36:29 UTC (rev 7473) +++ code/websim/examples/Makefile 2009-03-13 07:37:13 UTC (rev 7474) @@ -1,9 +1,9 @@ # set this to the directory that you installed websim -WSPREFIX=/Users/vaughan/Stage-3.0 +# WSPREFIX=/Users/vaughan/Stage-3.0 -WSLDFLAGS=-L${WSPREFIX}/lib -lwebsim `pkg-config --libs glib-2.0` -WSCFLAGS=-g -W -Wall -I${WSPREFIX}/include `pkg-config --cflags glib-2.0` +WSLDFLAGS=`pkg-config --libs websim` +WSCFLAGS=`pkg-config --cflags websim` all: clean websimple Modified: code/websim/examples/simple.cc =================================================================== --- code/websim/examples/simple.cc 2009-03-13 07:36:29 UTC (rev 7473) +++ code/websim/examples/simple.cc 2009-03-13 07:37:13 UTC (rev 7474) @@ -1,4 +1,4 @@ -#include "websim/websim.hh" +#include "websim.hh" class MinWebSim : public websim::WebSim { Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-03-13 07:36:29 UTC (rev 7473) +++ code/websim/src/parser.cc 2009-03-13 07:37:13 UTC (rev 7474) @@ -42,10 +42,15 @@ { GError* err = NULL; GKeyFile* keyfile = g_key_file_new(); - g_key_file_load_from_file( keyfile, - filename.c_str(), - G_KEY_FILE_NONE, - &err ); + if( ! g_key_file_load_from_file( keyfile, + filename.c_str(), + G_KEY_FILE_NONE, + &err ) ) + { + printf( "[websim] Can't find the federation file %s.\n", + filename.c_str() ); + exit( 0 ); + } if( ! g_key_file_has_group( keyfile, "federation" ) ) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-03-14 01:12:26
|
Revision: 7481 http://playerstage.svn.sourceforge.net/playerstage/?rev=7481&view=rev Author: rtv Date: 2009-03-14 01:12:23 +0000 (Sat, 14 Mar 2009) Log Message: ----------- much more functionality - currently fighting a race condition - do not use Modified Paths: -------------- code/websim/examples/world.fed code/websim/src/confederate.cc code/websim/src/parser.cc code/websim/src/websim.cc code/websim/src/websim.hh Modified: code/websim/examples/world.fed =================================================================== --- code/websim/examples/world.fed 2009-03-13 21:50:24 UTC (rev 7480) +++ code/websim/examples/world.fed 2009-03-14 01:12:23 UTC (rev 7481) @@ -6,9 +6,9 @@ deckard:8003=slave3 [master] -monkey=slave1:pioneer2dx;slave2:pioneer2dx;slave3:pioneer2dx -chunky=slave1:pioneer2dx;slave2:pioneer2dx;slave3:pioneer2dx -punky=slave1:pioneer2dx;slave2:pioneer2dx;slave3:pioneer2dx +monkey=slave1:pioneer2dx;slave2:pioneer2dx +chunky=slave1:pioneer2dx;slave2:pioneer2dx +punky=slave1:pioneer2dx;slave2:pioneer2dx Modified: code/websim/src/confederate.cc =================================================================== --- code/websim/src/confederate.cc 2009-03-13 21:50:24 UTC (rev 7480) +++ code/websim/src/confederate.cc 2009-03-14 01:12:23 UTC (rev 7481) @@ -33,6 +33,39 @@ #include "websim.hh" using namespace websim; +void greetingCb( evhttp_request* req, void* arg ) +{ + if( req == NULL ) + { + puts( "[websim] warning: broken connection waiting for greeting reply." ); + return; + } + + bool* created = (bool*)arg; + + printf( "cb created %p %d\n", created, *created ); + + switch( req->response_code ) + { + case 0: // host not available - we just retry + putchar('.'); fflush(stdout); + break; + case 200: // OK + (*created) = true; + break; + case 400: + printf( "[websim] server responds to greeting with error (400): %s.\n", + req->input_buffer->buffer ); + break; + default: + printf( "[websim] unknown greeting response code (%u): %s.\n", + req->response_code, + req->input_buffer->buffer ); + break; + } +} + + WebSim::Confederate::Confederate( WebSim* ws, std::string uri ) : ws(ws), @@ -62,8 +95,49 @@ printf( "\t\tConfederate %s constructed \n", name.c_str() ); - if( uri != ws->hostportname ) - ws->tick_count_expected++; + // greet the server - loop until reply is received + + bool created = false; + + struct timeval last; + last.tv_sec = 0; + last.tv_usec = 0; + + while( ! created ) + { + struct evhttp_request* er = + evhttp_request_new( greetingCb, &created ); + assert(er); + + struct timeval now; + gettimeofday( &now, NULL ); + + if( now.tv_sec > last.tv_sec ) + { + std::string buf = "/sim/greet/dummy"; + + printf( "emit created %p %u\n", &created, created ); + printf( "Emitting: http://%s/%s\n", name.c_str(), buf.c_str() ); + + int ret = evhttp_make_request( http_con, er, EVHTTP_REQ_GET, buf.c_str()); + if( ret != 0 ) + { + printf( "make request returned error %d\n", ret ); + exit(0); + } + + last.tv_sec = now.tv_sec; + } + + // loop until something happens or a short time passes + struct timeval tv; + tv.tv_sec=1; + tv.tv_usec=0; + event_loopexit( &tv ); + event_loop( EVLOOP_ONCE ); // loops until the request has completed + } + + ws->tick_count_expected++; } WebSim::Confederate::~Confederate() @@ -127,7 +201,8 @@ if( req->response_code == 200 ) { ch->conf->ws->unacknowledged_pushes--; - + ch->conf->ws->EscapeLoopIfDone(); + //printf( "puppet push for \"%s\" acked OK. Outstanding pushes %u\n", // ch->name.c_str(), ch->conf->ws->unacknowledged_pushes ); } @@ -143,9 +218,9 @@ int WebSim::Confederate::Push( std::string name, Pose p, Velocity v, Acceleration a ) { - printf( "\tconfederate %s pushing state of \"%s\"\n", - this->name.c_str(), - name.c_str() ); + //printf( "\tconfederate %s pushing state of \"%s\"\n", + // this->name.c_str(), + // name.c_str() ); // compose a struct to send into the callback cb_chunk_t* ch = new cb_chunk_t(); @@ -194,8 +269,10 @@ if( req->response_code == 200 ) { --ws->unacknowledged_ticks; - //printf( "tick ACK. Outstanding ticks %u\n", - // ws->unacknowledged_ticks ); + ws->EscapeLoopIfDone(); + + printf( "tick ACK. Outstanding ticks %u\n", + ws->unacknowledged_ticks ); } else { @@ -224,9 +301,6 @@ printf( "send tick returned error %d\n", ret ); exit(0); } - - - return 0; } Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-03-13 21:50:24 UTC (rev 7480) +++ code/websim/src/parser.cc 2009-03-14 01:12:23 UTC (rev 7481) @@ -78,11 +78,15 @@ *fedkeyp, logicalname ); string hosturi = *fedkeyp; - Confederate* conf = new Confederate( this, hosturi ); - assert(conf); - - // copy the hash table key so we can delete the original below - g_hash_table_insert( confederates, strdup(logicalname), conf ); + + if( hosturi != hostportname ) // don't conf with myself + { + Confederate* conf = new Confederate( this, hosturi ); + assert(conf); + + // copy the hash table key so we can delete the original below + g_hash_table_insert( confederates, strdup(logicalname), conf ); + } } cout << "Looking up logical name for myself " << hostportname << endl; Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-03-13 21:50:24 UTC (rev 7480) +++ code/websim/src/websim.cc 2009-03-14 01:12:23 UTC (rev 7481) @@ -37,12 +37,10 @@ const std::string WebSim::package = "WebSim"; const std::string WebSim::version = "0.1"; -WebSim::WebSim(const std::string& _fedfile, - const std::string& _host, - unsigned short _port) : +WebSim::WebSim( const std::string& _host, + const unsigned short _port) : tick_count_expected(0), ticks_remaining(0), - fedfile(_fedfile), host(_host), port(_port), puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), @@ -74,14 +72,6 @@ evhttp_set_gencb(eh, &WebSim::EventCallback, (void*)this); puts("Done."); - // if a federation file was specified, we parse it to populate the - // WebSim with confederates and puppets. - if( fedfile != "" ) - { - printf( "[websim] Loading federation file %s\n", _fedfile.c_str() ); - LoadFederationFile( _fedfile.c_str() ); - } - puts("[websim] Ready"); } @@ -93,40 +83,26 @@ void WebSim::Confederate::TickCb( std::string name, Confederate* conf, void* arg ) { - WebSim* ws = (WebSim*)arg; - - std::string confname = conf->name; - - if( confname != ws->hostportname ) // don't tick myself - { - // printf( "ticking conf %s\n", conf->name.c_str() ); - conf->Tick(); - } - //else - // printf( "NOT ticking myself %s\n", conf->name.c_str() ); + conf->Tick(); } -void -WebSim::Update() +void +WebSim::Go() { // tick all my confederates - ForEachConfederate( Confederate::TickCb, this ); - + ForEachConfederate( Confederate::TickCb, NULL ); +} + +void +WebSim::Wait() +{ ticks_remaining = tick_count_expected; - do - { -// printf( "Update: ticks pending %d/%d ACKS( tick %u push %u)\n", -// ticks_remaining, tick_count_expected, -// unacknowledged_ticks, -// unacknowledged_pushes ); - - if(tick_count_expected || unacknowledged_pushes ) - event_loop(EVLOOP_ONCE); - else - event_loop(EVLOOP_NONBLOCK); - } while( ticks_remaining ); - printf( "STEP %lu\n", total_ticks++ ); + // a callback will jump out of this loop when we've heard Ticks from + // all confederates + event_dispatch(); + + //printf( "STEP %lu\n", total_ticks++ ); } void @@ -194,6 +170,18 @@ } } +void WebSim::EscapeLoopIfDone() +{ + // if we're done waiting for things we can bail out of the event loop + + printf( "testing %d %d %d\n", ticks_remaining, unacknowledged_pushes, unacknowledged_ticks ); + if( ! (ticks_remaining || unacknowledged_pushes || unacknowledged_ticks) ) + { + puts( "OUTTA HERE" ); + event_loopbreak(); + } +} + bool WebSim::HandleSimRequest(const std::string& prop, const std::string& action, @@ -202,55 +190,64 @@ { // 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: Missing name and/or type argument for sim/factor/create"; - return false; - } - - return(CreateModel(name, type, response)); - } - else if(action == "create") - { - std::string name, type; - if(!GetValue(name, kv, "name")) - { - response = "ERROR: Missing name argument for sim/factor/create"; - return false; - } - - return(DeleteModel(name, response)); - } - else - { - response = "ERROR: Unknown action " + action + " for sim/factory"; - return false; - } - } + { + 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; + } + + return(CreateModel(name, type, response)); + } + else if(action == "create") + { + std::string name, type; + if(!GetValue(name, kv, "name")) + { + response = "ERROR: Missing name argument for sim/factor/create"; + return false; + } + + return(DeleteModel(name, response)); + } + else + { + response = "ERROR: Unknown action " + action + " for sim/factory"; + return false; + } + } else if(prop == "clock") - { - if(action == "tick") - { - ticks_remaining--; - response = "Ticked the clock"; - return true; - } - else - { - response = "ERROR: Unknown action " + action + " for sim/clock"; - return false; - } - } + { + if(action == "tick") + { + ticks_remaining--; + response = "Ticked the clock"; + + EscapeLoopIfDone(); + return true; + } + else + { + response = "ERROR: Unknown action " + action + " for sim/clock"; + return false; + } + } + else if(prop == "greet") // action is the name of the greeting server + { + // TODO - check to see if this server was anticipated + response = "Greetings " + action; + printf( "[websim] WebSim peer %s connected\n", action.c_str() ); + return true; + } else - { - response = "ERROR: Unknown property " + prop + " for sim"; - return false; - } + { + response = "ERROR: Unknown property " + prop + " for sim"; + return false; + } } bool @@ -424,7 +421,9 @@ // We require 3 path components: model/property/action StringSplit(bare_uri, uri_parts, "/"); - // There should be 4 parts, with the first one empty + + + // otherwise there should be 4 parts, with the first one empty if(uri_parts.size() != 4) { response = "Must be 3 slash-separated parts in the URI"; Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-03-13 21:50:24 UTC (rev 7480) +++ code/websim/src/websim.hh 2009-03-14 01:12:23 UTC (rev 7481) @@ -53,15 +53,18 @@ class WebSim { public: - WebSim(const std::string& _fedfile, - const std::string& _host, - unsigned short _port); + WebSim( const std::string& _host, + const unsigned short _port); virtual ~WebSim(); void LoadFederationFile( std::string filename ); - void Update(); + /** Wait for go signals from all confederates */ + void Wait(); + + /** Send go signals to all confederates */ + void Go(); // Interface to be implemented by simulators virtual bool CreateModel(const std::string& name, @@ -90,14 +93,15 @@ std::vector<std::string> &t, const std::string &d); - + void EscapeLoopIfDone(); + + // Number of ticks we require before exiting Update() int tick_count_expected; // Number of ticks remaining before we can quit update int ticks_remaining; -private: - std::string fedfile; +protected: std::string host; std::string hostportname; // format "host:port" to uniquely identify this instance unsigned short port; @@ -224,6 +228,7 @@ unsigned long total_ticks; +public: /** Get a puppet by name */ Puppet* GetPuppet( std::string name ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <as...@us...> - 2009-05-22 21:57:32
|
Revision: 7710 http://playerstage.svn.sourceforge.net/playerstage/?rev=7710&view=rev Author: asadat Date: 2009-05-22 21:57:22 +0000 (Fri, 22 May 2009) Log Message: ----------- Laser and sonar messages is added to the websim interface. Also, the response can be in XML format. Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/websim.cc code/websim/src/websim.hh Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-05-22 17:23:31 UTC (rev 7709) +++ code/websim/CMakeLists.txt 2009-05-22 21:57:22 UTC (rev 7710) @@ -39,9 +39,19 @@ MESSAGE( ${INDENT} "Glib not detected" ) ENDIF( GLIB_FOUND ) -include_directories( ${GLIB_INCLUDE_DIRS} ) -link_directories(${GLIB_LIBRARY_DIRS} ) +pkg_search_module( LIBXML2 REQUIRED libxml-2.0) +IF( LIBXML2_FOUND ) + MESSAGE( STATUS ${INDENT} "libxml version ${LIBXML2_VERSION} detected at ${LIBXML2_PREFIX}" ) +ELSE( LIBXML2_FOUND ) + MESSAGE( ${INDENT} "libxml2 not detected" ) +ENDIF( LIBXML2_FOUND ) +include_directories( ${GLIB_INCLUDE_DIRS} + ${LIBXML2_INCLUDE_DIRS} ) +link_directories(${GLIB_LIBRARY_DIRS} + ${LIBXML2_LIBRARY_DIRS} ) + + include_directories(src) add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) @@ -50,8 +60,9 @@ # Prevent deletion of existing lib of same name set_target_properties(websim-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) -target_link_libraries(websim event ${GLIB_LIBRARIES} ) +target_link_libraries(websim event ${GLIB_LIBRARIES} ${LIBXML2_LIBRARIES}) + install(TARGETS websim websim-static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-05-22 17:23:31 UTC (rev 7709) +++ code/websim/src/websim.cc 2009-05-22 21:57:22 UTC (rev 7710) @@ -31,12 +31,19 @@ #include <assert.h> #include <stdlib.h> +#include <string.h> +#include <libxml/encoding.h> +#include <libxml/xmlwriter.h> +#define MY_ENCODING "ISO-8859-1" + using namespace websim; const std::string WebSim::package = "WebSim"; const std::string WebSim::version = "0.1"; +xmlChar * +ConvertInput(const char *in, const char *encoding); std::string Time::String() { @@ -272,17 +279,8 @@ Time t; if(GetModelPVA(model, t, p, v, a, response)) { - char buf[1024]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" - " vel : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" - " acc : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", - model.c_str(), - t.String().c_str(), - p.x, p.y, p.z, p.r, p.p, p.a, - v.x, v.y, v.z, v.r, v.p, v.a, - a.x, a.y, a.z, a.r, a.p, a.a); - response = buf; + GetTextPVA(model, t, p, v, a, response); + return true; } else @@ -290,6 +288,79 @@ response = "ERROR: Failed to get pose for model " + model; return false; } + }else if(prop == "laser"){ + Time t; + uint32_t res; + double fov; + Pose p; + std::vector<double> ranges; + if(GetLaserData(model, t, res, fov, p,ranges, response)) + { + GetTextLaserData(model, t, res, fov, p, ranges, response); + return true; + + } + else + { + response = "ERROR: Failed to get laser data for model " + model; + return false; + } + + }else if(prop=="lasercfg"){ + + Time t; + uint32_t res; + double fov; + Pose p; + + if(GetLaserCfgData(model, t, res, fov, p, response)) + { + + GetTextLaserCfgData(model, t, res, fov, p, response); + return true; + + } + else + { + response = "ERROR: Failed to get laser cfg data for model " + model; + return false; + } + + }else if(prop=="ranger"){ + + Time t; + std::vector<double> ranges; + + if(GetRangerData(model, t, ranges, response)) + { + + GetTextRangerData(model, t, ranges, response); + return true; + + } + else + { + response = "ERROR: Failed to get ranger data for model " + model; + return false; + } + + }else if(prop=="rangercfg"){ + + Time t; + std::vector<Pose> p; + + if(GetRangerCfgData(model, t, p, response)) + { + + GetTextRangerCfgData(model, t, p, response); + return true; + + } + else + { + response = "ERROR: Failed to get ranger Cfg data for model " + model; + return false; + } } else { @@ -376,7 +447,459 @@ } } + + + +void +WebSim::GetTextPVA(const std::string& name, + Time& t, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& response) +{ + + char buf[1024]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" + " vel : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" + " acc : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", + name.c_str(), + t.String().c_str(), + p.x, p.y, p.z, p.r, p.p, p.a, + v.x, v.y, v.z, v.r, v.p, v.a, + a.x, a.y, a.z, a.r, a.p, a.a); + response = buf; + +} + + +void +WebSim::GetXMLPVA(const std::string& name, + Time& t, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& response) +{ + + xmlTextWriterPtr writer; + xmlBufferPtr buf; + xmlChar *tmp; + char str[32]; + + buf = xmlBufferCreate(); + writer = xmlNewTextWriterMemory(buf, 0); + + + xmlTextWriterStartElement(writer, BAD_CAST "Data"); + + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Time", BAD_CAST tmp); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Type", BAD_CAST "pva"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Model", BAD_CAST tmp); + + xmlTextWriterStartElement(writer, BAD_CAST "Pose"); + + sprintf(str,"%.3f",p.x); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "x", BAD_CAST tmp); + + sprintf(str,"%.3f",p.y); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "y", BAD_CAST tmp); + + sprintf(str,"%.3f",p.z); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "z", BAD_CAST tmp); + + sprintf(str,"%.3f",p.r); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "r", BAD_CAST tmp); + + sprintf(str,"%.3f",p.p); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "p", BAD_CAST tmp); + + sprintf(str,"%.3f",p.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "a", BAD_CAST tmp); + + xmlTextWriterEndElement(writer); + + + + xmlTextWriterStartElement(writer, BAD_CAST "Velocity"); + + sprintf(str,"%.3f",v.x); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "x", BAD_CAST tmp); + + sprintf(str,"%.3f",v.y); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "y", BAD_CAST tmp); + + sprintf(str,"%.3f",v.z); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "z", BAD_CAST tmp); + + sprintf(str,"%.3f",v.r); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "r", BAD_CAST tmp); + + sprintf(str,"%.3f",v.p); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "p", BAD_CAST tmp); + + sprintf(str,"%.3f",v.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "a", BAD_CAST tmp); + + xmlTextWriterEndElement(writer); + + + + + xmlTextWriterStartElement(writer, BAD_CAST "Acceleration"); + + sprintf(str,"%.3f",a.x); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "x", BAD_CAST tmp); + + sprintf(str,"%.3f",a.y); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "y", BAD_CAST tmp); + + sprintf(str,"%.3f",a.z); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "z", BAD_CAST tmp); + + sprintf(str,"%.3f",a.r); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "r", BAD_CAST tmp); + + sprintf(str,"%.3f",a.p); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "p", BAD_CAST tmp); + + sprintf(str,"%.3f",a.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "a", BAD_CAST tmp); + + xmlTextWriterEndElement(writer); + + xmlTextWriterEndElement(writer); + + xmlTextWriterEndDocument(writer); + xmlFreeTextWriter(writer); + + + puts((const char*) buf->content); + + response = (const char*) buf->content; + + xmlBufferFree(buf); + + + +} + void +WebSim::GetTextLaserData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::vector<double>& ranges, + std::string& response) +{ + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + + char buf[2048]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n laser: (%s)\n resolution: (%d)\n fov(%.2f)\n" + " pose (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", + name.c_str(), + t.String().c_str(), + res.c_str(), + resolution, + fov, + p.x,p.y,p.z,p.r,p.p,p.a); + response = buf; +} + +void +WebSim::GetXMLLaserData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::vector<double>& ranges, + std::string& response) +{ + + + xmlTextWriterPtr writer; + xmlBufferPtr buf; + xmlChar *tmp; + char str[32]; + + + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + + buf = xmlBufferCreate(); + writer = xmlNewTextWriterMemory(buf, 0); + + + xmlTextWriterStartElement(writer, BAD_CAST "Data"); + + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Time", BAD_CAST tmp); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Type", BAD_CAST "laser"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Model", BAD_CAST tmp); + + xmlTextWriterStartElement(writer, BAD_CAST "Laser"); + + sprintf(str,"%d",resolution); + tmp = ConvertInput(str,MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Resolution", BAD_CAST tmp); + + sprintf(str,"%.3f",fov); + tmp = ConvertInput(str,MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "FOV", BAD_CAST tmp); + + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, 0.f, 0.f, 0.f, p.a); + tmp = ConvertInput(str,MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Pose", BAD_CAST tmp); + + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Samples", BAD_CAST tmp); + + + xmlTextWriterEndElement(writer); + + xmlTextWriterEndElement(writer); + + xmlTextWriterEndDocument(writer); + xmlFreeTextWriter(writer); + + + puts((const char*) buf->content); + + response = (const char*) buf->content; + + xmlBufferFree(buf); + +} +void +WebSim::GetTextLaserCfgData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::string& response) +{ + char buf[2048]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n resolution(%d)\n fov(%.2f)\n" + " pose (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", + name.c_str(), + t.String().c_str(), + resolution, + fov, + p.x,p.y,p.z,p.r,p.p,p.a); + response = buf; +} +void +WebSim::GetTextRangerData(const std::string& name, + Time& t, + std::vector<double>& ranges, std::string& response) +{ + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + + char buf[2048]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n ranger: (%s)\n", + name.c_str(), + t.String().c_str(), + res.c_str()); + response = buf; +} + +void +WebSim::GetXMLRangerData(const std::string& name, + Time& t, + std::vector<double>& ranges, std::string& response) +{ + + xmlTextWriterPtr writer; + xmlBufferPtr buf; + xmlChar *tmp; + char str[32]; + + + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + + buf = xmlBufferCreate(); + writer = xmlNewTextWriterMemory(buf, 0); + + + xmlTextWriterStartElement(writer, BAD_CAST "Data"); + + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Time", BAD_CAST tmp); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Type", BAD_CAST "ranger"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "Model", BAD_CAST tmp); + + xmlTextWriterStartElement(writer, BAD_CAST "Ranger"); + + + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlTextWriterWriteAttribute(writer, BAD_CAST "samples", BAD_CAST tmp); + + + xmlTextWriterEndElement(writer); + + xmlTextWriterEndElement(writer); + + xmlTextWriterEndDocument(writer); + xmlFreeTextWriter(writer); + + + puts((const char*) buf->content); + + response = (const char*) buf->content; + + xmlBufferFree(buf); + + +} + + +void +WebSim::GetTextRangerCfgData(const std::string& name, + Time& t, + std::vector<Pose>& p, + std::string& response) +{ + + std::string res; + char temp[256]; + for(unsigned int i=0;i<p.size();i++){ + Pose pos = p.at(i); + sprintf(temp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", + pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); + res.append(temp); + + } + + + char buf[2048]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n rangerCfg:Pose (%s)\n", + name.c_str(), + t.String().c_str(), + res.c_str()); + response = buf; + + + +} + +xmlChar * +ConvertInput(const char *in, const char *encoding) +{ + xmlChar *out; + int ret; + int size; + int out_size; + int temp; + xmlCharEncodingHandlerPtr handler; + + if (in == 0) + return 0; + + handler = xmlFindCharEncodingHandler(encoding); + + if (!handler) { + printf("ConvertInput: no encoding handler found for '%s'\n", + encoding ? encoding : ""); + return 0; + } + + size = (int) strlen(in) + 1; + out_size = size * 2 - 1; + out = (unsigned char *) xmlMalloc((size_t) out_size); + + if (out != 0) { + temp = size - 1; + ret = handler->input(out, &out_size, (const xmlChar *) in, &temp); + if ((ret < 0) || (temp - size + 1)) { + if (ret < 0) { + printf("ConvertInput: conversion wasn't successful.\n"); + } else { + printf + ("ConvertInput: conversion wasn't successful. converted: %i octets.\n", + temp); + } + + xmlFree(out); + out = 0; + } else { + out = (unsigned char *) xmlRealloc(out, out_size + 1); + out[out_size] = 0; + } + } else { + printf("ConvertInput: no mem\n"); + } + + return out; +} + + + +void WebSim::EventCallback(evhttp_request* req, void* arg) { WebSim* obj = (WebSim*)arg; Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-05-22 17:23:31 UTC (rev 7709) +++ code/websim/src/websim.hh 2009-05-22 21:57:22 UTC (rev 7710) @@ -82,6 +82,86 @@ Acceleration& a, std::string& response) = 0; + void GetTextPVA(const std::string& name, + Time& t, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& response); + + void GetXMLPVA(const std::string& name, + Time& t, + const Pose& p, + const Velocity& v, + const Acceleration& a, + std::string& response); + virtual bool GetLaserData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::vector<double>& ranges, + std::string& response) = 0; + + void GetTextLaserData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + + std::vector<double>& ranges, + std::string& response); + + + void GetXMLLaserData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::vector<double>& ranges, + std::string& response); + + virtual bool GetLaserCfgData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::string& response) = 0; + + void GetTextLaserCfgData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::string& response); + + virtual bool GetRangerData(const std::string& name, + Time& t, + std::vector<double>& ranges, + std::string& response) = 0; + + + void GetTextRangerData(const std::string& name, + Time& t, + std::vector<double>& ranges, + std::string& response); + + + void GetXMLRangerData(const std::string& name, + Time& t, + std::vector<double>& ranges, + std::string& response); + + virtual bool GetRangerCfgData(const std::string& name, + Time& t, + std::vector<Pose>& p, + std::string& response) = 0; + + void GetTextRangerCfgData(const std::string& name, + Time& t, + std::vector<Pose>& p, + std::string& response); + /** Get the current simulation time */ virtual Time GetTime() = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-05-23 01:28:18
|
Revision: 7711 http://playerstage.svn.sourceforge.net/playerstage/?rev=7711&view=rev Author: rtv Date: 2009-05-23 00:19:58 +0000 (Sat, 23 May 2009) Log Message: ----------- moved to more STL containers Modified Paths: -------------- code/websim/examples/world.fed code/websim/src/confederate.cc code/websim/src/parser.cc code/websim/src/puppet.cc code/websim/src/websim.cc code/websim/src/websim.hh Modified: code/websim/examples/world.fed =================================================================== --- code/websim/examples/world.fed 2009-05-22 21:57:22 UTC (rev 7710) +++ code/websim/examples/world.fed 2009-05-23 00:19:58 UTC (rev 7711) @@ -2,13 +2,16 @@ [federation] deckard:8000=master deckard:8001=slave1 -deckard:8002=slave2 -deckard:8003=slave3 +#deckard:8002=slave2 +#deckard:8003=slave3 [master] -monkey=slave1:pioneer2dx;slave2:pioneer2dx -chunky=slave1:pioneer2dx;slave2:pioneer2dx -punky=slave1:pioneer2dx;slave2:pioneer2dx +#monkey=slave1:pioneer2dx;slave2:pioneer2dx +#chunky=slave1:pioneer2dx;slave2:pioneer2dx +#punky=slave1:pioneer2dx;slave2:pioneer2dx +monkey=slave1:pioneer2dx +chunky=slave1:pioneer2dx +punky=slave1:pioneer2dx Modified: code/websim/src/confederate.cc =================================================================== --- code/websim/src/confederate.cc 2009-05-22 21:57:22 UTC (rev 7710) +++ code/websim/src/confederate.cc 2009-05-23 00:19:58 UTC (rev 7711) @@ -189,8 +189,7 @@ while( ! puppet->created ) event_loop( EVLOOP_ONCE ); // loops until the request has completed - puppet_list = - g_list_append( puppet_list, puppet ); + puppet_list.push_back( puppet ); } void WebSim::Confederate::PuppetPushCallback( evhttp_request* req, void* arg ) Modified: code/websim/src/parser.cc =================================================================== --- code/websim/src/parser.cc 2009-05-22 21:57:22 UTC (rev 7710) +++ code/websim/src/parser.cc 2009-05-23 00:19:58 UTC (rev 7711) @@ -85,7 +85,8 @@ assert(conf); // copy the hash table key so we can delete the original below - g_hash_table_insert( confederates, strdup(logicalname), conf ); + //g_hash_table_insert( confederates, strdup(logicalname), conf ); + confederates[ logicalname ] = conf; } } Modified: code/websim/src/puppet.cc =================================================================== --- code/websim/src/puppet.cc 2009-05-22 21:57:22 UTC (rev 7710) +++ code/websim/src/puppet.cc 2009-05-23 00:19:58 UTC (rev 7711) @@ -38,18 +38,23 @@ created( false ), confederates( NULL ) { - g_hash_table_insert( ws->puppets, (void*)this->name.c_str(), this ); + ws->puppets[name] = this; printf( "Puppet \"%s\" constructed\n", this->name.c_str() ); } +WebSim::Puppet::~Puppet() +{ + ws->puppets.erase( name ); +} + void WebSim::Puppet::Push( Pose p, Velocity v, Acceleration a ) { - for( GList* it = confederates; - it; - it = it->next ) + for( std::list<Confederate*>::iterator it = confederates.begin(); + it != confederates.end(); + ++it ) { - Confederate* conf = (Confederate*)it->data; - conf->Push( name, p, v, a ); + // Confederate* conf = (Confederate*)it->data; + (*it)->Push( name, p, v, a ); } } @@ -57,7 +62,8 @@ const std::string& prototype ) { conf->AddPuppet( this, prototype ); - confederates = g_list_append( confederates, conf ); + //confederates = g_list_append( confederates, conf ); + confederates.push_back( conf ); } Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-05-22 21:57:22 UTC (rev 7710) +++ code/websim/src/websim.cc 2009-05-23 00:19:58 UTC (rev 7711) @@ -58,9 +58,11 @@ ticks_remaining(0), host(_host), port(_port), - puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), - confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), - logical_hosts( g_hash_table_new( g_str_hash, g_str_equal ) ), + //puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), + //confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), + //logical_hosts( g_hash_table_new( g_str_hash, g_str_equal ) ), + puppets(), + confederates(), unacknowledged_pushes(0), unacknowledged_ticks(0), total_ticks(0) @@ -105,7 +107,12 @@ WebSim::Go() { // tick all my confederates - ForEachConfederate( Confederate::TickCb, NULL ); + //ForEachConfederate( Confederate::TickCb, NULL ); + + for( std::map<std::string,Confederate*>::iterator it = confederates.begin(); + it != confederates.end(); + it++ ) + it->second->Tick(); } void @@ -987,26 +994,28 @@ return false; } -void WebSim::ForEachConfederate( void(*cb)(const std::string&, WebSim::Confederate*, void*), void* arg ) -{ - g_hash_table_foreach( WebSim::confederates, - (GHFunc)cb, - arg ); -} +// void WebSim::ForEachConfederate( void(*cb)(const std::string&, WebSim::Confederate*, void*), void* arg ) +// { +// g_hash_table_foreach( WebSim::confederates, +// (GHFunc)cb, +// arg ); +// } -void WebSim::ForEachPuppet( void(*cb)(const std::string&, WebSim::Puppet*, void*), void* arg ) -{ - g_hash_table_foreach( WebSim::puppets, - (GHFunc)cb, - arg ); -} +// void WebSim::ForEachPuppet( void(*cb)(const std::string&, WebSim::Puppet*, void*), void* arg ) +// { +// g_hash_table_foreach( WebSim::puppets, +// (GHFunc)cb, +// arg ); +// } WebSim::Puppet* WebSim::GetPuppet( const std::string& name ) { - return( (Puppet*)g_hash_table_lookup( WebSim::puppets, name.c_str() ) ); + //return( (Puppet*)g_hash_table_lookup( WebSim::puppets, name.c_str() ) ); + return puppets[name]; } WebSim::Confederate* WebSim::GetConfederate( const std::string& name ) { - return( (Confederate*)g_hash_table_lookup( WebSim::confederates, name.c_str() ) ); + //return( (Confederate*)g_hash_table_lookup( WebSim::confederates, name.c_str() ) ); + return confederates[name]; } Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-05-22 21:57:22 UTC (rev 7710) +++ code/websim/src/websim.hh 2009-05-23 00:19:58 UTC (rev 7711) @@ -28,6 +28,7 @@ #include <string> #include <vector> #include <map> +#include <list> // These headers must be included prior to the libevent headers #include <sys/types.h> @@ -225,7 +226,8 @@ public: Puppet( WebSim* ws, const std::string& name ); - + ~Puppet(); + // unique ID used as a system-wide handle for this puppet, used as // hash table key std::string name; @@ -233,8 +235,9 @@ bool created; // the remote servers that are hosting an instance of this puppet - GList* confederates; - + //GList* confederates; + std::list<Confederate*> confederates; + // sends the current physical state of the puppet to all // confederates void Push( Pose p, Velocity v, Acceleration a ); @@ -275,22 +278,22 @@ // list of pointers to Puppet objects that are hosted on this // connection - can iterate over these to update all puppets - GList* puppet_list; - + //GList* puppet_list; + std::list<Puppet*> puppet_list; + // unique ID for this confederate in format "hostname:port", used as // hash table key std::string name; }; - private: - // static const unsigned short DEFAULT_PORT; + protected: +// static const unsigned short DEFAULT_PORT; static const std::string package; static const std::string version; - - GHashTable* puppets; - GHashTable* confederates; - GHashTable* logical_hosts; + std::map<std::string,Puppet*> puppets; + std::map<std::string,Confederate*> confederates; + // counts the number of status messages sent and replies not yet received int unacknowledged_pushes; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rt...@us...> - 2009-06-24 22:54:54
|
Revision: 7893 http://playerstage.svn.sourceforge.net/playerstage/?rev=7893&view=rev Author: rtv Date: 2009-06-24 22:54:43 +0000 (Wed, 24 Jun 2009) Log Message: ----------- reverted to 3-part URI scheme. added some identification API Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/websim.cc code/websim/src/websim.hh Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-06-24 22:54:06 UTC (rev 7892) +++ code/websim/CMakeLists.txt 2009-06-24 22:54:43 UTC (rev 7893) @@ -20,7 +20,7 @@ INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/${_name}.pc DESTINATION lib/pkgconfig/ COMPONENT pkgconfig) ENDMACRO (WEBSIM_MAKE_PKGCONFIG) -WEBSIM_MAKE_PKGCONFIG("websim" "Websim library" "glib-2.0" "" "" "") +WEBSIM_MAKE_PKGCONFIG("websim" "Websim library" "glib-2.0 libxml-2.0" "" "" "") add_definitions(-g -Wall) cmake_minimum_required( VERSION 2.4 FATAL_ERROR ) @@ -28,6 +28,8 @@ cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) +# TODO: test for libevent and boost + include(FindPkgConfig) pkg_search_module( GLIB REQUIRED glib-2.0 ) @@ -46,6 +48,8 @@ MESSAGE( ${INDENT} "libxml2 not detected" ) ENDIF( LIBXML2_FOUND ) + + include_directories( ${GLIB_INCLUDE_DIRS} ${LIBXML2_INCLUDE_DIRS} ) link_directories(${GLIB_LIBRARY_DIRS} Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-06-24 22:54:06 UTC (rev 7892) +++ code/websim/src/websim.cc 2009-06-24 22:54:43 UTC (rev 7893) @@ -19,8 +19,8 @@ * */ -/* Desc: HTTP portal to libgazebo - * Author: Brian Gerkey +/* Desc: WebSim http server for robot interactiony + * Author: Brian Gerkey, Richard Vaughan, Abbas * Date: 9 March 2009 * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ */ @@ -59,9 +59,6 @@ ticks_remaining(0), host(_host), port(_port), - //puppets( g_hash_table_new( g_str_hash, g_str_equal ) ), - //confederates( g_hash_table_new( g_str_hash, g_str_equal ) ), - //logical_hosts( g_hash_table_new( g_str_hash, g_str_equal ) ), puppets(), confederates(), unacknowledged_pushes(0), @@ -69,36 +66,51 @@ total_ticks(0) { - char buf[512]; - snprintf( buf, 512, "%s:%u", host.c_str(), port ); - hostportname = buf; +} - printf( "[websim] %s %s ID \"%s\"\n", - package.c_str(), - version.c_str(), - hostportname.c_str() ); +WebSim::~WebSim() +{ + // No event_fini() to call... +} + +void WebSim::Startup( bool verbose ) +{ + if( verbose ) + { + char buf[512]; + snprintf( buf, 512, "%s:%u", host.c_str(), port ); + hostportname = buf; + + printf( "[%s] %s %s hosting %s %s at http://%s\n", + package.c_str(), + package.c_str(), + version.c_str(), + IdentificationString().c_str(), // implemented by the simulator + VersionString().c_str(), + hostportname.c_str() ); + } + // Set up the HTTP server // Not sure whether it's safe to do this more that once in one process event_init(); + + if( verbose ) + { + printf("[%s] Starting HTTP server...", package.c_str() ); + fflush(stdout); + } - printf("[websim] Starting HTTP server listening on %s:%d...", - this->host.c_str(), this->port); - fflush(stdout); this->eh = evhttp_start(this->host.c_str(), this->port); assert(eh); evhttp_set_gencb(eh, &WebSim::EventCallback, (void*)this); - puts("Done."); - puts("[websim] Ready"); + if( verbose ) + { + puts( " done." ); + } } - -WebSim::~WebSim() -{ - // No event_fini() to call... -} - void WebSim::Confederate::TickCb( const std::string& name, Confederate* conf, void* arg ) { conf->Tick(); @@ -111,27 +123,27 @@ //ForEachConfederate( Confederate::TickCb, NULL ); for( std::map<std::string,Confederate*>::iterator it = confederates.begin(); - it != confederates.end(); - it++ ) - it->second->Tick(); + it != confederates.end(); + it++ ) + it->second->Tick(); } void WebSim::Wait() { if( tick_count_expected ) // if we're federated with anyone - { - ticks_remaining = tick_count_expected; + { + ticks_remaining = tick_count_expected; - while( unacknowledged_ticks || unacknowledged_pushes || ticks_remaining ) - { - //printf( "event loop in wait (%d %d %d)\n", - // unacknowledged_ticks, unacknowledged_pushes, ticks_remaining ); - event_loop( EVLOOP_ONCE ); - } - } + while( unacknowledged_ticks || unacknowledged_pushes || ticks_remaining ) + { + //printf( "event loop in wait (%d %d %d)\n", + // unacknowledged_ticks, unacknowledged_pushes, ticks_remaining ); + event_loop( EVLOOP_ONCE ); + } + } else // not federated - just an isolated server - event_loop( EVLOOP_NONBLOCK ); + event_loop( EVLOOP_NONBLOCK ); } void @@ -142,10 +154,10 @@ t.clear(); size_t start = 0, end; while ((end = s.find_first_of(d, start)) != std::string::npos) - { - t.push_back(s.substr(start, end-start)); - start = end + 1; - } + { + t.push_back(s.substr(start, end-start)); + start = end + 1; + } t.push_back(s.substr(start)); } @@ -156,27 +168,27 @@ { struct evkeyval* kv; TAILQ_FOREACH(kv, query_args, next) - { - free(kv->key); - free(kv->value); - TAILQ_REMOVE(query_args, kv, next); - } + { + free(kv->key); + free(kv->value); + TAILQ_REMOVE(query_args, kv, next); + } } bool WebSim::GetValue( std::string& value, - struct evkeyvalq* query_args, - const std::string& key) + struct evkeyvalq* query_args, + const std::string& key) { struct evkeyval* kv; TAILQ_FOREACH(kv, query_args, next) - { - if(key == kv->key) { - value = std::string(kv->value); - return true; + if(key == kv->key) + { + value = std::string(kv->value); + return true; + } } - } return false; } @@ -193,314 +205,322 @@ // specify the format of the response: Text or Xml if(GetValue(f, kv, "format")){ - if(f == "xml") - format = XML; - else - format = TEXT; + if(f == "xml") + format = XML; + else + format = TEXT; }else - format = TEXT; + format = TEXT; // The special simulation model if(model == "sim") - { - return HandleSimRequest(prop, action, format, kv, response); - }else if(model == "viz"){ - if(prop ==""){ - puts("viz request"); - //response = "<html><header></header><body><img src=\"viz/1.png\" ></body></html>"; - - response = "<HTML><HEAD><TITLE>A Simple Program</TITLE></HEAD>"; - response += "<BODY> <CENTER><APPLET CODE=\"ScrollingSimple.class\" WIDTH=\"1500\" HEIGHT=\"1000\" id=\"TheApplet\"></APPLET></CENTER>"; - response += "<b>The returned data is:</b><br /><script type=\"text/javascript\"> document.write(TheApplet.getResponseText());</script></BODY></HTML>"; - }else{ + { + return HandleSimRequest(prop, action, format, kv, response); + } + else if(model == "viz") + { + if(prop ==""){ + puts("viz request"); + //response = "<html><header></header><body><img src=\"viz/1.png\" ></body></html>"; - puts("SendingFile:"); - puts(prop.c_str()); - - + response = "<HTML><HEAD><TITLE>A Simple Program</TITLE></HEAD>"; + response += "<BODY> <CENTER><APPLET CODE=\"ScrollingSimple.class\" WIDTH=\"1500\" HEIGHT=\"1000\" id=\"TheApplet\"></APPLET></CENTER>"; + response += "<b>The returned data is:</b><br /><script type=\"text/javascript\"> document.write(TheApplet.getResponseText());</script></BODY></HTML>"; + } + else + { + puts("SendingFile:"); + puts(prop.c_str()); } - return true; - - }else if(model == ""){ - - std::vector<std::string> links; - char tmp[2048]; - sprintf(tmp,"%s %s", WebSim::package.c_str(), WebSim::version.c_str()); - response = "<html><head ><title>WebSim</title></head><body><h3>"; - response.append(tmp); + return true; + + }else if(model == ""){ + + std::vector<std::string> links; + char tmp[2048]; + sprintf(tmp,"%s %s", WebSim::package.c_str(), WebSim::version.c_str()); + response = "<html><head ><title>WebSim</title></head><body><h3>"; + response.append(tmp); - response.append( "</h3><p>Welcome to WebSim, a web based interface to robot simulation. Through this program, you can get the state of the robots and their sensors using URIs. Here are some examples that might be useful: "); + response.append( "</h3><p>Welcome to WebSim, an HTTP interface to robot simulation. Through this program, you can get the state of the robots and their sensors using URIs. Here are some examples: "); - sprintf(tmp,"</p><p><a href=\"http://%s/sim/tree/get\">http://%s/sim/tree/get</a></p>",hostportname.c_str(), hostportname.c_str()); - links.push_back(std::string(tmp)); - - - sprintf(tmp,"<p><a href=\"http://%s/position:1/pva/get\">http://%s/position:1/pva/get</a></p>", hostportname.c_str(), hostportname.c_str()); - links.push_back(std::string(tmp)); + sprintf(tmp,"</p><p><a href=\"http://%s/sim/tree/get\">http://%s/sim/tree/get</a></p>",hostportname.c_str(), hostportname.c_str()); + links.push_back(std::string(tmp)); + // todo - these should be automatically generated working links + + sprintf(tmp,"<p><a href=\"http://%s/position:1/pva/get\">http://%s/position:1/pva/get</a></p>", hostportname.c_str(), hostportname.c_str()); + links.push_back(std::string(tmp)); + - sprintf(tmp, "<p><a href=\"http://%s/position:1/laser:0/data/get\">http://%s/position:1/laser:0/data/get</a></p>", hostportname.c_str(), hostportname.c_str()); - links.push_back(std::string(tmp)); + sprintf(tmp, "<p><a href=\"http://%s/position:1/laser:0/data/get\">http://%s/position:1/laser:0/data/get</a></p>", hostportname.c_str(), hostportname.c_str()); + links.push_back(std::string(tmp)); - sprintf(tmp,"<p><a href=\"http://%s/position:1/ranger:0/data/get\">http://%s/position:1/ranger:0:/data/get</a></p>", hostportname.c_str(), hostportname.c_str()); - links.push_back(std::string(tmp)); + sprintf(tmp,"<p><a href=\"http://%s/position:1/ranger:0/data/get\">http://%s/position:1/ranger:0:/data/get</a></p>", hostportname.c_str(), hostportname.c_str()); + links.push_back(std::string(tmp)); - sprintf(tmp,"<p><a href=\"http://%s/position:1/model:0/fiducial:0/data/get\">http://%s/position:1/model:0/fiducial:0/data/get</a></p>",hostportname.c_str(), hostportname.c_str()); - links.push_back(std::string(tmp)); - + sprintf(tmp,"<p><a href=\"http://%s/position:1/model:0/fiducial:0/data/get\">http://%s/position:1/model:0/fiducial:0/data/get</a></p>",hostportname.c_str(), hostportname.c_str()); + links.push_back(std::string(tmp)); - response += links[0]+links[1]+links[2]+ links[3]+links[4]+ "</body></html>"; - - - return true; + response += links[0]+links[1]+links[2]+ links[3]+links[4]+ "</body></html>"; + + return true; } // Everything else must be an existing model else - { - return HandleModelRequest(model, prop, action, format, kv, response); - } + { + return HandleModelRequest(model, prop, action, format, kv, response); + } } bool WebSim::HandleSimRequest(const std::string& prop, - const std::string& action, - Format format, - struct evkeyvalq* kv, - std::string& response) + const std::string& action, + Format format, + struct evkeyvalq* kv, + std::string& response) { + printf( "[%s] sim request %s %s\n", + IdentificationString().c_str(), prop.c_str(), action.c_str() ); + // 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: Missing name and/or type argument for sim/factor/create"; - return false; - } - - return(CreateModel(name, type, response)); - } - else if(action == "create") - { - std::string name, type; - if(!GetValue(name, kv, "name")) - { - response = "ERROR: Missing name argument for sim/factor/create"; - return false; - } - - return(DeleteModel(name, response)); - } - else - { - response = "ERROR: Unknown action " + action + " for sim/factory"; - return false; - } - } + { + if(action == "create") + { + std::string name, type; + if(!GetValue(name, kv, "name")) + { + response = "ERROR: Missing name argument for sim/factory/create"; + return false; + } + + if( !GetValue(type, kv, "type")) + { + response = "ERROR: Missing name type argument for sim/factory/create"; + return false; + } + + return(CreateModel(name, type, response)); + } + else if(action == "destroy") + { + std::string name, type; + if(!GetValue(name, kv, "name")) + { + response = "ERROR: Missing name argument for sim/factory/destroy"; + return false; + } + + return(DeleteModel(name, response)); + } + else + { + response = "ERROR: Unknown action " + action + " for sim/factory"; + return false; + } + } else if(prop == "clock") - { - if(action == "tick") - { - ticks_remaining--; - response = "Ticked the clock"; - return true; - } - else if(action == "get") - { - response = "Current time: " + GetTime().String(); - return true; - } - else - { - response = "ERROR: Unknown action " + action + " for sim/clock"; - return false; - } - } + { + if(action == "tick") + { + ticks_remaining--; + response = "Ticked the clock"; + return true; + } + else if(action == "get") + { + response = "Current time: " + GetTime().String(); + return true; + } + else + { + response = "ERROR: Unknown action " + action + " for sim/clock"; + return false; + } + } else if(prop == "extent") - {/* - double x,y,z; - Pose center; - GetModelExtent("sim", x, y, z, center, response); - GetXMLModelExtent("sim", x, y, z, center, response); - */ - return true; - } + {/* + double x,y,z; + Pose center; + GetModelExtent("sim", x, y, z, center, response); + GetXMLModelExtent("sim", x, y, z, center, response); + */ + return true; + } else if(prop == "children") - { - std::vector<std::string> children; - GetModelChildren("",children); + { + std::vector<std::string> children; + GetModelChildren("",children); - for(unsigned int i=0;i<children.size();i++) - response += "-" + children[i]; - } + for(unsigned int i=0;i<children.size();i++) + response += "-" + children[i]; + } else if(prop == "tree") - { - GetModelTree("", format, response, false); - return true; + { + GetModelTree("", format, response, false); + return true; - } + } else if(prop == "greet") // action is the name of the greeting server - { - // TODO - check to see if this server was anticipated - response = "Greetings " + action; - printf( "[websim] WebSim peer %s connected\n", action.c_str() ); - return true; - } + { + // TODO - check to see if this server was anticipated + response = "Greetings " + action; + printf( "[websim] WebSim peer %s connected\n", action.c_str() ); + return true; + } else - { - response = "ERROR: Unknown property " + prop + " for sim"; - return false; - } + { + response = "ERROR: Unknown property " + prop + " for sim"; + return false; + } return false; } bool WebSim::HandleModelRequest(const std::string& model, - const std::string& prop, - const std::string& action, - Format format, - struct evkeyvalq* kv, - std::string& response) + const std::string& prop, + const std::string& action, + Format format, + struct evkeyvalq* kv, + std::string& response) { if(action == "get") - { - if(prop == "data" || prop == ""){ + { + if(prop == "data" || prop == ""){ - return(GetModelData(model, response, format, NULL)); + return(GetModelData(model, response, format, NULL)); - }else if(prop == "pva"){ + }else if(prop == "pva"){ Pose p; Velocity v; Acceleration a; Time t; if(GetModelPVA(model, t, p, v, a, response)){ - GetPVA(model, t, p, v, a, format, response, NULL); - return true; + GetPVA(model, t, p, v, a, format, response, NULL); + return true; } else - return false; + return false; - }else if(prop == "children"){ + }else if(prop == "children"){ std::vector<std::string> children; GetModelChildren(model,children); for(unsigned int i=0;i<children.size();i++) - response += children[i] + "\n"; + response += children[i] + "\n"; return true; - }else if(prop == "tree"){ + }else if(prop == "tree"){ return(GetModelTree(model, format, response, true)); - }else if(prop == "extent"){ + }else if(prop == "extent"){ double x,y,z; Pose center; if(GetModelExtent(model, x, y, z, center, response)) - { + { - GetModelExtent(model, x, y, z, center, format, response, NULL); - return true; + GetModelExtent(model, x, y, z, center, format, response, NULL); + return true; - }else{ + }else{ - response = "ERROR: failed to get the extent of model " + model; - return false; + response = "ERROR: failed to get the extent of model " + model; + return false; } - }else{ + }else{ response = "ERROR: Unknown property " + prop + " for model " + model; return false; - } + } -}else if(action == "set") - { - if(prop == "pva") - { - std::string sx, sy, sz, sroll, spitch, syaw; + }else if(action == "set") + { + if(prop == "pva") + { + std::string sx, sy, sz, sroll, spitch, syaw; - // Get pose first, fill in what the caller provided - Pose p; - Velocity v; - Acceleration a; - Time t; - if(!GetModelPVA(model, t, p, v, a, response)) - { - response = "Failed to get pose before setting it"; - return false; - } - try - { - if(GetValue(sx, kv, "px")) - p.x = boost::lexical_cast<float>(sx); - if(GetValue(sy, kv, "py")) - p.y = boost::lexical_cast<float>(sy); - if(GetValue(sz, kv, "pz")) - p.z = boost::lexical_cast<float>(sz); - if(GetValue(sroll, kv, "pr")) - p.r = boost::lexical_cast<float>(sroll); - if(GetValue(spitch, kv, "pp")) - p.p = boost::lexical_cast<float>(spitch); - if(GetValue(syaw, kv, "pa")) - p.a = boost::lexical_cast<float>(syaw); + // Get pose first, fill in what the caller provided + Pose p; + Velocity v; + Acceleration a; + Time t; + if(!GetModelPVA(model, t, p, v, a, response)) + { + response = "Failed to get pose before setting it"; + return false; + } + try + { + if(GetValue(sx, kv, "px")) + p.x = boost::lexical_cast<float>(sx); + if(GetValue(sy, kv, "py")) + p.y = boost::lexical_cast<float>(sy); + if(GetValue(sz, kv, "pz")) + p.z = boost::lexical_cast<float>(sz); + if(GetValue(sroll, kv, "pr")) + p.r = boost::lexical_cast<float>(sroll); + if(GetValue(spitch, kv, "pp")) + p.p = boost::lexical_cast<float>(spitch); + if(GetValue(syaw, kv, "pa")) + p.a = boost::lexical_cast<float>(syaw); - if(GetValue(sx, kv, "vx")) - v.x = boost::lexical_cast<float>(sx); - if(GetValue(sy, kv, "vy")) - v.y = boost::lexical_cast<float>(sy); - if(GetValue(sz, kv, "vz")) - v.z = boost::lexical_cast<float>(sz); - if(GetValue(sroll, kv, "vr")) - v.r = boost::lexical_cast<float>(sroll); - if(GetValue(spitch, kv, "vp")) - v.p = boost::lexical_cast<float>(spitch); - if(GetValue(syaw, kv, "va")) - v.a = boost::lexical_cast<float>(syaw); + if(GetValue(sx, kv, "vx")) + v.x = boost::lexical_cast<float>(sx); + if(GetValue(sy, kv, "vy")) + v.y = boost::lexical_cast<float>(sy); + if(GetValue(sz, kv, "vz")) + v.z = boost::lexical_cast<float>(sz); + if(GetValue(sroll, kv, "vr")) + v.r = boost::lexical_cast<float>(sroll); + if(GetValue(spitch, kv, "vp")) + v.p = boost::lexical_cast<float>(spitch); + if(GetValue(syaw, kv, "va")) + v.a = boost::lexical_cast<float>(syaw); - if(GetValue(sx, kv, "ax")) - a.x = boost::lexical_cast<float>(sx); - if(GetValue(sy, kv, "ay")) - a.y = boost::lexical_cast<float>(sy); - if(GetValue(sz, kv, "az")) - a.z = boost::lexical_cast<float>(sz); - if(GetValue(sroll, kv, "ar")) - a.r = boost::lexical_cast<float>(sroll); - if(GetValue(spitch, kv, "ap")) - a.p = boost::lexical_cast<float>(spitch); - if(GetValue(syaw, kv, "aa")) - a.a = boost::lexical_cast<float>(syaw); - } - catch(boost::bad_lexical_cast e) - { - response = std::string("Failed to parse input value(s): ") + + if(GetValue(sx, kv, "ax")) + a.x = boost::lexical_cast<float>(sx); + if(GetValue(sy, kv, "ay")) + a.y = boost::lexical_cast<float>(sy); + if(GetValue(sz, kv, "az")) + a.z = boost::lexical_cast<float>(sz); + if(GetValue(sroll, kv, "ar")) + a.r = boost::lexical_cast<float>(sroll); + if(GetValue(spitch, kv, "ap")) + a.p = boost::lexical_cast<float>(spitch); + if(GetValue(syaw, kv, "aa")) + a.a = boost::lexical_cast<float>(syaw); + } + catch(boost::bad_lexical_cast e) + { + response = std::string("Failed to parse input value(s): ") + e.what(); - return false; - } + return false; + } - return(SetModelPVA(model, p, v, a, response)); + return(SetModelPVA(model, p, v, a, response)); + } + else + { + response = "ERROR: Unknown property " + prop + " for model " + model; + return false; + } } - else + else { - response = "ERROR: Unknown property " + prop + " for model " + model; + response = "ERROR: Unknown action " + action; return false; } - } - else - { - response = "ERROR: Unknown action " + action; - return false; - } return false; } @@ -510,616 +530,616 @@ void WebSim::GetPVA(const std::string& name, - Time& t, - const Pose& p, - const Velocity& v, - const Acceleration& a, - Format format, - std::string& response, - void* xmlnode) + Time& t, + const Pose& p, + const Velocity& v, + const Acceleration& a, + Format format, + std::string& response, + void* xmlnode) { - if(format == TEXT){ - char buf[1024]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" - " vel : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" - " acc : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", - name.c_str(), - t.String().c_str(), - p.x, p.y, p.z, p.r, p.p, p.a, - v.x, v.y, v.z, v.r, v.p, v.a, - a.x, a.y, a.z, a.r, a.p, a.a); - response = buf; + if(format == TEXT){ + char buf[1024]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" + " vel : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" + " acc : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", + name.c_str(), + t.String().c_str(), + p.x, p.y, p.z, p.r, p.p, p.a, + v.x, v.y, v.z, v.r, v.p, v.a, + a.x, a.y, a.z, a.r, a.p, a.a); + response = buf; - }else if (format == XML){ + }else if (format == XML){ - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; - if(xmlnode == NULL){ + if(xmlnode == NULL){ - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr) xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "PVA", NULL); - //root_node = (xmlNodePtr)parent; - } + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr) xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "PVA", NULL); + //root_node = (xmlNodePtr)parent; + } - sprintf(str,"%s",t.String().c_str()); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "pva"); + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "pva"); - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); - tmp = ConvertInput(str, MY_ENCODING); - xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",v.x, v.y, v.z, v.r, v.p, v.a); - tmp = ConvertInput(str, MY_ENCODING); - xmlNewProp(node, BAD_CAST "Velocity", BAD_CAST tmp); + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",v.x, v.y, v.z, v.r, v.p, v.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlNewProp(node, BAD_CAST "Velocity", BAD_CAST tmp); - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",a.x, a.y, a.z, a.r, a.p, a.a); - tmp = ConvertInput(str, MY_ENCODING); - xmlNewProp(node, BAD_CAST "Acceleration", BAD_CAST tmp); + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",a.x, a.y, a.z, a.r, a.p, a.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlNewProp(node, BAD_CAST "Acceleration", BAD_CAST tmp); - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } - } + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } + } } void WebSim::GetLaserData(const std::string& name, - Time& t, - uint32_t& resolution, - double& fov, - Pose& p, - std::vector<double>& ranges, - Format format, - std::string& response, - void* xmlnode) + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::vector<double>& ranges, + Format format, + std::string& response, + void* xmlnode) { - if(format == TEXT){ + if(format == TEXT){ - std::string res; - char temp[128]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } - char buf[4096]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n laser: (%s)\n resolution: (%d)\n fov(%.2f)\n" - " pose (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", - name.c_str(), - t.String().c_str(), - res.c_str(), - resolution, - fov, - p.x,p.y,p.z,p.r,p.p,p.a); - response = buf; + char buf[4096]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n laser: (%s)\n resolution: (%d)\n fov(%.2f)\n" + " pose (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", + name.c_str(), + t.String().c_str(), + res.c_str(), + resolution, + fov, + p.x,p.y,p.z,p.r,p.p,p.a); + response = buf; - }else if(format == XML){ + }else if(format == XML){ - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr) xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Laser", NULL); - //root_node = (xmlNodePtr)parent; - } + if(xmlnode == NULL){ + puts("no parent\n"); + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr) xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Laser", NULL); + //root_node = (xmlNodePtr)parent; + } - std::string res; - char temp[128]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } - xmlNewProp(node, BAD_CAST "Time", BAD_CAST t.String().c_str()); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "laser"); + xmlNewProp(node, BAD_CAST "Time", BAD_CAST t.String().c_str()); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "laser"); - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - sprintf(str,"%d",resolution); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Resolution", BAD_CAST tmp); + sprintf(str,"%d",resolution); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Resolution", BAD_CAST tmp); - sprintf(str,"%.3f",fov); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "FOV", BAD_CAST tmp); + sprintf(str,"%.3f",fov); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "FOV", BAD_CAST tmp); - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); - tmp = ConvertInput(res.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } - } + } } void WebSim::GetRangerData(const std::string& name, - Time& t, - std::vector<Pose>& p, - std::vector<double>& ranges, - Format format, - std::string& response, - void* xmlnode) + Time& t, + std::vector<Pose>& p, + std::vector<double>& ranges, + Format format, + std::string& response, + void* xmlnode) { - if(format == TEXT){ + if(format == TEXT){ - std::string res; - char temp[128]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } - std::string pstr; - char ptmp[256]; - for(unsigned int i=0;i<p.size();i++){ - Pose pos = p.at(i); - sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", - pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); - pstr.append(ptmp); + std::string pstr; + char ptmp[256]; + for(unsigned int i=0;i<p.size();i++){ + Pose pos = p.at(i); + sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", + pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); + pstr.append(ptmp); - } + } - char buf[2048]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n ranger\n ranges: (%s)\n pose: %s", - name.c_str(), - t.String().c_str(), - res.c_str(), - pstr.c_str()); - response = buf; + char buf[2048]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n ranger\n ranges: (%s)\n pose: %s", + name.c_str(), + t.String().c_str(), + res.c_str(), + pstr.c_str()); + response = buf; - }else if(format == XML){ + }else if(format == XML){ - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr)xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); - //root_node = (xmlNodePtr)parent; - } + if(xmlnode == NULL){ + puts("no parent\n"); + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr)xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); + //root_node = (xmlNodePtr)parent; + } - std::string res; - char temp[1024]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } + std::string res; + char temp[1024]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } - std::string pstr; - char ptmp[2048]; - for(unsigned int i=0;i<p.size();i++){ - Pose pos = p.at(i); - sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", - pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); - pstr.append(ptmp); - } + std::string pstr; + char ptmp[2048]; + for(unsigned int i=0;i<p.size();i++){ + Pose pos = p.at(i); + sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", + pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); + pstr.append(ptmp); + } - //xmlNodePtr node = xmlNewChild(root_node, NULL, BAD_CAST "Ranger", NULL); + //xmlNodePtr node = xmlNewChild(root_node, NULL, BAD_CAST "Ranger", NULL); - sprintf(str,"%s",t.String().c_str()); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "ranger"); + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "ranger"); - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - tmp = ConvertInput(res.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); - tmp = ConvertInput(pstr.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Positions", BAD_CAST tmp); + tmp = ConvertInput(pstr.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Positions", BAD_CAST tmp); - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } - } + } } void WebSim::GetFiducialData(const std::string& name, - Time& t, - std::vector<Fiducial>& f, - Format format, - std::string& response, - void* xmlnode ) + Time& t, + std::vector<Fiducial>& f, + Format format, + std::string& response, + void* xmlnode ) { - if(format == TEXT){ + if(format == TEXT){ - std::string res; - char temp[128]; - for(unsigned int i=0;i<f.size();i++){ - sprintf(temp,"(%.3f,%.3f,%d)\n", f.at(i).range, f.at(i).bearing, f.at(i).id); - res.append(temp); + std::string res; + char temp[128]; + for(unsigned int i=0;i<f.size();i++){ + sprintf(temp,"(%.3f,%.3f,%d)\n", f.at(i).range, f.at(i).bearing, f.at(i).id); + res.append(temp); - } + } - char buf[1024]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n Fiducial:\n", - name.c_str(), - t.String().c_str()); + char buf[1024]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n Fiducial:\n", + name.c_str(), + t.String().c_str()); - response = buf; - response.append(res); + response = buf; + response.append(res); - }else if(format == XML){ + }else if(format == XML){ - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr)xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); - //root_node = (xmlNodePtr)parent; - } + if(xmlnode == NULL){ + puts("no parent\n"); + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr)xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); + //root_node = (xmlNodePtr)parent; + } - std::string res; - char temp[128]; - for(unsigned int i=0;i<f.size();i++){ - sprintf(temp,"(%.3f,%.3f,%d)", f.at(i).range, f.at(i).bearing, f.at(i).id); - res.append(temp); + std::string res; + char temp[128]; + for(unsigned int i=0;i<f.size();i++){ + sprintf(temp,"(%.3f,%.3f,%d)", f.at(i).range, f.at(i).bearing, f.at(i).id); + res.append(temp); - } + } - sprintf(str,"%s",t.String().c_str()); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "fiducial"); + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "fiducial"); - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - tmp = ConvertInput(res.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Targets", BAD_CAST tmp); + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Targets", BAD_CAST tmp); - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } - } + } } void WebSim::GetModelExtent(const std::string& name, - double& x, - double& y, - double& z, - Pose& center, - Format format, - std::string& response, - void* xmlnode) + double& x, + double& y, + double& z, + Pose& center, + Format format, + std::string& response, + void* xmlnode) { - if(format == TEXT){ - char buf[1024]; - if(name == "sim") - snprintf(buf, sizeof(buf),"World Extent: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", - x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); - else - snprintf(buf, sizeof(buf),"%s's Extent: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", - name.c_str(), x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); + if(format == TEXT){ + char buf[1024]; + if(name == "sim") + snprintf(buf, sizeof(buf),"World Extent: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", + x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); + else + snprintf(buf, sizeof(buf),"%s's Extent: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", + name.c_str(), x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); - response = buf; - }else if(format == XML){ + response = buf; + }else if(format == XML){ - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "ModelExtent", NULL); - }else{ - node = (xmlNodePtr)xmlnode; - xmlNodeSetName(node, xmlCharStrdup("ModelExtent")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "ModelExtent", NULL); - //root_node = (xmlNodePtr)parent; - } + if(xmlnode == NULL){ + puts("no parent\n"); + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "ModelExtent", NULL); + }else{ + node = (xmlNodePtr)xmlnode; + xmlNodeSetName(node, xmlCharStrdup("ModelExtent")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "ModelExtent", NULL); + //root_node = (xmlNodePtr)parent; + } - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "extent"); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "extent"); - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - sprintf(str,"%.3f",x); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "X", BAD_CAST tmp); + sprintf(str,"%.3f",x); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "X", BAD_CAST tmp); - sprintf(str,"%.3f",y); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Y", BAD_CAST tmp); + sprintf(str,"%.3f",y); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Y", BAD_CAST tmp); - sprintf(str,"%.3f",z); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Z", BAD_CAST tmp); + sprintf(str,"%.3f",z); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Z", BAD_CAST tmp); - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",center.x,center.y,center.z,center.r,center.p,center.a); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Origin", BAD_CAST tmp); + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",center.x,center.y,center.z,center.r,center.p,center.a); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Origin", BAD_CAST tmp); - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } - } + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } + } } bool WebSim::GetModelTree(const std::string& model,Format format, std::string& response, bool everything){ - if(format == XML){ - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlBufferPtr buf; + if(format == XML){ + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlBufferPtr buf; - doc = xmlNewDoc(BAD_CAST "1.0"); - buf = xmlBufferCreate(); - root_node = xmlNewNode(NULL, BAD_CAST "ModelTree"); - xmlDocSetRootElement(doc, root_node); + doc = xmlNewDoc(BAD_CAST "1.0"); + buf = xmlBufferCreate(); + root_node = xmlNewNode(NULL, BAD_CAST "ModelTree"); + xmlDocSetRootElement(doc, root_node); - if(GetModelTreeXML(model, root_node, everything)){ + if(GetModelTreeXML(model, root_node, everything)){ - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc, root_node, 0, 1); - response = (const char*) buf->content; - }else{ - response = "Error in generating model tree.\n"; + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc, root_node, 0, 1); + response = (const char*) buf->content; + }else{ + response = "Error in generating model tree.\n"; - } + } - xmlBufferFree(buf); - xmlFreeDoc(doc); + xmlBufferFree(buf); + xmlFreeDoc(doc); - std::string out = "Model Tree:\n " + response + "\n"; - puts(out.c_str()); + std::string out = "Model Tree:\n " + response + "\n"; + puts(out.c_str()); - return true; + return true; - }else if(format == TEXT){ + }else if(format == TEXT){ - std::string str,type; - GetModelType(model, type); - str+= model + "("+type+")"+ "\n"; - std::vector<std::string> children; - GetModelChildren(model, children); - for(unsigned int i=0; i<children.size(); i++){ + std::string str,type; + GetModelType(model, type); + str+= model + "("+type+")"+ "\n"; + std::vector<std::string> children; + GetModelChildren(model, children); + for(unsigned int i=0; i<children.size(); i++){ - std::string sub; - GetModelTree(children[i], TEXT, sub, false); - str += sub + "\n"; - } + std::string sub; + GetModelTree(children[i], TEXT, sub, false); + str += sub + "\n"; + } - response = str; - return false; - } + response = str; + return false; + } - return false; + return false; } bool WebSim::GetModelTreeXML(const std::string& model, void* xmlparent, bool everything){ - std::string res; - xmlNodePtr node; + std::string res; + xmlNodePtr node; - if(!xmlparent){ - printf("Invalid xmlNode pointer. \n"); - return false; - } + if(!xmlparent){ + printf("Invalid xmlNode pointer. \n"); + return false; + } - if(model != ""){ + if(model != ""){ - node = xmlNewChild((xmlNodePtr)xmlparent, NULL, BAD_CAST "Model", NULL); + node = xmlNewChild((xmlNodePtr)xmlparent, NULL, BAD_CAST "Model", NULL); - bool flag = false; - std::string type; + bool flag = false; + std::string type; - if(everything){ - std::string error; - flag = !GetModelData(model, error, XML, node); + if(everything){ + std::string error; + flag = !GetModelData(model, error, XML, node); - } + } - if(!everything || flag){ + if(!everything || flag){ - GetModelType(model, type); - xmlNodeSetName(node, xmlCharStrdup("Model")); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST model.c_str()); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST type.c_str()); - } + GetModelType(model, type); + xmlNodeSetName(node, xmlCharStrdup("Model")); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST model.c_str()); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST type.c_str()); + } - }else - node = (xmlNodePtr) xmlparent; + }else + node = (xmlNodePtr) xmlparent; - std::vector<std::string> children; - GetModelChildren(model, children); - for(unsigned int i=0;i<children.size();i++) - GetModelTreeXML(children[i], node, everything); + std::vector<std::string> children; + GetModelChildren(model, children); + for(unsigned int i=0;i<children.size();i++) + GetModelTreeXML(children[i], node, everything); - return true; + return true; } xmlChar * ConvertInput(const char *in, const char *encoding) { - xmlChar *out; - int ret; - int size; - int out_size; - int temp; - xmlCharEncodingHandlerPtr handler; + xmlChar *out; + int ret; + int size; + int out_size; + int temp; + xmlCharEncodingHandlerPtr handler; - if (in == 0) - return 0; + if (in == 0) + return 0; - handler = xmlFindCharEncodingHandler(encoding); + handler = xmlFindCharEncodingHandler(encoding); - if (!handler) { - printf("ConvertInput: no encoding handler found for '%s'\n", - encoding ? encoding : ""); - return 0; - } + if (!handler) { + printf("ConvertInput: no encoding handler found for '%s'\n", + encoding ? encoding : ""); + return 0; + } - size = (int) strlen(in) + 1; - out_size = size * 2 - 1; - out = (unsigned char *) xmlMalloc((size_t) out_size); + size = (int) strlen(in) + 1; + out_size = size * 2 - 1; + out = (unsigned char *) xmlMalloc((size_t) out_size); - if (out != 0) { - temp = size - 1; - ret = handler->input(out, &out_size, (const xmlChar *) in, &temp); - if ((ret < 0) || (temp - size + 1)) { - if (ret < 0) { - printf("ConvertInput: conversion wasn't successful.\n"); - } else { - printf - ("ConvertInput: conversion wasn't successful. converted: %i octets.\n", - temp); - } + if (out != 0) { + temp = size - 1; + ret = handler->input(out, &out_size, (const xmlChar *) in, &temp); + if ((ret < 0) || (temp - size + 1)) { + if (ret < 0) { + printf("ConvertInput: conversion wasn't successful.\n"); + } else { + printf + ("ConvertInput: conversion wasn't successful. converted: %i octets.\n", + temp); + } - xmlFree(out); - out = 0; - } else { - out = (unsigned char *) xmlRealloc(out, out_size + 1); - out[out_size] = 0; - } + xmlFree(out); + out = 0; } else { - printf("ConvertInput: no mem\n"); + out = (unsigned char *) xmlRealloc(out, out_size + 1); + out[out_size] = 0; } + } else { + printf("ConvertInput: no mem\n"); + } - return out; + return out; } @@ -1141,20 +1161,20 @@ std::string model, prop, action, response; puts(req->uri); if(!obj->ParseURI(model, prop, action, req->uri, response)) - { - response_code = 400; - response_string = "Invalid request"; - } + { + response_code = 400; + response_string = "Invalid request"; + } else if(!obj->HandleURI(model, prop, action, &query_args, response)) - { - response_code = 400; - response_string = "Invalid request"; - } + { + response_code = 400; + response_string = "Invalid request"; + } else - { - response_code = 200; - response_string = "OK"; - } + { + response_code = 200; + response_string = "OK"; + } //puts(response.c_str()); @@ -1168,119 +1188,127 @@ bool WebSim::ParseURI( std::string& model, std::string& prop, - std::string& action, - const std::string uri, - std::string& response) + std::string& action, + const std::string uri, + std::string& response) { - //puts(uri.c_str()); - // Remove the query args + // Remove the query args std::vector<std::string> uri_parts; StringSplit(uri, uri_parts, "?"); assert(uri_parts.size() > 0); std::string bare_uri = uri_parts[0]; - + // We require 3 path components: model/property/action StringSplit(bare_uri, uri_parts, "/"); + - //puts("parts:"); - /*for(int j=0;j<uri_parts.size();j++) - puts(uri_parts[j].c_str()); - - puts("Here I am!");*/ - if(uri_parts.size() < 2) + // otherwise there should be 4 parts, with the first one empty + if(uri_parts.size() != 4) { - // return true, then generate the welcome html - return false; + response = "Must be 3 slash-separated parts in the URI"; + return false; } + + model = uri_parts[1]; + prop = uri_parts[2]; + action = uri_parts[3]; + + return true; +} + +// //puts(uri.c_str()); +// // Remove the query args +// std::vector<std::string> uri_parts; +// StringSplit(uri, uri_parts, "?"); +// assert(uri_parts.size() > 0); +// std::string bare_uri = uri_parts[0]; + - // example: http://localhost:8000/viz - if(uri_parts.size() ==2){ +// StringSplit(bare_uri, uri_parts, "/"); + +// //puts("parts:"); +// /*for(int j=0;j<uri_parts.size();j++) +// puts(uri_parts[j].c_str()); + +// puts("Here I am!");*/ +// if(uri_parts.size() < 2) +// { +// // return true, then generate the welcome html +// return false; +// } + +// // example: http://localhost:8000/viz +// if(uri_parts.size() ==2){ - //puts("1 Here I am!"); - model = uri_parts[1]; - prop = ""; - action = ""; - //puts("1.1 Here I am!"); - return true; - } +// //puts("1 Here I am!"); +// model = uri_parts[1]; +// prop = ""; +// action = ""; +// //puts("1.1 Here I am!"); +// return true; +// } - // example: http://localhost:8000/viz/applet.class - if(uri_parts.size() ==3){ +// // example: http://localhost:8000/viz/applet.class +// if(uri_parts.size() ==3){ - //puts("2 Here I am!"); +// //puts("2 Here I am!"); - model = uri_parts[1]; - prop = uri_parts[2]; - action = ""; - return true; - } +// model = uri_parts[1]; +// prop = uri_parts[2]; +// action = ""; +// return true; +// } - //puts("3 here I am"); - unsigned int size = uri_parts.size(); - unsigned int modelendindex = 0; +// //puts("3 here I am"); +// unsigned int size = uri_parts.size(); +// unsigned int modelendindex = 0; - if(uri_parts[size-1] == "get" || uri_parts[size-1]== "set"){ - action = uri_parts[size-1]; - modelendindex = size-3; - } - else{ - action = "get"; - modelendindex = size-2; - } +// if(uri_parts[size-1] == "get" || uri_parts[size-1]== "set"){ +// action = uri_parts[size-1]; +// modelendindex = size-3; +// } +// else{ +// action = "get"; +// modelendindex = size-2; +// } - prop = uri_parts[modelendindex+1]; +// prop = uri_parts[modelendindex+1]; - for(unsigned int i=1;i <= modelendindex;i++){ - model += uri_parts[i]; - if(i!=modelendindex) - model += "."; - } +// for(unsigned int i=1;i <= modelendindex;i++){ +// model += uri_parts[i]; +// if(i!=modelendindex) +// model += "."; +// } - return true; -} +// return true; + bool WebSim::SetPuppetPVA( const std::string& name, - Pose& p, - Velocity& v, - Acceleration& a ) + Pose& p, + Velocity& v, + Acceleration& a ) { Puppet* pup = GetPuppet( name.c_str() ); if( pup ) - { - pup->Push( p,v,a ); - return true; - } + { + pup->Push( p,v,a ); + return true; + } printf( "[websim] warning: attempt to set puppet PVA on non-existent puppet \"%s\"\n", - name.c_str() ); + name.c_str() ); return false; } -// void WebSim::ForEachConfederate( void(*cb)(const std::string&, WebSim::Confederate*, void*), void* arg ) -// { -// g_hash_table_foreach( WebSim::confederates, -// (GHFunc)cb, -// arg ); -// } - -// void WebSim::ForEachPuppet( void(*cb)(const std::string&, WebSim::Puppet*, void*), void* arg ) -// { -// g_hash_table_foreach( WebSim::puppets, -// (GHFunc)cb, -// arg ); -// } - WebSim::Puppet* WebSim::GetPuppet( const std::string& name ) { - //return( (Puppet*)g_hash_table_lookup( WebSim::puppets, name.c_str() ) ); return puppets[name]; } WebSim::Confederate* WebSim::GetConfederate( const std::string& name ) { - //return( (Confederate*)g_hash_table_lookup( WebSim::confederates, name.c_str() ) ); return confederates[name]; } Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-06-24 22:54:06 UTC (rev 7892) +++ code/websim/src/websim.hh 2009-06-24... [truncated message content] |
From: <rt...@us...> - 2009-06-24 23:55:48
|
Revision: 7894 http://playerstage.svn.sourceforge.net/playerstage/?rev=7894&view=rev Author: rtv Date: 2009-06-24 23:55:46 +0000 (Wed, 24 Jun 2009) Log Message: ----------- broke HandleSimRequests into manageable chunks and cleaned up a bit Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/websim.cc code/websim/src/websim.hh Added Paths: ----------- code/websim/src/req_sim.cc Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-06-24 22:54:43 UTC (rev 7893) +++ code/websim/CMakeLists.txt 2009-06-24 23:55:46 UTC (rev 7894) @@ -57,8 +57,8 @@ include_directories(src) -add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) -add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc ) +add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc src/req_sim.cc ) +add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc src/req_sim.cc ) # Set output name to be the same as shared lib (may not work on Windows) set_target_properties(websim-static PROPERTIES OUTPUT_NAME websim) # Prevent deletion of existing lib of same name Added: code/websim/src/req_sim.cc =================================================================== --- code/websim/src/req_sim.cc (rev 0) +++ code/websim/src/req_sim.cc 2009-06-24 23:55:46 UTC (rev 7894) @@ -0,0 +1,194 @@ +#include "websim.hh" +using namespace websim; + +// todo: XML format for sim requests + +bool WebSim::HandleSimRequest(const std::string& prop, + const std::string& action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + printf( "[%s] sim %s %s\n", + IdentificationString().c_str(), prop.c_str(), action.c_str() ); + + if(prop == "factory") + return HandleSimFactoryRequest( action, format, kv, response ); + + if(prop == "clock") + return HandleSimClockRequest( action, format, kv, response ); + + if(prop == "geometry") + return HandleSimGeometryRequest( action, format, kv, response ); + + if(prop == "children") + return HandleSimChildrenRequest( action, format, kv, response ); + + if(prop == "tree") + return HandleSimTreeRequest( action, format, kv, response ); + + if(prop == "greet") + return HandleSimGreetRequest( action, format, kv, response ); + + response = "ERROR: Unknown property " + prop + " for sim. Candidates are: children clock factory greet tree."; + return false; +} + +bool WebSim::HandleSimGeometryRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + /* + double x,y,z; + Pose center; + GetModelExtent("sim", x, y, z, center, response); + GetXMLModelExtent("sim", x, y, z, center, response); + */ + + response = "Warning: geometry not yet implemented"; + return true; +} + +bool WebSim::HandleSimChildrenRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if( action == "" ) + action = "get"; // default action + + if( action == "get" ) + { + std::vector<std::string> children; + GetModelChildren("",children); + + for(unsigned int i=0;i<children.size();i++) + response += "-" + children[i]; + + return true; + } + + response = "ERROR: Unknown action " + action + " for sim/children. Candidates are: get (default)."; + return false; +} + +bool WebSim::HandleSimTreeRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if( action == "" ) + action = "get"; // default action + + if( action == "get" ) + { + GetModelTree("", format, response, false); + return true; + } + + response = "ERROR: Unknown action " + action + " for sim/tree. Candidates are: get (default)."; + return false; +} + +bool WebSim::HandleSimGreetRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if( action == "" ) + action = "get"; // default action + + if( action == "get" ) + { + // TODO - check to see if this server was anticipated + response = "Greetings " + action; + printf( "[websim] WebSim peer %s connected\n", action.c_str() ); + return true; + } + + response = "ERROR: Unknown action " + action + " for sim/greet. Candidates are: get (default)."; + return false; +} + +bool WebSim::HandleSimFactoryRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if(action == "create") + { + std::string name, type; + if(!GetValue(name, kv, "name")) + { + response = "ERROR: Missing name argument for sim/factory/create"; + return false; + } + + if( !GetValue(type, kv, "type")) + { + response = "ERROR: Missing name type argument for sim/factory/create"; + return false; + } + + return(CreateModel(name, type, response)); + } + + if(action == "destroy") + { + std::string name, type; + if(!GetValue(name, kv, "name")) + { + response = "ERROR: Missing name argument for sim/factory/destroy"; + return false; + } + + return(DeleteModel(name, response)); + } + + response = "ERROR: Unknown action " + action + " for sim/factory. Candidates are: create destroy"; + return false; +} + +bool WebSim::HandleSimClockRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if( action == "" ) // DEFAULT ACTION + action = "get"; + + if( action == "get" ) + { + response = "Current time: " + GetTime().String() + " seconds."; + return true; + } + + if(action == "tick") + { + ticks_remaining--; + response = "Ticked the clock"; + return true; + } + + if(action == "start") + { + if( ClockStart() ) + response = "Started the clock"; + else + response = "Failed to start the clock"; + return true; + } + + if(action == "stop") + { + if( ClockStop() ) + response = "Stopped the clock"; + else + response = "Failed to stop the clock"; + return true; + } + + response = "ERROR: Unknown action " + action + " for sim/clock. Candidates are: get (default) start stop."; + return false; +} Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-06-24 22:54:43 UTC (rev 7893) +++ code/websim/src/websim.cc 2009-06-24 23:55:46 UTC (rev 7894) @@ -19,8 +19,8 @@ * */ -/* Desc: WebSim http server for robot interactiony - * Author: Brian Gerkey, Richard Vaughan, Abbas +/* Desc: HTTP interface to simulators + * Author: Brian Gerkey, Richard Vaughan, Abbas Sadat * Date: 9 March 2009 * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ */ @@ -276,111 +276,10 @@ } } -bool -WebSim::HandleSimRequest(const std::string& prop, - const std::string& action, - Format format, - struct evkeyvalq* kv, - std::string& response) -{ - printf( "[%s] sim request %s %s\n", - IdentificationString().c_str(), prop.c_str(), action.c_str() ); - // The special factory property - if(prop == "factory") - { - if(action == "create") - { - std::string name, type; - if(!GetValue(name, kv, "name")) - { - response = "ERROR: Missing name argument for sim/factory/create"; - return false; - } - - if( !GetValue(type, kv, "type")) - { - response = "ERROR: Missing name type argument for sim/factory/create"; - return false; - } - - return(CreateModel(name, type, response)); - } - else if(action == "destroy") - { - std::string name, type; - if(!GetValue(name, kv, "name")) - { - response = "ERROR: Missing name argument for sim/factory/destroy"; - return false; - } - - return(DeleteModel(name, response)); - } - else - { - response = "ERROR: Unknown action " + action + " for sim/factory"; - return false; - } - } - else if(prop == "clock") - { - if(action == "tick") - { - ticks_remaining--; - response = "Ticked the clock"; - return true; - } - else if(action == "get") - { - response = "Current time: " + GetTime().String(); - return true; - } - else - { - response = "ERROR: Unknown action " + action + " for sim/clock"; - return false; - } - } - else if(prop == "extent") - {/* - double x,y,z; - Pose center; - GetModelExtent("sim", x, y, z, center, response); - GetXMLModelExtent("sim", x, y, z, center, response); - */ - return true; - } - else if(prop == "children") - { - std::vector<std::string> children; - GetModelChildren("",children); - - for(unsigned int i=0;i<children.size();i++) - response += "-" + children[i]; - } - else if(prop == "tree") - { - GetModelTree("", format, response, false); - return true; - - } - else if(prop == "greet") // action is the name of the greeting server - { - // TODO - check to see if this server was anticipated - response = "Greetings " + action; - printf( "[websim] WebSim peer %s connected\n", action.c_str() ); - return true; - } - else - { - response = "ERROR: Unknown property " + prop + " for sim"; - return false; - } - - return false; -} + + bool WebSim::HandleModelRequest(const std::string& model, const std::string& prop, Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-06-24 22:54:43 UTC (rev 7893) +++ code/websim/src/websim.hh 2009-06-24 23:55:46 UTC (rev 7894) @@ -20,7 +20,7 @@ */ /* Desc: HTTP interface to simulators - * Author: Brian Gerkey, Richard Vaughan + * Author: Brian Gerkey, Richard Vaughan, Abbas Sadat * Date: 9 March 2009 * SVN: $Id: gazebo.h 7398 2009-03-09 07:21:49Z natepak $ */ @@ -85,6 +85,20 @@ for a human reader, e.g. "1.3.1" */ virtual std::string VersionString() = 0; + /** Start the virtual clock running, unpausing the simulation. If + the clock is already running, this does nothing. + + @return true on succes, false on failure. + */ + virtual bool ClockStart()=0; + + /** Stop the virtual clock running, pausing the simulation. If the + clock is already stopped, this does nothing. + + @return true on succes, false on failure. + */ + virtual bool ClockStop()=0; + virtual bool CreateModel(const std::string& name, const std::string& type, std::string& response) = 0; @@ -230,29 +244,63 @@ @returns TRUE if a parameter with the given key exists. */ bool GetValue( std::string& value, - struct evkeyvalq* query_args, - const std::string& key); + struct evkeyvalq* query_args, + const std::string& key); + bool HandleURI(const std::string& model, - const std::string& prop, - const std::string& action, - struct evkeyvalq* kv, - std::string& response); + const std::string& prop, + const std::string& action, + struct evkeyvalq* kv, + std::string& response); + bool HandleSimRequest(const std::string& prop, - const std::string& action, - Format format, - struct evkeyvalq* kv, - std::string& response); + const std::string& action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleSimClockRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleSimFactoryRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleSimChildrenRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleSimTreeRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleSimGeometryRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleSimGreetRequest( std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + bool HandleModelRequest(const std::string& model, - const std::string& prop, - const std::string& action, - Format format, - struct evkeyvalq* kv, - std::string& response); + const std::string& prop, + const std::string& action, + Format format, + struct evkeyvalq* kv, + std::string& response); + bool ParseURI(std::string& model, - std::string& prop, - std::string& action, - std::string uri, - std::string& response); + std::string& prop, + std::string& action, + std::string uri, + std::string& response); void DeleteKeyVal(struct evkeyvalq* query_args); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <as...@us...> - 2009-06-29 22:59:41
|
Revision: 7930 http://playerstage.svn.sourceforge.net/playerstage/?rev=7930&view=rev Author: asadat Date: 2009-06-29 22:58:45 +0000 (Mon, 29 Jun 2009) Log Message: ----------- did some refactoring Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/req_sim.cc code/websim/src/websim.cc code/websim/src/websim.hh Added Paths: ----------- code/websim/src/req_model.cc Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-06-29 19:35:46 UTC (rev 7929) +++ code/websim/CMakeLists.txt 2009-06-29 22:58:45 UTC (rev 7930) @@ -57,7 +57,7 @@ include_directories(src) -add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc src/req_sim.cc ) +add_library(websim SHARED src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc src/req_sim.cc src/req_model.cc ) add_library(websim-static STATIC src/websim.cc src/parser.cc src/confederate.cc src/puppet.cc src/req_sim.cc ) # Set output name to be the same as shared lib (may not work on Windows) set_target_properties(websim-static PROPERTIES OUTPUT_NAME websim) Added: code/websim/src/req_model.cc =================================================================== --- code/websim/src/req_model.cc (rev 0) +++ code/websim/src/req_model.cc 2009-06-29 22:58:45 UTC (rev 7930) @@ -0,0 +1,757 @@ +#include "websim.hh" +#include <boost/lexical_cast.hpp> + +//#include <assert.h> +//#include <stdlib.h> +//#include <string.h> +#include <libxml/encoding.h> +using namespace websim; + +#define MY_ENCODING "ISO-8859-1" + +xmlChar * +ConvertInput(const char *in, const char *encoding); + +bool +WebSim::HandleModelRequest(const std::string& model, + const std::string& prop, + const std::string& action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if(prop == "pva") + return HandleModelPVARequest(model, action, format, kv, response ); + + if(prop == "data") + return HandleModelDataRequest( model, action, format, kv, response ); + + if(prop == "geometry") + return HandleModelGeometryRequest( model, action, format, kv, response ); + + if(prop == "tree") + return HandleModelTreeRequest( model, action, format, kv, response ); + + response = "ERROR: Unknown property " + prop + " for model. Candidates are: pva data geometry tree."; + return false; +} + + + +bool +WebSim::HandleModelDataRequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if(action == "get"){ + + if(!GetModelData(model, response, format, NULL)){ + response = "ERROR: failed to get the Data of model " + model; + return false; + } + } + + return true; + +} + +bool +WebSim::HandleModelTreeRequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + + if(action == "get"){ + if(!GetModelTree(model, format, response, false)){ + response = "ERROR: failed to get the tree of model " + model; + return false; + } + } + + return true; +} + +bool +WebSim::HandleModelGeometryRequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + + double x,y,z; + Pose center; + if(GetModelGeometry(model, x, y, z, center, response)) + { + + GetGeometryData(model, x, y, z, center, format, response, NULL); + return true; + + }else{ + + response = "ERROR: failed to get the Geometry of model " + model; + return false; + + } + + return true; +} + +bool +WebSim::HandleModelPVARequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response) +{ + if(action == "get"){ + + Pose p; + Velocity v; + Acceleration a; + Time t; + if(GetModelPVA(model, t, p, v, a, response)){ + + GetPVA(model, t, p, v, a, format, response, NULL); + return true; + + }else{ + + response = "ERROR: failed to get the PVA of model "+model; + return false; + } + + + }else if(action == "set"){ + + std::string sx, sy, sz, sroll, spitch, syaw; + + // Get pose first, fill in what the caller provided + Pose p; + Velocity v; + Acceleration a; + Time t; + if(!GetModelPVA(model, t, p, v, a, response)) + { + response = "Failed to get pose before setting it"; + return false; + } + try + { + if(GetValue(sx, kv, "px")) + p.x = boost::lexical_cast<float>(sx); + if(GetValue(sy, kv, "py")) + p.y = boost::lexical_cast<float>(sy); + if(GetValue(sz, kv, "pz")) + p.z = boost::lexical_cast<float>(sz); + if(GetValue(sroll, kv, "pr")) + p.r = boost::lexical_cast<float>(sroll); + if(GetValue(spitch, kv, "pp")) + p.p = boost::lexical_cast<float>(spitch); + if(GetValue(syaw, kv, "pa")) + p.a = boost::lexical_cast<float>(syaw); + + if(GetValue(sx, kv, "vx")) + v.x = boost::lexical_cast<float>(sx); + if(GetValue(sy, kv, "vy")) + v.y = boost::lexical_cast<float>(sy); + if(GetValue(sz, kv, "vz")) + v.z = boost::lexical_cast<float>(sz); + if(GetValue(sroll, kv, "vr")) + v.r = boost::lexical_cast<float>(sroll); + if(GetValue(spitch, kv, "vp")) + v.p = boost::lexical_cast<float>(spitch); + if(GetValue(syaw, kv, "va")) + v.a = boost::lexical_cast<float>(syaw); + + if(GetValue(sx, kv, "ax")) + a.x = boost::lexical_cast<float>(sx); + if(GetValue(sy, kv, "ay")) + a.y = boost::lexical_cast<float>(sy); + if(GetValue(sz, kv, "az")) + a.z = boost::lexical_cast<float>(sz); + if(GetValue(sroll, kv, "ar")) + a.r = boost::lexical_cast<float>(sroll); + if(GetValue(spitch, kv, "ap")) + a.p = boost::lexical_cast<float>(spitch); + if(GetValue(syaw, kv, "aa")) + a.a = boost::lexical_cast<float>(syaw); + } + catch(boost::bad_lexical_cast e) + { + response = std::string("Failed to parse input value(s): ") + + e.what(); + return false; + } + + return(SetModelPVA(model, p, v, a, response)); + } + + return false; +} + +void +WebSim::GetPVA(const std::string& name, + Time& t, + const Pose& p, + const Velocity& v, + const Acceleration& a, + Format format, + std::string& response, + void* xmlnode) +{ + if(format == TEXT){ + char buf[1024]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" + " vel : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" + " acc : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", + name.c_str(), + t.String().c_str(), + p.x, p.y, p.z, p.r, p.p, p.a, + v.x, v.y, v.z, v.r, v.p, v.a, + a.x, a.y, a.z, a.r, a.p, a.a); + response = buf; + + }else if (format == XML){ + + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; + + if(xmlnode == NULL){ + + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr) xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "PVA", NULL); + //root_node = (xmlNodePtr)parent; + } + + + + + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "pva"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); + + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",v.x, v.y, v.z, v.r, v.p, v.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlNewProp(node, BAD_CAST "Velocity", BAD_CAST tmp); + + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",a.x, a.y, a.z, a.r, a.p, a.a); + tmp = ConvertInput(str, MY_ENCODING); + xmlNewProp(node, BAD_CAST "Acceleration", BAD_CAST tmp); + + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } + } + +} + + +void +WebSim::GetLaserData(const std::string& name, + Time& t, + uint32_t& resolution, + double& fov, + Pose& p, + std::vector<double>& ranges, + Format format, + std::string& response, + void* xmlnode) +{ + if(format == TEXT){ + + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + + char buf[4096]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n laser: (%s)\n resolution: (%d)\n fov(%.2f)\n" + " pose (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", + name.c_str(), + t.String().c_str(), + res.c_str(), + resolution, + fov, + p.x,p.y,p.z,p.r,p.p,p.a); + response = buf; + + }else if(format == XML){ + + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; + + if(xmlnode == NULL){ + puts("no parent\n"); + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr) xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Laser", NULL); + //root_node = (xmlNodePtr)parent; + } + + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + + + xmlNewProp(node, BAD_CAST "Time", BAD_CAST t.String().c_str()); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "laser"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + + sprintf(str,"%d",resolution); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Resolution", BAD_CAST tmp); + + sprintf(str,"%.3f",fov); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "FOV", BAD_CAST tmp); + + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); + + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); + + + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); + + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } + + + + + } +} + +void +WebSim::GetRangerData(const std::string& name, + Time& t, + std::vector<Pose>& p, + std::vector<double>& ranges, + Format format, + std::string& response, + void* xmlnode) +{ + if(format == TEXT){ + + std::string res; + char temp[128]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + std::string pstr; + char ptmp[256]; + for(unsigned int i=0;i<p.size();i++){ + Pose pos = p.at(i); + sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", + pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); + pstr.append(ptmp); + + } + + char buf[2048]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n ranger\n ranges: (%s)\n pose: %s", + name.c_str(), + t.String().c_str(), + res.c_str(), + pstr.c_str()); + response = buf; + + }else if(format == XML){ + + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; + + if(xmlnode == NULL){ + puts("no parent\n"); + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr)xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); + //root_node = (xmlNodePtr)parent; + } + + + std::string res; + char temp[1024]; + for(unsigned int i=0;i<ranges.size();i++){ + sprintf(temp,"%.3f",ranges.at(i)); + res.append(temp); + if(i+1 != ranges.size()) + res.append(","); + } + + std::string pstr; + char ptmp[2048]; + for(unsigned int i=0;i<p.size();i++){ + Pose pos = p.at(i); + sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", + pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); + pstr.append(ptmp); + } + + //xmlNodePtr node = xmlNewChild(root_node, NULL, BAD_CAST "Ranger", NULL); + + + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "ranger"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); + + tmp = ConvertInput(pstr.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Positions", BAD_CAST tmp); + + + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); + + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } + + + } + +} + +void +WebSim::GetFiducialData(const std::string& name, + Time& t, + std::vector<Fiducial>& f, + Format format, + std::string& response, + void* xmlnode ) +{ + + + if(format == TEXT){ + + std::string res; + char temp[512]; + for(unsigned int i=0;i<f.size();i++){ + sprintf(temp,"((%.3f,%.3f,%.3f),(%.3f,%.3f,%.3f),%d)\n", f.at(i).pos.x, f.at(i).pos.y, f.at(i).pos.z, + f.at(i).pos.r, f.at(i).pos.p, f.at(i).pos.a, f.at(i).id); + res.append(temp); + + } + + + char buf[2048]; + snprintf(buf, sizeof(buf), + "%s's state @%s: \n Fiducial:\n", + name.c_str(), + t.String().c_str()); + + response = buf; + response.append(res); + + }else if(format == XML){ + + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; + + if(xmlnode == NULL){ + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); + }else{ + node = (xmlNodePtr)xmlnode; + xmlNodeSetName(node, xmlCharStrdup("Model")); + //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); + //root_node = (xmlNodePtr)parent; + } + + + std::string res; + char temp[512]; + for(unsigned int i=0;i<f.size();i++){ + sprintf(temp,"((%.3f,%.3f,%.3f),(%.3f,%.3f,%.3f),%d)", f.at(i).pos.x, f.at(i).pos.y, f.at(i).pos.z, + f.at(i).pos.r, f.at(i).pos.p, f.at(i).pos.a, f.at(i).id); + res.append(temp); + + } + + + sprintf(str,"%s",t.String().c_str()); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "fiducial"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + + tmp = ConvertInput(res.c_str(), MY_ENCODING); + xmlNewProp(node, BAD_CAST "Targets", BAD_CAST tmp); + + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); + + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } + + + } + +} + +void +WebSim::GetGeometryData(const std::string& name, + double& x, + double& y, + double& z, + Pose& center, + Format format, + std::string& response, + void* xmlnode) +{ + if(format == TEXT){ + char buf[1024]; + if(name == "sim") + snprintf(buf, sizeof(buf),"World Size: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", + x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); + else + snprintf(buf, sizeof(buf),"%s's Size: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", + name.c_str(), x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); + + response = buf; + }else if(format == XML){ + + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlNodePtr node; + xmlChar *tmp; + char str[128]; + + if(xmlnode == NULL){ + doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(NULL, BAD_CAST "root"); + xmlDocSetRootElement(doc, root_node); + node = xmlNewChild(root_node, NULL, BAD_CAST "ModelGeometry", NULL); + }else{ + node = (xmlNodePtr)xmlnode; + xmlNodeSetName(node, xmlCharStrdup("ModelGeometry")); + } + + + xmlNewProp(node, BAD_CAST "Type", BAD_CAST "geometry"); + + tmp = ConvertInput(name.c_str(),MY_ENCODING); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); + + sprintf(str,"%.3f",x); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "X", BAD_CAST tmp); + + sprintf(str,"%.3f",y); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Y", BAD_CAST tmp); + + sprintf(str,"%.3f",z); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Z", BAD_CAST tmp); + + sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",center.x,center.y,center.z,center.r,center.p,center.a); + tmp = ConvertInput(str,MY_ENCODING); + xmlNewProp(node, BAD_CAST "Origin", BAD_CAST tmp); + + + if(xmlnode == NULL){ + xmlBufferPtr buf = xmlBufferCreate(); + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc,node, 0, 1); + + response = (const char*) buf->content; + puts(response.c_str()); + xmlBufferFree(buf); + xmlFreeDoc(doc); + } + } + +} + +bool +WebSim::GetModelTree(const std::string& model,Format format, std::string& response, bool everything){ + + if(format == XML){ + xmlNodePtr root_node = NULL; + xmlDocPtr doc = NULL; + xmlBufferPtr buf; + + doc = xmlNewDoc(BAD_CAST "1.0"); + buf = xmlBufferCreate(); + root_node = xmlNewNode(NULL, BAD_CAST "ModelTree"); + xmlDocSetRootElement(doc, root_node); + + if(GetModelTreeXML(model, root_node, everything)){ + + xmlKeepBlanksDefault(0); + xmlNodeDump(buf, doc, root_node, 0, 1); + response = (const char*) buf->content; + }else{ + response = "Error in generating model tree.\n"; + + } + + xmlBufferFree(buf); + xmlFreeDoc(doc); + + std::string out = "Model Tree:\n " + response + "\n"; + puts(out.c_str()); + + return true; + + }else if(format == TEXT){ + + std::string str,type; + GetModelType(model, type); + str+= model + "("+type+")"+ "\n"; + std::vector<std::string> children; + GetModelChildren(model, children); + for(unsigned int i=0; i<children.size(); i++){ + + std::string sub; + GetModelTree(children[i], TEXT, sub, false); + str += sub + "\n"; + } + + response = str; + return false; + } + + return false; +} + +bool +WebSim::GetModelTreeXML(const std::string& model, void* xmlparent, bool everything){ + + std::string res; + xmlNodePtr node; + + if(!xmlparent){ + printf("Invalid xmlNode pointer. \n"); + return false; + } + + if(model != ""){ + + node = xmlNewChild((xmlNodePtr)xmlparent, NULL, BAD_CAST "Model", NULL); + + bool flag = false; + std::string type; + + if(everything){ + std::string error; + flag = !GetModelData(model, error, XML, node); + + } + + if(!everything || flag){ + + GetModelType(model, type); + xmlNodeSetName(node, xmlCharStrdup("Model")); + xmlNewProp(node, BAD_CAST "Name", BAD_CAST model.c_str()); + xmlNewProp(node, BAD_CAST "Type", BAD_CAST type.c_str()); + } + + }else + node = (xmlNodePtr) xmlparent; + + std::vector<std::string> children; + GetModelChildren(model, children); + for(unsigned int i=0;i<children.size();i++) + GetModelTreeXML(children[i], node, everything); + + + + return true; + +} Modified: code/websim/src/req_sim.cc =================================================================== --- code/websim/src/req_sim.cc 2009-06-29 19:35:46 UTC (rev 7929) +++ code/websim/src/req_sim.cc 2009-06-29 22:58:45 UTC (rev 7930) @@ -36,7 +36,7 @@ if(prop == "viz") return HandleSimVisualizationRequest( action, format, kv, response ); - response = "ERROR: Unknown property " + prop + " for sim. Candidates are: children clock factory greet tree."; + response = "ERROR: Unknown property " + prop + " for sim. Candidates are: clock factory greet tree."; return false; } Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-06-29 19:35:46 UTC (rev 7929) +++ code/websim/src/websim.cc 2009-06-29 22:58:45 UTC (rev 7930) @@ -33,11 +33,10 @@ #include <stdlib.h> #include <string.h> #include <libxml/encoding.h> -//#include <libxml/xmlwriter.h> -//#include <libxml/tree.h> -#define MY_ENCODING "ISO-8859-1" + + using namespace websim; const std::string WebSim::package = "WebSim"; @@ -60,8 +59,6 @@ "src=\"http://192.168.1.210/viz.html\"></iframe></BODY></HTML>"; -xmlChar * -ConvertInput(const char *in, const char *encoding); std::string Time::String() { @@ -246,724 +243,6 @@ - - -bool -WebSim::HandleModelRequest(const std::string& model, - const std::string& prop, - const std::string& action, - Format format, - struct evkeyvalq* kv, - std::string& response) -{ - if(action == "get") - { - if(prop == "data" || prop == ""){ - - return(GetModelData(model, response, format, NULL)); - - }else if(prop == "pva"){ - Pose p; - Velocity v; - Acceleration a; - Time t; - if(GetModelPVA(model, t, p, v, a, response)){ - - GetPVA(model, t, p, v, a, format, response, NULL); - return true; - } - else - return false; - - }else if(prop == "children"){ - std::vector<std::string> children; - GetModelChildren(model,children); - - for(unsigned int i=0;i<children.size();i++) - response += children[i] + "\n"; - - return true; - - }else if(prop == "tree"){ - - - return(GetModelTree(model, format, response, false)); - - - }else if(prop == "geometry"){ - double x,y,z; - Pose center; - if(GetModelGeometry(model, x, y, z, center, response)) - { - - GetGeometryData(model, x, y, z, center, format, response, NULL); - return true; - - }else{ - - response = "ERROR: failed to get the extent of model " + model; - return false; - - } - }else{ - response = "ERROR: Unknown property " + prop + " for model " + model; - return false; - } - - - }else if(action == "set") - { - if(prop == "pva") - { - std::string sx, sy, sz, sroll, spitch, syaw; - - // Get pose first, fill in what the caller provided - Pose p; - Velocity v; - Acceleration a; - Time t; - if(!GetModelPVA(model, t, p, v, a, response)) - { - response = "Failed to get pose before setting it"; - return false; - } - try - { - if(GetValue(sx, kv, "px")) - p.x = boost::lexical_cast<float>(sx); - if(GetValue(sy, kv, "py")) - p.y = boost::lexical_cast<float>(sy); - if(GetValue(sz, kv, "pz")) - p.z = boost::lexical_cast<float>(sz); - if(GetValue(sroll, kv, "pr")) - p.r = boost::lexical_cast<float>(sroll); - if(GetValue(spitch, kv, "pp")) - p.p = boost::lexical_cast<float>(spitch); - if(GetValue(syaw, kv, "pa")) - p.a = boost::lexical_cast<float>(syaw); - - if(GetValue(sx, kv, "vx")) - v.x = boost::lexical_cast<float>(sx); - if(GetValue(sy, kv, "vy")) - v.y = boost::lexical_cast<float>(sy); - if(GetValue(sz, kv, "vz")) - v.z = boost::lexical_cast<float>(sz); - if(GetValue(sroll, kv, "vr")) - v.r = boost::lexical_cast<float>(sroll); - if(GetValue(spitch, kv, "vp")) - v.p = boost::lexical_cast<float>(spitch); - if(GetValue(syaw, kv, "va")) - v.a = boost::lexical_cast<float>(syaw); - - if(GetValue(sx, kv, "ax")) - a.x = boost::lexical_cast<float>(sx); - if(GetValue(sy, kv, "ay")) - a.y = boost::lexical_cast<float>(sy); - if(GetValue(sz, kv, "az")) - a.z = boost::lexical_cast<float>(sz); - if(GetValue(sroll, kv, "ar")) - a.r = boost::lexical_cast<float>(sroll); - if(GetValue(spitch, kv, "ap")) - a.p = boost::lexical_cast<float>(spitch); - if(GetValue(syaw, kv, "aa")) - a.a = boost::lexical_cast<float>(syaw); - } - catch(boost::bad_lexical_cast e) - { - response = std::string("Failed to parse input value(s): ") + - e.what(); - return false; - } - - return(SetModelPVA(model, p, v, a, response)); - } - else - { - response = "ERROR: Unknown property " + prop + " for model " + model; - return false; - } - } - else - { - response = "ERROR: Unknown action " + action; - return false; - } - - return false; -} - - - - -void -WebSim::GetPVA(const std::string& name, - Time& t, - const Pose& p, - const Velocity& v, - const Acceleration& a, - Format format, - std::string& response, - void* xmlnode) -{ - if(format == TEXT){ - char buf[1024]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n pose: (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" - " vel : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n" - " acc : (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", - name.c_str(), - t.String().c_str(), - p.x, p.y, p.z, p.r, p.p, p.a, - v.x, v.y, v.z, v.r, v.p, v.a, - a.x, a.y, a.z, a.r, a.p, a.a); - response = buf; - - }else if (format == XML){ - - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; - - if(xmlnode == NULL){ - - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr) xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "PVA", NULL); - //root_node = (xmlNodePtr)parent; - } - - - - - sprintf(str,"%s",t.String().c_str()); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "pva"); - - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); - tmp = ConvertInput(str, MY_ENCODING); - xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); - - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",v.x, v.y, v.z, v.r, v.p, v.a); - tmp = ConvertInput(str, MY_ENCODING); - xmlNewProp(node, BAD_CAST "Velocity", BAD_CAST tmp); - - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",a.x, a.y, a.z, a.r, a.p, a.a); - tmp = ConvertInput(str, MY_ENCODING); - xmlNewProp(node, BAD_CAST "Acceleration", BAD_CAST tmp); - - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } - } - -} - - -void -WebSim::GetLaserData(const std::string& name, - Time& t, - uint32_t& resolution, - double& fov, - Pose& p, - std::vector<double>& ranges, - Format format, - std::string& response, - void* xmlnode) -{ - if(format == TEXT){ - - std::string res; - char temp[128]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } - - - char buf[4096]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n laser: (%s)\n resolution: (%d)\n fov(%.2f)\n" - " pose (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", - name.c_str(), - t.String().c_str(), - res.c_str(), - resolution, - fov, - p.x,p.y,p.z,p.r,p.p,p.a); - response = buf; - - }else if(format == XML){ - - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; - - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr) xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Laser", NULL); - //root_node = (xmlNodePtr)parent; - } - - std::string res; - char temp[128]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } - - - - xmlNewProp(node, BAD_CAST "Time", BAD_CAST t.String().c_str()); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "laser"); - - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - - sprintf(str,"%d",resolution); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Resolution", BAD_CAST tmp); - - sprintf(str,"%.3f",fov); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "FOV", BAD_CAST tmp); - - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",p.x, p.y, p.z, p.r, p.p, p.a); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Pose", BAD_CAST tmp); - - tmp = ConvertInput(res.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); - - - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); - - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } - - - - - } -} - -void -WebSim::GetRangerData(const std::string& name, - Time& t, - std::vector<Pose>& p, - std::vector<double>& ranges, - Format format, - std::string& response, - void* xmlnode) -{ - if(format == TEXT){ - - std::string res; - char temp[128]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } - - std::string pstr; - char ptmp[256]; - for(unsigned int i=0;i<p.size();i++){ - Pose pos = p.at(i); - sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", - pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); - pstr.append(ptmp); - - } - - char buf[2048]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n ranger\n ranges: (%s)\n pose: %s", - name.c_str(), - t.String().c_str(), - res.c_str(), - pstr.c_str()); - response = buf; - - }else if(format == XML){ - - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; - - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr)xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); - //root_node = (xmlNodePtr)parent; - } - - - std::string res; - char temp[1024]; - for(unsigned int i=0;i<ranges.size();i++){ - sprintf(temp,"%.3f",ranges.at(i)); - res.append(temp); - if(i+1 != ranges.size()) - res.append(","); - } - - std::string pstr; - char ptmp[2048]; - for(unsigned int i=0;i<p.size();i++){ - Pose pos = p.at(i); - sprintf(ptmp," (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)", - pos.x,pos.y,pos.x,pos.r,pos.p,pos.a); - pstr.append(ptmp); - } - - //xmlNodePtr node = xmlNewChild(root_node, NULL, BAD_CAST "Ranger", NULL); - - - sprintf(str,"%s",t.String().c_str()); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "ranger"); - - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - - tmp = ConvertInput(res.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Samples", BAD_CAST tmp); - - tmp = ConvertInput(pstr.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Positions", BAD_CAST tmp); - - - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); - - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } - - - } - -} - -void -WebSim::GetFiducialData(const std::string& name, - Time& t, - std::vector<Fiducial>& f, - Format format, - std::string& response, - void* xmlnode ) -{ - - - if(format == TEXT){ - - std::string res; - char temp[512]; - puts("here1\n"); - for(unsigned int i=0;i<f.size();i++){ - sprintf(temp,"((%.3f,%.3f,%.3f),(%.3f,%.3f,%.3f),%d)\n", f.at(i).pos.x, f.at(i).pos.y, f.at(i).pos.z, - f.at(i).pos.r, f.at(i).pos.p, f.at(i).pos.a, f.at(i).id); - puts("here2\n"); - res.append(temp); - - } - - puts("here3\n"); - - char buf[2048]; - snprintf(buf, sizeof(buf), - "%s's state @%s: \n Fiducial:\n", - name.c_str(), - t.String().c_str()); - - response = buf; - response.append(res); - - }else if(format == XML){ - - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; - - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "Model", NULL); - }else{ - node = (xmlNodePtr)xmlnode; - xmlNodeSetName(node, xmlCharStrdup("Model")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "Ranger", NULL); - //root_node = (xmlNodePtr)parent; - } - - - std::string res; - char temp[512]; - for(unsigned int i=0;i<f.size();i++){ - sprintf(temp,"((%.3f,%.3f,%.3f),(%.3f,%.3f,%.3f),%d)", f.at(i).pos.x, f.at(i).pos.y, f.at(i).pos.z, - f.at(i).pos.r, f.at(i).pos.p, f.at(i).pos.a, f.at(i).id); - res.append(temp); - - } - - - sprintf(str,"%s",t.String().c_str()); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Time", BAD_CAST tmp); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "fiducial"); - - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - - tmp = ConvertInput(res.c_str(), MY_ENCODING); - xmlNewProp(node, BAD_CAST "Targets", BAD_CAST tmp); - - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); - - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } - - - } - -} - -void -WebSim::GetGeometryData(const std::string& name, - double& x, - double& y, - double& z, - Pose& center, - Format format, - std::string& response, - void* xmlnode) -{ - if(format == TEXT){ - char buf[1024]; - if(name == "sim") - snprintf(buf, sizeof(buf),"World Size: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", - x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); - else - snprintf(buf, sizeof(buf),"%s's Size: (%.3f,%.3f,%.3f)\n Origin (%.3f,%.3f,%.3f,%.3f,%.3f,%.3f)", - name.c_str(), x, y, z, center.x, center.y, center.z, center.r, center.p, center.a); - - response = buf; - }else if(format == XML){ - - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlNodePtr node; - xmlChar *tmp; - char str[128]; - - if(xmlnode == NULL){ - puts("no parent\n"); - doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(NULL, BAD_CAST "root"); - xmlDocSetRootElement(doc, root_node); - node = xmlNewChild(root_node, NULL, BAD_CAST "ModelGeometry", NULL); - }else{ - node = (xmlNodePtr)xmlnode; - xmlNodeSetName(node, xmlCharStrdup("ModelGeometry")); - //node = xmlNewChild((xmlNodePtr)parent, NULL, BAD_CAST "ModelExtent", NULL); - //root_node = (xmlNodePtr)parent; - } - - - xmlNewProp(node, BAD_CAST "Type", BAD_CAST "geometry"); - - tmp = ConvertInput(name.c_str(),MY_ENCODING); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST tmp); - - sprintf(str,"%.3f",x); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "X", BAD_CAST tmp); - - sprintf(str,"%.3f",y); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Y", BAD_CAST tmp); - - sprintf(str,"%.3f",z); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Z", BAD_CAST tmp); - - sprintf(str,"%.3f,%.3f,%.3f,%.3f,%.3f,%.3f",center.x,center.y,center.z,center.r,center.p,center.a); - tmp = ConvertInput(str,MY_ENCODING); - xmlNewProp(node, BAD_CAST "Origin", BAD_CAST tmp); - - - if(xmlnode == NULL){ - xmlBufferPtr buf = xmlBufferCreate(); - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc,node, 0, 1); - - response = (const char*) buf->content; - puts(response.c_str()); - xmlBufferFree(buf); - xmlFreeDoc(doc); - } - } - -} - -bool -WebSim::GetModelTree(const std::string& model,Format format, std::string& response, bool everything){ - - if(format == XML){ - xmlNodePtr root_node = NULL; - xmlDocPtr doc = NULL; - xmlBufferPtr buf; - - doc = xmlNewDoc(BAD_CAST "1.0"); - buf = xmlBufferCreate(); - root_node = xmlNewNode(NULL, BAD_CAST "ModelTree"); - xmlDocSetRootElement(doc, root_node); - - if(GetModelTreeXML(model, root_node, everything)){ - - xmlKeepBlanksDefault(0); - xmlNodeDump(buf, doc, root_node, 0, 1); - response = (const char*) buf->content; - }else{ - response = "Error in generating model tree.\n"; - - } - - xmlBufferFree(buf); - xmlFreeDoc(doc); - - std::string out = "Model Tree:\n " + response + "\n"; - puts(out.c_str()); - - return true; - - }else if(format == TEXT){ - - std::string str,type; - GetModelType(model, type); - str+= model + "("+type+")"+ "\n"; - std::vector<std::string> children; - GetModelChildren(model, children); - for(unsigned int i=0; i<children.size(); i++){ - - std::string sub; - GetModelTree(children[i], TEXT, sub, false); - str += sub + "\n"; - } - - response = str; - return false; - } - - return false; -} - -bool -WebSim::GetModelTreeXML(const std::string& model, void* xmlparent, bool everything){ - - std::string res; - xmlNodePtr node; - - if(!xmlparent){ - printf("Invalid xmlNode pointer. \n"); - return false; - } - - if(model != ""){ - - node = xmlNewChild((xmlNodePtr)xmlparent, NULL, BAD_CAST "Model", NULL); - - bool flag = false; - std::string type; - - if(everything){ - std::string error; - flag = !GetModelData(model, error, XML, node); - - } - - if(!everything || flag){ - - GetModelType(model, type); - xmlNodeSetName(node, xmlCharStrdup("Model")); - xmlNewProp(node, BAD_CAST "Name", BAD_CAST model.c_str()); - xmlNewProp(node, BAD_CAST "Type", BAD_CAST type.c_str()); - } - - }else - node = (xmlNodePtr) xmlparent; - - std::vector<std::string> children; - GetModelChildren(model, children); - for(unsigned int i=0;i<children.size();i++) - GetModelTreeXML(children[i], node, everything); - - - - return true; - -} - xmlChar * ConvertInput(const char *in, const char *encoding) { @@ -1097,74 +376,7 @@ return true; } -// //puts(uri.c_str()); -// // Remove the query args -// std::vector<std::string> uri_parts; -// StringSplit(uri, uri_parts, "?"); -// assert(uri_parts.size() > 0); -// std::string bare_uri = uri_parts[0]; - -// StringSplit(bare_uri, uri_parts, "/"); - -// //puts("parts:"); -// /*for(int j=0;j<uri_parts.size();j++) -// puts(uri_parts[j].c_str()); - -// puts("Here I am!");*/ -// if(uri_parts.size() < 2) -// { -// // return true, then generate the welcome html -// return false; -// } - -// // example: http://localhost:8000/viz -// if(uri_parts.size() ==2){ - -// //puts("1 Here I am!"); -// model = uri_parts[1]; -// prop = ""; -// action = ""; -// //puts("1.1 Here I am!"); -// return true; -// } - - -// // example: http://localhost:8000/viz/applet.class -// if(uri_parts.size() ==3){ - -// //puts("2 Here I am!"); - -// model = uri_parts[1]; -// prop = uri_parts[2]; -// action = ""; -// return true; -// } - -// //puts("3 here I am"); -// unsigned int size = uri_parts.size(); -// unsigned int modelendindex = 0; - -// if(uri_parts[size-1] == "get" || uri_parts[size-1]== "set"){ -// action = uri_parts[size-1]; -// modelendindex = size-3; -// } -// else{ -// action = "get"; -// modelendindex = size-2; -// } - -// prop = uri_parts[modelendindex+1]; - -// for(unsigned int i=1;i <= modelendindex;i++){ -// model += uri_parts[i]; -// if(i!=modelendindex) -// model += "."; -// } - -// return true; - - bool WebSim::SetPuppetPVA( const std::string& name, Pose& p, Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-06-29 19:35:46 UTC (rev 7929) +++ code/websim/src/websim.hh 2009-06-29 22:58:45 UTC (rev 7930) @@ -312,6 +312,30 @@ struct evkeyvalq* kv, std::string& response); + bool HandleModelDataRequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleModelTreeRequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleModelGeometryRequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + + bool HandleModelPVARequest( std::string model, + std::string action, + Format format, + struct evkeyvalq* kv, + std::string& response); + bool ParseURI(std::string& model, std::string& prop, std::string& action, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <as...@us...> - 2009-07-13 20:05:17
|
Revision: 8007 http://playerstage.svn.sourceforge.net/playerstage/?rev=8007&view=rev Author: asadat Date: 2009-07-13 20:05:09 +0000 (Mon, 13 Jul 2009) Log Message: ----------- the visualization applet is added Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/req_sim.cc code/websim/src/websim.cc code/websim/src/websim.hh Added Paths: ----------- code/websim/viz/ code/websim/viz/Main.java code/websim/viz/ReadMe code/websim/viz/java.policy.applet code/websim/viz/visualization.html Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-07-13 16:53:48 UTC (rev 8006) +++ code/websim/CMakeLists.txt 2009-07-13 20:05:09 UTC (rev 8007) @@ -1,5 +1,4 @@ project(WebSim) - SET( V_MAJOR 1 ) SET( V_MINOR 0 ) SET( V_BUGFIX 0 ) @@ -148,4 +147,18 @@ "make" "make install") +INSTALL (FILES README.txt COPYING.txt DESTINATION .) +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "WebSim") +#SET(CPACK_PACKAGE_DESCRIPTION_FILE "/home/abbas/websim/README.txt") +SET(CPACK_RESOURCE_FILE_LICENSE "/home/abbas/websim/COPYING.txt") +SET(CPACK_RESOURCE_FILE_README "/home/abbas/websim/README.txt") +SET(CPACK_PACKAGE_VERSION_MAJOR "0") +SET(CPACK_PACKAGE_VERSION_MINOR "1") +SET(CPACK_PACKAGE_VERSION_PATCH "0") +SET(CPACK_PACKAGE_VERSION "0.1") +SET(CPACK_PACKAGE_VENDOR "Richard Vaughan") +SET(CPACK_NSIS_DISPLAY_NAME "WebSim 0.1") + + +INCLUDE(CPack) Modified: code/websim/src/req_sim.cc =================================================================== --- code/websim/src/req_sim.cc 2009-07-13 16:53:48 UTC (rev 8006) +++ code/websim/src/req_sim.cc 2009-07-13 20:05:09 UTC (rev 8007) @@ -1,4 +1,5 @@ #include "websim.hh" +#include <stdlib.h> using namespace websim; const double TICK_INTERVAL = 1.0; @@ -40,6 +41,14 @@ if(prop == "viz") return HandleSimVisualizationRequest( action, format, kv, response ); + if(prop == "applet"){ + + + + + return true; + } + response = "ERROR: Unknown property " + prop + " for sim. Candidates are: clock factory greet tree."; return false; } @@ -49,12 +58,14 @@ struct evkeyvalq* kv, std::string& response) { + response = "<HTML><HEAD><TITLE>Websim Visualization</TITLE></HEAD>" "<BODY><iframe id=\"visualization\" frameborder=0 width=\"1000\" height=\"1000\" " "src=\"viz.html\"></iframe></BODY></HTML>"; return true; + } bool WebSim::HandleSimHomepageRequest( std::string action, Modified: code/websim/src/websim.cc =================================================================== --- code/websim/src/websim.cc 2009-07-13 16:53:48 UTC (rev 8006) +++ code/websim/src/websim.cc 2009-07-13 20:05:09 UTC (rev 8007) @@ -38,6 +38,7 @@ const std::string WebSim::package = "WebSim"; const std::string WebSim::version = "0.1"; + std::string Time::String() { std::string seconds = boost::lexical_cast<std::string>(sec); @@ -305,7 +306,6 @@ response_string = "OK"; } - //puts(response.c_str()); evbuffer_add_printf(eb, "%s\n", response.c_str()); evhttp_send_reply(req, response_code, response_string.c_str(), eb); @@ -330,6 +330,7 @@ // We require 3 path components: model/property/action StringSplit(bare_uri, uri_parts, "/"); + //check if the web page is requested if(uri_parts.size()==2){ Modified: code/websim/src/websim.hh =================================================================== --- code/websim/src/websim.hh 2009-07-13 16:53:48 UTC (rev 8006) +++ code/websim/src/websim.hh 2009-07-13 20:05:09 UTC (rev 8007) @@ -105,9 +105,11 @@ */ virtual bool ClockRunFor( double seconds )=0; + /** Create a model of the specified type */ virtual bool CreateModel(const std::string& name, const std::string& type, std::string& response) = 0; + /** Delete the specified model */ virtual bool DeleteModel(const std::string& name, std::string& response) = 0; @@ -665,10 +667,8 @@ { public: Pose pos; - double range; - double bearing; int id; - Fiducial():range(0),bearing(0),id(-1){} + Fiducial():id(-1){} }; Added: code/websim/viz/Main.java =================================================================== --- code/websim/viz/Main.java (rev 0) +++ code/websim/viz/Main.java 2009-07-13 20:05:09 UTC (rev 8007) @@ -0,0 +1,1212 @@ +/** + This program is for visualizing the webstage data. Requests for model tree, robots and their devices are sent to a server and the xml responses are parsed and visualized in this applet. The program will be run via an HTML page. +*/ + +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.net.URLConnection; +import java.net.URL; +import org.w3c.dom.Document; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.xml.sax.*; +import javax.swing.tree.*; +import java.util.*; +import org.xml.sax.helpers.*; +import javax.xml.parsers.*; + +/** + * This is the main class. 2 panels and an applet are created. "treepanel" contains a scrollpanel which has the model tree in it. "values" contains the checkboxes that + * determine which features should show up on the screen. The text field in "values" panel, determines the server address. The default server address is "192.168.1.210:8000". + * "mixture" is a Stage-like applet by which robots and their devices can be monitored. + * + * Parts of the code are from "http://www.developer.com/net/vb/article.php/626261" + */ +public class Main extends Applet implements Runnable{ + + Panel treepanel; + Panel values; + //Panel leftPanel; + StageApplet mixture; + private TextField host_address_textfield; + private Button submitButton; + + private final JCheckBoxMenuItem check1=new JCheckBoxMenuItem("position", true) ; + private final JCheckBoxMenuItem check2=new JCheckBoxMenuItem("laser", true) ; + private final JCheckBoxMenuItem check3=new JCheckBoxMenuItem("sonar", false) ; + private final JCheckBoxMenuItem check4=new JCheckBoxMenuItem("fiducial", false) ; + private final JCheckBoxMenuItem check5=new JCheckBoxMenuItem("sayings", false) ; + + JTree tree; + JScrollPane scrollPanel; + + public void init() + { + BorderLayout thisBorderLayout=new BorderLayout(); + thisBorderLayout.setHgap(20); + setLayout(thisBorderLayout); + this.setSize(new Dimension(900,900)); + + + try{ + mixture = (StageApplet)addApplet("StageApplet"); + mixture.mainApp=this; + + }catch(Exception e){ + e.printStackTrace(); + } + + host_address_textfield = new TextField("192.168.1.210:8000"); + host_address_textfield.setSize(100,25); + + submitButton = new Button("Send Request"); + submitButton.setSize(100,25); + submitButton.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent evt) { + try { + mixture.host_address = host_address_textfield.getText(); + mixture.address_changed=true; + } + catch (Exception e){ + System.out.println("Error reading host address: " +e.getMessage()); + }}}); + + check1.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent evt) { + if(check1.getSelectedObjects()!=null) + mixture.show_position=true; + else + mixture.show_position=false; + }}); + check2.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent evt) { + if(check2.getSelectedObjects()!=null) + mixture.show_laser=true; + else + mixture.show_laser=false; + }}); + check3.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent evt) { + if(check3.getSelectedObjects()!=null) + mixture.show_sonar=true; + else + mixture.show_sonar=false; + }}); + check4.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent evt) { + if(check4.getSelectedObjects()!=null) + mixture.show_fiducial=true; + else + mixture.show_fiducial=false; + }}); + check5.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent evt) { + if(check5.getSelectedObjects()!=null) + mixture.show_sayings=true; + else + mixture.show_sayings=false; + }}); + + values = new Panel(); + FlowLayout layout=new FlowLayout(); + values.setLayout(layout); + + + values.add(host_address_textfield); + values.add(submitButton); + check1.setSize(100,25); + check2.setSize(100,25); + check3.setSize(100,25); + check4.setSize(100,25); + values.add(check1); + values.add(check2); + values.add(check3); + values.add(check4); + + //leftPanel =new Panel(); + //leftPanel.setLayout(new BorderLayout()); + add(values,BorderLayout.NORTH); + + //add(leftPanel,BorderLayout.WEST); + + add(mixture); +// mixture.start(); + + treepanel=new Panel(); + tree = mixture.tree; + + + if(tree!=null) + scrollPanel=new JScrollPane(tree); + else + scrollPanel=new JScrollPane(); + + scrollPanel.setPreferredSize(new Dimension(200,600)); + treepanel.add(scrollPanel, BorderLayout.CENTER); + + + treepanel.setVisible(true); + treepanel.setLocation(100,400); + treepanel.setPreferredSize(new Dimension(200,600)); + //leftPanel.add(treepanel,BorderLayout.CENTER); + add(treepanel,BorderLayout.WEST); + + } + + + public void run(){ + repaint(); + } + + public void update(Graphics g) { + paint(g); + } + + public void paint(Graphics g){ + + super.paint(g); + } + + public Vector applets = new Vector(); + + public void addApplet( Applet applet ) { + // Create a new, "artificial" stub for the subapplet + AppletStub stub = new MultiAppletStub( this ); + // Give it to the subapplet to use + applet.setStub( stub ); + // Start up the subapplet + applet.init(); + // Finally, store it in our list + applets.addElement( applet ); + } + + public Applet addApplet( String className ) + throws ClassNotFoundException, IllegalAccessException, + InstantiationException { + // Create an instance of the named applet + Class clas = Class.forName( className ); + Applet applet = (Applet)clas.newInstance(); + // Add it to the system + addApplet( applet ); + // Return it, in case the caller wants to access the Applet + // object directly + return applet; + } + + public void start() { + for (Enumeration e=applets.elements(); e.hasMoreElements();) { + ((Applet)e.nextElement()).start(); + } + } + + public void stop() { + for (Enumeration e=applets.elements(); e.hasMoreElements();) { + ((Applet)e.nextElement()).stop(); + } + } + + public void destroy() { + for (Enumeration e=applets.elements(); e.hasMoreElements();) { + ((Applet)e.nextElement()).destroy(); + } + } + + public void appletResize( int width, int height ) { + + } + } + + class MultiAppletStub implements AppletStub + { + private Applet applet; + + public MultiAppletStub( Applet applet ) { + this.applet = applet; + } + + public boolean isActive() { + return applet.isActive(); + } + + public URL getDocumentBase() { + return applet.getDocumentBase(); + } + + public URL getCodeBase() { + return applet.getCodeBase(); + } + + public String getParameter( String name ) { + return applet.getParameter( name ); + } + + public AppletContext getAppletContext() { + return applet.getAppletContext(); + } + + public void appletResize( int width, int height ) { + } + } + + /** + * This is the Stage-like applet class. It sends a request for the model tree, and for each of the robots in that tree, will send out requests for each of their devices + * indicated in the model tree. Then based on the check boxes selected in the main applet, corresponding features of the robots would be drawn. + */ + class StageApplet extends Applet implements Runnable{ + + Main mainApp; + + int frame; + int delay; + //Size and coordinates of the map. + int boardSize=512, boardX=100, boardY=100; + Thread animator; + + Image scrnBuf; + Graphics scrnG; + Dimension dim; + + boolean address_changed=false; + + //The server address, default address is "192.168.1.210:8000" + String host_address="192.168.1.210:8000"; + + String time=""; + //Based on the checkboxes in the main applet, these variables will be true or false meaning whether that feature should be drawn or not. + boolean show_position=true, show_laser=true, show_sonar=false, show_fiducial=false, show_sayings=false; + + //Content handler for the model tree. + TreeSink sink2; + //Content handler for position and device requests. + Sink sink; + //All the robots indicated in the model tree. + ArrayList<Robot> robots; + TreeBuilder jsamp; + //The model tree. + JTree tree; + + TreePath[] paths; + Object[][] pathComponents; + + XMLReader reader,reader2; + + public void addNotify() { + super.addNotify(); + robots=new ArrayList<Robot>(); + scrnBuf = createImage(1000, 1000); + if(scrnBuf==null){ + System.out.println("Image Null"); + } + scrnG = scrnBuf.getGraphics(); + sink2=new TreeSink(this); + sink=new Sink(); + try{ + reader2 = XML.makeXMLReader(); + + reader2.setContentHandler( sink2 ); + reader2.parse( new InputSource( new URL("http://"+host_address+"/sim/tree/get?format=xml").openStream() )); + jsamp=new TreeBuilder(); + tree=jsamp.makeTree(sink2.arraylist, 1,0); + + reader = XML.makeXMLReader(); + reader.setContentHandler( sink ); + }catch(Exception e){ + e.printStackTrace(); + scrnG.drawString(e.getMessage(), 5, 130); + } + } + + public void init() { + super.init(); + try{ + dim=this.getSize(); + boardSize=Math.min(dim.height, dim.width)-200; + + }catch(Exception e){ + e.printStackTrace(); + scrnG.drawString(e.getMessage(), 5, 120); + } + int fps=10; + delay = (fps > 0) ? (1000 / fps) : 300; + + + } + + + public void start() { + try{ + /*reader2 = XML.makeXMLReader(); + reader2.setContentHandler( sink2 ); + reader2.parse( new InputSource( new URL("http://"+host_address+"/sim/tree/get?format=xml").openStream() )); + jsamp=new TreeBuilder(); + tree=jsamp.makeTree(sink2.arraylist, 1,0); + + reader = XML.makeXMLReader(); + reader.setContentHandler( sink );*/ + }catch(Exception e){ + e.printStackTrace(); + } + animator = new Thread(this); + animator.start(); + } + + public void run() { + + // Remember the starting time + long tm = System.currentTimeMillis(); + while (Thread.currentThread() == animator) { + // Display the next frame of animation. + repaint(); + + // Delay depending on how far we are behind. + try { + tm += delay; + Thread.sleep(Math.max(0, tm - System.currentTimeMillis())); + } catch (InterruptedException e) { + break; + } + + // Advance the frame + frame++; + } + } + + public void stop() { + animator = null; + } + + public void paint(Graphics g) { + if(address_changed){ + if(robots!=null) + robots.clear(); + if(sink2.arraylist!=null) + sink2.arraylist.clear(); + try{ + reader2.parse( new InputSource( new URL("http://"+host_address+"/sim/tree/get?format=xml").openStream() )); + jsamp=new TreeBuilder(); + tree=jsamp.makeTree(sink2.arraylist, 1,0); + reader = XML.makeXMLReader(); + reader.setContentHandler( sink ); + + if(tree!=null){ + mainApp.tree=tree; + mainApp.scrollPanel.setViewportView(tree); + mainApp.treepanel.add(mainApp.scrollPanel, BorderLayout.CENTER); + mainApp.treepanel.setVisible(true); + } + mainApp.add(mainApp.treepanel,BorderLayout.WEST); + mainApp.run(); + + }catch(Exception e){ + e.printStackTrace(); + } + address_changed=false; + } + scrnG.clearRect(0, 0, dim.height, dim.width); + dim=this.getSize(); + boardSize=Math.min(dim.height, dim.width)-200; + boardX=dim.width/7; + boardY=dim.height/8; + scrnG.setColor(new Color(110,110,110)); + scrnG.fillRect(boardX-100, boardY-100, boardSize+200, boardSize+200); + scrnG.setColor(Color.white); + scrnG.fillRect(boardX, boardY, boardSize, boardSize); + scrnG.setColor(Color.black); +// String response=getResponseText(); + scrnG.drawString(sink.time, boardX-40, boardY+boardSize+60); + + //For each of the robots, + for(int s=0;s<robots.size();s++){ + + if(robots.get(s)==null){ + robots.remove(s); + s--; + } + Robot current=robots.get(s); + current.selected=current.laserSelected=current.sonarSelected=current.fiducialSelected=false; + //Determine if the robot and/or any of its devices are selected on the tree + if(paths!=null && pathComponents!=null){ + for(int is=0;is<pathComponents.length;is++){ + for(int js=0;js<pathComponents[is].length;js++){ + if(pathComponents[is][js].toString().contains(current.name)){ + if(paths[is].getLastPathComponent().toString().equals(current.name)) + current.selected=true; + if(paths[is].getLastPathComponent().toString().contains("laser")) + current.laserSelected=true; + if(paths[is].getLastPathComponent().toString().contains("ranger")) + current.sonarSelected=true; + if(paths[is].getLastPathComponent().toString().contains("fiducial")) + current.fiducialSelected=true; + } + } + } + } + try{ + //Send the request for pva + InputStream pva_input_stream=new URL ( "http://"+host_address+"/"+current.name+"/pva/get?format=xml").openStream ( ); + reader.parse( new InputSource( pva_input_stream )); +// Send the request for laser + InputStream laser_input_stream=new URL ( "http://"+host_address+"/"+current.laserName/*.replace('.', '/')*/+"/data/get?format=xml").openStream ( ); + reader.parse( new InputSource( laser_input_stream )); +// Send the request for ranger + InputStream sonar_input_stream=new URL ( "http://"+host_address+"/"+current.sonarName/*.replace('.', '/')*/+"/data/get?format=xml").openStream ( ); + reader.parse( new InputSource( sonar_input_stream )); +// Send the request for fiducial + InputStream fiducial_input_stream=new URL ( "http://"+host_address+"/"+current.fiducialName/*.replace('.', '/')*/+"/data/get?format=xml").openStream ( ); + reader.parse( new InputSource( fiducial_input_stream )); + current.laser_fov=sink.robot.laser_fov; + current.laser_resol=sink.robot.laser_resol; + current.sonar_fov=sink.robot.sonar_fov; + current.laser_sampleCount=sink.robot.laser_sampleCount; + current.sonar_sampleCount=sink.robot.sonar_sampleCount; + current.pose=sink.robot.pose; + current.samples=sink.robot.samples; + current.sonar=sink.robot.sonar; + current.sonar_pairs=sink.robot.sonar_pairs; + current.fiducial=sink.robot.fiducial; + current.fiducial_sampleCount=sink.robot.fiducial_sampleCount; + + }catch(Exception e){ + e.printStackTrace(); + } + if(current!=null && current.pose!=null){ + // If the checkbox for position is selected in the main applet, draw the robots. + if(show_position) + drawRobot(current.pose.x,current.pose.y,current.pose.a,current); + //If the checkbox for laser is selected in the main applet, draw the laser beams. + if(show_laser && current.hasLaser) + drawLaser(current); + //If the checkbox for ranger is selected in the main applet, draw the sonar beams. + if(show_sonar && current.hasRanger) + drawSonar(current); + //If the checkbox for fiducial is selected in the main applet, draw the fiducials. + if(show_fiducial && current.hasFiducial && current.fiducial!=null) + drawFiducial(current); + + } + else{ + scrnG.drawString( "Robot Null", 5,140); + super.paint(g); + } + } + g.drawImage(scrnBuf, 0 , 0 , this); + } + + public void update(Graphics g) { + paths=null; + pathComponents=null; + if(tree!=null) + paths=tree.getSelectionPaths(); + if(paths!=null && paths.length>0){ + pathComponents=new Object[paths.length][]; + for(int i=0;i<paths.length;i++) + pathComponents[i]=paths[i].getPath(); + } + paint(g); + + + } + + + public String getResponseText(){ + + try{ + String urlstr="http://"+host_address+"/position:0/pva/get?format=xml"; + URL url = new URL(urlstr); + URLConnection urlconn = url.openConnection(); + + Document doc = null; + try { + + BufferedReader reader = new BufferedReader(new InputStreamReader(urlconn.getInputStream())); + StringBuilder sb = new StringBuilder(); + + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + + + } catch (IOException e) { + e.printStackTrace(); + } + + + return (sb.toString()); + + } catch (Exception e) { + + return e.toString(); + } + } catch (Exception e){ + return "Problem accessing the response text."; + } + } + + + public void drawRobot(double x,double y, double a, Robot robot){ + int[] verx=new int[4]; + int[] very=new int[4]; + int head_x,head_y,center_x,center_y; +// 0:0.25,0.25 1:0.25,-0.25 2:-0.25,-0.25 3:-0.25,0.25 + verx[0]=(int)((Math.cos(-a)*0.25+Math.sin(-a)*0.25+x)*(double)((double)boardSize/16.0)); + verx[1]=(int)((Math.cos(-a)*0.25+Math.sin(-a)*(-0.25)+x)*(double)((double)boardSize/16.0)); + verx[2]=(int)((Math.cos(-a)*(-0.25)+Math.sin(-a)*(-0.25)+x)*(double)((double)boardSize/16.0)); + verx[3]=(int)((Math.cos(-a)*(-0.25)+Math.sin(-a)*0.25+x)*(double)((double)boardSize/16.0)); + very[0]=(int)((-Math.sin(-a)*0.25+Math.cos(-a)*0.25+y)*(double)((double)boardSize/16.0)); + very[1]=(int)((-Math.sin(-a)*0.25+Math.cos(-a)*(-0.25)+y)*(double)((double)boardSize/16.0)); + very[2]=(int)((-Math.sin(-a)*(-0.25)+Math.cos(-a)*(-0.25)+y)*(double)((double)boardSize/16.0));; + very[3]=(int)((-Math.sin(-a)*(-0.25)+Math.cos(-a)*0.25+y)*(double)((double)boardSize/16.0)); + for(int i=0;i<4;i++){ + verx[i]=verx[i]+boardSize/2+boardX; + very[i]=-very[i]+boardSize/2+boardY; + } + center_x=(int)(x*(double)((double)boardSize/16.0))+boardSize/2+boardX; + center_y=(int)(-y*(double)((double)boardSize/16.0))+boardSize/2+boardY; + head_x=(int)((Math.cos(-a)*0.5+x)*(double)((double)boardSize/16.0))+boardSize/2+boardX; + head_y=(int)(-(-Math.sin(-a)*0.5+y)*(double)((double)boardSize/16.0))+boardSize/2+boardY; + Polygon poly=new Polygon(verx,very,4); + scrnG.setColor(Color.red); + scrnG.fillPolygon(poly); + //If robot is selected on the model tree, draw a highlighted square around it. + if(robot.selected){ + int[] selx=new int[4]; + int[] sely=new int[4]; + selx[0]=(int)((Math.cos(-a)*0.5+Math.sin(-a)*0.5+x)*(double)((double)boardSize/16.0)); + selx[1]=(int)((Math.cos(-a)*0.5+Math.sin(-a)*(-0.5)+x)*(double)((double)boardSize/16.0)); + selx[2]=(int)((Math.cos(-a)*(-0.5)+Math.sin(-a)*(-0.5)+x)*(double)((double)boardSize/16.0)); + selx[3]=(int)((Math.cos(-a)*(-0.5)+Math.sin(-a)*0.5+x)*(double)((double)boardSize/16.0)); + sely[0]=(int)((-Math.sin(-a)*0.5+Math.cos(-a)*0.5+y)*(double)((double)boardSize/16.0)); + sely[1]=(int)((-Math.sin(-a)*0.5+Math.cos(-a)*(-0.5)+y)*(double)((double)boardSize/16.0)); + sely[2]=(int)((-Math.sin(-a)*(-0.5)+Math.cos(-a)*(-0.5)+y)*(double)((double)boardSize/16.0));; + sely[3]=(int)((-Math.sin(-a)*(-0.5)+Math.cos(-a)*0.5+y)*(double)((double)boardSize/16.0)); + for(int i=0;i<4;i++){ + selx[i]=selx[i]+boardSize/2+boardX; + sely[i]=-sely[i]+boardSize/2+boardY; + } + Polygon selpoly=new Polygon(selx,sely,4); + scrnG.setColor(new Color((float)0,(float)1,(float)1,(float)0.5)); + scrnG.fillPolygon(selpoly); + } + scrnG.setColor(Color.BLACK); + scrnG.drawLine(verx[0],very[0],verx[1],very[1]); + scrnG.drawLine(center_x,center_y,head_x,head_y); + } + + public void drawLaser(Robot robot){ + //If the laser device is selected on the model tree, highlight it, otherwise draw it normally. + if(robot.laserSelected) + scrnG.setColor(new Color((float)0,(float)0,(float)1,(float)0.75)); + else + scrnG.setColor(new Color((float)0,(float)0,(float)1,(float)0.25)); + double fov=robot.laser_fov; + double[] samples=robot.getLaserRange(); + int sampleCount=samples.length; + double[] xs= new double[sampleCount+1]; + double[] ys= new double[sampleCount+1]; + double[] xprimes= new double[sampleCount+1]; + double[] yprimes= new double[sampleCount+1]; + int[] int_xprimes= new int[sampleCount+1]; + int[] int_yprimes= new int[sampleCount+1]; + double bearing = robot.pose.a; + + xs[0]=0.0; + ys[0]=0.0; + for(int s=0;s<sampleCount;s++){ + double ray_angle = (s * (fov / (sampleCount-1))) - fov/2.0; + xs[s+1] =(samples[s] * Math.cos(ray_angle) ); + ys[s+1] =(samples[s] * Math.sin(ray_angle) ); + } + xprimes[0]=robot.pose.x; + yprimes[0]=robot.pose.y; +// Rotates Counter-Clockwise with (-bearing) + for(int s=0;s<sampleCount;s++){ + xprimes[s+1] = Math.cos(-bearing)*xs[s+1]+Math.sin(-bearing)*ys[s+1]+xprimes[0]; + yprimes[s+1] = -Math.sin(-bearing)*xs[s+1]+Math.cos(-bearing)*ys[s+1]+yprimes[0]; + } + for(int i=0;i<sampleCount+1;i++){ + int_xprimes[i]=(int)(xprimes[i]*(double)((double)boardSize/16.0))+boardSize/2+boardX; + int_yprimes[i]=(int)(-yprimes[i]*(double)((double)boardSize/16.0))+boardSize/2+boardY; + } + scrnG.fillPolygon(int_xprimes,int_yprimes,sampleCount+1); + } + + public void drawSonar(Robot robot){ + //If the ranger device is selected on the model tree, highlight it, otherwise draw it normally. + if(robot.sonarSelected) + scrnG.setColor(new Color((float)0,(float)1,(float)0.75)); + else + scrnG.setColor(Color.green); + for(int i=0;i<robot.sonar_sampleCount;i++){ + int startx,starty,endx,endy; + startx=(int)(robot.sonar_pairs[i].start.x*(double)((double)boardSize/16.0))+boardSize/2+boardX; + starty=(int)(-robot.sonar_pairs[i].start.y*(double)((double)boardSize/16.0))+boardSize/2+boardY; + endx=(int)(robot.sonar_pairs[i].end.x*(double)((double)boardSize/16.0))+boardSize/2+boardX; + endy=(int)(-robot.sonar_pairs[i].end.y*(double)((double)boardSize/16.0))+boardSize/2+boardY; + scrnG.drawLine(startx,starty,endx,endy); + } + } + + public void drawFiducial(Robot robot){ + //If the fiducial device is selected on the model tree, highlight it, otherwise draw it normally. + if(robot.fiducialSelected) + scrnG.setColor(new Color((float)0.15,(float)0.15,(float)0.15)); + else + scrnG.setColor(Color.gray); + for(int i=0;i<robot.fiducial_sampleCount;i++){ + int startx,starty,endx,endy; + startx=(int)(robot.pose.x*(double)((double)boardSize/16.0))+boardSize/2+boardX; + starty=(int)(-robot.pose.y*(double)((double)boardSize/16.0))+boardSize/2+boardY; + endx=(int)((robot.pose.x+robot.fiducial[i].x)*(double)((double)boardSize/16.0))+boardSize/2+boardX; + endy=(int)(-(robot.pose.y+robot.fiducial[i].y)*(double)((double)boardSize/16.0))+boardSize/2+boardY; + scrnG.drawLine(startx,starty,endx,endy); + scrnG.drawString(new Integer(robot.fiducial[i].id).toString() ,endx, endy); + } + } + + + public double toDouble(String s){ + double ans=0; + boolean minusFlag=false; + if(s.startsWith("-")){ + minusFlag=true; + s=s.substring(1); + } + int dotLocation=s.length(); + for(int i=0;i<s.length();i++){ + if((s.charAt(i)<'0' ||s.charAt(i)>'9') && s.charAt(i)!='.' ) + break; + if(s.charAt(i)=='.'){ + dotLocation=i; + continue; + } + if(i<dotLocation){ + ans*=10; + ans+=((int)s.charAt(i)-'0'); + } + else + ans+=(double)((double)((int)s.charAt(i)-'0')/Math.pow(10.0,i-dotLocation)); + } + + if(minusFlag) + ans=-ans; + return ans; + } + + } + + + /** + * This class build a JTree based on the xml format of the tree. The xml parser builds an arraylist of the models and their depth in the tree which will be passed to this + * class. Then this class will recursively build the tree. + + * Parts of the code are from "http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-JTree.html" + */ + class TreeBuilder extends JPanel { + + public TreeBuilder() { + + } + + public JTree makeTree(ArrayList list, int level, int index){ + DefaultMutableTreeNode root = processHierarchy(list,level,index); + JTree tree = new JTree(root); + return tree; + } + + int staticIndex=0; + private DefaultMutableTreeNode processHierarchy(ArrayList list, int level, int index) { + DefaultMutableTreeNode node = + new DefaultMutableTreeNode(((ObjectLevelPair)list.get(index)).obj); + DefaultMutableTreeNode child; + for(int i=index+1; i<list.size(); i++) { + ObjectLevelPair nodeSpecifier = (ObjectLevelPair)list.get(i); + if (nodeSpecifier.level>((ObjectLevelPair)list.get(index)).level){ + child = processHierarchy(list,nodeSpecifier.level,i); + nodeSpecifier.level=0; + node.add(child); + } + else if(nodeSpecifier.level==0) + continue; + else + break; + } + return(node); + } + } + + /** + * This is a class used for building the tree. + */ + class ObjectLevelPair { + Object obj; + int level; + public ObjectLevelPair(Object argobj, int arglevel){ + obj=argobj; + level=arglevel; + } + + } + + /** + * A pair of double values. + */ + class Pair { + double x,y; + Pair(){ + x=0.0; + y=0.0; + } + Pair(double argx,double argy){ + x=argx; + y=argy; + } + + } + + + + /** + * This is a Robot class. Fields correspond to the devices and models a robot can have. + */ + class Robot{ + + //PVA + Pose pose; + //Laser samples + LaserSample[] samples; + //Sonar ranges + double[] sonar; + //Laser configurations + double laser_fov, laser_resol, sonar_fov; + int laser_sampleCount; + int sonar_sampleCount; + int fiducial_sampleCount; + //Start and end ponits of Sonar beams + SonarSample[] sonar_pairs; + //Fiducials detected + FiducialSample[] fiducial; + //Names of robot and its devices + String name, laserName,sonarName,fiducialName; + //Flags indicating if robot has any of these devices + boolean hasLaser, hasRanger, hasFiducial; + //Flags indicating if robot or any of these devices are selected on the model tree + boolean selected, laserSelected, sonarSelected, fiducialSelected; + + Robot(){ + name="r"; + laserName="laser:0"; + sonarName="ranger:0"; + fiducialName="fiducial:0"; + hasLaser=false; + hasRanger=false; + hasFiducial=false; + selected=false; + laserSelected=false; + sonarSelected=false; + fiducialSelected=false; + pose=new Pose(); + laser_sampleCount=30; + samples=new LaserSample[laser_sampleCount]; + sonar_sampleCount=10; + sonar=new double[sonar_sampleCount]; + sonar_pairs=new SonarSample[sonar_sampleCount]; + laser_fov=3.1416; + sonar_fov=6.2832; + laser_resol=1.0; + for(int i=0;i<laser_sampleCount;i++){ + samples[i]=new LaserSample(); + samples[i].range=1.0; + } + for(int i=0;i<sonar_sampleCount;i++){ + sonar[i]=2.2; + sonar_pairs[i]=new SonarSample(); + } + fiducial_sampleCount=0; + } + + //Returns pva of the robot. + public Pose getPosition(){ + return this.pose; + } + public void setPose(double argx,double argy,double argz,double argr,double argp,double arga){ + pose.a=arga; + pose.r=argr; + pose.p=argp; + pose.x=argx; + pose.y=argy; + pose.z=argz; + } + + //Returns laser samples of the robot. + public LaserSample[] getLaser(){ + return this.samples; + } + + //Returns laser ranges of the robot. + public double[] getLaserRange(){ + double[] ranges=new double[samples.length]; + for(int i=0;i<samples.length;i++){ + ranges[i]=samples[i].range; + } + return ranges; + } + + //Returns sonar samples of the robot. + public double[] getSonar(){ + return this.sonar; + } + + public void print(){ + System.out.println("pose:"); + System.out.println("x:"+pose.x+" y:"+pose.y+" z:"+pose.z+" r:"+pose.r+" p:"+pose.p+" a:"+pose.a); + } + + + + } + + /** + * A Class corresponding to the PVA of the robot, indicating x,y,z positions ans r,p,a, angles. + */ + class Pose{ + double a,r,p,x,y,z; + Pose(){ + a=r=p=x=y=z=0.0; + } + Pose(double argx,double argy,double argz,double argr,double argp,double arga){ + a=arga; + r=argr; + p=argp; + x=argx; + y=argy; + z=argz; + } + } + /** + * A Class corresponding to the Laser of the robot, indicating intensity and range of the laser beam. + */ + class LaserSample{ + double intensity; + double range; + LaserSample(){ + intensity=range=0.0; + } + } + /** + * A Class corresponding to the Sonar of the robot, indicating start and end point of the sonar beam. + */ + class SonarSample{ + Pair start,end; + SonarSample(){ + start=new Pair(); + end=new Pair(); + } + SonarSample(double startx,double starty,double endx,double endy){ + start=new Pair(startx,starty); + end=new Pair(endx,endy); + } + } + /** + * A Class corresponding to the Fiducial of the robot, indicating range, bearing, and id of the fiducial. + */ + class FiducialSample{ + double x,y; + int id; + FiducialSample(){ + x=0; + y=0; + id=0; + } + FiducialSample(double xarg,double yarg,int idarg){ + x=xarg; + y=yarg; + id=idarg; + } + } + + + /** + * This is a Content Handler for xml parser. This Content Handler parses the xml responses for Position, Laser, Ranger, and Fiducial requests. It has a robot field and + * whenever a property is parsed, the corresponding fields in the robot are (re)assigned. + * + * Parts of the code are from: http://www-inf.int-evry.fr/cours/WebServices/XML/sax.html + */ + class Sink + extends DefaultHandler + implements ContentHandler + + { + String time="Time: "; + Robot robot=new Robot(); + final private static void print + ( final String context, final String text ) + { System.out.println( context + ": \"" + text + "\"." ); } + + public void startElement + ( final String namespace, final String localname, + final String type, final Attributes attrs ) + { + try{ + time="Time: "+attrs.getValue("Time"); + if(attrs.getValue("Type").toLowerCase().equals("pva")){ + String pose=attrs.getValue("Pose"); + String x,y,z,r,p,a; + String[] vals=pose.split(","); + x = vals[0]; + y = vals[1]; + z = vals[2]; + r = vals[3]; + p = vals[4]; + a = vals[5]; + + double x_val,y_val,z_val,r_val,p_val,a_val; + x_val=Double.parseDouble(x); + y_val=Double.parseDouble(y); + z_val=Double.parseDouble(z); + r_val=Double.parseDouble(r); + p_val=Double.parseDouble(p); + a_val=Double.parseDouble(a); + robot.setPose(x_val,y_val,z_val,r_val,p_val,a_val); + + } + if(attrs.getValue("Type").toLowerCase().equals("laser")){ + String res,fov,sam; + res = attrs.getValue("Resolution"); + fov = attrs.getValue("FOV"); + sam = attrs.getValue("Samples"); + double res_val,fov_val; + String[] tokens=sam.split(","); + double[] samples=new double[tokens.length]; + robot.laser_sampleCount=tokens.length; + robot.samples=new LaserSample[tokens.length]; + for(int i=0;i<tokens.length;i++){ + samples[i]=Double.parseDouble(tokens[i]); + robot.samples[i]=new LaserSample(); + robot.samples[i].range=samples[i]; + } + res_val=Double.parseDouble(res); + fov_val=Double.parseDouble(fov); + robot.laser_fov=fov_val; + robot.laser_resol=res_val; + + } + if(attrs.getValue("Type").toLowerCase().equals("ranger")){ + String pos,sam; + sam = attrs.getValue("Samples"); + String[] tokens=sam.split(","); + robot.sonar_sampleCount=tokens.length; + robot.sonar=new double[tokens.length]; + robot.sonar_pairs=new SonarSample[tokens.length]; + double[] samples=new double[tokens.length]; + pos= attrs.getValue("Positions"); + pos=pos.replaceAll(" \\(", ""); + String[] posetokens=pos.split("\\)"); + for(int i=0;i<tokens.length;i++){ + String[] poses=posetokens[2*i].split(","); + String[] angles=posetokens[2*i+1].split(","); + double startx,starty,angle,endx,endy,startx1,starty1; + samples[i]=Double.parseDouble(tokens[i]); + robot.sonar[i]=samples[i]; + startx1=Double.parseDouble(poses[0]); + starty1=Double.parseDouble(poses[1]); + startx=Math.cos(-robot.pose.a)*startx1+Math.sin(-robot.pose.a)*starty1+robot.pose.x; + starty= -Math.sin(-robot.pose.a)*startx1+Math.cos(-robot.pose.a)*starty1+robot.pose.y; + angle=Double.parseDouble(angles[2]); + endx=startx+Math.cos(angle+robot.pose.a)*samples[i]; + endy=starty+Math.sin(angle+robot.pose.a)*samples[i]; + robot.sonar_pairs[i]=new SonarSample(startx,starty,endx,endy); + } + + } + if(attrs.getValue("Type").toLowerCase().equals("fiducial")){ + robot.fiducial=null; + robot.fiducial_sampleCount=0; + String fids; + fids = attrs.getValue("Targets"); + if(!fids.equals("")){ + fids=fids.replaceAll("\\)\\(", ","); + fids=fids.replaceAll("\\(", ""); + fids=fids.replaceAll("\\)", ""); + String[] fidtokens=fids.split(","); + robot.fiducial_sampleCount=fidtokens.length/7; + robot.fiducial= new FiducialSample[fidtokens.length/7]; + for(int i=0;i<fidtokens.length/7;i++){ + robot.fiducial[i]=new FiducialSample(); + robot.fiducial[i].x=Double.parseDouble(fidtokens[i*7]); + robot.fiducial[i].y=Double.parseDouble(fidtokens[i*7+1]); + robot.fiducial[i].id=Integer.parseInt(fidtokens[i*7+6]); + } + } + + + } + }catch(Exception e){ + e.printStackTrace(); + } + } + + + + + public void endElement + ( final String namespace, final String localname, + final String type ) + throws SAXException + { + + } + + final public void characters + ( final char[] ch, final int start, final int len ) + { final String text = new String( ch, start, len ); + final String text1 = text.trim(); + if( text1.length() > 0 )print( "characters ", text1 ); } + + public Robot getRobot(){ + return robot; + } + + } + + + /** + * This is a Content Handler for xml parser. This Content Handler parses the xml tree returned by the server. Based on the models that exist in the tree, + * corresponding models (robots, lasers, rangers, fiducials) are created. + * + * Parts of the code are from: "http://www-inf.int-evry.fr/cours/WebServices/XML/sax.html" + */ + class TreeSink + extends DefaultHandler + implements ContentHandler + + { + //int xposition=600, yposition=250; + Robot robot=new Robot(); + StageApplet np; + TreeBuilder tree; + int level=0; + ArrayList<ObjectLevelPair> arraylist; + + TreeSink(StageApplet nparg){ + np=nparg; + tree=new TreeBuilder(); + arraylist=new ArrayList<ObjectLevelPair>(); + } + + final private static void print + ( final String context, final String text ) + { System.out.println( context + ": \"" + text + "\"." ); } + + public void startElement + ( final String namespace, final String localname, + final String type, final Attributes attrs ) + { + + level++; + String model_type=attrs.getValue("Type"); + if(model_type!=null){ + if(model_type.toLowerCase().equals("position")){ + String name=attrs.getValue("Name"); + if(name.indexOf('.')!=-1) + name=name.substring(0,name.indexOf('.')); + if(np.robots.size()<1 || !np.robots.get(np.robots.size()-1).name.equals(name)){ + Robot r=new Robot(); + r.name=name; + np.robots.add(r); + } + } + if(model_type.toLowerCase().equals("laser")){ + String name=attrs.getValue("Name"); + if(np.robots.size()<1 || !np.robots.get(np.robots.size()-1).name.equals(name.substring(0,name.indexOf('.')))){ + Robot r=new Robot(); + r.name=name.substring(1,name.lastIndexOf('.')); + np.robots.add(r); + } + np.robots.get(np.robots.size()-1).hasLaser=true; + np.robots.get(np.robots.size()-1).laserName=name; + } + if(model_type.toLowerCase().equals("ranger")){ + String name=attrs.getValue("Name"); + if(np.robots.size()<1 || !np.robots.get(np.robots.size()-1).name.equals(name.substring(0,name.indexOf('.')))){ + Robot r=new Robot(); + r.name=name.substring(1,name.lastIndexOf('.')); + np.robots.add(r); + } + np.robots.get(np.robots.size()-1).hasRanger=true; + np.robots.get(np.robots.size()-1).sonarName=name; + } + if(model_type.toLowerCase().equals("fiducial")){ + String name=attrs.getValue("Name"); + if(np.robots.size()<1 || !np.robots.get(np.robots.size()-1).name.equals(name.substring(0,name.indexOf('.')))){ + Robot r=new Robot(); + r.name=name.substring(1,name.lastIndexOf('.')); + np.robots.add(r); + } + np.robots.get(np.robots.size()-1).hasFiducial=true; + np.robots.get(np.robots.size()-1).fiducialName=name; + } + + try{ + arraylist.add(new ObjectLevelPair((attrs.getValue("Name").lastIndexOf('.')>0?attrs.getValue("Name").substring(attrs.getValue("Name").lastIndexOf('.')+1):attrs.getValue("Name")),level)); + }catch(Exception e){ + e.printStackTrace(); + } + } + else{ + arraylist.add(new ObjectLevelPair(type,level)); + } + } + + + + + public void endElement + ( final String namespace, final String localname, + final String type ) + throws SAXException + { + + level--; + + } + + final public void characters + ( final char[] ch, final int start, final int len ) + { final String text = new String( ch, start, len ); + final String text1 = text.trim(); + if( text1.length() > 0 )print( "characters ", text1 ); } + + public Robot getRobot(){ + return robot; + } + + } + + /** + * This class creates a new XML reader. + * + * code from: "http://www-inf.int-evry.fr/cours/WebServices/XML/sax.html" + */ + final class XML + + { + + final public static XMLReader makeXMLReader() + throws Exception + { final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + final SAXParser saxParser = saxParserFactory.newSAXParser(); + final XMLReader parser = saxParser.getXMLReader(); + return parser; + } + } + + + + + + + + + Added: code/websim/viz/ReadMe =================================================================== --- code/websim/viz/ReadMe (rev 0) +++ code/websim/viz/ReadMe 2009-07-13 20:05:09 UTC (rev 8007) @@ -0,0 +1,3 @@ + The HTML page calls "Main.class" to be run. The applet will contain a textfield, that indicates the server address. The default value for it is set to "192.168.1.210:8000". The server address can be changed by editing this text field and then pressing the "Send Request" button. + On the left side of the panel, the model tree will show up. This tree contains all the models existing in the world. The parent of each node in the tree corresponds to its parent model in the world. Models can be selected or unselected on the tree by clicking on them. Selecting a model highlights it in the visualization panel. Several Models can be selected by holding "ctrl". + There are 4 checkboxes on the top of the page: Position, Laser, Sonar, and Fiducial. Selecting or unselecting each of them will result in those features being drawn or not. By default, position and laser are selected meaning the robots and their laser beams are drawn initially. Added: code/websim/viz/java.policy.applet =================================================================== --- code/websim/viz/java.policy.applet (rev 0) +++ code/websim/viz/java.policy.applet 2009-07-13 20:05:09 UTC (rev 8007) @@ -0,0 +1,7 @@ +/* AUTOMATICALLY GENERATED ON Tue Apr 16 17:20:59 EDT 2002*/ +/* DO NOT EDIT */ + +grant { + permission java.security.AllPermission; +}; + Added: code/websim/viz/visualization.html =================================================================== --- code/websim/viz/visualization.html (rev 0) +++ code/websim/viz/visualization.html 2009-07-13 20:05:09 UTC (rev 8007) @@ -0,0 +1,14 @@ +<HTML> +<HEAD> + <TITLE>Websim Visualization</TITLE> +</HEAD> +<BODY> + <CENTER> + <APPLET CODE="Main.class" WIDTH="1000" HEIGHT="1000" id="TheApplet"> + </APPLET> + </CENTER> + + +</BODY> +</HTML> + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <as...@us...> - 2009-07-14 19:25:45
|
Revision: 8017 http://playerstage.svn.sourceforge.net/playerstage/?rev=8017&view=rev Author: asadat Date: 2009-07-14 19:25:38 +0000 (Tue, 14 Jul 2009) Log Message: ----------- changed the viz html Modified Paths: -------------- code/websim/CMakeLists.txt code/websim/src/req_sim.cc Modified: code/websim/CMakeLists.txt =================================================================== --- code/websim/CMakeLists.txt 2009-07-14 18:36:30 UTC (rev 8016) +++ code/websim/CMakeLists.txt 2009-07-14 19:25:38 UTC (rev 8017) @@ -147,6 +147,8 @@ "make" "make install") + + INSTALL (FILES README.txt COPYING.txt DESTINATION .) SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "WebSim") Modified: code/websim/src/req_sim.cc =================================================================== --- code/websim/src/req_sim.cc 2009-07-14 18:36:30 UTC (rev 8016) +++ code/websim/src/req_sim.cc 2009-07-14 19:25:38 UTC (rev 8017) @@ -55,7 +55,15 @@ response = "<HTML><HEAD><TITLE>Websim Visualization</TITLE></HEAD>" "<BODY><iframe id=\"visualization\" frameborder=0 width=\"1000\" height=\"1000\" " - "src=\"viz.html\"></iframe></BODY></HTML>"; + "src=\"http://192.168.1.210/viz.html\"></iframe></BODY></HTML>"; + + /*response = + "<HTML><HEAD><TITLE>A Simple Program</TITLE></HEAD>" + "<BODY><CENTER>" + "<APPLET CODE=\"http://192.168.1.210/Main.class\" WIDTH=\"1000\" HEIGHT=\"1000\" id=\"TheApplet\"></APPLET>" + "</CENTER></BODY></HTML>"; +*/ + return true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |