はじめまして。E班の主に走行のプログラムを担当していたものです。ほかにも加速度センサの担当ももらっていたのですが仕様変更によりなくなってしまいました。今回はあまりにもうまくいかずに途中で仕様変更された加速度センサについて話していきたいと思います。
最初に、何に加速度センサを使うつもりだったか説明します。主に使う用途はその時その時の加速度を積分して足して速度にし、早すぎれば減速し、遅すぎれば加速するなど速度の調整に使う予定でした。
次に、詰まった部分について話していきます。結果から言うと動いていなくても速度が出て足されていくことでした。下のデータは加速度センサが送ってくる生データですが見ての通り静止していても一定ではなかったです。
こうなってしまっては自分には打つ手がなかったです。考えてみれば重力がかかっている以上傾いたり、小石を踏んだりした時も大きく数値が変わるのではと考えれば考えるほどどうすればいいかわからなくなっていきました。最終的には最初に10個分のデータを取り、それの平均値をそれぞれ常に生データから引くという力技で解決しようとしました。それでも動かしていなくても秒速0.0xmぐらいの誤差が出続けました。これは使い物にならないと思いギブアップしました。代行案として、実際に動かしたデータをもとに出力を決めることで速度の調整をすることになりました。
今にして思えば、自転車や自動車のようにタイヤに磁石をつけ磁気センサでタイヤが一周回った回数と時間で速度を出すやり方のほうがよかったなと思います。これを両サイドに使えばより精度の高い方向転換もできたと思っています。こうしてみると商品にされているものの完成度が高く、身近にある類似するものを参考にしていけば前よりももっといいものができたのにと今は反省しています。でも言い訳させてください。
私は電気工作初心者ですから!!!!!!!!!!
そんな柔軟に考えることなどできなかったです。道案内のプログラムの時も思ったのですがハードル高くない?道案内の最後の地点が定めていた目的地と最大で5~15mほどずれていましたがGPSの出す誤差なんてどうしようもないのでは?とか思っていました。解決策としてカーマンフィルターがあがりましたが、何それあてぃし知らない(/ω\)、それってプログラム習って6カ月で、残りの期間1カ月ちょっとでできりゅ?( ;∀;)
今回のCanSat講習で基礎的なことを学ぶことができたと思っています。これらを忘れずこれからの活動にも生かしていきたいです。最後に、私が書いたプログラムを載せておきますが、先ほどもありますが私はプログラムを書くのも電子工作するのも初心者であり、プログラムがきれいなものではないのをご了承ください。興味がある人以外は読まなくても結構です。
下のプログラムは直進以外の集計を行っていません。
#include "mbed.h"
#include "MPU6050.h"
//今回は統合できないので、変数を代入する(できるなら、最初からmpu6050(before)と連携する)
MPU6050 mpu(D4, D5);
int main(){
//下の平均値と倍率はプログラミング1で測った後で入れています。今考えたら、二つ混ぜてもいいかも。
double heikinX = 1292;
double heikinY = -482;
double heikinZ = 15894;
double bairitu = 1626.8255;
double X1;
double Y1;
double Z1;
float timespan = 0.1;
int k = 5;
int l = 0;
double oldAccelX;
double oldAccelY;
double oldAccelZ;
double speedX;
double speedY;
double speedZ;
double speed;
double oldSpeed;
while(k == 5){
if(l < 10){
int accel[3]; mpu.readAccelData(accel);
X1 = (accel[0] - heikinX) / bairitu;
Y1 = (accel[1] - heikinY) / bairitu;
Z1 = (accel[2] - heikinZ) / bairitu;
//傾きからsin、cosで運動方向を出す。できたら
speedY = ((Y1 + oldAccelY) * timespan) / 2 +speedY;
oldAccelY = Y1; oldSpeed = speedY;
l++;
wait(0.1);
}
else if(l >= 10){
int accel[3];
mpu.readAccelData(accel);
X1 = (accel[0] - heikinX) / bairitu;
Y1 = (accel[1] - heikinY) / bairitu;
Z1 = (accel[2] - heikinZ) / bairitu;
//傾きからsin、cosで運動方向を出す。できたら
speedY = ((Y1 + oldAccelY) * timespan) / 2 +speedY;
printf("現在の速度\r\n");
printf("%f\r\n", speedY);
oldAccelY = Y1; oldSpeed = speedY;
l = l - 9;
wait(0.1);
}
}
}
