粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

3D座標変換の勘所メモ①

タイトルが非常に付けづらかったので埋もれないようにキーワードだけ並べました。

問題設定

2つの座標系があった時,1つの座標系から見て位置^1t_{1p}にある点Pがもう片方の座標系からはどういう値に見えるかという問題を考えることがままあります。 例えばカメラの撮像系等でこのような話はよくありますね。

図で示すと以下のような感じです。

f:id:ossyaritoori:20190221171254p:plain
手書きですまない

毎回こんな図を書いて確認してしまうので記事として書いて答え合わせにしようと思います。

前提:ベクトルの記法について

どの座標系からみたベクトルかを左に添え字で書いています。そこそこPopularな記法だと思います。

例えば^2t_{1p}はベクトルt_{1p}を座標系2の上で解釈したものということにします。

また,^1_2 R^1_2 tはそれぞれ座標系1から2への回転と並進の変位を表しています。教科書では1,2等の数字ではなく記号で書かれることが多いですね。

導出

まず座標系1からみた「座標系2to点P」のベクトル^1t_{2p}

^1t_{2p}=^1t_{1p}-^1_2 t

のようになります。 このベクトルを座標系2から見た時は,回転量^1_2 Rの分だけ逆に回せばいいので(2次元座標で考えてみればすぐわかる)

\begin{align} ^2 t_{2p} = ^1_2 R^\top {}^1 t_{2p} \end{align}

これを先程の式と合わせると

\begin{align} ^2 t_{2p} = ^1_2 R^\top {}^1 t_{1p} - ^1_2 R^\top {}^1_2 t \end{align}

となります。

答え

結局これを以下のような同次表現に落としたとき,

\begin{align} ^2 t_{2p} = [R | t] \begin{bmatrix} {}^1 t_{1p} \\ 1 \end{bmatrix} \end{align}

R,tと「座標系1と2の関係を表すR,t」との関係は \begin{align} R = ^1_2 R^\top \\ t = - ^1_2 R^\top {}^1_2 t \end{align} という風になるわけです。この関係式はちょうど逆もしかりになります(当たり前)。

画像系でよくこのRとtを求めることがありますがGlobal座標でのカメラの位置に変換するにはこのような手順を踏む必要があるのを忘れないように。

余談:はてなブログTex記法を書く方法

以下の呪文を冒頭で唱えた後に,

<p style="display: none;">[tex: ]</p>

\begin{align}で囲むなどすれば通常とほぼ同様に書くことが出来ます。ただし,^や_などの文字には\でエスケープが必要になるらしく,特にt_{1p}などの複数の文字を配置したい場合にはt\_{1p}のように書いたほうが安定するようです。

[参考サイト]

はてなブログで数式が綺麗に書けるTeXの便利ワザ for 見たままモード - cBlog

追記: 最近同じことを書いているサイトを見つけました。No more 車輪の再発明。金言ですね。私はやってしまったわけですがw mem-archive.com

Travis CIを用いたPythonパッケージのテスト管理手順

本来は公式のチュートリアルに従うのが良いと思いますが,既存のコードにとりあえずTravisのマークを載せたいという方には参考になるかと思います。

Travis CIで何ができるのか

端的にはGithub等でコードを管理する際に自動でテストを走らせる事ができるツールです。

↓よく見るこれです。

Build Status

公式の説明はこちら。

Core Concepts for Beginners - Travis CI

自分の行ったプログラムの変更がシステムに影響を及ぼさないか自動でチェックしてくれます。

今の所,チェックなんてローカルでやるし具体的な共有相手みたいなのも想定していないのでせいぜい環境を移行した時にどう動くかの簡易チェック的なものでしか運用しない予定です。 でもOSSの人たちはみなやっているようなので今はフリだけでもできるようにしておこうというやつです。

本記事では最小限Travis CIでbuildを通すやり方のみ記載します。 賢明な皆さんは是非きちんとしたサイトや資料を元に一から勉強して私に教えてください。

下準備:TravisCIへの登録とリポジトリアクティベーション

Githubのアカウントを持った状態で以下のTravis.comのページに飛びます。

travis-ci.com

ここからGithubアカウントとの連携をぽちぽちと進めて登録は終了です。

その後右上のメニューからSettingを選んで以下の画像のように適用するリポジトリを選びます。

f:id:ossyaritoori:20190208143844p:plain
Travis CIのSetting画面

これで下準備は完了です。

.travis.ymlの作成

.travis.ymlというファイルを作成することで自動テストを実行することが出来ます。

例えばPython3.5のパッケージで何某かを実行させたい場合は以下のように書きます。

language: python
python:
  - "3.5"

install:
  - python setup.py install
  #- pip install yaml
    
script:
  - python test.py
  • 最初の行,language:pythonとあるのはどの言語でテストするかを示します。
  • python: 以下ではテストするバージョンを選択できます。
  • install:以降はどのモジュールが必要になるか記述します。setup.pyがある場合はそれを元にインストールすればいいですが,普通にpipから始まるコマンドも書けます。
  • script:以降では実際実行するコマンド群を表しています。この結果帰ってくる値が0であればテスト成功と判定されます。普通にディレクトリ移動などのシェル操作も出来ます。

結局やってることはリモートで仮想環境を立てて,該当する言語の環境を用意し,テストを実行・判定するという流れのようです。 先程のWebページからどのように処理が進んでいるか確認できます。

f:id:ossyaritoori:20190208190539p:plain

こんな感じ。

ハマったこと

いろいろくだらないミス等をたくさんしましたが,一番時間を取られたのは,

  • GUIを表示するタイプ(cv2.imshowとか)のプログラムはテストを通すのが難しい

ということです。( X server うんたらとかいうErrorが出る)

dvfbというのを使ってGUIの設定などできるようですが,今の理解度ではGUIの有無をSwitchできるように調整する方が早かったです。

テストが通ったら

以下の画面の箇所をクリックするとこの画像のURLを入手できます。

f:id:ossyaritoori:20190208191607p:plain

これをマークダウンでREADMEに貼り付ければ自分のパッケージに反映されます

余談:リポジトリの構造について

継続的インテグレーションとありますが結局ちゃんとしたリポジトリの構造から用意するのが良いです。

リポジトリの構造については様々な意見を聞きますが以下の記事の通りにするのが妥当そうです。

qiita.com

しかし開発とかいろいろやってると変なフォルダたくさん作っちゃったりしてややこしくなるんですよね。 意図的に機能ごとにブランチを切る開発スタイルに自然と移行したいものです。

setup.pyについて

さっきの記事にもありましたが,setup.pyを置いておくといろいろ捗る傾向にあります。

qiita.com

説明は今回は省くとしてこんな感じに書いたりします。(ちょっと元ファイルから変えてる)

from setuptools import setup, find_packages
import sys

sys.path.append('./sample')

setup(
    name = 'HOGE',
    version = '0.1',
    description='This is test codes for travis ci',
    install_requires=['numpy','opencv-contrib-python==3.4.0.12','docopt','matplotlib'],
    packages = find_packages(exclude=('sample', 'markers','trial')),
    license = 'MIT',
    author='Ossyaritoori',
)

あとがき

この手のインテグレーションの話を見るとやはりはじめが肝心です。 きちんとした手法で最初から管理している場合はこんなことには悩みませんが,我流でいろいろコーディングしている所にこういうツールを導入するのは非常にコストが重いように思われます。

エンジニア個人としてはどこかのタイミングで導入に踏み切ってリポジトリ単位で慣れていくというのが良いように思いますが,組織としてこういうのを導入して管理するのは結構難しそうです。 大変なことをする割に単体では実務自体にはつながらないのが辛い所ですよね。 「N日人かけて自動でテストできるようにしました。」『それで次の機能はいつ作るの?』「…」

次のプロジェクトからはきちんと構造考えて作る…!

山手線車内に荷物を忘れてしまった件

はい。表題の通りです。 めっちゃ焦りました。その後風邪もひいて踏んだり蹴ったりだったのをよく覚えています。

初動:最初にすべきこと

忘れ物の確認方法には、対応の早い順に以下の3つが考えられます。

  • 電車内を直接調べる
  • 駅員さんに聞く
  • 遺失物問い合わせセンターに電話

これを踏まえて荷物を忘れた人が最初にすべきことは,「乗っていた電車の発着時間や号車を確認する」ことです。

電車の特定の重要性

