2016-12-29 12:33:11 +00:00
|
|
|
// Package sensors provides a stratux interface to sensors used for AHRS calculations.
|
|
|
|
package sensors
|
2016-07-15 01:38:15 +00:00
|
|
|
|
|
|
|
import (
|
2017-03-08 22:16:29 +00:00
|
|
|
"log"
|
2016-07-15 01:38:15 +00:00
|
|
|
"time"
|
2016-12-29 12:33:11 +00:00
|
|
|
|
|
|
|
"github.com/westphae/goflying/mpu9250"
|
2016-07-15 01:38:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2016-12-29 12:33:11 +00:00
|
|
|
gyroRange = 250 // gyroRange is the default range to use for the Gyro.
|
|
|
|
accelRange = 4 // accelRange is the default range to use for the Accel.
|
|
|
|
updateFreq = 1000 // updateFreq is the rate at which to update the sensor values.
|
2016-07-15 01:38:15 +00:00
|
|
|
)
|
|
|
|
|
2016-12-29 12:33:11 +00:00
|
|
|
// MPU9250 represents an InvenSense MPU9250 attached to the I2C bus and satisfies
|
|
|
|
// the IMUReader interface.
|
2016-07-15 01:38:15 +00:00
|
|
|
type MPU9250 struct {
|
|
|
|
mpu *mpu9250.MPU9250
|
|
|
|
}
|
|
|
|
|
2016-12-29 12:33:11 +00:00
|
|
|
// NewMPU9250 returns an instance of the MPU9250 IMUReader, connected to an
|
|
|
|
// MPU9250 attached on the I2C bus with either valid address.
|
2016-07-15 01:38:15 +00:00
|
|
|
func NewMPU9250() (*MPU9250, error) {
|
|
|
|
var (
|
2016-07-15 05:30:40 +00:00
|
|
|
m MPU9250
|
|
|
|
mpu *mpu9250.MPU9250
|
|
|
|
err error
|
2016-07-15 01:38:15 +00:00
|
|
|
)
|
|
|
|
|
2016-12-29 12:33:11 +00:00
|
|
|
log.Println("AHRS Info: Making new MPU9250")
|
|
|
|
mpu, err = mpu9250.NewMPU9250(gyroRange, accelRange, updateFreq, true, false)
|
2016-07-15 01:38:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2016-11-23 15:34:41 +00:00
|
|
|
// Set Gyro (Accel) LPFs to 20 (21) Hz to filter out prop/glareshield vibrations above 1200 (1260) RPM
|
2016-12-29 12:33:11 +00:00
|
|
|
log.Println("AHRS Info: Setting MPU9250 LPF")
|
2016-11-23 15:34:41 +00:00
|
|
|
mpu.SetGyroLPF(21)
|
|
|
|
mpu.SetAccelLPF(21)
|
2017-03-08 22:16:29 +00:00
|
|
|
time.Sleep(100 * time.Millisecond)
|
2016-11-23 15:34:41 +00:00
|
|
|
|
2016-07-15 01:38:15 +00:00
|
|
|
m.mpu = mpu
|
|
|
|
|
2016-12-29 12:33:11 +00:00
|
|
|
log.Println("AHRS Info: monitoring IMU")
|
2016-07-15 01:38:15 +00:00
|
|
|
return &m, nil
|
|
|
|
}
|
|
|
|
|
2017-03-08 22:16:29 +00:00
|
|
|
// Read returns the average (since last reading) time, Gyro X-Y-Z, Accel X-Y-Z, Mag X-Y-Z, error reading Gyro/Accel, and error reading Mag.
|
|
|
|
func (m *MPU9250) Read() (T int64, G1, G2, G3, A1, A2, A3, M1, M2, M3 float64, GAError, MAGError error) {
|
|
|
|
data := <-m.mpu.CAvg
|
2016-07-19 11:49:41 +00:00
|
|
|
T = data.T.UnixNano()
|
|
|
|
G1 = data.G1
|
|
|
|
G2 = data.G2
|
|
|
|
G3 = data.G3
|
|
|
|
A1 = data.A1
|
|
|
|
A2 = data.A2
|
|
|
|
A3 = data.A3
|
|
|
|
M1 = data.M1
|
|
|
|
M2 = data.M2
|
|
|
|
M3 = data.M3
|
|
|
|
GAError = data.GAError
|
|
|
|
MAGError = data.MagError
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-12-29 12:33:11 +00:00
|
|
|
// Calibrate kicks off a calibration for specified duration (s) and retries.
|
2016-07-21 19:11:28 +00:00
|
|
|
func (m *MPU9250) Calibrate(dur, retries int) (err error) {
|
2017-02-28 00:57:01 +00:00
|
|
|
if dur > 0 {
|
|
|
|
for i := 0; i < retries; i++ {
|
|
|
|
m.mpu.CCal <- dur
|
2017-02-28 01:28:05 +00:00
|
|
|
log.Printf("AHRS Info: Waiting for calibration result try %d of %d\n", i+1, retries)
|
2017-02-28 00:57:01 +00:00
|
|
|
err = <-m.mpu.CCalResult
|
|
|
|
if err == nil {
|
|
|
|
log.Println("AHRS Info: MPU9250 calibrated")
|
|
|
|
break
|
|
|
|
}
|
|
|
|
time.Sleep(time.Duration(50) * time.Millisecond)
|
|
|
|
log.Println("AHRS Info: MPU9250 wasn't inertial, retrying calibration")
|
2016-07-21 19:11:28 +00:00
|
|
|
}
|
|
|
|
}
|
2016-07-19 11:49:41 +00:00
|
|
|
return
|
2016-07-15 05:31:03 +00:00
|
|
|
}
|
|
|
|
|
2016-12-29 12:33:11 +00:00
|
|
|
// Close stops reading the MPU.
|
2016-07-15 01:38:15 +00:00
|
|
|
func (m *MPU9250) Close() {
|
2017-03-08 22:16:29 +00:00
|
|
|
m.mpu.CloseMPU()
|
2016-07-15 01:38:15 +00:00
|
|
|
}
|