えいあーるれいの技術日記

ROS2やM5 Stack、Ubuntuについて書いています

Raspberry Pi用Xubuntu + ROSのOSイメージを公開しました。

 Raspberry PiでROSを使うときってノートPCなどの他の環境で構築するよりもストレスを感じることがありませんか?

 最大でも15Wの低消費電力のデバイスとはいえ環境構築を行う上では性能不足感があり、何かと面倒です。

 SSDを搭載したりOCをすることで多少は良くなるそうですが、それならOdyssey Blue Mini PC(過去のレビュー)やスティックPCにコストで負けるような気もするのでう〜んとなります。

 Raspberry Pi ImagerのOSのリストにはUbuntu 20.04 Desktopがないということもあり、GUIを使いたければ(慣れていなければ)更に面倒な工程を踏むことになります。

 Raspberry Piって初心者向けのPCなのに結構環境構築に時間がかかるので、ちょっとハードル高い気がします。

 そこでRaspberry Pi用のROS環境を構築済のUbuntuイメージを公開しようと決めました。

どこにアップしよう…

 OSのイメージは下記の記事を参考にしました。

qiita.com

 作成したのはいいものの、OSのイメージサイズは10GBを超えます。圧縮率の高い7zフォーマットで圧縮しても2.6GBとなり、公開先に困りました。

 GitHubにはReleaseであっても1ファイル2GB制限がありそのままでは公開できません。無料の大容量ファイル共有サービスは時間制限があり、使い勝手が悪いです。

 Google DriveDropboxに課金して共有を使うのも手かもしれませんが、もともと契約していないのにわざわざこのために契約するくらいなら公開しないという方を取りそうです。

 そこで、今回はそのイメージファイルをGitHubに公開するためにひと工夫したのでイメージファイルの紹介とともにその方法を解説します。

公開したファイルは何?

 Raspberry PiXubuntuのDesktop環境とROS環境が最初からインストールされているファイルを公開しました。もちろんROS環境のロードは任意なので、普通のXubuntuとしても使えます。

 Xubuntuは軽量Linuxに分類されるOSで、Ubuntu Desktopよりも軽量であるため、性能が控えめなコンピュータによくインストールされます。

https://raw.githubusercontent.com/Ar-Ray-code/rpi_xubuntu_ros/main/images_for_readme/desktop.jpeg

ログイン画面もUbuntuそのものです。ログインパスワードは「ubuntu20」です。

f:id:Ray_ar:20210606233309j:plain

なぜGitHubにアップできたのか?

 GitHubの2GB制限をくぐり抜ける方法はとてもシンプル。「分割」を行いました。

 フロッピーディスクにファイルを分割して転送していたという話は聞いたことがありましたが、まさか実際にファイル分割を行うとは…!

 実際に結合して復元が成功したときは感動しました(なぜ)

 こうして10GBのイメージファイルは2.6GBの7zファイルに圧縮され、分割されることで、1.5GB程度のファイルが2つ生成されました。

 使うときはユーザ側が復元します。これについては後述します。

https://raw.githubusercontent.com/Ar-Ray-code/rpi_xubuntu_ros/main/images_for_readme/how_to_create_img.png

 ファイルは以下のリンクで公開しています。

github.com

結合方法

 ビギナー用に公開したつもりだったのですが、まさかのファイル分割によってめっちゃ面倒なファイルになっていますが、しっかりと手順を踏めば完璧に復元できます。

 ここでは、Ubuntuでの結合方法を示します。Windowsでもファイル結合はできるしWSLもあるので、調べてみてください。

1.依存環境のインストール

  • 7zツールとRaspberry Pi Imagerをインストールします。
$ sudo apt install rpi-imager
$ sudo apt install p7zip-full

2.イメージファイルのダウンロード

 リリースページからクリックすることでもダウンロード可能です。末尾の番号が違うものをセットでダウンロードします。3GB近く通信するので注意。

