Skip to content

Aerodynamic drag force on Drag_Disturbance (second of the force stack) - #246

Merged
nscheuer merged 6 commits into
2_2/updatefrom
feat/drag-force
Oct 26, 2026
Merged

nscheuer merged 6 commits into
2_2/updatefrom
feat/drag-force

Conversation

@patrickmckeen

Copy link
Copy Markdown
Collaborator

The problem

Drag_Disturbance computes the aerodynamic torque but not the force that produces it, so the orbit cannot see drag. This is the drag part of #240, with tests, on top of the force interface PR.

What this adds

Nic's force, force_qjac and force_qqhess on Drag_Disturbance (his commit, drag portion only): the flat-plate drag force summed over the faces that see the flow,

F = -½ ρ Σ_i C_D,i A_i max(0, n_i · V_b) V_b,

with the same piecewise incidence gating as the torque. Layouts match the torque methods, (4, 3) and (4, 4, 3), units N.

Tests

testing/test_disturbances/drag/test_drag_force.py:

  • single face closed form, zero density, back-facing face, and an opposing pair that only counts the ram face;
  • torque consistency: torque() equals Σ (centroid − COM) × (per-face force), which ties the new force to the already-tested torque;
  • Jacobian and Hessian against raw central differences at relative tolerance 1e-6 and 1e-5 (the analytic derivatives agree to about 1e-13);
  • the force reaches Satellite.dist_forces.

One note from writing these: the existing fd_quat_jac helper renormalises the perturbed quaternion, which removes the radial part of the derivative. Nic's Jacobian is exact against the raw derivative; it only looked wrong against the renormalising helper because the force is large enough that the discrepancy clears the old tolerance. The torque tests do not notice because the torques are smaller.

🤖 Generated with Claude Code

t and others added 4 commits October 26, 2026 15:49
Disturbance gains force(), force_qjac() and force_qqhess() that return
zeros, mirroring the torque trio, so torque-only disturbances need no
change. Satellite.dist_forces() sums the body-frame forces over the
registered disturbances using the same sat/no-sat call convention as
dist_torques(). The attitude dynamics are untouched; the force is for
orbit propagation and inspection.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The analytic *_qjac/*_qqhess methods differentiate with respect to the four
raw quaternion components. The existing fd_quat_jac/fd_quat_hess renormalise
the perturbed quaternion, which drops the radial part of the derivative and
only agrees when the output is small enough to hide inside the tolerance.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Taken from 2_2/disturbance_forces_clean (#240), drag portion only.
…rences

Adds fd_quat_jac_raw/fd_quat_hess_raw helpers that do not renormalise the
perturbed quaternion; the analytic Jacobians differentiate with respect to
the raw components, so the renormalising helpers only agree when the output
is small enough to hide inside the tolerance.

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

Copy link
Copy Markdown

Test Results

1 590 tests  +8   1 588 ✅ +8   3m 42s ⏱️ +3s
    1 suites ±0       2 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 9669b6e. ± Comparison against base commit 08e2c0f.

Base automatically changed from feat/disturbance-force-interface to 2_2/update October 26, 2026 21:37
nscheuer and others added 2 commits October 26, 2026 22:53
…andle it. [drag_disturbance.py (line 253)](/home/nicla/Generalized_ADCS/ADCS/satellite_hardware/disturbances/drag_disturbance.py:253) annotates os as Orbital_State | Dict[...], but [line 288 (line 288)](/home/nicla/Generalized_ADCS/ADCS/satellite_hardware/disturbances/drag_disturbance.py:288) unconditionally calls os.get_state_vector(...). Passing a dictionary as the annotation permits raises AttributeError. Either support a mapping here or remove it from the annotation and docstring. The existing torque method has the same mismatch.

[P3] The raw finite-difference helper drops other state fields. [\\_helpers.py (line 120)](/home/nicla/Generalized_ADCS/testing/test_disturbances/_helpers.py:120) rebuilds a plain State with only w and q. That discards wheel momentum and, for EstimatorState, bias and disturbance-parameter values. A function that depends on those fields will be evaluated at a different state during the finite difference. Copy x and perturb its quaternion instead.

@nscheuer nscheuer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, made some small changes to the _helper files, otherwise looks awesome

@nscheuer
nscheuer merged commit b3b210b into 2_2/update Oct 26, 2026
2 checks passed
@nscheuer
nscheuer deleted the feat/drag-force branch October 26, 2026 21:55
@nscheuer nscheuer mentioned this pull request Oct 27, 2026
7 of 10 tasks
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.

2 participants