Kanadeの工作室

電気も機械もあるんだよ!

Azoteq IQS127D (静電容量タッチセンサIC)の使い方

www.azoteq.com

データシート:https://www.mouser.jp/datasheet/2/42/iqs127_datasheet-1602122.pdf

サンプルコード:https://www.azoteq.com/wp-content/uploads/2019/02/azd017_iqs127_1-wire_protocol_sample_code.pdf

機能

  • 電極とIC(とコンデンサと抵抗)だけでタッチスイッチを作れる
  • Proximity output (近接状態を検出できる)
  • ATI(自動調整機能)
  • 1-Wire通信でセンサ値を取れる

PIN

  1. TOUT - スイッチの出力・シリアル通信にも使用
  2. VSS - Ground
  3. POUT - Proximity output
  4. VREG - 内部レギュレータ用コンデンサに接続
  5. VDDHI - 電源(2.95V~5.5V)
  6. CX - 電極(抵抗を直列接続)

簡単な使い方

TOUTをトランジスタにつなぐだけで,スイッチとして使える

静電容量の値を取る

1-Wire っていうプロトコル*1で通信できて容量値を取れたり閾値を設定できたりするっぽい

ほげほげ(実験します)


タッチセンサ用のIC,アキバを回っても見つからなかったから秋月とかで売ってくれないかな

*1:電源ラインと信号ラインを1本にまとめられるらしい(ここではそうなってはいないが).簡易なセンサ用の通信によさそう.

Dockerはじめました

お仕事でちゃんとDockerを使わないといけなくなったので勉強し始めました.

とりあえず"docker しくみ"とかでgoogle先生に聞いて出てきたやつをざざっと読むと,

  • 仮想化
    • バーチャルマシンは重い
    • コンテナはホストの機能を使いつつ仮想化するので軽い
    • namespace・cgroupeというLinuxの機能がベースにある
  • イメージ
    • イメージというのがある
    • レイヤが積み重なった構造をしている
    • レイヤは利用時には一つに見える ←???
    • イメージをビルド?してコンテナを作る
    • レイヤのベースに配布されてるubuntuとかを使いがちらしい
  • コンテナ
    • 隔離された名前空間
    • プロセスはこの中で動く
  • Dockerfile
    • イメージを組み立てる設計図てきなもの
    • イメージのレイヤと対応している?
  • docker-compose.yml
    • Dockerfileとの違いがよくわからん
    • docker-compose up すると動く

実験:node.js

ishida-it.com

これを真似する

  • docker-compose.ymlを書いて実行
    • npm がなんか言ってる
    • コンテナ内の./app以下にいろいろたりねぇぞ
    • いったんコンテナ内に入って,npmうんぬんかんぬんしてやる
    • ./src(コンテナ外)に追加された!
  • これで実行すると……
    • localhost:3000になんか出た
    • コンテナ側のターミナルにnodeのログが出てる
  • nodemonを追加してリアルタイムで反映されるようにする

実験:TypeScript

qiita.com

  • 例のごとくdocker-compose.ymlを書く
version: "3"
services:
  app:
    image: nginx:latest
    container_name: "app"
    ports:
      - "8080:80"
    volumes:
      - ./src/html:/app
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf

  node:
    image: node:10
    container_name: node
    tty: true
    working_dir: /usr/src/app
    volumes:
      - ./src:/usr/src/app
  • volumes:のとこがあってればとりあえず動きそう

docker-compose.ymlを書くだけでとりあえず使えることがわかた

WSLに接続したVSCodeにclang-formatを追加する

① LLVMをインストールして(LLVMのclang-format.exeを使う)

releases.llvm.org

② WSL側からLLVMへのパスを通して

export PATH=$PATH:/mnt/c/'Program Files'/LLVM/bin

③ clang-format の拡張機能をインストールして

marketplace.visualstudio.com

③ settings.json

"clang-format.executable": "/mnt/c/Program Files/LLVM/bin/clang-format.exe"

VSCodeにclang-formatの場所を教える)

"[c]": {
    "editor.defaultFormatter": "xaver.clang-format"
  },

(言語ごとのフォーマッタの設定)

を追加すればおk

ついでに

  "editor.formatOnType": true,
  "editor.formatOnSave": true,

を設定しとくと編集時・保存時にフォーマットしてくれるよ

OS超入門

なぜOSを使うか

 そもそもコンピュータは機械語しか実行できません.そして機種によって機械語の書き方が違います.つまりあるコンピュータで動くプログラムを別のコンピュータで動かそうとしても動きません.これだとプログラムをコンピュータごとに作らないといけないので効率が悪いですね.

 このハードウェアごとの違いを,「システムコール」というインターフェースで抽象化します.機械語では「メモリの何番地の値を~~にする.」のようにハードウェア的な表現をしているのに対して,システムコールでは「~~を画面に表示する.」というように機能に即した表現をしています.そしてOSはシステムコールをハードウェアに合わせて実行してくれます.システムコールを使ってプログラムを書くことでハードウェアに依存しないプログラムが書けます.

