• R/O
  • SSH
  • HTTPS

qrobosdk: コミット


コミットメタ情報

リビジョン235 (tree)
日時2008-09-26 21:47:48
作者satofumi

ログメッセージ

adjut WiiBlade

変更サマリ

差分

--- trunk/libs/controller/WiiJoystick_lin.cpp (revision 234)
+++ trunk/libs/controller/WiiJoystick_lin.cpp (revision 235)
@@ -414,12 +414,12 @@
414414 setRepeatMode();
415415
416416 // コールバックを登録
417+ callback_->registerObject(wii_);
417418 if (cwiid_set_mesg_callback(wii_, &CallbackHandler::callback)) {
418419 disconnect();
419420 error_message_ = "error setting callback";
420421 return false;
421422 }
422- callback_->registerObject(wii_);
423423
424424 // キャリブレーション値の取得
425425 if (cwiid_get_acc_cal(wii_, CWIID_EXT_NONE, &calibration_)) {
--- trunk/libs/system/sdl/StopWatch.cpp (revision 234)
+++ trunk/libs/system/sdl/StopWatch.cpp (nonexistent)
@@ -1,122 +0,0 @@
1-/*!
2- \file
3- \brief 一時停止可能なタイマー
4-
5- \author Satofumi KAMIMURA
6-
7- $Id$
8-*/
9-
10-#include "StopWatch.h"
11-#include "getTicks.h"
12-
13-using namespace qrk;
14-
15-
16-struct StopWatch::pImpl
17-{
18- enum {
19- InvalidTicks = -1,
20- };
21-
22- int start_ticks_;
23- int pause_ticks_;
24-
25-
26- pImpl(void)
27- {
28- initialize();
29- }
30-
31-
32- void initialize(void)
33- {
34- start_ticks_ = InvalidTicks;
35- pause_ticks_ = InvalidTicks;
36- }
37-};
38-
39-
40-StopWatch::StopWatch(void) : pimpl(new pImpl)
41-{
42-}
43-
44-
45-StopWatch::~StopWatch(void)
46-{
47-}
48-
49-
50-void StopWatch::start(void)
51-{
52- if (pimpl->pause_ticks_ != pImpl::InvalidTicks) {
53- // 一時停止の場合、再開させる
54- resume();
55- return;
56-
57- } else if (pimpl->start_ticks_ != pImpl::InvalidTicks) {
58- // 再生中の場合は、戻る
59- return;
60-
61- } else {
62- // 停止中の場合は、開始する
63- pimpl->start_ticks_ = qrk::getTicks();
64- }
65-}
66-
67-
68-void StopWatch::stop(void)
69-{
70- pimpl->initialize();
71-}
72-
73-
74-void StopWatch::pause(void)
75-{
76- if ((pimpl->pause_ticks_ != pImpl::InvalidTicks) ||
77- (pimpl->start_ticks_ == pImpl::InvalidTicks)) {
78- // 一時停止、停止の場合、戻る
79- return;
80- }
81-
82- pimpl->pause_ticks_ = qrk::getTicks();
83-}
84-
85-
86-void StopWatch::resume(void)
87-{
88- // 一時停止でなければ、戻る
89- if (pimpl->pause_ticks_ == pImpl::InvalidTicks) {
90- return;
91- }
92-
93- int paused_msec = qrk::getTicks() - pimpl->pause_ticks_;
94- pimpl->start_ticks_ += paused_msec;
95- pimpl->pause_ticks_ = pImpl::InvalidTicks;
96-}
97-
98-
99-int StopWatch::getTicks(void)
100-{
101- if (pimpl->start_ticks_ == pImpl::InvalidTicks) {
102- // 停止
103- return 0;
104-
105- } else if (pimpl->pause_ticks_ != pImpl::InvalidTicks) {
106- // 一時停止
107- int now_ticks = qrk::getTicks();
108-
109- return ((now_ticks - pimpl->start_ticks_)
110- - (now_ticks - pimpl->pause_ticks_));
111-
112- } else {
113- // 再生
114- return qrk::getTicks() - pimpl->start_ticks_;
115- }
116-}
117-
118-
119-bool StopWatch::isPause(void)
120-{
121- return (pimpl->pause_ticks_ != pImpl::InvalidTicks) ? true : false;
122-}
Deleted: svn:keywords
## -1 +0,0 ##
-Id Date Author Rev URL
\ No newline at end of property
--- trunk/libs/system/sdl/Makefile (revision 234)
+++ trunk/libs/system/sdl/Makefile (revision 235)
@@ -29,7 +29,6 @@
2929 ${SYSTEM_SDL}(Thread.o) \
3030 ${SYSTEM_SDL}(Lock.o) \
3131 ${SYSTEM_SDL}(Semaphore.o) \
32- ${SYSTEM_SDL}(StopWatch.o) \
3332
3433 # DO NOT DELETE
3534
@@ -36,7 +35,6 @@
3635 Lock.o: ../Lock.h ../ConditionVariable.h SdlInit.h
3736 SdlInit.o: SdlInit.h
3837 Semaphore.o: ../Semaphore.h
39-StopWatch.o: ../StopWatch.h ../getTicks.h
4038 Thread.o: ../Thread.h SdlInit.h ../Lock.h ../ConditionVariable.h
4139 Thread.o: ../LockGuard.h
4240 delay.o: ../delay.h SdlInit.h
--- trunk/libs/system/StopWatch.cpp (nonexistent)
+++ trunk/libs/system/StopWatch.cpp (revision 235)
@@ -0,0 +1,122 @@
1+/*!
2+ \file
3+ \brief 一時停止可能なタイマー
4+
5+ \author Satofumi KAMIMURA
6+
7+ $Id$
8+*/
9+
10+#include "StopWatch.h"
11+#include "getTicks.h"
12+
13+using namespace qrk;
14+
15+
16+struct StopWatch::pImpl
17+{
18+ enum {
19+ InvalidTicks = -1,
20+ };
21+
22+ int start_ticks_;
23+ int pause_ticks_;
24+
25+
26+ pImpl(void)
27+ {
28+ initialize();
29+ }
30+
31+
32+ void initialize(void)
33+ {
34+ start_ticks_ = InvalidTicks;
35+ pause_ticks_ = InvalidTicks;
36+ }
37+};
38+
39+
40+StopWatch::StopWatch(void) : pimpl(new pImpl)
41+{
42+}
43+
44+
45+StopWatch::~StopWatch(void)
46+{
47+}
48+
49+
50+void StopWatch::start(void)
51+{
52+ if (pimpl->pause_ticks_ != pImpl::InvalidTicks) {
53+ // 一時停止の場合、再開させる
54+ resume();
55+ return;
56+
57+ } else if (pimpl->start_ticks_ != pImpl::InvalidTicks) {
58+ // 再生中の場合は、戻る
59+ return;
60+
61+ } else {
62+ // 停止中の場合は、開始する
63+ pimpl->start_ticks_ = qrk::getTicks();
64+ }
65+}
66+
67+
68+void StopWatch::stop(void)
69+{
70+ pimpl->initialize();
71+}
72+
73+
74+void StopWatch::pause(void)
75+{
76+ if ((pimpl->pause_ticks_ != pImpl::InvalidTicks) ||
77+ (pimpl->start_ticks_ == pImpl::InvalidTicks)) {
78+ // 一時停止、停止の場合、戻る
79+ return;
80+ }
81+
82+ pimpl->pause_ticks_ = qrk::getTicks();
83+}
84+
85+
86+void StopWatch::resume(void)
87+{
88+ // 一時停止でなければ、戻る
89+ if (pimpl->pause_ticks_ == pImpl::InvalidTicks) {
90+ return;
91+ }
92+
93+ int paused_msec = qrk::getTicks() - pimpl->pause_ticks_;
94+ pimpl->start_ticks_ += paused_msec;
95+ pimpl->pause_ticks_ = pImpl::InvalidTicks;
96+}
97+
98+
99+int StopWatch::getTicks(void)
100+{
101+ if (pimpl->start_ticks_ == pImpl::InvalidTicks) {
102+ // 停止
103+ return 0;
104+
105+ } else if (pimpl->pause_ticks_ != pImpl::InvalidTicks) {
106+ // 一時停止
107+ int now_ticks = qrk::getTicks();
108+
109+ return ((now_ticks - pimpl->start_ticks_)
110+ - (now_ticks - pimpl->pause_ticks_));
111+
112+ } else {
113+ // 再生
114+ return qrk::getTicks() - pimpl->start_ticks_;
115+ }
116+}
117+
118+
119+bool StopWatch::isPause(void)
120+{
121+ return (pimpl->pause_ticks_ != pImpl::InvalidTicks) ? true : false;
122+}
Added: svn:keywords
## -0,0 +1 ##
+Id Date Author Rev URL
\ No newline at end of property
--- trunk/libs/system/Makefile (revision 234)
+++ trunk/libs/system/Makefile (revision 235)
@@ -28,7 +28,8 @@
2828
2929 ${SYSTEM_LIB} : \
3030 ${SYSTEM_LIB}(LockGuard.o) \
31- ${SYSTEM_LIB}(logPrintf.o)
31+ ${SYSTEM_LIB}(logPrintf.o) \
32+ ${SYSTEM_LIB}(StopWatch.o)
3233
3334 # DO NOT DELETE
3435
@@ -35,4 +36,5 @@
3536 Lock.o: ConditionVariable.h
3637 MathUtils.o: DetectOS.h
3738 LockGuard.o: LockGuard.h Lock.h ConditionVariable.h
39+StopWatch.o: StopWatch.h getTicks.h
3840 logPrintf.o: logPrintf.h
--- trunk/libs/range_sensor/UrgCtrl.cpp (revision 234)
+++ trunk/libs/range_sensor/UrgCtrl.cpp (revision 235)
@@ -331,12 +331,10 @@
331331
332332 // 受信待ち
333333 ScanData data;
334- fprintf(stderr, "in thread.\n");
335334 while (1) {
336335 // 受信完了、およびエラーで抜ける
337336 CaptureType type = obj->scip_.receiveCaptureData(data.length_data,
338337 &data.timestamp);
339- fprintf(stderr, "type: %d\n", type);
340338
341339 if (type == Mx_Reply) {
342340 // MS/MD の応答パケットの場合、次のデータを待つ
@@ -443,12 +441,11 @@
443441 }
444442
445443 // QT コマンドの発行
446- fprintf(stderr, "setLaserOutput()\n");
447444 scip_.setLaserOutput(ScipHandler::Off);
448445
449446 // 応答を待つ
450447 if (thread_.isRunning()) {
451- fprintf(stderr, "wait()\n");
448+ // !!! monitor の playback が、ここの wait で停止してしまう
452449 thread_.wait();
453450 }
454451 }
--- trunk/libs/range_sensor/samples/mdCaptureSample.cpp (revision 234)
+++ trunk/libs/range_sensor/samples/mdCaptureSample.cpp (revision 235)
@@ -9,6 +9,7 @@
99
1010 #include "mUrgCtrl.h"
1111 #include "delay.h"
12+#include "getTicks.h"
1213
1314 using namespace qrk;
1415
@@ -29,18 +30,19 @@
2930
3031 // MD コマンドで連続データ取得を行い、指定回数だけ出力する
3132 enum { CaptureTimes = 3 };
32- for (int i = 0; i < CaptureTimes; ++i) {
33+ getTicks();
34+ for (int i = 0; i < CaptureTimes;) {
3335 int timestamp = -1;
3436 std::vector<long> data;
3537
3638 int n = urg.capture(data, &timestamp);
37- fprintf(stderr, "n = %d\n", n);
39+ //fprintf(stderr, "n = %d, (%d)\n", n, getTicks());
3840 if (n <= 0) {
3941 delay(scan_msec);
4042 continue;
4143 }
4244
43- printf("timestamp: %d\n", timestamp);
45+ printf("timestamp: %d, (%d)\n", timestamp, getTicks());
4446 #if 0
4547 for (int j = 0; j < n; ++j) {
4648 printf("%d:%ld, ", j, data[j]);
@@ -47,8 +49,7 @@
4749 }
4850 printf("\n");
4951 #endif
52+ ++i;
5053 }
51-
52- fprintf(stderr, "end.\n");
5354 return 0;
5455 }
--- trunk/libs/range_sensor/ScipHandler.cpp (revision 234)
+++ trunk/libs/range_sensor/ScipHandler.cpp (revision 235)
@@ -38,12 +38,14 @@
3838 std::string error_message_;
3939 Connection* con_;
4040 LaserState laser_state_;
41+ bool mx_capturing_;
4142
4243 std::vector<long> intensity_data_;
4344
4445
4546 pImpl(void)
46- : error_message_("no error."), con_(NULL), laser_state_(LaserUnknown)
47+ : error_message_("no error."), con_(NULL), laser_state_(LaserUnknown),
48+ mx_capturing_(false)
4749 {
4850 }
4951
@@ -276,7 +278,6 @@
276278
277279 bool setLaserOutput(bool on, bool force)
278280 {
279- fprintf(stderr, "laser: %d, %d\n", on, laser_state_);
280281 if (((on == true) && (laser_state_ == LaserOn)) ||
281282 ((on == false) && (laser_state_ == LaserOff))) {
282283 if (! force) {
@@ -297,16 +298,20 @@
297298
298299 } else {
299300 // "QT"
300- int return_code = -1;
301- char qt_expected_response[] = { 0, -1 };
302- response(return_code, "QT\r", qt_expected_response);
301+ con_->send("QT\r", 3);
303302
304- // !!! MD/GD 中の QT のコマンドの場合は応答が帰ってこないので、
305- // !!! 応答を待つべきでない
306- // !!! レーザ発行中の QT 処理は、区別できるようにしておくべき
303+ if (! mx_capturing_) {
304+ // BM を打ち消すための QT では、応答を待つべき
305+ int return_code = -1;
306+ char qt_expected_response[] = { 0, -1 };
307+ return response(return_code, "QT\r", qt_expected_response);
307308
308- // !!! または、1文字応答を読み出してから書き戻す
309- return false;
309+ } else {
310+ // MD を中断するための QT では、応答を待ってはならない
311+ // 応答は、受信スレッド内で処理される
312+ }
313+
314+ return true;
310315 }
311316 }
312317
@@ -327,7 +332,7 @@
327332 CaptureType type = TypeUnknown;
328333 int timeout = FirstTimeout;
329334 while (readline(con_, buffer, BufferSize, timeout) > 0) {
330- fprintf(stderr, "% 3d: %s\n", line_count, buffer);
335+ //fprintf(stderr, "% 3d: %s\n", line_count, buffer);
331336 // !!! チェックサムの確認
332337
333338 if (line_count == 0) {
@@ -341,6 +346,7 @@
341346 break;
342347 }
343348 type = (line[1] = 'D') ? GD : GS;
349+ data.resize(settings.capture_last + 1);
344350
345351 } else if ((! line.compare(0, 2, "MD")) ||
346352 (! line.compare(0, 2, "MS"))) {
@@ -349,6 +355,7 @@
349355 }
350356 type = (line[1] = 'D') ? MD : MS;
351357 laser_state_ = LaserOn;
358+ data.resize(settings.capture_last + 1);
352359
353360 } else if (! line.compare(0, 2, "ME")) {
354361 if (! parseMeEchoback(settings, line)) {
@@ -356,6 +363,7 @@
356363 }
357364 type = ME;
358365 laser_state_ = LaserOn;
366+ data.resize(settings.capture_last + 1);
359367 }
360368
361369 } else if (line_count == 1) {
@@ -422,7 +430,12 @@
422430 }
423431
424432 // !!! 残り回数がゼロのときは、レーザを消灯扱いにする
433+ // laser_state_ = LaserOff;
434+ // mx_capturing_ = false;
425435
436+ // !!! それ以外は、レーザは点灯中
437+ mx_capturing_ = true;
438+
426439 settings.capture_first = substr2int(line, 2, 4);
427440 settings.capture_last = substr2int(line, 6, 4);
428441 settings.skip_lines = substr2int(line, 10, 2);
--- trunk/libs/monitor/mUrgCtrl.cpp (revision 234)
+++ trunk/libs/monitor/mUrgCtrl.cpp (revision 235)
@@ -49,7 +49,6 @@
4949 {
5050 urg_.stop();
5151
52- fprintf(stderr, "delete monitor's connection\n");
5352 if (monitor_con_) {
5453 delete monitor_con_;
5554 }
--- trunk/programs/WiiBlade/SwingImageWidget.cpp (revision 234)
+++ trunk/programs/WiiBlade/SwingImageWidget.cpp (revision 235)
@@ -16,6 +16,11 @@
1616
1717 struct SwingImageWidget::pImpl
1818 {
19+ enum {
20+ MinimumWidth = 100,
21+ MinimumHeight = 100,
22+ };
23+
1924 SwingImageWidget* parent_;
2025 QColor clear_color_;
2126 Angle blade_angle_;
@@ -26,9 +31,10 @@
2631 }
2732
2833
29- void initialize(void)
34+ void initializeForm(void)
3035 {
3136 parent_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
37+ parent_->setMinimumSize(MinimumWidth, MinimumHeight);
3238 }
3339
3440
@@ -66,7 +72,8 @@
6672 glLoadIdentity();
6773
6874 // データの描画
69- glBegin(GL_LINE_STRIP);
75+ glColor3d(0.0, 1.0, 0.0);
76+ glBegin(GL_LINES);
7077 double radian = blade_angle_.to_rad();
7178 double x = 1000 * cos(radian);
7279 double y = 1000 * sin(radian);
@@ -80,7 +87,7 @@
8087 SwingImageWidget::SwingImageWidget(QGLWidget* parent)
8188 : QGLWidget(parent), pimpl(new pImpl(this))
8289 {
83- pimpl->initialize();
90+ pimpl->initializeForm();
8491 }
8592
8693
--- trunk/programs/WiiBlade/WiiBladeWindow.cpp (revision 234)
+++ trunk/programs/WiiBlade/WiiBladeWindow.cpp (revision 235)
@@ -5,6 +5,8 @@
55 \author Satofumi KAMIMURA
66
77 $Id$
8+
9+ \todo 記録中もスライドバーを移動させるか、を検討する
810 */
911
1012 #include "WiiBladeWindow.h"
@@ -12,10 +14,14 @@
1214 #include "TimeGraphWidget.h"
1315 #include "XyGraphWidget.h"
1416 #include "WiiJoystick.h"
17+#include "StopWatch.h"
1518 #include "getTicks.h"
1619 #include "AngleTypes.h"
1720 #include "MathUtils.h"
21+#include "split.h"
22+#include <QSettings>
1823 #include <QTimer>
24+#include <QShortcut>
1925 #include <QMessageBox>
2026 extern "C"
2127 {
@@ -30,7 +36,19 @@
3036 using namespace qrk;
3137 using namespace boost;
3238
39+namespace
40+{
41+ const char* Organization = "Hyakuren Soft";
42+ const char* Application = "Wii Blade";
3343
44+ const char* RecordFile = "acceleration.txt";
45+
46+ enum {
47+ RedrawInterval = 100, // [msec]
48+ };
49+};
50+
51+
3452 struct WiiBladeWindow::pImpl
3553 {
3654 enum {
@@ -45,12 +63,25 @@
4563 WiiJoystick wii_;
4664
4765 QTimer capture_timer_;
48- std::ofstream fout_;
66+ QTimer play_timer_;
67+ StopWatch play_stop_watch_;
68+ int play_first_ticks_;
69+ std::ofstream* record_fout_;
70+ std::ifstream* play_fin_;
71+ std::string last_read_line_;
72+ bool now_playing_;
73+ bool repeat_mode_;
74+ size_t ticks_max_;
75+ int pre_draw_ticks_;
4976
5077 lua_State* lua_;
5178
5279
53- pImpl(WiiBladeWindow* parent) : parent_(parent), lua_(lua_open())
80+ pImpl(WiiBladeWindow* parent)
81+ : parent_(parent), play_first_ticks_(0),
82+ record_fout_(NULL), play_fin_(NULL),
83+ now_playing_(false), repeat_mode_(false), ticks_max_(0),
84+ pre_draw_ticks_(0), lua_(lua_open())
5485 {
5586 luaL_openlibs(lua_);
5687 luabind::open(lua_);
@@ -58,7 +89,8 @@
5889 luabind::module(lua_) [
5990 luabind::def("sin", &sin),
6091 luabind::def("cos", &cos),
61- luabind::def("atan2", &atan2)
92+ luabind::def("atan2", &atan2),
93+ luabind::def("sqrt", &sqrt)
6294 ];
6395 }
6496
@@ -66,9 +98,29 @@
6698 ~pImpl(void)
6799 {
68100 lua_close(lua_);
101+
102+ delete record_fout_;
103+ delete play_fin_;
69104 }
70105
71106
107+ void saveSettings(void)
108+ {
109+ QSettings settings(Organization, Application);
110+
111+ settings.setValue("repeat_mode", parent_->repeat_button_->isChecked());
112+ }
113+
114+
115+ void loadSettings(void)
116+ {
117+ QSettings settings(Organization, Application);
118+
119+ repeat_mode_ = settings.value("repeat_mode", true).toBool();
120+ parent_->repeat_button_->setChecked(repeat_mode_);
121+ }
122+
123+
72124 void initializeForm(void)
73125 {
74126 // ウィジット
@@ -94,10 +146,19 @@
94146 parent_, SLOT(connectPressed()));
95147 connect(parent_->disconnect_button_, SIGNAL(clicked()),
96148 parent_, SLOT(disconnectPressed()));
149+ connect(parent_->play_button_, SIGNAL(clicked()),
150+ parent_, SLOT(playPressed()));
151+ connect(parent_->repeat_button_, SIGNAL(clicked(bool)),
152+ parent_, SLOT(repeatPressed(bool)));
97153
98154 // データ取得
99155 connect(&capture_timer_, SIGNAL(timeout()),
100156 parent_, SLOT(recordData()));
157+ connect(&play_timer_, SIGNAL(timeout()),
158+ parent_, SLOT(updatePlayData()));
159+
160+ // キーバインド
161+ (void) new QShortcut(Qt::Key_Space, parent_, SLOT(playPressed()));
101162 }
102163
103164
@@ -104,6 +165,9 @@
104165 void rescanPressed(void)
105166 {
106167 // !!!
168+ // !!! Windows ならば、WiimoteRescanner を実行する
169+
170+ // !!! Linux ならば、"hciconfig hci0 up" を実行する。(要、管理者権限)
107171 }
108172
109173
@@ -120,12 +184,10 @@
120184 }
121185
122186 // データ取得の開始
123- fout_.open("acceleration.txt");
124- if (! fout_.is_open()) {
125- return;
126- }
187+ setConnectEnabled(false);
188+ delete record_fout_;
189+ record_fout_ = new std::ofstream(RecordFile);
127190
128- setConnectEnabled(false);
129191 startPlay();
130192 capture_timer_.start(pImpl::CaptureInterval);
131193 }
@@ -133,8 +195,8 @@
133195
134196 void disconnectPressed(void)
135197 {
198+ stopPlay();
136199 capture_timer_.stop();
137- fout_.close();
138200 wii_.disconnect();
139201 setConnectEnabled(true);
140202 }
@@ -146,10 +208,16 @@
146208 parent_->rescan_button_->setEnabled(! enable);
147209 parent_->disconnect_button_->setEnabled(! enable);
148210
149- parent_->acceleration_group_->setEnabled(! enable);
211+ setDataEnabled(! enable);
150212 }
151213
152214
215+ void setDataEnabled(bool enable)
216+ {
217+ parent_->acceleration_group_->setEnabled(enable);
218+ }
219+
220+
153221 void recordData(void)
154222 {
155223 Grid3D<double> acc;
@@ -156,28 +224,23 @@
156224 wii_.getAcceleration(acc);
157225 int timestamp = getTicks();
158226
159- fout_ << timestamp
160- << '\t' << acc.x << '\t' << acc.y << '\t' << acc.z << std::endl;
227+ *record_fout_ << timestamp
228+ << '\t' << acc.x << '\t' << acc.y << '\t' << acc.z
229+ << std::endl;
161230
162- updateAccelerationValue(acc);
163- // !!! 各グラフの表示を更新
164-
165- int blade_degree =
166- luabind::call_function<int>(lua_, "calculateAngle",
167- timestamp, acc.x, acc.y, acc.z);
168- swing_image_.setBladeAngle(deg(blade_degree));
231+ setNewAccelerationData(acc, timestamp);
169232 }
170233
171234
172235 void updateAccelerationValue(const Grid3D<double>& acc)
173236 {
174- parent_->x_acc_label_->setText(doubleString(acc.x).c_str());
175- parent_->y_acc_label_->setText(doubleString(acc.y).c_str());
176- parent_->z_acc_label_->setText(doubleString(acc.z).c_str());
237+ parent_->x_acc_label_->setText(doubleToString(acc.x).c_str());
238+ parent_->y_acc_label_->setText(doubleToString(acc.y).c_str());
239+ parent_->z_acc_label_->setText(doubleToString(acc.z).c_str());
177240 }
178241
179242
180- std::string doubleString(double value)
243+ std::string doubleToString(double value)
181244 {
182245 char buffer[] = "-0.0000";
183246 snprintf(buffer, sizeof(buffer), "%.02f", value);
@@ -188,10 +251,203 @@
188251
189252 void startPlay(void)
190253 {
191- // !!! 記録時、再生時の両方で呼ばれる、とする
254+ luaL_dofile(lua_, "calculateAngle.lua");
192255
193- luaL_dofile(lua_, "calculateAngle.lua");
256+ setDataEnabled(true);
194257 }
258+
259+
260+ void stopPlay(void)
261+ {
262+ play_timer_.stop();
263+
264+ if (capture_timer_.isActive()) {
265+ // 記録時間の退避
266+ ticks_max_ = play_stop_watch_.getTicks();
267+ }
268+ play_stop_watch_.stop();
269+
270+ now_playing_ = false;
271+ setPlayingIcon(false);
272+ updatePlayEnable();
273+ setDataEnabled(false);
274+ }
275+
276+
277+ void pausePlay(void)
278+ {
279+ play_stop_watch_.pause();
280+ }
281+
282+
283+ void resumePlay(void)
284+ {
285+ play_stop_watch_.resume();
286+ }
287+
288+
289+ void updatePlayData(void)
290+ {
291+ if (last_read_line_.empty()) {
292+ if (! getline(*play_fin_, last_read_line_)) {
293+ last_read_line_.clear();
294+ }
295+ }
296+
297+ // 取得データのパース
298+ std::vector<std::string> tokens;
299+ if (split(tokens, last_read_line_, "\t") != 4) {
300+ // 異常なデータに遭遇したら、再生を中断する
301+ stopPlay();
302+
303+ if (repeat_mode_) {
304+ // 繰り返し再生する
305+ parent_->playPressed();
306+ }
307+ return;
308+ }
309+ int target_ticks = atoi(tokens[0].c_str());
310+
311+ // 再生タイミングを経過していたら出力を更新する
312+ int current_ticks = play_stop_watch_.getTicks();
313+ if (current_ticks > target_ticks) {
314+ last_read_line_.clear();
315+
316+ Grid3D<double> acc(atof(tokens[1].c_str()),
317+ atof(tokens[2].c_str()),
318+ atof(tokens[3].c_str()));
319+
320+ setNewAccelerationData(acc, target_ticks);
321+ }
322+ }
323+
324+
325+ void setNewAccelerationData(const Grid3D<double>& acc, int timestamp)
326+ {
327+ updateAccelerationValue(acc);
328+
329+ // X-Y グラフの更新
330+ xy_graph_.setData(timestamp, acc.x, acc.y);
331+
332+ // Time グラフの更新
333+ // !!!
334+
335+ // スライダ位置の更新
336+ if (now_playing_) {
337+ int percent = static_cast<int>(100.0 * timestamp / ticks_max_);
338+ parent_->progress_slider_->setValue(percent);
339+ } else {
340+ // !!!
341+ }
342+
343+ if ((timestamp - pre_draw_ticks_) > RedrawInterval) {
344+ pre_draw_ticks_ = timestamp;
345+
346+ xy_graph_.redraw();
347+
348+ int blade_degree =
349+ luabind::call_function<int>(lua_, "calculateAngle",
350+ timestamp, acc.x, acc.y, acc.z);
351+ swing_image_.setBladeAngle(deg(blade_degree));
352+ }
353+ }
354+
355+
356+ bool openRecordFile(void)
357+ {
358+ if (play_fin_ && (play_fin_->is_open() && (! play_fin_->eof()))) {
359+ // 既に開いている場合は、処理を戻す
360+ return true;
361+ }
362+
363+ // 新規に開く
364+ delete play_fin_;
365+ play_fin_ = new std::ifstream(RecordFile);
366+ if (! play_fin_->is_open()) {
367+ return false;
368+ }
369+
370+ // 再生時間の取得
371+ if (ticks_max_ == 0) {
372+ size_t ticks_max = 0;
373+ std::string line;
374+ while (getline(*play_fin_, line)) {
375+ size_t ticks = atoi(line.c_str());
376+ if (ticks > ticks_max) {
377+ ticks_max = ticks;
378+ }
379+ }
380+ if (ticks_max > 0) {
381+ ticks_max_ = ticks_max;
382+
383+ // play_fin_ が無効になっているため、再度ファイルを開く
384+ return openRecordFile();
385+ }
386+ }
387+
388+ return true;
389+ }
390+
391+
392+ void setPlayEnabled(bool enable)
393+ {
394+ parent_->play_button_->setEnabled(enable);
395+ parent_->repeat_button_->setEnabled(enable);
396+ parent_->progress_slider_->setEnabled(enable);
397+ }
398+
399+
400+ void updatePlayEnable(void)
401+ {
402+ bool play_enable = openRecordFile();
403+ setPlayEnabled(play_enable);
404+ }
405+
406+
407+ void setPlayingIcon(bool playing)
408+ {
409+ if (playing) {
410+ parent_->play_button_->setIcon(QPixmap(":/icons/pause_icon"));
411+ } else {
412+ parent_->play_button_->setIcon(QPixmap(":/icons/play_icon"));
413+ }
414+ }
415+
416+
417+ void startPlayTimer(void)
418+ {
419+ play_stop_watch_.start();
420+ play_timer_.start(10);
421+ }
422+
423+
424+ void playPressed(void)
425+ {
426+ if (! now_playing_) {
427+ if (play_stop_watch_.isPause()) {
428+ // 一時停止の処理を再開
429+ resumePlay();
430+
431+ } else {
432+ // 再生開始
433+ startPlay();
434+ startPlayTimer();
435+ }
436+
437+ } else {
438+ // 一時停止
439+ pausePlay();
440+ }
441+
442+ now_playing_ = ! now_playing_;
443+ setPlayingIcon(now_playing_);
444+ }
445+
446+
447+ void repeatPressed(bool checked)
448+ {
449+ repeat_mode_ = checked;
450+ }
195451 };
196452
197453
@@ -199,11 +455,14 @@
199455 {
200456 setupUi(this);
201457 pimpl->initializeForm();
458+ pimpl->loadSettings();
459+ pimpl->updatePlayEnable();
202460 }
203461
204462
205463 WiiBladeWindow::~WiiBladeWindow(void)
206464 {
465+ pimpl->saveSettings();
207466 }
208467
209468
@@ -239,3 +498,21 @@
239498 {
240499 pimpl->recordData();
241500 }
501+
502+
503+void WiiBladeWindow::playPressed(void)
504+{
505+ pimpl->playPressed();
506+}
507+
508+
509+void WiiBladeWindow::repeatPressed(bool checked)
510+{
511+ pimpl->repeatPressed(checked);
512+}
513+
514+
515+void WiiBladeWindow::updatePlayData(void)
516+{
517+ pimpl->updatePlayData();
518+}
--- trunk/programs/WiiBlade/WiiBladeWindow.h (revision 234)
+++ trunk/programs/WiiBlade/WiiBladeWindow.h (revision 235)
@@ -29,6 +29,9 @@
2929 void connectPressed(void);
3030 void disconnectPressed(void);
3131 void recordData(void);
32+ void playPressed(void);
33+ void repeatPressed(bool checked);
34+ void updatePlayData(void);
3235
3336 public:
3437 WiiBladeWindow(void);
--- trunk/programs/WiiBlade/TimeGraphWidget.cpp (revision 234)
+++ trunk/programs/WiiBlade/TimeGraphWidget.cpp (revision 235)
@@ -5,8 +5,6 @@
55 \author Satofumi KAMIMURA
66
77 $Id$
8-
9- \todo 背景色を白にする
108 */
119
1210 #include "TimeGraphWidget.h"
@@ -15,6 +13,9 @@
1513 struct TimeGraphWidget::pImpl
1614 {
1715 enum {
16+ MinimumWidth = 100,
17+ MinimumHeight = 100,
18+
1819 DefaultDrawPeriod = 3000, // [msec]
1920 };
2021
@@ -21,17 +22,73 @@
2122 TimeGraphWidget* parent_;
2223 int draw_period_;
2324
25+ QColor clear_color_;
2426
27+
2528 pImpl(TimeGraphWidget* parent)
26- : parent_(parent), draw_period_(DefaultDrawPeriod)
29+ : parent_(parent), draw_period_(DefaultDrawPeriod), clear_color_(Qt::gray)
2730 {
2831 }
2932
3033
31- void initialize(void)
34+ void initializeForm(void)
3235 {
3336 parent_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
3437 }
38+
39+
40+ void initializeGL(void)
41+ {
42+ parent_->qglClearColor(clear_color_);
43+ glEnable(GL_DEPTH_TEST);
44+ glEnable(GL_CULL_FACE);
45+ glEnable(GL_TEXTURE_2D);
46+ }
47+
48+
49+ void resizeGL(int width, int height)
50+ {
51+ glViewport(0, 0, width, height);
52+
53+ glMatrixMode(GL_PROJECTION);
54+ glLoadIdentity();
55+
56+ double aspect = 1.0 * width / height;
57+ glOrtho(-1.0 * aspect, +1.0 * aspect, -1.0, +1.0,
58+ std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
59+
60+ glMatrixMode(GL_MODELVIEW);
61+ }
62+
63+
64+ void paintGL(void)
65+ {
66+ parent_->qglClearColor(clear_color_);
67+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
68+
69+ glLoadIdentity();
70+
71+ // 軸の描画
72+ drawAxis();
73+
74+ // データの描画
75+ // !!!
76+ }
77+
78+
79+ void drawAxis(void)
80+ {
81+ glColor3d(1.0, 1.0, 1.0);
82+ glBegin(GL_LINES);
83+ glVertex2d(-0.95, 0.0);
84+ glVertex2d(+0.95, 0.0);
85+ glEnd();
86+
87+ glBegin(GL_LINES);
88+ glVertex2d(0.90, -0.95);
89+ glVertex2d(0.90, +0.95);
90+ glEnd();
91+ }
3592 };
3693
3794
@@ -38,7 +95,7 @@
3895 TimeGraphWidget::TimeGraphWidget(QGLWidget* parent)
3996 : QGLWidget(parent), pimpl(new pImpl(this))
4097 {
41- pimpl->initialize();
98+ pimpl->initializeForm();
4299 }
43100
44101
@@ -49,7 +106,7 @@
49106
50107 void TimeGraphWidget::redraw(void)
51108 {
52- // !!!
109+ updateGL();
53110 }
54111
55112
@@ -69,3 +126,21 @@
69126 {
70127 // !!!
71128 }
129+
130+
131+void TimeGraphWidget::initializeGL(void)
132+{
133+ pimpl->initializeGL();
134+}
135+
136+
137+void TimeGraphWidget::resizeGL(int width, int height)
138+{
139+ pimpl->resizeGL(width, height);
140+}
141+
142+
143+void TimeGraphWidget::paintGL(void)
144+{
145+ pimpl->paintGL();
146+}
--- trunk/programs/WiiBlade/XyGraphWidget.cpp (revision 234)
+++ trunk/programs/WiiBlade/XyGraphWidget.cpp (revision 235)
@@ -5,8 +5,6 @@
55 \author Satofumi KAMIMURA
66
77 $Id$
8-
9- \todo 背景色を白にする
108 */
119
1210 #include "XyGraphWidget.h"
@@ -14,6 +12,8 @@
1412
1513 namespace
1614 {
15+ const double DrawLengthMax = 5.2;
16+
1717 struct XyData {
1818 int timestamp;
1919 double x;
@@ -30,6 +30,9 @@
3030 struct XyGraphWidget::pImpl
3131 {
3232 enum {
33+ MinimumWidth = 100,
34+ MinimumHeight = 100,
35+
3336 DefaultDrawPeriod = 3000, // [msec]
3437 };
3538
@@ -37,17 +40,104 @@
3740 std::deque<XyData> xy_data_;
3841 int draw_period_;
3942
43+ QColor clear_color_;
4044
45+
4146 pImpl(XyGraphWidget* parent)
42- : parent_(parent), draw_period_(DefaultDrawPeriod)
47+ : parent_(parent), draw_period_(DefaultDrawPeriod), clear_color_(Qt::gray)
4348 {
4449 }
4550
4651
47- void initialize(void)
52+ void initializeForm(void)
4853 {
4954 parent_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
55+ parent_->setMinimumSize(MinimumWidth, MinimumHeight);
5056 }
57+
58+
59+ void initializeGL(void)
60+ {
61+ parent_->qglClearColor(clear_color_);
62+ glEnable(GL_DEPTH_TEST);
63+ glEnable(GL_CULL_FACE);
64+ glEnable(GL_TEXTURE_2D);
65+ }
66+
67+
68+ void resizeGL(int width, int height)
69+ {
70+ glViewport(0, 0, width, height);
71+
72+ glMatrixMode(GL_PROJECTION);
73+ glLoadIdentity();
74+
75+ double aspect = 1.0 * width / height;
76+ glOrtho(-1.0 * aspect, +1.0 * aspect, -1.0, +1.0,
77+ std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
78+
79+ glMatrixMode(GL_MODELVIEW);
80+ }
81+
82+
83+ void paintGL(void)
84+ {
85+ parent_->qglClearColor(clear_color_);
86+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
87+
88+ glLoadIdentity();
89+
90+ // 軸の描画
91+ drawAxis();
92+
93+ if (xy_data_.empty()) {
94+ // データがなければ、戻る
95+ return;
96+ }
97+
98+ // データの描画
99+ glPointSize(1.5);
100+ glBegin(GL_POINTS);
101+ int current_timestamp = xy_data_.back().timestamp;
102+ for (std::deque<XyData>::iterator it = xy_data_.begin();
103+ it != xy_data_.end(); ++it) {
104+ double alpha = 1.0 * (current_timestamp - it->timestamp) / draw_period_;
105+ glColor3d(alpha, alpha, alpha);
106+ double x = it->x / DrawLengthMax;
107+ double y = it->y / DrawLengthMax;
108+ //fprintf(stderr, "%f, %f, %f\n", x, y, alpha);
109+ glVertex2d(x, y);
110+ break;
111+ }
112+ }
113+
114+
115+ void drawAxis(void)
116+ {
117+ glColor3d(1.0, 1.0, 1.0);
118+ glBegin(GL_LINES);
119+ glVertex2d(-0.95, 0.0);
120+ glVertex2d(+0.95, 0.0);
121+ glEnd();
122+
123+ glBegin(GL_LINES);
124+ glVertex2d(0.0, -0.95);
125+ glVertex2d(0.0, +0.95);
126+ glEnd();
127+ }
128+
129+
130+ void removeOldData(int current_timestamp)
131+ {
132+ int n = xy_data_.size();
133+ for (int i = 0; i < n; ++i) {
134+ int timestamp = xy_data_.front().timestamp;
135+ if ((timestamp + draw_period_) > current_timestamp) {
136+ break;
137+ }
138+ xy_data_.pop_front();
139+ }
140+ }
51141 };
52142
53143
@@ -54,7 +144,7 @@
54144 XyGraphWidget::XyGraphWidget(QGLWidget* parent)
55145 : QGLWidget(parent), pimpl(new pImpl(this))
56146 {
57- pimpl->initialize();
147+ pimpl->initializeForm();
58148 }
59149
60150
@@ -65,7 +155,7 @@
65155
66156 void XyGraphWidget::redraw(void)
67157 {
68- // !!!
158+ updateGL();
69159 }
70160
71161
@@ -78,4 +168,25 @@
78168 void XyGraphWidget::setData(int timestamp, double x, double y)
79169 {
80170 pimpl->xy_data_.push_back(XyData(timestamp, x, y));
171+
172+ // 古いデータの破棄
173+ pimpl->removeOldData(timestamp);
81174 }
175+
176+
177+void XyGraphWidget::initializeGL(void)
178+{
179+ pimpl->initializeGL();
180+}
181+
182+
183+void XyGraphWidget::resizeGL(int width, int height)
184+{
185+ pimpl->resizeGL(width, height);
186+}
187+
188+
189+void XyGraphWidget::paintGL(void)
190+{
191+ pimpl->paintGL();
192+}
--- trunk/programs/WiiBlade/TimeGraphWidget.h (revision 234)
+++ trunk/programs/WiiBlade/TimeGraphWidget.h (revision 235)
@@ -21,6 +21,11 @@
2121 struct pImpl;
2222 std::auto_ptr<pImpl> pimpl;
2323
24+protected:
25+ void initializeGL(void);
26+ void resizeGL(int width, int height);
27+ void paintGL(void);
28+
2429 public:
2530 TimeGraphWidget(QGLWidget* parent = 0);
2631 ~TimeGraphWidget(void);
--- trunk/programs/WiiBlade/XyGraphWidget.h (revision 234)
+++ trunk/programs/WiiBlade/XyGraphWidget.h (revision 235)
@@ -21,6 +21,11 @@
2121 struct pImpl;
2222 std::auto_ptr<pImpl> pimpl;
2323
24+protected:
25+ void initializeGL(void);
26+ void resizeGL(int width, int height);
27+ void paintGL(void);
28+
2429 public:
2530 XyGraphWidget(QGLWidget* parent = 0);
2631 ~XyGraphWidget(void);
旧リポジトリブラウザで表示