Fawkes API  Fawkes Development Version
firestation.cpp
1 /***************************************************************************
2  * firestation.cpp - Firestation
3  *
4  * Created: Wed Oct 10 14:19:30 2007
5  * Copyright 2007-2008 Daniel Beck
6  *
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "firestation.h"
23 
24 #include "color_train_widget.h"
25 #include "fuse_transfer_widget.h"
26 
27 #include <fvcams/fileloader.h>
28 #include <fvcams/net.h>
29 #include <fvcams/shmem.h>
30 #include <fvwidgets/fuse_image_list_widget.h>
31 #include <gui_utils/avahi_dispatcher.h>
32 #include <utils/math/angle.h>
33 
34 #ifdef HAVE_MIRROR_CALIB
35 # include <fvmodels/mirror/mirror_calib.h>
36 #endif
37 
38 #include <arpa/inet.h>
39 #include <core/exception.h>
40 #include <fvutils/color/conversions.h>
41 #include <fvutils/color/yuv.h>
42 #include <fvutils/colormap/yuvcm.h>
43 #include <fvutils/draw/drawer.h>
44 #include <fvutils/ipc/shm_image.h>
45 #include <fvutils/scalers/lossy.h>
46 #include <fvutils/system/camargp.h>
47 #include <fvutils/writers/fvraw.h>
48 #include <fvutils/writers/jpeg.h>
49 #include <gdkmm/pixbuf.h>
50 
51 #include <iostream>
52 
53 using namespace std;
54 using namespace fawkes;
55 using namespace firevision;
56 
57 /** @class Firestation "firestation.h"
58  * Control GUI for vision related stuff.
59  * @author Daniel Beck
60  */
61 
62 /** Constructor.
63  * @param builder Gtk Builder
64  */
65 Firestation::Firestation(Glib::RefPtr<Gtk::Builder> builder)
66 {
67  // --- main window ------------------------------------------------
68  builder->get_widget("wndMain", m_wnd_main);
69  builder->get_widget("imgImage", m_img_image);
70  builder->get_widget("evtImageEventBox", m_evt_image);
71  builder->get_widget("trvShmImageIds", m_trv_shm_image_ids);
72  builder->get_widget("stbStatus", m_stb_status);
73  builder->get_widget("ckbContTrans", m_ckb_cont_trans);
74  builder->get_widget("spbUpdateTime", m_spb_update_time);
75 
76  m_img_image->signal_size_allocate().connect(sigc::mem_fun(*this, &Firestation::resize_image));
77  m_evt_image->signal_button_press_event().connect(sigc::mem_fun(*this, &Firestation::image_click));
78  m_ckb_cont_trans->signal_toggled().connect(
79  sigc::mem_fun(*this, &Firestation::enable_cont_img_trans));
80 
81  // ----------------------------------------------------------------
82 
83  // --- toolbar widgets --------------------------------------------
84  builder->get_widget("tbtnExit", m_tbtn_exit);
85  builder->get_widget("tbtnCloseCamera", m_tbtn_close_camera);
86  builder->get_widget("tbtnUpdate", m_tbtn_update);
87  builder->get_widget("tbtnSave", m_tbtn_save);
88  builder->get_widget("tbtnOpenFile", m_tbtn_open_file);
89  builder->get_widget("tbtnOpenFolder", m_tbtn_open_folder);
90  builder->get_widget("tbtnOpenShm", m_tbtn_open_shm);
91  builder->get_widget("tbtnOpenFuse", m_tbtn_open_fuse);
92 
93  m_tbtn_exit->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::exit));
94  m_tbtn_close_camera->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::close_camera));
95  m_tbtn_update->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::update_image));
96  m_tbtn_save->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::save_image));
97  m_tbtn_open_file->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::open_file));
98  m_tbtn_open_folder->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::open_folder));
99  m_tbtn_open_shm->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::open_shm));
100  m_tbtn_open_fuse->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::open_fuse));
101  // ----------------------------------------------------------------
102 
103  // --- dialogs ----------------------------------------------------
104  builder->get_widget("fcdOpenImage", m_fcd_open_image);
105  builder->get_widget("fcdSaveImage", m_fcd_save_image);
106  builder->get_widget("dlgOpenShm", m_dlg_open_shm);
107  builder->get_widget("trvShmImageIds", m_trv_shm_image_ids);
108  builder->get_widget("dlgOpenFuse", m_dlg_open_fuse);
109  builder->get_widget("ckbFuseJpeg", m_ckb_fuse_jpeg);
110  builder->get_widget("trvFuseServices", m_trv_fuse_services);
111 
112 #if GTK_VERSION_GE(3, 0)
113  Glib::RefPtr<Gtk::FileFilter> filter_jpg = Gtk::FileFilter::create();
114 #else
115  Gtk::FileFilter *filter_jpg = Gtk::manage(new Gtk::FileFilter());
116 #endif
117  filter_jpg->set_name("JPEG");
118  filter_jpg->add_pattern("*.jpg");
119  filter_jpg->add_pattern("*.jpeg");
120 
121 #if GTK_VERSION_GE(3, 0)
122  Glib::RefPtr<Gtk::FileFilter> filter_fvraw = Gtk::FileFilter::create();
123 #else
124  Gtk::FileFilter *filter_fvraw = Gtk::manage(new Gtk::FileFilter());
125 #endif
126  filter_fvraw->set_name("FVRaw");
127  filter_fvraw->add_pattern("*.raw");
128  filter_fvraw->add_pattern("*.fvraw");
129 
130 #if GTK_VERSION_GE(3, 0)
131  m_fcd_open_image->add_filter(filter_jpg);
132  m_fcd_open_image->add_filter(filter_fvraw);
133 
134  m_fcd_save_image->add_filter(filter_jpg);
135  m_fcd_save_image->add_filter(filter_fvraw);
136 
137 #else
138  m_fcd_open_image->add_filter(*filter_jpg);
139  m_fcd_open_image->add_filter(*filter_fvraw);
140 
141  m_fcd_save_image->add_filter(*filter_jpg);
142  m_fcd_save_image->add_filter(*filter_fvraw);
143 #endif
144 
145  m_shm_list_store = Gtk::ListStore::create(m_shm_columns);
146  m_trv_shm_image_ids->set_model(m_shm_list_store);
147  m_trv_shm_image_ids->append_column("#", m_shm_columns.m_id);
148  m_trv_shm_image_ids->append_column("Name", m_shm_columns.m_name);
149 
150  m_fuse_tree_store = Gtk::TreeStore::create(m_fuse_columns);
151  m_trv_fuse_services->set_model(m_fuse_tree_store);
152  // m_trv_fuse_services->append_column("#", m_fuse_columns.m_id);
153  m_trv_fuse_services->append_column("Name", m_fuse_columns.m_name);
154  // ----------------------------------------------------------------
155 
156  // --- color train widget -----------------------------------------
157  m_ctw = new ColorTrainWidget(this);
158  builder->get_widget("cmbCtObjectType", m_cmb_ct_type);
159  builder->get_widget("btnCtStart", m_btn_ct_start);
160  builder->get_widget("btnCtSeg", m_btn_ct_seg);
161  builder->get_widget("spbtnCtCmDepth", m_spbtn_depth);
162  builder->get_widget("spbtnCtCmWidth", m_spbtn_width);
163  builder->get_widget("spbtnCtCmHeight", m_spbtn_height);
164 
165  m_cmb_ct_type->signal_changed().connect(sigc::mem_fun(*this, &Firestation::ct_object_changed));
166  m_cmb_ct_type->set_active(0);
167 
168  m_btn_ct_start->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::ct_start));
169 
170  m_ctw->update_image().connect(sigc::mem_fun(*this, &Firestation::draw_image));
171  m_ctw->colormap_updated().connect(sigc::mem_fun(*this, &Firestation::on_colormap_updated));
172 
173  Gtk::Button *btn;
174  builder->get_widget("btnCtUnselect", btn);
175  m_ctw->set_reset_selection_btn(btn);
176 
177  builder->get_widget("btnCtAdd", btn);
178  m_ctw->set_add_to_colormap_btn(btn);
179 
180  builder->get_widget("btnCtReset", btn);
181  m_ctw->set_reset_colormap_btn(btn);
182 
183  builder->get_widget("btnCtSaveHistos", btn);
184  m_ctw->set_save_histos_btn(btn);
185 
186  builder->get_widget("btnCtLoadHistos", btn);
187  m_ctw->set_load_histos_btn(btn);
188 
189  builder->get_widget("btnCtSaveColormap", btn);
190  m_ctw->set_save_colormap_btn(btn);
191 
192  builder->get_widget("btnCtLoadColormap", btn);
193  m_ctw->set_load_colormap_btn(btn);
194 
195  Gtk::Scale *scl;
196  builder->get_widget("sclCtThreshold", scl);
197  m_ctw->set_threshold_scl(scl);
198 
199  builder->get_widget("sclCtMinProb", scl);
200  m_ctw->set_min_prob_scl(scl);
201 
202  builder->get_widget("sclCtLayerSelector", scl);
203  m_ctw->set_cm_layer_selector(scl);
204 
205  Gtk::Image *img;
206  builder->get_widget("imgCtSegmentation", img);
207  m_ctw->set_segmentation_img(img);
208 
209  builder->get_widget("imgCtColormap", img);
210  m_ctw->set_colormap_img(img);
211 
212  Gtk::FileChooserDialog *fcd;
213  builder->get_widget("fcdFilechooser", fcd);
214  m_ctw->set_filechooser_dlg(fcd);
215 
216  m_btn_ct_seg->signal_toggled().connect(sigc::mem_fun(*this, &Firestation::draw_image));
217  m_ctw->set_cm_selector(m_spbtn_depth, m_spbtn_width, m_spbtn_height);
218  // ----------------------------------------------------------------
219 
220  // --- mirror calibration -----------------------------------------
221 #ifdef HAVE_MIRROR_CALIB
222  m_calib_tool = new firevision::MirrorCalibTool();
223 #endif
224 
225 #ifndef HAVE_MIRROR_CALIB
226  Gtk::Notebook *nb;
227  Gtk::HBox * box;
228  builder->get_widget("ntbOptions", nb);
229  builder->get_widget("boxMirrorCalib", box);
230  nb->get_tab_label(*box)->set_sensitive(false);
231  box->set_sensitive(false);
232 #endif
233 
234  builder->get_widget("sclMcLine", m_scl_mc_line);
235  m_scl_mc_line->signal_change_value().connect(
236  sigc::mem_fun(*this, &Firestation::mc_on_line_angle_changed));
237 
238  builder->get_widget("btnMcLoadMask", m_btn_mc_load_mask);
239  m_btn_mc_load_mask->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::mc_load_mask));
240 
241  //builder->get_widget("btnMcStart", m_btn_mc_start);
242  builder->get_widget("btnCalibLoad", m_btn_mc_load);
243  builder->get_widget("btnCalibSave", m_btn_mc_save);
244  builder->get_widget("entCalibDist", m_ent_mc_dist);
245  builder->get_widget("entCalibOri", m_ent_mc_ori);
246  builder->get_widget("fcdCalibSave", m_fcd_mc_save);
247  builder->get_widget("fcdCalibLoad", m_fcd_mc_load);
248 
249  //m_btn_mc_start->signal_clicked().connect( sigc::mem_fun(*this, &Firestation::mc_start) );
250  m_btn_mc_load->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::mc_load));
251  m_btn_mc_save->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::mc_save));
252 
253  builder->get_widget("btnMcSetCenter", m_btn_mc_set_center);
254  m_btn_mc_set_center->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::mc_set_center));
255 
256  builder->get_widget("btnMcMemorize", m_btn_mc_memorize);
257  m_btn_mc_memorize->signal_clicked().connect(sigc::mem_fun(*this, &Firestation::mc_memorize));
258 
259  builder->get_widget("btnMcSimulateClicks", m_btn_mc_simulate_clicks);
260  m_btn_mc_simulate_clicks->signal_clicked().connect(
261  sigc::mem_fun(*this, &Firestation::mc_simulate_clicks));
262 
263  builder->get_widget("entCalibDist", m_ent_mc_dist);
264  builder->get_widget("entCalibOri", m_ent_mc_ori);
265 
266  // ----------------------------------------------------------------
267  builder->get_widget("fcdMcLoadMask", m_fcd_mc_load_mask);
268  builder->get_widget("fcdCalibSave", m_fcd_mc_save);
269  builder->get_widget("fcdCalibLoad", m_fcd_mc_load);
270  // ----------------------------------------------------------------
271 
272  // --- fuse transfer widget ---------------------------------------
273  m_ftw = new FuseTransferWidget();
274 
275  Gtk::TreeView *trv;
276  builder->get_widget("trvFuseRemoteLuts", trv);
277  m_ftw->set_remote_lut_list_trv(trv);
278  builder->get_widget("trvFuseLocalLuts", trv);
279  m_ftw->set_local_lut_list_trv(trv);
280  builder->get_widget("imgFuseLocal", img);
281  m_ftw->set_local_img(img);
282  builder->get_widget("imgFuseRemote", img);
283  m_ftw->set_remote_img(img);
284  builder->get_widget("btnFuseUpload", btn);
285  m_ftw->set_upload_btn(btn);
286  builder->get_widget("sclLocalLayerSelector", scl);
287  m_ftw->set_local_layer_selector(scl);
288  builder->get_widget("sclRemoteLayerSelector", scl);
289  m_ftw->set_remote_layer_selector(scl);
290  // ----------------------------------------------------------------
291 
292  // --- fuse image list widget -------------------------------------
293  m_filw = new FuseImageListWidget();
294  builder->get_widget("trvFuseImageList", trv);
295  m_filw->set_image_list_trv(trv);
296  Gtk::CheckButton *chk;
297  builder->get_widget("chkFuseImageListUpdate", chk);
298  m_filw->set_auto_update_chk(chk);
299  builder->get_widget("chkFuseCompression", chk);
300  m_filw->set_toggle_compression_chk(chk);
301  m_filw->image_selected().connect(sigc::mem_fun(*this, &Firestation::on_fuse_image_selected));
302  // ----------------------------------------------------------------
303 
304  m_yuv_orig_buffer = 0;
305  m_yuv_draw_buffer = 0;
306  m_yuv_scaled_buffer = 0;
307  m_rgb_scaled_buffer = 0;
308 
309  m_img_width = 0;
310  m_img_height = 0;
311  m_img_size = 0;
312  m_img_cs = CS_UNKNOWN;
313 
314  m_img_writer = 0;
315  m_camera = 0;
316  m_shm_buffer = 0;
317 
318  m_img_src = SRC_NONE;
319  m_op_mode = MODE_VIEWER;
320 
321  m_cont_img_trans = false;
322 
323  mc_line_angle_deg = 0.0;
324 
325  m_max_img_width = m_evt_image->get_width();
326  m_max_img_height = m_evt_image->get_height();
327  m_scaled_img_width = m_evt_image->get_width();
328  m_scaled_img_height = m_evt_image->get_height();
329  m_scale_factor = 1.0;
330 
331  m_avahi_thread = new AvahiThread();
332  m_avahi_dispatcher = new AvahiDispatcher;
333 
334  m_avahi_dispatcher->signal_service_added().connect(
335  sigc::mem_fun(*this, &Firestation::on_service_added));
336  m_avahi_dispatcher->signal_service_removed().connect(
337  sigc::mem_fun(*this, &Firestation::on_service_removed));
338 
339  m_avahi_thread->watch_service("_fountain._tcp", m_avahi_dispatcher);
340  m_avahi_thread->start();
341 }
342 
343 /** Destructor. */
345 {
346  if (m_yuv_orig_buffer)
347  free(m_yuv_orig_buffer);
348  if (m_yuv_draw_buffer)
349  free(m_yuv_draw_buffer);
350  if (m_yuv_scaled_buffer)
351  free(m_yuv_scaled_buffer);
352  if (m_rgb_scaled_buffer)
353  free(m_rgb_scaled_buffer);
354 
355  delete m_camera;
356  delete m_img_writer;
357 
358 #ifdef HAVE_MIRROR_CALIB
359  delete m_calib_tool;
360 #endif
361  delete m_ctw;
362  delete m_ftw;
363  delete m_filw;
364 
365  m_avahi_thread->cancel();
366  m_avahi_thread->join();
367  delete m_avahi_thread;
368  delete m_avahi_dispatcher;
369 
370  delete m_wnd_main;
371  delete m_fcd_open_image;
372  delete m_fcd_save_image;
373  delete m_dlg_open_shm;
374  delete m_dlg_open_fuse;
375 }
376 
377 /** Returns reference to main window.
378  * @return reference to main window
379  */
380 Gtk::Window &
382 {
383  return *m_wnd_main;
384 }
385 
386 /** Exit routine. */
387 void
388 Firestation::exit()
389 {
390  if (SRC_NONE != m_img_src) {
391  m_camera->close();
392  }
393 
394  m_wnd_main->hide();
395 }
396 
397 void
398 Firestation::close_camera()
399 {
400  if (SRC_NONE == m_img_src) {
401  return;
402  }
403 
404  m_img_src = SRC_NONE;
405 
406  m_camera->close();
407  delete m_camera;
408  m_camera = 0;
409 
410  m_img_width = 0;
411  m_img_height = 0;
412  m_img_cs = CS_UNKNOWN;
413 
414  m_img_size = 0;
415 
416  m_img_image->clear();
417  m_img_image->set("gtk-missing-image");
418 
419  m_ctw->set_src_buffer(NULL, 0, 0);
420  m_ctw->set_draw_buffer(NULL);
421 }
422 
423 /** Saves the current image. */
424 void
425 Firestation::save_image()
426 {
427  if (m_img_src == SRC_NONE) {
428  return;
429  }
430 
431  m_fcd_save_image->set_transient_for(*this);
432 
433  int result = m_fcd_save_image->run();
434 
435  switch (result) {
436  case (Gtk::RESPONSE_OK): {
437  delete m_img_writer;
438 
439  Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
440  if (Glib::ustring("JPEG") == filter_name) {
441  m_img_writer = new JpegWriter();
442  } else if (Glib::ustring("FVRaw") == filter_name) {
443  m_img_writer = new FvRawWriter();
444  } else {
445  cout << "save_file(): unknown file format" << endl;
446  break;
447  }
448 
449  std::string filename = m_fcd_save_image->get_filename();
450  m_img_writer->set_filename(filename.c_str());
451  m_img_writer->set_dimensions(m_img_width, m_img_height);
452  m_img_writer->set_buffer(m_img_cs, m_yuv_orig_buffer);
453  m_img_writer->write();
454 
455  std::cout << "Save file: " << filename << std::endl;
456  break;
457  }
458 
459  case (Gtk::RESPONSE_CANCEL): break;
460 
461  default: break;
462  }
463 
464  m_fcd_save_image->hide();
465 }
466 
467 /** Reads in a new image for the current image source. */
468 void
469 Firestation::update_image()
470 {
471  if (m_img_src == SRC_NONE) {
472  return;
473  }
474 
475  try {
476  m_camera->capture();
477  convert(
478  m_img_cs, YUV422_PLANAR, m_camera->buffer(), m_yuv_orig_buffer, m_img_width, m_img_height);
479  memcpy(m_yuv_draw_buffer,
480  m_yuv_orig_buffer,
481  colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
482  m_camera->dispose_buffer();
483 
484  draw_image();
485 
486  m_ctw->draw_segmentation_result();
487  } catch (Exception &e) {
488  e.print_trace();
489  }
490 }
491 
492 bool
493 Firestation::call_update_image()
494 {
495  if (!m_cont_img_trans) {
496  return false;
497  }
498 
499  update_image();
500 
501  return true;
502 }
503 
504 void
505 Firestation::enable_cont_img_trans()
506 {
507  if (m_cont_img_trans) {
508  m_cont_img_trans = false;
509  return;
510  }
511 
512  int timeout = (int)rint(m_spb_update_time->get_value());
513  sigc::connection conn =
514  Glib::signal_timeout().connect(sigc::mem_fun(*this, &Firestation::call_update_image), timeout);
515  m_cont_img_trans = true;
516 }
517 
518 /** Reads in an image from a file. */
519 void
520 Firestation::open_file()
521 {
522  m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_OPEN);
523  m_fcd_open_image->set_transient_for(*this);
524 
525  int result = m_fcd_open_image->run();
526 
527  switch (result) {
528  case Gtk::RESPONSE_OK: {
529  pre_open_img_src();
530 
531  std::string filename = m_fcd_open_image->get_filename();
532 
533  m_camera = new FileLoader(filename.c_str());
534  m_img_src = SRC_FILE;
535  post_open_img_src();
536  break;
537  }
538 
539  case Gtk::RESPONSE_CANCEL: {
540  break;
541  }
542 
543  default: {
544  break;
545  }
546  }
547 
548  m_fcd_open_image->hide();
549 }
550 
551 /** Reads in images from a directory. */
552 void
553 Firestation::open_folder()
554 {
555  m_fcd_open_image->set_action(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
556  m_fcd_open_image->set_transient_for(*this);
557 
558  int result = m_fcd_open_image->run();
559 
560  switch (result) {
561  case Gtk::RESPONSE_OK: {
562  pre_open_img_src();
563 
564  std::string extension;
565  Glib::ustring filter_name = m_fcd_save_image->get_filter()->get_name();
566  if (Glib::ustring("JPEG") == filter_name) {
567  extension = "jpg";
568  } else if (Glib::ustring("FVRaw") == filter_name) {
569  extension = "raw";
570  }
571 
572  std::string folder = m_fcd_open_image->get_current_folder();
573  char * as;
574  if (asprintf(&as, "file:file:dir=%s:ext=%s", folder.c_str(), extension.c_str()) != -1) {
575  CameraArgumentParser cap(as);
576  m_camera = new FileLoader(&cap);
577  m_img_src = SRC_FILE;
578  post_open_img_src();
579  free(as);
580  } else {
581  printf("Cannot open folder, asprintf() ran out of memory");
582  }
583 
584  break;
585  }
586 
587  case Gtk::RESPONSE_CANCEL: {
588  break;
589  }
590 
591  default: {
592  break;
593  }
594  }
595 
596  m_fcd_open_image->hide();
597 }
598 
599 /** Opens a SHM image. */
600 void
601 Firestation::open_shm()
602 {
605  shmit = SharedMemory::find(FIREVISION_SHM_IMAGE_MAGIC_TOKEN, h);
606 
607  if (shmit == SharedMemory::end()) {
608  m_stb_status->push("No SHM images found");
609  return;
610  } else {
611  unsigned int num_buffers = 0;
612  m_shm_list_store->clear();
613 
614  while (shmit != SharedMemory::end()) {
615  ++num_buffers;
616  Gtk::TreeModel::Row row = *(m_shm_list_store->append());
617  row[m_shm_columns.m_id] = num_buffers;
619  row[m_shm_columns.m_name] = h->image_id();
620  shmit++;
621  }
622  }
623 
624  m_dlg_open_shm->set_transient_for(*this);
625 
626  int result = m_dlg_open_shm->run();
627 
628  switch (result) {
629  case Gtk::RESPONSE_OK: {
630  delete m_shm_buffer;
631 
632  Gtk::TreeModel::Path path;
633  Gtk::TreeViewColumn *column;
634  m_trv_shm_image_ids->get_cursor(path, column);
635 
636  Gtk::TreeModel::iterator iter = m_shm_list_store->get_iter(path);
637 
638  if (iter) {
639  Gtk::TreeModel::Row row = *iter;
640  if (row) {
641  Glib::ustring name = row[m_shm_columns.m_name];
642  pre_open_img_src();
643 
644  try {
645  m_camera = new SharedMemoryCamera(name.c_str());
646  } catch (Exception &e) {
647  e.print_trace();
648  }
649 
650  m_img_src = SRC_SHM;
651 
652  post_open_img_src();
653  }
654  } else {
655  std::cout << "invalid iter" << std::endl;
656  }
657 
658  break;
659  }
660 
661  case Gtk::RESPONSE_CANCEL: break;
662 
663  default: break;
664  }
665 
666  m_dlg_open_shm->hide();
667 }
668 
669 /** Connects to a FUSE server. */
670 void
671 Firestation::open_fuse()
672 {
673  Gtk::TreeModel::Children children = m_fuse_tree_store->children();
674  if (0 == children.size()) {
675  m_stb_status->push("No FUSE services found");
676  return;
677  }
678 
679  m_trv_fuse_services->expand_all();
680  m_dlg_open_fuse->set_transient_for(*this);
681 
682  int result = m_dlg_open_fuse->run();
683 
684  switch (result) {
685  case Gtk::RESPONSE_OK: {
686  Gtk::TreeModel::Path path;
687  Gtk::TreeViewColumn *column;
688  m_trv_fuse_services->get_cursor(path, column);
689 
690  Gtk::TreeModel::iterator iter = m_fuse_tree_store->get_iter(path);
691 
692  if (iter) {
693  Gtk::TreeModel::Row row = *iter;
694  if (row) {
695  Glib::ustring hostname = row[m_fuse_columns.m_service_hostname];
696  unsigned short int port = row[m_fuse_columns.m_service_port];
697  Glib::ustring image_id = row[m_fuse_columns.m_image_id];
698  bool jpeg = m_ckb_fuse_jpeg->get_active();
699 
700  pre_open_img_src();
701 
702  try {
703  m_camera = new NetworkCamera(hostname.c_str(), port, image_id.c_str(), jpeg);
704  m_img_src = SRC_FUSE;
705  post_open_img_src();
706  } catch (Exception &e) {
707  m_img_src = SRC_NONE;
708  e.print_trace();
709  }
710  }
711  } else {
712  std::cout << "invalid iter" << std::endl;
713  }
714 
715  break;
716  }
717 
718  case Gtk::RESPONSE_CANCEL: break;
719 
720  default: break;
721  }
722 
723  m_dlg_open_fuse->hide();
724 }
725 
726 void
727 Firestation::pre_open_img_src()
728 {
729  if (SRC_NONE != m_img_src) {
730  m_camera->stop();
731  m_camera->close();
732 
733  delete m_camera;
734  m_camera = 0;
735 
736  m_img_src = SRC_NONE;
737  }
738 }
739 
740 /** Stuff that is executed after an image source has been selected. */
741 void
742 Firestation::post_open_img_src()
743 {
744  if (m_img_src == SRC_NONE) {
745  return;
746  }
747 
748  try {
749  m_camera->open();
750  m_camera->start();
751  m_camera->capture();
752  m_img_width = m_camera->pixel_width();
753  m_img_height = m_camera->pixel_height();
754  m_img_cs = m_camera->colorspace();
755 
756  m_img_size = colorspace_buffer_size(m_img_cs, m_img_width, m_img_height);
757 
758  m_yuv_orig_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
759  m_yuv_draw_buffer = malloc_buffer(YUV422_PLANAR, m_img_width, m_img_height);
760 
761  convert(
762  m_img_cs, YUV422_PLANAR, m_camera->buffer(), m_yuv_orig_buffer, m_img_width, m_img_height);
763  memcpy(m_yuv_draw_buffer,
764  m_yuv_orig_buffer,
765  colorspace_buffer_size(YUV422_PLANAR, m_img_width, m_img_height));
766 
767  m_camera->dispose_buffer();
768 
769  m_tbtn_update->set_sensitive(true);
770  m_tbtn_save->set_sensitive(true);
771 
772  draw_image();
773 
774  m_ctw->set_src_buffer(m_yuv_orig_buffer, m_img_width, m_img_height);
775  m_ctw->set_draw_buffer(m_yuv_draw_buffer);
776  m_ctw->draw_segmentation_result();
777 
778  mc_draw_line();
779  } catch (Exception &e) {
780  e.print_trace();
781  printf("Opening camera failed.\n");
782  }
783 }
784 
785 void
786 Firestation::on_fuse_image_selected()
787 {
788  string host_name;
789  unsigned short port;
790  string image_id;
791  bool compression;
792 
793  m_filw->get_selected_image(host_name, port, image_id, compression);
794 
795  pre_open_img_src();
796 
797  try {
798  m_camera = new NetworkCamera(host_name.c_str(), port, image_id.c_str(), compression);
799  m_img_src = SRC_FUSE;
800  } catch (Exception &e) {
801  m_img_src = SRC_NONE;
802  e.print_trace();
803  }
804 
805  post_open_img_src();
806 }
807 
808 void
809 Firestation::on_colormap_updated()
810 {
811  m_ftw->set_current_colormap(m_ctw->get_colormap());
812 }
813 
814 /** Draws the image. */
815 void
816 Firestation::draw_image()
817 {
818  if (m_img_src == SRC_NONE) {
819  return;
820  }
821 
822  LossyScaler scaler;
823  scaler.set_original_buffer(m_yuv_draw_buffer);
824  scaler.set_original_dimensions(m_img_width, m_img_height);
825  scaler.set_scaled_dimensions(m_max_img_width, m_max_img_height);
826 
827  unsigned int scaled_width = scaler.needed_scaled_width();
828  unsigned int scaled_height = scaler.needed_scaled_height();
829 
830  if (scaled_width != m_scaled_img_width || scaled_height != m_scaled_img_height) {
831  m_scaled_img_width = scaled_width;
832  m_scaled_img_height = scaled_height;
833  m_scale_factor = scaler.get_scale_factor();
834  }
835 
836  if (m_rgb_scaled_buffer)
837  free(m_rgb_scaled_buffer);
838  if (m_yuv_scaled_buffer)
839  free(m_yuv_scaled_buffer);
840  m_yuv_scaled_buffer = malloc_buffer(YUV422_PLANAR, m_scaled_img_width, m_scaled_img_height);
841  scaler.set_scaled_buffer(m_yuv_scaled_buffer);
842  scaler.scale();
843 
844  if (m_btn_ct_seg->get_active()) {
845  unsigned int sld_img_size = m_scaled_img_width * m_scaled_img_height;
846  unsigned char u_seg = 255 / (unsigned int)pow(2, m_spbtn_width->get_value());
847  unsigned char v_seg = 255 / (unsigned int)pow(2, m_spbtn_height->get_value());
848  unsigned int u = 0;
849  for (u = sld_img_size; u < sld_img_size + sld_img_size / 2; ++u) {
850  m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / u_seg) * u_seg;
851  }
852 
853  for (; u < 2 * sld_img_size; ++u) {
854  m_yuv_scaled_buffer[u] = (m_yuv_scaled_buffer[u] / v_seg) * v_seg;
855  }
856  }
857 
858  if (m_img_src == SRC_SHM) {
859  SharedMemoryCamera *shm_camera = dynamic_cast<SharedMemoryCamera *>(m_camera);
860  if (shm_camera->shared_memory_image_buffer()->circle_found()) {
861  Drawer drawer;
862  drawer.set_buffer(m_yuv_scaled_buffer, m_scaled_img_width, m_scaled_img_height);
863  drawer.set_color(YUV_t::white());
864  unsigned int roi_x =
865  (unsigned int)rint(shm_camera->shared_memory_image_buffer()->roi_x() * m_scale_factor);
866  unsigned int roi_y =
867  (unsigned int)rint(shm_camera->shared_memory_image_buffer()->roi_y() * m_scale_factor);
868  unsigned int roi_width =
869  (unsigned int)rint(shm_camera->shared_memory_image_buffer()->roi_width() * m_scale_factor);
870  unsigned int roi_height =
871  (unsigned int)rint(shm_camera->shared_memory_image_buffer()->roi_height() * m_scale_factor);
872  drawer.draw_rectangle(roi_x, roi_y, roi_width, roi_height);
873  }
874  }
875 
876  m_rgb_scaled_buffer =
877  (unsigned char *)malloc(colorspace_buffer_size(RGB, m_scaled_img_width, m_scaled_img_height));
878 
879  convert(YUV422_PLANAR,
880  RGB,
881  m_yuv_scaled_buffer,
882  m_rgb_scaled_buffer,
883  m_scaled_img_width,
884  m_scaled_img_height);
885 
886  Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_data(m_rgb_scaled_buffer,
887  Gdk::COLORSPACE_RGB,
888  false,
889  8,
890  m_scaled_img_width,
891  m_scaled_img_height,
892  3 * m_scaled_img_width);
893 
894  m_img_image->set(image);
895 }
896 
897 /** Signal handler that is called whenever the window size is changed.
898  * @param allocation a Gtk allocation
899  */
900 void
901 Firestation::resize_image(Gtk::Allocation &allocation)
902 {
903  unsigned int new_width = (unsigned int)allocation.get_width();
904  unsigned int new_height = (unsigned int)allocation.get_height();
905 
906  if (new_width != m_max_img_width || new_height != m_max_img_height) {
907  m_max_img_width = new_width;
908  m_max_img_height = new_height;
909  draw_image();
910  }
911 }
912 
913 /** Handles mouse clicks in the image area.
914  * @param event a Gtk event
915  * @return true if signal was handled
916  */
917 bool
918 Firestation::image_click(GdkEventButton *event)
919 {
920  unsigned int offset_x;
921  unsigned int offset_y;
922 
923  offset_x = (m_max_img_width - m_scaled_img_width) / 2;
924  offset_y = (m_max_img_height - m_scaled_img_height) / 2;
925 
926  offset_x = offset_x > m_max_img_width ? 0 : offset_x;
927  offset_y = offset_y > m_max_img_height ? 0 : offset_y;
928 
929  unsigned int image_x;
930  unsigned int image_y;
931 
932  if (event != NULL) {
933  image_x = (unsigned int)rint((event->x - offset_x) / m_scale_factor);
934  image_y = (unsigned int)rint((event->y - offset_y) / m_scale_factor);
935  } else {
936  image_x = 0;
937  image_y = 0;
938  }
939 
940  if (image_x > m_img_width || image_y > m_img_height) {
941  return true;
942  }
943 
944  switch (m_op_mode) {
945  case MODE_VIEWER:
946  if (m_img_src != SRC_NONE) {
947  unsigned char y;
948  unsigned char u;
949  unsigned char v;
950  YUV422_PLANAR_YUV(m_yuv_orig_buffer, m_img_width, m_img_height, image_x, image_y, y, u, v);
951  printf("Y=%u U=%u Y=%u @ (%u, %u)\n",
952  (unsigned int)y,
953  (unsigned int)u,
954  (unsigned int)v,
955  image_x,
956  image_y);
957  }
958  break;
959 
960  case MODE_COLOR_TRAIN:
961  m_ctw->click(image_x, image_y, event->button);
962  draw_image();
963  break;
964 
965  case MODE_MIRROR_CALIB: {
966 #ifdef HAVE_MIRROR_CALIB
967  if (m_btn_mc_set_center->get_active()) {
968  m_calib_tool->set_center(image_x, image_y);
969  m_btn_mc_set_center->set_active(false);
970  mc_draw_line();
971  printf("Setting center to %u, %u\n", image_x, image_y);
972  } else {
973  printf("Using center to %d, %d\n", m_calib_tool->center_x(), m_calib_tool->center_y());
974  m_calib_tool->next_step();
975  const unsigned char *last_yuv = m_calib_tool->get_last_yuv_buffer();
976  memcpy(m_yuv_draw_buffer, last_yuv, m_img_size);
977  memcpy(m_yuv_orig_buffer, last_yuv, m_img_size);
978  m_calib_tool->draw_mark_lines(m_yuv_draw_buffer);
979  draw_image();
980  m_stb_status->push(m_calib_tool->get_state_description());
981  }
982 #else
983  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
984 #endif
985  break;
986  }
987 
988  case MODE_MIRROR_CALIB_EVAL: {
989 #ifdef HAVE_MIRROR_CALIB
990  float dist;
991  float phi;
992  m_calib_tool->eval(image_x, image_y, &dist, &phi);
993  phi = normalize_mirror_rad(phi);
994  printf("(%u, %u) = POLAR(%.2f deg, %.2f meters)\n", image_x, image_y, rad2deg(phi), dist);
995  //printf("Distance: %2f\t Phi: %2f\n", dist, phi);
996 #else
997  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
998 #endif
999  break;
1000  }
1001 
1002  default: break;
1003  }
1004 
1005  return true;
1006 }
1007 
1008 /** Starts the color training. */
1009 void
1010 Firestation::ct_start()
1011 {
1012  if (m_op_mode == MODE_COLOR_TRAIN) {
1013  m_op_mode = MODE_VIEWER;
1014  m_stb_status->push("Leaving color training mode");
1015  } else {
1016  if (m_img_src != SRC_NONE) {
1017  m_ctw->set_fg_object(ct_get_fg_object());
1018 
1019  m_op_mode = MODE_COLOR_TRAIN;
1020 
1021  m_stb_status->push("Entering color training mode");
1022  }
1023  }
1024 }
1025 
1026 hint_t
1027 Firestation::ct_get_fg_object()
1028 {
1029  int active = m_cmb_ct_type->get_active_row_number();
1030  switch (active) {
1031  case 0: //Ball
1032  return H_BALL;
1033 
1034  case 1: //Field
1035  return H_FIELD;
1036 
1037  case 2: //Lines
1038  return H_LINE;
1039 
1040  case 3: //Robot (Team A or all)
1041  return H_ROBOT;
1042 
1043  case 4: //Robot (Team B)
1044  return H_ROBOT_OPP;
1045 
1046  case 5: //Goal (yellow)
1047  return H_GOAL_YELLOW;
1048 
1049  case 6: //Goal (sky-blue)
1050  return H_GOAL_BLUE;
1051 
1052  case 7: //Background
1053  return H_UNKNOWN;
1054 
1055  default: printf("ct_get_fg_object(): UNKNOWN\n"); return H_UNKNOWN;
1056  }
1057 }
1058 
1059 void
1060 Firestation::ct_object_changed()
1061 {
1062  hint_t object = ct_get_fg_object();
1063  m_ctw->set_fg_object(object);
1064 }
1065 
1066 void
1067 Firestation::mc_draw_line()
1068 {
1069  if (m_img_src != SRC_NONE) {
1070 #ifdef HAVE_MIRROR_CALIB
1071  memcpy(m_yuv_draw_buffer, m_yuv_orig_buffer, m_img_size);
1072  MirrorCalibTool::draw_line(m_yuv_draw_buffer,
1073  mc_line_angle_deg,
1074  m_calib_tool->center_x(),
1075  m_calib_tool->center_y(),
1076  m_img_width,
1077  m_img_height);
1078  draw_image();
1079 #else
1080  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1081 #endif
1082  }
1083 }
1084 
1085 bool
1086 Firestation::mc_on_line_angle_changed(Gtk::ScrollType scroll, double value)
1087 {
1088  mc_line_angle_deg = -1.0f * value;
1089  mc_line_angle_deg = rad2deg(normalize_mirror_rad(deg2rad(mc_line_angle_deg)));
1090  // Why -1.0f * value?
1091  // We want to display angles from the robot's real-world perspective.
1092  // We want to calculate with angles from the (mirrored!) image's perspective.
1093  // So when the user chooses 90 degrees, he wants to look to the left from the
1094  // robots perspective. But due to the mirroring, that's the right side in the
1095  // image, so we take -90 degrees.
1096  mc_draw_line();
1097  return true;
1098 }
1099 
1100 void
1101 Firestation::mc_load_mask()
1102 {
1103  m_fcd_mc_load_mask->set_transient_for(*this);
1104 
1105 #if GTK_VERSION_GE(3, 0)
1106  Glib::RefPtr<Gtk::FileFilter> filter_mirror = Gtk::FileFilter::create();
1107 #else
1108  Gtk::FileFilter *filter_mirror = Gtk::manage(new Gtk::FileFilter());
1109 #endif
1110  filter_mirror->set_name("Robot Mask");
1111  filter_mirror->add_pattern("*.pnm");
1112 #if GTK_VERSION_GE(3, 0)
1113  m_fcd_mc_load_mask->add_filter(filter_mirror);
1114 #else
1115  m_fcd_mc_load_mask->add_filter(*filter_mirror);
1116 #endif
1117 
1118  int result = m_fcd_mc_load_mask->run();
1119 
1120  switch (result) {
1121  case Gtk::RESPONSE_OK: {
1122 #ifdef HAVE_MIRROR_CALIB
1123  std::string filename = m_fcd_mc_load_mask->get_filename();
1124  m_calib_tool->load_mask(filename.c_str());
1125  //m_op_mode = MODE_MIRROR_CALIB_EVAL;
1126 #else
1127  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1128 #endif
1129  break;
1130  }
1131  case Gtk::RESPONSE_CANCEL: break;
1132  default: break;
1133  }
1134 
1135  m_fcd_mc_load_mask->hide();
1136 }
1137 
1138 /** Enters MODE_MIRROR_CALIB mode which waits for a click to mark the
1139  * preliminary center of the image. */
1140 void
1141 Firestation::mc_set_center()
1142 {
1143  m_op_mode = MODE_MIRROR_CALIB;
1144 }
1145 
1146 /** Start the mirror calibration process. */
1147 void
1148 Firestation::mc_memorize()
1149 {
1150  /* if (m_op_mode == MODE_MIRROR_CALIB)
1151  {
1152  m_op_mode = MODE_VIEWER;
1153  m_stb_status->push("Leaving mirror calibration mode");
1154  }
1155  else */
1156  if (m_img_src != SRC_NONE) {
1157 #ifdef HAVE_MIRROR_CALIB
1158  double ori = mc_line_angle_deg;
1159  std::cout << "Starting calibration for ori = " << ori << std::endl;
1160  m_calib_tool->push_back(m_yuv_orig_buffer, m_img_size, m_img_width, m_img_height, deg2rad(ori));
1161  m_op_mode = MODE_MIRROR_CALIB;
1162  std::cout << "Initialization for ori = " << ori << " completed" << std::endl;
1163 
1164  mc_line_angle_deg -= 120.0;
1165  mc_line_angle_deg = rad2deg(normalize_mirror_rad(deg2rad(mc_line_angle_deg)));
1166  m_scl_mc_line->set_value(-1.0f * mc_line_angle_deg);
1167  // Why -1.0f * mc_line_angle_deg?
1168  // We want to display angles from the robot's real-world perspective.
1169  // We want to calculate with angles from the (mirrored!) image's perspective.
1170  // So when the user chooses 90 degrees, he wants to look to the left from the
1171  // robots perspective. But due to the mirroring, that's the right side in the
1172  // image, so we take -90 degrees.
1173  mc_draw_line();
1174 #else
1175  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1176 #endif
1177  }
1178 }
1179 
1180 /** Start the mirror calibration process. */
1181 void
1182 Firestation::mc_simulate_clicks()
1183 {
1184  for (int i = 1; i <= 3; ++i) {
1185  image_click(NULL); // SHARPENING
1186  for (int j = 1; j <= 8; ++j) {
1187  image_click(NULL);
1188  } // EDGE_DETECTION
1189  for (int j = 1; j <= 2 * 8; ++j) {
1190  image_click(NULL);
1191  } // COMBINATION
1192  image_click(NULL); // PRE_MARKING
1193  image_click(NULL); // FINAL_MARKING
1194  }
1195 }
1196 
1197 /** Load mirror calibration data from a file. */
1198 void
1199 Firestation::mc_load()
1200 {
1201  m_fcd_mc_load->set_transient_for(*this);
1202 
1203 #if GTK_VERSION_GE(3, 0)
1204  Glib::RefPtr<Gtk::FileFilter> filter_mirror = Gtk::FileFilter::create();
1205 #else
1206  Gtk::FileFilter *filter_mirror = Gtk::manage(new Gtk::FileFilter());
1207 #endif
1208  filter_mirror->set_name("Mirror Calibration");
1209  filter_mirror->add_pattern("*.mirror");
1210  filter_mirror->add_pattern("*.bulb");
1211 #if GTK_VERSION_GE(3, 0)
1212  m_fcd_mc_load->add_filter(filter_mirror);
1213 #else
1214  m_fcd_mc_load->add_filter(*filter_mirror);
1215 #endif
1216 
1217  int result = m_fcd_mc_load->run();
1218 
1219  switch (result) {
1220  case Gtk::RESPONSE_OK: {
1221 #ifdef HAVE_MIRROR_CALIB
1222  std::string filename = m_fcd_mc_load->get_filename();
1223  m_calib_tool->load(filename.c_str());
1224  m_op_mode = MODE_MIRROR_CALIB_EVAL;
1225 #else
1226  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1227 #endif
1228  break;
1229  }
1230  case Gtk::RESPONSE_CANCEL: break;
1231  default: break;
1232  }
1233 
1234  m_fcd_mc_load->hide();
1235 }
1236 
1237 /** Save calibration data to a file. */
1238 void
1239 Firestation::mc_save()
1240 {
1241  m_fcd_mc_save->set_transient_for(*this);
1242 
1243  int result = m_fcd_mc_save->run();
1244 
1245  switch (result) {
1246  case (Gtk::RESPONSE_OK): {
1247 #ifdef HAVE_MIRROR_CALIB
1248  std::string filename = m_fcd_mc_save->get_filename();
1249 
1250  m_calib_tool->save(filename.c_str());
1251 #else
1252  printf("IPP and OpenCV not installed; mirror calibration does not work.\n");
1253 #endif
1254  break;
1255  }
1256 
1257  case (Gtk::RESPONSE_CANCEL): break;
1258 
1259  default: break;
1260  }
1261 
1262  m_fcd_mc_save->hide();
1263 }
1264 
1265 void
1266 Firestation::on_service_added(NetworkService *service)
1267 {
1268  const char * host = service->host();
1269  const char * name = service->name();
1270  const char * type = service->type();
1271  const char * domain = service->domain();
1272  unsigned short int port = service->port();
1273 
1274  std::vector<FUSE_imageinfo_t> image_list;
1275  NetworkCamera cam(host, port);
1276  try {
1277  cam.open();
1278  cam.start();
1279  image_list = cam.image_list();
1280  } catch (Exception &e) {
1281  e.append("Could not open camera on %s:%d", host, port);
1282  e.print_trace();
1283  return;
1284  }
1285  cam.close();
1286 
1287 #ifdef DEBUG_PRINT
1288  printf("%zu images available on host %s.\n", image_list.size(), host);
1289 #endif /* DEBUG_PRINT */
1290 
1291  std::vector<FUSE_imageinfo_t>::iterator fit;
1292 
1293  Gtk::TreeModel::Children children = m_fuse_tree_store->children();
1294  Gtk::TreeModel::Row row = *(m_fuse_tree_store->append());
1295  row[m_fuse_columns.m_id] = children.size();
1296  row[m_fuse_columns.m_name] = Glib::ustring(name);
1297  row[m_fuse_columns.m_service_name] = Glib::ustring(name);
1298  row[m_fuse_columns.m_service_type] = Glib::ustring(type);
1299  row[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
1300  row[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
1301  row[m_fuse_columns.m_service_port] = port;
1302 
1303  for (fit = image_list.begin(); fit != image_list.end(); ++fit) {
1304  Gtk::TreeModel::Row childrow = *(m_fuse_tree_store->append(row.children()));
1305  childrow[m_fuse_columns.m_name] = Glib::ustring(fit->image_id);
1306  childrow[m_fuse_columns.m_service_name] = Glib::ustring(name);
1307  childrow[m_fuse_columns.m_service_type] = Glib::ustring(type);
1308  childrow[m_fuse_columns.m_service_domain] = Glib::ustring(domain);
1309  childrow[m_fuse_columns.m_service_hostname] = Glib::ustring(host);
1310  childrow[m_fuse_columns.m_service_port] = port;
1311  childrow[m_fuse_columns.m_image_id] = Glib::ustring(fit->image_id);
1312  childrow[m_fuse_columns.m_image_width] = fit->width;
1313  childrow[m_fuse_columns.m_image_height] = fit->height;
1314  childrow[m_fuse_columns.m_image_colorspace] =
1315  Glib::ustring(colorspace_to_string((colorspace_t)fit->colorspace));
1316  }
1317 
1318  m_ftw->add_fountain_service(name, host, port);
1319  m_filw->add_fountain_service(name, host, port);
1320 }
1321 
1322 void
1323 Firestation::on_service_removed(NetworkService *service)
1324 {
1325  const char *name = service->name();
1326  const char *type = service->type();
1327  const char *domain = service->domain();
1328 
1329  Gtk::TreeModel::iterator rit = m_fuse_tree_store->children().begin();
1330  while (rit != m_fuse_tree_store->children().end()) {
1331  Glib::ustring n = (*rit)[m_fuse_columns.m_service_name];
1332  Glib::ustring t = (*rit)[m_fuse_columns.m_service_type];
1333  Glib::ustring d = (*rit)[m_fuse_columns.m_service_domain];
1334 
1335  if (strcmp(n.c_str(), name) == 0 && strcmp(t.c_str(), type) == 0
1336  && strcmp(d.c_str(), domain) == 0) {
1337  rit = m_fuse_tree_store->erase(rit);
1338  } else {
1339  ++rit;
1340  }
1341  }
1342 
1343  m_ftw->remove_fountain_service(name);
1344  m_filw->remove_fountain_service(name);
1345 }
firevision::SharedMemoryImageBuffer::roi_height
unsigned int roi_height() const
Get ROI height.
Definition: shm_image.cpp:290
firevision::Camera::start
virtual void start()=0
firevision::NetworkCamera
Definition: net.h:44
firevision::FileLoader
Definition: fileloader.h:43
firevision::SharedMemoryImageBufferHeader::image_id
const char * image_id() const
Get image number.
Definition: shm_image.cpp:837
firevision::LossyScaler::scale
virtual void scale()
Definition: lossy.cpp:143
firevision::Drawer::set_color
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.
Definition: drawer.cpp:75
firevision::SharedMemoryCamera
Definition: shmem.h:39
ColorTrainWidget
Definition: color_train_widget.h:38
Firestation::~Firestation
virtual ~Firestation()
Destructor.
Definition: firestation.cpp:344
firevision::LossyScaler::set_original_buffer
virtual void set_original_buffer(unsigned char *buffer)
Definition: lossy.cpp:113
fawkes::NetworkService::domain
const char * domain() const
Get domain of service.
Definition: service.cpp:396
firevision::Camera::open
virtual void open()=0
firevision::SharedMemoryImageBuffer::roi_width
unsigned int roi_width() const
Get ROI width.
Definition: shm_image.cpp:281
firevision::Camera::close
virtual void close()=0
firevision::MirrorCalibTool
Definition: mirror_calib.h:47
fawkes::AvahiDispatcher::signal_service_added
sigc::signal< void, NetworkService * > signal_service_added()
Get "service added" signal.
Definition: avahi_dispatcher.cpp:81
firevision::SharedMemoryImageBuffer::circle_found
bool circle_found() const
Check if circle was found .
Definition: shm_image.cpp:456
fawkes::Exception::append
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:332
FuseTransferWidget
Definition: fuse_transfer_widget.h:36
fawkes::rad2deg
float rad2deg(float rad)
Convert an angle given in radians to degrees.
Definition: angle.h:50
fawkes::NetworkService::host
const char * host() const
Get host of service.
Definition: service.cpp:405
fawkes::AvahiThread
Definition: avahi_thread.h:52
Firestation::get_window
Gtk::Window & get_window() const
Returns reference to main window.
Definition: firestation.cpp:381
firevision::Drawer::draw_rectangle
void draw_rectangle(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
Draw rectangle.
Definition: drawer.cpp:203
firevision::LossyScaler::set_scaled_dimensions
virtual void set_scaled_dimensions(unsigned int width, unsigned int height)
Definition: lossy.cpp:87
fawkes::NetworkService
Definition: service.h:41
firevision::SharedMemoryCamera::shared_memory_image_buffer
SharedMemoryImageBuffer * shared_memory_image_buffer()
Get the shared memory image buffer.
Definition: shmem.cpp:224
fawkes
fawkes::NetworkService::port
unsigned short int port() const
Get port of service.
Definition: service.cpp:414
firevision::FuseImageListWidget
Definition: fuse_image_list_widget.h:40
firevision::LossyScaler::get_scale_factor
virtual float get_scale_factor()
Definition: lossy.cpp:137
firevision::LossyScaler::needed_scaled_width
virtual unsigned int needed_scaled_width()
Definition: lossy.cpp:125
fawkes::deg2rad
float deg2rad(float deg)
Convert an angle given in degrees to radians.
Definition: angle.h:40
fawkes::AvahiDispatcher
Definition: avahi_dispatcher.h:41
fawkes::SharedMemory::SharedMemoryIterator
Definition: shm.h:122
fawkes::Exception::print_trace
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:600
firevision::CameraArgumentParser
Definition: camargp.h:39
firevision::LossyScaler
Definition: lossy.h:37
fawkes::NetworkService::type
const char * type() const
Get type of service.
Definition: service.cpp:387
firevision::SharedMemoryImageBufferHeader
Definition: shm_image.h:65
fawkes::normalize_mirror_rad
float normalize_mirror_rad(float angle_rad)
Normalize angle in radian between -PI (inclusive) and PI (exclusive).
Definition: angle.h:76
firevision::LossyScaler::set_original_dimensions
virtual void set_original_dimensions(unsigned int width, unsigned int height)
Definition: lossy.cpp:80
firevision::SharedMemoryImageBuffer::roi_x
unsigned int roi_x() const
Get ROI X.
Definition: shm_image.cpp:263
firevision::FvRawWriter
Definition: fvraw.h:35
firevision::Drawer
Definition: drawer.h:35
fawkes::NetworkService::name
const char * name() const
Get name of service.
Definition: service.cpp:353
firevision::JpegWriter
Definition: jpeg.h:37
firevision::LossyScaler::set_scaled_buffer
virtual void set_scaled_buffer(unsigned char *buffer)
Definition: lossy.cpp:119
firevision::LossyScaler::needed_scaled_height
virtual unsigned int needed_scaled_height()
Definition: lossy.cpp:131
firevision::Drawer::set_buffer
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
Definition: drawer.cpp:62
firevision::SharedMemoryImageBuffer::roi_y
unsigned int roi_y() const
Get ROI Y.
Definition: shm_image.cpp:272
Firestation::Firestation
Firestation(Glib::RefPtr< Gtk::Builder > builder)
Constructor.
Definition: firestation.cpp:65
fawkes::Exception
Definition: exception.h:39