$ wget https://github.com/Ar-Ray-code/rpi_xubuntu_ros/releases/download/20.04_v1.0/splited_xubuntu_2004_ros1_ros2_7z_00
$ wget https://github.com/Ar-Ray-code/rpi_xubuntu_ros/releases/download/20.04_v1.0/splited_xubuntu_2004_ros1_ros2_7z_01

3.結合と解凍

 ファイルを7zファイルに戻して、その7zファイルを解凍することでimgファイルを入手可能になります。Ubuntuではcatコマンドで結合できます(!)

 catコマンドを文字表示や文字列結合するだけのコマンドだと思い込みがちですが、catコマンドはsplitコマンドで分割されたバイナリファイルも結合できます。

$ cat splited_xubuntu_2004_ros1_ros2_7z_0* >> image.7z
$ 7z x image.7z
$ rpi-imager &

 Raspbrry Pi Imager のGUIが起動するので、後はいつもどおりのイメージ書き込みです。お疲れ様でした。

ちょっと注意

 イメージファイルからUbutnuを起動したら、次の設定を変更することをおすすめします。

  • 設定->電源から、スリープ時間と自動サスペンドの設定を変更します。

 Raspberry Pi は自動でサスペンドすると自力で復帰する手段を持たない(電源ボタンを実装すればその限りではない)ため、GJIで使用する場合は必ず変更してください。

https://raw.githubusercontent.com/Ar-Ray-code/rpi_xubuntu_ros/main/images_for_readme/setting_suspend.png

基本的にRaspberry Pi + ROSの場合はこのイメージファイルから環境構築を行っています。参考までに。

ROSについて

 ROSとはRobot Operating Systemの略称で、ロボット制御に必要なパッケージや環境が揃っているオープンソースプロジェクトです。企業での産業用ロボット開発から個人のホビーロボット開発まで多くの活用例があります。

 ROS関連の書籍も充実しているのでぜひチェックしてみてください。

(画像をクリックすると詳細ページに移動します)

darknet_ros(Foxy)でScaled-YOLOv4を使う

 Scaled-YOLOv4というのをご存知でしょうか?

 Scaled-YOLOv4はdarknet-YOLOv4の派生のアルゴリズムです。具体的な違いとしては、画像のスケーリングアップ・ダウンを行うためのネットワーク改良がされている点です。この改良によって精度を保ちつつ高速化に成功したそうです。Scaled-YOLOv4-tinyの場合、RTX 2080 Ti(Use Tensor RT)で1774FPSという意味がわからない速度を実現したそうです。JetsonやRaspberry Piなどの実装でも十分な速度が出るのでしょうか??

 以下の論文の概要を引用しました。

arxiv.org

ところでROSで使えるの??

 YOLO v4の良さを引き継ぎつつ高速なScaled-YOLOv4。これはROSで使うしかない!!

 しかし、ROSでScaled-YOLOv4を使えるという話を聞いたことがない。

 これにはROS2記事をQiitaに大量投下されているporizou氏も困惑(?)

 ということで、Scaled-YOLOv4が動くのかどうかを確かめに、アマゾンの奥地へと向かった…

Scaled-YOLOv4が動作する環境

 Scaled-YOLOv4って動くの??という疑問があると思いますが、その心配は無用のようです。

 なぜなら、Scaled-YOLOv4とはネットワークファイルを書き換えて計算量を効率よく削減することで高速化を目指すことを目標にしているからです。変更点はcfgファイルの書き換えが中心になるということでしょう。

 目標では、「演算速度とのトレードオフを考慮して CSPOSANet間での勾配切り捨てを行う新手法を提案する」らしいです。

Minimize/balance size of feature map: In order to get the best trade-off in terms of computing speed, we propose a new concept, which is to perform gradient truncation between computational block of the CSPOSANet.

 具体的には以下の点が変更されたみたいです。(見落とし箇所があるかもしれません。)

  • PAN(Path Aggregation Network for Instance Segmentation)をCSP化することで効率よく計算量を削減したよー