山手線には終点が存在せず,複数の電車が同じ経路をぐるぐる回っているため電車を特定しない限り,目的の車両にたどり着くのが困難になります。

電車の特定には,

  • 出発駅と時間,到着駅と時間
  • 内回りか外回り(反時計or時計回り)

の情報が最低限必要です。

駅に駆け込んだり,電話をする前に必ず乗っていた電車の情報をなにかにメモするようにしましょう。

車両ナンバーの特定方法

出発駅と到着駅とその時間さえ特定すれば駅員さんが車両を調べてくれますが,これを自分で予め調べておくことができます。

メリットとして,事前に車両ナンバーを抑えておけば,駅員さんに現在その車両がどこを走っているか聞くことができます。(時間外でしたが番号までわかっているということで特別に対応して貰った感があります。) 自力で探すつもりの人は調べ方を抑えておいても良いでしょう。

  • えきから時刻表での探し方を示します。 www.ekikara.jp

-「品川駅」で検索した後,次の画面から山手線を選択します。 f:id:ossyaritoori:20190130185015p:plain

  • 次のような時刻表が出るので乗った時刻または降りた時刻を選択します。(内回り・外回り・平日休日などの違いに注意) f:id:ossyaritoori:20190130185103p:plain

  • 次のような画面になります。この場合「1011G」というのが目的の車両番号です。 f:id:ossyaritoori:20190130185239p:plain

何時の~~という説明も必要になることが多いですが,車両番号を聞けば即対応してくれる駅は多かったです。 (なお,私のときは大崎の車庫に入ってしまったので延長戦に入ったわけですが。。。。)

号車をたどる

乗っていた号車を頑張って辿ったんですが正直あんまり聞かれなかったので何号車かまではガッツリ調べなくてもいい気がします。 駅構内の地図を駆使して頑張れば推定できます。不安ならどうぞ。

電車内を直接調べる,駅員さんに聞く

初動で時間があるor電車がまだ走っているならば,電車を直接調べることができます。 私は経験していないので他のサイトを参考にしてください。

www.chabo-eggs.com

延長戦:一日たったあとにすること

電車が車庫に入ったり,荷物が見つからなかったりした場合延長戦に入ります。 一日後の午後には車庫にあった忘れ物もシステムに登録されるため,検索をお願いすることが可能になります。

ここでは,電話でのお問い合わせセンターやお忘れ物承り所にアクセスすることになります。 www.jreast.co.jp

時間があるならお忘れ物承り所に行くべき

多くの方が電話で済ませているようですが,個人的には東京・上野・品川にあるお忘れ物承り所に行くのがおすすめです。

f:id:ossyaritoori:20190130185720p:plain

電話では,

  • 待たされる
  • 調べ方に柔軟性がない
  • 意思疎通に問題がある

といったデメリットが存在します(4回電話して見つからず,承り所で一発で見つけた人並みの感想)。

承り所の方がきめ細やかな対応をしていただけたのでゆとりがある人は承り所に行ったほうが結果的に早く見つかる可能性が高いと思います。20時までやっているので勤め人でもなんとか間に合うのではないでしょうか。

見つからなかったら

電話などで「みつからない」と言われても絶望するには少し早いです。 車庫に行ってしまってまだ登録されていないのかもしれませんし,カバンと思っていたものが別のカテゴリで登録されていたり(僕はこれでした)というのがあるので時間を改めて何度か電話・承り所を訪れるのが良いと思います。

どうしても見つからなかったら…この記事を見ている場合ではありません。駅に電話して警察に届け出るのが最終解でしょう。

そもそもなくさないように

始末書の類はだいたい次回の防止策を要求してきます。一応今回の反省として, 電車に乗らない。網棚をなるべく使わないというのは結構有効な手段と思われます。立っているときでも足元に荷物を置くようにすればという風に考えています。

「よーし,もうこれで電車にものを忘れないよ! もし忘れたら木の下に埋めてもらっても構わないよ!」

https://pbs.twimg.com/media/Dni2mJtU8AEf1nh.jpg

(完)

M5stackとRaspberry Pi zeroのBluetooth シリアル通信

ハードウェア

M5stackとRaspberry Pi zeroの2つのデバイス間でデータ通信することを目標にしています。

