Revision: 8589
          http://playerstage.svn.sourceforge.net/playerstage/?rev=8589&view=rev
Author:   rtv
Date:     2010-03-15 17:54:04 +0000 (Mon, 15 Mar 2010)

Log Message:
-----------
fasr2, and threading

Modified Paths:
--------------
    code/stage/trunk/examples/ctrl/fasr2.cc
    code/stage/trunk/examples/ctrl/source.cc
    code/stage/trunk/libstage/model.cc
    code/stage/trunk/libstage/powerpack.cc
    code/stage/trunk/libstage/stage.hh
    code/stage/trunk/libstage/world.cc
    code/stage/trunk/worlds/fasr2.world

Modified: code/stage/trunk/examples/ctrl/fasr2.cc
===================================================================
--- code/stage/trunk/examples/ctrl/fasr2.cc     2010-03-13 01:09:52 UTC (rev 
8588)
+++ code/stage/trunk/examples/ctrl/fasr2.cc     2010-03-15 17:54:04 UTC (rev 
8589)
@@ -19,12 +19,12 @@
 typedef enum {
   MODE_WORK=0,
   MODE_DOCK,
-  MODE_UNDOCK
+  MODE_UNDOCK,
+  MODE_QUEUE
 } nav_mode_t;
 
 
 
-
 class Edge;
 
 class Node
@@ -34,7 +34,7 @@
   double value;  
   std::vector<Edge*> edges;
   
-  Node( const Pose& pose )
+  Node( Pose pose )
         : pose(pose), value(0), edges() {}
   
   ~Node();
@@ -58,6 +58,7 @@
         : to(to), cost(cost) {}  
 };
 
+
 class Graph
 {
 public:
@@ -109,7 +110,7 @@
         
         if( best_node == NULL )
                {
-                 puts( "warning: no nodes in range" );
+                 printf( "FASR warning: no nodes in range" );
                  return false;
                }
         
@@ -282,20 +283,21 @@
         //      pos->GetUnusedModelOfType( "laser" );
         
         // PositionUpdate() checks to see if we reached source or sink
-        pos->AddUpdateCallback( (stg_model_callback_t)PositionUpdate, this );
+        pos->AddUpdateCallback( (stg_model_callback_t)UpdateCallback, this );
         pos->Subscribe();
+        
+        
+        // no other callbacks - we access all other data from the position
+        // callback 
 
-        // LaserUpdate() controls the robot, by reading from laser and
-        // writing to position
-        //laser->AddUpdateCallback( (stg_model_callback_t)LaserUpdate, this );
+        // start with only the laser enabled - we switch laser, ranger and
+        // fiducial on and off as needed to save energy and compute time
+        
+        //laser->AddUpdateCallback( 
(stg_model_callback_t)Robot::LaserUpdateCallback, this );
+
+
         EnableLaser(true);
 
-        // we subscribe to the fiducial device only while docking
-        fiducial->AddUpdateCallback( (stg_model_callback_t)FiducialUpdate, 
this );              
-        
-        // we subscribe to the ranger device only while undocking (i.e. 
backing up)
-        //ranger->AddUpdateCallback( (stg_model_callback_t)RangerUpdate, this 
);                        
-        
         pos->AddVisualizer( &graphvis, true );
         
         if( map_data == NULL )
@@ -327,7 +329,7 @@
                                else if( map_data[i] == 1 )
                                  map_data[i] = 9;
                                else
-                                 printf( "bad value %d in map at index %d\n", 
(int)map_data[i], (int)i );
+                                 printf( "FASR: bad value %d in map at index 
%d\n", (int)map_data[i], (int)i );
                                
                                assert( (map_data[i] == 1) || (map_data[i] == 
9) );               
                         }       
@@ -413,9 +415,11 @@
                                                                 path );
 
         pthread_mutex_unlock( &planner_mutex );
+        
+        if( ! result )
+               printf( "FASR warning: plan failed to find path from 
(%.2f,%.2f) to (%.2f,%.2f)\n",
+                                 pose.x, pose.y, sp.x, sp.y );
 
-        //printf( "#%s:\n", result ? "PATH" : "NOPATH" );
-
         graph.nodes.clear();
         
         unsigned int dist = 0;
@@ -481,7 +485,7 @@
                }                         
         else
                {
-                 printf( "%s docking but can't see a charger\n", pos->Token() 
);
+                 printf( "FASR: %s docking but can't see a charger\n", 
pos->Token() );
                  pos->Stop();
                  EnableFiducial( false );
                  mode = MODE_WORK; // should get us back on track eventually
@@ -507,7 +511,10 @@
         const unsigned int BACK_SENSOR_FIRST = 10;
         const unsigned int BACK_SENSOR_LAST = 13;
         
-        
+        // make sure the required sensors are running
+        assert( ranger_sub );
+        assert( fiducial_sub );
+
         if( charger_range < back_off_distance )
                {
                  pos->SetXSpeed( back_off_speed );
@@ -660,7 +667,7 @@
                  if( Hungry() )
                         SetGoal( fuel_zone );
                  
-                 // if the graph failes to offer advice or the goal has moved a
+                 // if the graph fails to offer advice or the goal has moved a
                  // ways since last time we planned
                  if( (graph.GoodDirection( pose, 4.0, a_goal ) == 0) || 
                                (goal->GetPose().Distance2D( cached_goal_pose ) 
> 2.0) )
@@ -708,19 +715,7 @@
                }  
   }
 
-  
-  static int RangerUpdate( ModelRanger* ranger, Robot* robot )
-  {
-               //printf( "%s RANGER UPDATE", ranger->Token() );
-        return 0;
-  }
 
