Hi all! My username is/was Southpark. I had been a regular here in the past, but because I didn't see any email from Arduino.cc about imminent deletion of my account unless I log in for some activity, then it would be deleted. Coincidentally, my account got automatically deleted around mid February this year. But that's ok. I have created this new account to use now.
In any case, I wanted to log in to get some recommendations about a particular issue that I had been recently encountering with the Arduino 'MatrixMath' library. I have just been trying it out with the Arduino MEGA2560.
In my code attached (which includes using the MatrixMath library), I have created a two element matrix, which is Xd on line 10, which is initialised with zeros, ie. {0.0, 0.0}.
In the setup() area, on line 116, I just use my own simple function to set new values for the vector Xd, In this case, on line 116, I set Xd to be [5.0 2.0].
Now, within the loop() part of my program, I simply print the element values of this vector Xd.
The issue I have encountered is that the printed value (when I run the program in the Arduino MEGA2560 and watch the serial monitor screen) is [0 2], instead of [5 2].
But interestingly, if I purposely set the values in line 10 to non-zero values, such as {1E-10, 0.0} or even {0.0, 0.0001}, then the printed element values of vector Xd will turn out to be the desired values that I want to see, which is [5 2].
Also, very interestingly as well, I have also noticed that if I purposely comment-out the Matrix.Multiply line on line 200, then the printed element values of vector Xd also 'magically' become the desired values, which is [5 2].
I have included my code below. Can anyone help me with figuring out why my element values set at line 116 are not properly or entirely transferring into the vector Xd (at line 184)?
At the moment, my code - if it is loaded into my MEGA2560, will print Xd as zero and two. And I don't yet know why it isn't printing out the values that I need, which is five and two.
Thanks in advance!!!
#include <MatrixMath.h>
#define N (2)
mtx_type Ad[N][N] = { {1.0, 0.002} , {0.0, 0.95} };
mtx_type Bd[N] = {0.000048, 0.048};
mtx_type Cd[N] = {1205.6, 0.0};
mtx_type Dd[1][1] = {0};
mtx_type Xd[N] = {0.0, 0.0}; // ISSUE is --- the printed element values of vector Xd at line 184 is always [ZERO and 2], unless we set one of these initial Xd element values on line 10 to a non-zero value. Eg. if we initialise line 10 Xd[N] with {1E-15, 0} or even {0 , 0.001}, then the printed values of Xd at line 184 become the desired values [5 2] (which is set at line 116)
mtx_type Fd[N] = {80, 1.6};
mtx_type U[1][1] = {0.0};
mtx_type Up[1][1] = {0.0};
mtx_type Ud[1][1] = {0.0};
mtx_type L[N] = {0.00016, 0.0077};
mtx_type Yd[1][1] = {0.0};
mtx_type Ya[1][1] = {0.0};
mtx_type ERROR[1][1] = {0.0};
mtx_type F_out[1][1] = {0.0};
mtx_type Ad_out[N] = {0.0, 0.0};
mtx_type Bd_out[N] = {0.0, 0.0};
mtx_type L_out[N] = {0.0, 0.0};
mtx_type SETPOINT_RPM1[1][1] = {1000.0};
mtx_type SETPOINT_RPM2[1][1] = {2000.0};
float ya;
float yd;
float setpoint_rpm1 = SETPOINT_RPM1[0][0];
float setpoint_rpm2 = SETPOINT_RPM2[0][0];
float grad = 0.1;
float y_int = -100;
float k = 80;
mtx_type SETPOINT_PWM1[1][1] = { (SETPOINT_RPM1[0][0] - y_int) / grad };
mtx_type SETPOINT_PWM2[1][1] = { (SETPOINT_RPM2[0][0] - y_int) / grad };
mtx_type R[1][1] = { (setpoint_rpm1 - y_int)/grad };
mtx_type ACCUM[1][1] = {0.0};
float accum = ACCUM[0][0];
int gear_ratio = 21.3;
float setpoint_rpm = setpoint_rpm1;
int setpoint_pwm = 0;
int pwm_offset = 0;
float error_rpm = 0;
float accum_error_rpm = 0;
int error_pwm = 0;
float error_rpm_prev = 0;
float u;
float ud;
float up;
float int_ku;
float Ad_o;
int ppr = 1024;
float RPM_raw = 0;
float RPM_array[700] = {};
int index = 0;
float RPM_initial = 0;
int flag = 0; //flag
unsigned long stab_time = 5000000;
unsigned long duration = 1000000;
unsigned long observe_ref = 0;
//************************************
unsigned long count_period = 2000;
unsigned long T = count_period;
byte number_of_sensors = 1;
unsigned long final_counts;
unsigned long start_time = micros();
unsigned long measured_time;
unsigned long current_time = micros();
//*************************************
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(100);
TCCR5A = 0;
TCCR5B = 0;
TCNT5 = 0;
pinMode( 47, INPUT_PULLUP);
TCCR5B = bit (CS50) | bit (CS51) | bit (CS52);
setpoint_pwm = 4000;
Serial.println("SETUP");
pop_Xd(5.0,2.0); //this function sets element values for vector Xd
Matrix.Print((mtx_type*)Xd,N,1,"Test 1 Xd");
pop_Ya(RPM_raw);
Matrix.Multiply((mtx_type*)Cd, (mtx_type*)Xd, N, 1, 1, (mtx_type*)Yd);
Matrix.Subtract((mtx_type*)Ya, (mtx_type*) Yd, 1, 1, (mtx_type*) ERROR);
Matrix.Print((mtx_type*)Xd,N,1,"Xd");
Matrix.Multiply((mtx_type*)Fd, (mtx_type*)Xd, N, 1, 1, (mtx_type*)F_out);
Matrix.Subtract((mtx_type*)R, (mtx_type*)F_out, 1, 1, (mtx_type*)U);
Matrix.Print((mtx_type*)Fd,1,N,"Fd");
//***************************************************************
DDRB = DDRB | 0x20;
ICR1 = 16383;
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 0;
TCCR1A |= 0x82;
TCCR1B |= 0x19;
//************************************************************************
delay(1000);
OCR1A = 0;
TCNT5 = 0;
observe_ref = micros();
start_time = micros();
}
void loop() {
if (flag == 0)
{
// put your main code here, to run repeatedly:
current_time = micros();
if (current_time - start_time >= T)
{
flag = 3; //REMOVE THIS LATER!!!!
TCCR5B = 0;
final_counts = TCNT5;
measured_time = current_time - start_time;
RPM_raw = ( (final_counts / float(ppr)) / (count_period*1e-6) ) * 60;
ya = RPM_raw;
pop_Ya(ya);
Serial.println();
Serial.println();
Serial.println("LOOP");
Matrix.Print((mtx_type*)Fd,1,N,"test Fd");
Matrix.Print((mtx_type*)Xd,N,1,"Test 2 Xd");
Matrix.Multiply((mtx_type*)Fd, (mtx_type*)Xd, N, 1, 1, (mtx_type*)F_out);
Matrix.Multiply((mtx_type*)Cd, (mtx_type*)Xd, N, 1, 1, (mtx_type*)Yd);
u = R[0][0] - F_out[0][0];
ud = u;
pop_U(u);
pop_Ud(ud);
Matrix.Print((mtx_type*)Bd, N, 1, "Bd");
Matrix.Print((mtx_type*)Ud,1,1,"Ud");
Matrix.Multiply((mtx_type*)Bd, (mtx_type*)Ud, N, 1, 1, (mtx_type*)Bd_out); //when this line 200 is INCLUDED, the elements of vector Xd at line 184 become [ZERO 2] for some reason, instead of being [5 2]
Matrix.Print((mtx_type*)Bd_out, N, 1, "Bd_out");
accum = 100;
if ( round(accum) > 16383 ) {
accum = 16383;
OCR1A = 16383;
Serial.println("accumulated error exceeded limit --- auto-limiting");
}
else if ( round(accum) <= 16383 ) {
OCR1A = round(accum);
}
else
{
Serial.println("exception");
}
current_time = micros();
start_time = micros();
TCNT5 = 0;
TCCR5B = bit (CS50) | bit (CS51) | bit (CS52); //restart external clock source
}
} //flag
} //loop
double pop_Xd (float a, float b)
{
Xd[0] = a;
Xd[1] = b;
}
void pop_Ya (float a)
{
Ya[0][0] = a;
}
void pop_Up (float a)
{
Up[0][0] = a;
}
void pop_U (float a)
{
U[0][0] = a;
}
void pop_Ud (float a)
{
Ud[0][0] = a;
}