STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
magnetometer_calibration.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""
3Magnetometer Calibration Script
4
5Calibrates magnetometer using ellipsoid fitting method.
6Requires sensor to be rotated through multiple orientations.
7
8Usage:
9 python magnetometer_calibration.py --sensor-id imu_0
10"""
11
12import argparse
13import numpy as np
14import time
15from imu_calibration import MagnetometerCalibrator, CalibrationPoint
16
17
19 """Collect magnetometer readings at multiple orientations"""
20 print("Magnetometer Calibration")
21 print("=" * 50)
22 print("Rotate sensor through multiple orientations")
23 print("Aim for at least 12 different orientations covering all axes")
24 print()
25
26 calibrator = MagnetometerCalibrator("imu_0")
27
28 # Reference magnetic field (normalized, pointing north)
29 reference_field = np.array([1.0, 0.0, 0.0]) # North
30
31 num_positions = 12
32 print(f"Collecting {num_positions} orientations...")
33
34 for i in range(num_positions):
35 input(f"Rotate sensor to orientation {i+1}/{num_positions} and press Enter...")
36
37 # Collect multiple readings and average
38 print("Collecting readings (3 seconds)...")
39 readings = []
40 start_time = time.time()
41 while time.time() - start_time < 3.0:
42 # In real implementation, read from sensor
43 # For now, simulate
44 raw = np.array([0.0, 0.0, 0.0]) # Would read from sensor
45 readings.append(raw)
46 time.sleep(0.1)
47
48 # Average readings
49 avg_reading = np.mean(readings, axis=0)
50
51 # Reference is the normalized field direction at this orientation
52 # (would need to know sensor orientation relative to magnetic field)
53 ref = reference_field # Simplified
54
55 # Create calibration point
56 point = CalibrationPoint(
57 raw_value=avg_reading,
58 reference_value=ref,
59 temperature=25.0,
60 timestamp=time.time(),
61 )
62 calibrator.add_calibration_point(point)
63
64 print(f" Collected orientation {i+1}: {avg_reading}")
65
66 return calibrator
67
68
69def main():
70 parser = argparse.ArgumentParser(description="Magnetometer Calibration")
71 parser.add_argument("--sensor-id", default="imu_0")
72 parser.add_argument("--output", default="mag_calibration.json")
73 parser.add_argument(
74 "--interactive",
75 action="store_true",
76 help="Interactive mode (collect orientations)",
77 )
78 parser.add_argument(
79 "--reference-field",
80 type=float,
81 nargs=3,
82 default=[1.0, 0.0, 0.0],
83 help="Reference magnetic field vector",
84 )
85
86 args = parser.parse_args()
87
88 if args.interactive:
90 else:
91 calibrator = MagnetometerCalibrator(args.sensor_id)
92 calibrator.reference_field_magnitude = np.linalg.norm(args.reference_field)
93 print("Add calibration points programmatically or use --interactive")
94 return
95
96 # Perform calibration
97 try:
98 params = calibrator.calibrate()
99 print("\nCalibration Results:")
100 print(f" Bias (Hard Iron): {params.bias}")
101 print(f" Scale Matrix (Soft Iron):\n{params.scale_matrix}")
102 print(f" Quality: {params.calibration_quality:.3f}")
103
104 # Save calibration
105 calibrator.save_calibration(args.output)
106 print(f"\nSaved calibration to {args.output}")
107 except Exception as e:
108 print(f"Calibration failed: {e}")
109
110
111if __name__ == "__main__":
112 main()
TOML_NODISCARD_CTOR time() noexcept=default