Git超初心者がRaspberry PiでGitサーバを構築して、Windowsでcloneするまで! 後編 Git構築
こんにちは。前回に続き、今回は実際にRaspberry Pi(Debian 8.0)でGitサーバ(リモートリポジトリ)を構築し、Windows PCからcloneしてみます。
・Raspberry Piにリモートリポジトリを作成!
まずはRaspberry PiにGitをインストールします。
(Raspberry Pi) apt-get install git
次に、Git専用のユーザーを作成しましょう。今回はgitというユーザーを追加します。
(Raspberry Pi) useradd -m git passwd パスワード
そして、リモートリポジトリを作成したいディレクトリ上で(今回は/home/git)
(Raspberry Pi) cd /home/git git init --bare --shared hoge.git
こうすることで/home/gitにhoge.gitという名前でリポジトリフォルダが作成されます。
--bareは作成するリポジトリをベアリポジトリとして、--sharedはみんな書き込みできるよ~というオプションです。
ベアリポジトリはフォルダ名に.gitを付けるのが慣例のようです。
ベアリポジトリについては前回の記事を参考に!
ls -a
で、".git"というフォルダが作成されていることが確認できると思います。
一旦これでRaspberry Piでの作業は置いておきます。
次にWindowsでの作業に移ります。
・Windows PCでローカルリポジトリを作成!
・Gitのインストール
まずはWindowsにGitをインストールしましょう。
こちらのページよりダウンロードできます。
インストール後、私はCygwinからGitを使用していきますが、コマンドプロンプトでもほぼ同じ内容で作業ができると思います。
・鍵の生成、登録
早速clone!と行きたいところですが、まだやらなければいけないことがあります。
Windowsから先ほど作成したRaspberry Piのgitユーザーでssh接続をできるようにします。
まずはWindows PCのわかりやすい場所に.sshというフォルダを作成し、そこに公開鍵とそれに対応する秘密鍵を作成しましょう。
(Windows) mkdir .ssh ssh-keygen -t rsa -C "コメント" Generating public/private rsa key pair. Enter file in which to save the key (//.ssh/id_rsa): ここに.sshのパスを入れる
すると、指定した.ssh内に「id_rsa」「id_rsa.pub」が生成されることが確認できると思います。この.sshのパスは覚えておいてください。
Raspberry Piに戻り、/home/git(ユーザー名)に「.ssh」ディレクトリを作成し、authorized_keysというファイルを作成しましょう。
そして、「id_rsa.pub」の中身をauthorized_keysへコピーしましょう。
(Raspberry Pi) mkdir /home/git/.ssh cd /home/git/.ssh vim authorized_keys (id_rsa.pubの中身をコピーして保存)
これでsshの為の鍵の登録は完了しました。
Windowsに戻ります。
次に、clone等をする際に行うsshで使用する秘密鍵の場所を設定してあげます。
(僕はこれを忘れていて、
The authenticity of host '' can't be established.
Host key verification failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
こんなエラーにしばらく悩まされましたとさ…)
(windows) vim ~/.ssh/config
で設定ファイルを開き、
Host 任意の名前 Hostname ssh://(さっき作ったユーザー名):(パスワード)@(IPアドレス)(リモートリポジトリのパス) User git IdentityFile "(さっき鍵を作ったパス)" Port 22
このように書き込みます。
IPアドレスの欄には、内部ネットワークから接続する場合はRaspberry PiのプライベートIPアドレスを、外部ネットワークから接続する場合はグローバルIPアドレスを入れましょう。
例えば
Host hoge Hostname ssh://git:password@192.168.0.50/home/git/hoge.git User git IdentityFile "c:/Users/$user_profile/.ssh/id_rsa" Port 22
こんな感じになります。
・いざclone!
これでようやくcloneの準備が整いました。
ローカルリポジトリを作成したいディレクトリへ移動し、以下のコマンドを実行します
git clone ssh://(さっき作ったユーザー名):(パスワード)@(IPアドレス)(リモートリポジトリのパス) (ローカルリポジトリフォルダ名)
例えば私の場合は
git clone ssh://git:password@192.168.0.50/home/git/hoge.git hoge
になります。
これでようやくcloneができましたね!(おそらく空のリポジトリをクローンしたよ!平気?という警告メッセージが出るかと思いますが、無視してください。)
ls -a
で、".git"というフォルダが作成されていることが確認できると思います。
・あとはこっちのモンだ
早速commit、pushしていきましょう!
ワーキングツリーで適当にファイルを作って…(ここではtest.txtを作りました)
(Windows) git status
これで、インデックスに追加されていない変更内容を確認できます。
On branch master Untracked files: (use "git add <file>..." to include in what will be committed) test.txt nothing added to commit but untracked files present (use "git add" to track)
test.txtが変更されてるけど追加されてないよ~って言ってますね
addでインデックスへ追加してあげましょう。
(Windows) git add test.txt
そして
(Windows) git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: test.txt
これで準備完了!commitしましょう。
git commit -m "test.txtを追加"
-mオプションを付けて、スペース空けて後ろにコメントを書きます。主にどのような更新をしたのかを記しましょう。
最後にpush!
初回のpushでは、-uオプションを付けましょう。
git push -u ssh://(さっき作ったユーザー名):(パスワード)@(IPアドレス)(リモートリポジトリのパス) master
無事pushできましたか?
ここで、毎回毎回pushの度にssh://~~を入力していたら大変ですよね。それを省略する機能を使いましょう。
git remote add origin ssh://(さっき作ったユーザー名):(パスワード)@(IPアドレス)(リモートリポジトリのパス)
このように、ホストをoriginという名前に対応させましょう。すると
git push
このように省略が可能になりました。
ちなみに、こう書けるのは対応した名前が"origin"の時のみで、別名を付けた場合は
git push 付けた名前
としましょう。
pullしたい時は、同じように
git pull
もしくは
git pull 付けた名前
するだけです。
・終わった…
これで一通り環境が整ったのではないでしょうか!(書き忘れていることがあるような気がしますが…)
長かった…疲れた…後半はテキトーに書いてました。
ここが違うよ!できないよ!といった意見がございましたら、どしどしコメントをください!
それでは!良いGitライフを!!
Git超初心者がRaspberry PiでGitサーバを構築して、Windowsでcloneするまで! 前編 Gitとは?
こんにちは。久しぶりの更新です。
今まで何かアプリケーションを開発する時、日付.zipやバージョン名.zipでクソ管理してきた僕ですが、ついにGitを使うときがやってきました。
訳あってGithub等の外部サービスにリモートリポジトリを置けない状況だったので、自宅にあるRaspberry Pi3でリモートリポジトリを作成し、手元のWindows PCにもGitを入れてそこからclone、pushできる環境を作りました。
Gitってなんだ?という状態から行ったこと、躓いたことを備忘録として書いていこうと思います。
・Gitってなんだ!
Gitはプログラムのバージョン管理を楽に行っちゃおうっていうツールです。
例えば1人でアプリを開発する場合。新たに機能を追加したいけど、それで何か不具合が起きたら困るし…と、既存のプログラムをoldVersionなんて言う名前にしてバックアップを取り、新たな機能を開発する…。そんな事を繰り返していると、フォルダの中はoldVersion1, oldVersion2, oldVersion2 - コピーと、意味分からないファイルでいっぱい!
または複数人で開発する場合。うまく連携が取れず、気がついたら同じプログラムを複数人で編集してしまい、競合が発生!
こんな経験、ありませんか?
これを全て解決してくれるのが、Gitなのです。
Gitは主に「リモートリポジトリ」「ローカルリポジトリ」「インデックス」「ワーキングツリー」から構成されます。
(リポジトリは、ファイルの変更履歴を保存する場所を指します。)
・ローカルリポジトリ
個人の変更履歴を保存する場所です。
・ワーキングツリー
ローカルリポジトリにあります。要は作業場です。ここにあるファイル(フォルダ)を編集していきます。
・インデックス
ローカルリポジトリへ変更内容を記録したいワーキングツリーのファイルを、まずはここに格納します。ここに格納されていないファイルは、変更内容がローカルリポジトリへ記録されません。
・リモートリポジトリ
サーバ等へ置き、みんなで共有するリポジトリ。みんなの変更履歴がどんどん追加されていく。基本的にリモートリポジトリはワーキングツリーを持たない。これをベアリポジトリという。
gitでは主なコマンドとして、
clone
add
commit
push
pull
があります。
・clone
リモートリポジトリを、個人(ローカル)のディレクトリへコピーする(クローンを生成する)コマンドです。それがローカルリポジトリとなります。
・add
指定したワーキングツリーのファイル(フォルダ)をインデックスへ格納するコマンドです。
・commit
インデックスにあるファイル(フォルダ)の前回commitからの更新内容をローカルリポジトリへ保存するコマンドです。普通はメッセージを付け、何をどう変更したのかを明白にします。
・push
ローカルリポジトリの中身をリモートリポジトリへ追加するコマンドです。
・pull
誰かが更新し、リモートリポジトリへ追加した内容を、自分のローカルリポジトリへ反映させるコマンドです。
他にもbranch等、大事な大事な機能がありますが、今はとにかくRaspberry Piでリモートリポジトリを作ってwinPCでcloneするのが目的なので、今回は省略!
もう文章だらけで飽きましたよね。
百聞は一見に如かず、次回はいよいよRaspberry Piでの作業に移ります!
後編はこちらから!
tocknlab.hatenablog.com
ESP32 (ESP-WROOM-32)でSDカードへ読み書きする。(Arduino IDE)
ESP32弄り第三弾は、SDカードへの読み書きです。
SDカードはSPIを使って通信します。
今回はこちらのSDカードモジュールを使用しました。
ピン配置は、
このようになっています。
ESP32への配線は以下の通り行いました。
- DAT2 -> 無し
- CD/DAT3 -> GPIO5
- CMD -> GPIO23
- VDD -> +3.3V
- CLK -> GPIO18
- VSS -> GND
- DAT0 -> GPIO19
- 以下接続なし
ちなみに、どうにかすれば接続するピンを変えられるみたいです。多分。
また、先に言っておきますが、絶対にいらないSDカードを使用してください。中身が飛ぶことがよくあります。
そして配線は慎重に行ってください。3.3V以上の電圧をかけるとSDカードがぶっ壊れると聞いたことがあります。
そして、SDカードの抜き差しは電源が入っていない状態で行ってください。SDカードを読み込まなくなったりします。
何か起きても私は責任トリマセン…
スケッチは、公式のExampleをそのまま使いました。ここにあります。
これを使えばSDカードの読み書きに関する大抵のことはできると思います。
もしライブラリを追加する方法がわからない~とかでしたら、コメントください。
上手く行けば実行結果はこんな感じになると思います。
SD Card Type: SDSC SD Card Size: 1875MB Listing directory: / DIR : /SYSTEM~1 FILE: /YEAH.TXT SIZE: 8 FILE: /TEST.TXT SIZE: 1048576 FILE: /FOO.TXT SIZE: 13 DIR : /MYDIR DIR : /TESTDIR Creating Dir: /mydir Dir created Listing directory: / DIR : /SYSTEM~1 FILE: /YEAH.TXT SIZE: 8 FILE: /TEST.TXT SIZE: 1048576 FILE: /FOO.TXT SIZE: 13 DIR : /MYDIR DIR : /TESTDIR Removing Dir: /mydir rmdir failed Listing directory: / DIR : /SYSTEM~1 Listing directory: /SYSTEM~1 FILE: /SYSTEM~1/WPSETT~1.DAT SIZE: 12 FILE: /SYSTEM~1/INDEXE~1 SIZE: 76 FILE: /YEAH.TXT SIZE: 8 FILE: /TEST.TXT SIZE: 1048576 FILE: /FOO.TXT SIZE: 13 DIR : /MYDIR Listing directory: /MYDIR DIR : /MYDIR/TEEEEE Listing directory: /MYDIR/TEEEEE DIR : /MYDIR/TEEEEE/SDF DIR : /TESTDIR Listing directory: /TESTDIR Writing file: /hello.txt File written Appending to file: /hello.txt Message appended Reading file: /hello.txt Read from file: Hello World! Deleting file: /foo.txt File deleted Renaming file /hello.txt to /foo.txt File renamed Reading file: /foo.txt Read from file: Hello World! 1048576 bytes read for 3219 ms 1048576 bytes written for 5442 ms
SDカードのルートディレクトリにFOO.TXT、TEST.TXTというファイルが生成され、FOO.TXTの中にHello World!と書いてあれば成功だと思います。
以上!
ESP32 (ESP-WROOM-32)でMPU6050を使おう!(i2C) (Arduino IDE)
ESP32弄り日記第二弾は、安くて有名なInvenSense製6軸センサ、MPU6050を使おう!です。
MPU6050には3軸加速度センサー、3軸ジャイロセンサーが積んであります。3+3=6軸センサーというわけです。
ESP32とMPU6050を用いて、角度計を作ってみましょう。
今回もArduino IDEを使って開発していきます。
私が使用したのは以下のモジュールです。
これでOKです。(めちゃくちゃ安い。ありがたい。)
まず配線ですが、ESP32は以前書いたように、SCL、SDAピンを対応している中から自由に選べます。
今回はSCLピンをGPIO25、SDAピンをGPIO26にしました。
するとブレッドボードはこんな具合になります。
いやぁ、、、わちゃわちゃしてるなぁ、、、
スケッチはこんな感じです。
(一応断っておきますが、私は素人です…こんな書き方はヤメロぉ!とかありましたらご指摘ください…)
#include <Wire.h> #define MPU6050_ADDR 0x68 // MPU-6050 device address #define MPU6050_SMPLRT_DIV 0x19 // MPU-6050 register address #define MPU6050_CONFIG 0x1a #define MPU6050_GYRO_CONFIG 0x1b #define MPU6050_ACCEL_CONFIG 0x1c #define MPU6050_WHO_AM_I 0x75 #define MPU6050_PWR_MGMT_1 0x6b double offsetX = 0, offsetY = 0, offsetZ = 0; double gyro_angle_x = 0, gyro_angle_y = 0, gyro_angle_z = 0; float angleX, angleY, angleZ; float interval, preInterval; float acc_x, acc_y, acc_z, acc_angle_x, acc_angle_y; float gx, gy, gz, dpsX, dpsY, dpsZ; void culcRotation(); //I2c書き込み void writeMPU6050(byte reg, byte data) { Wire.beginTransmission(MPU6050_ADDR); Wire.write(reg); Wire.write(data); Wire.endTransmission(); } //i2C読み込み byte readMPU6050(byte reg) { Wire.beginTransmission(MPU6050_ADDR); Wire.write(reg); Wire.endTransmission(true); Wire.requestFrom(MPU6050_ADDR, 1/*length*/); byte data = Wire.read(); return data; } void setup() { Wire.begin(26, 25); Wire.beginTransmission(MPU6050_ADDR); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); Serial.begin(9600); delay(100); //正常に接続されているかの確認 if (readMPU6050(MPU6050_WHO_AM_I) != 0x68) { Serial.println("\nWHO_AM_I error."); while (true) ; } //設定を書き込む writeMPU6050(MPU6050_SMPLRT_DIV, 0x00); // sample rate: 8kHz/(7+1) = 1kHz writeMPU6050(MPU6050_CONFIG, 0x00); // disable DLPF, gyro output rate = 8kHz writeMPU6050(MPU6050_GYRO_CONFIG, 0x08); // gyro range: ±500dps writeMPU6050(MPU6050_ACCEL_CONFIG, 0x00); // accel range: ±2g writeMPU6050(MPU6050_PWR_MGMT_1, 0x01); // disable sleep mode, PLL with X gyro //キャリブレーション Serial.print("Calculate Calibration"); for(int i = 0; i < 3000; i++){ int16_t raw_acc_x, raw_acc_y, raw_acc_z, raw_t, raw_gyro_x, raw_gyro_y, raw_gyro_z ; Wire.beginTransmission(MPU6050_ADDR); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU6050_ADDR, 14, true); raw_acc_x = Wire.read() << 8 | Wire.read(); raw_acc_y = Wire.read() << 8 | Wire.read(); raw_acc_z = Wire.read() << 8 | Wire.read(); raw_t = Wire.read() << 8 | Wire.read(); raw_gyro_x = Wire.read() << 8 | Wire.read(); raw_gyro_y = Wire.read() << 8 | Wire.read(); raw_gyro_z = Wire.read() << 8 | Wire.read(); dpsX = ((float)raw_gyro_x) / 65.5; dpsY = ((float)raw_gyro_y) / 65.5; dpsZ = ((float)raw_gyro_z) / 65.5; offsetX += dpsX; offsetY += dpsY; offsetZ += dpsZ; if(i % 1000 == 0){ Serial.print("."); } } Serial.println(); offsetX /= 3000; offsetY /= 3000; offsetZ /= 3000; Serial.print("offsetX : "); Serial.println(offsetX); Serial.print("offsetY : "); Serial.println(offsetY); Serial.print("offsetZ : "); Serial.println(offsetZ); } void loop() { calcRotation(); Serial.print("angleX : "); Serial.print(angleX); Serial.print(" angleY : "); Serial.print(angleY); Serial.print(" angleZ : "); Serial.println(angleZ); } //加速度、ジャイロから角度を計算 void calcRotation(){ int16_t raw_acc_x, raw_acc_y, raw_acc_z, raw_t, raw_gyro_x, raw_gyro_y, raw_gyro_z ; //レジスタアドレス0x3Bから、計14バイト分のデータを出力するようMPU6050へ指示 Wire.beginTransmission(MPU6050_ADDR); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU6050_ADDR, 14, true); //出力されたデータを読み込み、ビットシフト演算 raw_acc_x = Wire.read() << 8 | Wire.read(); raw_acc_y = Wire.read() << 8 | Wire.read(); raw_acc_z = Wire.read() << 8 | Wire.read(); raw_t = Wire.read() << 8 | Wire.read(); raw_gyro_x = Wire.read() << 8 | Wire.read(); raw_gyro_y = Wire.read() << 8 | Wire.read(); raw_gyro_z = Wire.read() << 8 | Wire.read(); //単位Gへ変換 acc_x = ((float)raw_acc_x) / 16384.0; acc_y = ((float)raw_acc_y) / 16384.0; acc_z = ((float)raw_acc_z) / 16384.0; //加速度センサーから角度を算出 acc_angle_y = atan2(acc_x, acc_z + abs(acc_y)) * 360 / -2.0 / PI; acc_angle_x = atan2(acc_y, acc_z + abs(acc_x)) * 360 / 2.0 / PI; dpsX = ((float)raw_gyro_x) / 65.5; // LSB sensitivity: 65.5 LSB/dps @ ±500dps dpsY = ((float)raw_gyro_y) / 65.5; dpsZ = ((float)raw_gyro_z) / 65.5; //前回計算した時から今までの経過時間を算出 interval = millis() - preInterval; preInterval = millis(); //数値積分 gyro_angle_x += (dpsX - offsetX) * (interval * 0.001); gyro_angle_y += (dpsY - offsetY) * (interval * 0.001); gyro_angle_z += (dpsZ - offsetZ) * (interval * 0.001); //相補フィルター angleX = (0.996 * gyro_angle_x) + (0.004 * acc_angle_x); angleY = (0.996 * gyro_angle_y) + (0.004 * acc_angle_y); angleZ = gyro_angle_z; gyro_angle_x = angleX; gyro_angle_y = angleY; gyro_angle_z = angleZ; }
まず最初のsetup()内のfor文ですが、これでジャイロセンサーのドリフト誤差を抑える為の計算をしています。
ドリフト誤差とはなんぞ?という方のために…
ジャイロセンサとは、つまりは角速度センサなのであります。角速度から角度を得るには…そう、積分ですよね!
プログラム内では、毎回毎回ジャイロセンサからの出力値と時間(秒)を掛け合わせたものを足していき、それが出力する角度としています。
理想的なジャイロセンサならば静止状態の時の出力値はゼロなのですが、世の中そうは行きません。普通は、静止状態でも常にゼロ以外の小さな値を出力し続けてしまいます。
放っておくと、どうなるでしょうか。
イエス、どんどん角度が増えて(減って)いってしまう!!!
これをドリフト誤差といいます。
それを防ぐために、静止状態で出力し続ける値を1000回位読み取って平均値を取り、その値を積分時に生の値から引いているのです。
さて次は、一番下の関数calcRotation()に注目してください。
その一部分
raw_acc_x = Wire.read() << 8 | Wire.read(); raw_acc_y = Wire.read() << 8 | Wire.read(); raw_acc_z = Wire.read() << 8 | Wire.read(); raw_t = Wire.read() << 8 | Wire.read(); raw_gyro_x = Wire.read() << 8 | Wire.read(); raw_gyro_y = Wire.read() << 8 | Wire.read(); raw_gyro_z = Wire.read() << 8 | Wire.read();
ここ、何だこれって思いませんか?私は思います。
MPU6050は、各センサの出力値を
x軸加速度、y軸加速度、z軸加速度、温度、x軸角速度、y軸角速度、z軸角速度
の順番に出力しますが、さらにその各データは上位8bit→下位8bitの順に出力されています。つまり計14個のデータですね。
そこで、上記の部分ではビットシフト演算を行い、正しい値へ変換しているのです。
そしてその下、「単位Gへ変換」という部分ですが、MPU6050は出力した加速度センサのデータを、16384で割ることで単位Gへ変換することが出来ます。
ただしこれは設定で変更することが出来ます。
ちゃっかりその設定を、最初のsetup()内で行っていました。
//設定を書き込む writeMPU6050(MPU6050_SMPLRT_DIV, 0x00); // sample rate: 8kHz/(7+1) = 1kHz writeMPU6050(MPU6050_CONFIG, 0x00); // disable DLPF, gyro output rate = 8kHz writeMPU6050(MPU6050_GYRO_CONFIG, 0x08); // gyro range: ±500dps writeMPU6050(MPU6050_ACCEL_CONFIG, 0x00); // accel range: ±2g writeMPU6050(MPU6050_PWR_MGMT_1, 0x01); // disable sleep mode, PLL with X gyro
ここです。(上から3,4行目)
今回は加速度センサは±2G、ジャイロセンサは±500dps(degree per second)まで計測できる設定にしています。
ここの設定によって、取得した生のデータから変換するための計算式が変わってくるのです。
詳しくはデータシートを見てネ!
その下
//加速度センサーから角度を算出 acc_angle_y = atan2(acc_x, acc_z + abs(acc_y)) * 360 / -2.0 / PI; acc_angle_x = atan2(acc_y, acc_z + abs(acc_x)) * 360 / 2.0 / PI;
こちらは書いてある通り、逆三角関数を用いて角度を計算しています。
選ぶ軸と正負には気をつけてね!!
dpsX = ((float)raw_gyro_x) / 65.5; // LSB sensitivity: 65.5 LSB/dps @ ±500dps dpsY = ((float)raw_gyro_y) / 65.5; dpsZ = ((float)raw_gyro_z) / 65.5;
ジャイロセンサーから取得した生のデータを、dps (degree per second)へ変換しています。加速度のときと同じですね。
//前回計算した時から今までの経過時間を算出 interval = millis() - preInterval; preInterval = millis(); gyro_angle_x += (dpsX - offsetX) * (interval * 0.001); gyro_angle_y += (dpsY - offsetY) * (interval * 0.001); gyro_angle_z += (dpsZ - offsetZ) * (interval * 0.001);
ここでは数値積分を行っています。最初に計算したoffset達がここで役立つわけなんです!
millis()は、ESP32の起動から今までの経過時間を単位ミリ秒で取得できます。interval * 0.001は、ミリ秒から秒へ変換しているわけです。
そして最後の
//相補フィルター angleX = (0.996 * gyro_angle_x) + (0.004 * acc_angle_x); angleY = (0.996 * gyro_angle_y) + (0.004 * acc_angle_y); angleZ = gyro_angle_z; gyro_angle_x = angleX; gyro_angle_y = angleY; gyro_angle_z = angleZ;
ここでは相補フィルターというものを使い、加速度センサーから求めた角度と、ジャイロセンサーから求めた角度を組み合わせています。
なぜそんなことをする必要があるのか、それは、互いの欠点を打ち消し合い、長所を活かしているのです。
まずジャイロセンサーには前述の通り、ドリフト誤差という欠点があります。一応このプログラムではそれを出来る限り抑えるようにしていますが、それでもやはりドリフトしてしまいます。
そして加速度センサーは、角度を加速度で求めているというのが欠点になります。なぜなら、静止状態なら良いのですが、対象が動く物体だったらどうでしょう。激しく動けば動くほど、あらゆる軸に加速度がかかり、角度がブレてしまうのです。
まとめると、
- ジャイロセンサーは長時間運用に弱いが、瞬間的ならばほぼ正確な値を出力する。
- 加速度センサーは長時間運用に強いが、瞬間的なもの(外力)には弱い
そこで
angleX = (0.996 * gyro_angle_x) + (0.004 * acc_angle_x); angleY = (0.996 * gyro_angle_y) + (0.004 * acc_angle_y);
この式なのです。
瞬間的にはジャイロセンサーの値を適用するが、ほぼ静止するとじわじわと加速度センサーの値へ近づいていくのがわかると思います。
これが相補フィルターなのです。(多分)
他にもNASAの?何かの?姿勢制御に使われた?カルマンフィルターなどがあるそうなのですが?、よくわかりませんでした。
こういったセンサーを組み合わせることを、センサフュージョンというらしいです。かっこいい!
説明は大体こんな感じでしょうか。
ちゃんと書き込めれば、こんな感じになると思います。
何か質問、ご指摘等ありましたら、気軽にコメントしてください!
以上!
ESP32 (ESP-WROOM-32)でi2C通信
2017/03/12追記:実際に使ってみました
先日、Arduinoの環境で開発できるということで、ESP32を購入しました。
私はATmega328(Arduino UNO)ではi2Cを頻繁に使用していたので、早速購入したESP32でもi2Cを使ってみました。
しかし、躓いた点があったので報告します。
Arduinoでi2C通信する際に欠かせないWireライブラリですが、最初に
Wire.begin();
を実行しますよね。
ATmegaではi2Cで使うSCL, SDAピンは固定されていますが、ESP32では対応している複数のピンの中から2つを選んで使うことができます。そのため、まず最初に使用するピンを指定しなければなりませんでした。
ESP32でWireライブラリを使う場合、SCL, SDAピンの指定は
int SDA = 25; int SCL = 26; Wire.begin(SDA, SCL);
のように、beginの引数にSDA、SCLの順にピンの番号を入れることで出来ます。
i2Cで使えるセンサーを使う時、データシートをみながらプログラムをコツコツ書かずに、誰かが作ったライブラリを用いることがあると思います。その場合にも、ライブラリ内のbegin()の部分を書き換える必要がありそうです。
以上!