Skip to content

Conversation

@demvlad
Copy link
Contributor

@demvlad demvlad commented Dec 17, 2025

Added trajectory tilt angle computed field. It is computed by using GPS NED velocities.
Now we have both trajectories angle: horizontal and vertical.
tilt

Summary by CodeRabbit

  • New Features
    • Added a GPS-derived trajectory tilt angle field (gpsTrajectoryTiltAngle) to flight logs, shown in lists and graphs (degrees, one decimal) with range -90 to 90.
    • Value is computed from GPS velocity when available; falls back to 0 if velocity data is missing or below threshold.
    • Display formatting and default graph scaling updated to include the new field.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Walkthrough

Adds a new computed field gpsTrajectoryTiltAngle (derived from GPS_velned Vn, Ve, Vd) and integrates it into flightlog computation, presentation mapping/formatting, and graph default configuration.

Changes

Cohort / File(s) Summary
Core computation logic
src/flightlog.js
Increased ADDITIONAL_COMPUTED_FIELD_COUNT (20 → 21); introduced gpsVelNED indices for GPS_velned[0..2] with presence checks; compute velocity from Vn, Ve, Vd and when velocity > 5 cm/s compute trajectoryTiltAngle = -asin(Vd/velocity) (degrees), else 0; append gpsTrajectoryTiltAngle to computed fields when GPS is enabled; updated related GPS calculation comments and normalization.
Presentation / formatting
src/flightlog_fields_presenter.js
Added gpsTrajectoryTiltAngle to FRIENDLY_FIELD_NAMES and extended decodeFieldToFriendly to format it with one decimal place and a degree symbol (same formatting as gpsHomeAzimuth).
Graph defaults
src/graph_config.js
Added default curve for gpsTrajectoryTiltAngle with { power: 1, MinMax: { min: -90, max: 90 } } and included the field in GPS example graph configurations; normalized numeric power literals across many curve definitions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Verify GPS_velned index mapping and presence/absence handling in src/flightlog.js.
  • Confirm units, 5 cm/s threshold, sign convention for -asin(Vd/velocity), and degree conversion.
  • Ensure ADDITIONAL_COMPUTED_FIELD_COUNT increment aligns with serialization/field indexing elsewhere to avoid off-by-one issues.

Possibly related PRs

Suggested reviewers

  • nerdCopter
  • haslinghuis

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the core feature (trajectory tilt angle computed from GPS NED velocities) and its purpose (complementing horizontal trajectory angle), but does not follow the repository's template structure with required sections and guidelines. Restructure the description to follow the repository template, including sections on motivation, implementation details, and testing. Remove the template instructions and ensure clarity on all changes made.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Added trajectory tilt angle computed field' directly and clearly describes the main change—adding a new computed field for trajectory tilt angle, which is the primary focus of the changeset across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@demvlad demvlad marked this pull request as draft December 17, 2025 19:49
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/graph_config.js (1)

487-500: Critical syntax error: Missing closing braces for GPS_velned block.

The previous else if block for GPS_velned (lines 487-492) is missing its closing braces before the new gpsTrajectoryTiltAngle block begins on line 493. This causes the parse errors reported by static analysis and the pipeline failure.

