-
Notifications
You must be signed in to change notification settings - Fork 304
Feature/lxnav105 #1963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Feature/lxnav105 #1963
Conversation
- Add SetVolume() function to LXNAVVario namespace - Update PutVolume() to support both LXNAV Vario and LX16xx devices - Add VOL setting to LXNAVVarioConfigWidget for reading and writing volume - Volume can be configured via device config dialog (0-100%) - Implements PLXV0,VOL protocol command per LXNAV specification 1.05
…io devices - Add support for reading and writing ALTOFF setting via PLXV0 protocol - Implement all three ALTOFF parameters: error, QNH, and takeoff offset - Add three integer fields to LXNAVVarioConfigWidget (-1000 to 1000 meters) - Use NMEAInputLine utility for parsing comma-separated float values - Implements PLXV0,ALTOFF protocol command per LXNAV specification 1.05
Add generic elevation setting support to the device interface, allowing devices to provide and receive elevation values for calibration. - Add elevation to ExternalSettings for device-provided elevation values - Add PutElevation() and RequestElevation() to Device interface - Implement elevation support in LXNAV driver via PLXV0,ELEVATION - Add elevation control to AltitudeSetupPanel (AutoAltitude InfoBox) - Display elevation value from device or "N/A" if not available - Integrate elevation with AutoQNH to sync elevation when QNH is set - Request elevation from devices when opening AltitudeSetup dialog The elevation setting is abstracted through ExternalSettings, similar to QNH, keeping the UI layer independent of driver-specific implementations.
Add firmware version logging when LXNAV devices are detected via PLXVC. The firmware and hardware version are included in the detection log message, or logged separately if received later via LXWP1. - Include firmware/hardware version in device detection log message - Use "unknown" for missing version information - Log firmware version separately if received after device detection - Only log once per device connection
- Parse license string from LXWP1 sentence - Display license in device setup dialogs (ManageLXNAVVarioDialog, ManageNanoDialog, ManageLX16xxDialog) as read-only field - Remove hardware version from PLXVC detection logging (it contains serial number, not hardware version, for privacy reasons) - Filter out high-frequency LXWP2 sentences from NMEA logging - Remove firmware version logging from LXWP1 handler (already logged in device detection message) All device information (product, serial, hardware version, firmware, license) remains available in the configuration dialogs when received from the device.
Extend baud rate options in device configuration dialog to include 256000, 460800, 500000, 921600, and 1000000 baud rates. Implement custom baud rate support for Linux using TIOCSSERIAL with ASYNC_SPD_CUST flag. This method works with USB-to-serial drivers like FTDI that don't support termios2. - Add TIOCSSERIAL implementation for baud rates > 230400 on Linux - Remove termios2 implementation (not widely supported by USB drivers) - Update GetBaudrate() to read custom baud rates from TIOCSSERIAL - Add platform-specific comments explaining Windows/macOS/iOS/Android behavior Windows natively supports arbitrary baud rates via SerialPort. macOS/iOS don't support TIOCSSERIAL and will show an error for custom baud rates. Android uses platform-specific implementations. TIOCSSERIAL has been available since Linux kernel 2.2, ensuring compatibility with older systems.
Parse the IGC press altitude field from PLXVS sentence and use it as the barometric altitude in IGC files when available. This ensures XCSoar's IGC files match the device's own IGC recording values. - Add igc_pressure_altitude field to NMEAInfo - Parse IGC press altitude from PLXVS sentence - Use IGC pressure altitude with highest priority in IGCFix::Apply() - Priority: IGC pressure altitude > pressure altitude > baro altitude > GPS altitude This follows the IGC standard requirement that the barometric altitude should match the device's recording value when available.
Add OnCalculatedUpdate method to send MacCready value to LXNAV device on startup. This ensures MC is synchronized when XCSoar starts, similar to how the OpenVario driver handles it. - Add mc_sent flag to track if MC has been sent - Implement OnCalculatedUpdate to send MC on first calculation cycle - Reset mc_sent flag in LinkTimeout for reconnection handling - Use proper locking to avoid race conditions
Refactor MC, Ballast, and Bugs synchronization to use ExternalSettings from the blackboard instead of DeviceSettingsMap. This makes the code consistent with XCSoar's architecture and eliminates data duplication. Changes: - Use basic.settings (ExternalSettings) from blackboard for all settings - Add SyncMacCready(), SyncBallast(), SyncBugs() utility functions - Add IsMCEcho(), IsBallastEcho(), IsBugsEcho() helper functions - Track last_sent values for feedback loop detection - Request MC on vario detection; ballast/bugs come via LXWP2 - If device has non-zero values (and not an echo), use device's values - Otherwise, send XCSoar's values to the device This ensures proper synchronization while respecting device settings and preventing feedback loops.
When converting ballast overload to ballast fraction, handle cases where the overload is less than 1.0 (glider lighter than reference mass). The ballast fraction must be clamped to >= 0 since negative water ballast is not physically possible. Also removed the >= 0.8 check to allow processing of any overload value, as overload can theoretically be negative when the actual mass is lighter than the reference mass.
- Rename ballast member to ballast_litres for clarity - Remove SetBallast()/GetBallast() fraction-based methods - Add SetBallastLitres(), SetBallastFraction(), SetBallastOverload() - Add GetBallastFraction(), GetBallastOverload() - Add max_ballast as configured member (not calculated) - Update all call sites to use new litres-based API - Update ActionInterface, ApplyExternalSettings, BallastDumpManager, dlgBasicSettings, GaugeVario, InputEventsSettings, lua/Settings, PlaneGlue to use GetBallastLitres() and related methods
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis pull request introduces significant infrastructure enhancements and a major ballast handling refactoring. It adds new build automation scripts and documentation, extends device driver capabilities (particularly LX LXNAV vario), refactors ballast from fraction-based to absolute litres-based representation throughout the codebase, expands external settings with elevation and POLAR data fields, and adds comprehensive FLARM protocol analysis documentation alongside new specification files. Changes
Sequence DiagramsequenceDiagram
participant User as User<br/>(Settings UI)
participant XCSoar as XCSoar<br/>(Core)
participant Device as LX Device<br/>(LXNAV Vario)
participant External as External<br/>Settings
User->>XCSoar: Set Crew Mass
activate XCSoar
XCSoar->>XCSoar: ActionInterface::SetCrewMass()
XCSoar->>External: ProvideCrewMass() check
XCSoar->>Device: PutCrewMass(crew_mass)
activate Device
Device->>Device: Send PLXV0,POLAR,...
Device-->>XCSoar: Success
deactivate Device
XCSoar->>XCSoar: SetTaskPolar (recalculate)
deactivate XCSoar
User->>XCSoar: Request Elevation
activate XCSoar
XCSoar->>Device: RequestElevation()
activate Device
Device->>Device: Send PLXV0,ELEVATION,R
Device-->>Device: Receive PLXV0,ELEVATION,W,...
Device-->>XCSoar: elevation data via PLXV0
deactivate Device
XCSoar->>External: ProvideElevation()
XCSoar->>XCSoar: Update DerivedInfo.pressure_elevation
deactivate XCSoar
Device->>Device: Periodic update (OnCalculatedUpdate)
activate Device
Device->>Device: SyncMacCready/Ballast/Bugs/CrewWeight/EmptyWeight
Device->>Device: Echo detection (avoid redundant sends)
Device->>XCSoar: PutBallast/SetMacCready if changed
deactivate Device
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Key areas requiring extra attention:
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/ApplyExternalSettings.cpp (1)
45-57: Consider propagating ballast litres changes via SetTaskPolar.The
BallastLitresProcessTimer()function sets ballast litres directly (line 52) but doesn't callSetTaskPolarto propagate changes, unlike the refactoredBallastProcessTimer()which callsSetTaskPolarafter bothSetBallastFraction(line 25) andSetBallastOverload(line 35).This inconsistency may prevent ballast litres updates from being properly propagated to backend components.
Consider applying this change for consistency:
BallastLitresProcessTimer() { bool modified = false; static Validity last_ballast_litres_validity; const NMEAInfo &basic = CommonInterface::Basic(); if(basic.settings.ballast_litres_available.Modified(last_ballast_litres_validity)){ PolarSettings &polar(CommonInterface::SetComputerSettings().polar); polar.glide_polar_task.SetBallastLitres(basic.settings.ballast_litres); + backend_components->SetTaskPolar(CommonInterface::GetComputerSettings().polar); modified = true; } last_ballast_litres_validity = basic.settings.ballast_litres_available; return modified; }src/NMEA/ExternalSettings.hpp (1)
162-171: Typo in comment: "absolure" should be "absolute"./** - * Compare the absolure ballast in kg (litres) setting with the specified value. + * Compare the absolute ballast in kg (litres) setting with the specified value. *
🧹 Nitpick comments (24)
check_screensize_usage.sh (1)
1-197: Script provides good automation for pattern analysis.The script effectively scans directories, aggregates pattern matches, and surfaces inconsistencies. It complements the SCREENSIZE_ANALYSIS.md documentation well. Error handling with
set -eand2>/dev/nullredirection is appropriate for a scanning utility.Minor suggestions:
- Consider adding an exit code check after grep commands (some fail silently with
|| true)- The logic at lines 64–68 could be simplified using grep's
-lflag directlysrc/Device/Port/TTYPort.cpp (2)
26-60: Consider using<linux/serial.h>instead of local definitions.Defining
serial_structlocally works but risks divergence from kernel definitions. The kernel's serial struct is part of the stable UAPI, so including<linux/serial.h>would be more maintainable and automatically provideTIOCGSERIAL,TIOCSSERIAL, andASYNC_SPD_CUST.If there's a specific reason to avoid the header (e.g., cross-compilation issues), a comment explaining this choice would be helpful.
#ifdef __linux__ #include <sys/ioctl.h> -/* For TIOCSSERIAL method (works on USB-to-serial drivers like FTDI) */ -/* TIOCSSERIAL has been available since kernel 2.2 */ -#ifndef TIOCGSERIAL -#define TIOCGSERIAL 0x541E -#endif -#ifndef TIOCSSERIAL -#define TIOCSSERIAL 0x541F -#endif -/* ASYNC_SPD_CUST may not be defined in very old kernel headers (pre-2.4) */ -#ifndef ASYNC_SPD_CUST -#define ASYNC_SPD_CUST 0x0030 -#endif -struct serial_struct { - int type; - int line; - unsigned int port; - int irq; - int flags; - int xmit_fifo_size; - int custom_divisor; - int baud_base; - unsigned short close_delay; - char io_type; - char reserved_char[1]; - int hub6; - unsigned short closing_wait; - unsigned short closing_wait2; - unsigned char *iomem_base; - unsigned short iomem_reg_shift; - unsigned int port_high; - unsigned long iomap_base; -}; +#include <linux/serial.h> #endif
163-178: Reduce code duplication in termios attribute setup.The termios configuration (lines 167-178) is nearly identical to the standard path (lines 200-210). Consider extracting a helper function to set the common attributes.
static void ConfigureRawMode(struct termios &attr) noexcept { attr.c_iflag &= ~(BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); attr.c_iflag |= (IGNPAR | IGNBRK); attr.c_oflag &= ~OPOST; attr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); attr.c_cflag &= ~(CSIZE | PARENB | CRTSCTS); attr.c_cflag |= (CS8 | CLOCAL); attr.c_cc[VMIN] = 0; attr.c_cc[VTIME] = 1; }Also applies to: 196-211
build_quick_test.sh (1)
59-60: Remove trailing blank lines.The script has unnecessary blank lines at the end. This is a minor style issue.
Apply this diff:
echo "Summary: $SUCCESS successful, $FAILED failed" - - -build_all_configs.sh (4)
31-33: Use explicit no-op command for file truncation.Shellcheck warns that these redirections lack commands. While
> fileworks in bash, using: > fileortrue > fileis more explicit and portable.# Initialize result files -> "$RESULTS_FILE" -> "$FAILED_BUILDS" -> "$SUCCESSFUL_BUILDS" +: > "$RESULTS_FILE" +: > "$FAILED_BUILDS" +: > "$SUCCESSFUL_BUILDS"
128-135: Remove unusedTARGET_SPECIFIC_FLAGSvariable.This array is defined but never referenced. If it's intended as documentation, consider converting it to a comment. If it's planned for future use, add a
# shellcheck disable=SC2034annotation or remove it.-# Flags that are target-specific and should be skipped for certain targets -TARGET_SPECIFIC_FLAGS=( - "ENABLE_SDL" # Only for UNIX-like targets - "USE_FB" # Only for Linux targets - "VFB" # Only for certain targets - "ENABLE_MESA_KMS" # Only for Linux targets - "GREYSCALE" # Only for certain targets - "DITHER" # Only for certain targets -) +# Note: Target-specific flags (ENABLE_SDL, USE_FB, VFB, ENABLE_MESA_KMS, +# GREYSCALE, DITHER) are filtered in is_valid_combination()
192-197: Separate variable declaration and assignment.Shellcheck warns that combining
localdeclaration with command substitution can mask return values. While low risk here, it's good practice to separate them.- local flag_name=$(echo "$flags" | sed 's/ /_/g' | sed 's/=/-/g') + local flag_name + flag_name=$(echo "$flags" | sed 's/ /_/g' | sed 's/=/-/g') build_name="${target}_${flag_name}" fi - local log_file="${LOG_DIR}/${build_name}.log" - local start_time=$(date +%s) + local log_file start_time + log_file="${LOG_DIR}/${build_name}.log" + start_time=$(date +%s)
210-211: Add comment explaining intentional word splitting.The unquoted
$flagsis intentional to allow word splitting for multiple make arguments. Adding a brief comment would clarify this for maintainers and silence potential linter warnings.# Build with make + # Note: $flags intentionally unquoted for word splitting (multiple make args) if make TARGET="$target" $flags > "$log_file" 2>&1; thensrc/Device/Driver/LX/Internal.hpp (2)
131-152: Consider consolidating overlapping struct fields.
TrackedPolarandDevicePolarshare several common fields (a,b,c,empty_mass/empty_weight). While they serve different purposes (tracking XCSoar's view vs. device-reported data), consider whether a common base or shared structure could reduce duplication.This is optional since the current separation clearly delineates the two different data sources and their distinct usage patterns.
139-139: Minor: Remove extra blank line.There's a double blank line between
tracked_polarandDevicePolarstruct definitions.src/NMEA/Info.cpp (1)
125-127: Reset of IGC pressure altitude looks correct; consider matching expiry semanticsResetting
igc_pressure_altitude_availableandigc_pressure_altitudehere is good and avoids stale values after a full reset. Ifigc_pressure_altitudeis intended to behave like the other altitude sources, you may also want to expireigc_pressure_altitude_availableinNMEAInfo::Expire()with a similar timeout topressure_altitude_available, to avoid an IGC fix using a very old IGC altitude.build_logs/successful_builds.txt (1)
1-8: Build log format looks consistent with multi-config workflowThe entries follow a clear, parseable
name|status|duration|flagsformat and align with the described multi-config build logging. If0sdurations are not expected for some configs, it may be worth double-checking the timing logic in the generator script, but the file itself looks fine.src/Plane/Plane.hpp (1)
39-43: Consider default‑initialisingplane_profile_activeto avoid indeterminate stateThe new
plane_profile_activeflag is useful for distinguishing default vs. profile-based planes. To guard against default-constructedPlaneinstances where this flag might not be explicitly set, it would be safer to give it an in-class default:- bool plane_profile_active; + bool plane_profile_active = false;This ensures a well-defined default and avoids relying on all construction paths to remember to set it.
BUILD_ALL_CONFIGS.md (2)
79-81: Consider minor wording improvements.The phrase "Only successful builds" and "Only failed builds" on consecutive lines creates repetition. Consider rewording for better readability:
The script creates a `build_logs/` directory with: - Individual log files for each build (`<target>_<flags>.log`) - `build_results.txt` - All results -- `successful_builds.txt` - Only successful builds -- `failed_builds.txt` - Only failed builds +- `successful_builds.txt` - Successful builds only +- `failed_builds.txt` - Failed builds only
104-104: Simplify "with success/failure counts" phrase.-- The script provides a summary at the end with success/failure counts +- The script provides a summary at the end showing success/failure countssrc/Dialogs/Settings/dlgBasicSettings.cpp (1)
134-143: Consider usingstatic_castinstead of C-style cast.The C-style cast on line 137 is flagged by static analysis. Using C++ style casts is preferred for type safety and clarity.
- DataFieldFloat &df = *(DataFieldFloat *)control.GetDataField(); + DataFieldFloat &df = *static_cast<DataFieldFloat *>(control.GetDataField());FLARM_FTD014_SPECIFICATION_ANALYSIS.md (1)
50-52: Add language specifier to fenced code block.The code block lacks a language specifier, which is flagged by markdownlint.
-``` +```text $PFLAC,A,<name>*<checksum></blockquote></details> <details> <summary>src/Device/Driver/LX/LXNAVVario.hpp (1)</summary><blockquote> `106-112`: **Consider using `snprintf` for bounds safety.** While the buffer size (32 bytes) is sufficient for this format string, using `snprintf` would be safer and more consistent with secure coding practices. This applies to other functions in this file as well. ```diff static inline void SetVolume(Port &port, OperationEnvironment &env, unsigned volume) { char buffer[32]; - sprintf(buffer, "PLXV0,VOL,W,%.1f", (double)volume); + snprintf(buffer, sizeof(buffer), "PLXV0,VOL,W,%u", volume); PortWriteNMEA(port, buffer, env); }Note: The
(double)cast and%.1fformat are unnecessary for an integer value;%uwould be more direct.src/InfoBoxes/Panel/AltitudeSetup.cpp (2)
48-49: Replace C-style casts withstatic_castfor DataField typesIn
OnModified()andPrepare(), the casts:
DataFieldFloat &df = (DataFieldFloat &)_df;DataFieldInteger &df = (DataFieldInteger &)_df;DataFieldFloat &df = *(DataFieldFloat *)qnh_control->GetDataField();are safe given how the controls are created, but trigger the static-analysis warning and are less explicit than necessary.
Consider switching to
static_castto make the intent clear and keep tools quiet:- DataFieldFloat &df = (DataFieldFloat &)_df; + auto &df = static_cast<DataFieldFloat &>(_df); - DataFieldInteger &df = (DataFieldInteger &)_df; + auto &df = static_cast<DataFieldInteger &>(_df); - DataFieldFloat &df = *(DataFieldFloat *)qnh_control->GetDataField(); + auto &df = static_cast<DataFieldFloat &>(*qnh_control->GetDataField());Also applies to: 61-62, 86-89
94-113: UI thread blocks up to 1 s while polling device_blackboardThe 10×
Sleep(100)loop runs on the UI thread duringPrepare(), which can freeze the dialog for up to 1 second if the device is slow or absent. If this becomes noticeable, consider reducing the wait or making the elevation request/refresh asynchronous instead of busy-waiting in the dialog.src/Device/Driver/LX/Settings.cpp (1)
150-211: Clarify unsupported-device semantics and avoid redundantlast_sent_*updatesThe new methods generally look good, but there are two small consistency points:
Return values for unsupported devices
PutCrewMass()/PutEmptyMass()returntruewhen!IsLXNAVVario(), i.e. they no-op but report success.PutElevation()/RequestElevation()returnfalsefor non‑LXNAV varios.If callers interpret
falseas “feature not supported” (rather than a hard error), it might be clearer to use the same convention for all three families (either alwaystrue/no-op or alwaysfalsefor unsupported devices) and document it. Right now DeviceDescriptor wrappers will see different statuses depending on which setter is called.
last_sent_*tracking in two layers
PutBallast(),PutBugs(), andPutMacCready()already setlast_sent_ballast_overload,last_sent_bugs, andlast_sent_mcundermutex.LXDevice::SyncBallast(),SyncBugs(), andSyncMacCready()inMode.cppset the same fields again after calling these methods.This duplication is harmless but makes ownership of the “last sent” state a bit fuzzy. You can simplify by relying on the driver methods to own
last_sent_*updates and dropping the extra assignments inSync*, which reduces the chance of the two drifting apart during future refactors.Also applies to: 213-255, 270-295
src/Device/Driver/LX/Mode.cpp (1)
192-544: Verify ballast overload calculation uses the correct mass unitsThe new
OnCalculatedUpdate()/Sync*logic is comprehensive and the direction-of-truth handling (default plane → read from vario, plane profile active → push to vario) is well structured. One detail worth double‑checking is the ballast overload computation inSyncBallast():const GlidePolar &polar = calculated.glide_polar_safety; ... const double ballast_litres = polar.GetBallastLitres(); const double dry_mass = polar.GetDryMass(); const double reference_mass = polar.GetReferenceMass(); ... const double overload = (dry_mass + ballast_litres) / reference_mass; ... PutBallast(0.0, overload, env);This assumes that
ballast_litrescan be added directly todry_mass(i.e. that 1 litre of ballast is effectively treated as 1 kg and thatGetBallastLitres()is already “mass-like”). IfGlidePolarever changes to distinguish litres from kilograms more explicitly (e.g. with a density factor or a separateGetBallastMass()), this formula could drift.It’s probably fine today, but to future‑proof the code you might want to:
- either switch to a mass-returning API if one exists (e.g.
GetTotalMass()orGetBallastMassKg()), or- add a short comment documenting the 1‑litre‑≈‑1‑kg assumption so it’s clear this is intentional.
The rest of the sync logic (MC, bugs, crew/empty mass echo checks, and polar change tracking via
tracked_polaranddevice_polar) looks consistent and avoids unnecessary device traffic.Also applies to: 578-617
src/Engine/GlideSolvers/GlidePolar.hpp (2)
266-283: Clarify and harden semantics of new ballast setters/gettersThe new trio
SetBallastLitres/SetBallastFraction/SetBallastOverloadplusGetBallastLitres/GetBallastFraction/GetBallastOverloadlooks like a clean API split, but a couple of edge-case behaviours are worth nailing down in the implementation:
- For
SetBallastFraction(const double fraction)(Lines 273-276), it’s not obvious whether callers may pass values outside[0, 1](or NaNs) and whether you clamp, assert, or allow them through. Given it’s a config-like API, clamping to[0, 1](or at least documenting the expectation) would avoid surprising states.- Similarly for
SetBallastOverload(const double overload)(Lines 279-282), it would be good to define behaviour for values< 1.0(or<= 0) and for pathological values. If you treat overload as “total_mass / reference_mass”, then overload < 1 probably deserves either clamping or an assertion.- For
GetBallastFraction()andGetBallastOverload()(Lines 299-304, 305-309), please ensure the implementation handlesmax_ballast <= 0and/orreference_mass <= 0gracefully (e.g. returning0rather than risking division by zero or NaNs in degenerate configurations).HasBallast()(Lines 287-289) now usesballast_litres > 0, which is consistent with the new storage. If in practice you often end up with tiny residuals (e.g. numerical noise after dumps), consider using a small epsilon threshold rather than strict> 0, but that’s more of a style choice.Tightening these behaviours (and documenting them briefly in the comments) would make the new API safer to use in the various UI, device, and test call sites.
Also applies to: 287-297, 299-310
49-50: Keepmax_ballast,ballast_ratio, andreference_massinvariants explicitThe introduction of
ballast_litresandmax_ballastplus the changes inSetMaxBallastandSetBallastRatio(Lines 545-558, 566-573) nicely encode a relationship:
SetMaxBallast()derivesballast_ratio = max_ballast / reference_masswhenreference_mass > 0.SetBallastRatio()derivesmax_ballast = ballast_ratio * reference_masswhenreference_mass > 0.A couple of design points are worth considering to avoid surprising states:
SetReferenceMass()(Lines 507-512) currently just updatesreference_massand callsUpdate(), without re-synchronisingmax_ballast/ballast_ratio. If the intent is that these three always satisfy the same physical relation, you might want to recompute one from the other inSetReferenceMass()(or document that changingreference_massdoes not affect the configured capacity/ratio).- Conversely, if you intend
max_ballastandballast_ratioto be independent configuration knobs, automatically deriving one from the other insideSetMaxBallast()/SetBallastRatio()may be surprising. In that case, it may be clearer to drop the implicit recomputation and leave them orthogonal.SetMaxBallast()currently always callsUpdate()by default, although changing the capacity alone doesn’t change the actual all-up mass unless you also change the current ballast. IfUpdate()is relatively expensive in real use (e.g. called often from settings flows), you might consider makingupdate=falsethe default here or deferring updates to the point where current ballast or mass really changes.Clarifying and, if needed, slightly refactoring these interactions would make the invariants around ballast configuration more obvious to future maintainers.
Also applies to: 76-80, 545-558, 566-573
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (65)
.bash_aliases(1 hunks).gitignore(1 hunks)BUILD_ALL_CONFIGS.md(1 hunks)FLARM_ANALYSIS_SUMMARY.md(1 hunks)FLARM_FTD014_COMPLIANCE_CHECKLIST.md(1 hunks)FLARM_FTD014_SPECIFICATION_ANALYSIS.md(1 hunks)FLARM_PROTOCOL_ANALYSIS.md(1 hunks)FTD-014.txt(1 hunks)LXNAV_105.txt(1 hunks)SCREENSIZE_ANALYSIS.md(1 hunks)android/UsbSerial(1 hunks)android/ioio(1 hunks)bash_aliases(1 hunks)build/test.mk(1 hunks)build_all_configs.sh(1 hunks)build_logs/build_results.txt(1 hunks)build_logs/failed_builds.txt(1 hunks)build_logs/successful_builds.txt(1 hunks)build_quick_test.sh(1 hunks)check_screensize_usage.sh(1 hunks)foo.bash(1 hunks)src/ActionInterface.cpp(4 hunks)src/ActionInterface.hpp(2 hunks)src/ApplyExternalSettings.cpp(3 hunks)src/BallastDumpManager.cpp(1 hunks)src/Computer/AutoQNH.cpp(1 hunks)src/Device/Descriptor.cpp(4 hunks)src/Device/Descriptor.hpp(2 hunks)src/Device/Driver.cpp(1 hunks)src/Device/Driver.hpp(3 hunks)src/Device/Driver/LX/Internal.hpp(6 hunks)src/Device/Driver/LX/LXNAVVario.hpp(4 hunks)src/Device/Driver/LX/Mode.cpp(3 hunks)src/Device/Driver/LX/Parser.cpp(9 hunks)src/Device/Driver/LX/Settings.cpp(5 hunks)src/Device/MultipleDevices.cpp(2 hunks)src/Device/MultipleDevices.hpp(2 hunks)src/Device/Port/TTYPort.cpp(4 hunks)src/Dialogs/Device/DeviceEditWidget.cpp(1 hunks)src/Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp(4 hunks)src/Dialogs/Device/LX/LXNAVVarioConfigWidget.hpp(1 hunks)src/Dialogs/Device/LX/ManageLX16xxDialog.cpp(1 hunks)src/Dialogs/Device/LX/ManageLXNAVVarioDialog.cpp(1 hunks)src/Dialogs/Device/LX/ManageNanoDialog.cpp(1 hunks)src/Dialogs/Settings/dlgBasicSettings.cpp(3 hunks)src/Engine/GlideSolvers/GlidePolar.cpp(2 hunks)src/Engine/GlideSolvers/GlidePolar.hpp(5 hunks)src/Gauge/GaugeVario.cpp(1 hunks)src/IGC/IGCFix.cpp(1 hunks)src/InfoBoxes/Panel/AltitudeSetup.cpp(3 hunks)src/Input/InputEventsSettings.cpp(1 hunks)src/NMEA/Derived.cpp(1 hunks)src/NMEA/Derived.hpp(1 hunks)src/NMEA/DeviceInfo.hpp(1 hunks)src/NMEA/ExternalSettings.cpp(6 hunks)src/NMEA/ExternalSettings.hpp(3 hunks)src/NMEA/Info.cpp(1 hunks)src/NMEA/Info.hpp(1 hunks)src/Plane/Plane.hpp(1 hunks)src/Plane/PlaneFileGlue.cpp(1 hunks)src/Plane/PlaneGlue.cpp(4 hunks)src/lua/Settings.cpp(1 hunks)test/src/TestDriver.cpp(4 hunks)test/src/TestGlidePolar.cpp(4 hunks)test/src/test_replay_task.cpp(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-09-04T20:52:26.947Z
Learnt from: lordfolken
Repo: XCSoar/XCSoar PR: 0
File: :0-0
Timestamp: 2025-09-04T20:52:26.947Z
Learning: In XCSoar's ApplyExternalSettings.cpp:178, when processing transponder data from external devices like Air Control Display, both transponder_code.IsDefined() and transponder_mode.IsDefined() must be checked before calling ActionInterface::SetTransponderCode() to prevent assertion failures when the transponder is switched off.
Applied to files:
src/ApplyExternalSettings.cppFLARM_PROTOCOL_ANALYSIS.mdFLARM_FTD014_COMPLIANCE_CHECKLIST.mdsrc/InfoBoxes/Panel/AltitudeSetup.cppsrc/NMEA/ExternalSettings.cppsrc/Device/Driver/LX/Mode.cppsrc/Device/Driver/LX/Parser.cppsrc/Device/Driver/LX/Internal.hpp
📚 Learning: 2025-08-02T01:25:49.521Z
Learnt from: yorickreum
Repo: XCSoar/XCSoar PR: 1714
File: src/ProgressWindow.cpp:0-0
Timestamp: 2025-08-02T01:25:49.521Z
Learning: In XCSoar's ProgressWindow.cpp, the iOS layout positioning issues that previously required magic number workarounds (3x progress_height multipliers) have been resolved with a proper fix that eliminates the need for hardcoded adjustments.
Applied to files:
src/ApplyExternalSettings.cppsrc/Dialogs/Device/LX/LXNAVVarioConfigWidget.cppsrc/IGC/IGCFix.cpp
📚 Learning: 2025-08-02T01:25:49.521Z
Learnt from: yorickreum
Repo: XCSoar/XCSoar PR: 1714
File: src/ProgressWindow.cpp:0-0
Timestamp: 2025-08-02T01:25:49.521Z
Learning: In XCSoar's ProgressWindow.cpp, iOS layout positioning issues that previously required magic number workarounds (3x progress_height multipliers) and platform-specific conditional code have been resolved with a proper fix, eliminating the need for hardcoded adjustments in the UpdateLayout method.
Applied to files:
src/Device/Driver/LX/Mode.cpp
🧬 Code graph analysis (22)
src/Device/Descriptor.hpp (3)
src/Device/Driver.hpp (14)
crew_mass(91-91)crew_mass(279-279)env(48-48)env(125-125)env(140-140)env(178-178)env(271-271)env(284-284)env(286-286)env(296-296)empty_mass(99-99)empty_mass(280-280)elevation(117-117)elevation(283-283)src/Device/Driver/LX/Internal.hpp (5)
crew_mass(367-367)env(348-348)env(350-350)empty_mass(368-368)elevation(372-372)src/Device/MultipleDevices.hpp (7)
crew_mass(79-79)env(66-66)env(68-68)env(82-82)env(90-90)empty_mass(80-80)elevation(89-89)
src/ApplyExternalSettings.cpp (6)
src/MainWindow.cpp (2)
SetComputerSettings(958-963)SetComputerSettings(959-959)src/MapWindow/GlueMapWindow.cpp (2)
SetComputerSettings(75-86)SetComputerSettings(76-76)src/BackendComponents.hpp (1)
settings(59-59)src/Menu/ExpandMacros.cpp (2)
GetComputerSettings(228-232)GetComputerSettings(229-229)src/MainWindow.hpp (1)
settings_computer(290-290)src/Device/MultipleDevices.hpp (1)
elevation(89-89)
src/Plane/PlaneFileGlue.cpp (1)
src/Plane/PlaneFileGlue.hpp (1)
Read(17-17)
src/Device/MultipleDevices.cpp (3)
src/Device/Descriptor.cpp (10)
PutCrewMass(886-910)PutCrewMass(887-887)env(53-55)env(53-53)PutEmptyMass(912-936)PutEmptyMass(913-913)PutElevation(1093-1117)PutElevation(1094-1094)RequestElevation(1119-1143)RequestElevation(1120-1120)src/Device/Driver.cpp (8)
PutCrewMass(47-51)PutCrewMass(48-48)PutEmptyMass(53-57)PutEmptyMass(54-54)PutElevation(66-70)PutElevation(67-67)RequestElevation(72-76)RequestElevation(73-73)src/Device/Driver/LX/Settings.cpp (8)
PutCrewMass(213-233)PutCrewMass(214-214)PutEmptyMass(235-255)PutEmptyMass(236-236)PutElevation(270-282)PutElevation(271-271)RequestElevation(284-294)RequestElevation(285-285)
src/ActionInterface.hpp (5)
src/Dialogs/Settings/dlgBasicSettings.cpp (2)
ballast_litres(81-86)ballast_litres(81-81)src/Engine/GlideSolvers/GlidePolar.hpp (5)
ballast_litres(287-289)ballast_litres(295-297)crew_mass(541-543)empty_mass(515-517)empty_mass(520-522)src/Device/Descriptor.hpp (2)
crew_mass(547-547)empty_mass(548-548)src/Device/Driver.hpp (4)
crew_mass(91-91)crew_mass(279-279)empty_mass(99-99)empty_mass(280-280)src/Device/MultipleDevices.hpp (2)
crew_mass(79-79)empty_mass(80-80)
src/lua/Settings.cpp (1)
src/MainWindow.hpp (1)
settings_computer(290-290)
src/Device/Port/TTYPort.cpp (1)
src/Device/Port/Port.hpp (1)
BaudRate(114-114)
src/Device/MultipleDevices.hpp (3)
src/Device/Descriptor.hpp (10)
crew_mass(547-547)env(394-394)env(403-403)env(410-410)env(418-418)env(428-428)env(550-550)env(561-561)empty_mass(548-548)elevation(560-560)src/Device/Driver.hpp (13)
crew_mass(91-91)crew_mass(279-279)env(48-48)env(125-125)env(140-140)env(178-178)env(271-271)env(284-284)env(286-286)empty_mass(99-99)empty_mass(280-280)elevation(117-117)elevation(283-283)src/Device/Driver/LX/Internal.hpp (3)
crew_mass(367-367)empty_mass(368-368)elevation(372-372)
src/IGC/IGCFix.cpp (1)
src/IGC/IGCFix.hpp (1)
basic(95-95)
src/Device/Driver/LX/Settings.cpp (4)
src/Device/Driver/LX/Mode.cpp (2)
EnableNMEA(56-96)EnableNMEA(57-57)src/Device/Descriptor.cpp (8)
PutCrewMass(886-910)PutCrewMass(887-887)env(53-55)env(53-53)EnableNMEA(565-586)EnableNMEA(566-566)PutElevation(1093-1117)PutElevation(1094-1094)src/Device/MultipleDevices.cpp (4)
PutCrewMass(101-106)PutCrewMass(102-102)PutElevation(163-168)PutElevation(164-164)src/Device/Driver/LX/LXNAVVario.hpp (6)
SetPilotWeight(142-152)SetPilotWeight(143-143)SetEmptyWeight(158-168)SetEmptyWeight(159-159)SetElevation(118-124)SetElevation(119-119)
src/Device/Driver.hpp (3)
src/Device/Descriptor.hpp (10)
crew_mass(547-547)env(394-394)env(403-403)env(410-410)env(418-418)env(428-428)env(550-550)env(561-561)elevation(560-560)pres(558-559)src/Device/Driver/LX/Internal.hpp (6)
crew_mass(367-367)env(348-348)env(350-350)env(359-359)elevation(372-372)pres(369-370)src/Device/MultipleDevices.hpp (7)
crew_mass(79-79)env(66-66)env(68-68)env(82-82)env(90-90)elevation(89-89)pres(88-88)
src/Dialogs/Settings/dlgBasicSettings.cpp (1)
src/Engine/GlideSolvers/GlidePolar.hpp (5)
_crew_mass(533-538)_crew_mass(533-533)ballast_litres(287-289)ballast_litres(295-297)overload(282-282)
src/InfoBoxes/Panel/AltitudeSetup.cpp (3)
src/Device/Descriptor.hpp (8)
env(394-394)env(403-403)env(410-410)env(418-418)env(428-428)env(550-550)env(561-561)elevation(560-560)src/Device/MultipleDevices.hpp (3)
elevation(89-89)i(47-49)i(47-47)src/system/Sleep.h (1)
Sleep(14-23)
src/BallastDumpManager.cpp (2)
src/Dialogs/Settings/dlgBasicSettings.cpp (2)
ballast_litres(81-86)ballast_litres(81-81)src/Engine/GlideSolvers/GlidePolar.hpp (3)
ballast_litres(287-289)ballast_litres(295-297)max_ballast(546-548)
src/ActionInterface.cpp (5)
src/ActionInterface.hpp (1)
SetBallast(23-23)src/Dialogs/Settings/dlgBasicSettings.cpp (5)
SetBallast(129-162)SetBallast(130-130)ballast_litres(81-86)ballast_litres(81-81)backend_components(77-79)src/Engine/GlideSolvers/GlidePolar.hpp (7)
ballast_litres(287-289)ballast_litres(295-297)polar(581-583)overload(282-282)crew_mass(541-543)empty_mass(515-517)empty_mass(520-522)src/Device/MultipleDevices.hpp (2)
crew_mass(79-79)empty_mass(80-80)src/Menu/ExpandMacros.cpp (2)
GetComputerSettings(228-232)GetComputerSettings(229-229)
src/NMEA/ExternalSettings.cpp (1)
src/NMEA/ExternalSettings.hpp (4)
add(116-116)other(127-128)time(115-115)a(240-240)
src/Device/Driver/LX/Mode.cpp (3)
src/Device/Descriptor.cpp (6)
OnCalculatedUpdate(1335-1347)OnCalculatedUpdate(1336-1337)env(53-55)env(53-53)PutMacCready(789-819)PutMacCready(790-791)src/Device/Driver/LX/Internal.hpp (12)
basic(385-386)basic(442-445)basic(450-453)basic(458-461)basic(462-465)basic(466-469)env(348-348)env(350-350)env(359-359)env(373-373)env(376-376)env(378-378)src/Device/Driver/LX/LXNAVVario.hpp (2)
SetPilotWeight(142-152)SetPilotWeight(143-143)
src/Plane/PlaneGlue.cpp (2)
src/Plane/PlaneFileGlue.cpp (2)
ReadFile(134-149)ReadFile(135-135)src/Plane/PlaneFileGlue.hpp (1)
ReadFile(20-20)
src/NMEA/ExternalSettings.hpp (4)
src/Device/Descriptor.hpp (2)
elevation(560-560)time(615-622)src/Device/Driver.hpp (2)
elevation(117-117)elevation(283-283)src/Device/Driver/LX/Internal.hpp (1)
elevation(372-372)src/Device/MultipleDevices.hpp (1)
elevation(89-89)
src/Engine/GlideSolvers/GlidePolar.hpp (2)
src/Dialogs/Settings/dlgBasicSettings.cpp (2)
ballast_litres(81-86)ballast_litres(81-81)src/Engine/GlideSolvers/GlidePolar.cpp (2)
Update(39-60)Update(40-40)
src/Device/Driver/LX/Parser.cpp (3)
src/NMEA/Info.hpp (16)
value(393-397)value(393-393)value(403-411)value(403-403)value(425-429)value(425-425)value(435-443)value(435-435)value(458-461)value(458-458)value(468-471)value(468-468)value(478-481)value(478-478)value(491-495)value(491-491)src/NMEA/ExternalSettings.hpp (1)
a(240-240)src/Device/Driver/LX/Mode.cpp (2)
lock(30-30)lock(35-35)
src/Engine/GlideSolvers/GlidePolar.cpp (2)
src/Engine/GlideSolvers/GlidePolar.hpp (13)
litres(270-270)assert(139-142)assert(149-152)assert(161-164)assert(180-184)assert(191-195)assert(202-206)assert(213-217)ballast_litres(287-289)ballast_litres(295-297)fraction(276-276)max_ballast(546-548)overload(282-282)src/BallastDumpManager.cpp (2)
Update(34-86)Update(35-36)
🪛 GitHub Check: Codacy Static Code Analysis
build_quick_test.sh
[warning] 46-46: build_quick_test.sh#L46
Double quote to prevent globbing and word splitting.
check_screensize_usage.sh
[warning] 79-79: check_screensize_usage.sh#L79
total_files appears unused. Verify use (or export if used externally).
src/Device/Port/TTYPort.cpp
[warning] 27-27: src/Device/Port/TTYPort.cpp#L27
Include file: <sys/ioctl.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
build_all_configs.sh
[warning] 128-128: build_all_configs.sh#L128
TARGET_SPECIFIC_FLAGS appears unused. Verify use (or export if used externally).
[warning] 211-211: build_all_configs.sh#L211
Double quote to prevent globbing and word splitting.
src/Dialogs/Settings/dlgBasicSettings.cpp
[warning] 137-137: src/Dialogs/Settings/dlgBasicSettings.cpp#L137
C-style pointer casting
src/InfoBoxes/Panel/AltitudeSetup.cpp
[warning] 86-86: src/InfoBoxes/Panel/AltitudeSetup.cpp#L86
C-style pointer casting
src/Device/Driver/LX/Mode.cpp
[warning] 423-423: src/Device/Driver/LX/Mode.cpp#L423
The scope of the variable 'polar' can be reduced.
src/Device/Driver/LX/Internal.hpp
[warning] 18-18: src/Device/Driver/LX/Internal.hpp#L18
Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.
🪛 LanguageTool
FLARM_FTD014_SPECIFICATION_ANALYSIS.md
[style] ~95-~95: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...erify) - COMPCLASS - Competition class (need to verify) - NEWTASK - Task declaration co...
(REP_NEED_TO_VB)
[style] ~96-~96: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...) - NEWTASK - Task declaration command (need to verify) - ADDWP - Add waypoint command ...
(REP_NEED_TO_VB)
[style] ~97-~97: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...verify) - ADDWP - Add waypoint command (need to verify) ### Version Information **Spe...
(REP_NEED_TO_VB)
FLARM_PROTOCOL_ANALYSIS.md
[style] ~133-~133: Try using a synonym here to strengthen your wording.
Context: ...e.cpp:23-26` Issue: There's a TODO comment about FLARM declaration checks that men...
(COMMENT_REMARK)
BUILD_ALL_CONFIGS.md
[style] ~81-~81: This adverb was used twice in the sentence. Consider removing one of them or replacing them with a synonym.
Context: ...ccessful builds - failed_builds.txt - Only failed builds ## Examples ### Build o...
(ADVERB_REPETITION_PREMIUM)
[style] ~104-~104: ‘with success’ might be wordy. Consider a shorter alternative.
Context: ...he script provides a summary at the end with success/failure counts - Failed builds are logg...
(EN_WORDINESS_PREMIUM_WITH_SUCCESS)
FLARM_FTD014_COMPLIANCE_CHECKLIST.md
[style] ~4-~4: Some style guides suggest that commas should set off the year in a month-day-year date.
Context: ...ation-1.18.pdf Date: December 19, 2024 Version: 1.18 This checklist sho...
(MISSING_COMMA_AFTER_YEAR)
🪛 markdownlint-cli2 (0.18.1)
FLARM_FTD014_SPECIFICATION_ANALYSIS.md
50-50: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 Shellcheck (0.11.0)
check_screensize_usage.sh
[warning] 79-79: total_files appears unused. Verify use (or export if used externally).
(SC2034)
build_all_configs.sh
[warning] 31-31: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 32-32: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 33-33: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).
(SC2188)
[warning] 128-128: TARGET_SPECIFIC_FLAGS appears unused. Verify use (or export if used externally).
(SC2034)
[warning] 192-192: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 197-197: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 212-212: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 220-220: Declare and assign separately to avoid masking return values.
(SC2155)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
- GitHub Check: build (macos-14, MACOS, XCSoar, bin, XCSoar, false)
- GitHub Check: build (ubuntu-22.04, PC, XCSoar, bin, XCSoar, .exe, true, debian:bookworm-slim)
- GitHub Check: build (ubuntu-22.04, WIN64, XCSoar, bin, XCSoar, .exe, true, debian:bookworm-slim)
- GitHub Check: build (ubuntu-22.04, ANDROID_BUNDLE, XCSoar, bin, XCSoar, .apk, false, r26d, debian:bookworm-slim)
- GitHub Check: build (ubuntu-22.04, ANDROID, XCSoar, bin, XCSoar, .apk, true, r26d, debian:bookworm-slim)
- GitHub Check: build (ubuntu-22.04, KOBO, KoboRoot, KoboRoot, .tgz, true, debian:bookworm-slim)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: build (macos-14, IOS64, XCSoar, bin, XCSoar, false)
- GitHub Check: build (macos-14, MACOS, XCSoar, bin, XCSoar, false)
- GitHub Check: build (ubuntu-22.04, WIN64, XCSoar, bin, XCSoar, .exe, true, debian:bookworm-slim)
- GitHub Check: build (ubuntu-22.04, PC, XCSoar, bin, XCSoar, .exe, true, debian:bookworm-slim)
- GitHub Check: build (ubuntu-22.04, KOBO, KoboRoot, KoboRoot, .tgz, true, debian:bookworm-slim)
- GitHub Check: build (ubuntu-22.04, UNIX, xcsoar_7.44_amd64, xcsoar_, .deb, true, debian:bookworm-slim)
- GitHub Check: Codacy Static Code Analysis
| alias unix='cd ~/git-xcsoar/XCSoar && make -j16 USE_CCACHE=y TARGET=UNIX && ./output/UNIX/bin/xcsoar $@' | ||
| alias wayland='cd ~/git-xcsoar/XCSoar && make -j16 USE_CCACHE=y TARGET=WAYLAND && ./output/WAYLAND/bin/xcsoar $@' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove developer-specific configuration and duplicate file.
This file has two issues:
-
Hardcoded developer-specific paths: The aliases contain paths (
~/git-xcsoar/XCSoar) specific to your environment that won't work for other contributors. -
Duplicate file: This file duplicates the content of
bash_aliases(without the dot prefix). Only one should exist, and.bash_aliasesis the more conventional naming.
Please remove both alias files from the PR and keep them in your local environment. If you want to share these patterns with other developers, consider documenting them in developer documentation instead of committing personal configuration files.
🤖 Prompt for AI Agents
In .bash_aliases (lines 1-2) the file contains developer-specific hardcoded
paths and duplicates the non-dot bash_aliases file; remove both alias files from
the branch/PR (delete the committed .bash_aliases and the duplicate
bash_aliases), keep the aliases only in your local environment, and if you want
to share them add a short snippet in project developer documentation instead of
committing personal dotfiles; also ensure these files are not re-added by
updating the repo ignore rules or excluding them from commits.
| alias unix='cd ~/git-xcsoar/XCSoar && make -j16 USE_CCACHE=y TARGET=UNIX && ./output/UNIX/bin/xcsoar' | ||
| alias wayland='cd ~/git-xcsoar/XCSoar && make -j16 USE_CCACHE=y TARGET=WAYLAND && ./output/WAYLAND/bin/xcsoar' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove developer-specific configuration from the repository.
These aliases contain hardcoded paths (~/git-xcsoar/XCSoar) that are specific to your development environment and will not work for other contributors. Developer-specific configuration files should not be committed to the repository.
Consider one of the following approaches:
- Remove this file entirely and keep it in your local environment
- Document the alias pattern in developer documentation for others to adapt
- Use environment variables instead of hardcoded paths (e.g.,
${XCSOAR_ROOT:-~/git-xcsoar/XCSoar})
Note: This file also appears to be duplicated as .bash_aliases (with a dot prefix).
🤖 Prompt for AI Agents
In bash_aliases around lines 1-2 the file contains developer-specific hardcoded
paths; remove or replace them: either delete this file from the repo and add it
to .gitignore (keeping a local copy), or replace the hardcoded path with an
environment-variable-based pattern like use ${XCSOAR_ROOT:-~/git-xcsoar/XCSoar}
in the alias so others can override it, and add a short note to developer docs
describing the alias pattern; also remove the duplicate (or consolidate) so only
the canonical .bash_aliases remains in the repo.
|
|
||
| # With flags | ||
| for flags in "${TEST_FLAGS[@]}"; do | ||
| if make TARGET="$target" $flags clean all > /dev/null 2>&1; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quote the variable to prevent word splitting.
The $flags variable should be quoted to prevent potential issues with word splitting and globbing, as indicated by the static analysis tool.
Apply this diff:
- if make TARGET="$target" $flags clean all > /dev/null 2>&1; then
+ if make TARGET="$target" "$flags" clean all > /dev/null 2>&1; thenHowever, note that in this specific case, $flags is intentionally unquoted because it contains multiple make variables that need to be split (e.g., "DEBUG=n LTO=y"). If you quote it, make will receive a single argument instead of separate variables. The current implementation is actually correct for this use case. You may want to add a shellcheck disable comment to suppress the warning:
# With flags
for flags in "${TEST_FLAGS[@]}"; do
+ # shellcheck disable=SC2086 - intentional word splitting for make flags
if make TARGET="$target" $flags clean all > /dev/null 2>&1; then📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if make TARGET="$target" $flags clean all > /dev/null 2>&1; then | |
| # With flags | |
| for flags in "${TEST_FLAGS[@]}"; do | |
| # shellcheck disable=SC2086 - intentional word splitting for make flags | |
| if make TARGET="$target" $flags clean all > /dev/null 2>&1; then |
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis
[warning] 46-46: build_quick_test.sh#L46
Double quote to prevent globbing and word splitting.
🤖 Prompt for AI Agents
In build_quick_test.sh around line 46, the static analyzer flagged unquoted
$flags in the make invocation; leave $flags unquoted because it must expand into
multiple make variable assignments (e.g., "DEBUG=n LTO=y"), and to silence the
warning add a ShellCheck disable comment directly above the if line (e.g., a
comment disabling SC2086) with a short rationale that $flags is intentionally
unquoted to allow word-splitting for make variables.
| echo "==========================================================" | ||
| echo "" | ||
|
|
||
| total_files=0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused variable declaration.
The variable total_files is initialized but never used in the script. Either remove this line or integrate the variable into the output logic if it was intended for reporting.
-total_files=0
for pattern in "${PATTERNS[@]}"; do📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| total_files=0 | |
| for pattern in "${PATTERNS[@]}"; do |
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis
[warning] 79-79: check_screensize_usage.sh#L79
total_files appears unused. Verify use (or export if used externally).
🪛 Shellcheck (0.11.0)
[warning] 79-79: total_files appears unused. Verify use (or export if used externally).
(SC2034)
🤖 Prompt for AI Agents
In check_screensize_usage.sh around line 79, the variable `total_files` is
declared but never used; remove this unused declaration to clean up the script,
or if it was intended to report the number of files, initialize and increment
`total_files` where files are discovered and include it in the script's final
output/report so the variable is actually referenced.
| #!/bin/bash | ||
|
|
||
| set -e | ||
| echo "hello world" | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove debug artifact from the PR.
This script appears to be a test/debug artifact with no production purpose. It only echoes "hello world" and is not referenced by any other files in the codebase.
Please remove this file from the PR.
🤖 Prompt for AI Agents
In foo.bash lines 1-5 the file is a debug/test artifact that only echoes "hello
world" and is unused; remove it from the PR by deleting the file from the branch
(e.g., run git rm foo.bash && git commit -m "remove debug artifact: foo.bash"
and push) or, if already committed in a feature branch, remove it from the
commit history (interactive rebase or git reset + recommit) so the file is no
longer present in the PR.
| const double max_ballast = glide_polar.GetBallastRatio() > 0 | ||
| ? glide_polar.GetBallastRatio() * glide_polar.GetReferenceMass() | ||
| : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use GetMaxBallast() instead of manual calculation.
The GlidePolar class provides GetMaxBallast() (see src/Engine/GlideSolvers/GlidePolar.hpp lines 545-547), which returns the max_ballast member directly. The manual calculation here may produce inconsistent results if max_ballast is set independently from ballast_ratio * reference_mass.
- // Calculate max ballast to determine dump rate
- const double max_ballast = glide_polar.GetBallastRatio() > 0
- ? glide_polar.GetBallastRatio() * glide_polar.GetReferenceMass()
- : 0;
+ // Get max ballast to determine dump rate
+ const double max_ballast = glide_polar.GetMaxBallast();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const double max_ballast = glide_polar.GetBallastRatio() > 0 | |
| ? glide_polar.GetBallastRatio() * glide_polar.GetReferenceMass() | |
| : 0; | |
| // Get max ballast to determine dump rate | |
| const double max_ballast = glide_polar.GetMaxBallast(); |
🤖 Prompt for AI Agents
In src/BallastDumpManager.cpp around lines 53 to 55, the code computes
max_ballast manually using GetBallastRatio() * GetReferenceMass(), which can be
inconsistent with the GlidePolar internal max_ballast; replace the manual
calculation with a call to glide_polar.GetMaxBallast() and assign that value
(ensuring the variable type remains double) so the code uses the canonical
max_ballast stored in GlidePolar.
| } else { | ||
| // No max ballast - dump directly from litres (assume 1L per second as fallback) | ||
| ballast_litres -= ToFloatSeconds(dt); | ||
|
|
||
| // Check if the plane is dry now | ||
| if (ballast_litres < 0) { | ||
| Stop(); | ||
| glide_polar.SetBallastLitres(0); | ||
| return false; | ||
| } | ||
|
|
||
| // Set new ballast | ||
| glide_polar.SetBallastLitres(ballast_litres); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent handling of dump_time in fallback path.
In the fraction-based path, the dump rate respects dump_time (ballast_fraction -= ToFloatSeconds(dt) / dump_time). However, in the fallback path, dump_time is ignored and a fixed 1 L/second rate is assumed. This inconsistency means the dump time configuration has no effect when max_ballast is zero.
Consider using dump_time consistently:
} else {
- // No max ballast - dump directly from litres (assume 1L per second as fallback)
- ballast_litres -= ToFloatSeconds(dt);
+ // No max ballast - dump directly from litres using dump_time
+ // dump_time represents total seconds to dump full ballast,
+ // but without max_ballast we need a reference. Using current ballast as reference:
+ if (ballast_litres > 0) {
+ ballast_litres -= ballast_litres * ToFloatSeconds(dt) / dump_time;
+ }Alternatively, clarify the intended behavior in documentation if the fixed 1 L/s rate is intentional.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } else { | |
| // No max ballast - dump directly from litres (assume 1L per second as fallback) | |
| ballast_litres -= ToFloatSeconds(dt); | |
| // Check if the plane is dry now | |
| if (ballast_litres < 0) { | |
| Stop(); | |
| glide_polar.SetBallastLitres(0); | |
| return false; | |
| } | |
| // Set new ballast | |
| glide_polar.SetBallastLitres(ballast_litres); | |
| } else { | |
| // No max ballast - dump directly from litres using dump_time | |
| // dump_time represents total seconds to dump full ballast, | |
| // but without max_ballast we need a reference. Using current ballast as reference: | |
| if (ballast_litres > 0) { | |
| ballast_litres -= ballast_litres * ToFloatSeconds(dt) / dump_time; | |
| } | |
| // Check if the plane is dry now | |
| if (ballast_litres < 0) { | |
| Stop(); | |
| glide_polar.SetBallastLitres(0); | |
| return false; | |
| } | |
| // Set new ballast | |
| glide_polar.SetBallastLitres(ballast_litres); |
🤖 Prompt for AI Agents
In src/BallastDumpManager.cpp around lines 71-83, the fallback path subtracts a
fixed 1 L/s ignoring dump_time; change it to respect dump_time by computing a
litres-per-second rate from the current ballast and dump_time (e.g.,
litres_per_sec = current_ballast_litres / dump_time) and subtracting
ToFloatSeconds(dt) * litres_per_sec, with a safe fallback to 1 L/s only when
dump_time is zero or invalid; ensure you still stop and clamp to zero as
currently done.
| if (speed == B0 && BaudRate > 230400) { | ||
| #ifdef __linux__ | ||
| struct serial_struct serinfo; | ||
| if (ioctl(tty.Get(), TIOCGSERIAL, &serinfo) < 0) | ||
| throw MakeErrno("TIOCGSERIAL failed"); | ||
|
|
||
| /* Set standard termios attributes first */ | ||
| struct termios attr; | ||
| if (!tty.GetAttr(attr)) | ||
| throw MakeErrno("tcgetattr() failed"); | ||
|
|
||
| attr.c_iflag &= ~(BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); | ||
| attr.c_iflag |= (IGNPAR | IGNBRK); | ||
| attr.c_oflag &= ~OPOST; | ||
| attr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); | ||
| attr.c_cflag &= ~(CSIZE | PARENB | CRTSCTS); | ||
| attr.c_cflag |= (CS8 | CLOCAL); | ||
| attr.c_cc[VMIN] = 0; | ||
| attr.c_cc[VTIME] = 1; | ||
| cfsetospeed(&attr, B38400); /* Use a standard speed as base */ | ||
| cfsetispeed(&attr, B38400); | ||
| if (!tty.SetAttr(TCSANOW, attr)) | ||
| throw MakeErrno("tcsetattr() failed"); | ||
|
|
||
| /* Set custom baud rate using TIOCSSERIAL */ | ||
| serinfo.flags |= ASYNC_SPD_CUST; | ||
| serinfo.custom_divisor = (serinfo.baud_base + (BaudRate / 2)) / BaudRate; | ||
| if (serinfo.custom_divisor < 1) | ||
| serinfo.custom_divisor = 1; | ||
| if (ioctl(tty.Get(), TIOCSSERIAL, &serinfo) < 0) | ||
| throw MakeErrno("TIOCSSERIAL failed"); | ||
| return; | ||
| #else | ||
| throw std::runtime_error("Custom baud rates above 230400 not supported on this platform"); | ||
| #endif | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for baud_base before computing divisor.
If serinfo.baud_base is zero or unexpectedly small (e.g., some virtual serial devices), the divisor calculation could produce incorrect results or the actual baud rate would be far from the requested value.
if (ioctl(tty.Get(), TIOCGSERIAL, &serinfo) < 0)
throw MakeErrno("TIOCGSERIAL failed");
+ if (serinfo.baud_base <= 0)
+ throw std::runtime_error("Serial port does not support custom baud rates (baud_base is 0)");
+
/* Set standard termios attributes first */🤖 Prompt for AI Agents
In src/Device/Port/TTYPort.cpp around lines 156-191, validate serinfo.baud_base
before computing custom_divisor: check if serinfo.baud_base is zero or
unreasonably small and handle it instead of using it in the divisor calculation.
If baud_base is 0 (or below a sane threshold) either throw a descriptive error
(MakeErrno or std::runtime_error) indicating custom baud rates are unsupported
for this device, or skip setting ASYNC_SPD_CUST and leave the port at the
standard base speed; do not perform the division when baud_base is zero to avoid
incorrect divisors or divide-by-zero. Ensure the chosen behavior returns/throws
before calling ioctl(TIOCSSERIAL).
| #ifdef __linux__ | ||
| /* Check if using custom baud rate via TIOCSSERIAL */ | ||
| struct serial_struct serinfo; | ||
| if (ioctl(tty.Get(), TIOCGSERIAL, &serinfo) == 0) { | ||
| if (serinfo.flags & ASYNC_SPD_CUST && serinfo.baud_base > 0) { | ||
| unsigned custom_baud = serinfo.baud_base / serinfo.custom_divisor; | ||
| if (custom_baud > 230400) | ||
| return custom_baud; | ||
| } | ||
| } | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard against division by zero when custom_divisor is zero.
If custom_divisor is zero (e.g., uninitialized or corrupted serial settings), line 363 will cause undefined behavior.
#ifdef __linux__
/* Check if using custom baud rate via TIOCSSERIAL */
struct serial_struct serinfo;
if (ioctl(tty.Get(), TIOCGSERIAL, &serinfo) == 0) {
- if (serinfo.flags & ASYNC_SPD_CUST && serinfo.baud_base > 0) {
+ if ((serinfo.flags & ASYNC_SPD_CUST) && serinfo.baud_base > 0 && serinfo.custom_divisor > 0) {
unsigned custom_baud = serinfo.baud_base / serinfo.custom_divisor;
if (custom_baud > 230400)
return custom_baud;
}
}
#endif🤖 Prompt for AI Agents
In src/Device/Port/TTYPort.cpp around lines 358 to 368, the code divides
serinfo.baud_base by serinfo.custom_divisor without checking for zero; add a
guard that ensures serinfo.custom_divisor != 0 (and typically > 0) before
performing the division and computing custom_baud, and if the divisor is zero
skip the custom baud calculation (or treat it as invalid) so no division by zero
can occur.
| if (SaveValueInteger(ALTOFF_ERROR, altoff_error) || | ||
| SaveValueInteger(ALTOFF_QNH, altoff_qnh) || | ||
| SaveValueInteger(ALTOFF_TAKEOFF, altoff_takeoff)) { | ||
| buffer.UnsafeFormat("%d,%d,%d", altoff_error, altoff_qnh, altoff_takeoff); | ||
| device.SendLXNAVVarioSetting("ALTOFF", buffer, env); | ||
| changed = true; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential bug: short-circuit evaluation may skip UI reads for unchanged fields.
The || operator short-circuits, so if SaveValueInteger(ALTOFF_ERROR, altoff_error) returns true, the other two SaveValueInteger calls won't execute. This means altoff_qnh and altoff_takeoff won't be updated from the UI before sending to the device.
Consider reading all values unconditionally:
- if (SaveValueInteger(ALTOFF_ERROR, altoff_error) ||
- SaveValueInteger(ALTOFF_QNH, altoff_qnh) ||
- SaveValueInteger(ALTOFF_TAKEOFF, altoff_takeoff)) {
+ bool altoff_changed = SaveValueInteger(ALTOFF_ERROR, altoff_error);
+ altoff_changed |= SaveValueInteger(ALTOFF_QNH, altoff_qnh);
+ altoff_changed |= SaveValueInteger(ALTOFF_TAKEOFF, altoff_takeoff);
+ if (altoff_changed) {
buffer.UnsafeFormat("%d,%d,%d", altoff_error, altoff_qnh, altoff_takeoff);
device.SendLXNAVVarioSetting("ALTOFF", buffer, env);
changed = true;
}🤖 Prompt for AI Agents
In src/Dialogs/Device/LX/LXNAVVarioConfigWidget.cpp around lines 145-151 the use
of the || operator causes short-circuiting so SaveValueInteger may not be called
for all fields; change the logic to call SaveValueInteger(ALTOFF_ERROR,
altoff_error), SaveValueInteger(ALTOFF_QNH, altoff_qnh) and
SaveValueInteger(ALTOFF_TAKEOFF, altoff_takeoff) unconditionally (assign each
result to a bool), then if any of those bools is true, format the buffer with
the now-updated altoff_error/altoff_qnh/altoff_takeoff values and call
device.SendLXNAVVarioSetting("ALTOFF", buffer, env) and set changed = true.
Your PR should:
For coding, style guide, architecture information please see our development guide:
https://xcsoar.readthedocs.io/en/latest/index.html
Summary by CodeRabbit
Release Notes
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.