In order to effectively reduce the amount of computation, we CSP-ize the PAN [20] architecture in YOLOv4.

  • CSP化されたPANにもSPPモジュールを挿入したよー

SPP: The SPP module was originally inserted in the middle position of the first computation list group of the neck. Therefore, we also inserted SPP module in the middle position of the first computation list group of the CSPPAN.

 YOLOv4が動けばScaled-YOLOv4も動くので、AlexeyAB/darknetのREADMEでもScaled-YOLOv4について言及されています。yolov4-cspという名称になっています。

実行

 あとは、AlexeyAB/darknetが継承されているdarknet_rosを使ってScaled-YOLOv4を動かすだけです。現時点ではまだマージされていないので、私のリポジトリから最新版のdarknet_rosを落としてください。

github.com

$ git clone --recursive https://github.com/Ar-Ray-code/darknet_ros.git

 colcon build で自動的にyolov4-csp.weights(https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-csp.weights)がダウンロードされると思います。

 実行は、yolov4.launchの代わりにyolov4-csp.launchを使用してください。

結果

 f:id:Ray_ar:20210602044210j:plain

 GPUメモリが1600MByte減り、FPSが30.4から51.1まで改善しました。めっちゃ高速化されている!!!

 こんなに速度が改善するなら、Scaled-YOLOv4使わない手はないですねーー。cuDNNなどをまだ適用していなかった気がするので、最適化すればもっと速くなりそうです。

 しっかりと動作報告もいただきました。

 最近、Darknet_ros関連の記事を出し過ぎな気もしますが、意外と新しい知見が得られまくるのでまだまだ尽きないと思います。

 そういえば、YOLORというもっと速いYOLOもあるみたいなので、weights形式で使えるようになったら使ってみたいですねーー。

Darknet学習・実行にオススメのGPU

 Darknetの学習・実行には非常に多くのGPUリソースが必要です。特にYOLO v4以降のモデルは実行だけでもVRAM 6GB以上必要になるので注意しましょう。VRAMが足りればゲーミングノートでも可です。

RTX 3060:ディープラーニングビギナーにオススメの1台。ディープラーニングはVRAM(GPUのメモリ)が最も重要なので12GBもあるRTX 3060は多少高騰気味の現市場でもオススメです。

Jetson (Xavier):組み込み用途としてはJetsonが有力です。一応RTXが搭載されたNUCやノートPCと比較して検討してみたほうが良さそうです。YOLO v4-tinyくらいなら30fps超えが可能です。

ROSについて

 ROSとはRobot Operating Systemの略称で、ロボット制御に必要なパッケージや環境が揃っているオープンソースプロジェクトです。企業での産業用ロボット開発から個人のホビーロボット開発まで多くの活用例があります。

 ROS関連の書籍も充実しているのでぜひチェックしてみてください。

(画像をクリックすると詳細ページに移動します) (画像をクリックすると詳細ページに移動します)

Neural Compute Stick 2でYOLO v4の物体認識(OpenCV DNN)

 いまさらだけどNeural Compute Stick 2 の環境構築(Ubuntu 20.04 LTS) - えいあーるれいの技術日記の続きです。

 Neural Compute Stickなどの視覚特化AIアクセラレータをVPUと言うみたいです。

環境構築(続き)

 OpenVINOをインストール後は、物体検出に必要なOpenCVをインストールします。本当は直接ビルドしたほうがいいと思いますが、ROSのパッケージをそのまま流用しても動いたので、今回はそれを採用します。

wiki.ros.org

 上記のリンクでROSのキーを取得してros-noetic-vision-opencvのインストールを行います。

※追記:libopencv-devだけを使用しているので、コレをインストールするだけで良さそうです。

プログラム

 CUDA4DNN YOLOv4 Discussion · GitHubを使いました。

 このプログラムをウェブカメラ入力用に変更して、Neural Compute Stickが使えるように書き換えました。

 実行は、$ python3 opencv_dnn_example.pyでOKです。

gist.github.com

GitHub - Ar-Ray-code/opencv_dnn_exampleにもUPしています)

 Neural Compute Stickで物体検出をする際は20行目についてDNN_TARGET_CPUDNN_TARGET_MYRIADに変更します。2つとも変更した場合は動かず、逆にしても上手く動きませんでした。

環境

以下の環境で実行しました。

項目 名称
CPU Intel(R) Core(TM) i5 10210u
GPU Intel UHD Graphics
VPU Intel(R) Neural Compute Stick 2
OS Ubuntu 20.04 LTS
OpenCV OpenCV4

OpenVINOは2021年3月のものを使用しました。

結果

 CPU検出とVPU検出の比較を示します。

 CPUで必要なリソースを全てVPUが肩代わりするのでCPUリソースをほとんど使いません。ただしIntel CPUが優秀なのか、VPUの方は17〜18fpsと多少性能が劣っています。Raspberry PiでもNeural Compute Stickは使えるので、Raspberry Pi + Neural Compute Stickの組み合わせなら電力消費を抑えつつ性能もそこそこになりそうですね。

f:id:Ray_ar:20210531150931p:plain

 Raspberry Pi + Neural Compute Stick 2の組み合わせの環境構築も後日する予定です。

Raspberry Pi + Neural Compute Stickについて

 Neural Compute StickはCPUの負荷を減らすことができるので、発熱を抑えることができ、長時間動作するシステムを作成するのに適しています。Raspberry PiやミニPCなどのGPUが非力なコンピュータの拡張パーツとして使用を検討してみてはいかがでしょうか?

いまさらだけどNeural Compute Stick 2 の環境構築(Ubuntu 20.04 LTS)

 皆さんはNeural Compute Stickをご存知でしょうか?

 最近は、Jetson NanoやCoral USB Accelerator、AIコア搭載のCPUなど多くのAI用デバイスが出てきています。

 そして、Intel(R) Neural Compute StickはそれらのAIアクセラレータのなかでもかなり昔に発売されたデバイスです。Intel(R) Neural Compute Stick 2はその後継で、Raspberry Pi + AIでも定番の組み合わせとなっています。

 私は1年半前にコレを購入したのですが、環境構築がよくわからない+Jetsonや高性能GPUを持っていたので全く使わずに放置していました…

 さすがにそれはまずいだろうと思い、いまさらながら使ってみることに。今回は環境構築編と実行編の2回に分けて説明します。

 Neural Compute Stick はスイッチサイエンスAmazonでなどで1万円程度で購入できます。

 環境は以下のとおりです。

項目 名称
CPU Intel(R) Core(TM) i5 10210u
GPU Intel UHD Graphics
VPU Intel(R) Neural Compute Stick 2
OS Ubuntu 20.04 LTS
OpenCV OpenCV 4

OpenVINO(TM)ツールキットのインストール

 Neural Compute Stick2 を使うためにはOpenVINOが必要です。

 まず、OpenVINOツールキットをダウンロードします。ダウンロードページに到達したら、該当するOSを選択します。ここでは、Linux->Web&Local->2021.3->Onlineを選択します。

software.intel.com

f:id:Ray_ar:20210529124456p:plain

 ダウンロード後はダウンロード先のフォルダでターミナルを開き、次のコマンドを実行します。

$ tar -xvzf l_openvino_toolkit_p_2021.3.394_online.tgz
$ cd l_openvino_toolkit_p_2021.3.394_online/
$ ./install_GUI.sh

 セットアップ画面が表示されます。基本は全てデフォルトでOKです。

f:id:Ray_ar:20210529125843p:plain

 次に、Neural Compute Stick 2のセットアップをします。(Neural Compute Stick 2を挿す必要はなさそうです)

docs.openvinotoolkit.org

 最初に、現在のユーザをusersグループに入れます。ログアウト後に適用されるそうなので、とりあえず以下のコマンドを入力後に再起動しました。

