Recently I added support in ArduPilot to talk directly with Sololink (the remote controller that comes with Solo). The idea was to use it on different frames, particularly the ones controlled by Linux-based boards, without changing much on the controller itself. In the end some change had to be done, but it's mostly compatible changes. Above is a maiden flight of Aero Compute Board (without the microcontroller that comes with the RTF) controlled by Sololink as the RC.
I started this before the code for Sololink became open source so I had to do some "reverse engineering", parsing the packets coming out of the controller when communicating with Solo. My first goal was to get the values for the RC sticks and checking where and how they were sent via wifi. After some trial and error with the help of tcpdump, tshark and reading they pairing python scripts that are executed on the controller to figure I had to change the runlevel, this PR has been created: https://github.com/ArduPilot/ardupilot/pull/6708
However the "Waiting for solo" screen on Sololink's screen was still there. Someone told me (I think it was on Facebook) that it would be sufficient to prepend each mavlink packet with 56 zeroed bytes and that did the trick. Since now the code running on Sololink is opensource, I could analyze it and figure out these 56 bytes are used to maintain a log of the timing and sequence on each part of Solo's stack (pixhawk2, imx6 on solo, sololink, stm32 on sololink). Note that the names I'm using may not be correct (I see mentions to artoo and other names in the code that still didn't map correctly in my head). The complete header for the packet is here: https://github.com/OpenSolo/sololink/blob/master/flightcode/util/link_packet.h#L9-L17. I did some little changes on this part of the code to tell the telem_ctrl process to ignore this header. You can check the patch here:
https://github.com/lucasdemarchi/sololink/commit/b367d4b756396c6f5faa1d741e870dba4abfe2ca . In order to build telem_ctrl, you will need their toolchain which can be built with an ancient Yocto version (which apparently only builds correctly with Ubuntu 14.04, not any version later or other recent Linux distros). With a docker container created with all the dependencies, following https://github.com/OpenSolo/3dr-arm-yocto-bsp and https://github.com/OpenSolo/sololink/blob/master/flightcode/telem_ctrl/Makefile#L6-L8 it's possible to build the toolchain.
Here is a step by step guide to get it working on Sololink:
- Update your solo and sololink to the latest version in order to ensure all the steps below apply (I have no idea if they were different before)
- Edit /log/3dr-pairing.conf and add the MAC address of your Linux board there. If you already paired with a Solo drone already, it should have the Solo's MAC in this file.
- Force Sololink to always give the same IP to your board (and it's particularly useful to give the 10.1.1.10 IP since it's the Solo's IP): edit
/etc/dnsmasq.conf and add the hostname of your board like
- Make Sololink start on runlevel 4 with the "Solo's IP" (which is actually your board's IP) set: add
echo 10.1.1.10 > /var/run/solo.ip to
/etc/rc.local. Then edit
/etc/inittab and change the default runlevel to 4.
- Build the telem_ctrl program mentioned above, copy it over to
/usr/bin in Sololink. It's a good idea to backup the original version in case you want to use the controller with a solo. This is the only incompatible change as far as I could notice.
- In your Linux board running ArduPilot, give the parameter
-A udp:10.1.1.1:14550. Sololink expects mavlink protocol on this port, sending the packets to
a) stm32 process that communicates with the microcontroller in charge of updating the screen, getting the RC inputs, etc;
b) a logging process and
c) any other board connected to the controller (so you can use a GCS). What the software on Sololink does is very similar to what mavlink-router does on the Aero RTF, routing mavlink packets to the several components on the Linux board.
What works right now are: the sticks to control the drone and the screen to show telemetry data like altitude. The button events are apparently sent to another port and are still not working.