質問編集履歴
4
解決したので、経緯を追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -315,3 +315,231 @@
|
|
315
315
|
- 無視するheader部分の行数が間違っていたので、`ignore_line > 9` を、` ignore_line > 8` に変更
|
316
316
|
|
317
317
|
- `line = f.readline()` を削除
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
### 修正:解決編(2020/2/28 14:55)
|
322
|
+
|
323
|
+
yuki23様のご指摘にあった、**出力されている角度が360を超えている問題**を解決すべく、元々のC++のソースと、自身が改変したC++を見比べ、可能な限り元の状態を維持しつつ、必要なデータを加えていくように修正を行いました。
|
324
|
+
|
325
|
+
その結果、360度以上のデータが出力されることはなくなりました。
|
326
|
+
|
327
|
+
そのままの形では、依然θと距離しか出力されてませんので、上述の修正後ソースをさらに修正し、Ⅹ座標とY座標に変換したところ、以下のように、部屋の形がきちんと描画されました。
|
328
|
+
|
329
|
+
![点群データ](71d3adec7886822f2bcc9bf131d80e4c.jpeg)
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
元のソース、修正しておかしくなっていたソース、最終的に正常に動いたソースは以下の通りです。
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
[オリジナルC++ソース(抜粋)]
|
338
|
+
|
339
|
+
```C++
|
340
|
+
|
341
|
+
while (1) {
|
342
|
+
|
343
|
+
rplidar_response_measurement_node_hq_t nodes[8192];
|
344
|
+
|
345
|
+
size_t count = _countof(nodes);
|
346
|
+
|
347
|
+
|
348
|
+
|
349
|
+
op_result = drv->grabScanDataHq(nodes, count);
|
350
|
+
|
351
|
+
if (IS_OK(op_result)) {
|
352
|
+
|
353
|
+
drv->ascendScanData(nodes, count);
|
354
|
+
|
355
|
+
for (int pos = 0; pos < (int)count ; ++pos) {
|
356
|
+
|
357
|
+
printf("%s theta: %03.2f Dist: %08.2f Q: %d \n",
|
358
|
+
|
359
|
+
(nodes[pos].flag & RPLIDAR_RESP_MEASUREMENT_SYNCBIT) ?"S ":" ",
|
360
|
+
|
361
|
+
(nodes[pos].angle_z_q14 * 90.f / (1 << 14)),
|
362
|
+
|
363
|
+
nodes[pos].dist_mm_q2/4.0f,
|
364
|
+
|
365
|
+
nodes[pos].quality);
|
366
|
+
|
367
|
+
}
|
368
|
+
|
369
|
+
}
|
370
|
+
|
371
|
+
|
372
|
+
|
373
|
+
if (ctrl_c_pressed){
|
374
|
+
|
375
|
+
break;
|
376
|
+
|
377
|
+
}
|
378
|
+
|
379
|
+
}
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
```
|
384
|
+
|
385
|
+
|
386
|
+
|
387
|
+
[修正失敗版C++ソース(抜粋)]
|
388
|
+
|
389
|
+
```C++
|
390
|
+
|
391
|
+
while (1) {
|
392
|
+
|
393
|
+
rplidar_response_measurement_node_t nodes[8192];
|
394
|
+
|
395
|
+
size_t count = _countof(nodes);
|
396
|
+
|
397
|
+
|
398
|
+
|
399
|
+
op_result = drv->grabScanData(nodes, count);
|
400
|
+
|
401
|
+
|
402
|
+
|
403
|
+
if (IS_OK(op_result)) {
|
404
|
+
|
405
|
+
drv->ascendScanData(nodes, count);
|
406
|
+
|
407
|
+
for (int pos = 0; pos < (int)count ; ++pos) {
|
408
|
+
|
409
|
+
clock_gettime(CLOCK_REALTIME, &ts);
|
410
|
+
|
411
|
+
std::strftime(buf, sizeof buf, "%F %T", std::localtime(&ts.tv_sec));
|
412
|
+
|
413
|
+
|
414
|
+
|
415
|
+
millisec = ts.tv_nsec / 100000000;
|
416
|
+
|
417
|
+
theta = (nodes[pos].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT)/64.0f;
|
418
|
+
|
419
|
+
dist = nodes[pos].distance_q2/4.0f;
|
420
|
+
|
421
|
+
|
422
|
+
|
423
|
+
outfile << buf
|
424
|
+
|
425
|
+
<< ":"
|
426
|
+
|
427
|
+
<< millisec
|
428
|
+
|
429
|
+
<< ","
|
430
|
+
|
431
|
+
<< std::to_string(theta)
|
432
|
+
|
433
|
+
<< ","
|
434
|
+
|
435
|
+
<< std::to_string(dist)
|
436
|
+
|
437
|
+
<< "\n";
|
438
|
+
|
439
|
+
|
440
|
+
|
441
|
+
printf("%s.%ld,%03.2f,%08.2f\n",
|
442
|
+
|
443
|
+
buf,
|
444
|
+
|
445
|
+
millisec,
|
446
|
+
|
447
|
+
(nodes[pos].angle_q6_checkbit >> RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT)/64.0f,
|
448
|
+
|
449
|
+
nodes[pos].distance_q2/4.0f);
|
450
|
+
|
451
|
+
}
|
452
|
+
|
453
|
+
}
|
454
|
+
|
455
|
+
|
456
|
+
|
457
|
+
if (ctrl_c_pressed){
|
458
|
+
|
459
|
+
break;
|
460
|
+
|
461
|
+
}
|
462
|
+
|
463
|
+
}
|
464
|
+
|
465
|
+
|
466
|
+
|
467
|
+
```
|
468
|
+
|
469
|
+
[最終版C++ソース(抜粋)]
|
470
|
+
|
471
|
+
```C++
|
472
|
+
|
473
|
+
while (1) {
|
474
|
+
|
475
|
+
rplidar_response_measurement_node_hq_t nodes[8192];
|
476
|
+
|
477
|
+
size_t count = _countof(nodes);
|
478
|
+
|
479
|
+
|
480
|
+
|
481
|
+
op_result = drv->grabScanDataHq(nodes, count);
|
482
|
+
|
483
|
+
if (IS_OK(op_result)) {
|
484
|
+
|
485
|
+
drv->ascendScanData(nodes, count);
|
486
|
+
|
487
|
+
for (int pos = 0; pos < (int)count ; ++pos) {
|
488
|
+
|
489
|
+
clock_gettime(CLOCK_REALTIME, &ts);
|
490
|
+
|
491
|
+
std::strftime(buf, sizeof buf, "%F %T", std::localtime(&ts.tv_sec));
|
492
|
+
|
493
|
+
millisec = ts.tv_nsec / 100000000;
|
494
|
+
|
495
|
+
printf("%s.%ld,%03.2f,%08.2f\n",
|
496
|
+
|
497
|
+
buf,
|
498
|
+
|
499
|
+
millsec,
|
500
|
+
|
501
|
+
(nodes[pos].angle_z_q14 * 90.f / (1 << 14)),
|
502
|
+
|
503
|
+
nodes[pos].dist_mm_q2/4.0f);
|
504
|
+
|
505
|
+
}
|
506
|
+
|
507
|
+
}
|
508
|
+
|
509
|
+
|
510
|
+
|
511
|
+
if (ctrl_c_pressed){
|
512
|
+
|
513
|
+
break;
|
514
|
+
|
515
|
+
}
|
516
|
+
|
517
|
+
}
|
518
|
+
|
519
|
+
|
520
|
+
|
521
|
+
```
|
522
|
+
|
523
|
+
|
524
|
+
|
525
|
+
whileブロックに入ってすぐの、` rplidar_response_measurement_node_hq_t nodes[8192]; `というところで、hqがついたりつかなかったりしていますが、
|
526
|
+
|
527
|
+
修正失敗版を最初にmakeした時、「hqありは使えない、ないのを使え」みたいなエラーをはかれたため、修正し、その後発生するエラーに対応していったら、結果的に上述のようになった次第です。
|
528
|
+
|
529
|
+
今回、改めてSDKを落とすと、バージョンが上がっており、それが原因か、単に以前が自分のミスだったのかは不明ですが、するっとmakeできてしまい、動くに至りました。
|
530
|
+
|
531
|
+
もっと細かく、何がどうしてエラーだったか、ご報告するのが本来の在り方だとは承知しておりますが、いかんせん、この問題とはこの1年、何度か中断しつつ付き合ってきたため、最初の頃の記憶があいまいで、説明のしようがありません。
|
532
|
+
|
533
|
+
ご理解、ご容赦の程よろしくお願いいたします。
|
534
|
+
|
535
|
+
|
536
|
+
|
537
|
+
### 謝辞
|
538
|
+
|
539
|
+
最後に、皆様のご助言のおかげで、無事にきれいな点群(と言っても16000点前後/秒程度ですが、これはLidarの限界です)の取得に成功しましたこと、心より感謝いたします。
|
540
|
+
|
541
|
+
ずっと一人で作業をしていたら、動いているからと、元のソースを見直すことを頑なに拒んでいたかもしれません。
|
542
|
+
|
543
|
+
こちらで、私などよりもはるかに知見のある皆様の意見に、素直に耳を傾けることができ、解決することができました。
|
544
|
+
|
545
|
+
本当にありがとうございました。
|
3
ファイルアップロード完了とソース修正の通知を追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -301,3 +301,17 @@
|
|
301
301
|
|
302
302
|
|
303
303
|
```
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
### 修正と追加(2020/2/28 11:05)
|
308
|
+
|
309
|
+
Githubに[専用のリポジトリ](https://github.com/taobody/RPLidar_A3)を作って、Pythonのソースと部屋の中で取得した点群データをアップしました。
|
310
|
+
|
311
|
+
ソースも一部修正をしています。
|
312
|
+
|
313
|
+
具体的には、if ブロック内の以下の点です。
|
314
|
+
|
315
|
+
- 無視するheader部分の行数が間違っていたので、`ignore_line > 9` を、` ignore_line > 8` に変更
|
316
|
+
|
317
|
+
- `line = f.readline()` を削除
|
2
掲載する修正後ソースが間違っていたのだ、訂正して再掲。
test
CHANGED
File without changes
|
test
CHANGED
@@ -221,3 +221,83 @@
|
|
221
221
|
何をどう書いていいかもよくわからないまま、思いつくことを書いてまいりましたが、ほかに必要な情報がありましたら、ご指摘いただければ幸いです。
|
222
222
|
|
223
223
|
よろしくお願いいたします。
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
### 修正(2020/2/27 16:30)
|
228
|
+
|
229
|
+
修正後のソースで、角度をラジアンに変換して、三角関数の引数のする箇所を間違っていました。
|
230
|
+
|
231
|
+
ただ、この点に関して、ラジアンに変換せずにthetaを直接使用するように改変したかといいうと、
|
232
|
+
|
233
|
+
1. Lidarの仕様書に、thetaが角度として図示されており、
|
234
|
+
|
235
|
+
1. 参考ソースで変換した際に点群が前述の画像の通り、歪んでいたため
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
です。
|
240
|
+
|
241
|
+
最初に使用した修正後ソースは以下の通りです。
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
[修正後ソース]
|
246
|
+
|
247
|
+
```Python
|
248
|
+
|
249
|
+
#!/usr/bin/python3
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
import math
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
file = "lidarlog2.txt" # Lidarログ出力ファイル
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
f = open(file, 'r')
|
262
|
+
|
263
|
+
line = f.readline()
|
264
|
+
|
265
|
+
ignore_line = 1
|
266
|
+
|
267
|
+
|
268
|
+
|
269
|
+
for line in f:
|
270
|
+
|
271
|
+
if ignore_line > 9: # headerを無視
|
272
|
+
|
273
|
+
line = line.strip().rstrip('\n')
|
274
|
+
|
275
|
+
line_data = line.split(",")
|
276
|
+
|
277
|
+
s = float(line_data[1])
|
278
|
+
|
279
|
+
c = float(line_data[2])
|
280
|
+
|
281
|
+
print(s)
|
282
|
+
|
283
|
+
r = s * math.pi /180
|
284
|
+
|
285
|
+
a = c * math.cos(r) # X座標
|
286
|
+
|
287
|
+
b = c * math.sin(r) # Y座標
|
288
|
+
|
289
|
+
print(line_data[0] + " " + str(a) + " " + str(b))
|
290
|
+
|
291
|
+
line = f.readline()
|
292
|
+
|
293
|
+
else:
|
294
|
+
|
295
|
+
ignore_line = ignore_line + 1
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
f.close()
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
```
|
1
Slamtec社の社名を修正(Slamtech → Slamtec)
test
CHANGED
File without changes
|
test
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
初めて質問させていただきます。
|
6
6
|
|
7
|
-
現在、Slamtec
|
7
|
+
現在、Slamtec社のRPLidar A3(https://www.slamtec.com/en/Lidar/A3)を用いた、マッピングシステムを、RaspberryPi3 B+ にて作成しております。
|
8
8
|
|
9
9
|
SDKが公開されているので、その中のultra_simpleというアプリケーションでテストを行い、C++には不慣れながらも、出力データに日付と時刻を付与するところまではできました。
|
10
10
|
|