OSの機能

 OSはハードウェアに依存しない形式でいろいろなシステムコールを実行してくれる便利な奴ですが,このような機能を実現するために,OSはコンピュータ起動の直後から実行されコンピュータを支配します.というのも,OSが動いてるコンピュータ上で,プログラムはコンピュータ資源を使うために毎度OSにお伺いを立てないといけないからです.

※OSが起動するまで

 コンピュータの電源を入れると,マザーボード上にあるBIOSが実行されます.BIOSは諸々の初期化をした後にOSを呼び出します.デュアルブートではここで呼び出すOSを変えてやればいいわけです.

 詳しくは → http://park12.wakwak.com/~eslab/pcmemo/boot/boot2.html

ファイルシステム

 ファイルが保存されているドライブは一次元配列ですが,それをWindowsのC:\user\hogeとかLinuxの/home/hogeのように,木構造にしてるのもOSです.

プロセス管理・メモリ管理

 パソコンで,同時にいくつかのプログラムを,お互いが干渉することなく実行できるのは,OSがプログラムごとに時間(CPUを使える時間)・空間(メモリ)を分割して割り当てているからです.あるプロセスからするとまるで自分一人だけがコンピュータを使っているかのように見えるような環境を提供します.

プロセス・スレッド

 プロセスを細かい単位に区切ったものをスレッドといいます.たとえばオムライスを作るというプロセスは,「米を炒める」「卵を焼く」というスレッドにわけることができます.

 OSはスレッド単位で実行を管理します.マルチスレッド(スレッドを同時に複数実行できる)なCPUを使っている場合はOSがそれぞれにスレッドを割り当ててくれます.プロセスを適切にスレッドを分割することでプロセスを早く実行できたり,CPUを効率的に使うことができます.

 ひとつしかフライパンがない場合,「米を炒める」→「卵を焼く」とするしかないですが,フライパン2つでオムライスを作る場合,平行して実行できますね.また「米を炒める」が7割ぐらい進んだら「卵を焼く」を実行すると,ちょうどいいタイミングで両方ができて冷めずに済みます.「米を炒める」が7割進んだところに「「卵を焼く」を実行する.」というシステムコールを書いておけば,OSはCPUのスレッドに合わせて(マルチスレッドならシステムコールが呼ばれたところから並列に,シングルスレッドなら順番に)実行してくれます.

 このようにOSはリソースを効率的に使うようにプロセスの実行を管理してくれます.

アドレス変換

 メモリは一本の一次元の配列です.複数のプロセスが同時に動いている場合,あるプロセスが使っているメモリが別のプロセスによって意図せずに書き換えられてしまうとまずいです.OSはメモリを分割してそれぞれプロセスに割り当てます.

プロセスにとってのアドレス(0~n)を物理メモリ(a~n+a)と対応させる仕組みがアドレス変換です.

それぞれのプロセスが一本のメモリを持っているかのようにするためにアドレス変換を行います.プロセスがメモリを要求してきたら,物理メモリの中から使われていない領域を探してプロセスにアクセス権を与えます.ここで,プロセスのメモリ

プロセスがn番地の値(0,1,2,,,)

しばらく使っていないメモリ領域を,いったんハードディスクに移します. (自分の部屋にも実装して……)

組込みOS

組込み機器

リアルタイム性,つまり時間に正確な

ITRON

参考書

OSを使ってみる

https://www.amazon.co.jp/dp/B075ST51Y5/ref=cm_sw_em_r_mt_dp_FJv4FbNGZNMK7

OSを作ってみる

https://www.amazon.co.jp/dp/B00IR1HYI0/ref=cm_sw_r_tw_dp_x_8Pv4FbYZHX1H4

https://www.amazon.co.jp/dp/B07YBQY75J/ref=cm_sw_r_tw_dp_x_7Qv4Fb2C6CE7S

最近出た チョットワカルようになる

https://www.amazon.co.jp/dp/4877832394/ref=cm_sw_r_tw_dp_x_HLn1FbEENZW6B

Linuxのコードを読む

ジャイロセンサを使った簡単な姿勢推定

機械系 Advent Calendar 2020の記事です

毎度阿鼻叫喚(?)でおなじみのキリキですが,角運動量とかこねくり回して問題は解けても実際の運動を記述できてる気がしなかった…というのも授業ではオイラー角を使って姿勢を表現できますよ~って説明があっただけなので…

ジャイロセンサを使って姿勢を求めると回転運動のお気持ちが完全に理解できたので記しておきます.

姿勢推定

姿勢の記述方法(回転行列)→姿勢と角速度の関係(微分方程式)→角速度センサから姿勢を推定するプログラム(離散化・差分方程式)

姿勢の表現

キリキでは,剛体の無数の質点の運動(を決定するのに必要十分な,二点の運動)として剛体の運動を記述することから始めていますが,ここでは剛体に貼り付いた(固定された)座標系の運動として剛体の運動を記述します.となれば回転の自然な表現はオイラー角ではなく行列になるはずです.オイラー角は「姿勢の表現としては」数学的に不自然で扱いにくいのでここでは使いません.(角速度の表現として使います.オイラー角が自然でないというのは,可換でないということです.またジンバルロックという問題もあります.)(もう一つ回転の表現としてよく使われるものとして,クオータニオンがあります.クオータニオン複素数の拡張で,複素数が平面の回転を表すのに適しているように,空間の回転をうまく表せます.)

