I was wondering if anyone can confirm that the LabVIEW code for calculating checksums at this link is still valid for the newest form of MAVLINK:
I have been able to monitor the serial communications from qgroundcontrol and RealTERM and verify the message contents but have not been able to confirm the checksum.
If this is not correct, could someone please explain to me how the checksum is calculated or if LabVIEW code has been updated to reflect the newest checksums that would be great as well.
here is the code the planner uses for crc
in mavlink 1.0 you need to use the seed value also. all packet types have one.
What is this seed value you speak of?
I was the one who added the 'seed' in MAVLink 1.0, so maybe I should explain how it works and why it was added.
While we were using MAVLink 0.9 we had a couple of incidents where the XML describing a message that was in active use changed. The change was such that the length of the message didn't change, but the fields did. This meant that when a MAV using the old code was talking to a ground station using updated code that the fields were badly corrupted. The MAVLink 0.9 protocol completely relied on everyone being careful not to change the meaning or format of any existing message. With so many people working on MAVLink this was hard to enforce.
So for MAVLink 1.0 we decided to solve this problem by adding a 1 byte 'seed' to the checksum based on the XML for the message. When the mavlink code generator runs, it takes a checksum of the XML structure for each message and creates an array define MAVLINK_MESSAGE_CRCS. This is used to initialise the mavlink_message_crcs array in the C/C++ implementation, and is similarly used in the python implementation.
When the checksum for a message is calculated, this extra byte is added on the end of the data that that the checksum is calculated over. The result is that if the XML changes then the message will be rejected by the recipient as having an incorrect checksum. This ensures that only messages where the sender and recipient are using the same XML structure will get through (or at least it makes a mistake much more unlikely).
If you are doing your own implementation of MAVLink 1.0 you can get this checksum in one of two ways:
This is the python code that calculates the seed:
'''calculate a 8-bit checksum of the key fields of a message, so we
can detect incompatible XML changes'''
crc = mavutil.x25crc(msg.name + ' ')
for f in msg.ordered_fields:
crc.accumulate(f.type + ' ')
crc.accumulate(f.name + ' ')
return (crc.crc&0xFF) ^ (crc.crc>>8)
Notice that it uses the same x25 chcksum that is used at runtime. It calculates a CRC over the message name (such as "RAW_IMU") followed by the type and name of each field, space separated. The order of the fields is the order they are sent over the wire. For arrays, the array length is also added.
My apologies if this seed has caused any confusion. Hopefully the above will explain the reason it was added.
thanks for the explanation. Today I also noticed the finalize_message functions inside mavlink_helpers in the libraries folder of the git repo, although I don't know if they always have been there. Is it so that these need to be called if one uses pack_msg_X? I'm wondering since seem to have problems with my home built ardustation since recent upgrades and I wonder if messages are dropped silently due to CRC "errors" that aren't any.
The finalize functions do the checksum over the entire message, and also add the extra seed needed for the new method, so they were needed in MAVLink 0.9 also.
Maybe you should add some debugging code to see why you aren't getting messages through?
Thanks for the reply. My problem turned out to be a hardware cabling/Xbee packet issue, hehe.
What confused me now more is that it actually works. As far as I can see the ardustation code still happily calls the pack functions without ever calling finalize and APM still receives parameter updates.
Btw: are you still developing pymavlink? The Xbee issue I had (Arduino Uno sending Mavlink heartbeats being received via USB but not via Xbee since they seem to become split or otherwise corrupted) seems to be fixable with some more careful state maintenance when parsing the incoming Mavlink stream (see Heino's latest ardustation code) but with pymavlink I did not manage. Maybe I didn't use it right though. My cutecom showed incoming heartsbeats though.
Anyway, I'm back ardustation now.
Thanks for you detailed explanation. I think I understand it now. However when I try to generate the checksums, I cannot get the right result.
Here's a message (a heartbeat) straight from the ardupilot (mavlink 1.0):
0xFE 0x09 0x13 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x02 0x03 0x51 0x04 0x03 0x94 0x88
CRC Extra added (heartbeat CRC extra is 50, which is 0x32):
I just CAN'T get 0x94 0x88 to come out.
Even if I don't add the seed byte to the message, I still get results that don't match the checksums the APM generates. As I understand the seed value should come after the data bits, so the very last byte besides the resulting checksum bytes.
Your expertise would be greatly appreciated.
Thanks in advance,
Attached is a labview example updated to highlight MAVLINK 1.0. You are not actually substituting the CRC extra value into the message. You run the original message through the checksum calculation. Next, rather than your conditioning value being FFFF you take the value calculated from the checksum and use that as your conditioning value and your input is the CRC extra value.
Thanks for your reply,
The labview code is very helpful. When I run the message through the labview checksum I get the expected checksums. So the problem is with me not the Mavlink protocol.
So when I run this message (heartbeat):
through just the first checksum generator (in labview - before the second seed conditioning one), I do not get the value expected like from here:
I put an indicator before the seed conditioning, and I get a checksum of 7E3F (in labview) instead of D0C0 as the online generator gets. So herein lies the problem. As far as I can understand the message is first passed through a standard CRC16CCIT calculator with a xFFFF conditioner and x1021 polynomial. However these values do not match. Any thoughts?
Thanks for any help,
Here is the labview with the indicator I added