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

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

新年の(プログラム)書初めはクソみくじだった(QT練習帳#1)

新年あけましておめでとうございます。

今年は1年数か月後に来るであろう(?)就活に向けていろいろ取り組んで、話せるような実績を作りたいと感じています。「量」をとにかく詰めて行きたいと考えています。

今週くらいにどこぞの学会のレジュメの締め切りや卒論がやばいですが…

本題

 私はこれまで、PythonC++言語を中心に研究や創作で取り組んでいたのですが、それにGUIを付けたプログラムをつけられたらいいのになーと考えていました。GUIが使いにくい場合もありますが、GUIは直感的に使えるので自分用のプログラムにGUIを付属させられれば、見栄えもよいし後々楽になると考えています。

 そのため、今年はROS2だけでなく、QTアプリケーションも力を入れて取り組みたいと考えています。

 今回は、QTのGUI作成の練習として、おみくじアプリ「KUS-omikuji」を作りました。ポプテ〇〇ックのパクリではありません。パワポといらすとやに頼って作りました。動作はとても簡単。プログラムの実行後、スタートボタンを押すと、ランダムに画像が切り替わるようになります。ストップは(あえて)しません。スクリーンショットを撮ることで運勢を占うことができます。

f:id:Ray_ar:20210101135149j:plain
GUI画面

 ボタンを押したらランダムで画像を切り替えるようにするのがとても難しかったです。ほとんどゼロの知識の状態からいろいろ調べて試行錯誤的に作っていったので、なかなか自分でも見づらいと感じるプログラムになってしまったと感じています。次はもっとクラスを理解して実装したいと感じました。公式リファレンスはありますが、いまいち理解が難しかったです。自分がC++理解不足なだけですかね…

 他の人のプログラムも見ながら、より良いプログラムを作りたいと思います。今年もよろしくお願いします。

ターミナルに画像を描画するプログラムを作った。

 もうあっという間に年の瀬となってしまいました…

 今年は、コロナ禍での専攻科受験をパスして一安心かと思ったら、初めての卒研(+α)で学会発表3件で文章作成であっという間に時間が過ぎてしまいました。学業のほうは、GPA評価になったおかげで昨年度以上に上がったんですけどね。シンプルに学業だけで決まらないというのもなんだか今の時代を表しているような気がします。あと、2年しか学生をできないと考えると、なにかは成し遂げたいと焦る気持ちもあります。

本編

 今回は、「無駄なもの」を作りました。何をするかはとても簡単。いつも皆さん(?)が使うコマンドプロンプトをイメージビューワーとして使用するプログラムです。

Githubリンクはこちらです。

GitHub - Ar-Ray-code/draw_on_terminal: This program draws images or videos on the terminal.

 もともとはPythonでos.systemを使って直接シェルを呼び出そうと思っていたのですが、実行ファイル(バイナリ)を作りたかったのと、結構遅い気がしたので、C++で書いていたら、このまま実用レベルまで作りこみたい!と思い、いろいろオプションを追加するようになり、2日くらいかけてプログラムを作成しました。

 使用法は、README.mdを見てください。このプログラムは、jpgなどの画像だけでなくmp4動画なども再生できます。ここでは特に動画を見せませんが、youtube_dl(PythonYoutubeダウンロードツール)とかをつかって動画を持ってきて再生してみるといいと思います。再生時は、デフォルトのサイズ(80x23)で見ることをお勧めします。描画速度に限界があるので、サイズを大きくしすぎると、再生が極端に遅くなります。また、リアルタイムな制御をしていないため、再生時間は実際の動画再生と一致しません。今のところ自ら実装をしようとも思っていませんが、アドバイスがあればありがたいです。

 残念ながら、デスクトップ環境でしか使えないので、catコマンドみたいな感じでCUI環境で写真を見るなどの用途に使えません。そこらへんも作りたいなーと思っています。意外と役に立つかもしれません。

 乱数を用いて描画しているため、どんないちゃもんがきても、「いや、これは乱数を表示しているだけで、絵に見えるのは気のせいですよ!」みたいな反論が可能になります。マイクラ実況者が作るコンクリートの壁や羊毛の島みたいなものと同じですね!

 おそらく誰かは作っているとは思いますが、個人的には、「私の彼女はUbuntuターミナルの中にいます!」という変な方向性のネタを作れたのは収穫かな(?)と思います。

f:id:Ray_ar:20201230164415p:plain
ターミナルへの表示例。プロ生ちゃんの壁紙を(勝手に)拝借しています

 ただ、絶対的な「推し」を見つけられていないので、せっかくの冬期休業なので何かアニメでも視聴したいなーと思っています。

よいお年を!

Darknet(本家)をLog収集可能にしてみた(プログラム改造)

 Darknetは偉大です。速いし、性能いいし、すぐ試せる。欠点を挙げるなら学習にちょっとクセがあるくらいです。使用方法は単純なのにディープなニューラルネットワークを構成するYOLO v3はコンピュータビジョン関連の研究をする大学生で知らない人はいない(?)くらい有名なアルゴリズムです。ROSにも組み込まれていて簡単に使えるからびっくり。

 しかし、研究で使うときに少し不都合があります。それは、ログの取り方が分からないことです。機械学習・深層学習の学習は基本は損失などのデータを貼り付けて学習回数の根拠とすることが多い気がしますが、Darknet(本家)ではデフォルトで実装されていません。(論文をあまり読んでいない上に、読んでいるプログラムも一部なので、もしかしたらほかに方法があるかもしれませんが…)

 学習進捗をweightsの結果以外で知りたい!と思ったので、darknet.cに追記する形で実装しました。

実装

 収集対象は学習コマンドを打ち込んだターミナルに出力される文字列(選択して白くなっている部分)です。

f:id:Ray_ar:20201209121133p:plain
収集対象のログ

 書き換えるプログラムはdarknet/examples/detector.cの130行目付近です。アルゴリズムは、ログが出力される→csvを新規作成or開く→同じ文字列でcsvに書き込む→ファイルを閉じる で、これを学習回数分だけ繰り返します。保存場所はbackupで指定したフォルダと同じ場所です。追記するソースコードを示します。

//直前の行:printf("%ld: %f, %f avg, %f rate, %lf seconds, %d images\n", get_current_batch(net), loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, i*imgs);
        
//Write log -------------------------------------------------
FILE *fp;
char log_name[100] = {};
sprintf(log_name, "%s/%s", backup_directory, "train_log.csv");
if(i == 1)
    fp=fopen(log_name, "w");
else
    fp=fopen(log_name, "a+b");
 
fprintf(fp,"%ld,%f,%f,%f,%lf,%d\n",get_current_batch(net), loss, avg_loss, get_current_rate(net), what_time_is_it_now()-time, i*imgs);
fclose(fp);


//直後の行:if(i%100==0){

 普通にコンパイルします。darknetディレクトリでmakeを実行

 1回目の学習時にファイルは消えるので、新たに学習を開始する場合は注意してください。これで生成されたcsvファイルを適当なアプリで開いてグラフを作成すれば、損失グラフを作ることができます!

f:id:Ray_ar:20201209122858p:plain
csvExcelで開いてグラフ描画

 グラフを表示することができました。Gnuplotとかでリアルタイムでグラフ表示するとかでもよさそうですね。

それにしても、C言語ニューラルネットワーク構築するとか自分だったら頭狂いそう…

またちまちまと改造して使いやすいようにしていきたいと思います。

自作アプリの Make install はしなくていいよね??

 自分の、 M5Core2届いた!ROS2Arduino動かした! - ArRayのてく日記 で Micro-XRCE-DDS 環境開発を構築したのに通信がうまくいかず、ころころとバージョンを変えていました。しかし、それが面倒でした。まず、sudo Make uninstallをできない…。あきらめてインストールしたものを削除しに行くにしても結構コマンド調べて打たないといけないので面倒…。

 ただし、別に make install はしなくてもbuildディレクトリを参照して実行ファイルが動いてくれるので、そこで試せばよいだけのお話です。

 そこで、ふと気づきました。実行ファイルは/usr/local/binとかに置かれるので、そこにシンボリックリンクを貼り付けてそのままbuildファイルにパスを通せば自分でも分かるし、削除も簡単なのでは!?と。

 エンジニアからすれば当然なのかもしれませんが、学生の私は「できるかもしれん!いや、できるぞ!!!」と多少興奮気味にコマンドを打つことに

作成方法

 作成方法は簡単です。sudo make install 以降の操作を行わず、makeを行ったディレクトリに移動して、

$ sudo ln -s [実行ファイル名] /usr/local/bin/[実行ファイル名]

とターミナルに打ちます。

実行ファイルはちゃんと実行可能にしておきましょう。

$ chmod +x [実行ファイル名]

をして、lsコマンドで緑色になっていればOKです。(色がつくターミナルならね)

 おそらく、コマンド実行時に make install を行った時と同じ挙動をしてくれると思います。

シンボリックリンクの名称さえ変えておけば複数バージョンをインストールできるので、環境の使い分けや検証を中心に使えそうです。ちょっとした小ネタにもなりそう。

M5Core2届いた!ROS2Arduino動かした!

 M5Core2を買いました!(研究費の予算だけど)  実はM5Stackシリーズを触ったことがなかったので、結構気になっていたところでした。

f:id:Ray_ar:20201121231341j:plain
届いたやつ

 届いて思ったのは、M5Core2をROSと接続してコントローラノードにしたら面白いんじゃね?と思い、ROSを使うことにしました。そして、何を間違ったのか、「ROS2で動かしてみよう!面白そうだし」と思い、ROS2で開発することに…

 ここからおよそ5日間の地獄の開発が始まるのでした…

 記事を書くのは面倒だけど忘れるのは嫌なので、追記していく感じでやっていきます。

環境

次の環境で動作を確認しました。ROS2(と周辺ツール)は2020年時点ではまだまだ未熟なところもあるため、現時点でほかの環境で動くと思わないほうがいいでしょう。

【ハードウェア】

【ソフトウェア】

  • 開発環境(M5Core2):Arduino IDE 1.8.13(Windows Store 1.8.42.0)
  • RasPiのOS:xubuntu18.04.5 LTS(Ubuntu Server上のインストール)
  • ROS:ROS2 Dashing(patch:7)
  • Micro-XRC-DDS:v1.3.0 (←Dashing patch6とMicro-XRC-DDS 1.3.0の組み合わせが推奨らしいです)

準備

  1. Raspberry Pi4 にUbuntu Server18.04 LTSをインストールします。Raspi-imagerに掲載されているやつを使いました。Mateとかでもいいと思います。
  2. RaspiのUbuntuxubuntu化します。Ubuntu mateとかlubuntuとかでもいいと思います。
  3. Raspberry Pi4 にROS2 Dashing(Patch7)をインストールします。Patch7は執筆時の最新バージョンです。Debianパッケージをそのままインストールしてokです。
  4. Micro-XRC-DDS-Agentをインストールします。サイトを参考にしてください。

github.com

  1. M5Core2をボードマネージャーから追加します。これは、環境設定のURL貼り付け欄にESP32のためのjson URLを貼り付けて読み込ませれば、ボードマネージャーに読み込まれるのでそれの最新版をインストールしましょう。
  2. ROS2Arduino関連のパッケージをインストールします。ros2arduinoと検索してライブラリマネージャーから適当に最新版を持ってくればOKです。

  3. ボードを「ESP32 Dev Module」にして適切なポートを選択すれば準備完了です!

Arduinoのスケッチ例からudpのサンプルプログラム(PublisherとSubscriber)があるため、それのSSIDとPASSWORDを適切なものにしてコンパイルします。

動きます。

今のところうまくいっていないところ(ROS2Arduino×ESP32)

  • ros2::Nodeは継承しないとコンパイルが通っていも使えない(?)セーブしていないので構文を間違えただけかもしれない。

  • ros2::Node.publishが使えない。コンパイルは通るのに動かない。不思議。そのため、周期的にPublishすることしかできないと考えている。

  • Micro-XRC-Agentは環境が大きく関係するみたい。Raspberry Pi4 + Dashingはいけるけど、汎用CPU+DashingやRaspberry Pi4 + Foxyの組み合わせはだめだった。(issueに伝えろと言われているので、さらに検証してみます。)

 SubscriberやMicro-XRC-Agentの互換性についてはこれから検証して追記します。