I recently changed my autopilot for the PX4 Autopilot in my CubeOrange, but now I can’t get some parameters via MAVLink in my program, because now the messages ID’s have changed. For example: the linear velocities were obtained by the GLOBAL_POSITION_INT header, but now is from the ODOMETRY header; and the ground distance was obtained by the OPTICAL_FLOW header but now is from the OPTICAL_FLOW_RAD header.
That said, I have now a problem with the MAVLink library. The “mavlink” library (Figure 1) doesn’t have the headers that I need, and the “c_library_v2-master” library (Figure 2) I can’t include in my Arduino project, because it doesn’t access to the common folder, that contains the headers.
UPDATE: I pasted only the common folder in the libraries, and drag the “protocol.h”, “mavlink_types.h”, etc., files into that folder.
Now I manage to get some messages (the ones I was getting before I tried this, from and older mavlink library), but not all of them.
It’s very odd because they are all in the same library, in the same folder, but I can get some but the ones I want I can’t. The “common” folder of the “c_library_v2” is the only folder that I have there.
Why is this happening?
Please confirm you have common/mavlink.h in the project. This should import most of what you need.
Yes, I have “common/mavlink.h” file in there, which is the only header file that I include in the Arduino project.
My only question (for anyone who wants to help me) is why can I receive the older messages, but not the ones I want? In my point of view there should be no difference between them, since they are in the same folder.
It looks like the Arduino mavlink library is possibly generated from an older version of mavlink. I’m trying to follow your issue on the mavlink google group, but it’s hard to parse without seeing the error message. The only include you should need is <common/mavlink.h> (or mavlink.h depending on your path)
The message ids should not have changed though. OPTICAL_FLOW is still #100 and OPTICAL_FLOW_RAD is #106. Same with ODOMETRY and GLOBAL_POSITION_INT.
Is it that the mavlink streams from the PX4 are different on your CubeOrange autopilot? Possibly you were using the NORMAL mavlink mode and now you have EXTVISION which sends out ODOMETRY instead of GLOBAL_POSITION_INT.
The thing is that Arduino doesn’t send a error message. The code compiles fine, which means that it understands the Message ID that I ask it to receive. For example, in this figure, it knows that it has to receive both attitude and odometry, and since it compiles without errors it shows that it has both IDs well defined. But although the attitude values are perfectly fine, the odometry ones are 0 everytime.
Yes, it can be that, I think. The Flight Controller is in my lab so I can only check the parameter tomorrow, but I will definitely try that. Just two questions:
what does that parameter MAV_#_MODE means exactly?
If I have in fact the EXTVISION mode what do I have to do to make it work?
On the PX4 Autopilot Firmware you have parameters you set. MAV_0_MODE sets the streaming mode for the 0th mavlink instance. MAV_1_MODE for the 1st instance. Setting this parameter to “0” results in the NORMAL stream. “8” would be the EXTVISION stream. See the links in my previous comment to see what each stream mode sends out.
I suggest you connect a QGroundControl instance to the serial connection your Arduino usually connects and you can use the Mavlink Inspector feature to see the incoming mavlink messages in real-time. Or write a mavlink lister in python with pymavlink that prints out the messages.
You say the velocity in the ODOMETRY message are zeros? roll, pitch, and yaw in your ATTITUDE message will be in radians while vx, vy, vz in your ODOMETRY message are in meters per second. Does the quaternion (q) reported in the ODOMETRY message match the corresponding roll, pitch, yaw Euler sequence?
Are you displaying enough digits? Is the aircraft moving faster than 1 meter/second in your tests? Does the aircraft have a Position lock?
Yes, the angle values from ATTITUDE are fine, but the ones from ODOMETRY (vx, vy and vz) and OPTICAL_FLOW_RAD (distance) show everytime a “0.00” value.
Show a 0.00 value on your Arduino or in QGC MAVlink Inspector? What values of velocity x,y,z do you expect to see?
Regarding the quaternion
A quaternion is a representation of attitude. This can be converted to Euler angles (roll, pitch, yaw for example) with some loss of information. q = [1 0 0 0] is equivalent to 0 roll, 0 pitch, and 0 yaw. What attitude quaternion is being sent in the ODOMETRY mavlink message?
In the Arduino Serial Monitor. In QGC the values are ok. Even when a move the Flight Controller in my hand, the velocities are 0, and they should be different.
I am not trying to ask for the quaternion, even because I am having this problem of not receiving the ODOMETRY message. But if I did, I believe that it would send the positions x, y and z of the drone (the figure I sent in the last message), since it is the predefined type.
I understand that, but it helps narrow down the issue if the quaternion is the identity (1,0,0,0) or some other value.
In the Arduino Serial Monitor. In QGC the values are ok.
Then this could be a print issue in or some bug in how you are displaying the values, since QGC shows you are getting good mavlink messages out the serial port. You’ll have to share your code. You’ll have to share the rest of your code to debug this.
Ok, new Update. I tried everything you said, and these were the results:
The predefined value for that parameter was the MAV_0_MODE, which is the normal one. I changed that to EXTVISION just to test and the result was even worse, I lost velocity in the data flow and some results were missing.
I asked for that, but the result was [0 0 0 0].
I’ve added breaks in all of them, but the only thing that happened was that I only received the first one (ATTITUDE).
This was the biggest surprise! I thought that the cases “ODOMETRY” and “OPTICAL_FLOW_RAD” were not being hitted too. But then I changed my code to print the name of the message if the cases were hitted, and it printed! So the code is recognizing the message ID.
Here is a screenshot of the new code and the Serial Monitor results:
The reason you are hitting the odometry and optical flow cases in your print statements is due to fall through because you don’t have “breaks” - not because you are receiving the messages. You are only getting the ATTITUDE message which continues on and evaluates the code until it hits a “break” or end of the switch.
Keep things orthogonal. Take a step back and get each feature functioning independent of the rest of the system.
I don’t understand. Aren’t the cases there to check if one of the messages that are being received have the same name as the written in the case? Because, if I miss one letter in the MAVLINK_MSG_ID_ODOMETRY definition it sends an error compiling the code.
Right now I switched the ODOMETRY for the LOCAL_POSITION_NED and it works fine for that msg ID, so I am guessing that’s not it. There’s some error in the livrary or whatever, at least with the ODOMETRY and the OPTICAL_FLOW_RAD messages
I believe that when I write the cases, the code only executes the code inside the case when it reads a message that has the same ID as the one expressed in the case line.
For example, if MAVLink does not send the ODOMETRY message, the code doesn’t execute the Serial.print.
But I can be wrong, I don’t know exactly. But since if I misspell the MSG_ID the Arduino gives as error compiling, I believe that thinking right.
comment out every case but ODOMETRY. Does “odometry” still print over the serial monitor?
Are you 100% sure ODOMETRY is coming over the serial line connected to the Arduino? Is Mavlink Inspector plugged into this serial port or into the USB port on the autopilot? These are two different mavlink instances with different modes and messages. Create a test script in python that generates the desired messages and use that instead of the autopilot.
Read up on switch statements. Are you tracking the output of the below code?
int a = 0
if not, convince yourself the above output is correct.
Yes, I guess so. MAVLink inspector is plugged into the serial port.
I substituted the ODOMETRY and OPTICAL_FLOW_RAD for other message IDs that send similar values, namely the LOCAL_POSITION_NED (vx, vy, vz) and the DISTANCE_SENSOR (current_distance).
The first one works fine, but the distance from the optical flow assumes big random values, although it should have a maximum of 255. Only very rarely the sent values make sense. This problem is the same as this one that I had some time ago, for other message IDs, for which no one answered me.