void processFlightCommands(void) { uint8_t channel; uint8_t channelsToRead = 8; float hdgDelta, simpleX, simpleY; if ( rcActive == true ) { // Read receiver commands if (eepromConfig.receiverType == PPM) channelsToRead = eepromConfig.ppmChannels; for (channel = 0; channel < channelsToRead; channel++) { if (eepromConfig.receiverType == SPEKTRUM) rxCommand[channel] = spektrumRead(eepromConfig.rcMap[channel]); else if (eepromConfig.receiverType == SBUS) rxCommand[channel] = sBusRead(eepromConfig.rcMap[channel]); else rxCommand[channel] = rxRead(eepromConfig.rcMap[channel]); } rxCommand[ROLL] -= eepromConfig.midCommand; // Roll Range -1000:1000 rxCommand[PITCH] -= eepromConfig.midCommand; // Pitch Range -1000:1000 rxCommand[YAW] -= eepromConfig.midCommand; // Yaw Range -1000:1000 for (channel = 3; channel < channelsToRead; channel++) rxCommand[channel] -= eepromConfig.midCommand - MIDCOMMAND; // Range 2000:4000 } // Set past command in detent values for (channel = 0; channel < 3; channel++) previousCommandInDetent[channel] = commandInDetent[channel]; // Apply deadbands and set detent discretes' for (channel = 0; channel < 3; channel++) { if ((rxCommand[channel] <= DEADBAND) && (rxCommand[channel] >= -DEADBAND)) { rxCommand[channel] = 0; commandInDetent[channel] = true; } else { commandInDetent[channel] = false; if (rxCommand[channel] > 0) { rxCommand[channel] = (rxCommand[channel] - DEADBAND) * DEADBAND_SLOPE; } else { rxCommand[channel] = (rxCommand[channel] + DEADBAND) * DEADBAND_SLOPE; } } } /////////////////////////////////// // Check for low throttle if ( rxCommand[THROTTLE] < eepromConfig.minCheck ) { // Check for disarm command ( low throttle, left yaw ) if ( (rxCommand[YAW] < (eepromConfig.minCheck - MIDCOMMAND)) && (armed == true) ) { disarmingTimer++; if (disarmingTimer > eepromConfig.disarmCount) { zeroPIDstates(); armed = false; disarmingTimer = 0; } } else { disarmingTimer = 0; } // Check for gyro bias command ( low throttle, left yaw, aft pitch, right roll ) if ( (rxCommand[YAW ] < (eepromConfig.minCheck - MIDCOMMAND)) && (rxCommand[ROLL ] > (eepromConfig.maxCheck - MIDCOMMAND)) && (rxCommand[PITCH] < (eepromConfig.minCheck - MIDCOMMAND)) ) { computeMPU6000RTData(); pulseMotors(3); } // Check for arm command ( low throttle, right yaw) if ((rxCommand[YAW] > (eepromConfig.maxCheck - MIDCOMMAND) ) && (armed == false) && (execUp == true)) { armingTimer++; if (armingTimer > eepromConfig.armCount) { zeroPIDstates(); armed = true; armingTimer = 0; } } else { armingTimer = 0; } } /////////////////////////////////// // Check for armed true and throttle command > minThrottle if ((armed == true) && (rxCommand[THROTTLE] > eepromConfig.minThrottle)) pidReset = false; else pidReset = true; /////////////////////////////////// // Check yaw in detent and flight mode to determine hdg hold engaged state if ((commandInDetent[YAW] == true) && (flightMode == ATTITUDE) && (headingHoldEngaged == false)) { headingHoldEngaged = true; setPIDstates(HEADING_PID, 0.0f); setPIDstates(YAW_RATE_PID, 0.0f); headingReference = heading.mag; } if (((commandInDetent[YAW] == false) || (flightMode != ATTITUDE)) && (headingHoldEngaged == true)) { headingHoldEngaged = false; } /////////////////////////////////// // Vertical Mode Command Processing verticalReferenceCommand = rxCommand[THROTTLE] - eepromConfig.midCommand; // Set past altitude reference in detent value previousVertRefCmdInDetent = vertRefCmdInDetent; // Apply deadband and set detent discrete' if ((verticalReferenceCommand <= ALT_DEADBAND) && (verticalReferenceCommand >= -ALT_DEADBAND)) { verticalReferenceCommand = 0; vertRefCmdInDetent = true; } else { vertRefCmdInDetent = false; if (verticalReferenceCommand > 0) { verticalReferenceCommand = (verticalReferenceCommand - ALT_DEADBAND) * ALT_DEADBAND_SLOPE; } else { verticalReferenceCommand = (verticalReferenceCommand + ALT_DEADBAND) * ALT_DEADBAND_SLOPE; } } /////////////////////////////////////////////// // Need to have AUX channels update modes // based on change, to allow for both external // remote commanding from serial port and with // transmitter switches // // Conditions --------------------------------- // A switch can actuate multiple modes // Mode enables are defined by channel ranges // A mode is only enabled/disabled when a // channel range changes, this allows remote // commands via serial to be sent /////////////////////////////////////////////// // Search through each AUX channel int ch; for (ch=AUX1; ch<LASTCHANNEL; ch++) { // Only make update if channel value changed if (fabs(previousRxCommand[ch] - rxCommand[ch]) > CHANGE_RANGE) { // Search through each mode slot int slot; for (slot=1; slot < MODE_SLOTS; slot++) { // If mode slot uses current rx channel, update if mode is on/off if (eepromConfig.mode[slot].channel == ch) { // Only change the mode state if the rx channels are in range int chValue = constrain(rxCommand[ch]/2, 1000, 2000); if ((chValue >= eepromConfig.mode[slot].minChannelValue) && (chValue <= eepromConfig.mode[slot].maxChannelValue)) { switch(eepromConfig.mode[slot].modeType) { case MODE_NONE: flightMode = ATTITUDE; verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; autoNavMode = MODE_NONE; break; case MODE_ATTITUDE: autoNavMode = MODE_NONE; if (eepromConfig.mode[slot].state) { flightMode = ATTITUDE; setPIDstates(ROLL_ATT_PID, 0.0f); setPIDstates(PITCH_ATT_PID, 0.0f); setPIDstates(HEADING_PID, 0.0f); } else { // if OFF and no other mode set, default to rate mode flightMode = RATE; setPIDstates(ROLL_RATE_PID, 0.0f); setPIDstates(PITCH_RATE_PID, 0.0f); setPIDstates(YAW_RATE_PID, 0.0f); } break; case MODE_RATE: autoNavMode = MODE_NONE; if (eepromConfig.mode[slot].state) { flightMode = RATE; setPIDstates(ROLL_RATE_PID, 0.0f); setPIDstates(PITCH_RATE_PID, 0.0f); setPIDstates(YAW_RATE_PID, 0.0f); } else { // if OFF and no other mode set, default to attitude mode flightMode = ATTITUDE; setPIDstates(ROLL_ATT_PID, 0.0f); setPIDstates(PITCH_ATT_PID, 0.0f); setPIDstates(HEADING_PID, 0.0f); } break; case MODE_SIMPLE: autoNavMode = MODE_NONE; if (eepromConfig.mode[slot].state) { flightMode = MODE_SIMPLE; hdgDelta = sensors.attitude500Hz[YAW] - homeData.magHeading; hdgDelta = standardRadianFormat(hdgDelta); simpleX = cosf(hdgDelta) * rxCommand[PITCH] + sinf(hdgDelta) * rxCommand[ROLL ]; simpleY = cosf(hdgDelta) * rxCommand[ROLL ] - sinf(hdgDelta) * rxCommand[PITCH]; rxCommand[ROLL ] = simpleY; rxCommand[PITCH] = simpleX; } else { // if OFF and no other mode set, default to attitude mode flightMode = ATTITUDE; setPIDstates(ROLL_ATT_PID, 0.0f); setPIDstates(PITCH_ATT_PID, 0.0f); setPIDstates(HEADING_PID, 0.0f); } break; case MODE_AUTONAV: if (eepromConfig.mode[slot].state) { flightMode = ATTITUDE; //verticalModeState = ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT; autoNavMode = MODE_AUTONAV; setAutoNavState(AUTONAV_ENABLED); } else { flightMode = ATTITUDE; //verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; autoNavMode = MODE_NONE; setAutoNavState(AUTONAV_DISABLED); } break; case MODE_POSITIONHOLD: if (eepromConfig.mode[slot].state) { flightMode = ATTITUDE; //verticalModeState = ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT; autoNavMode = MODE_POSITIONHOLD; } else { flightMode = ATTITUDE; //verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; autoNavMode = MODE_NONE; } break; case MODE_RETURNTOHOME: if (eepromConfig.mode[slot].state) { flightMode = ATTITUDE; //verticalModeState = ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT; autoNavMode = MODE_RETURNTOHOME; } else { flightMode = ATTITUDE; //verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; autoNavMode = MODE_NONE; } break; case MODE_ALTHOLD: if (eepromConfig.mode[slot].state) { if (verticalModeState == ALT_DISENGAGED_THROTTLE_ACTIVE) { verticalModeState = ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT; setPIDstates(HDOT_PID, 0.0f); setPIDstates(H_PID, 0.0f); altitudeHoldReference = hEstimate; throttleReference = rxCommand[THROTTLE]; } else if (verticalModeState == ALT_DISENGAGED_THROTTLE_INACTIVE) verticalModeState = ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT; } else if (verticalModeState == VERTICAL_VELOCITY_HOLD_AT_REFERENCE_VELOCITY) { verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; altitudeHoldReference = hEstimate; } else verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; break; case MODE_PANIC: if (eepromConfig.mode[slot].state) { flightMode = ATTITUDE; verticalModeState = ALT_DISENGAGED_THROTTLE_ACTIVE; autoNavMode = MODE_PANIC; } break; } } } } } previousRxCommand[ch] = rxCommand[ch]; } /////////////////////////////////// // AutoNavigation State Machine switch (autoNavMode) { case MODE_NONE: autoNavPitchAxisCorrection = 0.0; autoNavRollAxisCorrection = 0.0; autoNavYawAxisCorrection = 0.0; break; case MODE_AUTONAV: processAutoNavigation(); break; case MODE_POSITIONHOLD: processPositionHold(); break; case MODE_RETURNTOHOME: processReturnToHome(); break; } /////////////////////////////////// // Vertical Mode State Machine switch (verticalModeState) { case ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT: if ((vertRefCmdInDetent == true) || eepromConfig.verticalVelocityHoldOnly) verticalModeState = ALT_HOLD_AT_REFERENCE_ALTITUDE; break; case ALT_DISENGAGED_THROTTLE_ACTIVE: break; case ALT_HOLD_AT_REFERENCE_ALTITUDE: if ((vertRefCmdInDetent == false) || eepromConfig.verticalVelocityHoldOnly) verticalModeState = VERTICAL_VELOCITY_HOLD_AT_REFERENCE_VELOCITY; break; case VERTICAL_VELOCITY_HOLD_AT_REFERENCE_VELOCITY: if ((vertRefCmdInDetent == true) && !eepromConfig.verticalVelocityHoldOnly) { verticalModeState = ALT_HOLD_AT_REFERENCE_ALTITUDE; altitudeHoldReference = hEstimate; } break; case ALT_DISENGAGED_THROTTLE_INACTIVE: // This mode verifies throttle is at center when disengaging alt hold if (((rxCommand[THROTTLE] < throttleCmd + THROTTLE_WINDOW) && (rxCommand[THROTTLE] > throttleCmd - THROTTLE_WINDOW)) || eepromConfig.verticalVelocityHoldOnly) verticalModeState = ALT_DISENGAGED_THROTTLE_ACTIVE; } }
void processFlightCommands(void) { uint8_t channel; if ( rcActive == true ) { // Read receiver commands for (channel = 0; channel < 8; channel++) rxCommand[channel] = (float)rxRead(eepromConfig.rcMap[channel]); rxCommand[ROLL] -= eepromConfig.midCommand; // Roll Range -1000:1000 rxCommand[PITCH] -= eepromConfig.midCommand; // Pitch Range -1000:1000 rxCommand[YAW] -= eepromConfig.midCommand; // Yaw Range -1000:1000 rxCommand[THROTTLE] -= eepromConfig.midCommand - MIDCOMMAND; // Throttle Range 2000:4000 rxCommand[AUX1] -= eepromConfig.midCommand - MIDCOMMAND; // Aux1 Range 2000:4000 rxCommand[AUX2] -= eepromConfig.midCommand - MIDCOMMAND; // Aux2 Range 2000:4000 rxCommand[AUX3] -= eepromConfig.midCommand - MIDCOMMAND; // Aux3 Range 2000:4000 rxCommand[AUX4] -= eepromConfig.midCommand - MIDCOMMAND; // Aux4 Range 2000:4000 } // Set past command in detent values for (channel = 0; channel < 3; channel++) previousCommandInDetent[channel] = commandInDetent[channel]; // Apply deadbands and set detent discretes' for (channel = 0; channel < 3; channel++) { if ((rxCommand[channel] <= DEADBAND) && (rxCommand[channel] >= -DEADBAND)) { rxCommand[channel] = 0; commandInDetent[channel] = true; } else { commandInDetent[channel] = false; if (rxCommand[channel] > 0) { rxCommand[channel] = (rxCommand[channel] - DEADBAND) * DEADBAND_SLOPE; } else { rxCommand[channel] = (rxCommand[channel] + DEADBAND) * DEADBAND_SLOPE; } } } /////////////////////////////////// // Check for low throttle if ( rxCommand[THROTTLE] < eepromConfig.minCheck ) { // Check for disarm command ( low throttle, left yaw ), will disarm immediately if ( (rxCommand[YAW] < (eepromConfig.minCheck - MIDCOMMAND)) && (armed == true) ) { armed = false; zeroPIDintegralError(); zeroPIDstates(); } // Check for gyro bias command ( low throttle, left yaw, aft pitch, right roll ) if ( (rxCommand[YAW ] < (eepromConfig.minCheck - MIDCOMMAND)) && (rxCommand[ROLL ] > (eepromConfig.maxCheck - MIDCOMMAND)) && (rxCommand[PITCH] < (eepromConfig.minCheck - MIDCOMMAND)) ) { computeMPU6000RTData(); pulseMotors(3); } // Check for arm command ( low throttle, right yaw), must be present for 1 sec before arming if ((rxCommand[YAW] > (eepromConfig.maxCheck - MIDCOMMAND) ) && (armed == false) && (execUp == true)) { armingTimer++; if ( armingTimer > 50 ) { zeroPIDintegralError(); zeroPIDstates(); armed = true; armingTimer = 0; } } else { armingTimer = 0; } } /////////////////////////////////// // Check for armed true and throttle command > minThrottle if ((armed == true) && (rxCommand[THROTTLE] > eepromConfig.minThrottle)) holdIntegrators = false; else holdIntegrators = true; /////////////////////////////////// // Check AUX1 for rate, attitude, or GPS mode (3 Position Switch) NOT COMPLETE YET.... if ((rxCommand[AUX1] > MIDCOMMAND) && (flightMode == RATE)) { flightMode = ATTITUDE; setPIDintegralError(ROLL_ATT_PID, 0.0f); setPIDintegralError(PITCH_ATT_PID, 0.0f); setPIDintegralError(HEADING_PID, 0.0f); setPIDstates(ROLL_ATT_PID, 0.0f); setPIDstates(PITCH_ATT_PID, 0.0f); setPIDstates(HEADING_PID, 0.0f); } else if ((rxCommand[AUX1] <= MIDCOMMAND) && (flightMode == ATTITUDE)) { flightMode = RATE; setPIDintegralError(ROLL_RATE_PID, 0.0f); setPIDintegralError(PITCH_RATE_PID, 0.0f); setPIDintegralError(YAW_RATE_PID, 0.0f); setPIDstates(ROLL_RATE_PID, 0.0f); setPIDstates(PITCH_RATE_PID, 0.0f); setPIDstates(YAW_RATE_PID, 0.0f); } /////////////////////////////////// if ((commandInDetent[YAW] == true) && (flightMode == ATTITUDE)) headingHoldEngaged = true; else headingHoldEngaged = false; /////////////////////////////////// // Check AUX2 for altitude hold mode (2 Position Switch) if ((rxCommand[AUX2] > MIDCOMMAND) && (previousAUX2State <= MIDCOMMAND)) // Rising edge detection { altitudeHoldState = ENGAGED; altitudeHoldThrottleValue = rxCommand[THROTTLE]; } else if ((rxCommand[AUX2] <= MIDCOMMAND) && (previousAUX2State > MIDCOMMAND)) // Falling edge detection { altitudeHoldState = DISENGAGED; } previousAUX2State = rxCommand[AUX2]; /////////////////////////////////// }
void initMPU6000(void) { /////////////////////////////////// ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_PWR_MGMT_1); // Device Reset spiTransfer(MPU6000_SPI, BIT_H_RESET); DISABLE_MPU6000; delay(150); ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_PWR_MGMT_1); // Clock Source PPL with Z axis gyro reference spiTransfer(MPU6000_SPI, MPU_CLK_SEL_PLLGYROZ); DISABLE_MPU6000; delayMicroseconds(1); ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_USER_CTRL); // Disable Primary I2C Interface spiTransfer(MPU6000_SPI, BIT_I2C_IF_DIS); DISABLE_MPU6000; delayMicroseconds(1); ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_PWR_MGMT_2); spiTransfer(MPU6000_SPI, 0x00); DISABLE_MPU6000; delayMicroseconds(1); ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_SMPLRT_DIV); // Accel Sample Rate 1000 Hz, Gyro Sample Rate 8000 Hz spiTransfer(MPU6000_SPI, 0x00); DISABLE_MPU6000; delayMicroseconds(1); ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_CONFIG); // Accel and Gyro DLPF Setting spiTransfer(MPU6000_SPI, eepromConfig.dlpfSetting); DISABLE_MPU6000; delayMicroseconds(1); ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_ACCEL_CONFIG); // Accel +/- 4 G Full Scale spiTransfer(MPU6000_SPI, BITS_FS_4G); DISABLE_MPU6000; delayMicroseconds(1); ENABLE_MPU6000; spiTransfer(MPU6000_SPI, MPU6000_GYRO_CONFIG); // Gyro +/- 1000 DPS Full Scale spiTransfer(MPU6000_SPI, BITS_FS_1000DPS); DISABLE_MPU6000; /////////////////////////////////// setSPIdivisor(MPU6000_SPI, 2); // 21 MHz SPI clock (within 20 +/- 10%) /////////////////////////////////// delay(100); computeMPU6000RTData(); }
void processFlightCommands(void) { uint8_t channel; if (rcActive == true) { // Read receiver commands for (channel = 0; channel < 8; channel++) { if (eepromConfig.receiverType == SPEKTRUM) rxCommand[channel] = (float)spektrumRead(eepromConfig.rcMap[channel]); else rxCommand[channel] = (float)ppmRxRead(eepromConfig.rcMap[channel]); } rxCommand[ROLL] -= eepromConfig.midCommand; // Roll Range -1000:1000 rxCommand[PITCH] -= eepromConfig.midCommand; // Pitch Range -1000:1000 rxCommand[YAW] -= eepromConfig.midCommand; // Yaw Range -1000:1000 rxCommand[THROTTLE] -= eepromConfig.midCommand - MIDCOMMAND; // Throttle Range 2000:4000 rxCommand[AUX1] -= eepromConfig.midCommand - MIDCOMMAND; // Aux1 Range 2000:4000 rxCommand[AUX2] -= eepromConfig.midCommand - MIDCOMMAND; // Aux2 Range 2000:4000 rxCommand[AUX3] -= eepromConfig.midCommand - MIDCOMMAND; // Aux3 Range 2000:4000 rxCommand[AUX4] -= eepromConfig.midCommand - MIDCOMMAND; // Aux4 Range 2000:4000 } // Set past command in detent values for (channel = 0; channel < 3; channel++) previousCommandInDetent[channel] = commandInDetent[channel]; // Apply deadbands and set detent discretes' for (channel = 0; channel < 3; channel++) { if ((rxCommand[channel] <= DEADBAND) && (rxCommand[channel] >= -DEADBAND)) { rxCommand[channel] = 0; commandInDetent[channel] = true; } else { commandInDetent[channel] = false; if (rxCommand[channel] > 0) { rxCommand[channel] = (rxCommand[channel] - DEADBAND) * DEADBAND_SLOPE; } else { rxCommand[channel] = (rxCommand[channel] + DEADBAND) * DEADBAND_SLOPE; } } } /////////////////////////////////// // Check for low throttle if ( rxCommand[THROTTLE] < eepromConfig.minCheck ) { // Check for disarm command ( low throttle, left yaw ) if (((rxCommand[YAW] < (eepromConfig.minCheck - MIDCOMMAND)) && (armed == true)) && (verticalModeState == ALT_DISENGAGED_THROTTLE_ACTIVE)) { disarmingTimer++; if (disarmingTimer > eepromConfig.disarmCount) { zeroPIDintegralError(); zeroPIDstates(); armed = false; disarmingTimer = 0; } } else { disarmingTimer = 0; } // Check for gyro bias command ( low throttle, left yaw, aft pitch, right roll ) if ( (rxCommand[YAW ] < (eepromConfig.minCheck - MIDCOMMAND)) && (rxCommand[ROLL ] > (eepromConfig.maxCheck - MIDCOMMAND)) && (rxCommand[PITCH] < (eepromConfig.minCheck - MIDCOMMAND)) ) { computeMPU6000RTData(); pulseMotors(3); } // Check for arm command ( low throttle, right yaw) if ((rxCommand[YAW] > (eepromConfig.maxCheck - MIDCOMMAND) ) && (armed == false) && (execUp == true)) { armingTimer++; if (armingTimer > eepromConfig.armCount) { zeroPIDintegralError(); zeroPIDstates(); armed = true; armingTimer = 0; } } else { armingTimer = 0; } } /////////////////////////////////// // Check for armed true and throttle command > minThrottle if ((armed == true) && (rxCommand[THROTTLE] > eepromConfig.minThrottle)) holdIntegrators = false; else holdIntegrators = true; /////////////////////////////////// // Check AUX1 for rate, attitude, or GPS mode (3 Position Switch) NOT COMPLETE YET.... if ((rxCommand[AUX1] > MIDCOMMAND) && (flightMode == RATE)) { flightMode = ATTITUDE; setPIDintegralError(ROLL_ATT_PID, 0.0f); setPIDintegralError(PITCH_ATT_PID, 0.0f); setPIDintegralError(HEADING_PID, 0.0f); setPIDstates(ROLL_ATT_PID, 0.0f); setPIDstates(PITCH_ATT_PID, 0.0f); setPIDstates(HEADING_PID, 0.0f); } else if ((rxCommand[AUX1] <= MIDCOMMAND) && (flightMode == ATTITUDE)) { flightMode = RATE; setPIDintegralError(ROLL_RATE_PID, 0.0f); setPIDintegralError(PITCH_RATE_PID, 0.0f); setPIDintegralError(YAW_RATE_PID, 0.0f); setPIDstates(ROLL_RATE_PID, 0.0f); setPIDstates(PITCH_RATE_PID, 0.0f); setPIDstates(YAW_RATE_PID, 0.0f); } /////////////////////////////////// // Check yaw in detent and flight mode to determine hdg hold engaged state if ((commandInDetent[YAW] == true) && (flightMode == ATTITUDE) && (headingHoldEngaged == false)) { headingHoldEngaged = true; setPIDintegralError(HEADING_PID, 0.0f); setPIDstates(YAW_RATE_PID, 0.0f); headingReference = heading.mag; } if (((commandInDetent[YAW] == false) || (flightMode != ATTITUDE)) && (headingHoldEngaged == true)) { headingHoldEngaged = false; } /////////////////////////////////// // Vertical Mode Command Processing verticalReferenceCommand = rxCommand[THROTTLE] - eepromConfig.midCommand; // Set past altitude reference in detent value previousVertRefCmdInDetent = vertRefCmdInDetent; // Apply deadband and set detent discrete' if ((verticalReferenceCommand <= ALT_DEADBAND) && (verticalReferenceCommand >= -ALT_DEADBAND)) { verticalReferenceCommand = 0; vertRefCmdInDetent = true; } else { vertRefCmdInDetent = false; if (verticalReferenceCommand > 0) { verticalReferenceCommand = (verticalReferenceCommand - ALT_DEADBAND) * ALT_DEADBAND_SLOPE; } else { verticalReferenceCommand = (verticalReferenceCommand + ALT_DEADBAND) * ALT_DEADBAND_SLOPE; } } /////////////////////////////////// // Vertical Mode State Machine switch (verticalModeState) { case ALT_DISENGAGED_THROTTLE_ACTIVE: if ((rxCommand[AUX2] > MIDCOMMAND) && (previousAUX2State <= MIDCOMMAND)) // AUX2 Rising edge detection { verticalModeState = ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT; setPIDintegralError(HDOT_PID, 0.0f); setPIDintegralError(H_PID, 0.0f); setPIDstates(HDOT_PID, 0.0f); setPIDstates(H_PID, 0.0f); altitudeHoldReference = hEstimate; throttleReference = rxCommand[THROTTLE]; } break; /////////////////////////////// case ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT: if ((vertRefCmdInDetent == true) || eepromConfig.verticalVelocityHoldOnly) verticalModeState = ALT_HOLD_AT_REFERENCE_ALTITUDE; if ((rxCommand[AUX2] <= MIDCOMMAND) && (previousAUX2State > MIDCOMMAND)) // AUX2 Falling edge detection verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; if ((rxCommand[AUX4] > MIDCOMMAND) && (previousAUX4State <= MIDCOMMAND)) // AUX4 Rising edge detection verticalModeState = ALT_DISENGAGED_THROTTLE_ACTIVE; break; /////////////////////////////// case ALT_HOLD_AT_REFERENCE_ALTITUDE: if ((vertRefCmdInDetent == false) || eepromConfig.verticalVelocityHoldOnly) verticalModeState = VERTICAL_VELOCITY_HOLD_AT_REFERENCE_VELOCITY; if ((rxCommand[AUX2] <= MIDCOMMAND) && (previousAUX2State > MIDCOMMAND)) // AUX2 Falling edge detection verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; if ((rxCommand[AUX4] > MIDCOMMAND) && (previousAUX4State <= MIDCOMMAND)) // AUX4 Rising edge detection verticalModeState = ALT_DISENGAGED_THROTTLE_ACTIVE; break; /////////////////////////////// case VERTICAL_VELOCITY_HOLD_AT_REFERENCE_VELOCITY: if ((vertRefCmdInDetent == true) && !eepromConfig.verticalVelocityHoldOnly) { verticalModeState = ALT_HOLD_AT_REFERENCE_ALTITUDE; altitudeHoldReference = hEstimate; } if ((rxCommand[AUX2] <= MIDCOMMAND) && (previousAUX2State > MIDCOMMAND)) // AUX2 Falling edge detection { verticalModeState = ALT_DISENGAGED_THROTTLE_INACTIVE; altitudeHoldReference = hEstimate; } if ((rxCommand[AUX4] > MIDCOMMAND) && (previousAUX4State <= MIDCOMMAND)) // AUX4 Rising edge detection verticalModeState = ALT_DISENGAGED_THROTTLE_ACTIVE; break; /////////////////////////////// case ALT_DISENGAGED_THROTTLE_INACTIVE: if (((rxCommand[THROTTLE] < throttleCmd + THROTTLE_WINDOW) && (rxCommand[THROTTLE] > throttleCmd - THROTTLE_WINDOW)) || eepromConfig.verticalVelocityHoldOnly) verticalModeState = ALT_DISENGAGED_THROTTLE_ACTIVE; if ((rxCommand[AUX2] > MIDCOMMAND) && (previousAUX2State <= MIDCOMMAND)) // AUX2 Rising edge detection verticalModeState = ALT_HOLD_FIXED_AT_ENGAGEMENT_ALT; if ((rxCommand[AUX4] > MIDCOMMAND) && (previousAUX4State <= MIDCOMMAND)) // AUX4 Rising edge detection verticalModeState = ALT_DISENGAGED_THROTTLE_ACTIVE; break; } previousAUX2State = rxCommand[AUX2]; previousAUX4State = rxCommand[AUX4]; /////////////////////////////////// }
void sensorCLI() { uint8_t sensorQuery = 'x'; uint8_t tempInt; uint8_t validQuery = false; cliBusy = true; cliPortPrint("\nEntering Sensor CLI....\n\n"); while(true) { cliPortPrint("Sensor CLI -> "); while ((cliPortAvailable() == false) && (validQuery == false)); if (validQuery == false) sensorQuery = cliPortRead(); cliPortPrint("\n"); switch(sensorQuery) { /////////////////////////// case 'a': // Sensor Data cliPortPrintF("\n"); cliPortPrintF("External HMC5883 in use: %s\n", eepromConfig.externalHMC5883 ? "Yes" : "No"); cliPortPrintF("External MS5611 in use: %s\n", eepromConfig.externalMS5611 ? "Yes" : "No"); cliPortPrintF("MXR9150 Accel in use: %s\n", eepromConfig.useMXR9150 ? "Yes" : "No"); cliPortPrintF("\n"); if (eepromConfig.useMXR9150 == true) { cliPortPrintF("MXR Accel Bias: %9.3f, %9.3f, %9.3f\n", eepromConfig.accelBiasMXR[XAXIS], eepromConfig.accelBiasMXR[YAXIS], eepromConfig.accelBiasMXR[ZAXIS]); cliPortPrintF("MXR Accel Scale Factor: %9.7f, %9.7f, %9.7f\n", eepromConfig.accelScaleFactorMXR[XAXIS], eepromConfig.accelScaleFactorMXR[YAXIS], eepromConfig.accelScaleFactorMXR[ZAXIS]); } else { cliPortPrintF("MPU Accel Bias: %9.3f, %9.3f, %9.3f\n", eepromConfig.accelBiasMPU[XAXIS], eepromConfig.accelBiasMPU[YAXIS], eepromConfig.accelBiasMPU[ZAXIS]); cliPortPrintF("MPU Accel Scale Factor: %9.7f, %9.7f, %9.7f\n", eepromConfig.accelScaleFactorMPU[XAXIS], eepromConfig.accelScaleFactorMPU[YAXIS], eepromConfig.accelScaleFactorMPU[ZAXIS]); } cliPortPrintF("Accel Temp Comp Slope: %9.4f, %9.4f, %9.4f\n", eepromConfig.accelTCBiasSlope[XAXIS], eepromConfig.accelTCBiasSlope[YAXIS], eepromConfig.accelTCBiasSlope[ZAXIS]); cliPortPrintF("Accel Temp Comp Bias: %9.4f, %9.4f, %9.4f\n", eepromConfig.accelTCBiasIntercept[XAXIS], eepromConfig.accelTCBiasIntercept[YAXIS], eepromConfig.accelTCBiasIntercept[ZAXIS]); cliPortPrintF("Gyro Temp Comp Slope: %9.4f, %9.4f, %9.4f\n", eepromConfig.gyroTCBiasSlope[ROLL ], eepromConfig.gyroTCBiasSlope[PITCH], eepromConfig.gyroTCBiasSlope[YAW ]); cliPortPrintF("Gyro Temp Comp Intercept: %9.4f, %9.4f, %9.4f\n", eepromConfig.gyroTCBiasIntercept[ROLL ], eepromConfig.gyroTCBiasIntercept[PITCH], eepromConfig.gyroTCBiasIntercept[YAW ]); cliPortPrintF("Internal Mag Bias: %9.4f, %9.4f, %9.4f\n", eepromConfig.magBias[XAXIS], eepromConfig.magBias[YAXIS], eepromConfig.magBias[ZAXIS]); cliPortPrintF("External Mag Bias: %9.4f, %9.4f, %9.4f\n", eepromConfig.magBias[XAXIS + 3], eepromConfig.magBias[YAXIS + 3], eepromConfig.magBias[ZAXIS + 3]); cliPortPrintF("Accel One G: %9.4f\n", accelOneG); cliPortPrintF("Accel Cutoff: %9.4f\n", eepromConfig.accelCutoff); cliPortPrintF("KpAcc (MARG): %9.4f\n", eepromConfig.KpAcc); cliPortPrintF("KiAcc (MARG): %9.4f\n", eepromConfig.KiAcc); cliPortPrintF("KpMag (MARG): %9.4f\n", eepromConfig.KpMag); cliPortPrintF("KiMag (MARG): %9.4f\n", eepromConfig.KiMag); cliPortPrintF("hdot est/h est Comp Fil A: %9.4f\n", eepromConfig.compFilterA); cliPortPrintF("hdot est/h est Comp Fil B: %9.4f\n", eepromConfig.compFilterB); cliPortPrint("MPU6000 DLPF: "); switch(eepromConfig.dlpfSetting) { case DLPF_256HZ: cliPortPrint("256 Hz\n"); break; case DLPF_188HZ: cliPortPrint("188 Hz\n"); break; case DLPF_98HZ: cliPortPrint("98 Hz\n"); break; case DLPF_42HZ: cliPortPrint("42 Hz\n"); break; } cliPortPrint("Sensor Orientation: "); switch(eepromConfig.sensorOrientation) { case 1: cliPortPrint("Normal\n"); break; case 2: cliPortPrint("Rotated 90 Degrees CW\n"); break; case 3: cliPortPrint("Rotated 180 Degrees\n"); break; case 4: cliPortPrint("Rotated 90 Degrees CCW\n"); break; default: cliPortPrint("Normal\n"); } if (eepromConfig.verticalVelocityHoldOnly) cliPortPrint("Vertical Velocity Hold Only\n\n"); else cliPortPrint("Vertical Velocity and Altitude Hold\n\n"); cliPortPrintF("Voltage Monitor Scale: %9.4f\n", eepromConfig.voltageMonitorScale); cliPortPrintF("Voltage Monitor Bias: %9.4f\n", eepromConfig.voltageMonitorBias); cliPortPrintF("Number of Battery Cells: %1d\n\n", eepromConfig.batteryCells); cliPortPrintF("Battery Low Setpoint: %4.2f volts\n", eepromConfig.batteryLow); cliPortPrintF("Battery Very Low Setpoint: %4.2f volts\n", eepromConfig.batteryVeryLow); cliPortPrintF("Battery Max Low Setpoint: %4.2f volts\n\n", eepromConfig.batteryMaxLow); validQuery = false; break; /////////////////////////// case 'b': // MPU6000 Calibration mpu6000Calibration(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'c': // Magnetometer Calibration magCalibration(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'd': // Accel Bias and Scale Factor Calibration if (eepromConfig.useMXR9150 == true) accelCalibrationMXR(); else accelCalibrationMPU(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'e': // Toggle External HMC5883 Use if (eepromConfig.externalHMC5883 == 0) eepromConfig.externalHMC5883 = 3; else eepromConfig.externalHMC5883 = 0; initMag(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'f': // Toggle External MS5611 Use if (eepromConfig.externalMS5611) eepromConfig.externalMS5611 = false; else eepromConfig.externalMS5611 = true; initPressure(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'g': // Toggle MXR9150 Use if (eepromConfig.useMXR9150) eepromConfig.useMXR9150 = false; else eepromConfig.useMXR9150 = true; computeMPU6000RTData(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'h': // MXR Bias eepromConfig.accelBiasMXR[XAXIS] = readFloatCLI(); eepromConfig.accelBiasMXR[YAXIS] = readFloatCLI(); eepromConfig.accelBiasMXR[ZAXIS] = readFloatCLI(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'v': // Toggle Vertical Velocity Hold Only if (eepromConfig.verticalVelocityHoldOnly) eepromConfig.verticalVelocityHoldOnly = false; else eepromConfig.verticalVelocityHoldOnly = true; sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'x': cliPortPrint("\nExiting Sensor CLI....\n\n"); cliBusy = false; return; break; /////////////////////////// case 'A': // Set MPU6000 Digital Low Pass Filter tempInt = (uint8_t)readFloatCLI(); switch(tempInt) { case DLPF_256HZ: eepromConfig.dlpfSetting = BITS_DLPF_CFG_256HZ; break; case DLPF_188HZ: eepromConfig.dlpfSetting = BITS_DLPF_CFG_188HZ; break; case DLPF_98HZ: eepromConfig.dlpfSetting = BITS_DLPF_CFG_98HZ; break; case DLPF_42HZ: eepromConfig.dlpfSetting = BITS_DLPF_CFG_42HZ; break; } setSPIdivisor(MPU6000_SPI, 64); // 0.65625 MHz SPI clock (within 20 +/- 10%) GPIO_ResetBits(MPU6000_CS_GPIO, MPU6000_CS_PIN); spiTransfer(MPU6000_SPI, MPU6000_CONFIG); spiTransfer(MPU6000_SPI, eepromConfig.dlpfSetting); GPIO_SetBits(MPU6000_CS_GPIO, MPU6000_CS_PIN); setSPIdivisor(MPU6000_SPI, 2); // 21 MHz SPI clock (within 20 +/- 10%) sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'B': // Accel Cutoff eepromConfig.accelCutoff = readFloatCLI(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'C': // kpAcc, kiAcc eepromConfig.KpAcc = readFloatCLI(); eepromConfig.KiAcc = readFloatCLI(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'D': // kpMag, kiMag eepromConfig.KpMag = readFloatCLI(); eepromConfig.KiMag = readFloatCLI(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'E': // h dot est/h est Comp Filter A/B eepromConfig.compFilterA = readFloatCLI(); eepromConfig.compFilterB = readFloatCLI(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'F': // Sensor Orientation eepromConfig.sensorOrientation = (uint8_t)readFloatCLI(); orientSensors(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'N': // Set Voltage Monitor Trip Points eepromConfig.batteryLow = readFloatCLI(); eepromConfig.batteryVeryLow = readFloatCLI(); eepromConfig.batteryMaxLow = readFloatCLI(); thresholds[BATTERY_LOW].value = eepromConfig.batteryLow; thresholds[BATTERY_VERY_LOW].value = eepromConfig.batteryVeryLow; thresholds[BATTRY_MAX_LOW].value = eepromConfig.batteryMaxLow; sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'V': // Set Voltage Monitor Parameters eepromConfig.voltageMonitorScale = readFloatCLI(); eepromConfig.voltageMonitorBias = readFloatCLI(); eepromConfig.batteryCells = (uint8_t)readFloatCLI(); sensorQuery = 'a'; validQuery = true; break; /////////////////////////// case 'W': // Write EEPROM Parameters cliPortPrint("\nWriting EEPROM Parameters....\n\n"); writeEEPROM(); validQuery = false; break; /////////////////////////// case '?': cliPortPrint("\n"); cliPortPrint("'a' Display Sensor Data 'A' Set MPU6000 DLPF A0 thru 3, see aq32Plus.h\n"); cliPortPrint("'b' MPU6000 Temp Calibration 'B' Set Accel Cutoff BAccelCutoff\n"); cliPortPrint("'c' Magnetometer Calibration 'C' Set kpAcc/kiAcc CkpAcc;kiAcc\n"); cliPortPrint("'d' Accel Bias and SF Calibration 'D' Set kpMag/kiMag DkpMag;kiMag\n"); cliPortPrint("'e' Toggle External HMC5883 State 'E' Set h dot est/h est Comp Filter A/B EA;B\n"); cliPortPrint("'f' Toggle External MS5611 State 'F' Set Sensor Orientation F1 thru 4\n"); cliPortPrint("'g' Toggle MXR9150 Use\n"); cliPortPrint(" 'N' Set Voltage Monitor Trip Points Nlow;veryLow;maxLow\n"); cliPortPrint("'v' Toggle Vertical Velocity Hold Only 'V' Set Voltage Monitor Parameters Vscale;bias;cells\n"); cliPortPrint(" 'W' Write EEPROM Parameters\n"); cliPortPrint("'x' Exit Sensor CLI '?' Command Summary\n"); break; /////////////////////////// } } }
int main(void) { /////////////////////////////////////////////////////////////////////////// uint32_t currentTime; arm_matrix_instance_f32 a; arm_matrix_instance_f32 b; arm_matrix_instance_f32 x; systemReady = false; systemInit(); systemReady = true; evrPush(EVR_StartingMain, 0); #ifdef _DTIMING #define LA1_ENABLE GPIO_SetBits(GPIOA, GPIO_Pin_4) #define LA1_DISABLE GPIO_ResetBits(GPIOA, GPIO_Pin_4) #define LA4_ENABLE GPIO_SetBits(GPIOC, GPIO_Pin_5) #define LA4_DISABLE GPIO_ResetBits(GPIOC, GPIO_Pin_5) #define LA2_ENABLE GPIO_SetBits(GPIOC, GPIO_Pin_2) #define LA2_DISABLE GPIO_ResetBits(GPIOC, GPIO_Pin_2) #define LA3_ENABLE GPIO_SetBits(GPIOC, GPIO_Pin_3) #define LA3_DISABLE GPIO_ResetBits(GPIOC, GPIO_Pin_3) GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); GPIO_StructInit(&GPIO_InitStructure); // Init pins GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); // Init pins GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); // Init pins GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5; //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); // PB0_DISABLE; LA4_DISABLE; LA2_DISABLE; LA3_DISABLE; LA1_DISABLE; #endif while (1) { checkUsbActive(false); evrCheck(); /////////////////////////////// if (frame_50Hz) { #ifdef _DTIMING LA2_ENABLE; #endif frame_50Hz = false; currentTime = micros(); deltaTime50Hz = currentTime - previous50HzTime; previous50HzTime = currentTime; processFlightCommands(); if (newTemperatureReading && newPressureReading) { d1Value = d1.value; d2Value = d2.value; calculateTemperature(); calculatePressureAltitude(); newTemperatureReading = false; newPressureReading = false; } sensors.pressureAlt50Hz = firstOrderFilter(sensors.pressureAlt50Hz, &firstOrderFilters[PRESSURE_ALT_LOWPASS]); rssiMeasure(); updateMax7456(currentTime, 0); executionTime50Hz = micros() - currentTime; #ifdef _DTIMING LA2_DISABLE; #endif } /////////////////////////////// if (frame_10Hz) { #ifdef _DTIMING LA4_ENABLE; #endif frame_10Hz = false; currentTime = micros(); deltaTime10Hz = currentTime - previous10HzTime; previous10HzTime = currentTime; if (newMagData == true) { nonRotatedMagData[XAXIS] = (rawMag[XAXIS].value * magScaleFactor[XAXIS]) - eepromConfig.magBias[XAXIS + eepromConfig.externalHMC5883]; nonRotatedMagData[YAXIS] = (rawMag[YAXIS].value * magScaleFactor[YAXIS]) - eepromConfig.magBias[YAXIS + eepromConfig.externalHMC5883]; nonRotatedMagData[ZAXIS] = (rawMag[ZAXIS].value * magScaleFactor[ZAXIS]) - eepromConfig.magBias[ZAXIS + eepromConfig.externalHMC5883]; arm_mat_init_f32(&a, 3, 3, (float *)hmcOrientationMatrix); arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedMagData); arm_mat_init_f32(&x, 3, 1, sensors.mag10Hz); arm_mat_mult_f32(&a, &b, &x); newMagData = false; magDataUpdate = true; } decodeUbloxMsg(); batMonTick(); cliCom(); if (eepromConfig.mavlinkEnabled == true) { mavlinkSendAttitude(); mavlinkSendVfrHud(); } executionTime10Hz = micros() - currentTime; #ifdef _DTIMING LA4_DISABLE; #endif } /////////////////////////////// if (frame_500Hz) { #ifdef _DTIMING LA1_ENABLE; #endif frame_500Hz = false; currentTime = micros(); deltaTime500Hz = currentTime - previous500HzTime; previous500HzTime = currentTime; TIM_Cmd(TIM10, DISABLE); timerValue = TIM_GetCounter(TIM10); TIM_SetCounter(TIM10, 0); TIM_Cmd(TIM10, ENABLE); dt500Hz = (float)timerValue * 0.0000005f; // For integrations in 500 Hz loop computeMPU6000TCBias(); nonRotatedAccelData[XAXIS] = ((float)accelSummedSamples500Hz[XAXIS] * 0.5f - accelTCBias[XAXIS]) * ACCEL_SCALE_FACTOR; nonRotatedAccelData[YAXIS] = ((float)accelSummedSamples500Hz[YAXIS] * 0.5f - accelTCBias[YAXIS]) * ACCEL_SCALE_FACTOR; nonRotatedAccelData[ZAXIS] = ((float)accelSummedSamples500Hz[ZAXIS] * 0.5f - accelTCBias[ZAXIS]) * ACCEL_SCALE_FACTOR; arm_mat_init_f32(&a, 3, 3, (float *)mpuOrientationMatrix); arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedAccelData); arm_mat_init_f32(&x, 3, 1, sensors.accel500Hz); arm_mat_mult_f32(&a, &b, &x); nonRotatedGyroData[ROLL ] = ((float)gyroSummedSamples500Hz[ROLL] * 0.5f - gyroRTBias[ROLL ] - gyroTCBias[ROLL ]) * GYRO_SCALE_FACTOR; nonRotatedGyroData[PITCH] = ((float)gyroSummedSamples500Hz[PITCH] * 0.5f - gyroRTBias[PITCH] - gyroTCBias[PITCH]) * GYRO_SCALE_FACTOR; nonRotatedGyroData[YAW ] = ((float)gyroSummedSamples500Hz[YAW] * 0.5f - gyroRTBias[YAW ] - gyroTCBias[YAW ]) * GYRO_SCALE_FACTOR; arm_mat_init_f32(&a, 3, 3, (float *)mpuOrientationMatrix); arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedGyroData); arm_mat_init_f32(&x, 3, 1, sensors.gyro500Hz); arm_mat_mult_f32(&a, &b, &x); MargAHRSupdate(sensors.gyro500Hz[ROLL], sensors.gyro500Hz[PITCH], sensors.gyro500Hz[YAW], sensors.accel500Hz[XAXIS], sensors.accel500Hz[YAXIS], sensors.accel500Hz[ZAXIS], sensors.mag10Hz[XAXIS], sensors.mag10Hz[YAXIS], sensors.mag10Hz[ZAXIS], eepromConfig.accelCutoff, magDataUpdate, dt500Hz); magDataUpdate = false; computeAxisCommands(dt500Hz); mixTable(); writeServos(); writeMotors(); executionTime500Hz = micros() - currentTime; #ifdef _DTIMING LA1_DISABLE; #endif } /////////////////////////////// if (frame_100Hz) { #ifdef _DTIMING LA3_ENABLE; #endif frame_100Hz = false; currentTime = micros(); deltaTime100Hz = currentTime - previous100HzTime; previous100HzTime = currentTime; TIM_Cmd(TIM11, DISABLE); timerValue = TIM_GetCounter(TIM11); TIM_SetCounter(TIM11, 0); TIM_Cmd(TIM11, ENABLE); dt100Hz = (float)timerValue * 0.0000005f; // For integrations in 100 Hz loop nonRotatedAccelData[XAXIS] = ((float)accelSummedSamples100Hz[XAXIS] * 0.1f - accelTCBias[XAXIS]) * ACCEL_SCALE_FACTOR; nonRotatedAccelData[YAXIS] = ((float)accelSummedSamples100Hz[YAXIS] * 0.1f - accelTCBias[YAXIS]) * ACCEL_SCALE_FACTOR; nonRotatedAccelData[ZAXIS] = ((float)accelSummedSamples100Hz[ZAXIS] * 0.1f - accelTCBias[ZAXIS]) * ACCEL_SCALE_FACTOR; arm_mat_init_f32(&a, 3, 3, (float *)mpuOrientationMatrix); arm_mat_init_f32(&b, 3, 1, (float *)nonRotatedAccelData); arm_mat_init_f32(&x, 3, 1, sensors.accel100Hz); arm_mat_mult_f32(&a, &b, &x); createRotationMatrix(); bodyAccelToEarthAccel(); vertCompFilter(dt100Hz); if (armed == true) { if ( eepromConfig.activeTelemetry == 1 ) { // Roll Loop openLogPortPrintF("1,%1d,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f\n", flightMode, rateCmd[ROLL], sensors.gyro500Hz[ROLL], ratePID[ROLL], attCmd[ROLL], sensors.attitude500Hz[ROLL], attPID[ROLL]); } if ( eepromConfig.activeTelemetry == 2 ) { // Pitch Loop openLogPortPrintF("2,%1d,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f,%9.4f\n", flightMode, rateCmd[PITCH], sensors.gyro500Hz[PITCH], ratePID[PITCH], attCmd[PITCH], sensors.attitude500Hz[PITCH], attPID[PITCH]); } if ( eepromConfig.activeTelemetry == 4 ) { // Sensors openLogPortPrintF("3,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,%8.4f,\n", sensors.accel500Hz[XAXIS], sensors.accel500Hz[YAXIS], sensors.accel500Hz[ZAXIS], sensors.gyro500Hz[ROLL], sensors.gyro500Hz[PITCH], sensors.gyro500Hz[YAW], sensors.mag10Hz[XAXIS], sensors.mag10Hz[YAXIS], sensors.mag10Hz[ZAXIS], sensors.attitude500Hz[ROLL], sensors.attitude500Hz[PITCH], sensors.attitude500Hz[YAW]); } if ( eepromConfig.activeTelemetry == 8 ) { } if ( eepromConfig.activeTelemetry == 16) { // Vertical Variables openLogPortPrintF("%9.4f, %9.4f, %9.4f, %4ld, %1d, %9.4f\n", verticalVelocityCmd, hDotEstimate, hEstimate, ms5611Temperature, verticalModeState, throttleCmd); } } executionTime100Hz = micros() - currentTime; #ifdef _DTIMING LA3_DISABLE; #endif } /////////////////////////////// if (frame_5Hz) { frame_5Hz = false; currentTime = micros(); deltaTime5Hz = currentTime - previous5HzTime; previous5HzTime = currentTime; if (gpsValid() == true) { } //if (eepromConfig.mavlinkEnabled == true) //{ // mavlinkSendGpsRaw(); //} if (batMonVeryLowWarning > 0) { LED1_TOGGLE; batMonVeryLowWarning--; } if (execUp == true) BLUE_LED_TOGGLE; executionTime5Hz = micros() - currentTime; } /////////////////////////////// if (frame_1Hz) { frame_1Hz = false; currentTime = micros(); deltaTime1Hz = currentTime - previous1HzTime; previous1HzTime = currentTime; if (execUp == true) GREEN_LED_TOGGLE; if (execUp == false) execUpCount++; // Initialize sensors after being warmed up if ((execUpCount == 20) && (execUp == false)) { computeMPU6000RTData(); initMag(); initPressure(); } // Initialize PWM and set mag after sensor warmup if ((execUpCount == 25) && (execUp == false)) { execUp = true; pwmEscInit(); homeData.magHeading = sensors.attitude500Hz[YAW]; } if (batMonLowWarning > 0) { LED1_TOGGLE; batMonLowWarning--; } if (eepromConfig.mavlinkEnabled == true) { mavlinkSendHeartbeat(); mavlinkSendSysStatus(); } executionTime1Hz = micros() - currentTime; } //////////////////////////////// } /////////////////////////////////////////////////////////////////////////// }