Go to the documentation of this file.00001
00023 #include <boost/function.hpp>
00024 #include "micros_swarm/scds_pso.h"
00025
00026 namespace micros_swarm {
00027 Agent::Agent():name_(""), run_(false), dim_(0), fitness_(0)
00028 {
00029
00030 w_ = 1;
00031 c1_ = 1.49445;
00032 c2_ = 1.49445;
00033 best_tuple_ = SCDSPSOTuple();
00034 rth_ = Singleton<RuntimeHandle>::getSingleton();
00035 robot_id_ = rth_->getRobotID();
00036 cur_gen_ = 0;
00037 gen_limit_ = 0;
00038 if(robot_id_ == 0) {
00039 file.open("~/catkin_ws/scds_pso.data");
00040 }
00041 }
00042
00043 Agent::Agent(std::string name):name_(name), run_(false), dim_(0), fitness_(0)
00044 {
00045
00046 w_ = 1;
00047 c1_ = 1.49445;
00048 c2_ = 1.49445;
00049 best_tuple_ = SCDSPSOTuple();
00050 rth_ = Singleton<RuntimeHandle>::getSingleton();
00051 robot_id_ = rth_->getRobotID();
00052 cur_gen_ = 0;
00053 gen_limit_ = 0;
00054 if(robot_id_ == 0) {
00055 file.open("~/catkin_ws/scds_pso.data");
00056 }
00057 }
00058
00059 Agent::~Agent()
00060 {
00061 rth_.reset();
00062 }
00063
00064 void Agent::set_param(float w, float c1, float c2)
00065 {
00066 w_ = w;
00067 c1_ = c1;
00068 c2_ = c2;
00069 }
00070
00071 void Agent::set_dim(int dim)
00072 {
00073 dim_ = dim;
00074 min_pos_.resize(dim_);
00075 for(int i = 0; i < dim_; i++) {
00076 min_pos_[i] = 0;
00077 }
00078 max_pos_.resize(dim_);
00079 for(int i = 0; i < dim_; i++) {
00080 max_pos_[i] = 0;
00081 }
00082 min_vel_.resize(dim_);
00083 for(int i = 0; i < dim_; i++) {
00084 min_vel_[i] = 0;
00085 }
00086 max_vel_.resize(dim_);
00087 for(int i = 0; i < dim_; i++) {
00088 max_vel_[i] = 0;
00089 }
00090 cur_pos_.resize(dim_);
00091 for(int i = 0; i < dim_; i++) {
00092 cur_pos_[i] = 0;
00093 }
00094 cur_vel_.resize(dim_);
00095 for(int i = 0; i < dim_; i++) {
00096 cur_vel_[i] = 0;
00097 }
00098 }
00099
00100 void Agent::set_fitness(const boost::function<float(const std::vector<float>& )>& fitness)
00101 {
00102 fitness_ = fitness;
00103 }
00104
00105 void Agent::set_min_pos(const std::vector<float>& pos)
00106 {
00107 for(int i = 0; i < pos.size(); i++) {
00108 min_pos_[i] = pos[i];
00109 }
00110 }
00111
00112 void Agent::set_max_pos(const std::vector<float>& pos)
00113 {
00114 for(int i = 0; i < pos.size(); i++) {
00115 max_pos_[i] = pos[i];
00116 }
00117 }
00118
00119 void Agent::set_min_vel(const std::vector<float>& vel)
00120 {
00121 for(int i = 0; i < vel.size(); i++) {
00122 min_vel_[i] = vel[i];
00123 }
00124 }
00125
00126 void Agent::set_max_vel(const std::vector<float>& vel)
00127 {
00128 for(int i = 0; i < vel.size(); i++) {
00129 max_vel_[i] = vel[i];
00130 }
00131 }
00132
00133 void Agent::init_pos(const std::vector<float>& pos)
00134 {
00135 for(int i = 0; i < pos.size(); i++) {
00136 cur_pos_[i] = pos[i];
00137 }
00138
00139 pbest_.pos = cur_pos_;
00140 pbest_.val = fitness_(pbest_.pos);
00141 pbest_.robot_id = robot_id_;
00142 pbest_.gen = cur_gen_;
00143 pbest_.timestamp = time(NULL);
00144
00145 gbest_.pos = cur_pos_;
00146 gbest_.val = fitness_(gbest_.pos);
00147 gbest_.robot_id = robot_id_;
00148 gbest_.gen = cur_gen_;
00149 gbest_.timestamp = time(NULL);
00150
00151 best_tuple_.put("scds_pso", gbest_);
00152 }
00153
00154 void Agent::init_vel(const std::vector<float>& vel)
00155 {
00156 for(int i = 0; i < vel.size(); i++) {
00157 cur_vel_[i] = vel[i];
00158 }
00159 }
00160
00161 bool Agent::has_pos_limit(int index)
00162 {
00163 if((min_pos_[index] == 0) && (max_pos_[index] == 0)) {
00164 return false;
00165 }
00166 return true;
00167 }
00168
00169 bool Agent::has_vel_limit(int index)
00170 {
00171 if((min_vel_[index] == 0) && (max_vel_[index] == 0)) {
00172 return false;
00173 }
00174 return true;
00175 }
00176
00177 void Agent::rand_init()
00178 {
00179 for(int i = 0; i < dim_; i++) {
00180 if(has_pos_limit(i)) {
00181 cur_pos_[i] = random_float(min_pos_[i], max_pos_[i]);
00182 }
00183 else {
00184 cur_pos_[i] = random_float(-5.12, 5.12);
00185 }
00186
00187 pbest_.pos = cur_pos_;
00188 pbest_.val = fitness_(pbest_.pos);
00189 pbest_.robot_id = robot_id_;
00190 pbest_.gen = cur_gen_;
00191 pbest_.timestamp = time(NULL);
00192 gbest_.pos = cur_pos_;
00193 gbest_.val = fitness_(gbest_.pos);
00194 gbest_.robot_id = robot_id_;
00195 gbest_.gen = cur_gen_;
00196 gbest_.timestamp = time(NULL);
00197
00198 best_tuple_.put("scds_pso", gbest_);
00199
00200 if(has_vel_limit(i)) {
00201 cur_vel_[i] = random_float(min_vel_[i], max_vel_[i]);
00202 }
00203 else {
00204 cur_vel_[i] = random_float(-5.12, 5.12);
00205 }
00206 }
00207 }
00208
00209 void Agent::loop(const ros::TimerEvent &)
00210 {
00211 if(!run_) {
00212 return;
00213 }
00214
00215 cur_gen_++;
00216 float r1 = (float)rand()/RAND_MAX;
00217 float r2 = (float)rand()/RAND_MAX;
00218 gbest_ = best_tuple_.get("scds_pso");
00219
00220 for(int i = 0; i < dim_; i++) {
00221 float s1 = c1_*r1*(pbest_.pos[i] - cur_pos_[i]);
00222 float s2 = c2_*r2*(gbest_.pos[i] - cur_pos_[i]);
00223 cur_vel_[i] = w_*cur_vel_[i] + s1 + s2;
00224
00225 if(has_vel_limit(i)) {
00226 if(cur_vel_[i] > max_vel_[i]) {
00227 cur_vel_[i] = max_vel_[i];
00228 }
00229 if(cur_vel_[i] < min_vel_[i]) {
00230 cur_vel_[i] = min_vel_[i];
00231 }
00232 }
00233
00234 cur_pos_[i] = cur_pos_[i] + cur_vel_[i];
00235 if(has_pos_limit(i)) {
00236 if(cur_pos_[i] > max_pos_[i]) {
00237 cur_pos_[i] = max_pos_[i];
00238 }
00239 if(cur_pos_[i] < min_pos_[i]) {
00240 cur_pos_[i] = min_pos_[i];
00241 }
00242 }
00243 }
00244
00245 float cur_val = fitness_(cur_pos_);
00246 if(cur_val > pbest_.val) {
00247 pbest_.pos = cur_pos_;
00248 pbest_.val = cur_val;
00249 pbest_.robot_id = robot_id_;
00250 pbest_.gen = cur_gen_;
00251 pbest_.timestamp = time(NULL);
00252 }
00253
00254 if(cur_val > gbest_.val) {
00255 gbest_.pos = cur_pos_;
00256 gbest_.val = cur_val;
00257 gbest_.robot_id = robot_id_;
00258 gbest_.gen = cur_gen_;
00259 gbest_.timestamp = time(NULL);
00260
00261 best_tuple_.put("scds_pso", gbest_);
00262 }
00263
00264
00265
00266
00267
00268
00269 if(robot_id_ == 0) {
00270 std::cout<<cur_gen_<<" "<<gbest_.val<< std::endl;
00271 file<<cur_gen_<<" "<<gbest_.val<< std::endl;
00272 }
00273
00274 if(gen_limit_) {
00275 if(cur_gen_ > gen_limit_) {
00276 timer_.stop();
00277 }
00278 }
00279 }
00280
00281 void Agent::start()
00282 {
00283 if(!dim_) {
00284 std::cout<<"dimension is not set!"<<std::endl;
00285 return;
00286 }
00287
00288 if(fitness_ == 0) {
00289 std::cout<<"fitness is not set!"<<std::endl;
00290 return;
00291 }
00292
00293 run_ = true;
00294 timer_ = nh_.createTimer(ros::Duration(1), &Agent::loop, this);
00295 }
00296
00297 void Agent::start(int loop_gen)
00298 {
00299 gen_limit_ = loop_gen;
00300 start();
00301 }
00302
00303 void Agent::stop()
00304 {
00305 run_ = false;
00306 dim_ = 0;
00307 name_ = "";
00308 cur_gen_ = 0;
00309 gen_limit_ = 0;
00310 }
00311 };