25 m /= size_m / (float)size_c;
26 return (
unsigned int)floor(m);
32 meters_t cell_size = size_m/(float)size_c;
36 return m + cell_size/2.0;
51 : source(source), sink(sink), participants(0)
67 : to(to), cost(cost) {}
78 : pose(pose), value(value), edges() {}
89 edges.push_back( edge );
107 const std::vector<Node*>::iterator& it = nodes.begin();
115 FOR_EACH( it, nodes ){ (*it)->Draw(); }
127 Node* best_node = NULL;
133 double dist = hypot( node->
pose.
x - pose.
x, node->
pose.
y - pose.
y );
138 ( best_node == NULL || node->
value < best_node->
value ))
144 if( best_node == NULL )
146 fprintf( stderr,
"FASR warning: no nodes in range" );
151 heading_result = atan2( best_node->
pose.
y - pose.
y,
152 best_node->
pose.
x - pose.
x );
156 heading_result =
normalize( heading_result + 0.25 );
168 :
Visualizer(
"graph",
"vis_graph" ), graphpp(graphpp) {}
173 if( *graphpp == NULL )
206 int avoidcount, randcount;
207 int work_get, work_put;
209 double charger_bearing;
210 double charger_range;
211 double charger_heading;
253 fiducial( (
ModelFiducial*)pos->GetUnusedModelOfType(
"fiducial" )),
254 task(random() % tasks.size() ),
267 goal(tasks[task].source),
272 node_interval_countdown( node_interval ),
276 force_recharge( false )
286 pos->
SetColor( tasks[task].source->GetColor() );
288 tasks[task].participants++;
298 if( map_data == NULL )
300 map_data =
new uint8_t[map_width*map_height*2];
304 memset( map_data, 0,
sizeof(uint8_t) * map_width * map_height);
314 g.
size.
x/(
float)map_width,
315 g.
size.
y/(
float)map_height );
319 unsigned int sz = map_width * map_height;
320 for(
unsigned int i=0; i<sz; i++ )
322 if( map_data[i] == 0 )
324 else if( map_data[i] == 1 )
327 printf(
"FASR: bad value %d in map at index %d\n", (
int)map_data[i], (
int)i );
329 assert( (map_data[i] == 1) || (map_data[i] == 9) );
355 Enable( sonar, sonar_sub, on );
360 Enable( laser, laser_sub, on );
365 Enable( fiducial, fiducial_sub, on );
374 uint64_t x = pt.
x / 1;
375 uint64_t y = pt.
y / 1;
382 std::pair<uint64_t,uint64_t> key( Pt64(start),Pt64(goal));
383 plancache[key] = graph;
388 std::pair<uint64_t,uint64_t> key(Pt64(start),Pt64(goal));
389 return plancache[key];
395 static float hits = 0;
396 static float misses = 0;
425 graphp = LookupPlan( start, goal );
431 std::vector<ast::point_t> path;
440 printf(
"FASR2 warning: plan failed to find path from (%.2f,%.2f) to (%.2f,%.2f)\n",
441 pose.
x, pose.
y, sp.
x, sp.
y );
443 graphp =
new Graph();
445 unsigned int dist = 0;
447 Node* last_node = NULL;
449 for( std::vector<ast::point_t>::reverse_iterator rit = path.rbegin();
468 CachePlan( start, goal, graphp );
483 const meters_t creep_distance = 0.5;
489 const double orient =
normalize( M_PI - (charger_bearing - charger_heading) );
490 const double a_goal =
normalize( charger_bearing - 2.0 * orient );
492 if( charger_range > creep_distance )
494 if( !ObstacleAvoid() )
505 if( charger_range < 0.08 )
509 EnableLaser(
false );
520 EnableFiducial(
false );
531 EnableFiducial(
true);
532 force_recharge =
false;
539 tasks[task].participants++;
544 const meters_t back_off_distance = 0.2;
545 const meters_t back_off_speed = -0.02;
546 const radians_t undock_rotate_speed = 0.3;
548 const unsigned int BACK_SENSOR_FIRST = 10;
549 const unsigned int BACK_SENSOR_LAST = 13;
553 assert( fiducial_sub );
555 if( charger_range < back_off_distance )
562 const std::vector<ModelRanger::Sensor>& sensors = sonar->
GetSensors();
564 for(
unsigned int s = BACK_SENSOR_FIRST;
s <= BACK_SENSOR_LAST; ++
s )
565 if( sensors[
s].ranges.size() < 1 || sensors[
s].ranges[0] < wait_distance)
567 pos->
Say(
"Waiting..." );
577 if( fabs( heading_error ) > 0.05 )
592 SetTask( random() % tasks.size() );
593 SetGoal( tasks[task].source );
596 SetGoal( tasks[task].sink );
599 EnableFiducial(
false);
607 bool obstruction =
false;
612 double minleft = 1e6;
613 double minright = 1e6;
618 const std::vector<meters_t>& scan = laser->
GetSensors()[0].ranges;
620 uint32_t sample_count = scan.size();
623 for (uint32_t i = 0; i < sample_count; i++)
625 if(
verbose ) printf(
"%.3f ", scan[i] );
627 if( (i > (sample_count/4))
628 && (i < (sample_count - (sample_count/4)))
631 if(
verbose ) puts(
" obstruction!" );
637 if(
verbose ) puts(
" stopping!" );
641 if( i > sample_count/2 )
642 minleft = std::min( minleft, scan[i] );
644 minright = std::min( minright, scan[i] );
650 printf(
"minleft %.3f \n", minleft );
651 printf(
"minright %.3f\n ", minright );
654 if( obstruction || stop || (avoidcount>0) )
656 if(
verbose ) printf(
"Avoid %d\n", avoidcount );
664 if(
verbose ) puts(
"Avoid START" );
667 if( minleft < minright )
690 if( goal != this->goal )
700 if( ! ObstacleAvoid() )
706 SetGoal( fuel_zone );
713 if( graphp == NULL ||
724 cached_goal_pose = goal->
GetPose();
730 EnableFiducial(
true);
734 printf(
"%s replanning in Work()\n", pos->
Token() );
742 const double a_error =
normalize( a_goal - pose.
a );
767 if( strcmp( pos->
Token(),
"position:0") == 0 )
769 static int seconds = 0;
773 if( timenow - seconds > 5 )
791 charger_ahoy =
false;
796 std::vector<ModelFiducial::Fiducial>& fids = fiducial->
GetFiducials();
798 if( fids.size() > 0 )
802 for(
unsigned int i = 0; i < fids.size(); i++ )
810 if( f->
id == 2 && ( closest == NULL || f->
range < closest->
range ))
820 charger_bearing = closest->
bearing;
821 charger_range = closest->
range;
822 charger_heading = closest->
geom.
a;
834 if( goal == tasks[task].source )
840 meters_t dest_dist = hypot( sourcepose.
x-pose.
x, sourcepose.
y-pose.
y );
843 if( dest_dist < sourcegeom.
size.
x/2.0 )
844 if( wait_started_at < 0 && pos->GetFlagCount() == 0 )
850 if( wait_started_at > 0 )
855 if( drand48() < 0.0005 )
860 force_recharge =
true;
861 tasks[task].participants--;
862 wait_started_at = -1;
868 if( dest_dist < sourcegeom.
size.
x/2.0 &&
878 wait_started_at = -1;
882 SetGoal( tasks[task].sink );
885 else if( goal == tasks[task].sink )
891 if( hypot( sinkpose.
x-pose.
x, sinkpose.
y-pose.
y ) < sinkgeom.
size.
x/2.0 &&
902 SetGoal( tasks[task].source );
907 assert( goal == fuel_zone || goal == pool_zone );
928 printf(
"unrecognized mode %u\n", mode );
937 printf(
"model %s collected flag\n", mod->
Token() );
943 printf(
"model %s dropped flag\n", mod->
Token() );
963 glVertex2f( pose.x, pose.y );
964 glVertex2f( (*it)->to->pose.x, (*it)->to->pose.y );
981 void split(
const std::string& text,
const std::string& separators, std::vector<std::string>& words)
983 const int n = text.length();
985 start = text.find_first_not_of(separators);
986 while ((start >= 0) && (start < n))
988 stop = text.find_first_of(separators, start);
989 if ((stop < 0) || (stop > n)) stop = n;
990 words.push_back(text.substr(start, stop - start));
991 start = text.find_first_not_of(separators, stop+1);
1002 srandom( time(NULL) );
1005 std::vector<std::string> words;
1008 assert( words.size() > 1 );
1013 for(
unsigned int s=1;
s<words.size();
s++ )
1015 w->GetModel( words[
s] +
"_sink") ) );
void SetTurnSpeed(double a)
meters_t range
range to the target
virtual void PushColor(Color col)
static meters_t CellToMeters(unsigned int c, meters_t size_m, unsigned int size_c)
static void UpdateCallback(WorldGui *world)
void EnableSonar(bool on)
Task(Model *source, Model *sink)
bool astar(uint8_t *map, uint32_t width, uint32_t height, const point_t start, const point_t goal, std::vector< point_t > &path)
static const bool verbose
unsigned int GetFlagCount() const
usec_t SimTimeNow(void) const
The Stage library uses its own namespace.
std::vector< Fiducial > & GetFiducials()
Node(Pose pose, double value=0)
static const double minfrontdistance
void EnableLaser(bool on)
void Init(int *argc, char **argv[])
std::vector< Node * > nodes
unsigned int participants
int(* model_callback_t)(Model *mod, void *user)
void Rasterize(uint8_t *data, unsigned int width, unsigned int height, meters_t cellwidth, meters_t cellheight)
bool GoodDirection(const Pose &pose, meters_t range, radians_t &heading_result)
static const double avoidturn
void SetColor(const Color &col)
double ProportionRemaining() const
static unsigned int MetersToCell(meters_t m, meters_t size_m, unsigned int size_c)
void EnableFiducial(bool on)
void Say(const std::string &str)
static int FlagIncr(Model *mod, Robot *robot)
static const unsigned int map_width
Robot(ModelPosition *pos, Model *fuel, Model *pool)
void pose_inverse_shift(const Pose &pose)
double normalize(double a)
void AddCallback(callback_type_t type, model_callback_t cb, void *user)
static const unsigned int map_height
Pose GetGlobalPose() const
radians_t bearing
bearing to the target
void PushFlag(Flag *flag)
uint64_t Pt64(const ast::point_t &pt)
static const unsigned int avoidduration
void SetGoal(Model *goal)
Edge(Node *to, double cost=1.0)
void SetTask(unsigned int t)
const std::vector< Sensor > & GetSensors() const
void AddVisualizer(Visualizer *custom_visual, bool on_by_default)
Graph * LookupPlan(const ast::point_t &start, const ast::point_t &goal)
std::vector< Edge * > edges
static const double avoidspeed
static pthread_mutex_t planner_mutex
static std::vector< Task > tasks
unsigned int node_interval
static const double cruisespeed
void Enable(Stg::Model *model, bool &sub, bool on)
meters_t Distance2D(const Pose &other) const
Pose geom
size and relative angle of the target
Model * GetModel(const std::string &name) const
static uint8_t * map_data
virtual void Visualize(Model *mod, Camera *cam)
static int FlagDecr(Model *mod, Robot *robot)
static const unsigned int PAYLOAD
PowerPack * FindPowerPack() const
void split(const std::string &text, const std::string &separators, std::vector< std::string > &words)
radians_t a
rotation about the z axis.
GraphVis(Graph **graphpp)
static int UpdateCallback(ModelRanger *laser, Robot *robot)
static const double stopdist
unsigned int node_interval_countdown
static std::map< std::pair< uint64_t, uint64_t >, Graph * > plancache
void CachePlan(const ast::point_t &start, const ast::point_t &goal, Graph *graph)
int id
the fiducial identifier of the target (i.e. its fiducial_return value), or -1 if none can be detected...
const char * Token() const