[GSoC2018|OrbitDeterminator|Jorge] Week #3-4 – Least squares fit to cartesian positions as a function of time

Introduction

An orbital fit by least-squares is a technique for computing the set of six Keplerian elements which best describe an orbit with respect to a *whole* set of observations.
As the set of Keplerian elements we choose semimajor axis a, eccentricity e, time of perigee passage τ (i.e., how much time has elapsed since the last perigee), as well as the standard Euler angles which describe the orientation of the orbital plane with respecto to the inertial frame: argument of pericenter ω, inclination I and longitude of ascending node Ω. We denote by X the set of these six Keplerian elements; that is, X = (a, e, τ, ω, I, Ω).
A least-squares fit is simply to look the minimum of a scalar (i.e., real-valued) „cost“ function Q(X). The Q function is simply a measure of how well our theoretical predictions, for a given set X of orbital elements, depart from observations. In an ideal world, we could find a set of orbital elements such that it perfectly matched the observations and thus Q(X)=0. Nevertheless, real-world measures carry uncertainties, and we can only hope to find orbital elements X which make Q attain its minimum possible value with respect to all the observations we have made.
The values of the cost function Q(X) for a least-squared problem are constructed the following way: take *all* the values you observed (call them v_i), and substract from each of those the values you were expecting to measure for a given set of orbital elements X (say, V_i(X) ). Call each of these differences the residuals, xi_i(X) = v_i-V_i(X) . Then, square the residuals, and sum all the squared residuals. The value you obtain following this recipe, is the value of Q(X).
In practice, the least-squares method finds a local minimum of the cost function by performing an iterative procedure, which needs a good initial „guess“ solution X0; otherwise the procedure may converge to non-feasible results. Hence, it is necessary that the „good“ initial guess be provided by a preliminary orbit determination method.

„[GSoC2018|OrbitDeterminator|Jorge] Week #3-4 – Least squares fit to cartesian positions as a function of time“ weiterlesen

[GSoC2018|OrbitDeterminator|Jorge] Week #1-2 – Look up to the sky and marvel!

Hi, everyone! My name is Jorge Pérez, I’m a Physics PhD student at UNAM, Mexico, and this year I have been honored to form part of Aerospaceresearch.net as a GSoC student. Since I am a Python newbie, in these lines, I will try to follow the great Kepler, who in the Preface of his New Astronomy wrote:

What matters to me, is not merely to impart to the reader what I have to say, but above all to convey to him the reasons, subterfuges, and lucky hazards which led me to my discoveries. When Christopher Columbus, Magellan and the Portuguese relate how they went astray on their journeys, we not only forgive them, but would regret to miss their narration because without it the whole grand entertainment would be lost.

So, indeed, even when these last few days have been about warming up, I have been learning a lot. As a first task for my GSoC project, I have been coding some Python functions which will allow orbitdeterminator to load data from text files which contain position observations of either satellites or natural bodies, such as Near-Earth Asteroids (NEAs). Observational data for these type of objects is usually written to text files following fixed-width column formats. That is, in this kind of text files, for example, column 1 to 5 might refer to a numeric ID of the observed object; etc…

As a first thought to implement this, since these formats are defined via columns, my idea was that it might be safer to read these files using Python’s native file reading functions. And I was indeed able to read formatted files and save them into a Python list, but then I would have had to convert that to e.g. a numpy array, or something similar, in order to compute interesting stuff from the data.

So, as a second option, and after learning more about numpy, I thought that the `numpy.loadtxt` function might be the best approach, interpreting the whitespaces as delimiters and read each element as a string. This worked for a particular case I was working with, but I wasn’t sure if this approach would work for other formats.

And then, I worked on a third attempt at this. I realized that there was another numpy file-reading function, `numpy.gentfromtxt`. I liked this function better, since it tolerates files with missing values, as well as admitting files formatted with fixed-width columns. So, at the end, this was the approach that I took, and went on to code file-reading functions for some relevant formats which we will be using during the summer.

So now that we have the ability to load actual position data for satellites and asteroids, the next step, besides refining what I already coded, will be to implement orbit determination methods which take into account this kind of observational data from optical instruments, i.e., telescopes. And once this is done, the next step will be to code an orbit determination subroutine for radar observations, which are more subtle to reduce, but we will talk about this in a future blog post.

Incidentally, these last few days in Mexico City have been unusually warm; but tonight this weather, with clear skies and soft winds, allowed one of the most beautiful sights of the rising Moon in Mexico City since I can remember. Let’s not forget to always look up to the sky and marvel!