グローバル座標系E(x,y,z)とセンサ座標系S(x',y',z')の変換として姿勢を表現します.


\begin{bmatrix}
x'(t)\\y'(t)\\z'(t)
\end{bmatrix}
=R'(t)
\begin{bmatrix}
x(t)\\y(t)\\z(t)
\end{bmatrix}

x',y',z'の成分表示を縦に並べるだけで回転行列になります.

角速度ベクトル

センサが微小回転したとき,センサ座標系の単位ベクトルの変位は,


\begin{bmatrix}
x'(t+dt)-x'(t)\\y'(t+dt)-y'(t)\\z'(t+dt)-z'(t)
\end{bmatrix}
=
\begin{bmatrix}
x'(t) \times \omega dt \\y'(t)\times \omega dt \\z'(t)\times \omega dt 
\end{bmatrix}

角速度ベクトルwとの外積になります.

ジャイロセンサで計測される値(w1',w2',w3')は,角速度をセンサ座標系(x',y',z')で表現したものです. これはそれぞれx',y',z'軸を中心とした角速度,つまりオイラー角の時間微分になっています.じゃあそいつを積分したればええやんけ!とはならないんですね(残当).一言で言えば微小回転は可換だが回転は非可換であるからです.(Rx(θ1),Ry(θ2),Rz(θ3)を順番を変えてかけたら一致しないが微小角なら一致することからわかります.)

角速度ベクトルの成分を使って,


w = 
\begin{bmatrix}
w'_1\\w'_2\\w'_3
\end{bmatrix}
^T
\begin{bmatrix}
x'\\y'\\z'
\end{bmatrix}

外積を計算してやると,


\begin{bmatrix}
x'(t) \times \omega \\y'(t)\times \omega \\z'(t)\times \omega 
\end{bmatrix}
=
\begin{bmatrix}
0 & -\omega'_3 & \omega'_2 \\
\omega'_3 & 0 & -\omega'_1 \\
-\omega'_2 & \omega'_1 & 0 
\end{bmatrix}
\begin{bmatrix}
x'(t)\\y'(t)\\z'(t)
\end{bmatrix}

もとの式は


\begin{bmatrix}
x'(t+dt)-x'(t)\\y'(t+dt)-y'(t)\\z'(t+dt)-z'(t)
\end{bmatrix}
=
\begin{bmatrix}
0 & -\omega'_3 & \omega'_2 \\
\omega'_3 & 0 & -\omega'_1 \\
-\omega'_2 & \omega'_1 & 0 
\end{bmatrix}
\begin{bmatrix}
x'(t)\\y'(t)\\z'(t)
\end{bmatrix}
dt

これをグローバル座標系で表すと


R'(t+dt) 
\begin{bmatrix}
x\\y\\z
\end{bmatrix}
=
R'(t)
\begin{bmatrix}
x\\y\\z
\end{bmatrix}
+
\begin{bmatrix}
0 & -\omega'_3 & \omega'_2 \\
\omega'_3 & 0 & -\omega'_1 \\
-\omega'_2 & \omega'_1 & 0 
\end{bmatrix}
R'(t)
\begin{bmatrix}
x\\y\\z
\end{bmatrix}
dt

差分方程式


R'(t+dt) 
=
R'(t)+\omega'R'(t)
dt

\omega' =
\begin{bmatrix}
0 & -\omega'_3 & \omega'_2 \\
\omega'_3 & 0 & -\omega'_1 \\
-\omega'_2 & \omega'_1 & 0 
\end{bmatrix}

これを使ってジャイロセンサから姿勢を計算する ※Rは正規化します

実験

Arduinoでセンサ値をSerialでUnityに渡して表示する 使用したセンサ→秋月

Arduinoのコードは秋月のほぼサンプルです.Arduinoはセンサ値を送るだけで処理はUnity側でしてます.

Unityでシリアルを受け取る方法 → https://rikoubou.hatenablog.com/entry/2018/02/08/174506

周期を安定化

タイマ割り込みでサンプリング周期を安定させてます. これでも±10%の誤差が残ります.

#include<MsTimer.h>
#include<Wire.h>

void setup(){
  Wire.begin();
  Serial.begin(2000000);
  BMX055_Init();
  delay(300);
  MsTimer2::set(10,sense); //sense();を10msごとに実行
  MsTimer2::start();
}

void sense(){
  sei();
  // 略 センサを読んでSerialに送る
}

void loop(){
  // きょむ~
}

Wireが割り込みを使っているのにMsTimer2が割り込みに飛ぶときに割り込み禁止にしちゃうので割り込み許可をするためにsei();する. 先人のおかげで沼らずにすんだ→ http://kuchem.kyoto-u.ac.jp/kinso/weda/blog/?date=20180107#c

結果

積分誤差が蓄積してます. カルマンフィルタとか使いましょう() 最近はMadgwickフィルタなんてのがあるらしいですね.

₍ᐢ.ˬ.ᐢ₎ にゃーん