Skip to content

Integrate parts of libmav into MAVSDK and add MavlinkDirect plugin#2610

Merged
julianoes merged 26 commits intomainfrom
pr-add-libmavlike
Jul 24, 2025
Merged

Integrate parts of libmav into MAVSDK and add MavlinkDirect plugin#2610
julianoes merged 26 commits intomainfrom
pr-add-libmavlike

Conversation

@julianoes
Copy link
Copy Markdown
Collaborator

@julianoes julianoes commented Jul 12, 2025

This is work towards MavlinkPassthrough for language wrappers called MavlinkDirect.

The work is based on a hard fork of libmav. The fork is required because:

  • MAVSDK doesn't work with C++ exceptions
  • rapidxml is replaced with tinyxml2 as rapidxml is not the right choice without exceptions
  • The connection classes are not required.
  • Header only is a poor way to manage dependencies and unnecessarily increases compile time for incremental builds.

The MavlinkDirect allows you to:

  • Send and receive MAVLink messages based on just the message name and fields/data as JSON (strings which are easily forwarded to and parsed in language wrappers).
  • Add custom MAvlink xml to send and receive messages

While this seems to be working end to end in system tests, most of the work is Claude Code generated slop, so I will have to review this properly myself.

@julianoes julianoes force-pushed the pr-add-libmavlike branch from b48a3b5 to 67dcac6 Compare July 15, 2025 09:00
@julianoes julianoes marked this pull request as ready for review July 17, 2025 22:56
@julianoes julianoes force-pushed the pr-add-libmavlike branch from 67dcac6 to 45e410c Compare July 17, 2025 22:57
Copy link
Copy Markdown
Collaborator

@JonasVautherin JonasVautherin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice to have this feature! 🚀 🚀

Comment on lines +16 to +19
set(MAVLINK_MINIMAL_XML "${DEPS_INSTALL_PATH}/include/mavlink/message_definitions/v1.0/minimal.xml")
set(MAVLINK_STANDARD_XML "${DEPS_INSTALL_PATH}/include/mavlink/message_definitions/v1.0/standard.xml")
set(MAVLINK_COMMON_XML "${DEPS_INSTALL_PATH}/include/mavlink/message_definitions/v1.0/common.xml")
set(MAVLINK_ARDUPILOTMEGA_XML "${DEPS_INSTALL_PATH}/include/mavlink/message_definitions/v1.0/ardupilotmega.xml")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this creates a hard dependency on the superbuild. Maybe it would be worth having the path as an option, e.g. MAVLINK_MSG_DEFINITIONS_PATH, and the superbuild would by default set it to ${DEPS_INSTALL_PATH}/include/mavlink or something?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that too but then it worked in CI...

@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.13)

project(external-libmavlike)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the name, libmavlike 😬

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might rename my fork as well.

set(MAVLINK_ARDUPILOTMEGA_XML "${DEPS_INSTALL_PATH}/include/mavlink/message_definitions/v1.0/ardupilotmega.xml")
set(EMBEDDED_XML_HEADER "${CMAKE_CURRENT_BINARY_DIR}/embedded_mavlink_xml.h")

add_custom_command(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am always nervous with add_custom_command. CMake is really not a super nice scripting language, and those always look cryptic to me. It took me way longer than I'm comfortable with to realise that this really just creates one header file called embedded_mavlink_xml.h that gets included later and that doesn't change unless we update the mavlink dependency.

The risk I see is going the road of the PX4 build system, which is so custom that I don't consider it to be CMake anymore, and it is always painful for me to read/use.

What about doing it like we do for the proto files, i.e. generate it once and version it? Just like you only need to run generate_from_protos.sh when you modify the protos, you would only have to run generate_embedded_mavlink.sh when you modify mavlink. And nobody should ever have to do it except those who update libmavlink in MAVSDK (so... pretty much the maintainers).

So that it keeps the CMakeLists readable, and I'm pretty sure that a shell script would be a lot more readable than this custom command 🙈.

What do you think?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree in terms of readability but would you then check the generated header file in, or generate it each time?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check it in, like we do with the protobuf files. Maybe in a generated/ folder, to be consistent?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that but I want to make it easy for users to swap this out as well. I guess we can make it, so you need to load "common" manually before using it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought, a script like ./tools/generate_mavlink_direct.sh that would generate the file and put it in the right place (something/generated/mavlink_embedded_headers.h). And that file is versioned. So that it doesn't require a change in the CMakeLists (except for installing the header), users don't have to care about it but they can always update libmavlink and regenerate the file with the ./tools/generate_mavlink_direct.sh script.

Exactly like we do now with the proto files.

Or does that sound to complicated?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm somewhat tempted to leave it as is because it has the advantage that the MAVLink version included will match the one from the headers, and if someone changes the C headers, both change accordingly, and don't get out of sync.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, your call. I'm just always nervous when I see add_custom_command in CMake, but I guess it won't go as far as in did in PX4 anyway 🙈.

julianoes added 25 commits July 24, 2025 10:52
This will support something like MavlinkPassthrough for language
wrappers.
This will bring MavlinkPassthrough to the language wrappers.
This was somewhat duplicate, we can just use a subscription with empty
string to get all messages.
This is nice after auto-generation where a huge diff is just noise,
especially for an LLM to parse.
This adds two examples:
- One to show the GPS message JSON output
- One to show stats about MAVLink messages arriving.
@julianoes julianoes force-pushed the pr-add-libmavlike branch from 459971f to fefa769 Compare July 23, 2025 22:53
@sonarqubecloud
Copy link
Copy Markdown

@julianoes julianoes merged commit b547752 into main Jul 24, 2025
52 checks passed
@julianoes julianoes deleted the pr-add-libmavlike branch July 24, 2025 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants