Revision: 7410
          http://playerstage.svn.sourceforge.net/playerstage/?rev=7410&view=rev
Author:   rtv
Date:     2009-03-10 01:44:08 +0000 (Tue, 10 Mar 2009)

Log Message:
-----------
working on clientside of websim

Modified Paths:
--------------
    code/branches/federation/stage/examples/gzfed/Makefile
    code/branches/federation/stage/examples/gzfed/main.cc
    code/branches/federation/stage/examples/gzfed/parser.cc
    code/branches/federation/stage/examples/gzfed/world.fed

Added Paths:
-----------
    code/branches/federation/stage/examples/gzfed/confederate.cc
    code/branches/federation/stage/examples/gzfed/puppet.cc
    code/branches/federation/stage/examples/gzfed/websim.cc
    code/branches/federation/stage/examples/gzfed/websim.hh

Modified: code/branches/federation/stage/examples/gzfed/Makefile
===================================================================
--- code/branches/federation/stage/examples/gzfed/Makefile      2009-03-10 
01:07:25 UTC (rev 7409)
+++ code/branches/federation/stage/examples/gzfed/Makefile      2009-03-10 
01:44:08 UTC (rev 7410)
@@ -1,4 +1,6 @@
 
+CFLAGS=`pkg-config --cflags glib-2.0`
+LIBS=-levent -lyaml `pkg-config --libs glib-2.0`
 
-parser: parser.cc main.cc
-       g++ parser.cc main.cc -o parser -lyaml
\ No newline at end of file
+websim: websim.hh websim.cc parser.cc main.cc puppet.cc confederate.cc
+       g++ $(CFLAGS) websim.cc parser.cc main.cc puppet.cc confederate.cc -o 
$@ $(LIBS)
\ No newline at end of file

Added: code/branches/federation/stage/examples/gzfed/confederate.cc
===================================================================
--- code/branches/federation/stage/examples/gzfed/confederate.cc                
                (rev 0)
+++ code/branches/federation/stage/examples/gzfed/confederate.cc        
2009-03-10 01:44:08 UTC (rev 7410)
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <assert.h>
+
+#include "websim.hh"
+
+Confederate::Confederate( const char* host, unsigned short port ) :
+  puppet_list( NULL )
+{
+  if(! (http_con = evhttp_connection_new( host, port )) )
+        printf( "Error: Confederate object failed to connect to server at 
%s:%d\n",
+                               host, port );
+  
+  char* remote_host = NULL;
+  unsigned short remote_port = 0;
+
+  // store the name and port post-connection for sanoty check
+  evhttp_connection_get_peer( http_con, 
+                                                                               
&remote_host, 
+                                                                               
&remote_port );
+  
+  // build the canonical name for this confederate
+  snprintf( name, 512, "%s:%u", remote_host, remote_port );
+
+  g_hash_table_insert( WebSim::confederates, name, this );
+  //printf( "\t\tConfederate %s constructed \n", name );
+}
+
+Confederate::~Confederate()
+{
+  evhttp_connection_free( http_con );
+}
+
+void Confederate::PuppetCreationCallback( evhttp_request* req, void* arg )
+{
+  Puppet* pup = (Puppet*)arg;
+  printf( "response regarding puppet \"%s\"\n", pup->name );
+
+  printf( "code: %d\n", req->response_code );
+ 
+  printf( "response: %s\n", req->input_buffer->buffer );
+
+  if( req->response_code == 200 )
+        pup->created = true;
+}
+
+void Confederate::AddPuppet( Puppet* puppet,
+                                                                         const 
char* prototype )
+{
+  // send a create message
+  printf( "Creating puppet \"%s\" on %s using prototype \"%s\"\n",
+                        puppet->name,
+                        name,
+                        prototype );
+
+  struct evhttp_request* er = 
+        evhttp_request_new( PuppetCreationCallback, puppet );
+  assert(er);
+  
+  char buf[512];
+  snprintf( buf, 512, "/sim/factory/create?name=%s&type=%s",
+                               puppet->name,
+                               prototype );
+  
+  printf( "URI: %s\n", buf );
+  
+  int ret = evhttp_make_request( http_con, er, EVHTTP_REQ_GET, buf );
+  if( ret != 0 )
+        {
+               printf( "make request returned error %d\n", ret );
+               exit(0);
+        }
+  
+  // a successful response sets puppet->created to true
+  while( ! puppet->created )
+        event_dispatch(); // loops until the request has completed
+
+  puppet_list = 
+        g_list_append( puppet_list, puppet );                                  
                                                 
+}
+
+int Confederate::Push( Puppet* puppet )
+{
+  printf( "\tpushing \"%s\" to %s.\n",
+                        puppet->name,
+                        name );
+}
+
+int Confederate::RunStep()
+{
+  // construct and send a tick message
+  printf( "Confederate %s clock tick\n",
+                        name );
+  return 0;
+}
+
+

Modified: code/branches/federation/stage/examples/gzfed/main.cc
===================================================================
--- code/branches/federation/stage/examples/gzfed/main.cc       2009-03-10 
01:07:25 UTC (rev 7409)
+++ code/branches/federation/stage/examples/gzfed/main.cc       2009-03-10 
01:44:08 UTC (rev 7410)
@@ -1,17 +1,61 @@
 
-#include "stdio.h"
+#include <unistd.h>
+#include <stdio.h>
 
-// declaration
-int parse_federation_file( const char* filename );
+#include "websim.hh"
 
+void print_confederate( const char* name, Confederate* conf, void* prefix )
+{
+  //printf( "%skey: %s name :%s\n", prefix, name, conf->name );
+  printf( "%s%s\n", prefix, conf->name );
+}
+
+void update_puppet( const char* name, Puppet* pup, void* dummy )
+{
+  // poke new state into puppet here 
+  pup->pose.x = 10;
+  pup->pose.y = 10;
+  pup->pose.z = 10;
+  pup->pose.a = 10;
+  
+  // and send the changes to the remote simulator
+  pup->Push();
+}
+
 int main( int argc, char** argv )
 {
-  printf( "parsing file %s\n", argv[1] );
+  WebSim ws( argv[1], createcallback, stateupdatecallback );
   
-  if( parse_federation_file( argv[1] ) )
-        printf( "failed to parse file." );
-  else
-        printf( "file parsed OK" );
+  puts( "\nConfederates:" );
+  ws.ForEachConfederate( print_confederate, 
+                                                                (void*)"\t" );
+  
+  while( 1 )
+        {
+                       
 
+               // native loop
+               
+               until( simtime >= (lasttime + ws.interval) )
+                 { 
+                        for each model
+                                                       update model
+                 }
+
+               for each model          
+                         ws.Push( "monkey", x,y,z )              
+                                                 
+               ws.Update();
+        }
+
   return 0;
 }
+
+
+               //puts( "\nUpdating puppets" );
+               //WebSim::ForEachPuppet( update_puppet, 
+               //                                                NULL );
+       //                        if( pup =  WebSim::getPuppet( model->name ) )
+//                                              pup->Push()
+
+                                                                               
        

Modified: code/branches/federation/stage/examples/gzfed/parser.cc
===================================================================
--- code/branches/federation/stage/examples/gzfed/parser.cc     2009-03-10 
01:07:25 UTC (rev 7409)
+++ code/branches/federation/stage/examples/gzfed/parser.cc     2009-03-10 
01:44:08 UTC (rev 7410)
@@ -1,11 +1,14 @@
-#include <yaml.h>
+
 #include <stdio.h>
 #include <assert.h>
 #include <string>
 #include <iostream>
 
+#include <yaml.h>   // YAML parser
 using namespace std;
 
+#include "websim.hh"
+
 static yaml_event_t event;
 static yaml_parser_t parser;
 static string hostname;
@@ -51,39 +54,68 @@
 }
 
 
-void parse_ghost_mapping( string host,
-                                                                 string model )
+Confederate* GetConfederate( const char* host, unsigned short port )
 {
-  expect( YAML_SCALAR_EVENT, "ghost host" );
-  string ghosthost = (const char*)event.data.scalar.value;
+  char lookup[256];
+  snprintf( lookup, 256, "%s:%u", host, port );
+
+  Confederate* conf = (Confederate*)
+        g_hash_table_lookup( WebSim::confederates, lookup );
   
-  expect( YAML_SCALAR_EVENT, "ghost type" );
-  string ghosttype = (const char*)event.data.scalar.value;
+  if( ! conf )  
+        conf = new Confederate( host, port );          
   
-  expect( YAML_MAPPING_END_EVENT, "ghost mapping" );
-                               
-  if( host == hostname )        
-        httprequest( "http://"; + ghosthost + "/sim/create?type=" + ghosttype );
+  return conf;
 }
 
 
-void parse_ghost_mapping_sequence( string host, 
-                                                                               
          string model )
+Confederate* GetConfederate( const char* hostandport )
 {
-  expect( YAML_SEQUENCE_START_EVENT, "start of sequence of ghost mappings" );
+  unsigned int port = WebSim::DEFAULT_PORT;
+  char hostnoport[256];
   
+  // parse out port number from hostname
+  sscanf( hostandport, "%s %u", &hostnoport, &port );
+  
+  //printf( " \"%s\" -> %s:%u\n", 
+  //    hostandport, hostnoport, port );
+  
+  return GetConfederate( hostnoport, port );           
+}
+
+void parse_puppet_mapping( Puppet* pup )
+{
+  expect( YAML_SCALAR_EVENT, "puppet host" );
+  const char* host = strdup((const char*)event.data.scalar.value);
+  
+  expect( YAML_SCALAR_EVENT, "puppet type" );
+  const char* prototype = strdup((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 parse_puppet_mapping_sequence( Puppet* pup )
+{
+  expect( YAML_SEQUENCE_START_EVENT, "start of sequence of puppet mappings" );
+  
   while( 1 )
         {
                next_event( "" );
                switch( event.type )
                  { 
                  case YAML_MAPPING_START_EVENT:
-                        parse_ghost_mapping( host, model );
+                        parse_puppet_mapping( pup );
                         break;
                  case  YAML_SEQUENCE_END_EVENT:
                         return;
                  default:
-                        parse_failed( "expecting a ghost mapping or end of 
sequence" );
+                        parse_failed( "expecting a puppet mapping or end of 
sequence" );
                  }
         }
 }
@@ -92,8 +124,13 @@
 {
   expect( YAML_SCALAR_EVENT, "model name" );  
   string model = (char*)event.data.scalar.value;
+  
+  Puppet* pup = NULL;
 
-  parse_ghost_mapping_sequence( host, model );
+  if( host == hostname )
+        pup = new Puppet( model.c_str() );
+
+  parse_puppet_mapping_sequence( pup );
   
   expect( YAML_MAPPING_END_EVENT, "end of model mapping" );
 }
@@ -129,9 +166,12 @@
                  { 
                  case YAML_SCALAR_EVENT:
                         {
-                               string host = (char*)event.data.scalar.value;  
-                               cout << "HOST " << host << endl;
-                               parse_model_mapping_sequence( host );
+                               string host = (const 
char*)event.data.scalar.value;
+                               
+                               // cout << "HOST " << host << endl;
+
+                               Confederate* conf = GetConfederate( 
host.c_str() );
+                               parse_model_mapping_sequence( conf->name );
                         }
                         break;
                  case  YAML_MAPPING_END_EVENT:
@@ -165,8 +205,11 @@
                exit( 0 );
         }
 
+  char buf[256];
+  snprintf( buf, 256, "%s:%u", hst, WebSim::DEFAULT_PORT );
+
   // copy the c string into a std:string
-  hostname = hst;
+  hostname = buf;
   
   /* Create the Parser object. */
   yaml_parser_initialize(&parser);

Added: code/branches/federation/stage/examples/gzfed/puppet.cc
===================================================================
--- code/branches/federation/stage/examples/gzfed/puppet.cc                     
        (rev 0)
+++ code/branches/federation/stage/examples/gzfed/puppet.cc     2009-03-10 
01:44:08 UTC (rev 7410)
@@ -0,0 +1,38 @@
+
+#include <string.h> //for strdup()
+#include <stdio.h> 
+
+#include "websim.hh"
+
+
+Puppet::Puppet( const char* name ) :
+  name( strdup(name) ),
+  created( false )
+{
+  g_hash_table_insert( WebSim::puppets, (void*)this->name, this );
+
+  //printf( "\t Puppet \"%s\" constructed\n", this->name );
+}
+
+
+void Puppet::Push()
+{
+  for( GList* it = confederates;
+                it;
+                it = it->next )
+        {
+               Confederate* conf = (Confederate*)it->data;
+               conf->Push( this );               
+        }
+}
+
+void Puppet::AddConfederate( Confederate* conf, 
+                                                                         const 
char* prototype )
+{
+  conf->AddPuppet( this, prototype );  
+  confederates = g_list_append( confederates, conf );
+}
+
+
+
+

Added: code/branches/federation/stage/examples/gzfed/websim.cc
===================================================================
--- code/branches/federation/stage/examples/gzfed/websim.cc                     
        (rev 0)
+++ code/branches/federation/stage/examples/gzfed/websim.cc     2009-03-10 
01:44:08 UTC (rev 7410)
@@ -0,0 +1,66 @@
+#include <iostream>
+
+#include "websim.hh"
+
+// declaration - parser defined in parser.cc
+int parse_federation_file( const char* filename );
+
+// static members  
+ GHashTable* WebSim::confederates = 
+  g_hash_table_new( g_str_hash, g_str_equal );
+
+GHashTable* WebSim::puppets = 
+  g_hash_table_new( g_str_hash, g_str_equal );
+
+const unsigned short WebSim::DEFAULT_PORT = 8000;
+
+const std::string WebSim::package = "WebSim";
+const std::string WebSim::version = "0.1";
+
+
+// WebSim::WebSim( const char* filename )
+// {
+//   std::cout << package << ' ' << version << std::endl;
+//   parse_federation_file( filename );  
+//   std::cout << package << " ready." << std::endl;
+// }
+
+void WebSim::Init( const char* filename )
+{
+  std::cout << package << ' ' << version << std::endl;
+
+  event_init(); // libevent startup
+  parse_federation_file( filename );  
+
+  std::cout << package << " ready." << std::endl;
+}
+
+void WebSim::ForEachConfederate(  void(*cb)(const char*, Confederate*, void*), 
void* arg )
+{
+  g_hash_table_foreach( WebSim::confederates,
+                                                               (GHFunc)cb, 
+                                                               arg );
+}
+
+void WebSim::ForEachPuppet( void(*cb)(const char*, Puppet*, void*), void* arg )
+{
+  g_hash_table_foreach( WebSim::puppets,
+                                                               (GHFunc)cb, 
+                                                               arg );
+}
+
+
+Puppet* WebSim::GetPuppet( const char* name )
+{
+  return( (Puppet*)g_hash_table_lookup( WebSim::puppets, name ) );
+}
+
+Confederate* WebSim::GetConfederate( const char* name )
+{
+  return( (Confederate*)g_hash_table_lookup( WebSim::confederates, name ) );
+}
+
+void WebSim::Update()
+{
+  event_loop( EVLOOP_ONCE );
+}

Added: code/branches/federation/stage/examples/gzfed/websim.hh
===================================================================
--- code/branches/federation/stage/examples/gzfed/websim.hh                     
        (rev 0)
+++ code/branches/federation/stage/examples/gzfed/websim.hh     2009-03-10 
01:44:08 UTC (rev 7410)
@@ -0,0 +1,146 @@
+#include <sys/types.h> 
+#include <sys/queue.h> 
+
+#include <event.h> // libevent
+#include <evhttp.h> // libevent's http tools
+#include <string>
+
+#include <glib.h>
+
+class Pose
+{
+public:
+  double x,y,z,r,p,a;
+  
+  Pose() :
+        x(0), y(0), z(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), 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 )
+  {}  
+};
+
+
+// forward decl.
+class Confederate;
+
+// manage an object we control on some federated simulators
+class Puppet
+{
+public:  
+  Puppet( const char* name );
+  
+  // unique ID used as a system-widel handle for this puppet, used as
+  // hash table key
+  const char* name;
+  
+  Pose pose;
+  Velocity vel;
+  Acceleration acc;
+  
+  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();
+  
+  // 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
+{
+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 );
+
+
+public:
+  Confederate( const char* host, unsigned short port );  
+  ~Confederate();
+  
+  void AddPuppet( Puppet* puppet,
+                                               const char* prototype );
+
+  int Push( Puppet* puppet );
+  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
+  char name[512];  
+};
+
+
+class WebSim
+{
+public:
+  static const unsigned short DEFAULT_PORT;
+  static const std::string package;
+  static const std::string version;
+  static GHashTable* puppets;
+  static GHashTable* confederates;
+
+  static void Init(  const char* federation_filename );
+        
+  //WebSim( const char* federation_filename );
+
+  /** For each confederate, call the callback function */
+  static void ForEachConfederate( void(*cb)(const char*, Confederate*, void*), 
void* arg );
+
+  /** For each puppet, call the callback function */
+  static void ForEachPuppet( void(*cb)(const char*, Puppet*, void*), void* arg 
);
+  
+  /** Get a puppet by name */
+  static Puppet* GetPuppet( const char* name );
+
+  /** Get a confederate by name in format "host:port" */
+  static Confederate* GetConfederate( const char* name );
+
+  static void Update();
+};

Modified: code/branches/federation/stage/examples/gzfed/world.fed
===================================================================
--- code/branches/federation/stage/examples/gzfed/world.fed     2009-03-10 
01:07:25 UTC (rev 7409)
+++ code/branches/federation/stage/examples/gzfed/world.fed     2009-03-10 
01:44:08 UTC (rev 7410)
@@ -3,17 +3,27 @@
 #        - desthost: prototype
 
 gort:
-  - pioneer2dx_model1: 
-       - deckard: pioneer
-       - roy: pioneer
-       - priss: pioneer
-  - pioneer2dx_model2: 
-       - deckard: pioneer
+  - monkey: 
+       - localhost: pioneer2dx
+  - punky: 
+       - localhost: pioneer2dx
+  - chunky: 
+       - localhost: pioneer2dx
+  - funky: 
+       - localhost: pioneer2dx
 
-tenner:
-  - pr2_1:
-       - deckard: pr2
 
-priss:
-  - pr2_1:
-       - deckard: pr2
+#       - 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


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

------------------------------------------------------------------------------
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to