Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00009
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014 #include <sstream>
00015 #include <iostream>
00016 #include <cmath>
00017
00018 #include "stage.hh"
00019
00020 class Robot
00021 {
00022 public:
00023 Stg::ModelPosition* position;
00024 Stg::ModelRanger* ranger;
00025 };
00026
00027 class Logic
00028 {
00029 public:
00030 static int Callback(Stg::World* world, void* userarg)
00031 {
00032 Logic* lg = reinterpret_cast<Logic*>(userarg);
00033
00034 lg->Tick(world);
00035
00036
00037 return 0;
00038 }
00039
00040 Logic(unsigned int popsize)
00041 :
00042 population_size(popsize),
00043 robots(new Robot[population_size])
00044 {
00045
00046 }
00047
00048 void connect(Stg::World* world)
00049 {
00050
00051 for(unsigned int idx = 0; idx < population_size; idx++)
00052 {
00053
00054 std::stringstream name;
00055 name << "r" << idx;
00056
00057
00058 Stg::ModelPosition* posmod = reinterpret_cast<Stg::ModelPosition*>(
00059 world->GetModel(name.str())
00060 );
00061 assert(posmod != 0);
00062
00063 robots[idx].position = posmod;
00064 robots[idx].position->Subscribe();
00065
00066
00067 Stg::ModelRanger* rngmod = reinterpret_cast<Stg::ModelRanger*>(
00068 robots[idx].position->GetChild( "ranger:0" )
00069 );
00070 assert(rngmod != 0);
00071
00072 robots[idx].ranger = rngmod;
00073 robots[idx].ranger->Subscribe();
00074 }
00075
00076
00077 world->AddUpdateCallback(Logic::Callback, reinterpret_cast<void*>(this));
00078 }
00079
00080 ~Logic()
00081 {
00082 delete[] robots;
00083 }
00084
00085
00086 void Tick(Stg::World*)
00087 {
00088
00089 const double vspeed = 0.4;
00090 const double wgain = 1.0;
00091 const double safe_dist = 0.1;
00092 const double safe_angle = 0.3;
00093
00094
00095
00096
00097 for(unsigned int idx = 0; idx < population_size; idx++)
00098 {
00099 Stg::ModelRanger* rgr = robots[idx].ranger;
00100
00101
00102 double dx=0, dy=0;
00103
00104
00105 typedef std::vector<Stg::ModelRanger::Sensor>::const_iterator sensor_iterator;
00106 const std::vector<Stg::ModelRanger::Sensor> sensors = rgr->GetSensors();
00107
00108 for(sensor_iterator sensor = sensors.begin(); sensor != sensors.end(); sensor++)
00109 {
00110
00111 const double srange = (*sensor).ranges[0];
00112 const double angle = (*sensor).pose.a;
00113
00114 dx += srange * std::cos(angle);
00115 dy += srange * std::sin(angle);
00116 }
00117
00118 if(dx == 0)
00119 continue;
00120
00121 if(dy == 0)
00122 continue;
00123
00124
00125 const double resultant_angle = std::atan2( dy, dx );
00126
00127
00128 const unsigned int forward_idx = sensors.size() / 2u - 1u;
00129
00130 const double forwardm_range = sensors[forward_idx - 1].ranges[0];
00131 const double forward_range = sensors[forward_idx + 0].ranges[0];
00132 const double forwardp_range = sensors[forward_idx + 1].ranges[0];
00133
00134 bool front_clear = (
00135 (forwardm_range > safe_dist / 5.0) &&
00136 (forward_range > safe_dist) &&
00137 (forwardp_range > safe_dist / 5.0) &&
00138 (std::abs(resultant_angle) < safe_angle)
00139 );
00140
00141
00142
00143
00144 const double forward_speed = front_clear ? vspeed : 0.0;
00145
00146 const double side_speed = 0.0;
00147
00148
00149 const double turn_speed = wgain * resultant_angle;
00150
00151
00152 robots[idx].position->SetSpeed( forward_speed, side_speed, turn_speed );
00153 }
00154 }
00155
00156 protected:
00157 unsigned int population_size;
00158 Robot* robots;
00159 };
00160
00161 int main( int argc, char* argv[] )
00162 {
00163
00164 if( argc < 3 )
00165 {
00166 puts( "Usage: stest <worldfile> <number of robots>" );
00167 exit(0);
00168 }
00169
00170 const int popsize = atoi(argv[2] );
00171
00172
00173 Stg::Init( &argc, &argv );
00174
00175
00176
00177 Stg::WorldGui world(800, 700, "Stage Benchmark Program");
00178 world.Load( argv[1] );
00179
00180
00181 Logic logic(popsize);
00182 logic.connect(&world);
00183
00184
00185 world.Run();
00186
00187 return 0;
00188 }