LoArbiter.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef INVT_HAVE_LIBPTHREAD
00046
00047 #include "Robots/LoBot/control/LoArbiter.H"
00048 #include "Robots/LoBot/misc/LoExcept.H"
00049
00050 namespace lobot {
00051
00052
00053 Arbiter::Arbiter(int)
00054 : m_update_delay(0),
00055 m_freeze_priority(-1), m_freeze_mutex(0),
00056 m_votes_mutex(0), m_viz_mutex(0)
00057 {
00058 throw missing_libs(MISSING_PTHREAD) ;
00059 }
00060
00061
00062 void Arbiter::run(){}
00063 void Arbiter::pre_run(){}
00064 void Arbiter::post_run(){}
00065
00066 void Arbiter::init_priorities(){}
00067 float Arbiter::priority(const std::string&) {return 0 ;}
00068
00069 void Arbiter::render_cb(unsigned long){}
00070 void Arbiter::render(){}
00071
00072 Arbiter::vote_data::vote_data(const std::string&, long long, VoteBase*){}
00073 Arbiter::vote_data::~vote_data(){}
00074 void Arbiter::vote(const std::string&, void*){}
00075
00076 void Arbiter:: freeze (const std::string&){}
00077 void Arbiter::unfreeze (const std::string&){}
00078 bool Arbiter::is_frozen(const std::string&) const {return false ;}
00079
00080
00081 Arbiter::~Arbiter(){}
00082
00083 }
00084
00085 #else // pthreads available ==> the real McCoy
00086
00087
00088
00089
00090 #include "Robots/LoBot/control/LoArbiter.H"
00091 #include "Robots/LoBot/control/LoBehavior.H"
00092
00093 #include "Robots/LoBot/LoApp.H"
00094 #include "Robots/LoBot/ui/LoLaserViz.H"
00095 #include "Robots/LoBot/config/LoConfigHelpers.H"
00096
00097 #include "Robots/LoBot/thread/LoShutdown.H"
00098 #include "Robots/LoBot/thread/LoPause.H"
00099
00100 #include "Robots/LoBot/misc/LoExcept.H"
00101 #include "Robots/LoBot/util/LoSTL.H"
00102 #include "Robots/LoBot/util/LoTime.H"
00103
00104
00105 #include "Util/log.H"
00106
00107
00108 #include <unistd.h>
00109
00110
00111
00112 namespace lobot {
00113
00114
00115
00116 Arbiter::
00117 Arbiter(int update_delay, const std::string& name, const Drawable::Geometry& g)
00118 : Drawable(name, g),
00119 m_update_delay(clamp(update_delay, 1, 900000) * 1000),
00120 m_freeze_priority(-1)
00121 {
00122 if (pthread_mutex_init(& m_freeze_mutex, 0) != 0)
00123 throw thread_error(MUTEX_INIT_ERROR) ;
00124 if (pthread_mutex_init(& m_votes_mutex, 0) != 0) {
00125 pthread_mutex_destroy(& m_freeze_mutex) ;
00126 throw thread_error(MUTEX_INIT_ERROR) ;
00127 }
00128 }
00129
00130
00131
00132 void Arbiter::pre_run(){}
00133
00134 void Arbiter::run()
00135 {
00136 try
00137 {
00138
00139
00140
00141 App::wait_for_init() ;
00142
00143 init_priorities() ;
00144 if (! App::robot()) {
00145 LERROR("arbiter error: robot sensorimotor subsystem unavailable") ;
00146 return ;
00147 }
00148
00149
00150 pre_run() ;
00151 while (! Shutdown::signaled())
00152 {
00153 if (Pause::is_clear())
00154 {
00155 pthread_mutex_lock(& m_votes_mutex) ;
00156 if (! m_votes.empty()) {
00157 motor_cmd(m_votes, App::robot()) ;
00158 purge_container(m_votes) ;
00159 m_votes.clear() ;
00160 }
00161 pthread_mutex_unlock(& m_votes_mutex) ;
00162 }
00163 usleep(m_update_delay) ;
00164 }
00165 post_run() ;
00166 }
00167 catch (uhoh& e)
00168 {
00169 LERROR("arbiter error: %s", e.what()) ;
00170 purge_container(m_votes) ;
00171 m_votes.clear() ;
00172 pthread_mutex_unlock(& m_votes_mutex) ;
00173 }
00174 }
00175
00176 void Arbiter::post_run(){}
00177
00178
00179
00180 void Arbiter::init_priorities()
00181 {
00182 float sum = 0 ;
00183 App::Behaviours::const_iterator it = App::behaviours().begin() ;
00184 for (; it != App::behaviours().end(); ++it)
00185 {
00186 const std::string& i = (*it)->name ;
00187 float p = get_configured_priority(i) ;
00188 m_priorities[i] = p ;
00189 sum += p ;
00190 }
00191
00192
00193 if (sum > 0)
00194 for (it = App::behaviours().begin(); it != App::behaviours().end(); ++it)
00195 m_priorities[(*it)->name] /= sum ;
00196 }
00197
00198 float Arbiter::priority(const std::string& behaviour) const
00199 {
00200 PriorityMap::const_iterator it = m_priorities.find(behaviour) ;
00201 if (it == m_priorities.end())
00202 return 0 ;
00203 return it->second ;
00204 }
00205
00206
00207
00208 void Arbiter::freeze(const std::string& name)
00209 {
00210 float p = priority(name) ;
00211 pthread_mutex_lock(& m_freeze_mutex) ;
00212 if (p > m_freeze_priority) {
00213 m_freezer = name ;
00214 m_freeze_priority = p ;
00215 }
00216 pthread_mutex_unlock(& m_freeze_mutex) ;
00217 }
00218
00219 void Arbiter::unfreeze(const std::string& name)
00220 {
00221 pthread_mutex_lock(& m_freeze_mutex) ;
00222 if (m_freezer == name) {
00223 m_freezer.clear() ;
00224 m_freeze_priority = -1 ;
00225 }
00226 pthread_mutex_unlock(& m_freeze_mutex) ;
00227 }
00228
00229 bool Arbiter::is_frozen(const std::string& name) const
00230 {
00231 bool frozen = false ;
00232 pthread_mutex_lock(& m_freeze_mutex) ;
00233 if (name == m_freezer)
00234 frozen = true ;
00235 pthread_mutex_unlock(& m_freeze_mutex) ;
00236 return frozen ;
00237 }
00238
00239
00240
00241 Arbiter::VoteBase::~VoteBase(){}
00242
00243 Arbiter::vote_data::
00244 vote_data(const std::string& n, long long t, VoteBase* v)
00245 : behavior_name(n), vote_time(t), vote(v)
00246 {}
00247
00248 Arbiter::vote_data::~vote_data()
00249 {
00250 delete vote ;
00251 }
00252
00253 void Arbiter::vote(const std::string& name, VoteBase* vote)
00254 {
00255 if (! running())
00256 throw arbiter_error(ARBITER_NOT_RUNNING) ;
00257
00258 pthread_mutex_lock(& m_freeze_mutex) ;
00259 float freeze_priority = m_freeze_priority ;
00260 pthread_mutex_unlock(& m_freeze_mutex) ;
00261 if (priority(name) < freeze_priority)
00262 return ;
00263
00264 pthread_mutex_lock(& m_votes_mutex) ;
00265 m_votes.push_back(new vote_data(name, current_time(), vote)) ;
00266 pthread_mutex_unlock(& m_votes_mutex) ;
00267 }
00268
00269
00270
00271 Arbiter::~Arbiter()
00272 {
00273 pthread_mutex_destroy(& m_freeze_mutex) ;
00274 pthread_mutex_destroy(& m_votes_mutex) ;
00275 purge_container(m_votes) ;
00276 }
00277
00278
00279
00280 }
00281
00282 #endif // INVT_HAVE_PTHREAD
00283
00284
00285
00286
00287