Skip to content

Dev#15

Closed
llLeo306 wants to merge 8 commits into
masterfrom
dev
Closed

Dev#15
llLeo306 wants to merge 8 commits into
masterfrom
dev

Conversation

@llLeo306

@llLeo306 llLeo306 commented Mar 29, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Refine the chassis power control module with Eigen-based RLS estimation, error‑aware power distribution, and updated CI to build and run the module against libxr in a Linux container.

New Features:

  • Expose chassis measured power, capacitor energy, and SuperPower online status through new PowerControl accessors.
  • Support error‑aware power distribution by accepting optional motor speed error inputs and tracking per‑motor speed error for power limiting decisions.

Enhancements:

  • Replace custom matrix utilities with Eigen in both PowerControl and the RLS estimator to modernize linear algebra handling.
  • Adjust power model parameter adaptation bounds and available power budgeting to improve stability of power limiting behavior.
  • Simplify current back‑calculation from target power with a revised quadratic solution strategy and clamped outputs.

Build:

  • Rework the GitHub Actions workflow to build the module on a generic Linux libxr toolchain, generate a minimal xrobot main, add required dependent modules, and compile a host executable instead of a STM32 firmware build.

@sourcery-ai

sourcery-ai Bot commented Mar 29, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors the PowerControl module to use Eigen-based RLS, adds error-aware power distribution and additional telemetry accessors, and replaces the STM32/bsp-dev-c-based CI flow with a libxr/Linux-based xrobot test harness while modernizing RLS implementation details.

Sequence diagram for omni power limiting with error-aware distribution

sequenceDiagram
  actor ChassisLoop
  participant PowerControl
  participant SuperPower
  participant Motors3508

  ChassisLoop->>PowerControl: SetMotorData3508(output_current, rotorspeed_rpm, speed_error)

  ChassisLoop->>PowerControl: CalculatePowerControlParam()
  PowerControl->>SuperPower: GetChassisPower()
  SuperPower-->>PowerControl: measured_power
  PowerControl->>SuperPower: IsOnline()
  SuperPower-->>PowerControl: online_flag
  PowerControl->>PowerControl: update samples_3508_ and mechanical_power
  PowerControl->>PowerControl: compute residual and update params_3508_

  ChassisLoop->>PowerControl: OutputLimit(max_power)
  alt is_helm_ is false
    PowerControl->>PowerControl: OutputLimitOmni(max_power)
    loop each 3508 motor
      PowerControl->>PowerControl: calculate_motor_model_power()
      PowerControl->>PowerControl: accumulate required_power_3508_sum, sum_error_
    end
    PowerControl->>PowerControl: compute error_confidence_
    alt required_power_3508_sum > available_power
      loop each 3508 motor
        PowerControl->>PowerControl: compute power_weight_error and power_weight_prop
        PowerControl->>PowerControl: mix weights using error_confidence_
        PowerControl->>PowerControl: solve_current_for_power()
        PowerControl-->>Motors3508: new_output_current_3508[i]
      end
    else power sufficient
      PowerControl-->>Motors3508: pass-through output_current_3508
    end
  else is_helm_ is true
    PowerControl->>PowerControl: OutputLimitHelm(max_power)
  end
Loading

Class diagram for updated PowerControl and RLS modules

classDiagram
  class LibXR_Application
  class LibXR_Mutex
  class LibXR_HardwareContainer
  class LibXR_ApplicationManager

  class SuperPower {
    +float GetChassisPower()
    +float GetCapEnergy()
    +bool IsOnline()
  }

  class PowerControlData {
    +float new_output_current_3508[6]
    +float new_output_current_6020[6]
    +bool is_power_limited
  }

  class RLS_dim {
    +RLS_dim(delta_: float, lambda_: float)
    +void Reset()
    +ParamVector Update(sample_vector: ParamVector, actual_output: float)
    +void SetParamVector(updated_params: ParamVector)
    -uint32_t dimension_
    -float lambda_
    -float delta_
    -Matrix_dim_dim transmatrix_
    -ParamVector gainvector_
    -ParamVector paramsvector_
    -ParamVector defaultparamsvector_
  }

  class PowerControl {
    +static int MAX_MOTOR_COUNT
    +PowerControl(hw: LibXR_HardwareContainer, app: LibXR_ApplicationManager, superpower: SuperPower, is_helm: bool, chassis_static_power_loss: float, motor_count_3508: int, motor_count_6020: int)
    +void SetMotorData3508(output_current: float*, rotorspeed_rpm: float*, speed_error: float*)
    +void SetMotorData6020(output_current: float*, rotorspeed_rpm: float*, speed_error: float*)
    +void CalculatePowerControlParam()
    +void OutputLimit(max_power: float)
    +PowerControlData GetPowerControlData()
    +float GetMeasuredPower()
    +float GetCapEnergy()
    +bool IsOnline()
    -void OutputLimitOmni(max_power: float)
    -void OutputLimitHelm(max_power: float)
    -LibXR_Mutex mutex_
    -SuperPower* superpower_
    -bool is_helm_
    -RLS_dim rls_
    -PowerControlData powercontrol_data_
    -float k3_chassis_
    -float error_confidence_
    -float sum_error_
    -float speed_error_3508_[6]
    -float speed_error_6020_[6]
    -int motor_count_3508_
    -int motor_count_6020_
    -float kt_3508_
    -float k1_3508_
    -float k2_3508_
    -Eigen_Matrix_2_1 samples_3508_
    -Eigen_Matrix_2_1 params_3508_
    -float output_current_3508_[6]
    -float rotorspeed_rpm_3508_[6]
    -float motor_power_3508_[6]
    -float kt_6020_
    -float k1_6020_
    -float k2_6020_
    -float output_current_6020_[6]
    -float rotorspeed_rpm_6020_[6]
    -float motor_power_6020_[6]
    -float measured_power_
  }

  PowerControl ..|> LibXR_Application
  PowerControl o-- SuperPower
  PowerControl o-- RLS_dim
  PowerControl o-- PowerControlData
  PowerControl ..> LibXR_Mutex
