He asked if I could make a function for calculating the optimal indicated speed 'v' at different headwinds and altitudes. The Significant Range of an airplane is defined as fuel flow over ground speed. I find the name 'Significant Range' quite unhelpful but hopefully you can imagine that if you can maximize your ground speed while minimizing your fuel flow, you will be able to travel the furthest distance. Therefore, finding the indicated speed which minimizes your Significant Range will be the speed that takes you the furthest distance.

`def specific_range(a, b, m, k1, k2, k3, v, W, H): return (a*v + b*m*((k1/k3)*(v**4)+(k2*W**2)/k3))/(v*(m*v - H))`

When trying to minimize a function, we want to get to the bottom of the curve of that function. We know we are at the bottom of this curve when the slope of the function equals 0. Getting the derivative of a function at a given point will give us the slope at that point. Here is the derivative of the Significant Range function. If anyone would like to see how this is found, here's a link to my derivation.

`def derivative(a, b, m, k1, k2, k3, v, W, H): return (m*(b*((2*k1*m*v**5)/k3 - (3*H*k1*v**4)/k3 - (2*k2*m*W**2*v)/k3 + (H*k2*W**2)/k3) - a*v**2))/(v**2*(m*v - H)**2)`

If we find the indicated speed at which the derivative of the function equals 0, that will be the speed that minimizes our Significant Range. Unfortunately this is not a simple task because our derivative function is a quintic polynomial (of degree 5). We can find the roots of lower order polynomials using universal functions such as the quadratic formula (the '-b formula') for quadratics, but with quintics there is no one-stop-shop for finding the roots... so we must be more creative.

Gradient Descent is an algorithm commonly used in AI to minimize very complex functions. In our case, it is an intuitive way to get down to the bottom of the hill of our function. Basically we start off at the top of the hill, check what direction the hill is sloping in, then move a bit in that direction until we reach the bottom. For our Significant Range function, we know that we will not want to move at negative speeds (flying backwards) so we can choose the 'top of the hill' to be 300 knots, which is about the maximum speed of a propeller aircraft. With this choice, we know that going to the bottom of the hill from this point will give us a positive value, as the function slopes towards 0:

If we were to choose a negative value as the 'top of the hill' we would still make it to the bottom of the hill but would end up in the wrong valley:

Here's the Gradient Descent algorithm which returns the best indicated speed starting in the correct position of 300 knots:

`def gradient_descent(a, b, m, k1, k2, k3, W, H, num_iters=100, learning_rate=10000): v = 300 for _ in range(num_iters): v = v - learning_rate*derivative(a, b, m, k1, k2, k3, v, W, H) return v`

And here's the output using some default values along with a display of how the value was reached:

`gradient_descent(16, 39, 1.58, 0.037, 1.5, 469350, 3000, 20)`

If you would like to mess around with it yourself and see the actual code along with some explanations, you can check out my Colab Notebook. And as always, if you think I'm an idiot and have made a horrible mistake, please let me know!

]]>"There are several advanced movement-analysis instruments that record and interpret bar path information"

Knowing the advancements made in mobile technology since the release of this book, I went on to the android Play Store and downloaded a number of apps which attempted to provide bar-path tracking functionality. I was disappointed to find that they had an average rating of around 2 stars and didn't seem to make use of the power of machine learning. I figured I could make something better and decided to make my own bar-path tracking android app. I knew that if I could train an object detection model to find the position of weight-plates in a photo, the centre of these plates would be the position of the bar.

This project was doable but difficult. I will include a number of problems I faced and their relative solutions.

Initially I was using frames from videos of my friends and myself to train my object detection model. I soon realised that the small number of videos wouldn't provide a wide enough variety of images. After scouring Instagram and YouTube to no avail, I finally found the holy grail of lifting videos - Reddit. There are a number of subreddits where people help eachother with their lifting form. I downloaded 200 videos and extracted a frame from each with the help of some Python scripts. I could not fully automate the process though, because I needed to ensure that the frames collected had an adequate side-view of the lift.

As a college student, spending all of my money on expensive GPUs or costly cloud services would leave me with no funds left for mint-chocolate protein. With regards to training my model, I was able to use the free resources of Google Colab. There were some limitations, but scarcity often leads to creativity. As for inference on users' videos, a faster and more accurate approach would have been to use REST/gRPC with an online server. This is still very expensive for machine learning models so I decided to perform all inference on-device.

Having decided to perform inference on-device, the most practical solution was to do transfer learning using TensorFlow Lite with an SSD Mobilenet checkpoint. These small models sacrifice accuracy for speed and didn't perform to the standard I had hoped for. My solution was to prompt the user to select the area in which the plates are moving. Inference is then performed on this restricted area, blocking out any other noise in the rest of the frame. This approach vastly improved results and made the tool more robust.

Phones are generally still quite limited in their speeds for video processing, which is necessary for performing inference on each frame of a video. I used the FFmpeg library for trimming, decoding and encoding the users' videos. Initially this was very slow but I managed to halve the processing time by choosing to reduce the video resolution of the output.

Time to show you the finished product. BarPath was launched on the Play Store on June 12th 2020. It is a completely free app and I won't be spamming you with Candy Crush ads either. My only satisfaction will come from people getting use and enjoyment out of the app. My metric of project success will be user ratings.

Here are some demos of the app:

And here are the results from some videos of people who are way better lifters than I am:

Well, what do you think? Do you like it? Do you loath it entirely? Please let me know! It is difficult to get feedback during the pandemic so all comments and messages will be appreciated. Furthermore, if you have any ideas you would like to discuss, I would be very interested to hear them.

Link to the app: https://play.google.com/store/apps/details?id=com.davidnugent.barpath

]]>