I’m trying to make PX4 firmware and add a very simple MAVLINK message. To put it kindly, the tutorial to make expand on the PX4 Firmware is absolutely useless, but I’ll go on about that later. Just read the whole post because there are a lot “kinda works” and “if I do X then Y works but Z breaks” type problems.
I can build on Windows and Linux just fine, add a uORB message just fine, but cannot for the life of me get MAVLINK messages to work.
Here’s my uORB message (mav_test.msg):
uint64 timestamp
uint8 mav_data
It’s included, it’s building fine.
Here’s my custom_messages.xml:
<?xml version="1.0"?>
<mavlink>
<include>ardupilotmega.xml</include>
<dialect>2</dialect>
<messages>
<message id="9101" name="MAV_TEST">
<description>Testing MAVLINK</description>
<field type="uint64_t" name="timestamp">Timestamp</field>
<field type="uint8_t" name="mav_data">MAV Data</field>
</message>
</messages>
</mavlink>
So far, this is building fine with a few exceptions I’ll explain later.
Here are my includes in mavlink_messages.cpp:
#include <uORB/topics/mav_test.h>
#include <v2.0/custom_messages/mavlink_msg_mav_test.h>
Here’s my function in mavlink_messages.cpp:
class MavlinkStreamMavTest : public MavlinkStream
{
public:
const char *get_name() const override
{
return MavlinkStreamMavTest ::get_name_static();
}
static constexpr const char *get_name_static()
{
return "MAV_TEST";
}
static constexpr uint16_t get_id_static()
{
return MAVLINK_MSG_ID_MAV_TEST;
}
uint16_t get_id() override
{
return get_id_static();
}
static MavlinkStream *new_instance(Mavlink *mavlink)
{
return new MavlinkStreamMavTest(mavlink);
}
unsigned get_size() override
{
return MAVLINK_MSG_ID_MAV_TEST_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES;
}
private:
/* do not allow top copying this class */
MavlinkStreamMavTest(MavlinkStreamMavTest &) = delete;
MavlinkStreamMavTest &operator = (const MavlinkStreamMavTest &) = delete;
protected:
explicit MavlinkStreamMavTest(Mavlink *mavlink) : MavlinkStream(mavlink)
{}
bool send(const hrt_abstime t) override
{
mavlink_mav_test_t msg{};
msg.mav_data = uint8_t(1234);
mavlink_msg_mav_test_send_struct(_mavlink->get_channel(), &msg);
return true;
}
};
I included the lines to add the stream just after and to enable the stream in …/init.d-posix/rcS, and they have never given me any issue. Those are just fine and not a part of the problem.
Now, if I build the program is it stands with an include in the custom_messages.xml and copy over the files, I get tons of errors on build. I’m going to include an image below. It’s a lot.
Now, if I remove the include in the XML, generate files, then move them over, I can build the firmware and it will run and send the message just fine. But the problem is QGroundControl refuses the message and drops it. I brought this up with DonLakeFlyer who mentioned it may be an issue with CRC. Lo and behold, there’s no CRC data for the custom message being included in the program. That’s in v2.0/custom_messages/custom_messages.h. That doesn’t get included because if you include v2.0/custom_messages/mavlink.h, nothing ever gets included because MAVLINK_H is already defined and everything in the file is skipped. So I have to include the message file directly to get things like the message ID, which obviously leaves out important data like CRC data. It’s a circular situation where you can’t include all the data.
There might be a fix for this as is, but it would include manual splicing of files, which I have not been successful with and is not something that a user should have to do anyway.
There is so much not working here it’s ridiculous. There is zero help in the tutorial or online I can find after over 100 hours of working this. The fact that following the steps of the tutorial causes even more issues than fucking around and trying random other things is a problem. This is all I have to go off of and no amount of tweaking, file splicing, comparing to other questions online, etc. gets me any closer.