No match for operator error

Hi, Im trying to understand and make a 2D kalman filter for a drone.

#include <BasicLinearAlgebra.h>
using namespace BLA;
float AltitudeKalman, VelocityVerticalKalman;
BLA::Matrix<2,2> F; BLA::Matrix<2,1> G;
BLA::Matrix<2,2> P; BLA::Matrix<2,2> Q;
BLA::Matrix<2,1> S; BLA::Matrix<1,2> H;
BLA::Matrix<2,2> I; BLA::Matrix<1,1> Acc;
BLA::Matrix<2,1> K; BLA::Matrix<1,1> R;
BLA::Matrix<1,1> L; BLA::Matrix<1,1> M;
void kalman_2d(void){
  Acc = {AccZInertial};
  S=F*S+G*Acc;
  P=F*P*~F+Q;
  L=H*P*~H+R;
  K=P*~H*Invert(L);
  M={AltitudeBarometer};
  S=S+K*(M-H*S);
  AltitudeKalman=S(0,0); 
  VelocityVerticalKalman=S(1,0); 
  P=(I-K*H)*P;
}
AltitudeBarometerStartUp/=2000;
  F = {1, 0.004,
            0, 1};  
  G = {0.5*0.004*0.004,
            0.004};
  H = {1, 0};
  I = {1, 0,
           0, 1};
  Q = G * ~G*10*10;
  R = {30*30};
  P = {0, 0,
           0, 0};
  S = {0,
           0};
           LoopTimer=micros();

Thats the code, but its giving me this error message:

Compilation error: no match for 'operator*' (operand types are 'BLA::Matrix<2, 1>' and 'bool')

Its in two places, both K=P*~H*Invert(L); and Q = G * ~G*10*10; found in the second block of code

I am inexperienced in this area and I dont know how to fix it. Could someone please help me?

We cannot see tge type of Q, R, S etc. From your cide snippet.
What is the ~ supposed to do?
It is a bitwise not operator. From your code I expect G is a float. No idea if you can do a biwise not on a float. My guess: either you cannot or it is a bad idea...

I find your question interesting, but I have a problem understanding your setup. After reading your description, I still have no idea what your actual configuration looks like. To help you better, please provide the following:

  1. Your Code: Post the complete code using code tags.

  2. Technical Details: Provide links to the technical information for all hardware components used in your setup. There are many different and sometimes incompatible devices that look similar but behave differently, so it's crucial that we have accurate information. Avoid linking to marketplace sites like Amazon that often lack detailed specifications.

  3. Why This Matters: All you want is to make everything work together correctly, and all we want is to help you achieve that. By providing the correct details, we can offer more targeted and effective assistance.

Use Inverse() instead of Invert().

that solved the first line's error, but not the second one

This is the complete code

#include <Wire.h>
float RateRoll, RatePitch, RateYaw;
float AngleRoll, AnglePitch;
float AccX, AccY, AccZ;
float AccZInertial;
float LoopTimer;
uint16_t dig_T1, dig_P1;
int16_t  dig_T2, dig_T3, dig_P2, dig_P3, dig_P4, dig_P5;
int16_t  dig_P6, dig_P7, dig_P8, dig_P9; 
float AltitudeBarometer, AltitudeBarometerStartUp;
int RateCalibrationNumber;
#include <BasicLinearAlgebra.h>
using namespace BLA;
float AltitudeKalman, VelocityVerticalKalman;
BLA::Matrix<2,2> F; BLA::Matrix<2,1> G;
BLA::Matrix<2,2> P; BLA::Matrix<2,2> Q;
BLA::Matrix<2,1> S; BLA::Matrix<1,2> H;
BLA::Matrix<2,2> I; BLA::Matrix<1,1> Acc;
BLA::Matrix<2,1> K; BLA::Matrix<1,1> R;
BLA::Matrix<1,1> L; BLA::Matrix<1,1> M;
void kalman_2d(void){
  Acc = {AccZInertial};
  S=F*S+G*Acc;
  P=F*P*~F+Q;
  L=H*P*~H+R;
  K=P*~H*Invert(L);
  M={AltitudeBarometer};
  S=S+K*(M-H*S);
  AltitudeKalman=S(0,0); 
  VelocityVerticalKalman=S(1,0); 
  P=(I-K*H)*P;
}
void barometer_signals(void){
  Wire.beginTransmission(0x76);
  Wire.write(0xF7);
  Wire.endTransmission();
  Wire.requestFrom(0x76,6);
  uint32_t press_msb = Wire.read();
  uint32_t press_lsb = Wire.read();
  uint32_t press_xlsb = Wire.read();
  uint32_t temp_msb = Wire.read();
  uint32_t temp_lsb = Wire.read();
  uint32_t temp_xlsb = Wire.read();
  unsigned long int adc_P = (press_msb << 12) | (press_lsb << 4) | (press_xlsb >>4);
  unsigned long int adc_T = (temp_msb << 12) | (temp_lsb << 4) | (temp_xlsb >>4);
  signed long int var1, var2;
  var1 = ((((adc_T >> 3) - ((signed long int )dig_T1 <<1)))* ((signed long int )dig_T2)) >> 11;
  var2 = (((((adc_T >> 4) - ((signed long int )dig_T1)) * ((adc_T>>4) - ((signed long int )dig_T1)))>> 12) * ((signed long int )dig_T3)) >> 14;
  signed long int t_fine = var1 + var2;
  unsigned long int p;
  var1 = (((signed long int )t_fine)>>1) - (signed long int )64000;
  var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int )dig_P6);
  var2 = var2 + ((var1*((signed long int )dig_P5)) <<1);
  var2 = (var2>>2)+(((signed long int )dig_P4) <<16);
  var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13))>>3)+((((signed long int )dig_P2) * var1)>>1))>>18;
  var1 = ((((32768+var1))*((signed long int )dig_P1)) >>15);
  if (var1 == 0) { p=0;}    
  p = (((unsigned long int )(((signed long int ) 1048576)-adc_P)-(var2>>12)))*3125;
  if(p<0x80000000){ p = (p << 1) / ((unsigned long int ) var1);}
  else { p = (p / (unsigned long int )var1) * 2;  }
  var1 = (((signed long int )dig_P9) * ((signed long int ) (((p>>3) * (p>>3))>>13)))>>12;
  var2 = (((signed long int )(p>>2)) * ((signed long int )dig_P8))>>13;
  p = (unsigned long int)((signed long int )p + ((var1 + var2+ dig_P7) >> 4));
  double pressure=(double)p/100;
  AltitudeBarometer=44330*(1-pow(pressure/1013.25, 1/5.255))*100;
}
void gyro_signals(void) {
  Wire.beginTransmission(0x68);
  Wire.write(0x1A);
  Wire.write(0x05);
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x1C);
  Wire.write(0x10);
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(0x3B);
  Wire.endTransmission(); 
  Wire.requestFrom(0x68,6);
  int16_t AccXLSB = Wire.read() << 8 | Wire.read();
  int16_t AccYLSB = Wire.read() << 8 | Wire.read();
  int16_t AccZLSB = Wire.read() << 8 |  Wire.read();
  Wire.beginTransmission(0x68);
  Wire.write(0x1B); 
  Wire.write(0x8);
  Wire.endTransmission();                                                   
  Wire.beginTransmission(0x68);
  Wire.write(0x43);
  Wire.endTransmission();
  Wire.requestFrom(0x68,6);
  int16_t GyroX=Wire.read()<<8 | Wire.read();
  int16_t GyroY=Wire.read()<<8 | Wire.read();
  int16_t GyroZ=Wire.read()<<8 | Wire.read();
  RateRoll=(float)GyroX/65.5;
  RatePitch=(float)GyroY/65.5;
  RateYaw=(float)GyroZ/65.5;
  AccX=(float)AccXLSB/4096;
  AccY=(float)AccYLSB/4096;
  AccZ=(float)AccZLSB/4096;
  AngleRoll=atan(AccY/sqrt(AccX*AccX+AccZ*AccZ))*1/(3.142/180);
  AnglePitch=-atan(AccX/sqrt(AccY*AccY+AccZ*AccZ))*1/(3.142/180);
}
void setup() {
  Serial.begin(57600);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  Wire.setClock(400000);
  Wire.begin();
  delay(250);
  Wire.beginTransmission(0x68); 
  Wire.write(0x6B);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.beginTransmission(0x76);
  Wire.write(0xF4);
  Wire.write(0x57);
  Wire.endTransmission();   
  Wire.beginTransmission(0x76);
  Wire.write(0xF5); 
  Wire.write(0x14);
  Wire.endTransmission();   
  uint8_t data[24], i=0;
  Wire.beginTransmission(0x76);
  Wire.write(0x88);
  Wire.endTransmission();
  Wire.requestFrom(0x76,24);        
  while(Wire.available()){
    data[i] = Wire.read();
    i++;
  } 
  dig_T1 = (data[1] << 8) | data[0]; 
  dig_T2 = (data[3] << 8) | data[2];
  dig_T3 = (data[5] << 8) | data[4];
  dig_P1 = (data[7] << 8) | data[6]; 
  dig_P2 = (data[9] << 8) | data[8];
  dig_P3 = (data[11]<< 8) | data[10];
  dig_P4 = (data[13]<< 8) | data[12];
  dig_P5 = (data[15]<< 8) | data[14];
  dig_P6 = (data[17]<< 8) | data[16];
  dig_P7 = (data[19]<< 8) | data[18];
  dig_P8 = (data[21]<< 8) | data[20];
  dig_P9 = (data[23]<< 8) | data[22]; delay(250);
  for (RateCalibrationNumber=0; RateCalibrationNumber<2000; RateCalibrationNumber ++) {
    barometer_signals();
    AltitudeBarometerStartUp+=AltitudeBarometer; 
    delay(1); 
  }
  AltitudeBarometerStartUp/=2000;
  F = {1, 0.004,
            0, 1};  
  G = {0.5*0.004*0.004,
            0.004};
  H = {1, 0};
  I = {1, 0,
           0, 1};
  Q = G * ~G*10*10;
  R = {30*30};
  P = {0, 0,
           0, 0};
  S = {0,
           0};
           LoopTimer=micros();
}
void loop() {
 gyro_signals();
  AccZInertial=-sin(AnglePitch*(3.142/180))*AccX+cos(AnglePitch*(3.142/180))*sin(AngleRoll*(3.142/180))* AccY+cos(AnglePitch*(3.142/180))*cos(AngleRoll*(3.142/180))*AccZ;   
  AccZInertial=(AccZInertial-1)*9.81*100;
  barometer_signals();
  AltitudeBarometer-=AltitudeBarometerStartUp;
  kalman_2d();
  Serial.print("Altitude [cm]: ");
  Serial.print(AltitudeKalman);
  Serial.print(" Vertical velocity [cm/s]: ");
  Serial.println(VelocityVerticalKalman);
  while (micros() - LoopTimer < 4000); 
  LoopTimer=micros();                  
}

I am using a Arduino Nano ESP32 because i need it to run a library for my drone receiver. This filter is used to combine the outputs of a BMP280 and a MPU6050 so that i can get the height that the drone is flying at. Both these components alone give horrible data but together can accurately say at what height it is using a kalman filter

1 Like

The types of the matrix and the scalar must match (float matrix * float):

  Q = G * ~G*10.0f*10.0f;

Did you write this yourself or is this AI generated? Or borrowed from some instructables?
It is pretty difficult to follow...

Is that proven, a statement or wishfull thinking???

This:

Can be done in 3 lines...

its from this video https://www.youtube.com/watch?v=GZevJyabMdI

Friendly guy, but not the best starting point for your kalman filter code...
There is a lot of hocus pocus and magic numbers going on in this code.
Maybe it is a good idea to search for a better code resource to start your project. It will take me days to find out what this code is doing and to rewrite it in a better way. For you it may take days, weeks or months (depending on whether you know what an inverse matrix is).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.