2016年3月8日 星期二
MPU6060 的研究筆記2
initilize 來看
quadcopter dmp.cpp的程式如下:
void DMP::set_com() {
// initialize device
printf("Initializing I2C devices...\n");
mpu.initialize();
// verify connection
printf("Testing device connections...\n");
printf(mpu.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n");
// load and configure the DMP
printf("Initializing DMP...\n");
devStatus = mpu.dmpInitialize();
// make sure it worked (returns 0 if so)
if (devStatus == 0) {
// turn on the DMP, now that it's ready
printf("Enabling DMP...\n");
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
//Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
//attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
printf("DMP ready!\n");
dmpReady = true;
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
// ERROR!
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
printf("DMP Initialization failed (code %d)\n", devStatus);
}
}
void DMP::initialize(){
if (!dmpReady) return;
printf("Initializing IMU...\n");
// 看起來是讓他 run 個 3500 ...等待 機子平穩
for (int n=1;n<3500;n++) {
// wait for FIFO count > 42 bits
do {
fifoCount = mpu.getFIFOCount();
}while (fifoCount<42);
if (fifoCount >= 1024) {
// reset so we can continue cleanly
mpu.resetFIFO();
printf("FIFO overflow!\n");
// otherwise, check for DMP data ready interrupt
//(this should happen frequently)
} else {
//read packet from fifo
mpu.getFIFOBytes(fifoBuffer, packetSize);
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
// printf("yaw = %f, pitch = %f, roll = %f\n",
// ypr[YAW]*180/M_PI, ypr[PITCH]*180/M_PI,
// ypr[ROLL]*180/M_PI);
}
}
// 重點是這個....把初始化的 ypr存起來....
for (int i=0;i<DIM;i++) m_ypr_off[i] = ypr[i];
printf("IMU init done; offset values are :\n");
printf("yaw = %f, pitch = %f, roll = %f\n\n",
ypr[YAW]*180/M_PI, ypr[PITCH]*180/M_PI,
ypr[ROLL]*180/M_PI);
initialized = true;
}
從 piBit來看
printf("Initializing I2C devices...\n");
mpu.initialize();
// verify connection
printf("Testing device connections...\n");
printf(mpu.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n");
// load and configure the DMP
printf("Initializing DMP...\n");
devStatus = mpu.dmpInitialize();
if (devStatus == 0) { // 代表有連線
// turn on the DMP, now that it's ready
printf("Enabling DMP...\n");
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
//Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
//attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
printf("DMP ready!\n");
dmpReady = true;
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
// ERROR!
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
printf("DMP Initialization failed (code %d)\n", devStatus);
}
getdata來看
從quqdcopter 的dmp.cpp 來看...
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
ypr[0]-=m_ypr_off[0]; // 假設你的飛機是水平....所以 roll 和 pitch 幾乎為零...只需要校正YAW
// 轉換成 度數....原本是弧度....
//scaling for degrees output
for (int i=0;i<DIM;i++){
//no offset removal
//should be accounted while triming
//ypr[i]-=m_ypr_off[i];
ypr[i]*=180/M_PI;
}
//unwrap yaw when it reaches 180
ypr[0] = wrap_180(ypr[0]);
//change sign of Pitch, MPU is attached upside down
ypr[1]*=-1.0; //
然後 wrap_180 的定義如下:
#define wrap_180(x) (x < -180 ? x+360 : (x > 180 ? x - 360: x))
確保x 的值永遠在 0 到 180度之間....
然後從 https://github.com/richardghirst/PiBits/tree/master/MPU6050-Pi-Demo
來看.... 發覺他做好很多模組.... 看起來 dmp.cpp 是使用 OUTPUT_READABLE_YAWPITCHROLL 這個定義....
#ifdef OUTPUT_READABLE_QUATERNION
// display quaternion values in easy matrix form: w x y z
mpu.dmpGetQuaternion(&q, fifoBuffer);
printf("quat %7.2f %7.2f %7.2f %7.2f ", q.w,q.x,q.y,q.z);
#endif
#ifdef OUTPUT_READABLE_EULER
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetEuler(euler, &q);
printf("euler %7.2f %7.2f %7.2f ", euler[0] * 180/M_PI, euler[1] * 180/M_PI, euler[2] * 180/M_PI);
#endif
#ifdef OUTPUT_READABLE_YAWPITCHROLL
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
printf("ypr %7.2f %7.2f %7.2f ", ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI);
#endif
#ifdef OUTPUT_READABLE_REALACCEL
// display real acceleration, adjusted to remove gravity
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetAccel(&aa, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
printf("areal %6d %6d %6d ", aaReal.x, aaReal.y, aaReal.z);
#endif
#ifdef OUTPUT_READABLE_WORLDACCEL
// display initial world-frame acceleration, adjusted to remove gravity
// and rotated based on known orientation from quaternion
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetAccel(&aa, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
printf("aworld %6d %6d %6d ", aaWorld.x, aaWorld.y, aaWorld.z);
#endif
#ifdef OUTPUT_TEAPOT
// display quaternion values in InvenSense Teapot demo format:
teapotPacket[2] = fifoBuffer[0];
teapotPacket[3] = fifoBuffer[1];
teapotPacket[4] = fifoBuffer[4];
teapotPacket[5] = fifoBuffer[5];
teapotPacket[6] = fifoBuffer[8];
teapotPacket[7] = fifoBuffer[9];
teapotPacket[8] = fifoBuffer[12];
teapotPacket[9] = fifoBuffer[13];
Serial.write(teapotPacket, 14);
teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
#endif
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言