Revision: 8623
http://playerstage.svn.sourceforge.net/playerstage/?rev=8623&view=rev
Author: rtv
Date: 2010-04-26 13:50:18 +0000 (Mon, 26 Apr 2010)
Log Message:
-----------
beautifying fasr2 code
Modified Paths:
--------------
code/stage/trunk/examples/ctrl/fasr2.cc
code/stage/trunk/libstage/model_fiducial.cc
code/stage/trunk/worlds/fasr2.world
Modified: code/stage/trunk/examples/ctrl/fasr2.cc
===================================================================
--- code/stage/trunk/examples/ctrl/fasr2.cc 2010-04-24 22:47:52 UTC (rev
8622)
+++ code/stage/trunk/examples/ctrl/fasr2.cc 2010-04-26 13:50:18 UTC (rev
8623)
@@ -1,290 +1,195 @@
+#include <pthread.h>
+
#include "stage.hh"
using namespace Stg;
+// generic planner implementation
#include "astar/astar.h"
-const bool verbose = false;
+static const bool verbose = false;
// navigation control params
-const double cruisespeed = 0.4;
-const double avoidspeed = 0.05;
-const double avoidturn = 0.5;
-const double minfrontdistance = 0.7;
-const double stopdist = 0.5;
-const unsigned int avoidduration = 10;
-const unsigned int PAYLOAD = 1;
+static const double cruisespeed = 0.4;
+static const double avoidspeed = 0.05;
+static const double avoidturn = 0.5;
+static const double minfrontdistance = 0.7;
+static const double stopdist = 0.5;
+static const unsigned int avoidduration = 10;
+static const unsigned int PAYLOAD = 1;
-//const int TRAIL_LENGTH_MAX = 500;
-typedef enum {
- MODE_WORK=0,
- MODE_DOCK,
- MODE_UNDOCK,
- MODE_QUEUE
-} nav_mode_t;
-
-
-
-// abstract base class
-class Queue
+static unsigned int
+MetersToCell( stg_meters_t m, stg_meters_t size_m, unsigned int size_c )
{
-public:
- Queue() {};
- virtual ~Queue() {}
-
- virtual int Clear() = 0;
- virtual int Position( const char* id ) = 0;
- virtual int Join( const char* id ) = 0;
- virtual int Leave( const char* id ) = 0;
-};
-
-// on-host implementation
-#include <list>
-
-class Task
-{
-public:
- Model* source;
- Model* sink;
- unsigned int participants;
-
- Task( Model* source, Model* sink )
- : source(source), sink(sink), participants(0)
- {}
-};
-
-class LocalQueue : public Queue
-{
-public:
- std::list<std::string> list;
- //pthread_mutex_t* mutex;
-
- LocalQueue() :
- Queue(),
- list()
- //mutex( NULL )
- {
- //pthread_mutex_init( &mutex, NULL );
- }
-
- virtual int Clear()
- {
- list.clear();
- return 0;
- }
-
- virtual int Position( const char* id )
- {
- std::list<std::string>::iterator it( std::find( list.begin(),
list.end(), std::string(id) ));
-
- if( it == list.end() )
- return -1;
- else
- return std::distance( list.begin(), it );
- }
-
- virtual int Join( const char* id )
- {
- list.push_back( id );
- return 0;
- }
-
- virtual int Leave( const char* id )
- {
- list.erase( std::remove( list.begin(), list.end(), std::string(id)));
- return 0;
- }
-
- virtual void Print( const char* prefix )
- {
- printf( "%s queue:\n", prefix );
- FOR_EACH( it, list )
- printf( "\t%s\n", it->c_str() );
- }
-};
-
-
-class Node;
-
-class Edge
-{
-public:
- Node* to;
- double cost;
-
- Edge( Node* to, double cost=1.0 )
- : to(to), cost(cost) {}
-};
-
-class Node
-{
-public:
- Pose pose;
- double value;
- std::vector<Edge*> edges;
-
- Node( Pose pose )
- : pose(pose), value(0), edges() {}
-
- ~Node()
- {
- FOR_EACH( it, edges )
- { delete *it; }
- }
-
- void AddEdge( Edge* edge )
- {
- assert(edge);
- edges.push_back( edge );
- }
-
- void Draw() const;
-};
-
-
-class Graph
-{
-public:
- std::vector<Node*> nodes;
-
- Graph(){}
- ~Graph() { FOR_EACH( it, nodes ){ delete *it; }}
-
- void AddNode( Node* node ){ nodes.push_back( node ); }
-
- void PopFront()
- {
- const std::vector<Node*>::iterator& it = nodes.begin();
- delete *it;
- nodes.erase( it );
- }
-
- void Draw() const
- {
- glPointSize(3);
- FOR_EACH( it, nodes ){ (*it)->Draw(); }
- }
-
- bool GoodDirection( const Pose& pose, stg_meters_t range, stg_radians_t&
heading_result )
- {
- // find the node with the lowest value within range of the given
- // pose and return the absolute heading from pose to that node
-
- if( nodes.empty() )
- return 0; // a null guess
-
-
- Node* best_node = NULL;
-
- // find the closest node
- FOR_EACH( it, nodes )
- {
- Node* node = *it;
- double dist = hypot( node->pose.x - pose.x, node->pose.y -
pose.y );
-
- // if it's in range, and either its the first we have found,
- // or it has a lower value than the current best
- if( dist < range &&
- ( best_node == NULL || node->value <
best_node->value ))
- {
- best_node = node;
- }
- }
-
- if( best_node == NULL )
- {
- printf( "FASR warning: no nodes in range" );
- return false;
- }
-
- //else
- heading_result = atan2( best_node->pose.y - pose.y,
-
best_node->pose.x - pose.x );
-
- // add a little bias
- heading_result = normalize( heading_result + 0.25 );
-
- return true;
- }
-};
-
-
-class GraphVis : public Visualizer
-{
-public:
- Graph& graph;
-
- GraphVis( Graph& graph )
- : Visualizer( "graph", "vis_graph" ), graph(graph) {}
- virtual ~GraphVis(){}
-
- virtual void Visualize( Model* mod, Camera* cam )
- {
-
- glPushMatrix();
-
- Gl::pose_inverse_shift( mod->GetGlobalPose() );
-
- //mod->PushColor( 1,0,0,1 );
-
- Color c = mod->GetColor();
- c.a = 0.4;
-
- mod->PushColor( c );
- graph.Draw();
- mod->PopColor();
-
- glPopMatrix();
- }
-};
-
-
-
-void Node::Draw() const
-{
- // print value
- //char buf[32];
- //snprintf( buf, 32, "%.0f", value );
- //Gl::draw_string( pose.x, pose.y+0.2, 0.1, buf );
-
- //glBegin( GL_POINTS );
- //glVertex2f( pose.x, pose.y );
- //glEnd();
-
- glBegin( GL_LINES );
- FOR_EACH( it, edges )
- {
- glVertex2f( pose.x, pose.y );
- glVertex2f( (*it)->to->pose.x, (*it)->to->pose.y );
- }
- glEnd();
-}
-
-unsigned int MetersToCell( stg_meters_t m, stg_meters_t size_m, unsigned int
size_c )
-{
m += size_m / 2.0; // shift to local coords
m /= size_m / (float)size_c; // scale
return (unsigned int)floor(m); // quantize
}
-stg_meters_t CellToMeters( unsigned int c, stg_meters_t size_m, unsigned int
size_c )
+static stg_meters_t
+CellToMeters( unsigned int c, stg_meters_t size_m, unsigned int size_c )
{
stg_meters_t cell_size = size_m/(float)size_c;
stg_meters_t m = c * cell_size; // scale
m -= size_m / 2.0; // shift to local coords
-
return m + cell_size/2.0; // offset to cell center
}
-#include <pthread.h>
-
class Robot
{
+public:
+ class Task
+ {
+ public:
+ Model* source;
+ Model* sink;
+ unsigned int participants;
+
+ Task( Model* source, Model* sink )
+ : source(source), sink(sink), participants(0)
+ {}
+ };
+
+ static std::vector<Task> tasks;
+
private:
- static std::vector<Robot*> robots;
+ class Node;
+
+ class Edge
+ {
+ public:
+ Node* to;
+ double cost;
+
+ Edge( Node* to, double cost=1.0 )
+ : to(to), cost(cost) {}
+ };
+
+ class Node
+ {
+ public:
+ Pose pose;
+ double value;
+ std::vector<Edge*> edges;
+
+ Node( Pose pose, double value=0 )
+ : pose(pose), value(value), edges() {}
+
+ ~Node()
+ {
+ FOR_EACH( it, edges )
+ { delete *it; }
+ }
+
+ void AddEdge( Edge* edge )
+ {
+ assert(edge);
+ edges.push_back( edge );
+ }
+
+ void Draw() const;
+ };
+
+ class Graph
+ {
+ public:
+ std::vector<Node*> nodes;
+
+ Graph(){}
+ ~Graph() { FOR_EACH( it, nodes ){ delete *it; }}
+
+ void AddNode( Node* node ){ nodes.push_back( node ); }
+
+ void PopFront()
+ {
+ const std::vector<Node*>::iterator& it = nodes.begin();
+ delete *it;
+ nodes.erase( it );
+ }
+
+ void Draw() const
+ {
+ glPointSize(3);
+ FOR_EACH( it, nodes ){ (*it)->Draw(); }
+ }
+
+ bool GoodDirection( const Pose& pose, stg_meters_t range,
stg_radians_t& heading_result )
+ {
+ // find the node with the lowest value within range of
the given
+ // pose and return the absolute heading from pose to
that node
+
+ if( nodes.empty() )
+ return 0; // a null guess
+
+
+ Node* best_node = NULL;
+
+ // find the closest node
+ FOR_EACH( it, nodes )
+ {
+ Node* node = *it;
+ double dist = hypot( node->pose.x -
pose.x, node->pose.y - pose.y );
+
+ // if it's in range, and either its the
first we have found,
+ // or it has a lower value than the
current best
+ if( dist < range &&
+ ( best_node == NULL ||
node->value < best_node->value ))
+ {
+ best_node = node;
+ }
+ }
+
+ if( best_node == NULL )
+ {
+ printf( "FASR warning: no nodes in
range" );
+ return false;
+ }
+ //else
+ heading_result = atan2( best_node->pose.y - pose.y,
+
best_node->pose.x - pose.x );
+
+ // add a little bias to one side (the left) - creates
two lanes
+ // of robot traffic
+ heading_result = normalize( heading_result + 0.25 );
+
+ return true;
+ }
+ };
+
+ class GraphVis : public Visualizer
+ {
+ public:
+ Graph& graph;
+
+ GraphVis( Graph& graph )
+ : Visualizer( "graph", "vis_graph" ), graph(graph) {}
+ virtual ~GraphVis(){}
+
+ virtual void Visualize( Model* mod, Camera* cam )
+ {
+
+ glPushMatrix();
+
+ Gl::pose_inverse_shift( mod->GetGlobalPose() );
+
+ //mod->PushColor( 1,0,0,1 );
+
+ Color c = mod->GetColor();
+ c.a = 0.4;
+
+ mod->PushColor( c );
+ graph.Draw();
+ mod->PopColor();
+
+ glPopMatrix();
+ }
+ };
+
+
+private:
long int wait_started_at;
ModelPosition* pos;
@@ -294,7 +199,6 @@
unsigned int task;
- //Model *source, *sink;
Model* fuel_zone;
Model* pool_zone;
int avoidcount, randcount;
@@ -303,8 +207,14 @@
double charger_bearing;
double charger_range;
double charger_heading;
- nav_mode_t mode;
-
+
+ enum {
+ MODE_WORK=0,
+ MODE_DOCK,
+ MODE_UNDOCK,
+ MODE_QUEUE
+ } mode;
+
stg_radians_t docked_angle;
static pthread_mutex_t planner_mutex;
@@ -318,8 +228,8 @@
unsigned int node_interval;
unsigned int node_interval_countdown;
- static unsigned int map_width;
- static unsigned int map_height;
+ static const unsigned int map_width;
+ static const unsigned int map_height;
static uint8_t* map_data;
static Model* map_model;
@@ -329,817 +239,741 @@
bool force_recharge;
- static std::vector<LocalQueue> queues;
-
public:
- static std::vector<Task> tasks;
Robot( ModelPosition* pos,
- Model* fuel,
- Model* pool )
- :
- wait_started_at(-1),
- pos(pos),
- laser( (ModelLaser*)pos->GetUnusedModelOfType( "laser" )),
- ranger( (ModelRanger*)pos->GetUnusedModelOfType( "ranger" )),
- fiducial( (ModelFiducial*)pos->GetUnusedModelOfType( "fiducial" )),
- task(random() % tasks.size() ), // choose a task at random
- fuel_zone(fuel),
- pool_zone(pool),
- avoidcount(0),
- randcount(0),
- work_get(0),
- work_put(0),
- charger_ahoy(false),
- charger_bearing(0),
- charger_range(0),
- charger_heading(0),
- mode(MODE_WORK),
- docked_angle(0),
- goal(tasks[task].source),
- cached_goal_pose(),
- graph(),
- graphvis( graph ),
- last_node( NULL ),
- node_interval( 20 ),
- node_interval_countdown( node_interval ),
- fiducial_sub(false),
- laser_sub(false),
- ranger_sub(false),
- force_recharge( false )
+ Model* fuel,
+ Model* pool )
+ :
+ wait_started_at(-1),
+ pos(pos),
+ laser( (ModelLaser*)pos->GetUnusedModelOfType( "laser" )),
+ ranger( (ModelRanger*)pos->GetUnusedModelOfType( "ranger" )),
+ fiducial( (ModelFiducial*)pos->GetUnusedModelOfType( "fiducial"
)),
+ task(random() % tasks.size() ), // choose a task at random
+ fuel_zone(fuel),
+ pool_zone(pool),
+ avoidcount(0),
+ randcount(0),
+ work_get(0),
+ work_put(0),
+ charger_ahoy(false),
+ charger_bearing(0),
+ charger_range(0),
+ charger_heading(0),
+ mode(MODE_WORK),
+ docked_angle(0),
+ goal(tasks[task].source),
+ cached_goal_pose(),
+ graph(),
+ graphvis( graph ),
+ last_node( NULL ),
+ node_interval( 20 ),
+ node_interval_countdown( node_interval ),
+ fiducial_sub(false),
+ laser_sub(false),
+ ranger_sub(false),
+ force_recharge( false )
{
- // add myself to the static list of all robots
- robots.push_back( this );
-
- // need at least these models to get any work done
- // (pos must be good, as we used it in the initialization list)
- assert( laser );
- assert( fiducial );
- assert( ranger );
- assert( goal );
+ // need at least these models to get any work done
+ // (pos must be good, as we used it in the initialization list)
+ assert( laser );
+ assert( fiducial );
+ assert( ranger );
+ assert( goal );
- // match the color of my destination
- pos->SetColor( tasks[task].source->GetColor() );
+ // match the color of my destination
+ pos->SetColor( tasks[task].source->GetColor() );
+
+ tasks[task].participants++;
+
+ EnableLaser(true);
- tasks[task].participants++;
+ // we access all other data from the position callback
+ pos->AddCallback( Model::CB_UPDATE,
(stg_model_callback_t)UpdateCallback, this );
+ pos->Subscribe();
- // pos->GetUnusedModelOfType( "laser" );
+ pos->AddVisualizer( &graphvis, true );
- // PositionUpdate() checks to see if we reached source or sink
- pos->AddCallback( Model::CB_UPDATE,
(stg_model_callback_t)UpdateCallback, this );
- pos->Subscribe();
-
-
- // no other callbacks - we access all other data from the position
- // callback
- EnableLaser(true);
-
- pos->AddVisualizer( &graphvis, true );
-
- if( map_data == NULL )
- {
- map_data = new uint8_t[map_width*map_height*2];
+ if( map_data == NULL )
+ {
+ map_data = new uint8_t[map_width*map_height*2];
- // MUST clear the data, since Model::Rasterize() only enters
- // non-zero pixels
- memset( map_data, 0, sizeof(uint8_t) * map_width *
map_height);
+ // MUST clear the data, since
Model::Rasterize() only enters
+ // non-zero pixels
+ memset( map_data, 0, sizeof(uint8_t) *
map_width * map_height);
- // get the map
- map_model = pos->GetWorld()->GetModel( "cave" );
- assert(map_model);
- Geom g = map_model->GetGeom();
+ // get the map
+ map_model = pos->GetWorld()->GetModel( "cave" );
+ assert(map_model);
+ Geom g = map_model->GetGeom();
- map_model->Rasterize( map_data,
-
map_width,
-
map_height,
-
g.size.x/(float)map_width,
-
g.size.y/(float)map_height );
+ map_model->Rasterize( map_data,
+
map_width,
+
map_height,
+
g.size.x/(float)map_width,
+
g.size.y/(float)map_height );
- // fix the node costs for astar: 0=>1, 1=>9
+ // fix the node costs for astar: 0=>1, 1=>9
- unsigned int sz = map_width * map_height;
- for( unsigned int i=0; i<sz; i++ )
- {
- if( map_data[i] == 0 )
- map_data[i] = 1;
- else if( map_data[i] == 1 )
- map_data[i] = 9;
- else
- printf( "FASR: bad value %d in map at index
%d\n", (int)map_data[i], (int)i );
+ unsigned int sz = map_width * map_height;
+ for( unsigned int i=0; i<sz; i++ )
+ {
+ if( map_data[i] == 0 )
+ map_data[i] = 1;
+ else if( map_data[i] == 1 )
+ map_data[i] = 9;
+ else
+ 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) );
- }
- }
+ assert( (map_data[i] == 1) ||
(map_data[i] == 9) );
+ }
+ }
- //( goal );
- //puts("");
+ //( goal );
+ //puts("");
}
-
-
+
+ void Enable( Stg::Model* model, bool& sub, bool on )
+ {
+ if( on && !sub )
+ {
+ sub = true;
+ model->Subscribe();
+ }
+
+ if( !on && sub )
+ {
+ sub = false;
+ model->Unsubscribe();
+ }
+ }
+
void EnableRanger( bool on )
{
- if( on && !ranger_sub )
- {
- ranger_sub = true;
- ranger->Subscribe();
- }
-
- if( !on && ranger_sub )
- {
- ranger_sub = false;
- ranger->Unsubscribe();
- }
+ Enable( ranger, ranger_sub, on );
}
void EnableLaser( bool on )
{
- if( on && !laser_sub )
- {
- laser_sub = true;
- laser->Subscribe();
- }
-
- if( !on && laser_sub )
- {
- laser_sub = false;
- laser->Unsubscribe();
- }
+ Enable( laser, laser_sub, on );
}
void EnableFiducial( bool on )
{
- if( on && !fiducial_sub )
- {
- fiducial_sub = true;
- fiducial->Subscribe();
- }
-
- if( !on && fiducial_sub )
- {
- fiducial_sub = false;
- fiducial->Unsubscribe();
- }
+ Enable( fiducial, fiducial_sub, on );
}
void Plan( Pose sp )
{
- // change my color to that of my destination
- //pos->SetColor( dest->GetColor() );
-
- Pose pose = pos->GetPose();
- //Pose sp = dest->GetPose();
- Geom g = map_model->GetGeom();
-
- point_t start( MetersToCell(pose.x, g.size.x, map_width),
- MetersToCell(pose.y, g.size.y,
map_height) );
- point_t goal( MetersToCell(sp.x, g.size.x, map_width),
- MetersToCell(sp.y, g.size.y,
map_height) );
-
- //printf( "searching from (%.2f, %.2f) [%d, %d]\n", pose.x, pose.y,
start.x, start.y );
- //printf( "searching to (%.2f, %.2f) [%d, %d]\n", sp.x, sp.y,
goal.x, goal.y );
+ // change my color to that of my destination
+ //pos->SetColor( dest->GetColor() );
+
+ Pose pose = pos->GetPose();
+ Geom g = map_model->GetGeom();
+
+ point_t start( MetersToCell(pose.x, g.size.x, map_width),
+
MetersToCell(pose.y, g.size.y, map_height) );
+ point_t goal( MetersToCell(sp.x, g.size.x, map_width),
+
MetersToCell(sp.y, g.size.y, map_height) );
+
+ //printf( "searching from (%.2f, %.2f) [%d, %d]\n", pose.x,
pose.y, start.x, start.y );
+ //printf( "searching to (%.2f, %.2f) [%d, %d]\n", sp.x, sp.y,
goal.x, goal.y );
+
+ // astar() is not reentrant, so we protect it thus
+ pthread_mutex_lock( &planner_mutex );
+
+ std::vector<point_t> path;
+ bool result = astar( map_data,
+
map_width,
+
map_height,
+
start,
+
goal,
+
path );
- // astar() is not reentrant, so we protect it thus
- pthread_mutex_lock( &planner_mutex );
-
- std::vector<point_t> path;
- bool result = astar( map_data,
- map_width,
- map_height,
- start,
- goal,
- path );
-
- pthread_mutex_unlock( &planner_mutex );
+ 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 );
+ 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 );
- graph.nodes.clear();
+ graph.nodes.clear();
- unsigned int dist = 0;
- //FOR_EACH( it, path )
- for( std::vector<point_t>::const_reverse_iterator rit = path.rbegin();
- rit != path.rend();
- ++rit )
- {
- //printf( "%d, %d\n", it->x, it->y );
+ unsigned int dist = 0;
+
+ for( std::vector<point_t>::const_reverse_iterator rit =
path.rbegin();
+ rit != path.rend();
+ ++rit )
+ {
+ //printf( "%d, %d\n", it->x, it->y );
+
+ Node* node = new Node( Pose(
CellToMeters(rit->x, g.size.x, map_width ),
+
CellToMeters(rit->y, g.size.y, map_height),
+
0, 0 ),
+
dist++ ); // value stored at node
- Node* node = new Node( Pose( CellToMeters(rit->x, g.size.x,
map_width ),
-
CellToMeters(rit->y, g.size.y, map_height),
-
0, 0 ) );
+ graph.AddNode( node );
- node->value = dist++;
+ if( last_node )
+ last_node->AddEdge( new Edge( node ) );
- graph.AddNode( node );
-
- if( last_node )
- last_node->AddEdge( new Edge( node ) );
-
- last_node = node;
- }
+ last_node = node;
+ }
}
void Dock()
{
- const stg_meters_t creep_distance = 0.5;
+ const stg_meters_t creep_distance = 0.5;
- if( charger_ahoy )
- {
- // drive toward the charger
- double a_goal = normalize( charger_bearing );
-
- // helps to align with the way the charger is pointing
- double orient = normalize( M_PI - (charger_bearing -
charger_heading) );
-
- a_goal = normalize( a_goal - 2.0 * orient );
+ if( charger_ahoy )
+ {
+ // drive toward the charger
+ // orient term helps to align with the way the
charger is pointing
+ const double orient = normalize( M_PI -
(charger_bearing - charger_heading) );
+ const double a_goal = normalize(
charger_bearing - 2.0 * orient );
- if( charger_range > creep_distance )
- {
- if( !ObstacleAvoid() )
- {
- pos->SetXSpeed( cruisespeed );
- pos->SetTurnSpeed( a_goal );
- }
- }
- else // we are very close!
- {
- pos->SetTurnSpeed( a_goal );
- pos->SetXSpeed( 0.02 ); // creep towards it
+ if( charger_range > creep_distance )
+ {
+ if( !ObstacleAvoid() )
+ {
+ pos->SetXSpeed(
cruisespeed );
+
pos->SetTurnSpeed( a_goal );
+ }
+ }
+ else // we are very close!
+ {
+ pos->SetTurnSpeed( a_goal );
+ pos->SetXSpeed( 0.02 ); //
creep towards it
- if( charger_range < 0.08 ) // close enough
- {
- pos->Stop();
- docked_angle = pos->GetPose().a;
- EnableLaser( false );
- }
+ if( charger_range < 0.08 ) //
close enough
+ {
+ pos->Stop();
+ docked_angle =
pos->GetPose().a;
+ EnableLaser(
false );
+ }
- if( pos->Stalled() ) // touching
- pos->SetXSpeed( -0.01 ); // back off a bit
- }
- }
- else
- {
- //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
- }
+ if( pos->Stalled() ) // touching
+ pos->SetXSpeed( -0.01
); // back off a bit
+ }
+ }
+ else
+ {
+ //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
+ }
- // if the battery is charged, go back to work
- if( Full() )
- {
- //printf( "fully charged, now back to work\n" );
- mode = MODE_UNDOCK;
- EnableRanger(true); // enable the sonar to see behind us
- EnableLaser(true);
- EnableFiducial(true);
- force_recharge = false;
- }
+ // if the battery is charged, go back to work
+ if( Full() )
+ {
+ //printf( "fully charged, now back to work\n"
);
+ mode = MODE_UNDOCK;
+ EnableRanger(true); // enable the sonar to see
behind us
+ EnableLaser(true);
+ EnableFiducial(true);
+ force_recharge = false;
+ }
}
void SetTask( unsigned int t )
{
- //tasks[task].participants--;
- task = t;
- tasks[task].participants++;
+ task = t;
+ tasks[task].participants++;
}
void UnDock()
{
- const stg_meters_t back_off_distance = 0.2;
- const stg_meters_t back_off_speed = -0.02;
- const stg_radians_t undock_rotate_speed = 0.3;
- const stg_meters_t wait_distance = 0.2;
- const unsigned int BACK_SENSOR_FIRST = 10;
- const unsigned int BACK_SENSOR_LAST = 13;
+ const stg_meters_t back_off_distance = 0.2;
+ const stg_meters_t back_off_speed = -0.02;
+ const stg_radians_t undock_rotate_speed = 0.3;
+ const stg_meters_t wait_distance = 0.2;
+ 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 );
+ // make sure the required sensors are running
+ assert( ranger_sub );
+ assert( fiducial_sub );
- if( charger_range < back_off_distance )
- {
- pos->SetXSpeed( back_off_speed );
+ if( charger_range < back_off_distance )
+ {
+ pos->SetXSpeed( back_off_speed );
- pos->Say( "" );
+ pos->Say( "" );
- // stay put while anything is close behind
- const std::vector<ModelRanger::Sensor>& sensors =
ranger->GetSensors();
+ // stay put while anything is close behind
+ const std::vector<ModelRanger::Sensor>& sensors
= ranger->GetSensors();
- for( unsigned int s = BACK_SENSOR_FIRST; s <=
BACK_SENSOR_LAST; ++s )
- if( sensors[s].range < wait_distance)
- {
- pos->Say( "Waiting..." );
- pos->SetXSpeed( 0.0 );
- return;
- }
- }
- else
- { // we've backed up enough
+ for( unsigned int s = BACK_SENSOR_FIRST; s <=
BACK_SENSOR_LAST; ++s )
+ if( sensors[s].range < wait_distance)
+ {
+ pos->Say( "Waiting..."
);
+ pos->SetXSpeed( 0.0 );
+ return;
+ }
+ }
+ else
+ { // we've backed up enough
- double heading_error = normalize( pos->GetPose().a -
(docked_angle + M_PI ) );
+ double heading_error = normalize(
pos->GetPose().a - (docked_angle + M_PI ) );
- if( fabs( heading_error ) > 0.05 )
- {
- // turn
- pos->SetXSpeed( 0 );
- pos->SetTurnSpeed( undock_rotate_speed *
sgn(-heading_error) );
- }
- else
- {
- // we're pointing the right way, so we're done
- mode = MODE_WORK;
-
- // if we're not working on a drop-off
- if( pos->GetFlagCount() == 0 )
- {
- // pick a new task at random
- SetTask( random() % tasks.size() );
- SetGoal( tasks[task].source );
- }
+ if( fabs( heading_error ) > 0.05 )
+ {
+ // turn
+ pos->SetXSpeed( 0 );
+ pos->SetTurnSpeed(
undock_rotate_speed * sgn(-heading_error) );
+ }
else
- SetGoal( tasks[task].sink );
+ {
+ // we're pointing the right
way, so we're done
+ mode = MODE_WORK;
+
+ // if we're not working on a
drop-off
+ if( pos->GetFlagCount() == 0 )
+ {
+ // pick a new
task at random
+ SetTask(
random() % tasks.size() );
+ SetGoal(
tasks[task].source );
+ }
+ else
+ SetGoal(
tasks[task].sink );
- EnableFiducial(false);
- EnableRanger(false);
- }
- }
+ EnableFiducial(false);
+ EnableRanger(false);
+ }
+ }
}
bool ObstacleAvoid()
{
- bool obstruction = false;
- bool stop = false;
+ bool obstruction = false;
+ bool stop = false;
- // find the closest distance to the left and right and check if
- // there's anything in front
- double minleft = 1e6;
- double minright = 1e6;
+ // find the closest distance to the left and right and check if
+ // there's anything in front
+ double minleft = 1e6;
+ double minright = 1e6;
- // Get the data
- const std::vector<ModelLaser::Sample>& scan = laser->GetSamples();
+ // Get the data
+ const std::vector<ModelLaser::Sample>& scan =
laser->GetSamples();
uint32_t sample_count = scan.size();
- for (uint32_t i = 0; i < sample_count; i++)
- {
- if( verbose ) printf( "%.3f ", scan[i].range );
+ for (uint32_t i = 0; i < sample_count; i++)
+ {
+ if( verbose ) printf( "%.3f ", scan[i].range );
- if( (i > (sample_count/4))
- && (i < (sample_count - (sample_count/4)))
- && scan[i].range < minfrontdistance)
- {
- if( verbose ) puts( " obstruction!" );
- obstruction = true;
- }
+ if( (i > (sample_count/4))
+ && (i < (sample_count -
(sample_count/4)))
+ && scan[i].range <
minfrontdistance)
+ {
+ if( verbose ) puts( "
obstruction!" );
+ obstruction = true;
+ }
- if( scan[i].range < stopdist )
- {
- if( verbose ) puts( " stopping!" );
- stop = true;
- }
+ if( scan[i].range < stopdist )
+ {
+ if( verbose ) puts( "
stopping!" );
+ stop = true;
+ }
- if( i > sample_count/2 )
- minleft = std::min( minleft, scan[i].range );
- else
- minright = std::min( minright, scan[i].range );
- }
+ if( i > sample_count/2 )
+ minleft = std::min( minleft,
scan[i].range );
+ else
+ minright = std::min( minright,
scan[i].range );
+ }
- if( verbose )
- {
- puts( "" );
- printf( "minleft %.3f \n", minleft );
- printf( "minright %.3f\n ", minright );
- }
+ if( verbose )
+ {
+ puts( "" );
+ printf( "minleft %.3f \n", minleft );
+ printf( "minright %.3f\n ", minright );
+ }
- if( obstruction || stop || (avoidcount>0) )
- {
- if( verbose ) printf( "Avoid %d\n", avoidcount );
+ if( obstruction || stop || (avoidcount>0) )
+ {
+ if( verbose ) printf( "Avoid %d\n", avoidcount
);
- pos->SetXSpeed( stop ? 0.0 : avoidspeed );
+ pos->SetXSpeed( stop ? 0.0 : avoidspeed );
- /* once we start avoiding, select a turn direction and stick
- with it for a few iterations */
- if( avoidcount < 1 )
- {
- if( verbose ) puts( "Avoid START" );
- avoidcount = random() % avoidduration +
avoidduration;
+ /* once we start avoiding, select a turn
direction and stick
+ with it for a few iterations */
+ if( avoidcount < 1 )
+ {
+ if( verbose ) puts( "Avoid
START" );
+ avoidcount = random() %
avoidduration + avoidduration;
- if( minleft < minright )
- {
- pos->SetTurnSpeed( -avoidturn );
- if( verbose ) printf( "turning right
%.2f\n", -avoidturn );
- }
- else
- {
- pos->SetTurnSpeed( +avoidturn );
- if( verbose ) printf( "turning left
%2f\n", +avoidturn );
- }
- }
+ if( minleft < minright )
+ {
+
pos->SetTurnSpeed( -avoidturn );
+ if( verbose )
printf( "turning right %.2f\n", -avoidturn );
+ }
+ else
+ {
+
pos->SetTurnSpeed( +avoidturn );
+ if( verbose )
printf( "turning left %2f\n", +avoidturn );
+ }
+ }
- avoidcount--;
+ avoidcount--;
- return true; // busy avoding obstacles
- }
+ return true; // busy avoding obstacles
+ }
- return false; // didn't have to avoid anything
+ return false; // didn't have to avoid anything
}
void SetGoal( Model* goal )
{
- if( goal != this->goal )
- {
- this->goal = goal;
- Plan( goal->GetPose() );
- pos->SetColor( goal->GetColor() );
- }
+ if( goal != this->goal )
+ {
+ this->goal = goal;
+ Plan( goal->GetPose() );
+ pos->SetColor( goal->GetColor() );
+ }
}
void Work()
{
- if( ! ObstacleAvoid() )
- {
- if( verbose ) puts( "Cruise" );
-
- //avoidcount = 0;
-
- Pose pose = pos->GetPose();
-
- double a_goal = 0;
+ if( ! ObstacleAvoid() )
+ {
+ if( verbose )
+ puts( "Cruise" );
+
+ if( Hungry() )
+ SetGoal( fuel_zone );
+
+ const Pose pose = pos->GetPose();
+ double a_goal = 0;
+
+ // 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) )
+ {
+ //printf( "%s replanning from
(%.2f,%.2f) to %s at (%.2f,%.2f) in Work()\n",
+ // pos->Token(),
+ // pose.x, pose.y,
+ // goal->Token(),
+ // goal->GetPose().x,
+ // goal->GetPose().y );
+ Plan( goal->GetPose() );
+ cached_goal_pose =
goal->GetPose();
+ }
- // dtor( ( pos->GetFlagCount() ) ? have[y][x] :
need[y][x] ); // map
- //atan2( gp.y - pose.y, gp.x - pose.x ); // crow flies
- // use direction of lowest value node within range in
graph
-
-
- // Model* goal = fuel_zone;
-
- if( Hungry() )
- SetGoal( fuel_zone );
-
- // 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) )
- {
- //printf( "%s replanning from (%.2f,%.2f) to %s
at (%.2f,%.2f) in Work()\n",
- // pos->Token(),
- // pose.x, pose.y,
- // goal->Token(),
- // goal->GetPose().x,
- // goal->GetPose().y );
- Plan( goal->GetPose() );
- cached_goal_pose = goal->GetPose();
- }
-
- // if we are low on juice - find the direction to the
recharger instead
- if( Hungry() )
- {
- EnableFiducial(true);
-
- //puts( "hungry - using refuel map" );
+ // if we are low on juice - find the direction
to the recharger instead
+ if( Hungry() )
+ {
+ EnableFiducial(true);
- // use the refuel map
- //a_goal = dtor( refuel[y][x] );
+ while( graph.GoodDirection(
pose, 4.0, a_goal ) == 0 )
+ {
+ printf( "%s
replanning in Work()\n", pos->Token() );
+ }
- while( graph.GoodDirection( pose, 4.0, a_goal )
== 0 )
- {
- printf( "%s replanning in Work()\n",
pos->Token() );
- }
+ if( charger_ahoy ) // I see a
charger while hungry!
+ mode = MODE_DOCK;
+ }
- if( charger_ahoy ) // I see a charger while
hungry!
- mode = MODE_DOCK;
- }
-
- double a_error = normalize( a_goal - pose.a );
- pos->SetTurnSpeed( a_error );
-
- //double a_error_size = fabs(a_error);
-
- //if( a_error_size < 1.0 )
- //pos->SetXSpeed( (1.0 - a_error_size) * cruisespeed
);
- //else
- //pos->SetXSpeed( 0.0 );
- pos->SetXSpeed( cruisespeed );
- }
+ const double a_error = normalize( a_goal -
pose.a );
+ pos->SetTurnSpeed( a_error );
+ pos->SetXSpeed( cruisespeed );
+ }
}
bool Hungry()
{
- return( force_recharge || pos->FindPowerPack()->ProportionRemaining()
< 0.2 );
+ return( force_recharge ||
pos->FindPowerPack()->ProportionRemaining() < 0.2 );
}
bool Full()
{
- return( pos->FindPowerPack()->ProportionRemaining() > 0.95 );
+ return( pos->FindPowerPack()->ProportionRemaining() > 0.95 );
}
// static callback wrapper
static int UpdateCallback( ModelLaser* laser, Robot* robot )
{
- return robot->Update();
+ return robot->Update();
}
int Update( void )
{
- if( strcmp( pos->Token(), "position:0") == 0 )
- {
- static int seconds = 0;
+ if( strcmp( pos->Token(), "position:0") == 0 )
+ {
+ static int seconds = 0;
- int timenow = pos->GetWorld()->SimTimeNow() / 1e6;
+ int timenow = pos->GetWorld()->SimTimeNow() /
1e6;
- if( timenow - seconds > 5 )
- {
- seconds = timenow;
+ if( timenow - seconds > 5 )
+ {
+ seconds = timenow;
- // report the task participation
- printf( "time: %d sec\n", seconds );
+ // report the task
participation
+ printf( "time: %d sec\n",
seconds );
- unsigned int sz = tasks.size();
- for( unsigned int i=0; i<sz; ++i )
- printf( "\t task[%u] %3u (%s)\n",
- i,
tasks[i].participants, tasks[i].source->Token() );
- }
- }
+ unsigned int sz = tasks.size();
+ for( unsigned int i=0; i<sz;
++i )
+ printf( "\t task[%u]
%3u (%s)\n",
+
i, tasks[i].participants, tasks[i].source->Token() );
+ }
+ }
- Pose pose = pos->GetPose();
+ Pose pose = pos->GetPose();
#if 0
- // when countdown reaches zero
- if( --node_interval_countdown == 0 )
- {
- // reset countdown
- node_interval_countdown = node_interval;
+ // when countdown reaches zero
+ if( --node_interval_countdown == 0 )
+ {
+ // reset countdown
+ node_interval_countdown = node_interval;
- Node* node = new Node( pose );
- graph.AddNode( node );
+ Node* node = new Node( pose );
+ graph.AddNode( node );
- if( last_node )
- last_node->AddEdge( new Edge( node ) );
+ if( last_node )
+ last_node->AddEdge( new Edge( node ) );
- last_node = node;
+ last_node = node;
- // limit the number of nodes
- while( graph.nodes.size() > TRAIL_LENGTH_MAX )
- graph.PopFront();
- }
+ // limit the number of nodes
+ while( graph.nodes.size() > TRAIL_LENGTH_MAX )
+ graph.PopFront();
+ }
#endif
- // assume we can't see the charger
- charger_ahoy = false;
+ // 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 the fiducial is enabled
+ if( fiducial_sub )
+ {
+ std::vector<ModelFiducial::Fiducial>& fids =
fiducial->GetFiducials();
- if( fids.size() > 0 )
- {
- ModelFiducial::Fiducial* closest = NULL;
+ 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 );
+ 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];
+
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;
- }
+ // 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;
+ if( closest )
+ {
// record that I've seen it and where it is
+ charger_ahoy =
true;
- //printf( "AHOY %s\n", pos->Token() );
+ //printf( "AHOY
%s\n", pos->Token() );
- charger_bearing = closest->bearing;
- charger_range = closest->range;
- charger_heading = closest->geom.a;
- }
- }
- }
+ 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 );
+ //printf( "Pose: [%.2f %.2f %.2f %.2f]\n",
+ // pose.x, pose.y, pose.z, pose.a );
- //pose.z += 0.0001;
- //pos->SetPose( pose );
+ //pose.z += 0.0001;
+ //pos->SetPose( pose );
- if( goal == tasks[task].source )
- {
- // if we're close to the source we get a flag
- Pose sourcepose = goal->GetPose();
- Geom sourcegeom = goal->GetGeom();
+ if( goal == tasks[task].source )
+ {
+ // if we're close to the source we get a flag
+ Pose sourcepose = goal->GetPose();
+ Geom sourcegeom = goal->GetGeom();
- stg_meters_t dest_dist = hypot( sourcepose.x-pose.x,
sourcepose.y-pose.y );
+ stg_meters_t dest_dist = hypot(
sourcepose.x-pose.x, sourcepose.y-pose.y );
- // when we get close enough, we start waiting
- if( dest_dist < sourcegeom.size.x/2.0 ) // nearby
- if( wait_started_at < 0 && pos->GetFlagCount() == 0 )
- {
- wait_started_at =
pos->GetWorld()->SimTimeNow() / 1e6; // usec to seconds
- //printf( "%s begain waiting at %ld
seconds\n", pos->Token(), wait_started_at );
- }
+ // when we get close enough, we start waiting
+ if( dest_dist < sourcegeom.size.x/2.0 ) //
nearby
+ if( wait_started_at < 0 &&
pos->GetFlagCount() == 0 )
+ {
+ wait_started_at =
pos->GetWorld()->SimTimeNow() / 1e6; // usec to seconds
+ //printf( "%s begain
waiting at %ld seconds\n", pos->Token(), wait_started_at );
+ }
- if( wait_started_at > 0 )
- {
- long int waited =
(pos->GetWorld()->SimTimeNow() / 1e6) - wait_started_at;
+ if( wait_started_at > 0 )
+ {
+ //long int waited =
(pos->GetWorld()->SimTimeNow() / 1e6) - wait_started_at;
-
- // leave with small probability
- if( drand48() < 0.0005 )
- {
- //printf( "%s abandoning task %s after
waiting %ld seconds\n",
- // pos->Token(),
goal->Token(), waited );
+ // leave with small probability
+ if( drand48() < 0.0005 )
+ {
+ //printf( "%s
abandoning task %s after waiting %ld seconds\n",
+ //
pos->Token(), goal->Token(), waited );
- force_recharge = true; // forces
hungry to return true
- tasks[task].participants--;
- wait_started_at = -1;
- return 0;
- }
- }
+ force_recharge
= true; // forces hungry to return true
+
tasks[task].participants--;
+ wait_started_at
= -1;
+ return 0;
+ }
+ }
- // when we get onto the square
- if( dest_dist < sourcegeom.size.x/2.0 &&
- pos->GetFlagCount() < PAYLOAD )
- {
+ // when we get onto the square
+ if( dest_dist < sourcegeom.size.x/2.0 &&
+ pos->GetFlagCount() < PAYLOAD )
+ {
- // transfer a chunk from source to robot
- pos->PushFlag( goal->PopFlag() );
+ // transfer a chunk from source
to robot
+ pos->PushFlag( goal->PopFlag()
);
- if( pos->GetFlagCount() == 1 && wait_started_at
> 0 )
- {
- // stop waiting, since we have
received our first flag
- wait_started_at = -1;
- }
+ if( pos->GetFlagCount() == 1 &&
wait_started_at > 0 )
+ {
+ // stop
waiting, since we have received our first flag
+ wait_started_at
= -1;
+ }
- if( pos->GetFlagCount() == PAYLOAD )
- SetGoal( tasks[task].sink ); // we're done
working
- }
- }
- else if( goal == tasks[task].sink )
- {
- // if we're close to the sink we lose a flag
- Pose sinkpose = goal->GetPose();
- Geom sinkgeom = goal->GetGeom();
+ if( pos->GetFlagCount() ==
PAYLOAD )
+ SetGoal(
tasks[task].sink ); // we're done working
+ }
+ }
+ else if( goal == tasks[task].sink )
+ {
+ // if we're close to the sink we lose a flag
+ Pose sinkpose = goal->GetPose();
+ Geom sinkgeom = goal->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
- goal->PushFlag( pos->PopFlag() );
+ 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
+ goal->PushFlag( pos->PopFlag()
);
- if( pos->GetFlagCount() == 0 )
- SetGoal( tasks[task].source ); // we're done
dropping off
- }
- }
- else
- {
- assert( goal == fuel_zone || goal == pool_zone );
- }
+ if( pos->GetFlagCount() == 0 )
+ SetGoal(
tasks[task].source ); // we're done dropping off
+ }
+ }
+ else
+ {
+ assert( goal == fuel_zone || goal == pool_zone
);
+ }
- //printf( "diss: %.2f\n", pos->FindPowerPack()->GetDissipated() );
-
- // if( laser->power_pack && laser->power_pack->charging )
- // printf( "model %s power pack @%p is charging\n",
- // laser->Token(), laser->power_pack );
-
- //if( laser->GetSamples(NULL) == NULL )
- //return 0;
-
- //assert( laser->GetSamples().size() > 0 );
-
- switch( mode )
- {
- case MODE_DOCK:
- //puts( "DOCK" );
- Dock();
- break;
+ switch( mode )
+ {
+ case MODE_DOCK:
+ //puts( "DOCK" );
+ Dock();
+ break;
- case MODE_WORK:
- //puts( "WORK" );
- Work();
- break;
+ case MODE_WORK:
+ //puts( "WORK" );
+ Work();
+ break;
- case MODE_UNDOCK:
- //puts( "UNDOCK" );
- UnDock();
- break;
+ case MODE_UNDOCK:
+ //puts( "UNDOCK" );
+ UnDock();
+ break;
- //case MODE_QUEUE:
- //Queue();
-
- default:
- printf( "unrecognized mode %u\n", mode );
- }
+ default:
+ printf( "unrecognized mode %u\n", mode );
+ }
- return 0; // run again
+ return 0; // run again
}
-
-
- void JoinQueue( unsigned int q )
- {
- //puts( "joing queue" );
-
- if( queues[q].Position( pos->Token() ) < 0 )
- {
- queues[q].Join( pos->Token() );
- queues[q].Print( "q0");
- }
- }
-
-
- void LeaveQueue( unsigned int q )
- {
- queues[q].Leave( pos->Token() );
- }
-
-
static int FlagIncr( Model* mod, Robot* robot )
- {
- printf( "model %s collected flag\n", mod->Token() );
- return 0;
+ {
+ printf( "model %s collected flag\n", mod->Token() );
+ return 0;
}
static int FlagDecr( Model* mod, Robot* robot )
{
- printf( "model %s dropped flag\n", mod->Token() );
- return 0;
+ printf( "model %s dropped flag\n", mod->Token() );
+ return 0;
}
};
+void Robot::Node::Draw() const
+{
+ // print value
+ //char buf[32];
+ //snprintf( buf, 32, "%.0f", value );
+ //Gl::draw_string( pose.x, pose.y+0.2, 0.1, buf );
+
+ //glBegin( GL_POINTS );
+ //glVertex2f( pose.x, pose.y );
+ //glEnd();
+
+ glBegin( GL_LINES );
+ FOR_EACH( it, edges )
+ {
+ glVertex2f( pose.x, pose.y );
+ glVertex2f( (*it)->to->pose.x, (*it)->to->pose.y );
+ }
+ glEnd();
+}
+
+
// STATIC VARS
pthread_mutex_t Robot::planner_mutex = PTHREAD_MUTEX_INITIALIZER;
-unsigned int Robot::map_width( 50 );
-unsigned int Robot::map_height( 50 );
+const unsigned int Robot::map_width( 50 );
+const unsigned int Robot::map_height( 50 );
uint8_t* Robot::map_data( NULL );
Model* Robot::map_model( NULL );
-std::vector<LocalQueue> Robot::queues(100);
-std::vector<Robot*> Robot::robots;
-std::vector<Task> Robot::tasks;
+std::vector<Robot::Task> Robot::tasks;
void split( const std::string& text, const std::string& separators,
std::vector<std::string>& words)
{
- int n = text.length();
+ const int n = text.length();
int start, stop;
start = text.find_first_not_of(separators);
while ((start >= 0) && (start < n))
- {
- stop = text.find_first_of(separators, start);
- if ((stop < 0) || (stop > n)) stop = n;
- words.push_back(text.substr(start, stop - start));
- start = text.find_first_not_of(separators, stop+1);
- }
+ {
+ stop = text.find_first_of(separators, start);
+ if ((stop < 0) || (stop > n)) stop = n;
+ words.push_back(text.substr(start, stop - start));
+ start = text.find_first_not_of(separators, stop+1);
+ }
}
// Stage calls this when the model starts up
-extern "C" int Init( Model* mod, CtrlArgs* args )
+extern "C" int Init( ModelPosition* mod, CtrlArgs* args )
{
- //printf( "%s args: %s\n", mod->Token(), args->worldfile.c_str() );
-
- // tokenize the argument string into words
- std::vector<std::string> words;
- split( args->worldfile, std::string(" \t"), words );
-
- // printf( "words size %u\n", words.size() );
- //FOR_EACH( it, words )
- // printf( "word: %s\n", it->c_str() );
- //puts( "" );
-
- // expecting a task color name as the 1th argument
- assert( words.size() > 1 );
-
// some init for only the first controller
if( Robot::tasks.size() == 0 )
- {
- srandom( time(NULL) );
-
- World* w = mod->GetWorld();
- for( unsigned int s=1; s<words.size(); s++ )
- Robot::tasks.push_back( Task( w->GetModel( words[s] +
"_source"),
-
w->GetModel( words[s] + "_sink") ) );
- }
-
- new Robot( (ModelPosition*)mod,
- mod->GetWorld()->GetModel( "fuel_zone" ),
- mod->GetWorld()->GetModel( "pool_zone" ) );
-
+ {
+ srandom( time(NULL) );
+
+ // tokenize the worldfile ctrl argument string into
words
+ std::vector<std::string> words;
+ split( args->worldfile, std::string(" \t"), words );
+ // expecting at least one task color name
+ assert( words.size() > 1 );
+
+ const World* w = mod->GetWorld();
+
+ // make an array of tasks by reading the controller
arguments
+ for( unsigned int s=1; s<words.size(); s++ )
+ Robot::tasks.push_back( Robot::Task(
w->GetModel( words[s] + "_source"),
+
w->GetModel( words[s] + "_sink") ) );
+ }
+
+ new Robot( mod,
+ mod->GetWorld()->GetModel(
"fuel_zone" ),
+ mod->GetWorld()->GetModel(
"pool_zone" ) );
+
return 0; //ok
}
Modified: code/stage/trunk/libstage/model_fiducial.cc
===================================================================
--- code/stage/trunk/libstage/model_fiducial.cc 2010-04-24 22:47:52 UTC (rev
8622)
+++ code/stage/trunk/libstage/model_fiducial.cc 2010-04-26 13:50:18 UTC (rev
8623)
@@ -11,7 +11,7 @@
//
///////////////////////////////////////////////////////////////////////////
-#define DEBUG 0
+#undef DEBUG
#include "stage.hh"
#include "option.hh"
@@ -252,7 +252,7 @@
max_range_anon = wf->ReadLength( wf_entity, "range_max",
max_range_anon );
max_range_id = wf->ReadLength( wf_entity, "range_max_id",
max_range_id );
fov = wf->ReadAngle ( wf_entity, "fov", fov
);
- ignore_zloc = wf->ReadInt ( wf_entity, "ignore_zloc",
ignore_zloc);
+ ignore_zloc = wf->ReadInt ( wf_entity, "ignore_zloc",
ignore_zloc);
}
Modified: code/stage/trunk/worlds/fasr2.world
===================================================================
--- code/stage/trunk/worlds/fasr2.world 2010-04-24 22:47:52 UTC (rev 8622)
+++ code/stage/trunk/worlds/fasr2.world 2010-04-26 13:50:18 UTC (rev 8623)
@@ -189,7 +189,7 @@
gui_move 0
)
-zone( color "gray5"
+zone( color "wheat"
pose [ -19.459 -42.499 0 0 ]
name "pool_zone"
size [ 1.000 1.000 0.010 ]
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