Example #1
0
bool imu6ManufacturingTest(void)
{
  bool testStatus = false;
  Axis3f gyro; // Gyro axis data in deg/s
  Axis3f acc;  // Accelerometer axis data in mG
  float pitch, roll;
  uint32_t startTick = xTaskGetTickCount();

  testStatus = mpu6500SelfTest();

  if (testStatus)
  {
    while (xTaskGetTickCount() - startTick < IMU_VARIANCE_MAN_TEST_TIMEOUT)
    {
      imu6Read(&gyro, &acc);
      if (gyroBias.isBiasValueFound)
      {
        DEBUG_PRINT("Gyro variance test [OK]\n");
        break;
      }
    }

    if (gyroBias.isBiasValueFound)
    {
      // Calculate pitch and roll based on accelerometer. Board must be level
      pitch = tanf(-acc.x/(sqrtf(acc.y*acc.y + acc.z*acc.z))) * 180/(float) M_PI;
      roll = tanf(acc.y/acc.z) * 180/(float) M_PI;

      if ((fabsf(roll) < IMU_MAN_TEST_LEVEL_MAX) && (fabsf(pitch) < IMU_MAN_TEST_LEVEL_MAX))
      {
        DEBUG_PRINT("Acc level test [OK]\n");
        testStatus = true;
      }
      else
      {
        DEBUG_PRINT("Acc level test Roll:%0.2f, Pitch:%0.2f [FAIL]\n", roll, pitch);
        testStatus = false;
      }
    }
    else
    {
      DEBUG_PRINT("Gyro variance test [FAIL]\n");
      testStatus = false;
    }
  }

  return testStatus;
}
void imu9Read(Axis3f* gyroOut, Axis3f* accOut, Axis3f* magOut)
{
    imu6Read(gyroOut, accOut);

    if (isHmc5883lPresent)
    {
        hmc5883lGetHeading(&mag.x, &mag.y, &mag.z);
        magOut->x = (float)mag.x / MAG_GAUSS_PER_LSB;
        magOut->y = (float)mag.y / MAG_GAUSS_PER_LSB;
        magOut->z = (float)mag.z / MAG_GAUSS_PER_LSB;
    }
    else
    {
        magOut->x = 0.0;
        magOut->y = 0.0;
        magOut->z = 0.0;
    }
}
Example #3
0
void imu9Read(Axis3f* gyroOut, Axis3f* accOut, Axis3f* magOut)
{
  imu6Read(gyroOut, accOut);

  if (isHmc5883lPresent)
  {
    hmc5883lGetHeading(&mag.x, &mag.y, &mag.z);
    magOut->x = (fix_t)mag.x * (1.0k / MAG_GAUSS_PER_LSB);
    magOut->y = (fix_t)mag.y * (1.0k / MAG_GAUSS_PER_LSB);
    magOut->z = (fix_t)mag.z * (1.0k / MAG_GAUSS_PER_LSB);
  }
  else
  {
    magOut->x = 0.0k;
    magOut->y = 0.0k;
    magOut->z = 0.0k;
  }
}
Example #4
0
void imu9Read(Axis3f* gyroOut, Axis3f* accOut, Axis3f* magOut)
{
  imu6Read(gyroOut, accOut);

  if (isMagPresent)
  {
    ak8963GetHeading(&mag.x, &mag.y, &mag.z);
    ak8963GetOverflowStatus();
    magOut->x = (float)mag.x / MAG_GAUSS_PER_LSB;
    magOut->y = (float)mag.y / MAG_GAUSS_PER_LSB;
    magOut->z = (float)mag.z / MAG_GAUSS_PER_LSB;
  }
  else
  {
    magOut->x = 0.0;
    magOut->y = 0.0;
    magOut->z = 0.0;
  }
}
static void stabilizerTask(void* param)
{
  uint32_t attitudeCounter = 0;
  uint32_t altHoldCounter = 0;
  uint32_t lastWakeTime;

  vTaskSetApplicationTaskTag(0, (void*)TASK_STABILIZER_ID_NBR);

  //Wait for the system to be fully started to start stabilization loop
  systemWaitStart();

  lastWakeTime = xTaskGetTickCount ();

  while(1)
  {
    vTaskDelayUntil(&lastWakeTime, F2T(IMU_UPDATE_FREQ)); // 500Hz

    imu6Read(&gyro, &acc);
    hmc5883lGetHeading(&heading.x, &heading.y, &heading.z);

    if (imu6IsCalibrated())
    {
      commanderGetRPY(&eulerRollDesired, &eulerPitchDesired, &eulerYawDesired);
      commanderGetRPYType(&rollType, &pitchType, &yawType);

      // 250HZ
      if (++attitudeCounter >= ATTITUDE_UPDATE_RATE_DIVIDER)
      {
        sensfusion6UpdateQ(gyro.x, gyro.y, gyro.z, acc.x, acc.y, acc.z, FUSION_UPDATE_DT);
        sensfusion6GetEulerRPY(&eulerRollActual, &eulerPitchActual, &eulerYawActual);

        accWZ = sensfusion6GetAccZWithoutGravity(acc.x, acc.y, acc.z);
        // Estimate speed from acc (drifts)
        vSpeed += deadband(accWZ, vAccDeadband) * FUSION_UPDATE_DT;

        controllerCorrectAttitudePID(eulerRollActual, eulerPitchActual, eulerYawActual,
                                     eulerRollDesired, eulerPitchDesired, -eulerYawDesired,
                                     &rollRateDesired, &pitchRateDesired, &yawRateDesired);
        attitudeCounter = 0;
      }

      // 100HZ
      if (imuHasBarometer() && (++altHoldCounter >= HOVER_UPDATE_RATE_DIVIDER))
      {
        stabilizerAltHoldUpdate();
        altHoldCounter = 0;
      }

      if (rollType == RATE)
      {
        rollRateDesired = eulerRollDesired;
      }
      if (pitchType == RATE)
      {
        pitchRateDesired = eulerPitchDesired;
      }
      if (yawType == RATE)
      {
        yawRateDesired = -eulerYawDesired;
      }

      // TODO: Investigate possibility to subtract gyro drift.
      controllerCorrectRatePID(gyro.x, -gyro.y, gyro.z,
                               rollRateDesired, pitchRateDesired, yawRateDesired);

      controllerGetActuatorOutput(&actuatorRoll, &actuatorPitch, &actuatorYaw);

      if (!altHold || !imuHasBarometer())
      {
        // Use thrust from controller if not in altitude hold mode
        commanderGetThrust(&actuatorThrust);
      }
      else
      {
        // Added so thrust can be set to 0 while in altitude hold mode after disconnect
        commanderWatchdog();
      }

      if (actuatorThrust > 0)
      {
#if defined(TUNE_ROLL)
        distributePower(actuatorThrust, actuatorRoll, 0, 0);
#elif defined(TUNE_PITCH)
        distributePower(actuatorThrust, 0, actuatorPitch, 0);
#elif defined(TUNE_YAW)
        distributePower(actuatorThrust, 0, 0, -actuatorYaw);
#else
        distributePower(actuatorThrust, actuatorRoll, actuatorPitch, -actuatorYaw);
#endif
      }
      else
      {
        distributePower(0, 0, 0, 0);
        controllerResetAllPID();
      }
    }
  }
}
bool sensorsAreCalibrated()
{
  Axis3f dummyData;
  imu6Read(&dummyData, &dummyData);
  return imu6IsCalibrated();
}
static void stabilizerTask(void* param)
{
  uint32_t attitudeCounter = 0;
  uint32_t lastWakeTime;

  vTaskSetApplicationTaskTag(0, (void*)TASK_STABILIZER_ID_NBR);

  //Wait for the system to be fully started to start stabilization loop
  systemWaitStart();

  lastWakeTime = xTaskGetTickCount ();

  while(1)
  {
    vTaskDelayUntil(&lastWakeTime, F2T(IMU_UPDATE_FREQ));

    imu6Read(&gyro, &acc);

    hmc5883lGetHeading(&magHeadingX, &magHeadingY, &magHeadingZ);

    if(altMode == ALTIMETER_MODE_PRESSURE) {
        altimeterTmp = ms5611GetPressure(MS5611_OSR_4096);
        if(altimeterTmp > 0.0f) {
            pressure = altimeterTmp;
            altMode = ALTIMETER_MODE_TEMPERATURE;
        }
    }

    if(altMode == ALTIMETER_MODE_TEMPERATURE) {
    	altimeterTmp = ms5611GetTemperature(MS5611_OSR_4096);
    	if(altimeterTmp > 0.0f) {
    		temperature = altimeterTmp;
    		altMode = ALTIMETER_MODE_PRESSURE;
    	}
    }

    if (imu6IsCalibrated())
    {
      commanderGetRPY(&eulerRollDesired, &eulerPitchDesired, &eulerYawDesired);
      commanderGetRPYType(&rollType, &pitchType, &yawType);

      if (++attitudeCounter >= ATTITUDE_UPDATE_RATE_DIVIDER)
      {
        //sensfusion6UpdateQ(gyro.x, gyro.y, gyro.z, acc.x, acc.y, acc.z, FUSION_UPDATE_DT);
        //sensfusion6GetEulerRPY(&eulerRollActual, &eulerPitchActual, &eulerYawActual);

        //controllerCorrectAttitudePID(eulerRollActual, eulerPitchActual, eulerYawActual,
        //                             eulerRollDesired, eulerPitchDesired, -eulerYawDesired,
        //                             &rollRateDesired, &pitchRateDesired, &yawRateDesired);
    	//controllerCorrectAttitudePID(0, 0, 0, 0, 0, 0, &rollRateDesired, &pitchRateDesired, &yawRateDesired);
        attitudeCounter = 0;
      }

      if (rollType == RATE)
      {
        rollRateDesired = eulerRollDesired;
      }
      if (pitchType == RATE)
      {
        pitchRateDesired = eulerPitchDesired;
      }
      if (yawType == RATE)
      {
        yawRateDesired = -eulerYawDesired;
      }

      	  /*
      // TODO: Investigate possibility to subtract gyro drift.
      controllerCorrectRatePID(gyro.x, -gyro.y, gyro.z,
                               rollRateDesired, pitchRateDesired, yawRateDesired);

      controllerGetActuatorOutput(&actuatorRoll, &actuatorPitch, &actuatorYaw);
	*/
      commanderGetTrust(&actuatorThrust);
      distributePower(actuatorThrust, 0, 0, 0);

      if (actuatorThrust > 0)
      {
#if defined(TUNE_ROLL)
        distributePower(actuatorThrust, actuatorRoll, 0, 0);
#elif defined(TUNE_PITCH)
        distributePower(actuatorThrust, 0, actuatorPitch, 0);
#elif defined(TUNE_YAW)
        distributePower(actuatorThrust, 0, 0, -actuatorYaw);
#else
        distributePower(actuatorThrust, actuatorRoll, actuatorPitch, -actuatorYaw);
#endif
      }
      else
      {
        distributePower(0, 0, 0, 0);
        controllerResetAllPID();
      }
#if 0
     static int i = 0;
      if (++i > 19)
      {
        uartPrintf("%i, %i, %i\n",
            (int32_t)(eulerRollActual*100),
            (int32_t)(eulerPitchActual*100),
            (int32_t)(eulerYawActual*100));
        i = 0;
      }
#endif
    }
  }
}