How to use external module

How can I use out-of-tree driver I wrote? Simply adding my driver name into DRIVERS section does not work. Build fails with message

CMake Error at CMakeLists.txt:430 (add_subdirectory):
add_subdirectory given source “src/drivers/linux_ibus” which is not an
existing directory.

Check this: https://dev.px4.io/en/advanced/out_of_tree_modules.html

And ping @bkueng if you run into problems.

@lord.didger did you solve your problem? I am running into the same issue. I followed the instructions posted for the px4_simple_app module (and renamed it) but I can not include it into the EXAMPLES section of the CMakeLists.txt fle. I get the same error as you posted.

Maybe @bkueng could have a look at it as well?

Thanks for any help, I would really appreciate it :slight_smile:

@notoriou5: I came to conclusion that feature is not vital and abandoned the issue.

Well, okay, thanks anyway :slight_smile: Maybe someone else has a solution?

I have moved the module vtol_att_control out of the tree and into a new Component Folder next to the Firmware. It looks as follows:


Firmware

Components

  • src
    • CMakeLists.txt
    • modules
      • vtol_att_control
        • CMakeLists.txt
        • … (all the original files from vtol_att_control)

I removed vtol_att_control from px4/sitl/default.cmake because I think the module is now already defined as external module. I checked the part about external modules in the main CMakeLists.txt of the Firmware and it seems to find and add my external files correctly.

The issue is now, that files like the FixedwingAttitudeControl.cpp can not find
#include <vtol_att_control/vtol_type.h> anymore.

Anyone any suggestions? Thanks in advance :slight_smile:

Did you also copy over that file?
If so, you probably need something like include_directories(.)

If not, you need to add include_directories()back to where the file is in the Firmware tree.

Hi @JulianOes,
I copied over the whole vtol_att_control folder with all files.

I experimented with the main CMakeLists.txt from the Firmware folder, but I am still not finding this reference. Here is the part of the CMakeLists.txt which I modified a bit:

I am not super familiar with CMake so I am having trouble debugging and figuring out whats wrong.

What about the CMakeLists.txt in the external folder? Does it have the needed include_directories()?

It works :partying_face:

But I had to adjust the folder structure in order to make it work:

-Components
 |- CMakeLists.txt
 |- vtol_att_control
   |- CMakeLists.txt
   |- ...(other files from folder)

So basically I removed the module folder between (I didn’t check if it works with it too, but I ran in a lot of problems having it). The CMakeLists.txt in the Components folder looks like this:

set(config_module_list_external
    vtol_att_control
    PARENT_SCOPE
)
include_directories(.)

Thanks a lot for your help @JulianOes :slight_smile:

1 Like

@JulianOes I have a couple follow up questions to make the our-of-tree module work in VSCode:

  1. I would like to exclude the original vtol_att_control (inside Firmware) from the search path when looking for references, so only the files which are out-of-tree are listed in the results. I added in the .vscode/c_cpp_properties.json file following lines (like here mentioned link)

        "files.exclude": {
            "**/PX4_Firmware/src/modules/vtol_att_control": true
        },
        "search.exclude": {
            "**/PX4_Firmware/src/modules/vtol_att_control": true
        },
    

    These settings do not exclude any files from the search. But If I add these locations to the appropriate file exclude and search exclude section in the vscode setting options, I can exclude the files from search (Ctrl+Shift+F) but still not from the reference search. Is there a way to solve this?

  2. How can I include the EXTERNAL_MODULES_LOCATION= variable during compilation into VSCode? I coudn’t find a working option. For now I use build it through the terminal the first time before using VSCode to build.

  3. I tried to start gazbo tiltrotor in the debug console (SITL (gazebo standard_vtol)) but it gets stuck after building. I adjusted the folder structure in .vscode/launch.json and .vscode/tasks.json . Does the gazebo debug start depend on some other files which I need to change? Debug with the SITL (shell) works with the adjusted folder structure.

  4. How to run the unit tests from an external module?

