「LMS」タグアーカイブ

記録済みデータのフォーマットを Ruby で変更する

あるツールを使ってデータを記録したが、ツールに手を加えたためにデータの互換性がなくなってしまったのを「互換性がないなら、スクリプトで変更すればいいじゃない」という作業の流れを書きだしたものが、この記事です。

どういう仕組みで何を記録したのか

LMS511 という平面の距離を計測できるセンサがあるのですが、そのセンサとの通信内容を全て記録しました。通信データの記録は LMS11 から距離データを取得するために C++ で実装した Lms_driver というクラスで行なっています。

この Lms_driver クラスは Connection インターフェースを継承させていて、Connection インターフェースはセンサに対する open, read, write を提供します。そのため、Connection インターフェースの中身を差し替えることで、センサからのデータ取得、センサからデータを取得しつつログを記録、ログからデータを読み出して再生、ということが実現できます。

lms_driver_usage_2013_1228

ただ、この仕組みでデータの記録と再生を実現しようとすると Lms_driver でセンサとの通信に使っているコマンドの順番を変えると記録済みのデータが再生できなくなる、という欠点があります。今回は、いろいろ機能を追加すべく Lms_driver を変更した結果、過去に記録したデータが再生できなくなってしまいました。

行う必要があること

過去の実装から変更した点は、センサに発行するコマンドを追加した程度なので、そのセンサからの応答を過去のデータに追加してしまえば O.K. です。

実際に行ったこと

LMS511 との通信は STX, ETX が付加された以外は普通の ASCII 文字列で行われるため、Ruby スクリプトを用いて必要な箇所を置換していくことにします。

具体的に行う処理は

  • 追加したコマンドぶんの応答を追加
  • データ取得コマンドの変更による、データ先頭のコマンド文字列の置換

くらいかな。
改めて書きだしてみると、大したことはないですね。作成するスクリプトの方針としては、引数で与えたファイルの内容を読み込んで、置換でどうにかすることにします。

まず、引数で与えたファイル名を読み出すあたりまでの実装は、こんな感じでしょうか?

# -*- coding: utf-8 -*-
# LMS のログデータを変換するスクリプト

# 引数で渡されたファイルを順に処理する
ARGV.each { |log_file|
  original = File.open(log_file).read

  # コマンドの応答を追加する
  # !!!

  # 必要な置換を行う
  # !!!
}

次に、置換まわりのコードを追加します。(コードの一部の通信データを省略しています)

# -*- coding: utf-8 -*-
# LMS のログデータを変換するスクリプト

# 引数で渡されたファイルを順に処理する
ARGV.each { |log_file|
  converted = File.open(log_file).read

  # 最初のコマンド応答の部分を切り取る
  converted.sub!(/.+?/, "")

  # 必要な置換を行う
  converted.gsub!(/sRA/, "sSN")

  # 最初のコマンド応答を追加する
  converted = "sRA (省略) sEA LMDscandata 1" + converted

  # ファイル名を変更して出力する
  output_file = "converted_" + log_file
  File.open(output_file, "w").write(converted)
}

いつものことですが、実際に手を動かしてみると簡単です。
個人的には、面倒くさがらずに簡単ならもう少し早く取りかかれるようになりたいのですが「怠惰」はプログラマにとって美徳なので悩ましいところです。

まとめ

これからは怠惰な気持ちで楽することを考えつつも、実際には怠惰にならないようにする。

SICK LMS5xx 用の C++ ドライバの作成 (マルチエコーを扱えるようにした)

LMS511 用に開発している C++ ドライバの Lms_driver で、マルチエコー情報を扱うあたりを実装した。

lms_viewer_2013_1217
2エコー目の距離が水色で表示されている

とりあえずは利用できるようになったので、ここまでの実装を hrk_lidar という名前のライブラリとして公開した。URG や LMS センサ用の C++ ドライバで Windows, Linux, Mac で動作する。

hrk_lidar, Lidar_viewer パッケージのダウンロードページ
https://bitbucket.org/satofumi/hobby_robot_sdk/downloads

ドライバの細かな修正は、使いながら行っていきたい。
あとは、このドライバで利用している Viewer も Lidar_viewer という名前のパッケージにして公開した。(Windows 版 binary は Lidar_viewer_win? という名前)

今後は、前回の実験で取得したデータを解析するあたりを行いたい。

SICK LMS5xx 用の C++ ドライバの作成 (強度情報を取得できるようにした)

暇なわけではないが、メイン仕事をする気が起きなかったので Lms_driver.cpp に強度情報を取得するあたりの機能を実装した。
https://bitbucket.org/satofumi/hobby_robot_sdk/src/b5734dc0ba50bf78957748e978cf05223d2d1f3d8/lib/lidar/Lms_driver.cpp?at=default

lms_viewer_2013_1210
オレンジ色のプロットが強度情報

正面に回帰反射版を置いたところ、そこの値が 16 進数の 8 bit 表記で 0xFE になっているのが確認できた。(0xFF には、ならないようだ)

強度データが 0xFE になる特性を利用すれば、反射版かどうかの判定が簡単にできるはず。是非、次回の実験時にこのあたりの情報をうまく使っていきたい。

残るは複数エコーを取得するあたりだが、その実装はまた今度にしたい。

 

SICK LMS5xx 用の C++ ドライバ作成 (Scale Factor の修正)

作成中の Lms_driver で取得した距離が 1/2 になっていたので修正した。
LMDscandata コマンド応答の Scale Factor が x2 なのに、取得した距離データをそのまま表示していたのが原因だった。

lms_viewer_2013_1207
修正前

lms_viewer_2013_1207_2nd
修正後

引き続き、強度情報を取得したりするあたりを実装したい。

SICK LMS5xx 用の C++ ドライバ作成

仕事に関係して SICK 社の LMS511 という距離センサを買ってもらったので、それを使うための C++ クラスを作成した。
https://bitbucket.org/satofumi/hobby_robot_sdk/src/0916bb0ee31d6aa207749dfab44581e53ebea180/lib/lidar/Lms_driver.cpp?at=default

lms_511

単に「作成した」とか書くと簡単に作ったように思えるが、使う日まで時間がないのに同僚からの「時間ないんだし付属してきたライブラリがあるなら、それ使えば?」というコメントに、「Java とか使いたくないし、自分で C++ で書いた方が早く使える気がする」とか返したりしたが…、作り始めたら割と面倒だわ出発の時刻が迫ってくるわで大変だった。みなさん、準備はちゃんとしましょう。

作ったライブラリは以前に作成した URG 用のクラス Urg_driver と同様 Lidar クラスを継承しているので、URG 用に作ったツールなんかがそのまま利用できるといいなー、と思っている。

ただ、未実装な機能が多いので引き続き実装していきます。