Nonlinear optimization proof-of-concept
The goal of this page is to prove that the math behind the 3-d magnetic field camera concept for my final project actually works. That is to say, can we use an array of magnetic field sensors to find the position and orientation of a magnet?
Theory
Need to prove that given an array of magnetic field measurements, we can "work backwards" to find the magnetic dipole moment that created them. For now we'll just assume there's a single dipole moment, if that works we'll allow more complicated magnetic sources.
The
magnetic field at a point \(\vec{r}\) some distance from a magnetic dipole \(\vec{m}\) at the origin is:
$$ \vec{B}(\vec{r}) = \frac{\mu_0}{4\pi} \left[ \frac{3 \vec{r}(\vec{m}\cdot\vec{r})}{r^5} - \frac{\vec{m}}{r^3}
\right]$$
Given \(N\) magnetic field measurements \(\vec{Bobs}_i\) at locations \(\vec{r}_i\), and a source diple at location \(\vec{r}\), the field at these locations
should be:
$$ \vec{B}_i = \frac{\mu_0}{4\pi} \left[ \frac{3 (\vec{r}_i - \vec{r})[\vec{m}\cdot(\vec{r}_i - \vec{r})]}{|\vec{r}_i - \vec{r}|^5} - \frac{\vec{m}}{|\vec{r}_i - \vec{r}|^3}
\right]$$
Our goal is to find \(\vec{r}\) and \(\vec{m}\) (6 unknowns) to minimize the cost function
$$ J(\vec{r},\vec{m}) = \sum_{i=1}^N (\vec{Bobs_i} - \vec{B}_i)^2$$
Python implementation
We implement this in Python using the
scipy.optimize library.
I've written a test code called
scipy_optimize_test.py
that demonstrates that
scipy.optimize.minimize
, using the
BFGS method, is able to find the 3-d position and direction of a magnetic dipole, given three or more vector observations of the field some distance away.
Which is to say it works: we can use three magnetic field sensors to figure out where a single nearby magnet is, and which direction its north and south poles are. This seems to be very robust to noise and limited data.
Code output
True dipole location:
[0. 0.5 0. ]
True dipole moment:
[1. 0.2 0.4]
Sensor positions:
[[0. 0. 1. ]
[0. 0.2 1. ]
[0.2 0. 1. ]]
Noisy sensor field measurements:
[-0.71892588 -0.40225166 0.22562442]
[-0.87653349 -0.42249006 0.48106843]
[-0.52462101 -0.53349802 0.50905385]
Initial guess for dipole location
[-0.52528806 -1.0950005 0.21400471]
Initial guess for dipole moment
[1.51117041 0.4961279 0.47349426]
Optimization terminated successfully.
Current function value: 0.000203
Iterations: 172
Function evaluations: 1421
Gradient evaluations: 203
Optimized dipole location
[-0.0144755 0.50219301 -0.00484672]
Optimized dipole moment
[1.02772215 0.21357374 0.38935003]
Camera range
How far away will our camera be able to "see" a magnet?
As mentioned in the
final project components page, it's easy to get a sensor that can sense Earth's field (0.5 gauss), but the camera won't work if we are so far away that the field from a permanent magnet is tough to distinguish from Earth's field, so let's use 1 gauss as our lower sensitivity. The field from a small rare earth magnet can be about
1 Tesla or 10,000 gauss, 1 cm away from the center of the magnet. The field strength from a
magnetic dipole drops off as the cube of the inverse distance, so a dipole that's 10,000 gauss at a distance of 1 cm will have a 1 gauss strength at a distance of \((10000)^{1/3} = 20\) cm away from the source. That's closer than I'd hoped, but it's acceptable.