I thought I’d start a thread to document my progress and struggles in building a custom flight controller for my ROV. Unfortunately due to cost constraints and living in Australia I cant really justify the cost of the navigator flight controller so I decided to try giving it a shot to design/build my own. I’ve used the navigator schematics and integrated more easily available parts in my design.
So far I’ve cloned the ardupilot repo and modified all the navigator components in the code (I’ll be adding a new board section once its all working) to change the main sensors used and got it to build the custom firmware successful. I’ve also drawn a schematic heavily influenced by the navigator as well but am currently waiting on parts to arrive so I can build it, then start testing and troubleshooting any issues I encounter (I expect there to be a lot).
My main concern at the moment is how to integrate the controller with blueOS as I’m not too sure what the process will be to add a new controller. Will it be as simple as plugging the controller in and loading the custom firmware into blueOS or will I need to make an addition to blueOS core in the “flight controller detector”?
Any advice is greatly appreciated and I’ll continue to update this thread as I make progress if anyone else wishes to follow in my footsteps. I’ll also be creating a Github repo for all the schematics, designs and firmware modifications I make once I get some extra time.
Due to the required channel volumes, our flight controller is a stack of boards. We have a board that handles the communications and on it is a chip with a unique identifier/address. The detect.py looks for this identifier. If you look in the detect.py script, look for “argonot”, that’s how our board is identified.
We’re busy with the firmware. We’ve managed to fork the BlueROV2 and a Rover’s firmware that has us starting. We have to integrate stepper motor control that I believe would integrate with the firmware.
We’re using the same sensors as is on the Navigator, however, only some reflect—a work in progress. @williangalvani I believe is the person to support the firmware side.
Thankfully my “flight controller” isn’t that complicated and has most of the same functions as the navigator but using a different IMU (MPU9250). The main reason I didn’t go with the Navigator is cost, the whole budget for my project is around $1000aud, but I have plenty of time to spend on it and am willing to trial and error until it works.
I saw this in the source code and forked the repo to attempt to add my board’s identifiers but it failed to build after I made the changes. I ran out of time to try and diagnose the issue but the quick look I did didn’t seem to have any helpful pointers.
Okay, so after a long break from this project, I’ve finally come back with fresh eyes and a lot more experience with code in general.
So far I’ve forked the BlueOS repo and added a custom placeholder board to the flight_controller_detector under the Ardupilot service. I also managed to get a docker image created but haven’t had a chance to test it just yet. If all goes well and BlueOS detects the “flight controller” I’ll start working on modifying ArduPilot to build firmware for it.
I just have a question regarding the way linux based boards are detected, I understand that BlueOS checks for addresses on the i2c ports but if 2 boards had the sames i2c sensors how does BlueOS decide which one to use or does it present the option to the user?
I’ll update this topic later today with the results from my testing. If I ever get everything working I’d be interested in documenting the steps in the wiki or something to make it easier for people in the future who choose the same path.
The boards are checked for in order of class hierarchy, so if you had all the same I2C devices as a Pi4 Navigator, and your board inherited from NavigatorPi4 to reflect that commonality, then currently your board would register as a Pi4 Navigator before it even gets to your subclass.
If you have the same I2C devices but different serial devices then the detection mechanism could presumably be extended to account for that in its differentiation (although that may be somewhat involved to do).
It’s perhaps worth noting that BlueOS does allow switching between detected boards (when in Pirate Mode), so if necessary there could be a user selection option where multiple boards are presented, but it would require some refactoring of that backend code that assumes there can only be one Linux board attached, and it’s likely preferable to have some hardware based detection mechanism so users don’t need to concern themselves with that.
If there’s at least one Navigator I2C peripheral that your board doesn’t have then the current detection logic should be sufficient. If you only have extra stuff / different non-I2C components then the logic will need to be changed to some extent to account for that, hopefully in some minimal / reasonably straightforward way
Okay so I managed to get BlueOS to build the docker images for me and had it detect my “flight controller”. I then added the flight controller to ArduPilot and created the firmware file, however I ran into an issue when trying to upload the firmware to BlueOS and kept getting an error.
After a bit of troubleshooting I think the error was due to the board sub-type in the FirmwareInstall.py service not matching the sub-type in the firmware file (Was BoardSubType.LINUX_NAVIGATOR but I changed it to BoardSubType.LINUX_PLACEHOLDER)
After changing this the workflow fails to pass and I can’t seem to work out the issue. I’ve narrowed it down to the test_FirmwareInstall.py but can’t seem to solve the problem. I’m hoping someone might have a solution or be able to point me in the right direction. Unfortunately, I have very limited knowledge of python and am mainly relying on my c/c++ experience so I wouldn’t be surprised if I’m missing something obvious.
I’m not sure how much bandwidth we have to go deep into this at the moment, but it would definitely help if you could provide the errors/tracebacks you’re getting, either through uploading your system logs (and possibly checking them yourself if you haven’t already), or directly looking at the logs for the ardupilotmanager service through the BlueOS Terminal
I found what was causing the error, I had to edit the download link for ardupilot_fw_decoder to include LINUX_PLACEHOLDER in the BoardSubType enum.
I loaded the new image onto the rpi4 and BlueOS detected the board correctly and let me load the ArduPilot firmware successfully. However I’m now running into an issue with the ardupilot manager constantly throwing the ARDUPILOT_VEHICLE_TYPE_FETCH_FAIL error and I can’t seem to work out whats causing it
From a brief look at the log file, it seems to think it’s successfully installing the firmware, and then when it runs it the autopilot is not responding.
You could try switching to a different MAVLink router option (since BlueOS offers a few via the MAVLink Endpoints page), but it seems more likely this is an issue with your custom autopilot firmware than a problem in your BlueOS build.
That seems to check out from what I understood from the logs.
I think my plan now will to be to attempt to port an existing Linux based flight controller (most likely the OBAL because I have the sensors laying around) so I don’t have to modify ArduPilot as much. If I manage to get that working I’ll then come back to wrapping my head around the ArduPilot source.
When building the firmware from scratch to upload to the rpi4 I’m assuming the ArduPilot manager is just looking for the bin file produced when running the command ./waf sub after configuring for the correct board.
Sorry for asking so many questions but thank you for all the help you’ve given so far
I think for now I’m going to put this back on hold and see if I can make a different idea I’ve had work but I might come back in the future and have another crack at it.