-
-//   // inspect the laser data and decide what to do
-//   static int LaserUpdate( ModelLaser* laser, Robot* robot )
-//   {
-//   }
-
   bool Hungry()
   {
         return( pos->FindPowerPack()->ProportionRemaining() < 0.2 );
@@ -730,68 +725,119 @@
   {
         return( pos->FindPowerPack()->ProportionRemaining() > 0.95 );
   }     
+  
+  // static callback wrapper
+  static int UpdateCallback( ModelLaser* laser, Robot* robot )
+  {  
+        return robot->Update();
+  }
 
-  static int PositionUpdate( ModelPosition* pos, Robot* robot )
-  {  
+  int Update( void )
+  {
         Pose pose = pos->GetPose();
 
 #if 0   
         // when countdown reaches zero
-        if( --robot->node_interval_countdown == 0 )
+        if( --node_interval_countdown == 0 )
                {
                  // reset countdown
-                 robot->node_interval_countdown = robot->node_interval;
+                 node_interval_countdown = node_interval;
                  
                  Node* node = new Node( pose );
-                 robot->graph.AddNode( node );
+                 graph.AddNode( node );
                  
-                 if( robot->last_node )
-                        robot->last_node->AddEdge( new Edge( node ) );
+                 if( last_node )
+                        last_node->AddEdge( new Edge( node ) );
                  
-                 robot->last_node = node;
+                 last_node = node;
                  
                  // limit the number of nodes
-                 while( robot->graph.nodes.size() > TRAIL_LENGTH_MAX )
-                        robot->graph.PopFront();                        
+                 while( graph.nodes.size() > TRAIL_LENGTH_MAX )
+                        graph.PopFront();                       
                }
 #endif  
 
+        
+        // assume we can't see the charger
+        charger_ahoy = false;
+        
+        // if the fiducial is enabled
+        if( fiducial_sub ) 
+               {        
+                 std::vector<ModelFiducial::Fiducial>& fids = 
fiducial->GetFiducials();
+                 
+                 if( fids.size() > 0 )
+                        {
+                               ModelFiducial::Fiducial* closest = NULL;        
        
+                               
+                               for( unsigned int i = 0; i < fids.size(); i++ )
+                                 {                             
+                                        //printf( "fiducial %d is %d at %.2f m 
%.2f radians\n",
+                                        //       i, f->id, f->range, 
f->bearing );             
+                                        
+                                        ModelFiducial::Fiducial* f = &fids[i];
+                                        
+                                        // find the closest 
+                                        if( f->id == 2 && ( closest == NULL || 
f->range < closest->range )) // I see a charging station
+                                               closest = f; 
+                                 }                                             
  
+                 
+                               if( closest )
+                                 {                      // record that I've 
seen it and where it is
+                                        charger_ahoy = true;
+                                        
+                                        //printf( "AHOY %s\n", pos->Token() );
+                                        
+                                        charger_bearing = closest->bearing;
+                                        charger_range = closest->range;
+                                        charger_heading = closest->geom.a;     
                 
+                                 }
+                        }
+               }
+
+
         //printf( "Pose: [%.2f %.2f %.2f %.2f]\n",
         //  pose.x, pose.y, pose.z, pose.a );
   
         //pose.z += 0.0001;
-        //robot->pos->SetPose( pose );
+        //pos->SetPose( pose );
         
         // if we're close to the source we get a flag
-        Pose sourcepose = robot->source->GetPose();
-        Geom sourcegeom = robot->source->GetGeom();
+        Pose sourcepose = source->GetPose();
+        Geom sourcegeom = source->GetGeom();
 
-        if( hypot( sourcepose.x-pose.x, sourcepose.y-pose.y ) < 
sourcegeom.size.x/2.0 &&
+        stg_meters_t dest_dist = hypot( sourcepose.x-pose.x, 
sourcepose.y-pose.y );
+        
+        // if we're close, go get in line
+        //      if( dest_dist < sourcegeom.size.x )
+        //  mode = MODE_QUEUE;
+
+        
+        if( dest_dist < sourcegeom.size.x/2.0 &&
                  pos->GetFlagCount() < PAYLOAD )
                {
                  // transfer a chunk from source to robot
-                 pos->PushFlag( robot->source->PopFlag() );
+                 pos->PushFlag( source->PopFlag() );
                  
                  if( pos->GetFlagCount() == PAYLOAD )
-                        robot->SetGoal( robot->sink ); // we're done working
+                        SetGoal( sink ); // we're done working
                }
         
         // if we're close to the sink we lose a flag
-        Pose sinkpose = robot->sink->GetPose();
-        Geom sinkgeom = robot->sink->GetGeom();
+        Pose sinkpose = sink->GetPose();
+        Geom sinkgeom = sink->GetGeom();
         
         if( hypot( sinkpose.x-pose.x, sinkpose.y-pose.y ) < 
sinkgeom.size.x/2.0 && 
                  pos->GetFlagCount() > 0 )
                {
                  //puts( "dropping" );
                  // transfer a chunk between robot and goal
-                 robot->sink->PushFlag( pos->PopFlag() );                
+                 sink->PushFlag( pos->PopFlag() );               
                  
                  if( pos->GetFlagCount() == 0 ) 
-                        robot->SetGoal( robot->source ); // we're done 
dropping off
+                        SetGoal( source ); // we're done dropping off
                }
-  
-
+        
         //printf( "diss: %.2f\n", pos->FindPowerPack()->GetDissipated() );
 
         //   if( laser->power_pack && laser->power_pack->charging )
@@ -801,27 +847,30 @@
         //if( laser->GetSamples(NULL) == NULL )
                //return 0;
 
-        //assert( robot->laser->GetSamples().size() > 0 );
+        //assert( laser->GetSamples().size() > 0 );
 
-        switch( robot->mode )
+        switch( mode )
                {
                case MODE_DOCK:
                  //puts( "DOCK" );
-                 robot->Dock();
+                 Dock();
                  break;
                
                case MODE_WORK:
                  //puts( "WORK" );
-                 robot->Work();
+                 Work();
                  break;
 
                case MODE_UNDOCK:
                  //puts( "UNDOCK" );
-                 robot->UnDock();
+                 UnDock();
                  break;
                
+                 //case MODE_QUEUE:
+                 //Queue();
+
                default:
-                 printf( "unrecognized mode %u\n", robot->mode );              
+                 printf( "unrecognized mode %u\n", mode );             
                }
   
   
@@ -829,40 +878,13 @@
   }
 
 
-
-  static int FiducialUpdate( ModelFiducial* mod, Robot* robot )
-  {    
-        robot->charger_ahoy = false;
+  void Queue()
+  {
         
-        std::vector<ModelFiducial::Fiducial>& fids = mod->GetFiducials();
-        
-        ModelFiducial::Fiducial* closest = NULL;               
-        
-        for( unsigned int i = 0; i < fids.size(); i++ )
-               {                               
-                 //printf( "fiducial %d is %d at %.2f m %.2f radians\n",
-                 //      i, f->id, f->range, f->bearing );             
-                 
-                 ModelFiducial::Fiducial* f = &fids[i];
-                 
-                 // find the closest 
-                 if( f->id == 2 && ( closest == NULL || f->range < 
closest->range )) // I see a charging station
-                        closest = f; 
-               }                                                 
-        
-        if( closest )
-               {                        // record that I've seen it and where 
it is
-                 robot->charger_ahoy = true;
-               
-                 //printf( "AHOY %s\n", robot->pos->Token() );
 
-                 robot->charger_bearing = closest->bearing;
-                 robot->charger_range = closest->range;
-                 robot->charger_heading = closest->geom.a;                     
 
-               }
-        
-        return 0; // run again
   }
+
+
   
   
   static int FlagIncr( Model* mod, Robot* robot )
@@ -925,8 +947,6 @@
   const std::string& color = sources[ rand() % sources_count ];
   
   new Robot( (ModelPosition*)mod,
-                                //mod->GetWorld()->GetModel( words[1] + 
"_source" ),
-                                //mod->GetWorld()->GetModel( words[1] + 
"_sink" ),
                                 mod->GetWorld()->GetModel( color + "_source" ),
                                 mod->GetWorld()->GetModel( color + "_sink" ),
                                 mod->GetWorld()->GetModel( "fuel_zone" ) );

Modified: code/stage/trunk/examples/ctrl/source.cc
===================================================================
--- code/stage/trunk/examples/ctrl/source.cc    2010-03-13 01:09:52 UTC (rev 
8588)
+++ code/stage/trunk/examples/ctrl/source.cc    2010-03-15 17:54:04 UTC (rev 
8589)
@@ -5,18 +5,7 @@
 const double FLAGSZ = 0.25;
 const unsigned int CAPACITY = 1;
 
-int Update( Model* mod, void* dummy );
 
-
-// Stage calls this when the model starts up
-extern "C" int Init( Model* mod )
-{
-  mod->AddUpdateCallback( (stg_model_callback_t)Update, NULL );  
-  mod->Subscribe();
-  return 0; //ok
-}
-
-// inspect the laser data and decide what to do
 int Update( Model* mod, void* dummy )
 {
   if((  mod->GetWorld()->GetUpdateCount() % INTERVAL == 0 )
@@ -26,3 +15,11 @@
   return 0; // run again
 }
 
+// Stage calls this when the model starts up
+extern "C" int Init( Model* mod )
+{
+  mod->AddUpdateCallback( (stg_model_callback_t)Update, NULL );  
+  mod->Subscribe();
+  return 0; //ok
+}
+

Modified: code/stage/trunk/libstage/model.cc
===================================================================
--- code/stage/trunk/libstage/model.cc  2010-03-13 01:09:52 UTC (rev 8588)
+++ code/stage/trunk/libstage/model.cc  2010-03-15 17:54:04 UTC (rev 8589)
@@ -734,9 +734,9 @@
 
 void Model::Update( void )
 { 
-       if( hooks.attached_update )
-               CallCallbacks( &hooks.update );  
-
+  if( hooks.attached_update )
+        CallCallbacks( &hooks.update );  
+  
   last_update = world->sim_time;  
   world->Enqueue( event_queue_num, interval, this );
 }

Modified: code/stage/trunk/libstage/powerpack.cc
===================================================================
--- code/stage/trunk/libstage/powerpack.cc      2010-03-13 01:09:52 UTC (rev 
8588)
+++ code/stage/trunk/libstage/powerpack.cc      2010-03-15 17:54:04 UTC (rev 
8589)
@@ -48,12 +48,6 @@
   mod->RemoveVisualizer( &stored_vis );
 }
 
-
-void PowerPack::Print( char* prefix ) const
-{
-  printf( "%s stored %.2f/%.2f joules\n", prefix, stored, capacity );
-}
-
 /** OpenGL visualization of the powerpack state */
 void PowerPack::Visualize( Camera* cam ) 
 {

Modified: code/stage/trunk/libstage/stage.hh
===================================================================
--- code/stage/trunk/libstage/stage.hh  2010-03-13 01:09:52 UTC (rev 8588)
+++ code/stage/trunk/libstage/stage.hh  2010-03-15 17:54:04 UTC (rev 8589)
@@ -349,14 +349,15 @@
   };
   
   
-  /** Specify a 3 axis velocity in x, y and heading.   */
+  /** Specify a 4 axis velocity: 3D vector in [x, y, z], plus rotation
+               about Z (yaw).*/
   class Velocity : public Pose
   {
   public:
-        /** @param x x position in meters 
-                 @param y y position in meters 
-                 @param z z position in meters 
-                 @param a heading in radians 
+        /** @param x velocity vector component along X axis (forward speed), 
in meters per second.
+                 @param y velocity vector component along Y axis (sideways 
speed), in meters per second.
+                 @param z velocity vector component along Z axis (vertical 
speed), in meters per second.
+                 @param a rotational velocity around Z axis (yaw), in radians 
per second.
         */
     Velocity( stg_meters_t x, 
                                  stg_meters_t y, 
@@ -368,13 +369,18 @@
     Velocity()
     { /*empty*/ }               
     
-        /** Print velocity in human-readable format on stdout
-                 @param prefix Character string to prepend to pose output 
+        /** Print velocity in human-readable format on stdout, with a
+                 prefix string 
+                 
+                 @param prefix Character string to prepend to output, or NULL.
         */
-    virtual void Print( const char* prefix )
+    virtual void Print( const char* prefix ) const
     {
-      printf( "%s velocity [x:%.3f y:%.3f z:%3.f a:%.3f]\n",
-                                 prefix, x,y,z,a );
+               if( prefix )
+                 printf( "%s", prefix );
+               
+               printf( "velocity [x:%.3f y:%.3f z:%3.f a:%.3f]\n",
+                                 x,y,z,a );            
     }   
   };
   
@@ -386,10 +392,17 @@
     Pose pose;///< position
     Size size;///< extent
     
-    void Print( const char* prefix )
+        /** Print geometry in human-readable format on stdout, with a
+                 prefix string 
+                 
+                 @param prefix Character string to prepend to output, or NULL.
+        */
+    void Print( const char* prefix ) const
     {
-      printf( "%s geom pose: (%.2f,%.2f,%.2f) size: [%.2f,%.2f]\n",
-                                 prefix,
+               if( prefix )
+                 printf( "%s", prefix );
+               
+               printf( "geom pose: (%.2f,%.2f,%.2f) size: [%.2f,%.2f]\n",
                                  pose.x,
                                  pose.y,
                                  pose.a,
@@ -1577,10 +1590,6 @@
         /** OpenGL visualization of the powerpack state */
         void Visualize( Camera* cam );
 
-        /** Print human-readable status on stdout, prefixed with the
-                 argument string */
-        void Print( char* prefix ) const;
-        
         /** Returns the energy capacity minus the current amount stored */
         stg_joules_t RemainingCapacity() const;
         
@@ -1596,8 +1605,15 @@
         double ProportionRemaining() const
         { return( stored / capacity ); }
 
+        /** Print human-readable status on stdout, prefixed with the
+                 argument string, or NULL */
         void Print( const char* prefix ) const
-        { printf( "%s PowerPack %.2f/%.2f J\n", prefix, stored, capacity ); }  
        
+        { 
+               if( prefix )
+                 printf( "%s", prefix );
+
+               printf( "PowerPack %.2f/%.2f J\n", stored, capacity ); 
+        }              
         
         stg_joules_t GetStored() const;
         stg_joules_t GetCapacity() const;

Modified: code/stage/trunk/libstage/world.cc
===================================================================
--- code/stage/trunk/libstage/world.cc  2010-03-13 01:09:52 UTC (rev 8588)
+++ code/stage/trunk/libstage/world.cc  2010-03-15 17:54:04 UTC (rev 8589)
@@ -539,6 +539,13 @@
 
 bool World::Update()
 {
+  if( show_clock && ((this->updates % show_clock_interval) == 0) )
+    {
+      printf( "\r[Stage: %s]", ClockString().c_str() );
+      fflush( stdout );
+    }
+
+
   //puts( "World::Update()" );
   
   // if we've run long enough, exit
@@ -586,12 +593,6 @@
   FOR_EACH( it, active_energy )
         (*it)->UpdateCharge();
   
-  if( show_clock && ((this->updates % show_clock_interval) == 0) )
-    {
-      printf( "\r[Stage: %s]", ClockString().c_str() );
-      fflush( stdout );
-    }
-
   ++updates;  
     
   return false;

Modified: code/stage/trunk/worlds/fasr2.world
===================================================================
--- code/stage/trunk/worlds/fasr2.world 2010-03-13 01:09:52 UTC (rev 8588)
+++ code/stage/trunk/worlds/fasr2.world 2010-03-15 17:54:04 UTC (rev 8589)
@@ -16,7 +16,7 @@
 
 resolution 0.02
 
-threads 0
+threads 8
 
 # configure the GUI window
 window


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

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to