This is a followup post on my project to measure the orientation of a Dobsonian telescope. Initially I started using a single magnetometer. The results were disappointing. Now I am continuing using a SenseHat.
Installation on Raspberry
sudo bash apt-get update apt-get install sense-hat octave
Calibrate magnetometer (from Raspberry forum)
cp /usr/share/librtimulib-utils/RTEllipsoidFit ~ -a cd ~/RTEllipsoidFit RTIMULibCal
rm ~/.config/sense_hat/RTIMULib.ini sudo cp RTIMULib.ini /etc
cp -a /usr/src/sense-hat/examples ~/sense-hat-examples pi@raspberrypi:~/sense-hat-examples/RTIMULib/python $ python Fusion11.py Using settings file /etc/RTIMULib.ini IMU Name: LSM9DS1 Pressure Name: LPS25H Humidity Name: HTS221 IMU Init Succeeded Pressure sensor Init Succeeded Humidity sensor Init Succeeded Recommended Poll Interval: 3mS r: 1.882622 p: -2.228657 y: -34.041202 Pressure: 1022.269775, height above sea level: -74.813392 Pressure temperature: 31.514584 Humidity: 45.418594 Humidity temperature: 31.910820
First test with Stellarium
Modifying the telescope_server.py program from Communications between Python and Stellarium (Stellarium Telescope Protocol) to use RTIMULib values was relatively easy. In the core loop of this program I previously calculated altitude and azimuth from observed magnetometer values, which were then converted to ra/dec coordinates.
Now we have a sensor and library that reports r(oll), p(itch) and y(aw), the meaning of which is illustrated by the figure on the left. It is clear from this picture that yaw corresponds to azimuth and pitch to altitude.
Conversion from yaw to azimuth requires two operations: 1- convert from radians to degrees. 2- modulo 360.
Without modulo 360, yaw will flip from 180 to -180 at the South direction, decreasing to -90 at West. The following python code is used to transform pitch and yaw to altitude and azimuth.
def pitch_to_altitude(p): return math.degrees(p) def yaw_to_azimuth(y): return math.degrees(y) % 360
The following code snippet from telescope_server.py shows the modification to use the RTIMULib provided azimuth and altitude.
while True: asyncore.loop(timeout=0.1, count=1) if self.tel is not None: (r, p, y) = get_info() # (x, y, z) = get_axes() # cart = [x, y, z]/norm([x, y, z]) # real = matrix_to_cart(rotate(self.R, cart_list_to_matrix([cart]))) # real_az = azimuth(real, real, real) # real_alt = altitude(real, real, real) # radec = deg_to_rad(azalt_to_radec(real_az, real_alt)) radec = deg_to_rad(azalt_to_radec(yaw_to_azimuth(y), pitch_to_altitude(p))) self.tel.act_pos(radec, radec)
While the result was better than the previous setup with a 3-dof magnetometer, there is still more work to do:
- Azimuth still fluctuates +- 0.5 degrees, even with using the moving average of 200 measurements (using the RTIMULib provided polling interval) Altitude seems about one order more precise. This is understandable given the difference in underlying sensors used to provide both values. I am wondering if adding an additional IMU will increase accuracy. The margin of error will decrease if the sample size is larger. The question I have is, will taking two samples from two different sensor be better than taking two consecutive samples from a single sensor.
- Improve finding the average of two coordinates on a sphere, to use for smoothing with a moving average. Until now I simply averaged each axis separately with coordinates in a cartesian representation. This might provide correct results for the angle, but not for the magnitude of the vectors
- Magnetic declination adjustment for my location.
- Need to mount the device on the telescope and repeat measurements. Calibration with the AstroPi attached to the metal OTA ill be an issue, since the SenseHat provided calibration method required my rotating the device for about a minute, and I have to rotate the OTA myself. That will be a good workout!
- Remember that the IMU may not be mounted in any direction, but must be mounted so the pitch and yaw axes correspond with altitude and azimuth axes.