All Classes Namespaces Files Functions Variables Enumerations Enumerator
programs/UrgViewer/UrgViewerWindow.cpp
Go to the documentation of this file.
00001 
00010 #include "UrgViewerWindow.h"
00011 #include "UrgDrawWidget.h"
00012 #include "RangeSensorConnectThread.h"
00013 #include "SerialConnectionWidget.h"
00014 #include "EthernetConnectionWidget.h"
00015 #include "CaptureSettingWidget.h"
00016 #include "LengthViewWidget.h"
00017 #include "mUrgDevice.h"
00018 #include "RangeSensorParameter.h"
00019 #include "SerialDevice.h"
00020 #include "TcpipSocket.h"
00021 #include "FindComPorts.h"
00022 #include "UrgUsbCom.h"
00023 #include "ticks.h"
00024 #include "MonitorModeManager.h"
00025 #include "MonitorEventScheduler.h"
00026 #include "Lock.h"
00027 #include "LockGuard.h"
00028 #include "log_printf.h"
00029 #include "codedString.h"
00030 #include "split.h"
00031 #include <QTimer>
00032 #include <QDateTime>
00033 #include <QShortcut>
00034 #include <QMessageBox>
00035 #include <QSettings>
00036 #include <QCloseEvent>
00037 
00038 using namespace qrk;
00039 using namespace std;
00040 
00041 
00042 //#define DEBUG 1
00043 
00044 
00045 namespace
00046 {
00047     const char* Version = "1.0.4";
00048 
00049     const char* Organization = "Hokuyo LTD.";
00050     const char* Application = "URG Viewer";
00051     const char* UrgDefaultAddress = "192.168.0.10";
00052 
00053     enum {
00054         UrgDefaultPort = 10940,
00055         InvalidTimestamp = -1,
00056     };
00057 }
00058 
00059 
00060 struct UrgViewerWindow::pImpl
00061 {
00062     UrgViewerWindow* widget_;
00063 
00064     mUrgDevice urg_;
00065     SerialDevice* serial_connection_;
00066     TcpipSocket ethernet_connection_;
00067 
00068     FindComPorts com_finder_;
00069     UrgUsbCom urg_usb_;
00070 
00071     CaptureSettingWidget capture_setting_widget_;
00072     LengthViewWidget length_view_widget_;
00073 
00074     UrgDrawWidget urg_draw_widget_;
00075     SerialConnectionWidget serial_connection_widget_;
00076     EthernetConnectionWidget ethernet_connection_widget_;
00077     RangeSensorConnectThread connect_thread_;
00078     bool draw_intensity_;
00079     Lock urg_mutex_;
00080 
00081     QTimer capture_timer_;
00082     long last_timestamp_;
00083     QDateTime last_record_time_;
00084 
00085     RangeSensorParameter parameter_;
00086     CaptureSettings* settings_;
00087 
00088     bool set_length_view_;
00089     vector<int> draw_line_indexes_;
00090     vector<Point<long> > draw_line_points_;
00091 
00092 
00093     pImpl(int argc, char *argv[], UrgViewerWindow* widget)
00094         : widget_(widget), urg_(argc, argv), serial_connection_(NULL),
00095           capture_setting_widget_(urg_), connect_thread_(urg_),
00096           draw_intensity_(false), last_timestamp_(InvalidTimestamp),
00097           last_record_time_(QDateTime::currentDateTime()),
00098           settings_(NULL), set_length_view_(false)
00099     {
00100         com_finder_.addBaseName("/dev/ttyACM");
00101         com_finder_.addBaseName("/dev/tty.usbmodem");
00102 
00103         com_finder_.addDriverName("URG Series USB Device Driver");
00104         com_finder_.addDriverName("URG-X002 USB Device Driver");
00105 
00106         ethernet_connection_widget_.setPort(UrgDefaultPort);
00107 
00108         for (int i = 1; i < argc; ++i) {
00109             if (! strcmp("-i", argv[i])) {
00110                 draw_intensity_ = true;
00111             }
00112         }
00113 
00114         if (draw_intensity_) {
00115             capture_setting_widget_.setIntensityMode();
00116         }
00117     }
00118 
00119 
00120     ~pImpl(void)
00121     {
00122         delete settings_;
00123     }
00124 
00125 
00126     void initializeForm(void)
00127     {
00128         // タイトルにバージョン情報を付加
00129         const QString title = widget_->windowTitle() + " " + Version;
00130         widget_->setWindowTitle(title);
00131 
00132         // ウィジットの配置
00133         widget_->dummy_label_2_->hide();
00134         widget_->main_layout_->addWidget(&urg_draw_widget_);
00135         widget_->connect_layout_->addWidget(&serial_connection_widget_);
00136         widget_->connect_layout_->addWidget(&ethernet_connection_widget_);
00137 
00138         // メニュー項目
00139         connect(widget_->action_quit_, SIGNAL(triggered()),
00140                 widget_, SLOT(close()));
00141         connect(widget_->action_about_, SIGNAL(triggered()),
00142                 widget_, SLOT(aboutApplication()));
00143         connect(widget_->action_zoomIn_, SIGNAL(triggered()),
00144                 widget_, SLOT(zoomLarger()));
00145         connect(widget_->action_zoomOut_, SIGNAL(triggered()),
00146                 widget_, SLOT(zoomSmaller()));
00147         connect(widget_->action_capture_setting_, SIGNAL(triggered()),
00148                 widget_, SLOT(showCaptureSettingWidget()));
00149         connect(widget_->action_length_view_, SIGNAL(triggered()),
00150                 widget_, SLOT(showLengthViewWidget()));
00151         connect(widget_->action_serial_, SIGNAL(triggered()),
00152                 widget_, SLOT(selectSerial()));
00153         connect(widget_->action_ethernet_, SIGNAL(triggered()),
00154                 widget_, SLOT(selectEthernet()));
00155 
00156         // URG デバイス
00157         connect(&capture_timer_, SIGNAL(timeout()),
00158                 widget_, SLOT(captureHandler()));
00159 
00160         // Serial 接続
00161         connect(&serial_connection_widget_, SIGNAL(rescanRequest()),
00162                 widget_, SLOT(rescanPressed()));
00163         connect(&serial_connection_widget_,
00164                 SIGNAL(connectRequest(bool, const std::string&)),
00165                 widget_, SLOT(connectPressed(bool, const std::string&)));
00166         connect(&connect_thread_, SIGNAL(connected(bool)),
00167                 widget_, SLOT(connectDevice(bool)));
00168 
00169         // Ethernet 接続
00170         connect(&ethernet_connection_widget_,
00171                 SIGNAL(connectRequest(bool, const std::string&,
00172                                       unsigned short)),
00173                 widget_, SLOT(connectPressed(bool, const std::string&,
00174                                              unsigned short)));
00175 
00176         // ステータスバー表示
00177         connect(&urg_draw_widget_, SIGNAL(position(bool, long, long)),
00178                 widget_, SLOT(updateStatusBar(bool, long, long)));
00179 
00180         // キー割り付け
00181         (void) new QShortcut(Qt::Key_Return, widget_, SLOT(initializeView()));
00182         (void) new QShortcut(Qt::Key_Less, widget_, SLOT(zoomSmaller()));
00183         (void) new QShortcut(Qt::Key_Comma, widget_, SLOT(zoomSmaller()));
00184         (void) new QShortcut(Qt::Key_Greater, widget_, SLOT(zoomLarger()));
00185         (void) new QShortcut(Qt::Key_Period, widget_, SLOT(zoomLarger()));
00186 
00187         // 外部 Widget からのシグナル
00188         connect(&capture_setting_widget_,
00189                 SIGNAL(setCaptureSettings(const qrk::CaptureSettings&)),
00190                 widget_,
00191                 SLOT(receiveCaptureSettings(const qrk::CaptureSettings&)));
00192         connect(&capture_setting_widget_, SIGNAL(reconnectRequest()),
00193                 widget_, SLOT(receiveReconnectRequest()));
00194         connect(&length_view_widget_, SIGNAL(lengthViewRequest()),
00195                 widget_, SLOT(receiveLengthViewRequest()));
00196 
00197         connect(&capture_setting_widget_,
00198                 SIGNAL(widgetClose(const std::string&)),
00199                 widget_, SLOT(receiveWidgetClose(const std::string&)));
00200         connect(&length_view_widget_, SIGNAL(widgetClose(const std::string&)),
00201                 widget_, SLOT(receiveWidgetClose(const std::string&)));
00202         connect(&length_view_widget_, SIGNAL(quit()), widget_, SLOT(close()));
00203         connect(&capture_setting_widget_, SIGNAL(quit()),
00204                 widget_, SLOT(close()));
00205 
00206         connect(&length_view_widget_,
00207                 SIGNAL(drawLineRequest(const std::vector<int>&)),
00208                 widget_, SLOT(receiveDrawLine(const std::vector<int>&)));
00209 
00210         connect(widget_, SIGNAL(reconnectCompleted()),
00211                 &capture_setting_widget_, SLOT(reconnectCompleted()));
00212 
00213         // キー割り付け
00214         (void) new QShortcut(Qt::CTRL + Qt::Key_W, widget_, SLOT(close()));
00215 
00216         widget_->rescanPressed();
00217     }
00218 
00219 
00220     void saveSettings(void)
00221     {
00222         QSettings settings(Organization, Application);
00223 
00224         settings.setValue("geometry", widget_->saveGeometry());
00225         settings.setValue("LengthView_geometry",
00226                           length_view_widget_.saveGeometry());
00227         settings.setValue("CaptureSetting_geometry",
00228                           capture_setting_widget_.saveGeometry());
00229 
00230         if (MonitorModeManager::object()->mode() != MonitorModeManager::Play) {
00231             settings.setValue("LengthView_showed",
00232                               widget_->action_length_view_->isChecked());
00233             settings.setValue("CaptureSetting_showed",
00234                               widget_->action_capture_setting_->isChecked());
00235         }
00236 
00237         bool use_serial = serial_connection_widget_.isVisible();
00238         settings.setValue("serial_connection", use_serial);
00239 
00240         settings.setValue("address",
00241                           ethernet_connection_widget_.address().c_str());
00242         settings.setValue("port", ethernet_connection_widget_.port());
00243     }
00244 
00245 
00246     void loadSettings(void)
00247     {
00248         QSettings settings(Organization, Application);
00249 
00250         widget_->restoreGeometry(settings.value("geometry").toByteArray());
00251         length_view_widget_.
00252             restoreGeometry(settings.value("LengthView_geometry").toByteArray());
00253         capture_setting_widget_.
00254             restoreGeometry(settings.value("CaptureSetting_geometry").toByteArray());
00255 
00256         if (MonitorModeManager::object()->mode() != MonitorModeManager::Play) {
00257             if (settings.value("LengthView_showed", false).toBool() == true) {
00258                 activateWidget(&length_view_widget_,
00259                                widget_->action_length_view_);
00260             }
00261             if (settings.value("CaptureSetting_showed",
00262                                false).toBool() == true) {
00263                 activateWidget(&capture_setting_widget_,
00264                                widget_->action_capture_setting_);
00265             }
00266         }
00267 
00268         bool use_serial = settings.value("serial_connection", true).toBool();
00269         if (use_serial) {
00270             widget_->selectSerial();
00271         } else {
00272             widget_->selectEthernet();
00273         }
00274 
00275         string address =
00276             settings.value("address",
00277                            UrgDefaultAddress).toString().toStdString();
00278         ethernet_connection_widget_.setAddress(address);
00279         unsigned short port = settings.value("port", UrgDefaultPort).toInt();
00280         ethernet_connection_widget_.setPort(port);
00281     }
00282 
00283 
00284     void connectDevice(bool connected)
00285     {
00286         last_timestamp_ = InvalidTimestamp;
00287         serial_connection_widget_.setConnected(connected);
00288         ethernet_connection_widget_.setConnected(connected);
00289         capture_setting_widget_.setConnected(connected);
00290         if (! connected) {
00291             // エラーメッセージのポップアップ表示
00292             QString error_message = localedToUnicode(urg_.what());
00293             QMessageBox::warning(widget_,
00294                                  tr("Connection error"), error_message);
00295             return;
00296         }
00297 
00298         // パラメータ情報が与えられていない場合、センサ情報を反映させる
00299         parameter_ = urg_.parameter();
00300         if (! settings_) {
00301             settings_ = initializeCaptureSettings(parameter_.area_min,
00302                                                   parameter_.area_max);
00303             capture_setting_widget_.loadPressed();
00304         }
00305 
00306         size_t type_length = parameter_.model.find('(');
00307         string urg_type = parameter_.model.substr(0, type_length);
00308         bool cluster_enable =
00309             ! (draw_intensity_ && urg_type.compare("UTM-30LX"));
00310         if (draw_intensity_) {
00311             capture_setting_widget_.setIntensityMode(cluster_enable);
00312         }
00313 
00314         receiveReconnectRequest();
00315         length_view_widget_.setMinDistance(urg_.minDistance());
00316 
00317         // URG 設定
00318         urg_.setTimestamp(ticks());
00319         int scan_msec = urg_.scanMsec();
00320         urg_draw_widget_.setDrawPeriod(scan_msec);
00321 
00322         // データの取得開始
00323         capture_timer_.setInterval(scan_msec / 2);
00324         capture_timer_.start();
00325     }
00326 
00327 
00328     CaptureSettings* initializeCaptureSettings(int first_index, int last_index)
00329     {
00330         CaptureSettings* settings = new CaptureSettings;
00331         settings->type = MD;
00332         settings->capture_first = first_index;
00333         settings->capture_last = last_index;
00334         settings->skip_lines = 1;
00335         settings->skip_frames = 0;
00336         settings->remain_times = 0;
00337         settings->data_byte = 3;
00338 
00339         return settings;
00340     }
00341 
00342     void receiveReconnectRequest(void)
00343     {
00344         capture_timer_.stop();
00345         urg_draw_widget_.clear();
00346 
00347         if (draw_intensity_) {
00348             urg_.setCaptureMode(IntensityCapture);
00349 
00350         } else if (settings_->type == MD) {
00351             urg_.setCaptureMode(AutoCapture);
00352 
00353         } else if (settings_->type == GD) {
00354             urg_.setCaptureMode(ManualCapture);
00355         }
00356 
00357         urg_.setCaptureRange(settings_->capture_first, settings_->capture_last);
00358         urg_.setCaptureSkipLines(settings_->skip_lines);
00359 
00360         if (settings_->type != GD) {
00361             urg_.setCaptureFrameInterval(settings_->skip_frames);
00362             urg_.setCaptureTimes(settings_->remain_times);
00363         }
00364 
00365         if (! urg_.isConnected()) {
00366             // 未接続ならば再開させない
00367             return;
00368         }
00369 
00370         setConnectionMenuEnabled(false);
00371         capture_timer_.start();
00372     }
00373 
00374 
00375     void disconnectDevice(void)
00376     {
00377         // データの取得停止
00378         widget_->scans_label_->setText("");
00379         capture_timer_.stop();
00380         urg_draw_widget_.clear();
00381         capture_setting_widget_.setApplyEnabled(true);
00382 
00383         serial_connection_widget_.setConnected(false);
00384         ethernet_connection_widget_.setConnected(false);
00385         capture_setting_widget_.setConnected(false);
00386         setConnectionMenuEnabled(true);
00387     }
00388 
00389 
00390     void setConnectionMenuEnabled(bool enabled)
00391     {
00392         widget_->action_serial_->setEnabled(enabled);
00393         widget_->action_ethernet_->setEnabled(enabled);
00394     }
00395 
00396 
00397     void captureHandler(void)
00398     {
00399         LockGuard guard(urg_mutex_);
00400 
00401         vector<long> data;
00402         vector<long> intensity_data;
00403         long timestamp = 0;
00404 
00405         RangeCaptureMode capture_mode = urg_.captureMode();
00406         int n = 0;
00407         if (capture_mode != IntensityCapture) {
00408             n = urg_.capture(data, &timestamp);
00409 
00410         } else {
00411             n = urg_.captureWithIntensity(data, intensity_data, &timestamp);
00412         }
00413         if (n <= 0) {
00414             return;
00415         }
00416 
00417 #if defined(DEBUG)
00418         // !!! debug message
00419         QDateTime current = QDateTime::currentDateTime();
00420         if (last_record_time_.secsTo(current) >= 60) {
00421             log_printf("%s\n",
00422                        current.toString(Qt::ISODate).toStdString().c_str());
00423             last_record_time_ = current;
00424         }
00425 #endif
00426 
00427         // update "scans interval"
00428         int interval_msec = timestamp - last_timestamp_;
00429         if (last_timestamp_ != InvalidTimestamp) {
00430             widget_->updateScansInterval(interval_msec);
00431         }
00432         last_timestamp_ = timestamp;
00433 
00434         // setUrgData() を呼び出すとデータは空になるので、
00435         // ここで LengthView 用のデータ格納を行う
00436         if (set_length_view_) {
00437             set_length_view_ = false;
00438 
00439             length_view_widget_.setLength(data);
00440             if (capture_mode == IntensityCapture) {
00441                 length_view_widget_.setIntensity(intensity_data);
00442             }
00443         }
00444 
00445         // 補助線の登録
00446         for (vector<int>::iterator it = draw_line_indexes_.begin();
00447              it != draw_line_indexes_.end(); ++it) {
00448             double radian = urg_.index2rad(*it) + (M_PI/2.0);
00449             int x = static_cast<int>(100 * 1000 * cos(radian));
00450             int y = static_cast<int>(100 * 1000 * sin(radian));
00451             draw_line_points_.push_back(Point<long>(x, y));
00452         }
00453         urg_draw_widget_.setDrawColor(Color(0.0, 1.0, 0.0, 1.0));
00454         urg_draw_widget_.setUrgData(draw_line_points_, timestamp);
00455 
00456         // 描画データの登録
00457         if (capture_mode == IntensityCapture) {
00458             urg_draw_widget_.setUrgIntensityData(intensity_data,
00459                                                  &urg_, timestamp);
00460         }
00461         urg_draw_widget_.setDrawColor(Color(0.2f, 0.2f, 1.0f, 0.6f));
00462         urg_draw_widget_.setUrgData(data, &urg_, timestamp);
00463 
00464         // 一定間隔での描画
00465         // !!! FPS を定義する
00466         // !!! 可能ならば、URG のタイムスタンプを利用する
00467         urg_draw_widget_.redraw();
00468 
00469         if (settings_->type != GD) {
00470             if ((settings_->remain_times > 0) &&
00471                 (urg_.remainCaptureTimes() == 0)) {
00472                 // 回数指定のデータ取得のときは、指定回数後に取得を終了する
00473                 capture_timer_.stop();
00474                 capture_setting_widget_.setApplyEnabled(true);
00475             }
00476         }
00477     }
00478 
00479 
00480     void setPlayConnection(void)
00481     {
00482         // 接続操作を disable にする
00483         serial_connection_widget_.setEnabled(false);
00484         ethernet_connection_widget_.setEnabled(false);
00485 
00486         // 接続処理
00487         QTimer::singleShot(1000, widget_, SLOT(autoPlay()));
00488     }
00489 
00490 
00491     void activateWidget(QWidget* widget, QAction* action)
00492     {
00493         widget->show();
00494         widget->raise();
00495         action->setChecked(true);
00496     }
00497 
00498 
00499     void useSerialConnection(bool checked)
00500     {
00501         // メニューのチェックボックスの変更
00502         widget_->action_serial_->setChecked(checked);
00503         widget_->action_ethernet_->setChecked(! checked);
00504 
00505         // 接続用 Widget の変更
00506         // ウィンドウが広がらないように、表示されている方を消してから追加する
00507         if (checked) {
00508             ethernet_connection_widget_.setEnabled(false);
00509             ethernet_connection_widget_.hide();
00510             serial_connection_widget_.show();
00511             serial_connection_widget_.setEnabled(true);
00512         } else {
00513             serial_connection_widget_.setEnabled(false);
00514             serial_connection_widget_.hide();
00515             ethernet_connection_widget_.show();
00516             ethernet_connection_widget_.setEnabled(true);
00517         }
00518     }
00519 };
00520 
00521 
00522 UrgViewerWindow::UrgViewerWindow(int argc, char *argv[])
00523     : pimpl(new pImpl(argc, argv, this))
00524 {
00525     setupUi(this);
00526     pimpl->initializeForm();
00527     pimpl->loadSettings();
00528 
00529     if (MonitorModeManager::object()->mode() == MonitorModeManager::Play) {
00530         // 接続操作を disable にして、接続を行っておく
00531         pimpl->setPlayConnection();
00532 
00533         // 取得範囲の設定ウィンドウは表示させない
00534         menu_Window_->setEnabled(false);
00535     }
00536 }
00537 
00538 
00539 UrgViewerWindow::~UrgViewerWindow(void)
00540 {
00541     pimpl->saveSettings();
00542 }
00543 
00544 
00545 void UrgViewerWindow::rescanPressed(void)
00546 {
00547     vector<string> devices;
00548     pimpl->com_finder_.find(devices);
00549 
00550     for (vector<string>::iterator it = devices.begin();
00551          it != devices.end(); ++it) {
00552         if (pimpl->urg_usb_.isUsbCom(it->c_str())) {
00553             *it = *it + " [URG]";
00554         }
00555     }
00556     pimpl->serial_connection_widget_.setDevices(devices);
00557     if (! devices.empty()) {
00558         pimpl->serial_connection_widget_.setFocus();
00559     }
00560 }
00561 
00562 
00563 void UrgViewerWindow::connectPressed(bool connection,
00564                                      const string& device)
00565 {
00566     LockGuard guard(pimpl->urg_mutex_);
00567 
00568     if (connection) {
00569         // URG との接続
00570         pimpl->connect_thread_.setConnectSettings(device, 115200);
00571         pimpl->connect_thread_.start();
00572 
00573         vector<string> tokens;
00574         size_t n = split(tokens, device, "/");
00575         if (n > 0) {
00576             string base_name = tokens[n - 1] + "_error_log.txt";
00577             log_setName(base_name.c_str());
00578         }
00579 
00580     } else {
00581         // 切断
00582         pimpl->disconnectDevice();
00583         pimpl->urg_.disconnect();
00584     }
00585 }
00586 
00587 
00588 void UrgViewerWindow::connectPressed(bool connection,
00589                                      const std::string& address,
00590                                      unsigned short port)
00591 {
00592     LockGuard guard(pimpl->urg_mutex_);
00593 
00594     if (connection) {
00595         // URG との接続
00596         pimpl->connect_thread_.setConnectSettings(address, port);
00597         pimpl->connect_thread_.start();
00598 
00599     } else {
00600         // 切断
00601         pimpl->disconnectDevice();
00602         pimpl->urg_.disconnect();
00603     }
00604 }
00605 
00606 
00607 void UrgViewerWindow::connectDevice(bool connection)
00608 {
00609     pimpl->connectDevice(connection);
00610 }
00611 
00612 
00613 void UrgViewerWindow::captureHandler(void)
00614 {
00615     pimpl->captureHandler();
00616 }
00617 
00618 
00619 void UrgViewerWindow::initializeView(void)
00620 {
00621     pimpl->urg_draw_widget_.initializeView();
00622 }
00623 
00624 
00625 void UrgViewerWindow::updateStatusBar(bool active, long x_mm, long y_mm)
00626 {
00627     if (! active) {
00628         statusBar()->clearMessage();
00629         return;
00630     }
00631 
00632     QString message = QString("X: %1 [mm], Y: %2 [mm]").arg(x_mm).arg(y_mm);
00633     statusBar()->showMessage(message, 60 * 1000);
00634 }
00635 
00636 
00637 void UrgViewerWindow::updateScansInterval(int msec)
00638 {
00639     scans_label_->setText(QString(tr("%1 [msec] (scans interval)")).arg(msec));
00640 }
00641 
00642 
00643 void UrgViewerWindow::aboutApplication(void)
00644 {
00645     QString message =
00646         "<h2>URG Viewer " + QString(Version) + "</h2>"
00647         "<p>Demo Application for URG sensor</p>"
00648         "<p>Report bugs to &lt;satofumi@users.sourceforge.jp&gt;</p>";
00649 
00650     QMessageBox::about(this, tr("About URG Viewer"), message);
00651 }
00652 
00653 
00654 void UrgViewerWindow::autoPlay(void)
00655 {
00656     pimpl->connect_thread_.start();
00657 }
00658 
00659 
00660 void UrgViewerWindow::zoomSmaller(void)
00661 {
00662     pimpl->urg_draw_widget_.updateZoomRatio(+1);
00663 }
00664 
00665 
00666 void UrgViewerWindow::zoomLarger(void)
00667 {
00668     pimpl->urg_draw_widget_.updateZoomRatio(-1);
00669 }
00670 
00671 
00672 void UrgViewerWindow::closeEvent(QCloseEvent* event)
00673 {
00674     pimpl->capture_setting_widget_.hide();
00675     pimpl->length_view_widget_.hide();
00676 
00677     pimpl->capture_timer_.stop();
00678 
00679     LockGuard guard(pimpl->urg_mutex_);
00680     pimpl->urg_.disconnect();
00681     pimpl->connect_thread_.terminate();
00682     pimpl->connect_thread_.wait(100);
00683 
00684     event->accept();
00685 
00686     // デストラクタ内で呼び出したいが、
00687     // exit() を呼ぶとデストラクタが呼び出されないのでここで呼び出す
00688     pimpl->saveSettings();
00689 
00690     exit(0);
00691 }
00692 
00693 
00694 void UrgViewerWindow::showCaptureSettingWidget(void)
00695 {
00696     pimpl->activateWidget(&pimpl->capture_setting_widget_,
00697                           action_capture_setting_);
00698 }
00699 
00700 
00701 void UrgViewerWindow::receiveCaptureSettings(const CaptureSettings& settings)
00702 {
00703     if (! pimpl->settings_) {
00704         int dummy = -1;
00705         pimpl->settings_ = pimpl->initializeCaptureSettings(dummy, dummy);
00706     }
00707     *pimpl->settings_ = settings;
00708 }
00709 
00710 
00711 void UrgViewerWindow::receiveReconnectRequest(void)
00712 {
00713     pimpl->receiveReconnectRequest();
00714     emit reconnectCompleted();
00715 }
00716 
00717 
00718 void UrgViewerWindow::showLengthViewWidget(void)
00719 {
00720     pimpl->activateWidget(&pimpl->length_view_widget_,
00721                           action_length_view_);
00722 }
00723 
00724 
00725 void UrgViewerWindow::receiveLengthViewRequest(void)
00726 {
00727     pimpl->set_length_view_ = true;
00728 }
00729 
00730 
00731 void UrgViewerWindow::receiveWidgetClose(const string& widget_name)
00732 {
00733     if (! widget_name.compare("CaptureSettingWidget")) {
00734         action_capture_setting_->setChecked(false);
00735 
00736     } else if (! widget_name.compare("LengthViewWidget")) {
00737         action_length_view_->setChecked(false);
00738     }
00739 }
00740 
00741 
00742 void UrgViewerWindow::receiveDrawLine(const vector<int>& indexes)
00743 {
00744     pimpl->draw_line_indexes_ = indexes;
00745 }
00746 
00747 
00748 void UrgViewerWindow::selectSerial(void)
00749 {
00750     pimpl->useSerialConnection(true);
00751 
00752     // Serial 用の Connection を登録
00753     if (pimpl->serial_connection_) {
00754         pimpl->urg_.setConnection(pimpl->serial_connection_);
00755     }
00756 }
00757 
00758 
00759 void UrgViewerWindow::selectEthernet(void)
00760 {
00761     pimpl->useSerialConnection(false);
00762 
00763     // Ethernet 用の Connection を登録
00764     pimpl->urg_.setConnection(&pimpl->ethernet_connection_);
00765 }