feat: always-on markdown report from computed analysis outputs#156
Conversation
📝 WalkthroughWalkthroughThis PR refactors flight log analysis to generate a structured markdown "BlackBox Flight Report." It introduces a typed ChangesStructured Flight Report Generation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes The PR introduces a substantial refactor touching data flow across 10+ files with multiple new public structures, signature changes in core plot/analysis functions, and a complete rewrite of the report generation module. The changes are heterogeneous (data structures, signatures, control flow, markdown generation) but follow a coherent narrative around structured reporting, requiring careful review of data aggregation paths, type consistency across plot/report boundaries, and report content accuracy. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
abe3b5b to
af0ffda
Compare
|
@coderabbitai, AI generated comment Requesting review of PR #156 (
Local CodeRabbit ( |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get the PR diff
gh pr view 156 --repo nerdCopter/BlackBox_CSV_Render --json title,body,files,commits | jq .
# Get the full diff
gh pr diff 156 --repo nerdCopter/BlackBox_CSV_Render 2>&1 | head -5000Length of output: 85507 🏁 Script executed: #!/bin/bash
# Check how margins_results is built in plot_bode.rs relative to tf_results
gh api repos/nerdCopter/BlackBox_CSV_Render/contents/src/plot_functions/plot_bode.rs \
--jq '.content' | base64 -d | head -250Length of output: 9389
🐛 Bug — misleading
|
| Severity | File | Issue |
|---|---|---|
| 🐛 Bug | d_term_delay.rs |
na_reason = "No D-term data" when gyroUnfilt is absent |
report.rs |
fmt_imuf _ arm silently renders ptn_order 0 as "2×PT1" |
|
| 📌 Maint | main.rs |
Hardcoded PNG filenames diverge silently from plot functions |
| 📎 Low | filter_delay.rs |
axis_delays misses non-XCorr method results |
|
@coderabbitai, AI generated comment Addressed findings from review #4682551809:
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify the fixes in commit 3bcace5
gh api repos/nerdCopter/BlackBox_CSV_Render/commits/3bcace5 --jq '.files[] | select(.filename | test("d_term_delay|report")) | {filename, patch}' 2>&1 | head -200Length of output: 1502
The deferred items (hardcoded PNG filenames and (╯°□°)╯ → 🐇 ✓ If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
src/main.rs (2)
668-672: ⚡ Quick winReplace the new hard-coded axis counts with shared axis constants.
This report wiring adds fresh
3/0..2axis assumptions in several places even thoughAXIS_COUNTand the axis-name helpers already exist. That duplicates a core contract and makes the new report path easier to drift from the rest of the analyzer.♻️ Suggested cleanup
- let pd_ratios_for_report: [Option<f64>; 3] = [ + let pd_ratios_for_report: [Option<f64>; AXIS_COUNT] = [ pid_metadata.roll.calculate_pd_ratio(), pid_metadata.pitch.calculate_pd_ratio(), pid_metadata.yaw.calculate_pd_ratio(), ]; - let mut setpoint_authority_names: [Option<&'static str>; 3] = [None, None, None]; - let mut setpoint_authority_means: [Option<f32>; 3] = [None, None, None]; + let mut setpoint_authority_names: [Option<&'static str>; AXIS_COUNT] = + std::array::from_fn(|_| None); + let mut setpoint_authority_means: [Option<f32>; AXIS_COUNT] = + std::array::from_fn(|_| None); - let mut step_warnings: [Vec<String>; 3] = [Vec::new(), Vec::new(), Vec::new()]; + let mut step_warnings: [Vec<String>; AXIS_COUNT] = + std::array::from_fn(|_| Vec::new()); - for axis_index in 0..2 { + for axis_index in 0..crate::axis_names::ROLL_PITCH_AXIS_COUNT {As per coding guidelines, "All constants go in
src/constants.rs— no hardcoded magic numbers in function code" and "Axis indices (0=Roll, 1=Pitch, 2=Yaw) must use thesrc/axis_names.rsmodule withAXIS_COUNT,AXIS_NAMES, andaxis_name()function instead of creating redundant axis index constants."Also applies to: 782-787, 1197-1255
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main.rs` around lines 668 - 672, The new report code uses hard-coded axis counts and indices (e.g., the literal 3 and 0..2) when building pd_ratios_for_report and similar arrays; replace those literals by using the shared axis constants and helpers: iterate from 0..AXIS_COUNT (from AXIS_COUNT in constants) to build the array/vector, call pid_metadata.<axis>.calculate_pd_ratio() dynamically for each axis, and when names are needed use axis_name(index) or AXIS_NAMES[index]; update all occurrences (including the other reported ranges noted) to remove magic numbers and rely on AXIS_COUNT/axis_name()/AXIS_NAMES so the report contract stays consistent with the rest of the analyzer.Source: Coding guidelines
1630-1695: 🏗️ Heavy liftAvoid making
png_linksa second source of truth for output names.Every string in this block has to stay in lockstep with the plot function that actually writes the PNG. The step-response branch already had to fall back to directory scanning because the filename is dynamic; the rest of these links can silently go stale on the next rename for the same reason. Prefer returning emitted paths from the plot functions, or deriving this list from the files actually written.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main.rs` around lines 1630 - 1695, png_links is acting as a second source of truth for output filenames and can drift from the actual PNGs written; instead have each plotting function return its emitted path(s) and build png_links from those returns. Modify the plotting functions (the ones invoked when plot_config.* is true) to return a PathBuf or Vec<PathBuf> (or String/Vec<String>) of written files, change callers to call those functions and png_links.extend(returned_paths.iter().map(|p| p.to_string_lossy().into_owned())), and keep the step_response directory-scan only if that particular plotting function still produces dynamic names — otherwise consume its returned path(s) too so all output names come from the writers rather than hardcoded strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main.rs`:
- Around line 1697-1722: Report generation is happening before the optional ESO
plot is created so png_links never includes the ESO PNG; move the report
generation (the block that builds report_filename, flight_report, and calls
report::generate_markdown_report) to run after the code that handles the "--eso"
branch and updates png_links (also apply the same change to the analogous block
around lines 1726-1769), ensuring png_links is finalized before constructing and
writing the markdown report.
- Around line 1697-1722: The code currently logs errors from
report::generate_markdown_report(&flight_report, report_path) and continues,
which masks failures; instead propagate the error through process_file() by
replacing the match/logging with a fallible call that returns the error (use the
? operator or map_err to convert to the function's error type) so a failed write
of report_filename/report_path causes process_file() to return Err; locate the
FlightReport construction and the match around report::generate_markdown_report
and change that match to propagate the error.
In `@src/plot_functions/plot_setpoint_vs_gyro.rs`:
- Around line 31-35: DelayAnalysisResult is being constructed with axis_delays
as an empty Vec which violates the per-axis indexing contract; change the
initialization in the DelayAnalysisResult construction to allocate a vector
sized to AXIS_NAMES (e.g., axis_delays: vec![None; AXIS_NAMES.len()]) so
downstream code that uses axis_delays.get(axis_idx) or indexes by axis (see
filter_delay.rs contract and usages like plot_gyro_spectrums.rs) always finds
the expected positions.
In `@src/report.rs`:
- Line 50: Replace hardcoded axis counts and names with the centralized axis
metadata: change the pd_ratios field type from [Option<f64>; 3] to [Option<f64>;
axis_names::AXIS_COUNT] (using axis_names::AXIS_COUNT), and update any loops or
indexing that use hardcoded 3 or explicit axis name arrays (the code around
pd_ratios, the section at lines ~113-127, and ~170-172) to iterate
0..axis_names::AXIS_COUNT or over axis_names::AXIS_NAMES and call
axis_names::axis_name(i) for labels; ensure you import the axis_names module (or
its symbols) and replace all magic “3”/hardcoded axis strings with AXIS_COUNT,
AXIS_NAMES, or axis_name() as appropriate.
---
Nitpick comments:
In `@src/main.rs`:
- Around line 668-672: The new report code uses hard-coded axis counts and
indices (e.g., the literal 3 and 0..2) when building pd_ratios_for_report and
similar arrays; replace those literals by using the shared axis constants and
helpers: iterate from 0..AXIS_COUNT (from AXIS_COUNT in constants) to build the
array/vector, call pid_metadata.<axis>.calculate_pd_ratio() dynamically for each
axis, and when names are needed use axis_name(index) or AXIS_NAMES[index];
update all occurrences (including the other reported ranges noted) to remove
magic numbers and rely on AXIS_COUNT/axis_name()/AXIS_NAMES so the report
contract stays consistent with the rest of the analyzer.
- Around line 1630-1695: png_links is acting as a second source of truth for
output filenames and can drift from the actual PNGs written; instead have each
plotting function return its emitted path(s) and build png_links from those
returns. Modify the plotting functions (the ones invoked when plot_config.* is
true) to return a PathBuf or Vec<PathBuf> (or String/Vec<String>) of written
files, change callers to call those functions and
png_links.extend(returned_paths.iter().map(|p|
p.to_string_lossy().into_owned())), and keep the step_response directory-scan
only if that particular plotting function still produces dynamic names —
otherwise consume its returned path(s) too so all output names come from the
writers rather than hardcoded strings.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: bd563044-c1a2-4095-b657-826925b1249d
📒 Files selected for processing (12)
src/data_analysis/d_term_delay.rssrc/data_analysis/filter_delay.rssrc/lib.rssrc/main.rssrc/plot_functions/plot_bode.rssrc/plot_functions/plot_d_term_psd.rssrc/plot_functions/plot_d_term_spectrums.rssrc/plot_functions/plot_gyro_spectrums.rssrc/plot_functions/plot_gyro_vs_unfilt.rssrc/plot_functions/plot_motor_spectrums.rssrc/plot_functions/plot_setpoint_vs_gyro.rssrc/report.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.rs: All constants go insrc/constants.rs— no hardcoded magic numbers in function code
Axis indices (0=Roll, 1=Pitch, 2=Yaw) must use thesrc/axis_names.rsmodule withAXIS_COUNT,AXIS_NAMES, andaxis_name()function instead of creating redundant axis index constants
ALWAYS useFirmware revisionheader to detect firmware type, NEVER useFirmware type
Firmware revision patterns: Betaflight usesBetaflight 4.x.xorBetaflight YYYY.MM, Emuflight usesEmuFlight 0.x.x, INAV usesINAV x.x.x
Files:
src/lib.rssrc/plot_functions/plot_setpoint_vs_gyro.rssrc/plot_functions/plot_gyro_vs_unfilt.rssrc/plot_functions/plot_motor_spectrums.rssrc/plot_functions/plot_bode.rssrc/plot_functions/plot_d_term_psd.rssrc/data_analysis/filter_delay.rssrc/plot_functions/plot_d_term_spectrums.rssrc/plot_functions/plot_gyro_spectrums.rssrc/data_analysis/d_term_delay.rssrc/main.rssrc/report.rs
🔇 Additional comments (22)
src/lib.rs (1)
14-14: LGTM!src/data_analysis/d_term_delay.rs (6)
15-20: LGTM!
54-62: LGTM!
78-83: LGTM!
135-142: LGTM!
233-236: LGTM!Also applies to: 242-242, 255-258, 264-264
273-273: LGTM!src/data_analysis/filter_delay.rs (4)
191-191: LGTM!
278-284: LGTM!
309-309: LGTM!Also applies to: 315-315, 322-322
339-340: LGTM!src/plot_functions/plot_gyro_vs_unfilt.rs (1)
38-38: LGTM!src/plot_functions/plot_d_term_psd.rs (2)
62-62: LGTM!
332-332: LGTM!src/plot_functions/plot_gyro_spectrums.rs (5)
25-36: LGTM!
48-48: LGTM!Also applies to: 58-58
64-64: LGTM!
225-241: LGTM!
614-614: LGTM!Also applies to: 616-616
src/plot_functions/plot_bode.rs (1)
31-35: LGTM!Also applies to: 45-45, 189-196
src/plot_functions/plot_d_term_spectrums.rs (1)
24-32: LGTM!Also applies to: 46-46, 278-288, 568-568, 585-585
src/plot_functions/plot_motor_spectrums.rs (1)
33-40: LGTM!Also applies to: 48-48, 146-189, 300-300
|
@coderabbitai , AI generated comment Addressed all inline findings from review 4478617008 in commit
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify the fixes in commit be171d8
gh api repos/nerdCopter/BlackBox_CSV_Render/commits/be171d8 \
--jq '.files[] | {filename, patch}' 2>&1 | head -400Length of output: 7160
One minor note for a future cleanup pass: (╯°□°)╯ → 🐇 ✓ |
|
@coderabbitai, ESO is not supposed to be in this branch. investigating now. |
Automatically writes <stem>_report.md alongside PNGs on every run. No flag required. Includes firmware/config metadata, per-axis signal statistics (mean/std/min/max/rms for gyro, setpoint, P/I/D/F), and linked (not inline) references to all generated PNG files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Returns per-axis StabilityMargins from Bode analysis for downstream report collection. Early-exit paths return empty vec. Suppress dead_code until report wiring in a follow-up commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Returns per-motor oscillation analysis (detected flag, peak/avg in 50-200 Hz range, overall max amplitude) for downstream report collection. Restructures the oscillation-check loop to build typed results instead of printing only. Early-exit paths return empty vec. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces raw CSV-stats report with typed structs capturing the same analysis results already printed to console — no CSV re-reading, no println duplication. - report.rs: rewritten with FlightReport, StepAxisReport, DTermRec; generate_markdown_report(&FlightReport, &Path) formats P:D ratios, step response assessments and D-term recommendations, Optimal P analysis, Bode stability margins, motor oscillation, and PNG links - plot_bode.rs: remove unused axis field from BodeAxisResult; drop #[allow(dead_code)] now that fields are consumed by the report - plot_motor_spectrums.rs: drop #[allow(dead_code)] from MotorOscillationResult - main.rs: capture pd_ratios_for_report, build step_reports from existing analysis arrays (re-computing aggressive tier inline), clone optimal_p_analyses before move into OptimalPConfig, capture motor_results and bode_results from plot function returns, assemble FlightReport and call new generate_markdown_report Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
StepAxisReport gains setpoint_authority_name/mean fields populated from the already-computed compute_setpoint_authority() result in main.rs. Report displays authority level and mean dps under each axis's step response section. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
plot_gyro_spectrums now returns GyroAnalysisResult containing the average filtering delay (already computed via cross-correlation) and per-axis primary unfiltered spectrum peaks. FlightReport stores this as gyro_analysis; the report emits a Gyro Analysis section with delay and a peaks table. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
plot_d_term_spectrums now returns Vec<DTermAxisResult> with per-axis primary peak (freq/amplitude) and filtering delay (ms + confidence) already computed by d_term_delay::calculate_d_term_filtering_delay_comparison. FlightReport stores dterm_results; the report emits a D-Term Analysis table with delay and primary peak per axis. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…onfidence - Store full peaks Vec (primary + subordinates up to MAX_PEAKS_TO_LABEL=3) in both GyroSpectrumAxisResult and DTermAxisResult instead of first-only - DelayAnalysisResult gains axis_delays Vec so per-axis (delay_ms, confidence) is surfaced from calculate_average_filtering_delay_comparison - GyroSpectrumAxisResult carries per-axis delay_ms/delay_confidence sourced from axis_delays; GyroAnalysisResult.average_delay_ms removed (superseded) - Report tables for Gyro Analysis and D-Term Analysis now share identical column format: Axis | Delay (ms) | Confidence | Peak | Freq (Hz) | Amplitude Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… in report (#153) Add three new report sections from console output that were missing: 1. Filter Configuration: per-axis LPF1/LPF2/IMUF table + dynamic notch and RPM filter lines. Parses AllFilterConfigs, DynamicNotchConfig, RpmFilterConfig from header metadata via filter_response. Works for BF (unified), EmuFlight (per-axis), HELIOSPRING (IMUF PTn), and EmuFlight pseudo-Kalman. 2. D-term N/A disambiguation: DTermAxisDelay struct replaces Vec<Option<DelayResult>>, carrying na_reason alongside the result. Possible reasons: "D gain disabled", "Low signal correlation", "Insufficient samples", "No D-term data". Report now shows e.g. "N/A (Low signal correlation)" instead of bare "N/A". 3. Step response warnings: warnings: Vec<String> on StepAxisReport captures severe overshoot and unreasonable P:D ratio alerts that previously only appeared on console. Rendered as bold "⚠ Warning:" lines after recommendations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When gyroUnfilt data comes from debug[0-2] channels instead of dedicated gyroUnfilt columns, add a ⚠ note in Metadata with the debug mode name (e.g. GYRO_SCALED, RC_SMOOTHING). Pilots need to know that unfiltered gyro spectrums and filtering delay calculations in that report are derived from debug channels, not actual gyroUnfilt — affecting their interpretation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
root_name_string was moved into FlightReport.root_name then borrowed again by plot_eso_output; clone before the move. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two issues flagged by CodeRabbit review: 1. d_term_delay.rs: split the combined gyroUnfilt/d_term unavailability guard into separate checks so na_reason correctly reflects the actual cause — 'No gyroUnfilt data' vs 'No D-term data'. Previously both conditions silently fell through with 'No D-term data', misleading pilots whose log lacked gyroUnfilt but had D-term data. 2. report.rs fmt_imuf: change the catch-all ptn_order arm from '2×PT1' to 'PT?' so an unknown or zero order renders visibly wrong rather than silently plausible. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fill in the empty 'Generated Reports' section in OVERVIEW.md and add a 'Markdown Report' subsection to README.md Output section. Both now describe the always-on *_report.md output, its sections, and when optional sections (Optimal P, Bode) appear. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Four issues resolved: 1. ESO PNG missing from report: moved report generation to after the ESO block so png_links is complete. Also adds the ESO stacked PNG to png_links on success. 2. Error propagation: replaced log-and-continue match on generate_markdown_report with ? operator so a write failure propagates out of process_file(). 3. Empty axis_delays in plot_setpoint_vs_gyro.rs: changed Vec::new() fallback to vec![None; AXIS_NAMES.len()] to satisfy the per-axis indexing contract expected by downstream consumers. 4. Hardcoded axis counts: replaced [Option<f64>; 3], [None, None, None], [Vec::new()...] and 0..2 introduced by the report wiring with AXIS_COUNT, std::array::from_fn, and ROLL_PITCH_AXIS_COUNT. Deferred: png_links as second source of truth (heavy refactor — tracked as follow-up). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Tip For best results, initiate chat on the files or code changes.
(づ。◕‿‿◕。)づ 🐇 |
|
Tip For best results, initiate chat on the files or code changes.
The one remaining cleanup note from the prior pass: (╯°□°)╯ → 🐇 ✓ |
be171d8 to
8b8ed49
Compare
|
@coderabbitai, I force-pushed fixes. is everything resolved? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check the current tip of the PR branch
gh pr view 156 --repo nerdCopter/BlackBox_CSV_Render --json headRefName,headRefOid,commits | jq '{headRef: .headRefName, headSha: .headRefOid, lastCommits: [.commits[-3:][].messageHeadline]}'
# Check d_term_delay.rs for the na_reason fix
gh api repos/nerdCopter/BlackBox_CSV_Render/contents/src/data_analysis/d_term_delay.rs \
--jq '.content' | base64 -d | grep -n "na_reason\|gyro_unfilt\|d_term_avail" | head -30
# Check report.rs fmt_imuf for the PT? fix
gh api repos/nerdCopter/BlackBox_CSV_Render/contents/src/report.rs \
--jq '.content' | base64 -d | grep -n "PT?\|ptn_order\|fmt_imuf\|2×PT1" | head -20
# Check main.rs for ESO references and remaining [None, None, None] / literal 3
gh api repos/nerdCopter/BlackBox_CSV_Render/contents/src/main.rs \
--jq '.content' | base64 -d | grep -n "eso\|ESO\|\[None, None, None\]\|recommended_d_max_aggressive\|\[; 3\]" | head -40
# Check axis_delays fallback in plot_setpoint_vs_gyro.rs
gh api repos/nerdCopter/BlackBox_CSV_Render/contents/src/plot_functions/plot_setpoint_vs_gyro.rs \
--jq '.content' | base64 -d | grep -n "axis_delays\|AXIS_NAMES" | head -15
# Check axis_delays fallback in plot_gyro_vs_unfilt.rs
gh api repos/nerdCopter/BlackBox_CSV_Render/contents/src/plot_functions/plot_gyro_vs_unfilt.rs \
--jq '.content' | base64 -d | grep -n "axis_delays\|AXIS_NAMES" | head -15Length of output: 4396 🏁 Script executed: #!/bin/bash
BRANCH="20260610_Report"
# Re-fetch report.rs with explicit branch ref
gh api "repos/nerdCopter/BlackBox_CSV_Render/contents/src/report.rs?ref=${BRANCH}" \
--jq '.content' | base64 -d | grep -n "PT?\|ptn_order\|fmt_imuf\|2.PT1" | head -20
# Check axis_delays in plot_setpoint_vs_gyro.rs more broadly
gh api "repos/nerdCopter/BlackBox_CSV_Render/contents/src/plot_functions/plot_setpoint_vs_gyro.rs?ref=${BRANCH}" \
--jq '.content' | base64 -d | grep -n "axis_delays" | head -15
# Check axis_delays in plot_gyro_vs_unfilt.rs more broadly
gh api "repos/nerdCopter/BlackBox_CSV_Render/contents/src/plot_functions/plot_gyro_vs_unfilt.rs?ref=${BRANCH}" \
--jq '.content' | base64 -d | grep -n "axis_delays" | head -15
# Confirm no ESO in main.rs
gh api "repos/nerdCopter/BlackBox_CSV_Render/contents/src/main.rs?ref=${BRANCH}" \
--jq '.content' | base64 -d | grep -ni "eso" | head -20Length of output: 1294
The Deferred items remain deferred as previously agreed:
Would you like me to open GitHub issues to track those two deferred items so they don't get lost? (╯°□°)╯ → 🐇 ✓ |
|
@coderabbitai approve (only if you actually approve) |
|
The two deferred follow-ups (hardcoded PNG filenames in (╯°□°)╯ → 🐇 ✓ ✅ Action performedComments resolved and changes approved. |
|
The two deferred follow-ups (hardcoded PNG filenames in (╯°□°)╯ → 🐇 ✓ ✅ Action performedComments resolved and changes approved. |
- Merge origin/master (fddd046, PR #156 always-on markdown report) - Add eso_results: [Option<EsoResult>; AXIS_COUNT] field to FlightReport - Add ESO Gain Optimization section to generate_markdown_report: table of omega_0, beta1, beta2, b0, b0 source, MSE, [at ceiling] note per axis; skipped axes shown as N/A - Move ESO block before report generation so results and PNG link are available when FlightReport is assembled - ESO PNG link added to png_links on successful plot write Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AI Generated pull-request
Summary
Adds an always-on markdown flight report (
*_report.md) generated alongside PNGs on every run. No flag required.Content is assembled from typed result structs returned by each analysis pass — no CSV re-reading.
Report Sections
--estimate-optimal-pproduces results--bodeproduces resultsWhat this does NOT include
src/eso.rs/src/plot_functions/plot_eso.rsare absent (separate branch: PR feat: ESO gain optimization (2nd-order LESO, argmin GSS, at_ceiling marker) #136)--reportflag needed; report is always generatedBased on clean master
Branch was rebased onto master after the accidental ESO squash in PR #157 was reverted (PR #158) and the debug guard fix was re-applied cleanly (PR #159). ESO block stripped from
main.rsduring rebase conflict resolution.