Antenna Tracker
Antenna Tracker with the Nanostation mounted the wrong way, 2 February 2023.
Quick Start Guide
Setup
- Connect an Ethernet cable between the Arduino and the router.
- Connect power to the Arduino. After aquiring a GPS lock (which may take a couple minutes, especially if at a new location) and no telemetry, the antenna tracker will point at Geisel.
- Make sure GCS is setup correctly and powered on. Aircraft GPS telemetry will be forwarded, and antenna tracker will begin operation.
Troubleshooting
- Antenna tracker spins at a constant speed without stopping
- Something has caused the Arduino code to crash. Repower the antenna tracker to reset it.
- Antenna tracker is not pointing at the plane
- Due to GPS errors, the antenna tracker is not accurate at close range (<10m).
Objective
Point the antenna at the plane.
System Overview
To get the location of the plane, the GCS sends the most recent GPS location from the plane to the Arduino through the Ethernet connection. The antenna tracker has its own GPS onboard, and computes the azimuth and elevation angles needed to point from antenna tracker to the plane using some coordinate transformations and trigonometry. The elevation angle is then written to the elevation servo, while the azimuth angle is fed into a PID controller to align the antenna tracker with the setpoint using a magnetometer.
Coordinate Transformations
The GPS data we get from the aircraft and the antenna tracker GPS consists of a latitude, longitude, and altitude. These values do not have much meaning without a reference ellipsoid (where are we measuring altitude from?). We will use the semi major and semi minor axis values defined by WGS84 for our calculations. Now that we have our reference ellipse, the first thing we do is use it to convert these coordinates to an Earth Centered, Earth Fixed (ECEF) coordinate system. This is a 3D coordinate system with the origin located at the center of the Earth. By substracting the ECEF location of the station from that of the aircraft, we can obtain the vector pointing from the antenna tracker to the aircraft. Now, we rotate it so that it is in East, North, Up (ENU) coordinates relative to the antenna tracker. The latitude and longitude from the antenna tracker GPS is used to do this. This wikipedia page explains these processes in more detail and with the relevant equations.
Trigonometry
Now that we have a vector pointing from the antenna tracker to the aircraft in ENU coordinates, we can compute the azimuth and elevation angles required to point at the plane.
azimuth = atan2(east, north)
The elevation is slightly more complicated because we need to find our horizontal distance first.
hdistance = sqrt(east^2 + north^2)
elevation = atan2(up, hdistance)
Now, the antenna tracker knows where it should point! This angle can be written to the elevation servo, but there is still more to do before we know what to send to the azimuth servo.
PID Controller
Why do we need a controller for a servo?
At this point, you may be wondering why we need a PID controller to control a servo. Normally, servos are sent a PWM signal with a duty cycle corresponding to the desired angle, but our azimuth servo has been modified. We took out the potentiometer and replaced it with a voltage divider so that now, the servo thinks it is always in its middle position. Additionally, we have taken out the mechanical end stops so that it is free to rotate continously. With a little deception, our servo is now a PWM controlled bidirectional motor. When given a duty cycle greater than 1500 µs, the servo will spin indefinately, and when given a duty cycle less than 1500 µs, the servo will spin the other way. The speed of rotation depends on how far the duty cycle is from 1500 µs (although we max it out fairly early, so our useful range is around 1400-1600 µs).
PID Controller Implementation
In order to compute the command to send to the servo, we first need to find the error. This is equal to the setpoint (where we want to be) minus the current state (where we are). But there is a problem with simply subtracting these two values. Consider the case where our setpoint is 6 degrees, and our current state is 359 degrees. Our error would then be -353 degrees. This would cause the antenna tracker to spin all the way around the long way, and we would prefer to take the short path. What we want instead is an error of +7 degrees. In Arduino, we use the following to achieve this:
errorDegrees = -(fmod(state - setPoint + 540, 360) - 180);
Now, we can use our error value to get proportional, integral, and derivative terms.
proportional = errorDegrees;
integral = integral + (errorDegrees / frequency);
derivative = (errorDegrees - previousError) * frequency;
previousError = errorDegrees;
Our controller output is just the sum of these terms multiplied by coefficients that we input during tuning.
controllerOutput = pGain*proportional + iGain*integral + dGain*derivative;
The tracker was tuned by trial and error. Because the magnetometer signal was fairly noisy, our D term could not be raised too high. The P term was just raised as high as it could go without causing overshooting, and the I term was raised until it started causing problems at which point we selected a slightly lower value. A more rigorous tuning method may result in better performance, but for now we have a somewhat working system.
Improvements
Latency
Currently, the antenna tracker recieves aircraft telemetry once per second. This results in the antenna tracker "jumping" to each position every time it gets a telemetry update. While this currently may be acceptable for keeping the plane within the beam width of the antenna, a more continuous movement would look way cooler. Possible solutions include increasing the telemetry rate or including a predictive filter.
Cable twisting
Currently, the Ethernet cables for the Arduino and Nanostation run through the azimuth bearing. After many revolutions, these cables twist together. This might be an issue at competition if the waypoint mission includes many laps around the ground station. Slip rings would be the perfect solution, if they weren't so expensive.