Apply this diff to fix the syntax error:

     } else if (fieldName.match(/^GPS_velned\[/)) {
       return {
         power: 1.0,
         MinMax: {
           min: -25,
           max: 25,
+        },
+      };
     } else if (fieldName == "gpsTrajectoryTiltAngle") {
       return {
         power: 1.0,
         MinMax: {
           min: -90,
           max: 90,
         },
       };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17e89ab and cd0eaa1.

📒 Files selected for processing (3)
  • src/flightlog.js (7 hunks)
  • src/flightlog_fields_presenter.js (2 hunks)
  • src/graph_config.js (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-05-26T16:18:25.863Z
Learnt from: demvlad
Repo: betaflight/blackbox-log-viewer PR: 833
File: src/graph_spectrum.js:0-0
Timestamp: 2025-05-26T16:18:25.863Z
Learning: In src/graph_spectrum_calc.js, the user created dedicated PSD functions `dataLoadPowerSpectralDensityVsThrottle()` and `dataLoadPowerSpectralDensityVsRpm()` instead of using boolean parameters, following a consistent naming pattern for spectrum data loading methods.

Applied to files:

  • src/graph_config.js
🧬 Code graph analysis (1)
src/graph_config.js (2)
src/graph_legend.js (1)
  • fieldName (191-191)
src/graph_minmax_setting_menu.js (1)
  • fieldName (896-896)
🪛 Biome (2.1.2)
src/graph_config.js

[error] 493-493: expected , but instead found else

Remove else

(parse)


[error] 493-493: expected : but instead found if

Remove if

(parse)


[error] 493-493: expected , but instead found ==

Remove ==

(parse)


[error] 493-493: This property is later overwritten by an object member with the same name.

Overwritten with this property.

If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored.
Unsafe fix: Remove this property.

(lint/suspicious/noDuplicateObjectKeys)


[error] 493-501: This method is later overwritten by an object member with the same name.

Overwritten with this method.

If an object property with the same name is defined multiple times (except when combining a getter with a setter), only the last definition makes it into the object and previous definitions are ignored.
Unsafe fix: Remove this method.

(lint/suspicious/noDuplicateObjectKeys)

🪛 GitHub Actions: Deployment to Cloudflare Pages
src/graph_config.js

[error] 1-1: vite-plugin-pwa:build: [plugin vite:build-import-analysis] Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension.

🔇 Additional comments (4)
src/flightlog_fields_presenter.js (1)

144-144: LGTM! Consistent field presentation.

The friendly name and formatting for gpsTrajectoryTiltAngle correctly follow the same pattern as gpsHomeAzimuth, displaying the angle with one decimal place and the degree symbol.

Also applies to: 857-857

src/flightlog.js (3)

33-33: LGTM! Field count and naming correctly updated.

The ADDITIONAL_COMPUTED_FIELD_COUNT is appropriately incremented to 21, and the new field is added in the GPS section with a clear comment explaining its purpose.

Also applies to: 289-289


640-644: LGTM! GPS velocity indices properly defined and validated.

The gpsVelNED array and its null check follow the same pattern as other GPS-related field indices like gpsCoord, ensuring the field is only processed when GPS velocity data is available.

Also applies to: 714-716


758-765: Clarify unrelated quaternion normalization change.

This quaternion normalization code appears unrelated to the trajectory tilt angle feature described in the PR. The previous code only handled the case where m < 1.0, but this adds an else branch to normalize when m >= 1.0.

Was this change intentional? If it's a bug fix or improvement, it should ideally be in a separate PR with its own description and testing.

@demvlad demvlad marked this pull request as ready for review December 17, 2025 19:58
@haslinghuis haslinghuis added this to the 2025.12.0 milestone Dec 17, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 18, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 18, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 18, 2025
@sonarqubecloud
Copy link

@github-actions
Copy link

Preview URL: https://pr875.betaflight-blackbox.pages.dev

@demvlad
Copy link
Contributor Author

demvlad commented Dec 19, 2025

@coderabbitai
Please, check my last code improvements

@coderabbitai
Copy link

coderabbitai bot commented Dec 19, 2025

@demvlad I'll review the latest code improvements in your PR. Let me examine the changes you've made to the trajectory tilt angle implementation.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/flightlog.js (1)

911-926: Good improvements addressing previous review concerns.

The implementation now includes:

  • ✓ Bounds checking via clamping (line 920) to prevent NaN from asin
  • ✓ Documented threshold units (line 917: "5cm/s")
  • ✓ Better numerical stability using Math.hypot instead of manual square-root calculation
  • ✓ Increased threshold from 1 to 5 cm/s (more practical)

The null/undefined handling for velocity components is implicit: if any component is null/undefined, Math.hypot returns NaN, the condition velocity > minVelo evaluates to false, and the angle safely defaults to 0. While this works correctly, the previous review suggested explicit null checks for clarity.

Optional: Explicit null handling for maintainability

If you prefer to make the null handling explicit (as suggested in the previous review), consider:

             // Calculate trajectory tilt angle by NED GPS velocity
             if (gpsVelNED) {
               const Vn = srcFrame[gpsVelNED[0]],
                     Ve = srcFrame[gpsVelNED[1]],
                     Vd = srcFrame[gpsVelNED[2]];
+              
+              if (Vn == null || Ve == null || Vd == null) {
+                destFrame[fieldIndex++] = 0;
+              } else {
                 const velocity = Math.hypot(Vn, Ve, Vd);
                 const minVelo = 5;  // 5cm/s limit to prevent division by zero and miss tiny noise values
                 let trajectoryTiltAngle = 0;
                 if (velocity > minVelo) {
                   const angleSin = Math.max(-1, Math.min(1, Vd / velocity));
                   trajectoryTiltAngle = -Math.asin(angleSin) * 180 / Math.PI; // [degree], if velo is up then >0
                 }
                 destFrame[fieldIndex++] = trajectoryTiltAngle;
+              }
             } else {
               destFrame[fieldIndex++] = 0;
             }

This makes the intent clearer for future maintainers, though the current implicit handling is functionally correct.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0fbe88 and 3241059.

📒 Files selected for processing (2)
  • src/flightlog.js (7 hunks)
  • src/graph_config.js (63 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/graph_config.js
🔇 Additional comments (5)
src/flightlog.js (5)

33-33: LGTM!

The field count increment is correct for the new gpsTrajectoryTiltAngle field, and the comment accurately documents all computed fields.


288-289: LGTM!

The field name addition follows the established naming convention and is correctly positioned with GPS-related fields.


640-644: LGTM!

The gpsVelNED initialization follows the established pattern for field index arrays and correctly references the GPS NED velocity components.


714-716: LGTM!

The availability check for gpsVelNED follows the same defensive pattern used for other optional field arrays.


758-765: LGTM!

The formatting change improves consistency and readability by using explicit braces for the else block.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants