How to use COMPASS_TYPEMASK?

It says this is a bitmask. But the wiki lists them sequentially 1-12. I want to manually disable the QMC5883, which is #12. But if I just enter 12, that doesn’t seem like a valid bitmask.

it is a bitmask, so I would think that when you want to disable #12 you should set 4096 (2^12 or 1<<12)

https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_Compass/AP_Compass.cpp#L504-L511

Perhaps I don’t actually know how a bitmask works… But thank you, I will use 4096. Thx.

Can someone elaborate on how to use this parameter. The wiki instructions do not explain it.

The COMPASS_TYPEMASK parameter should be set to a number between 0 and 8191. (That’s a weird max value, right? I’ll explain below.) It’s value determines which compass hardware types are NOT permitted for use, in other words, completely ignored by the ArduPilot software. I am guessing your question is: “How does some specific value (in the range from 0 to 8191) specify which compasses to ignore?”

The key is in understanding a bitmask, which also means you need to be comfortable translating base-10 numbers to base-2 (a.k.a. binary). I’m not going to explain how binary works, you’ll need to google that if you’re not familiar.

Any number from 0 to 8191 displayed in binary can be said to have 13 digits, each digit can be either 0 or 1. Let’s call the least-significant-digit (a.k.a. the right-most digit) the “0th digit” and the next digit (i.e. 2nd-from-the-right) as the “1st digit” and so on… until the most-significant digit (i.e. the left-most, or 13th-from-the-right) is called the “12th digit.”

Now, given a 13-digit value in binary, to determine which compasses are DISABLED, just find which digits have a value of 1, and then look up those digit-positions on the table provided in the documentation: http://ardupilot.org/plane/docs/parameters.html?highlight=compass_typemask

Example:
Value = 0010000100001.
The “10th, 5th, and 0th digits” are set to 1. Therefore, following the chart, the following compasses are disabled: QFLIGHT, LIS3MDL, and HMC5883. (See that these correspond to the 10th, 5th, and 0th bit in the table.)

Finally, how does a 13-digit number of ones-and-zeros translate to the COMPASS_TYPEMASK value? Just convert it’s value to base-10.

Example:
Binary value = 0010000100001.
Base 10 value = 1057.

So you know which compasses you want to disable, but don’t know how to construct the COMPASS_TYPEMASK value? Just do the exact process, except in reverse:
0) Pick the compasses you want to disable,

  1. Find their bit-position from the table,
  2. Construct the binary number with 1’s on those bits,
  3. Convert that binary value to base 10, and
  4. Put the base 10 value into COMPASS_TYPEMASK.

Does this help? I’m not sure where the confusion is, so feel free to ask questions!


P.S. [An aside on programmer/math notation]
Since computers “speak binary” programmers have come up with a number of elegant mathematical syntax for doing things in binary. If you don’t understand them, then many explanations won’t make sense. If someone is bit-shifting (using the << or >> operators) that is one elegant representation for binary manipulation. Another is by raising 2 to a power (i.e. 2^12 = 4096 from above) which makes sense if you understand binary. Some more are and-ing some numbers, and or-ing some numbers. (There are very likely others.) I only mention these so that you’ll understand that they’re excellent ways to understand all of this, if you understand them, and very confusing if you don’t.

P.P.S. [Why that (weird) max value of 8191?]
Question 1: What’s the biggest value, in binary, that a 13-digit number can have?
Answer 1: That’s 13 ones, which is: 1111111111111.

Question 2: What’s the value of 1111111111111 in base-10?
Answer 2: It is: 8191.

1 Like

Wow. That definitely covered it I think.

The compass enum is
DRIVER_HMC5883 =0, DRIVER_LSM303D =1, DRIVER_AK8963 =2, DRIVER_BMM150 =3, DRIVER_LSM9DS1 =4, DRIVER_LIS3MDL =5, DRIVER_AK09916 =6, DRIVER_IST8310 =7, DRIVER_ICM20948 =8, DRIVER_MMC3416 =9, DRIVER_QFLIGHT =10, DRIVER_UAVCAN =11, DRIVER_QMC5883 =12, DRIVER_SITL =13,

So if I want to disable 5 & 10-13, that would be 00000100001111 and a base-10 of 271? I used this to do the conversion: http://www.unitconversion.org/numbers/binary-to-base-10-conversion.html

Almost correct. You got the digit-order backwards. The “0th” digit is the right-most, while the 13th is the left-most, as written.

The binary value 11110000100000 would disable:
SITL, QMC5883, UAVCAN, QFLIGHT, LIS3MDL.
Converted to base 10, that’s a value of 15392.

P.S. my post assumed you didn’t know about SITL, because it’s not in the documentation. But you’re right, in fact it is in the source code as the 14th digit, and it looks like you went there. That means you’re using a 14-bit number, which has a maximum value of 16383.

ohhh. ok got it. Thanks!