The motivation behind this project was to improve issues with dropped packets from the main comms antenna to the rover in the field. In previous years, the team had a manual rotator which allowed them to crank a pulley system to rotate the antenna manually until a certain threshold of packet loss was met (this was gauged by inspecting how stable the video feed from the rover was). This project aimed to automate that process. While this was originally proposed as an electrical engineering capstone project, it was interdisciplinary in scope. The "finished" project includes mechanical, electrical, and software design.
At its core, the problem behind this project is a localization problem. The goal is to locate the rover in the field and then rotate the antenna towards it. Originally, our team researched traditional radio direction finding techniques such as psuedo-doppler or phased directional antenna arrays- but our respective skill sets and budget made these solutions prohibitive. Instead we chose to use GPS to locate our rover. There were 2 gps modules- one on the rover and one on the base station. Positional data from the rover was sent via LoRa to the base station and then the corresponding bearing angle between the base station and the rover's position was calculated. This angle was then sent to an arduino-based servo controller on the antenna module to physically rotate the antenna to face the rover. Check out the project showcase page linked below to read about the entire project- not just my contributions
My contributions to this project were developing the tracking algorithm and the corresponding UI for the rover control station. For the tracking algorithm- my main tasks were to 1- capture the reported latitude/longitude from both the base station and the rover, and 2- utilize those coordinates to calcualate what direction/bearing the antenna needs to rotate to point towards the rover. The entire algorithm was written in Python 3 and runs on a Linux operating system
The coordinates from the rover are obtained using the PySerial library. A USB connects the the LoRa receiver board to the computer where the tracking algorithm runs. PySerial is used to open a port for the USB and parse data from the receiver to turn it into useable numbers for the tracking algorithm. For the GPS on the base station, GPSd is used. GPSd is a service daemon for linux that allows users to communicate with various GPS modules from the command line and via a Python or C++ library. I utilized the inbuilt functions from this to obtain the GPS coordinates from the base station once on startup- since the base station GPS doesn't move. Once the coordinates are obtained they are fed into a function that calculates the forward bearing along the great-circle arc. I ended up rolling my own function at first, but later switched to using the python Geodesic library for higher accuracy. Once the bearing angle is calculated, it is sent to the arduino-controlled antenna rotator over USB- again using PySerial.
Keen readers may notice that the above work didn't fully address the localization problem- and that is correct. The implementation above naively assumes that the GPS coordinates reported as the rover moves are completely accurate. See the below section on "Lessons Learned" for how I'm working to address that.
The control station for the rover uses PyQt5 as a base for UI. For the tracking algorithm, I wanted the ground station to display the current bearing angle of the antenna as well as allow the user to manually send angles to the antenna rotator in the case that the tracking algorithm is not working properly. The updated information about the bearing angle and the coordinates was transferred to the UI via a UDP socket that communicates from the tracking algorithm to the UI code. I am aware that sockets are not the typical choice for interprocess communication in Python- but this ended up being what played the nicest with PyQt. Since the rover team has since moved away from PyQt due to numerous issues with its 'event-loop' structure and blocking essential tasks- I will likely have to modify my code a bit to work with the new, web based UI.
As I mentioned above- the work I did with the tracking algorithm didn't fully address the issues with localizing the rover. Coursework I completed after the completion of the capstone course opened my eyes to just how unreliable relying on measurement from a single sensor is. When testing the antenna rotator with a constantly moving rover, it ended up pointing in incorrect directions and also ended up rotating with every update of the GPS coordinates- including noisy measurements. This is not what we wanted. The problem here was two-fold: 1- the GPS module used was outdated and somewhat inaccurate (circular error probability of 50% within 2.5m), and 2- the sensor measurements were not filtered at all.
The first step to address this issue is to update the GPS to one that is more "accurate". We have obtained a new GPS module but have yet to test it. The second is to filter the GPS data. A concept I was introduced to in my intelligent robotics class is kalman filtering. If I just wanted to filter the gps data alone- the best way to go about this via the literature would be to either develop a single variate Kalman filter, or possibly use a least squares filter. However if we want more pose accuracy- the typical approach is to fuse values from multiple sensors. That way if one sensor is reporting position in error, the other sensor's measurement can improve our estimate of position.
My current plan is to implement fusion of a 9-DOF IMU and GPS module using either an Extended Kalman Filter or an Unscented Kalman Filter. Since this will be running on a RPI 2040 microcontroller- I will have to take care to keep the computational complexity of the filter within the limits of what the processor can handle. Unscented Kalman Filters by their nature are usually less computational complex than the EKF- however the EKF is more commonly used for sensor fusion applications in literature. Check back on this page- or on my github- to see the development of the localization part of this project.