$ sudo usermod -a -G users "$(whoami)"
$ sudo reboot

 再起動後に次のコマンドを入力します。

$ sudo cp /opt/intel/openvino_2021/inference_engine/external/97-myriad-usbboot.rules /etc/udev/rules.d/
$ sudo udevadm control --reload-rules
$ sudo udevadm trigger
$ sudo ldconfig
$ sudo reboot

 環境変数のロード用コマンドを登録します。

$ echo "source /opt/intel/openvino_2021/bin/setupvars.sh" >> ~/.bashrc

 これで、Neural Compute Stick 2を挿すと使用可能になります。

 実行編は次回解説します。

Arduino + Processingをやってみた

 リード線付き表面実装LEDを自作してみた - えいあーるれいの技術日記の続きです。

 前々からGUIを簡単に作れるProcessingに興味があったので、実際にそれを用いたプログラムを作成して実装してみました。このプログラムではLEDをGUIのスライドバーと同期させてPWM制御します。GUI画面もそれに伴って色が変わります。

Processingのインストール

 下記のリンクからプラットフォームを選択してダウンロードします。

processing.org

 zipファイルを解凍して実行ファイルをクリックして実行しました。

接続

 以下の図のように接続しています。Arduinoに挿したLEDをGUIツールで直接制御しています。LEDは表面実装用を使用しています。

f:id:Ray_ar:20210527161736p:plain

プログラム(Processing側)

 Processing側のプログラムを示します。setup関数でツールバーと配置する画像の読み込みなどを行います。そして、Arduinoのシリアルポート接続を開始します。draw関数ではスライドバーの量に応じてArduinoに数字を1バイト送ります。また、スライドバーの値に応じて背景の色も変化させています。

import controlP5.*;
import processing.serial.*;

ControlP5 slider;
Serial port;
int sliderValue;
PImage img;

void setup() {
  int myColor = color(255, 0, 0);
  
  port = new Serial(this, Serial.list()[0], 9600);
  port.bufferUntil(10);

  size(500, 500); 
  img = loadImage("data/data_sq.png");
  image(img, 0, 0);
  
  slider = new ControlP5(this);
  slider.addSlider("sliderValue")
    .setRange(0, 239)
    .setValue(0)
    .setPosition(100, 40)
    .setSize(200, 20)
    .setNumberOfTickMarks(10)
    .setColorValueLabel(myColor);

  slider.getController("sliderValue")
    .getValueLabel()
    .align(ControlP5.RIGHT, ControlP5.BOTTOM_OUTSIDE)
    .setPaddingX(-20);
}

void draw() {
  print(sliderValue);
  print(": ");
  port.write(char(sliderValue));
  int a = port.read();
  println(a);
  background(0,sliderValue*137/239,sliderValue);
  image(img, 0, 0);
}

プログラム(Arduino側)

 次はArduino側です。こっちは非常に簡単です。PWMピンは11番ピンを指定します。map関数でProcessing側から送られてくる最大値239を255に変更します。

void setup() {
  Serial.begin(9600);
  analogWrite(11, 0);
}

void loop() {
  if (Serial.available() > 0) {
    char pwm_c = Serial.read();
    if (pwm_c != 10) {
      map(pwm_c, 0, 239, 0, 255);
      Serial.write(pwm_c);
      analogWrite(11, pwm_c);
    }
  }
  delay(10);
}

 最初はM5 Atomで動かそうとしていましたが、直接USBで接続する方式のシリアル通信ができず苦労しました。Processing自体は簡単なのに結構いいGUIが作れるので便利だと感じました。いい感じの本とか買って必要に応じて辞書引く感覚で使いたいですね。

f:id:Ray_ar:20210527162914g:plain

参考サイト

【Processing】controlP5を使ってGUIを作成する | 物を作る者

ProcessingとArduinoでシリアル通信する方法 | 理系大学院生の知識の森