M5stackはディスプレイやボタンのインターフェイス用として,Raspberry Pi zeroはより高度な処理用として用います。 今回はM5stackが情報を送信するのみ,という仮定でやっています。

M5stackについて

M5Stackとはディスプレイ付きのマイコンその他もろもろ開発ボードです。

M5Stack Gray(9軸IMU搭載)

M5Stack Gray(9軸IMU搭載)

開発手段には以下の2つが存在します。

前者のほうがライブラリなどが豊富ですが,後者はPythonベースなので記述量が非常に少ないというメリットがあります。 僕はファームウェアの書き換えが上手く行かなかったので前者を採用しました。

なお,WindowsPCでシリアル通信をしたことない場合などはドライバがない可能性があるのでこちらを参照にすれば良いと思います。

特定の通信機器を使う際にはそれに対応するCP210xのドライバが必要ということみたい? 本製品ではこちらからダウンロードするのが良さげです。

Raspberry Pi zeroについて

いわゆるRaspberry Piの小型軽量版です。省スペースかつ省電力なのにDebianベースのLinux OSが動かせるのでわりと使えそうです。

ossyaritoori.hatenablog.com

M5stack側の準備

ここではArduino開発環境を前提に進めていきます。 このサイトを参考に進めると良いでしょう。

また,Arduinoのエディタは正直言ってあまり使い勝手は良くないので,ここではVScodeで開発をしました。

「ファイル」の「環境設定」から「外部のエディタを使用する」にチェックを入れることで他のエディタで編集した.inoファイルの変更内容をArduinoIDEに反映させることが出来ます。ただし,IDEの方から文章を変更できなくなるのは注意。

BluetoothSerial.hの利用

Bluetoothで単に送信するだけの関数は驚くほど簡単で,"BluetoothSerial.h"をインクルードして,BluetoothSerial クラスを呼ぶだけです。 その後,print,println,writeなどの関数で文字列や数値を送信することができます。

#include <M5Stack.h>
#include "BluetoothSerial.h"

byte counter;

BluetoothSerial bts;

void setup() {
  M5.begin();
  M5.Lcd.println("Bluetooth Now");

  Serial.begin(9600);
  bts.begin("M5Stack");//PC側で確認するときの名前

  counter = 0;
}

void loop() {
  bts.println(counter);
  counter++;
  delay(100);
}

Raspberry pi 側のセットアップ

M5stackが上記のようなプログラムですでに初期化・起動しているとします。

ペアリング,MACアドレスの取得

Bluetoothのペアリングはラズパイ側のGUIで設定する方法とCUIで設定する方法があります。その後の手順を考えるとCUIでやった方がいいのかなと思います。

  • CUIでペアリング:bluetoothctlの起動

bluetoothctlとコマンドを打つことでBluetoothの管理モードに移行します。

こんな感じの表記になるはずです。

pi@raspberrypi:~ $ bluetoothctl
[NEW] Controller B8:27:EB:8C:43:C6 raspberrypi [default]
[bluetooth]#

この後,以下のコマンドを順番に実行します。

agent on
default-agent
discoverable on
scan on

しばらくするとscanの結果として,次のような画面に移行するので先程設定したM5Stackの文字を探しましょう。

[bluetooth]# scan on
Discovery started
[CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
[NEW] Device 30:AE:A4:4F:A3:76 M5Stack

私の場合はこの30:AE:A4:4F:A3:76がM5stackのMACアドレスということになります。(重要)

その後このMACアドレスを用いてpair <MACアドレス>とコマンドを実行することでペアリングは完了です。

以下のような画面が出るかと思います。その後は適当にquitして元のターミナルに戻ってください。

[bluetooth]# pair 30:AE:A4:4F:A3:76
Attempting to pair with 30:AE:A4:4F:A3:76
[CHG] Device 30:AE:A4:4F:A3:76 Connected: yes
Request confirmation
[agent] Confirm passkey 952397 (yes/no): yes
[CHG] Device 30:AE:A4:4F:A3:76 UUIDs: 000~
[CHG] Device 30:AE:A4:4F:A3:76 UUIDs: 000~
[CHG] Device 30:AE:A4:4F:A3:76 UUIDs: 000~
[CHG] Device 30:AE:A4:4F:A3:76 ServicesResolved: yes
[CHG] Device 30:AE:A4:4F:A3:76 Paired: yes
Pairing successful
[CHG] Device 30:AE:A4:4F:A3:76 ServicesResolved: no
[CHG] Device 30:AE:A4:4F:A3:76 Connected: no

接続も自動で行われるはずですが,不安ならば先程のbluetoothctlの画面にてconnect MACアドレスを実行すると良いでしょう。

バインドしてシリアル受信確認

接続しただけではデバイスとして認識できないのでrfcommというコマンドを使ってBindを行います。 例えば先程メモしたMACアドレスを用いて,

sudo rfcomm bind 1 30:AE:A4:4F:A3:76 2

のように実行することで,/dev/rfcomm1のポート2がBluetoothの入出力に対応するようになります。

シリアルにて流れてくる情報を単に閲覧したければ

cat /dev/rfcomm1 

とうって確認できます。

Pythonで受信した文字列を表示

先程バインドしたrfcomm1を引数にしてSerialモジュールを呼ぶことで通信が可能です。

import serial
ser=serial.Serial('/dev/rfcomm1')

while 1:
    print(ser.readline())

トラブルを避けるならKeyboardInterruptでser.close()を呼ぶなどした方が安全でしょうが,一応これでM5stackが発信している文字を確認できます。

逆にser.send()を用いてラズパイ側から送信した場合は,M5stack側でread()を用いて受信関数を書けば動作します。

ラズパイ起動時にプログラム実行

先程の接続やバインドなどをラズパイの起動時にキー入力なしでしたいと思った場合,/etc/rc.localというファイルに書き込むという手段があります。 root権限で実行されるので少し気をつける必要がありますが,とりあえず動かしたい場合はこれでも良いかと。

# connect
echo "connect 30:AE:A4:4F:A3:76 \nquit" | bluetoothctl

#bind
sudo rfcomm bind 1 30:AE:A4:4F:A3:76 2

# add your program below

何に使ったか

M5stackで作ったタイマーと組み合わせて起床時に徐々に明かりを明るくするIoT目覚ましセットを作成しました。 睡眠リズムの改善が求められる…

f:id:ossyaritoori:20190111231037p:plain
目覚ましセット

参考文献メモ置き場

記事で引用すると思ったけどしなかった参考文献たち:

Wifi接続などに関する参考文献

Raspberry Pi zero wh のセットアップ

最近セットアップ記事しか書けてない気がしますが気のせいです。

RaspberryPi Zero WH

正月の電子工作の延長でIoTごっこをしたいと思い,Raspberry Pi Zero WHを買いました。

特徴として,

  • 安い(680~1900円)
  • 小さい
  • 省電力

があります。単体では安いですが,地味に必要物が違ってくるのでいろいろセットになっているやつを買うのがいいと思います。(MicroUSB-USB A変換とか普通持ってないでしょう)

準備物は,

  • 上記セット
  • HDMIディスプレイ
  • PC,キーボード
  • microSDカード
  • USB電源(microUSB)

なお,はじめからsshで全部やるきの人はこの限りではないです。

Raspberry Pi Zero Wをディスプレイやキーボードなしで初期設定、Wi-Fi接続

OSのインストール

以前用いた手法にのっとってOSを入れます。

今回はRAMが512MBしかないのでUbuntuMateでも不安がありました。 Raspbianを代わりに使います。

デバッグ1:電源が着かない問題

最初に電源が着かないという問題に直面しました。 デバッグの方法として,

  • Vcc端子の電圧をチェックする
  • PCにUSB接続でつないで動作確認

があります。

[参照] 電源LEDが点灯しない!?のは当たり前。ゼロから始めるRaspberry Pi Zero(3)Raspberry Pi Zeroが壊れていないか確認する方法 | bokuraku.com

僕は2つ目のチェックで故障でないことを確認しました。なおZero WHには電源のすぐ横に緑色LEDがあるのでうまく行ったら光るはずです。

いくつか端子を抜き差ししたら治った(キーボードをごついやつから小さいものに変えたらうまく行った) ので,接触や供給電力の問題等もあるのかも?

固定IPの設定

通常はDHCPというIPアドレス自動割当の様式に従ってルータから適当に番号を振られてしまいます。 sshでアクセスしやすいよう固定IPを振ります。

固定IPの決定方法

ではどのIPを振っていいかということですが,末尾10以降はDHCPの自動割当に含まれていることが多いようなので2~9あたりで決めるのが良さそうです。

なお,192.168.x.1のようにIPの末尾を1にしてブラウザに入力すればルータの設定が見れます。

[参照] 自宅のLANでIPアドレスを固定するマイルールを決めてみる【自宅Wi-Fiの“わからない”をスッキリ!】 - INTERNET Watch

固定IPをふる

以下のブログなどを参照にしてIPを振ります。 qiita.com

# ↓ の行を追加
interface wlan0
SSID SSID名
inform IPアドレス/マスク
static routers=デフォルトゲートウェイ
static domain_name_servers=DNSサーバ

なんですけど,なんか僕の環境ではうまくふれてないんですね。直し次第修正します。

[参考になりそう] Static IP Addressing issues (Wlan0) - Raspberry Pi Forums

雑談:Nanoエディタ

geditやvscodeばかり使っていましたがSSHで接続するにあたりNanoエディタを使うことにしました。

下にGuideが出ていますが,Ctrl+<キー>で実行します。

誰も興味が無いnanoの基礎の基礎 - nanoはpicoの千倍なの! - - KAYAC engineers' blog

vi? 可能な限り避けたい。

SSH接続

sshで接続するときの基本的なコマンドは ssh ユーザ@IPアドレス -p ポート番号です。

例えばこんなふう。

ssh pi@192.168.x.x -p 22

Windows環境からSSHする

これにもいくつか手順があるようですが,以下のサイトの情報に従って進めました。

usado.jp

Raspberry Pi から高精度AD/DA変換ボードを用いてAD/DA入出力

Raspberry PiでAD/DA変換をする方法

Raspberry PiにはHigh/Lowのディジタル入出力が可能なGPIOがついていますが,アナログセンサデータを読んだりアナログ電圧を出力することはできません。 従ってこの記事で紹介されているようなAD/DAコンバータが必要になります。

回路を組むのはだるいのでAmazonで以下のAD/DA変換ボードを購入してみました。

高精度AD/DA変換ボード

高精度とうたっていますがカタログスペックは以下の通りです。

  • ADポート6チャンネル(16bit)
  • DAポート2チャンネル(12bit)

Vccは5VなのでDA出力が 0~5Vとすると,12bitで分割して大体8mVくらいの分解能があります。すごい。嘘やけど。

ボードのセットアップ

今回の環境は前回 SetupしたUbuntu MATEとします。ROSは使ってないのでROSの項は飛ばしてもOK。

bcm2835 のインストール

ここからtarファイルを落として7zで解凍します。

解凍した中にINSTALLという名前のファイルがあるのでその指示に従います。

一応実行するコマンドは以下の通りです。途中sudoが必要な点に注意。

./configure
make
sudo make check
sudo make install
make installcheck

でインストール状況をチェックできます。

提供されているサンプル

ここで配ってますが正直読むのは結構だるいので誰か解説してやってください。

コマンドラインからDA出力を制御する自分用ライブラリ

てなわけで自分でプログラムつくりました。 下記からCloneしてmakeすれば完了です。

github.com

こういうふうに5VとVcc,Vref そしてDA0,AD0とDA1,AD1を接続します。

makeした後に出てくる実行ファイルは2つです。

Vcc補正用プログラム:calib

このAD/DAコンバータでは正確な5Vが必要っぽいのですが,ラズパイから電力供給するとVccが微妙に5Vにならないという問題を抱えているため,その補正用です。

以下に実行結果を示します。

$ sudo ./calib
Supposed DA output[V] DA0:3.000000 DA1:3.000000 
Measured DA output V0 = 3.070409, V1 = 3.066153 
Supposed Vref = 5.058334 
magnitude offset: 1.011667, 1.010965

この実行結果から,3Vを出しているのに3.07Vが出ている(とADで読める)ズレが有ることがわかります。これでは12bitの分解能が台無しです。 この関係から実際のVcc=Vrefを5.058Vと推定しています。テスタで測ると5.053なので5.0Vとして考えるよりはマシになりそうです。

このときの5Vに対するVccの倍率を一番下の行で計算しています。僕の環境では1.01倍と出ていますね。

注意:原理は多分Vrefとの比較でADやDAのしきい値を変えているのでVrefの倍率分DAやADの値が変化すると読んで計算しています。もっといい方法なんかあるなら知りたいっす…

出力プログラム:dac8532_output

こちらでは,引数にDA0とDA1の出力電圧[V],Sleep時間[ms]を与えることでコマンドラインから出力を可能にしています。

$ sudo ./dac8532_output  <電圧1>  <電圧2>  <時間>  <補正> 

と打ちます。 <補正>項はデフォルトで1.01にしているので抜いてもOKです。

  • データ例

試しに4Vと2Vを出力させるよう

$ sudo ./dac8532_output  4 2 10  1.01

を実行しました。

結果は3.998Vと1.999Vでした。

Vccの電圧をきちんとしない限りカタログスペックの12bit分解能は正直出ないと思われます。 でもまぁそこまで気にしないのならそこそこの精度かなと思います。 5Vや0V等の上限下限近づいた場合はこの限りではないので注意。

Pythonからの実行

結局最近プログラムの多くをPythonで書くようになったのでDA出力もPythonからしたいです。

実はsubprocessというやつを用いるとコマンドライン実行をめちゃ簡単にできます。

import subprocess

da0 = 3
da1 = 4
duration = 20

subprocess.call(["./dac8532_test",str(da0),str(da1),str(duration)])

呼び出し先のプログラムにはsudo権限がいるのでこのPythonコードをsudoで実行すればいいわけです。 (/dev/memにアクセスするからのようですが,できればsudoなしでアクセスしたい…)

総括

カタログスペックは高いですが電源をちゃんとするとかしないと正直カタログのような超精度は出なさそうです。 ただ,ラズパイの上に乗って収まりが良く,はんだ付けなどなしで動作させられるのでアプリケーションによっては結構ありかも? 私は今回は車載用センサ処理に使っています。

久々にリポジトリ作りました。汚いですが指摘などあれば歓迎です。超暇なら直します。

Raspberry Pi + Ubuntu Mate + ROS のセットアップ

ラズパイに入れるOSの選定

Raspberry Piの公式で推されているのはRaspbianですが,Ubuntu系列も入れる事ができます。Raspbian使いづらい

ではなぜPopularなUbuntuではなくその亜種を使っているかというと,端的にリソースの問題だと思われます。(以下参考サイト) itsfoss.com これらはデスクトップ環境が異なっておりざっくりと聞きかじったところ以下のような特徴があるそうです。(上記サイト参照)

  • UbuntuGNOME 3 使用。RAMが4G以上推奨?
  • KubuntuKDE使用。RAM 2G以上推奨?
  • XubuntuXfce使用。RAM 1G程度でも動作。
  • Lubuntu:LXDE使用。RAM 1G程度でも動作。
  • Ubuntu MATE:GNOME 2使用。RAM 1G程度でも可。

もちろん必要RAMの少ない軽量なディストリビューションはあまり洗練された描画を行えないとのことですが,ラズパイ環境では贅沢できないのでXubuntu, Lubuntu, Ubuntu MATEで妥協する必要がありそうです。

筆者の主観的な選定基準

  • Raspbian:とりあえず安牌な選択肢2018年12月時点では個人的におすすめしないです

買ったばかりのときはRaspberry用に最もPopularと思われるRaspbianを用いました。特にやることが決まってない人やUnixのOSにこだわりがない人はこちらから始めてもよいでしょう。Mathematicaも入ってるし。

ossyaritoori.hatenablog.com

今回使うROS等特にUbuntuで使われているソフトを使いたい場合は軽量版のUbuntu亜種を使う人が多いようです。

ouroboros.hamazo.tv

簡易版があるとはいえ,Ubuntuそのものを使いたい事情があるならばそちらを入れることもあるでしょう。 事実MATEでいくつかうまくいかないことがあったりしたのでUbuntuならなんとかなったのかもしれません。 「Raspberry Pi 3」に「Ubuntu 16.04」を入れる(備忘録) - Qiita

準備する機器

2年前のものですが必要なものは変わってないです。SDカードと電源は気を使いましょう。 ossyaritoori.hatenablog.com

Ubuntu MATEのインストールと初期設定

Raspberry pi 3本体とmicroSDカード,マウス,キーボードその他ディスプレイ環境は整っているものとします。 その他に今回はWindowsのマシンを使用します。Ubuntuマシンを使う方はこのあたりは他の記事を参照にしてください。

microSDのフォーマット

買いたてのまっさらなmicroSDを使う人はこの章は飛ばしても結構です。

パーティションの削除(ある場合)

すでにブート環境を整えたりしてパーティションを作ってしまった場合,windowsではdiskpartというツールが用意されています。 スタートページまたはコマンドプロンプトからdiskpartを起動しましょう。

list diskとコマンドを打つとコンピュータが認識しているディスクが表示されます。512GのSSDと32GのSDカードが刺さっている場合は以下のようになります。

DISKPART> list disk

  ディスク      状態           サイズ   空き   ダイナ GPT
  ###                                          ミック
  ------------  -------------  -------  -------  ---  ---
  ディスク 0    オンライン           476 GB      0 B        *
  ディスク 1    オンライン            29 GB   109 MB

ちなみに,容量が減って見えるのは販売時は1GB=1000MB=1,000,000KB=1,000,000,000Bとして売っていいということになっているためらしいです。 つまり,販売時に32GBとあるメモリは実質 32/1.0243 = 29.8GBの容量になるわけですざけんな。

その後select disk 1でディスク1を選択し,list partitionパーティションを確認します。

DISKPART> SELECT DISK 1

ディスク 1 が選択されました。

DISKPART> LIST PARTITION

  Partition ###  Type                Size     Offset
  -------------  ------------------  -------  -------
  Partition 1    プライマリ               63 MB  4096 KB
  Partition 2    プライマリ               29 GB    67 MB

これをそれぞれのパーティションに入ってdelete partitionとうってすべてのパーティションを消し飛ばせます。なお,大文字小文字の区別はないようです。

DISKPART> SELECT PARTITION 1

パーティション 1 が選択されました。

DISKPART> DELETE PARTITION

DiskPart は選択されたパーティションを正常に削除しました。

すべてのパーティションを消したあと,以下のようにしてパーティションを再構成します。

DISKPART> CREATE PARTITION PRIMARY

DiskPart は指定したパーティションの作成に成功しました。
フォーマット

Windows側から読めないディスクを検知した場合,エクスプローラ起動時に「フォーマットしますか?」とのメッセージが出る仕様になってます。 メッセージに従ってFAT32でSDカードのフォーマットを行えばOKです。

microSDへのイメージ書き込み

次にUbuntuMATEのイメージを書き込みます。 まずは下準備として,

  1. ここからRaspberry Pi用のUbuntu MATEのイメージをダウンロードして解凍。
  2. DD for windowsをダウンロードしてインストール。

回線しだいですが10分程度かかるかと。

次に,DDforWindowsを管理者権限で実行します。

ディスクの選択の後,ファイル選択で先程解凍した.imgファイルを選択します。

ラズパイに挿して起動

いよいよ起動です。 起動後に現れるメッセージに従って進めていくと良いでしょう。

なお僕は一度Wifiの設定にてWPA-PEAPのネットワークにつなごうとして失敗して入れ直したのではじめはWifiに繋がずに進めるといいかもしれません。

起動後即やることは,WifiまたはEthernetにつないだ後に

sudo apt-get update
sudo apt-get upgrade

を行うことです。

これには1時間以上かかったので休憩するタイミングはここです。

Chromiumのインストール

自分の環境ではFirefoxがCrashしてしまうので,代わりにChromiumを使うことにしました。

sudo apt install chromium-browser

https://laptop.ninja/how-to-install-chromium-and-google-chrome-on-ubuntu-mate/laptop.ninja

ROS Kineticのインストール

さて,このあとは公式のガイドに従っていつものようにROSを入れればいいです。

実行するだけチートシート

どういうことが行われているかわかっているから手っ取り早く結果を見たい!という場合は以下のコマンドをコピペして順に実行すればいいです。

所要時間は1時間くらいだったかと思います。

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install ros-kinetic-desktop-full
sudo rosdep init
rosdep update
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc 
source ~/.bashrc

ここから各種センサつないだりいろいろあると思いますがとりあえずはここまで。