Loading

File-Level Changes

Change Details Files
Refine power limiting algorithm to incorporate speed tracking error, expose additional power telemetry, and migrate math structures to Eigen.
  • Replace custom Matrixf usage with Eigen::Matrix in PowerControl, including RLS parameter/sample storage
  • Extend motor data setters to accept optional speed error arrays and store per-motor absolute speed tracking errors
  • Modify OutputLimitOmni and OutputLimitHelm to subtract a fixed reserve power margin and distribute limited power using a blend of demand-based and error-based weights with configurable thresholds
  • Expose measured chassis power, capacitor energy and online status via new accessors on PowerControl
  • Adjust recursive parameter identification to update k1/k2 bounds with a relaxed minimum value and convert indexing to Eigen-style accessors
  • Change solve_current_for_power to simplified root selection logic and remove the previous direction-preserving, closest-to-zero selection scheme
PowerControl.hpp
Reimplement the RLS helper to use Eigen types instead of custom matrix utilities while keeping the external API conceptually similar.
  • Remove dependency on FreeRTOS- and matrix.h-based Matrixf and replace with Eigen::Matrix-based ParamVector and covariance/gain matrices
  • Change Update to take const Eigen param vectors and use Eigen indexing semantics
  • Keep Reset and SetParamVector semantics while storing default parameter vector as an Eigen vector
  • Retain basic constructor-time validation for lambda and delta while depending on configASSERT from the existing environment
RLS.hpp
Replace the STM32/bsp-dev-c GitHub Actions build with a Linux/libxr-based xrobot module test harness.
  • Switch CI container image from STM32-specific toolchain to a generic linux libxr image
  • Clone this module and its dependencies (Referee, CMD, SuperPower, libxr) into a flat Modules/ layout and generate a minimal main.cpp and CMakeLists.txt for building a simple xr_test binary
  • Use xrobot_setup/xrobot_init_mod/xrobot_add_mod to configure modules and generate xrobot_main.hpp in CI
  • Update build steps to standard CMake+make flow under a local build directory while preserving the tag-creation step for non-PR runs
.github/workflows/build.yml
Keep module documentation and CMake integration effectively unchanged, with only trivial whitespace/encoding adjustments.
  • Normalize or preserve README content and structure without semantic changes
  • Leave module CMakeLists behavior identical aside from formatting/whitespace changes
README.md
CMakeLists.txt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The new solve_current_for_power implementation no longer guards against a being near-zero or delta being negative and calls sqrtf(delta) unconditionally; this can lead to NaNs/division-by-zero and also never updates final_current in the delta < 1e-9f case (it just overwrites original_current and returns clamped 0), so consider restoring the previous robustness checks and making the small-delta branch explicitly set final_current.
  • In RLS::Validate you still call configASSERT but removed the FreeRTOS headers, and the condition lambda_ >= 0.0f || lambda_ <= 1.0f is always true; either include the appropriate header or replace configASSERT with a portable check, and fix the predicate to lambda_ >= 0.0f && lambda_ <= 1.0f so out-of-range lambda values are actually caught.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `solve_current_for_power` implementation no longer guards against `a` being near-zero or `delta` being negative and calls `sqrtf(delta)` unconditionally; this can lead to NaNs/division-by-zero and also never updates `final_current` in the `delta < 1e-9f` case (it just overwrites `original_current` and returns clamped 0), so consider restoring the previous robustness checks and making the small-`delta` branch explicitly set `final_current`.
- In `RLS::Validate` you still call `configASSERT` but removed the FreeRTOS headers, and the condition `lambda_ >= 0.0f || lambda_ <= 1.0f` is always true; either include the appropriate header or replace `configASSERT` with a portable check, and fix the predicate to `lambda_ >= 0.0f && lambda_ <= 1.0f` so out-of-range `lambda` values are actually caught.

## Individual Comments

### Comment 1
<location path=".github/workflows/build.yml" line_range="87-50" />
<code_context>
+        run: |
+          pip3 install xrobot libxr
+
+      - name: Run xrobot_setup
+        run: |
+          xrobot_setup || true
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `xrobot_setup || true` may hide real failures in the toolchain setup.

Because later steps rely on a valid XRobot setup, swallowing non-zero exit codes here can turn a clear setup failure into harder-to-debug downstream errors. If there are specific, expected failure modes, handle those explicitly; otherwise, let the step fail so setup issues surface immediately.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

set(XROBOT_MODULES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Modules/)
add_subdirectory(libxr)
target_include_directories(xr_test PUBLIC $<TARGET_PROPERTY:xr,INTERFACE_INCLUDE_DIRECTORIES> ${CMAKE_SOURCE_DIR}/User)
target_link_libraries(xr_test PUBLIC xr)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Using xrobot_setup || true may hide real failures in the toolchain setup.

Because later steps rely on a valid XRobot setup, swallowing non-zero exit codes here can turn a clear setup failure into harder-to-debug downstream errors. If there are specific, expected failure modes, handle those explicitly; otherwise, let the step fail so setup issues surface immediately.

@llLeo306 llLeo306 closed this Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants