I’m trying to create an array to store RPM values that I will then use to calculate an exponential moving average of the RPM values the take-back-half algorithm for our flywheels will use.
The structure of the take-back-half algorithm is a struct (pun somewhat intended); it’s a derivative of jpearman’s take-back-half algorithm. I like this version of the algorithm because we have 2 independently moving flywheels, so each one needs its own velocity controller, and this lets us have the two instances without having to have 2 copies of the code (the only duplication is that each side of the flywheel needs its own controller task).
Here’s the relevant code for the moving average:
typedef struct _fw_controller {
long counter; ///< loop counter used for debug
// encoder tick per revolution
float ticks_per_rev; ///< encoder ticks per revolution
// Encoder
long e_current; ///< current encoder count
long e_last; ///< current encoder count
// velocity measurement
float v_current; ///< current velocity in rpm
int termsInAvg = 0; ///< number of terms included in the average; the exponential weighted average calculation changes slightly if this value is less than 10
float v_last10[10]; ///< array holding last 10 RPM calculations - this line causes a compiler error: "**Error**:Initializing expressions not allowed within 'struct' definition."
float v_avg; ///< weighted exponential average of the last 10 RPM measurements that is used to calculate error
long v_time; ///< Time of last velocity calculation
// TBH control algorithm variables
long target; ///< target velocity
long current; ///< current velocity
long last; ///< last velocity
float error; ///< error between actual and target velocities
float last_error; ///< error last time update called
float gain; ///< gain
float drive; ///< final drive out of TBH (0.0 to 1.0)
float drive_at_zero; ///< drive at last zero crossing
long first_cross; ///< flag indicating first zero crossing
float drive_approx; ///< estimated open loop drive
float MOTOR_TPR; ///< ticks per rev for IME
// final motor drive
long motor_drive; ///< final motor control value
} fw_controller;
//a few functions in here
void
updateRPMAverage(fw_controller *fw, float array, float newRPM) {
//shift values up one; a side effect will be that the oldest value will be removed if there are more than 10 RPM values
for (int i = 1; i <= 9; i++) {
array* = array*;
}
//set the newest RPM value to index 9 of the array
array[9] = newRPM;
float sum = 0;
int weightedNumTerms = 0; //number to divide by
int stopIndex = fw->termsInAvg == 10 ? 0 : 9 - fw->termsInAvg;
//computed the new weighted average
for (int i = 9; i >= stopIndex; i--) {
sum += pow(array*, i + 1);
weightedNumTerms += i + 1; //if i is 9, then array* is included in the average 10 times to weight it; thus, we need to divide i by 10
}
fw->termsInAvg = fw->termsInAvg + 1 > 10 ? 10 : fw->termsInAvg + 1;
fw->v_avg = sum / (float) weightedNumTerms; //cast weightedNumTerms as a float so we don't mistakenly end up with integer division
}
/*-----------------------------------------------------------------------------*/
/** @brief Calculate the current flywheel motor velocity */
/** @param[in] fw pointer to flywheel controller structure */
/*-----------------------------------------------------------------------------*/
void
FwCalculateSpeed( fw_controller *fw, long encoderValue )
{
int delta_ms;
int delta_enc;
// Get current encoder value
fw->e_current = encoderValue;
// This is just used so we don't need to know how often we are called
// how many mS since we were last here
delta_ms = nSysTime - fw->v_time;
fw->v_time = nSysTime;
// Change in encoder count
delta_enc = (fw->e_current - fw->e_last);
// save last position
fw->e_last = fw->e_current;
// Calculate velocity in rpm
fw->v_current = (1000.0 / delta_ms) * delta_enc * 60.0 / fw->ticks_per_rev;
updateRPMAverage(fw, fw->v_current);
}
The error I’m getting is
**Error**:Initializing expressions not allowed within 'struct' definition.
on the line that is supposed to create the array to hold the last 10 RPM values, which are then used to calculate the average.
My questions are:
- Is there any reason I can’t create this array within a struct?
- Is there a way around this? I’d rather not have to use individual variables for each of the 10 past RPM values because of how much cleaner an array would be.
Thanks in advance for any help!****