Thanks,

Hello, I have the same problem.
I’ll try to recap the steps from the External Modules guide to be clear.

  • folder structure

    PX4-Autopilot
        ...
    external-modules/
        CMakeLists.txt
        src/
            modules/
                px4_simple_app/
                    CMakeLists.txt
                    ...
    
  • removed px4_simple_app from the EXAMPLES section of PX4-Autopilot/boards/px4/sitl/default.cmake

  • added the following to external-modules/CMakeLists.txt

    set(config_module_list_external
        modules/px4_simple_app
        PARENT_SCOPE
        )
    
  • added px4_simple_app to the MODULES section of PX4-Autopilot/boards/px4/sitl/default.cmake

  • added EXTERNAL and changing examples__px4_simple_app to modules__px4_simple_app in the external-modules/src/modules/px4_simple_app/CMakeLists.txt

  • removed the PX4-Autopilot/src/examples/px4_simple_app folder

  • building from PX4-Autopilot folder with make px4_sitl gazebo EXTERNAL_MODULES_LOCATION=/absolute/path/to/external-modules

that gives the following error

  • so I moved the file inside src like:
    external-modules/
        src/
            CMakeLists.txt
            modules/
                ...
    

and gives:

  • adding include_directories(.) to external-modules/src/CMakeLists.txt gives the same error above

Am I missing something?
@notoriou5 can you share more details of your setup?
Maybe @bkueng can help?

Thanks

Same error arranging the folder like stated in this thread solution:

Although the external module structure worked for me as documented, it was inconvenient with no clear benefits. I could imagine some scenarios, but I was only adding a PX4-architecture-speecific module, not shared anywhere else. As such, my fork has my additional modules in same repo as the rest of PX4.

You might be making some slight misstep for external modules scheme, but perhaps you can just not have the problem at all and add your modules to your forked repo.

Thanks, but so why PX4 has this feature?
It seems a good modularization approach.

By the way how do you added the external module in the cmake file?
And which version were you using?

I’ve the above problem on 1.12 and 1.11

My experience was with v1.10.3.

As for the purpose of the feature, I don’t honestly know. I was compelled to try it because someone else thought it would be somehow useful. I found no benefit and only overhead by doing something special and off the normal workflow.

Since then, my module sits in our fork under src/modules, just like any other module. There are even some benefits to this approach. I could not figure out how to add new uorb topics in some out-of-tree manner, for example. It is easy to do in-tree.

I just thought I’d share about my wasted effort in case it would help you avoid such. YMMV and you may have a better use case, than I did.

I appreciate your help in trying to avoid time wasting.

I’m just trying to understand if it’s a broken feature or if the documentation is incomplete or what else.

Seems documented here as well, but I didn’t tried as I’m stuck with the modules
https://docs.px4.io/master/en/advanced/out_of_tree_modules.html#out-of-tree-uorb-message-definitions

I misspoke about outside messages. I should have said publish to same topic type with different name. Inside tree it is a simple as adding an “alias” in the msg file.

I still have the external module repo and will report back if I can make it work in v1.12 workspace.

Ok, thanks!

I tried with v1.10 with same errors, probably I’m missing something.
Let me know how you declared the module in the target cmake file.

@guglielmodev, I suddenly recalled that perhaps - is unacceptable by some actor in this toolchain (CMake?). ISTR having that problem and just got lucky, somehow. Try using external_modules instead of external-modules.

external_modules/src/CMakeLists.txt:

set(config_module_list_external
	modules/ai_vtol_att_control
	PARENT_SCOPE
	)

external_modules/src/modules/ai_vtol_att_control/CMakeLists.txt:

px4_add_module(
	MODULE modules__ai_vtol_att_control
	MAIN ai_vtol_att_control
	SRCS
		ai_vtol_att_control_main.cpp
		vtol_type.cpp
		tailsitter.cpp
	EXTERNAL
	)