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