Develop and Download Open Source Software

Browse Subversion Repository

Contents of /rangesCtrl/UrgCtrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 290 - (show annotations) (download) (as text)
Tue Mar 18 06:43:15 2008 UTC (16 years ago) by satofumi
File MIME type: text/x-c++src
File size: 15336 byte(s)
Mac 用の調整
1 /*!
2 \file
3 \brief –k—z“d‹@ť‚Ě URG §Œä
4
5 \author Satofumi KAMIMURA
6
7 $Id$
8 */
9
10 #include "UrgCtrl.h"
11 #include "LockGuard.h"
12 #include "SerialCtrl.h"
13 #include "ScipHandler.h"
14 #include "ThreadCreator.h"
15 #include "PointerRingBuffer.h"
16 #include "Delay.h"
17 #include "DetectOS.h"
18 #include "SearchFilePath.h"
19 #include "FileToArgs.h"
20 #include "GetTicks.h"
21
22
23 #if defined(LINUX_OS)
24 #define DefaultDevice "/dev/ttyACM0"
25 #elif defined(WINDOWS_OS)
26 #define DefaultDevice "COM1"
27 #elif defined(MAC_OS)
28 #define DefaultDevice "/dev/tty.usbmodem1d11"
29 #endif
30
31 using namespace beego;
32
33
34 /*!
35 \brief –k—z“d‹@ť‚Ě URG §Œä
36 */
37 struct UrgCtrl::pImpl {
38
39 std::string error_message;
40 SDL_mutex* mutex;
41 ScipHandler scip;
42 SerialCtrl sci;
43 std::string device;
44 long baudrate_setting;
45 CaptureMode capture_mode;
46
47 size_t skip_frames;
48 size_t groups;
49 int first_index;
50 int last_index;
51 bool urg_handstand;
52
53 class ThreadArgs {
54 public:
55 /*!
56 \brief ŽóMƒf[ƒ^‚ĚŠi”[—p
57 */
58 typedef struct {
59 int n;
60 long* data;
61 size_t timestamp;
62 } data_t;
63 ScipHandler& scip;
64 SDL_mutex* mutex;
65 CaptureMode& capture_mode;
66 SDL_sem* recv_size;
67 long max_dataLength;
68 size_t buffer_size;
69 PointerRingBuffer<data_t*> ring_buffer;
70 size_t current_timestamp;
71 bool active;
72 int scan_msec;
73 bool capture_stop;
74
75 ThreadArgs(ScipHandler& scip_ref, SDL_mutex* mutex_obj,
76 CaptureMode& capture_mode_ref)
77 : scip(scip_ref), mutex(mutex_obj), capture_mode(capture_mode_ref),
78 recv_size(SDL_CreateSemaphore(0)),
79 max_dataLength(0), buffer_size(0), current_timestamp(0),
80 active(false), capture_stop(false) {
81 }
82
83 ~ThreadArgs(void) {
84 SDL_DestroySemaphore(recv_size);
85 }
86 };
87 ThreadArgs thread_args;
88 ThreadCreator thread;
89 long urgTimestamp_diff;
90
91 pImpl(void)
92 : error_message("not connected."), mutex(SDL_CreateMutex()),
93 device(DefaultDevice), baudrate_setting(DefaultBaudrate),
94 capture_mode(ManualCapture),
95 skip_frames(0), groups(0), first_index(0), last_index(0),
96 urg_handstand(false),
97 thread_args(scip, mutex, capture_mode),
98 thread(capture_thread, &thread_args), urgTimestamp_diff(0) {
99 }
100
101 ~pImpl(void) {
102 //thread.wait();
103 //fprintf(stderr, "pImpl::stopCapture()\n");
104 scip.stopCapture();
105 SDL_DestroyMutex(mutex);
106 }
107
108 void setHandstand(bool on) {
109 urg_handstand = on;
110 }
111
112 void parseArgs(int argc, char *argv[]) {
113 for (int i = 1; i < argc; ++i) {
114 if (! strncmp("--urg_port=", argv[i], 11)) {
115 device = &argv[i][11];
116
117 } else if (! strncmp("--urg_baudrate=", argv[i], 15)) {
118 baudrate_setting = atoi(&argv[i][15]);
119
120 } else if (! strcmp("--urg_handstand", argv[i])) {
121 setHandstand(true);
122 }
123 }
124 }
125
126 bool connect(const char* device, long baudrate) {
127 if (isConnected()) {
128 disconnect();
129 }
130
131 sci.disconnect();
132 if (! sci.connect(device, baudrate)) {
133 error_message = sci.what();
134 return false;
135 }
136 baudrate_setting = baudrate;
137 return connect(&sci);
138 }
139
140 bool connect(ConnectionInterface* con_obj) {
141 scip.setConnection(con_obj);
142
143 // ‰ž“š‚đ—p‚˘‚˝ƒ{[ƒŒ[ƒg‡‚킚
144 if (! scip.adjustBaudrate(baudrate_setting)) {
145 error_message = scip.what();
146 return false;
147 }
148
149 // ƒZƒ“ƒTî•ń‚Ě”˝‰f
150 if (! loadSensorParameter(NULL)) {
151 return false;
152 }
153
154 // ŽóMƒf[ƒ^‚ĚĹ‘ĺ”
155 thread_args.max_dataLength = getMaxDataLength();
156 thread_args.scan_msec = (scip.getScanRpm() / 6) +1;
157
158 // Žć“žƒXƒŒƒbƒh‚Ě‹N“Ž
159 thread.run();
160
161 return true;
162 }
163
164 void disconnect(void) {
165 thread.stop();
166 UnlockMutex(mutex);
167
168 stopCaptures();
169
170 //fprintf(stderr, "pImpl::disconnect::stopCapture()\n");
171 //thread.wait();
172 scip.disconnect();
173 error_message = "disconnected.";
174
175 // ƒf[ƒ^ƒoƒbƒtƒ@‚Ěíœ
176 deleteBuffers();
177 }
178
179 void deleteBuffers(void) {
180
181 #if 0
182 // !!! ‚˘‚¸‚ęAŽŔ‘•‚ˇ‚邹‚Ć
183
184 for (size_t i = 0; i < n; ++i) {
185 data_t* p = ring_buffer.front();
186 delete [] p->data;
187 // !!! ˆČ‰ş‚́A‚Ü‚¸‚˘‚ń‚ś‚á‚Č‚˘‚Ě‚Š‚ČH
188 // !!! ‚Ü‚žA\‘˘‘Ě‚ÉƒfƒXƒgƒ‰ƒNƒ^‚đ’č‹`‚ˇ‚ׂŤ‚Š‚Ć
189 delete p;
190 ring_buffer.rotate();
191 }
192
193 // !!! ‚Ü‚˝Acapture_thread() “ŕ‚Ě static buffer ‚đ‰đ•ú‚ˇ‚邹‚Ć
194 // !!! ÄÚ‘ąŽž‚Ě‚˝‚ß
195 #endif
196 }
197
198 bool isConnected(void) {
199 return (! scip.isConnected()) ? false : true;
200 }
201
202 bool loadSensorParameter(SensorParameter* parameter) {
203 if (! scip.isConnected()) {
204 return false;
205 }
206 bool ret = scip.loadSensorParameter(parameter);
207 if (! ret) {
208 error_message = scip.what();
209 }
210 return ret;
211 }
212
213 void setLaserOutput(bool on) {
214 if (! isConnected()) {
215 return;
216 }
217 scip.setLaserOutput(on);
218 }
219
220 bool getVersionInfo(std::vector<std::string>& lines) {
221 if (! scip.isConnected()) {
222 return false;
223 }
224 bool ret = scip.getVersionInfo(lines);
225 if (! ret) {
226 error_message = scip.what();
227 }
228 return ret;
229 }
230
231 long getMaxDataLength(void) const {
232 return scip.getMaxDataLength();
233 }
234
235 void setMaxBufferNum(size_t size) {
236 for (size_t i = thread_args.ring_buffer.capacity(); i < size; ++i) {
237 ThreadArgs::data_t* new_data = new ThreadArgs::data_t;
238 new_data->data = new long[thread_args.max_dataLength];
239 new_data->timestamp = 0;
240 thread_args.ring_buffer.push_buffer(new_data);
241 }
242 thread_args.buffer_size = size;
243 }
244
245 void startCaptures(void) {
246
247 // ƒXƒŒƒbƒh‚Ĺ‚Ěƒf[ƒ^Žć“ž‚đ‹–‰Â
248 thread_args.active = true;
249
250 // ƒoƒbƒtƒ@“ŕ‚Ěƒf[ƒ^‚đƒNƒŠƒA
251 thread_args.ring_buffer.clear();
252 while (SDL_SemValue(thread_args.recv_size) > 0) {
253 SDL_SemWait(thread_args.recv_size);
254 }
255
256 // ƒoƒbƒtƒ@‚đ‚Q‚ÂˆČăŠm•Ű‚ľAŽć“ž‰ń”‚đ–łŒŔ‰ń‚É‚ˇ‚é
257 if (capture_mode == AutoCapture) {
258 if (thread_args.buffer_size < 1) {
259 setMaxBufferNum(2);
260 }
261 scip.setCaptureTimes(0);
262 }
263 if (! ((capture_mode == ManualCapture) &&
264 (thread_args.buffer_size <= 1))) {
265 scip.sendCaptureMessage();
266 }
267 }
268
269 void stopCaptures(void) {
270
271 // capture ’âŽ~ƒRƒ}ƒ“ƒh‚Ě”­s
272 scip.stopCapture();
273
274 // ƒXƒŒƒbƒh‚Ĺ‚Ěƒf[ƒ^Žć“ž‚đ’âŽ~
275 thread_args.active = false;
276
277 // !!! stop Œă‚Ěƒf[ƒ^‚đ“ǂݎ̂ĂéŽd‘g‚Ý‚đ’ljÁ‚ˇ‚ׂŤ
278 // !!!
279 }
280
281 int capture(long* data, size_t max_size) {
282
283 if (capture_mode == ManualCapture) {
284 // ManualCapture
285 if (thread_args.buffer_size <= 1) {
286 setLaserOutput(true);
287
288 // Žć“žƒƒbƒZ[ƒW‚Ě‘—M, 1 ‰ń•Ş
289 scip.sendCaptureMessage('G');
290
291 } else {
292 // Žć“žƒƒbƒZ[ƒW‚Ě‘—M, •Ą”‰ń•Ş
293 scip.sendCaptureMessage();
294
295 // ‚Q‰ń–ÚˆČ~‚Ěƒf[ƒ^‚đƒXƒŒƒbƒh‚Ŏ擞‚ˇ‚é‚˝‚ß
296 thread_args.active = true;
297 }
298 // ŽóM
299 int n = scip.recvCaptureData(data, max_size,
300 thread_args.current_timestamp);
301 return n;
302
303 } else {
304 // AutoCapture
305
306 // startCaptures() ‚ތĂ΂ę‚Ä‚˘‚Ȃ݂ę‚΁AŒÄ‚яo‚ˇ
307 if (thread_args.active == false) {
308 startCaptures();
309 }
310
311 if (thread_args.ring_buffer.size() <= 0) {
312 return 0;
313 }
314 if (SDL_SemTryWait(thread_args.recv_size) == SDL_MUTEX_TIMEDOUT) {
315 // ’ź‘O‚Ĺ ring_buffer.size() ”ť’č‚đ‚ľ‚Ä‚˘‚é‚̂ŁAޏ”s‚ľ‚Č‚˘‚Í‚¸‚ž‚Şˆę‰ž
316 return 0;
317 }
318
319 // ƒoƒbƒtƒ@‚Ě“ŕ—e‚đƒRƒs[‚ľ‚ĕԂˇ
320 pImpl::ThreadArgs::data_t* p = thread_args.ring_buffer.front();
321 int n = p->n;
322 memmove(data, p->data, sizeof(p->data[0]) * n);
323 thread_args.current_timestamp = p->timestamp;
324 thread_args.ring_buffer.rotate();
325
326 return n;
327 }
328 }
329
330 static int capture_thread(void* args) {
331 static long* buffer = NULL;
332 ThreadArgs* info = static_cast<ThreadArgs*>(args);
333
334 // ƒf[ƒ^‚̎擞ˆ—
335 LockMutex(info->mutex);
336 if (info->active) {
337 UnlockMutex(info->mutex);
338
339 // ŽóMˆ—
340 if (! buffer) {
341 // !!! ‚ą‚Ěƒoƒbƒtƒ@‚́Aě‚č’ź‚š‚é•K—v‚Ş‚ ‚é
342 // !!! ÄÚ‘ą‚ĚŰ‚ÉA“Ż‚ś URG ‚Ş‚Â‚Č‚Ş‚é‚Ć‚ÍŒŔ‚ç‚Č‚˘
343 buffer = new long[info->max_dataLength];
344 }
345 size_t recv_timestamp;
346 int n = info->scip.recvCaptureData(buffer, info->max_dataLength,
347 recv_timestamp);
348
349 // QT ‚ĚŒă‚Ĺƒf[ƒ^‚ŞŽć“ž‚Ĺ‚Ť‚Č‚˘‚Ć‚Ť‚ɁAI—š‚ł‚š‚é
350 if ((info->capture_stop && (n < 0)) || (n == ScipHandler::QT_Recv)) {
351 // Žć“žˆ—‚𒆎~‚ˇ‚é
352 info->active = false;
353 info->capture_stop = false;
354 }
355
356 LockMutex(info->mutex);
357 // AutoCapture Žž‚Ĺƒoƒbƒtƒ@‚Ş–ž‚˝‚ł‚ę‚Ä‚˘‚é‚Ć‚Ť‚ɂ͂P‚Â•Ş‚Ěƒf[ƒ^‚đŽĚ‚Ä‚é
358 if (info->capture_mode == AutoCapture) {
359 if ((info->buffer_size <= info->ring_buffer.size()) && (n > 0)) {
360 // ‚P‚Â•Ş‚Ěƒf[ƒ^‚đŽĚ‚āAŽóM—Ěˆć‚đě‚é
361 info->ring_buffer.rotate();
362 }
363 }
364 if ((info->buffer_size > info->ring_buffer.size()) && (n > 0)) {
365 ThreadArgs::data_t* p = info->ring_buffer.get_buffer();
366 p->n = n;
367 p->timestamp = recv_timestamp;
368 memmove(p->data, buffer, sizeof(long) * n);
369
370 // Žć“žŹŒ÷
371 SDL_SemPost(info->recv_size);
372 }
373 }
374 UnlockMutex(info->mutex);
375 delay(info->scan_msec / 10 +1);
376 return 0;
377 }
378 };
379
380
381 UrgCtrl::UrgCtrl(void) : pimpl(new pImpl) {
382 }
383
384
385 UrgCtrl::~UrgCtrl(void) {
386 //fprintf(stderr, "~UrgCtrl()\n");
387 disconnect();
388 }
389
390
391 const char* UrgCtrl::what(void) {
392 return pimpl->error_message.c_str();
393 }
394
395
396 bool UrgCtrl::connect(int argc, char* argv[]) {
397 LockGuard guard(pimpl->mutex);
398
399 // ƒfƒtƒHƒ‹ƒgÝ’č‚Ě“Ç‚Ýo‚ľ
400 std::vector<std::string> search_path;
401 search_path.push_back("./");
402 search_path.push_back("~/.beego/");
403
404 std::string config_file;
405 if (searchFilePath(config_file, "beegoconf", search_path)) {
406 // Ý’čƒtƒ@ƒCƒ‹‚Ě“ŕ—e‚đˆř”‚Ć‚ľ‚Ĉľ‚¤
407 FileToArgs fileArgs;
408 fileArgs.load(config_file.c_str(), argv[0]);
409 pimpl->parseArgs(fileArgs.argc, fileArgs.argv);
410 }
411 pimpl->parseArgs(argc, argv);
412 return pimpl->connect(pimpl->device.c_str(), pimpl->baudrate_setting);
413 }
414
415
416 bool UrgCtrl::connect(const char* device, long baudrate) {
417 LockGuard guard(pimpl->mutex);
418 return pimpl->connect(device, baudrate);
419 }
420
421
422 bool UrgCtrl::connect(ConnectionInterface* con) {
423 LockGuard guard(pimpl->mutex);
424 return pimpl->connect(con);
425 }
426
427
428 void UrgCtrl::disconnect(void) {
429 //fprintf(stderr, "UrgCtrl::disconnect()\n");
430 LockMutex(pimpl->mutex);
431 pimpl->disconnect();
432 }
433
434
435 bool UrgCtrl::isConnected(void) {
436 LockGuard guard(pimpl->mutex);
437 return pimpl->isConnected();
438 }
439
440
441 bool UrgCtrl::getVersionInfo(std::vector<std::string>& lines) {
442 LockGuard guard(pimpl->mutex);
443 return pimpl->getVersionInfo(lines);
444 }
445
446
447 bool UrgCtrl::loadSensorParameter(SensorParameter* parameter) {
448 LockGuard guard(pimpl->mutex);
449 return pimpl->loadSensorParameter(parameter);
450 }
451
452
453 void UrgCtrl::setSensorParameter(const SensorParameter* parameter) {
454 LockGuard guard(pimpl->mutex);
455 pimpl->scip.setSensorParameter(parameter);
456 }
457
458
459 void UrgCtrl::setHandstand(bool on) {
460 pimpl->setHandstand(on);
461 }
462
463
464 void UrgCtrl::setCaptureMode(CaptureMode mode) {
465 LockGuard guard(pimpl->mutex);
466 if (pimpl->capture_mode != mode) {
467 // Žć“žˆ—‚Ě’âŽ~
468 //pimpl->scip.stopCapture();
469 pimpl->scip.forceStopCapture(ScipHandler::WaitReply);
470 pimpl->thread_args.capture_stop = true;
471
472 #if 0
473 if (pimpl->capture_mode == AutoCapture) {
474 pimpl->thread.wait();
475 }
476 #endif
477 //pimpl->scip.forceStopCapture(ScipHandler::NoWaitReply);
478 }
479 pimpl->capture_mode = mode;
480 }
481
482
483 int UrgCtrl::getCaptureMode(void) {
484 return pimpl->capture_mode;
485 }
486
487
488 void UrgCtrl::startCaptures(void) {
489 LockGuard guard(pimpl->mutex);
490 pimpl->startCaptures();
491 }
492
493
494 void UrgCtrl::stopCaptures(void) {
495 LockGuard guard(pimpl->mutex);
496 pimpl->stopCaptures();
497 }
498
499
500 int UrgCtrl::capture(long data[], size_t max_size) {
501 LockGuard guard(pimpl->mutex);
502 int ret = pimpl->capture(data, max_size);
503
504 if (! pimpl->urg_handstand) {
505 // ƒf[ƒ^‚Ě”˝“]ˆ—
506 size_t n = pimpl->thread_args.max_dataLength;
507 int front_index = pimpl->scip.getFrontIndex();
508 if (front_index < 0) {
509 // –˘Ú‘ą‚Ěę‡‚Č‚Ç
510 return -1;
511 }
512 if (max_size < n) {
513 n = max_size;
514 }
515 for (size_t i = 0; i < static_cast<size_t>(front_index); ++i) {
516 size_t j = (front_index - i) + front_index;
517 if (j < n) {
518 std::swap(data[i], data[j]);
519 }
520 }
521 }
522 return ret;
523 }
524
525
526 void UrgCtrl::setMaxBufferNum(size_t size) {
527 LockGuard guard(pimpl->mutex);
528 pimpl->setMaxBufferNum(size);
529 if (pimpl->capture_mode == ManualCapture) {
530 // ManualCapture Žž‚́AŽć“žƒoƒbƒtƒ@”‚ž‚Żƒf[ƒ^‚đŽóM‚ˇ‚é
531 pimpl->scip.setCaptureTimes(size);
532 } else {
533 // AutoCapture Žž‚́Aí‚Ƀf[ƒ^‚đŽóM‚ˇ‚é
534 pimpl->scip.setCaptureTimes(0);
535 }
536 }
537
538
539 unsigned long UrgCtrl::getRawTimestamp(void) {
540 LockGuard guard(pimpl->mutex);
541 return pimpl->thread_args.current_timestamp;
542 }
543
544
545 void UrgCtrl::setFrameSkipFrames(size_t skip_frames) {
546 LockGuard guard(pimpl->mutex);
547 pimpl->skip_frames = skip_frames;
548 }
549
550
551 void UrgCtrl::setDataGroups(size_t groups) {
552 LockGuard guard(pimpl->mutex);
553 pimpl->groups = groups;
554 }
555
556
557 void UrgCtrl::setCaptureRange(int first_index, int last_index) {
558 LockGuard guard(pimpl->mutex);
559
560 if (pimpl->capture_mode == AutoCapture) {
561 // AutoCapture ‚ĚŰ‚ÍA–žŽŚ“I‚ÉÄŽć“ž‚đs‚킚‚é‚˝‚߂ɁA‚P“x’âŽ~‚ˇ‚é
562 pimpl->scip.forceStopCapture(ScipHandler::NoWaitReply);
563 pimpl->thread_args.capture_stop = true;
564 }
565
566 if (pimpl->urg_handstand) {
567 pimpl->first_index = first_index;
568 pimpl->last_index = last_index;
569
570 } else {
571 size_t front_index = pimpl->scip.getFrontIndex();
572 pimpl->last_index = (front_index - first_index) + front_index;
573 pimpl->first_index = (front_index - last_index) + front_index;
574 }
575
576 pimpl->scip.setCaptureRange(pimpl->first_index, pimpl->last_index);
577 }
578
579
580 long UrgCtrl::getMinDistance(void) const {
581 LockGuard guard(pimpl->mutex);
582 return pimpl->scip.getMinDistance();
583 }
584
585
586 long UrgCtrl::getMaxDistance(void) const {
587 LockGuard guard(pimpl->mutex);
588 return pimpl->scip.getMaxDistance();
589 }
590
591
592 int UrgCtrl::getMaxDataLength(void) const {
593 LockGuard guard(pimpl->mutex);
594 return pimpl->getMaxDataLength();
595 }
596
597
598 void UrgCtrl::setLaserOutput(bool on) {
599 LockGuard guard(pimpl->mutex);
600 pimpl->setLaserOutput(on);
601 }
602
603
604 double UrgCtrl::index2rad(const int index) const {
605 LockGuard guard(pimpl->mutex);
606 return pimpl->scip.index2rad(index);
607 }
608
609
610 int UrgCtrl::rad2index(const double radian) const {
611 LockGuard guard(pimpl->mutex);
612 return pimpl->scip.rad2index(radian);
613 }
614
615
616 int UrgCtrl::getScanMsec(void) {
617 LockGuard guard(pimpl->mutex);
618 return 1000 * 60 / pimpl->scip.getScanRpm();
619 }
620
621
622 void UrgCtrl::adjustTimestamp(int set_value) {
623
624 // ŒÄ‚яo‚ľŽž‚Ě PC ƒ^ƒCƒ€ƒXƒ^ƒ“ƒv‚đŽć“ž
625 size_t first_ticks = GetTicks();
626
627 // URG ‚Š‚ç‚Ěƒ^ƒCƒ€ƒXƒ^ƒ“ƒv‚đŽć“ž‚ˇ‚é
628 int estimated_delay = 0;
629 size_t urg_timestamp = pimpl->scip.getImmediateTimestamp(&estimated_delay);
630
631 // URG ƒ^ƒCƒ€ƒXƒ^ƒ“ƒvŽć“žŒă‚Ě PC ƒ^ƒCƒ€ƒXƒ^ƒ“ƒv‚đŽć“ž‚ľAˇ•ŞŽžŠÔ‚đŒvŽZ‚ˇ‚é
632 size_t last_ticks = GetTicks();
633
634 pimpl->urgTimestamp_diff =
635 (urg_timestamp - set_value) - (last_ticks - first_ticks) + estimated_delay;
636 }
637
638
639 long UrgCtrl::getTimestamp(void) {
640 return (getRawTimestamp() - pimpl->urgTimestamp_diff);
641 }
642
643
644 ConnectionInterface* UrgCtrl::getConnection(void) {
645 return pimpl->scip.getConnection();
646 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26