Skip to content

Sensor scale factor and misalignment: the device as built - #234

Open
patrickmckeen wants to merge 1 commit into
feat/sensor-noise-densityfrom
feat/sensor-scale-misalignment
Open

patrickmckeen wants to merge 1 commit into
feat/sensor-noise-densityfrom
feat/sensor-scale-misalignment

Conversation

@patrickmckeen

Copy link
Copy Markdown
Collaborator

What this adds

Real sensors are not mounted exactly where the drawing says and do not have exactly unit gain. Until now a sensor model had no way to say either: a gyro read exactly axis · ω plus bias and noise, with the same axis the estimator uses. Calibration error, which is where much of the real attitude error budget lives, could not be simulated.

Every sensor now takes two optional constructor arguments:

  • scale_factor: the reading is this factor times what a perfect device would read (default 1).
  • misalignment: a rotation vector in radians (axis times angle) from the nominal sensor frame to the frame the device is actually mounted in (default none).

What they do, by sensor type:

  • A single-axis sensor (gyro, magnetometer, sun sensor, sun pair) reads along its sensitive axis as mounted, sensing_axis = R(misalignment) · axis, times the scale factor. The sun sensors' one-sided and two-sided responses apply to the projection on that axis.
  • A vector sensor (horizon sensor, star tracker) reports the vector in its frame as mounted, scale_factor · R(misalignment)ᵀ · v.
  • The quaternion star tracker reports the attitude of its own frame, which is the body frame rotated by the misalignment; it has no scale factor and refuses one.
  • GPS has neither and refuses both.

The sensors' analytic Jacobians follow the device as built, so a filter given a sensor with known calibration errors on its own side is consistent with it. The usual case is the opposite: the plant has the errors and the filter does not know them. For that, EstimatedSatellite.from_satellite resets the cloned sensors to the nominal device, because calibration error is exactly what the estimator is not told. A satellite's noiseless_sensor_readings include the calibration errors, since they are part of the device, not of its noise.

Nothing changes for a sensor built without these arguments. This PR stacks on #233.

Tests

testing/test_sensors/test_sensor_mounting_errors.py, 6 tests: each single-axis sensor reads the tilted axis times its gain; the horizon sensor and both star trackers report in the rotated frame (the quaternion tracker's reported rotation equals the body rotation times the mounting rotation); every sensor's analytic Jacobian matches a central-difference Jacobian of its clean reading with the errors in place; the quaternion tracker's Jacobian equals the linear map of right-multiplication by the mounting quaternion; the estimator's clone is nominal while the plant is not; and the validation of bad inputs. The full suite passes.

🤖 Generated with Claude Code

Every sensor takes a scale_factor (its reading is that factor times a
perfect device's) and a misalignment (a rotation vector from the nominal
sensor frame to the actual one). A single-axis sensor reads along its
sensitive axis as mounted; a vector sensor reports in its frame as
mounted; the quaternion star tracker reports the attitude of its own
frame. The sensors' Jacobians follow the device as built. The estimator's
clone of a satellite is reset to the nominal device, since these errors
are exactly what the filter does not know.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Test Results

1 574 tests   1 572 ✅  2m 26s ⏱️
    1 suites      2 💤
    1 files        0 ❌

Results for commit b4c6bc2.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant