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 #include "Robots/LoBot/control/LoCalibrateLET.H"
00046
00047 #include "Robots/LoBot/tti/LoTTIEstimator.H"
00048 #include "Robots/LoBot/tti/LoSensorModel.H"
00049 #include "Robots/LoBot/lgmd/gabbiani/LoGabbiani.H"
00050
00051 #include "Robots/LoBot/config/LoConfigHelpers.H"
00052 #include "Robots/LoBot/misc/LoRegistry.H"
00053
00054 #include "Robots/LoBot/util/LoGL.H"
00055 #include "Robots/LoBot/util/LoMath.H"
00056 #include "Robots/LoBot/util/range.hh"
00057 #include "Robots/LoBot/util/triple.hh"
00058
00059
00060 #ifdef INVT_HAVE_LIBGLU
00061 #include <GL/glu.h>
00062 #endif
00063
00064 #ifdef INVT_HAVE_LIBGL
00065 #include <GL/gl.h>
00066 #endif
00067
00068
00069 #include <sstream>
00070 #include <algorithm>
00071 #include <vector>
00072
00073
00074
00075 namespace lobot {
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 SensorModel* g_sensor_model ;
00087
00088
00089
00090
00091
00092
00093 static bool g_update_flag ;
00094
00095
00096
00097
00098 template<typename T>
00099 static inline T conf(const std::string& key, const T& default_value)
00100 {
00101 return get_conf<T>(LOBE_CALIBRATE_LET, key, default_value) ;
00102 }
00103
00104
00105
00106 CalibrateLET::CalibrateLET()
00107 : base(clamp(conf("update_delay", 1500), 1000, 5000),
00108 LOBE_CALIBRATE_LET,
00109 conf<std::string>("geometry", "0 0 320 320"))
00110 {
00111 start(LOBE_CALIBRATE_LET) ;
00112 }
00113
00114
00115 void CalibrateLET::pre_run()
00116 {
00117 g_sensor_model = &TTIEstimator::looming_sensor_model() ;
00118 TTIEstimator::blanking_sensor_model() ;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128 void CalibrateLET::action(){}
00129
00130 void CalibrateLET::keypress(unsigned char key)
00131 {
00132 SensorModel* looming = &TTIEstimator::looming_sensor_model() ;
00133 SensorModel* blanking = &TTIEstimator::blanking_sensor_model() ;
00134
00135 float dsigma = 0 ;
00136 switch (key)
00137 {
00138 case '\t':
00139 viz_lock() ;
00140 if (g_sensor_model == looming)
00141 g_sensor_model = blanking ;
00142 else if (g_sensor_model == blanking)
00143 g_sensor_model = looming ;
00144 g_update_flag = false ;
00145 viz_unlock() ;
00146 return ;
00147
00148 case 'u':
00149 case 'i':
00150 case 'k':
00151 case '+':
00152 dsigma = Params::dsigma() ;
00153 break ;
00154
00155 case 'd':
00156 case 'j':
00157 case '-':
00158 dsigma = -Params::dsigma() ;
00159 break ;
00160
00161 default:
00162 return ;
00163 }
00164
00165 g_sensor_model->update(dsigma) ;
00166 viz_lock() ;
00167 g_update_flag = true ;
00168 viz_unlock() ;
00169 }
00170
00171
00172
00173 #ifdef INVT_HAVE_LIBGLU
00174
00175 namespace {
00176
00177
00178
00179 class GLTexture {
00180 const SensorModel* m_sensor_model ;
00181 range<float> m_prob_range ;
00182 unsigned int m_name ;
00183 int m_width, m_height ;
00184 public:
00185 GLTexture() ;
00186 void init(const SensorModel*) ;
00187 int width() const {return m_width ;}
00188 int height() const {return m_height ;}
00189 range<float> prob_range() const {return m_prob_range ;}
00190 void update() ;
00191 void render(float left, float right, float bottom, float top) const ;
00192 void cleanup() ;
00193 } ;
00194
00195 GLTexture::GLTexture()
00196 : m_sensor_model(0), m_prob_range(0, 1), m_name(0), m_width(0), m_height(0)
00197 {}
00198
00199 void GLTexture::init(const SensorModel* S)
00200 {
00201 m_sensor_model = S ;
00202 m_width = S->column_size() ;
00203 m_height = S->row_size() ;
00204
00205 glGenTextures(1, &m_name) ;
00206
00207 glBindTexture(GL_TEXTURE_2D, m_name) ;
00208 glPixelStorei(GL_UNPACK_ALIGNMENT, 1) ;
00209 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) ;
00210 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) ;
00211 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) ;
00212 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) ;
00213
00214 const int W = next_power_of_two(m_width) ;
00215 const int H = next_power_of_two(m_height) ;
00216 const int N = W * H ;
00217 GLubyte* texture = new GLubyte[N] ;
00218 std::fill_n(texture, N, GLubyte(0)) ;
00219 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, W, H, 0,
00220 GL_LUMINANCE, GL_UNSIGNED_BYTE, texture) ;
00221 delete[] texture ;
00222
00223 update() ;
00224 }
00225
00226
00227
00228
00229 class scale {
00230 float min, scale_factor ;
00231 public:
00232 scale(const range<float>& prob_range) ;
00233 GLubyte operator()(float p) const {
00234 return static_cast<GLubyte>((p - min) * scale_factor) ;
00235 }
00236 } ;
00237
00238 scale::scale(const range<float>& p)
00239 : min(p.min()), scale_factor(255/p.size())
00240 {}
00241
00242
00243 void GLTexture::update()
00244 {
00245
00246
00247 std::vector<float> prob = m_sensor_model->table() ;
00248
00249
00250
00251
00252
00253
00254 m_prob_range = make_range(*(std::min_element(prob.begin(), prob.end())),
00255 *(std::max_element(prob.begin(), prob.end()))) ;
00256
00257
00258
00259
00260 const int N = prob.size() ;
00261 GLubyte* texture = new GLubyte[N] ;
00262 std::transform(prob.begin(), prob.end(), texture, scale(m_prob_range)) ;
00263
00264
00265
00266
00267
00268 for (GLubyte* t = texture; t < texture + N; t += m_width)
00269 std::reverse(t, t + m_width) ;
00270
00271
00272
00273 glBindTexture(GL_TEXTURE_2D, m_name) ;
00274 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height,
00275 GL_LUMINANCE, GL_UNSIGNED_BYTE, texture) ;
00276 delete[] texture ;
00277 }
00278
00279
00280 void GLTexture::render(float left, float right, float bottom, float top) const
00281 {
00282 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT) ;
00283 glEnable(GL_TEXTURE_2D) ;
00284 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) ;
00285 glBindTexture(GL_TEXTURE_2D, m_name) ;
00286
00287 const float S = static_cast<float>(m_width) /next_power_of_two(m_width) ;
00288 const float T = static_cast<float>(m_height)/next_power_of_two(m_height);
00289 glBegin(GL_QUADS) ;
00290 glTexCoord2i(0, 0) ;
00291 glVertex2f(left, bottom) ;
00292
00293 glTexCoord2f(S, 0) ;
00294 glVertex2f(right, bottom) ;
00295
00296 glTexCoord2f(S, T) ;
00297 glVertex2f(right, top) ;
00298
00299 glTexCoord2f(0, T) ;
00300 glVertex2f(left, top) ;
00301 glEnd() ;
00302
00303 glDisable(GL_TEXTURE_2D) ;
00304 glPopAttrib() ;
00305 }
00306
00307
00308 void GLTexture::cleanup()
00309 {
00310 glDeleteTextures(1, &m_name) ;
00311 }
00312
00313
00314
00315 static GLTexture looming_texture ;
00316 static GLTexture blanking_texture ;
00317
00318 }
00319
00320
00321
00322 static std::string sigma_label(float sigma)
00323 {
00324 std::ostringstream str ;
00325 str << "sigma: " << sigma ;
00326 return str.str() ;
00327 }
00328
00329
00330
00331
00332 static std::string prob_label(const range<float>& prob_range)
00333 {
00334 std::ostringstream str ;
00335 str << "P-range: ["
00336 << prob_range.min() << ", " << prob_range.max() << ']' ;
00337 return str.str() ;
00338 }
00339
00340 void CalibrateLET::gl_init()
00341 {
00342 looming_texture.init(&TTIEstimator:: looming_sensor_model()) ;
00343 blanking_texture.init(&TTIEstimator::blanking_sensor_model()) ;
00344 }
00345
00346
00347
00348 void CalibrateLET::render_me()
00349 {
00350 const SensorModel* looming = &TTIEstimator::looming_sensor_model() ;
00351 const SensorModel* blanking = &TTIEstimator::blanking_sensor_model() ;
00352
00353 viz_lock() ;
00354 if (g_update_flag) {
00355 if (g_sensor_model == looming)
00356 looming_texture.update() ;
00357 else if (g_sensor_model == blanking)
00358 blanking_texture.update() ;
00359 g_update_flag = false ;
00360 }
00361 viz_unlock() ;
00362
00363 setup_view_volume(0, looming_texture.width(),
00364 -(blanking_texture.height() + 1),
00365 looming_texture.height() + 1) ;
00366 looming_texture.render(0, looming_texture.width() - 1,
00367 1, looming_texture.height() - 1) ;
00368 blanking_texture.render(0, blanking_texture.width() - 1,
00369 -blanking_texture.height() + 1, -1) ;
00370
00371 glColor3f(1, 1, 0) ;
00372 glBegin(GL_LINES) ;
00373 glVertex2i(0, 0) ;
00374 glVertex2i(looming_texture.width(), 0) ;
00375 glEnd() ;
00376
00377 glMatrixMode(GL_PROJECTION) ;
00378 glPopMatrix() ;
00379 glMatrixMode(GL_MODELVIEW) ;
00380 glPopMatrix() ;
00381
00382 text_view_volume() ;
00383 if (g_sensor_model == looming)
00384 glColor3f(1, 0, 0) ;
00385 else
00386 glColor3f(0.5f, 0.5f, 0.5f) ;
00387 draw_label(3, 14, looming->name().c_str()) ;
00388 draw_label(3, 26, sigma_label(looming->sigma()).c_str()) ;
00389 draw_label(3, 38, prob_label(looming_texture.prob_range()).c_str()) ;
00390
00391 const int y = m_geometry.height - 26 ;
00392 if (g_sensor_model == blanking)
00393 glColor3f(1, 0, 0) ;
00394 else
00395 glColor3f(0.5f, 0.5f, 0.5f) ;
00396 draw_label(3, y, blanking->name().c_str()) ;
00397 draw_label(3, y + 10, sigma_label(blanking->sigma()).c_str()) ;
00398 draw_label(3, y + 20, prob_label(blanking_texture.prob_range()).c_str());
00399 restore_view_volume() ;
00400 }
00401
00402 void CalibrateLET::gl_cleanup()
00403 {
00404 looming_texture.cleanup() ;
00405 blanking_texture.cleanup() ;
00406 }
00407
00408 #endif
00409
00410
00411
00412 CalibrateLET::~CalibrateLET(){}
00413
00414
00415
00416
00417 CalibrateLET::Params::Params()
00418 : m_dsigma(clamp(conf("dsigma", 0.01f), 0.001f, 100.00f))
00419 {}
00420
00421
00422 CalibrateLET::Params::~Params(){}
00423
00424
00425
00426 }
00427
00428
00429
00430
00431