Skip to content
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

Ros2 fix led bug #441

Merged
merged 2 commits into from
Nov 19, 2024
Merged

Ros2 fix led bug #441

merged 2 commits into from
Nov 19, 2024

Conversation

KmakD
Copy link
Contributor

@KmakD KmakD commented Nov 19, 2024

Description

Requirements

  • Code style guidelines followed
  • Documentation updated

Tests 🧪

  • Robot
  • Container

Summary by CodeRabbit

  • New Features

    • Added a parameter to the SetPinValue method for specifying a wait time before verifying pin state changes, enhancing reliability.
    • Updated the LEDControlEnable method to include a delay parameter for improved pin state transitions.
  • Bug Fixes

    • Improved validation mechanism for pin state changes after setting values, accommodating hardware limitations.

Copy link
Contributor

coderabbitai bot commented Nov 19, 2024

Walkthrough

The changes involve modifications to the SetPinValue method in the GPIODriver class and the LEDControlEnable method in the GPIOControllerPTH12X class. The SetPinValue method now includes an additional parameter for a validation wait time, allowing for a delay after setting a pin value. Similarly, the LEDControlEnable method has been updated to accept a delay parameter to accommodate slower pin state transitions. Documentation for both methods has been updated to reflect these changes.

Changes

File Change Summary
panther_hardware_interfaces/include/panther_hardware_interfaces/panther_system/gpio/gpio_driver.hpp Updated SetPinValue method signature to include pin_validation_wait_time. Documentation updated accordingly.
panther_hardware_interfaces/src/panther_system/gpio/gpio_controller.cpp Updated LEDControlEnable method signature to include a delay parameter.
panther_hardware_interfaces/src/panther_system/gpio/gpio_driver.cpp Updated SetPinValue method implementation to incorporate pin_validation_wait_time and utilize std::unique_lock.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GPIODriver
    participant GPIOControllerPTH12X

    User->>GPIODriver: SetPinValue(pin, value, pin_validation_wait_time)
    GPIODriver->>GPIODriver: Lock mutex
    GPIODriver->>GPIODriver: Set pin value
    alt pin_validation_wait_time > 0
        GPIODriver->>GPIODriver: Unlock mutex
        GPIODriver->>GPIODriver: Sleep for pin_validation_wait_time
        GPIODriver->>GPIODriver: Re-lock mutex
    end
    GPIODriver->>GPIODriver: Validate pin state
    GPIODriver-->>User: Return success/failure

    User->>GPIOControllerPTH12X: LEDControlEnable(enable, pin_validation_wait_time)
    GPIOControllerPTH12X->>GPIOControllerPTH12X: Set pin value with delay
    GPIOControllerPTH12X-->>User: Return success/failure
Loading

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@KmakD KmakD requested a review from BOOTCFG November 19, 2024 10:13
Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (3)
panther_hardware_interfaces/src/panther_system/gpio/gpio_driver.cpp (1)

Documentation needed for GPIO pin timing requirements

The verification reveals:

  1. No existing documentation about GPIO pin timing requirements in any of the hardware interface or LED-related documentation
  2. Tests exist but don't cover timing validation scenarios
  3. Found a hardcoded 10ms wait time in gpio_controller.cpp with a comment "used due to slow pin state transition"

Action items:

  • Add timing requirements to panther_hardware_interfaces/README.md explaining the minimum wait times needed for GPIO pins, especially for LEDs
  • Update test_gpio_driver.cpp to include test cases with different validation wait times
  • Consider extracting the hardcoded 10ms wait time into a named constant or configuration parameter
🔗 Analysis chain

Line range hint 167-188: Document hardware timing requirements

Since this change addresses a hardware-related timing issue:

  1. Please add documentation about the minimum required validation wait time for different hardware components (especially LEDs)
  2. Consider adding unit tests with different wait time scenarios
  3. Update the hardware interface documentation to reflect this new parameter

The PR objectives mention that testing on the robot and in a container is incomplete. This change particularly needs testing on actual hardware to verify the timing requirements.

Let's check for existing documentation and tests:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Look for related documentation
fd -e md -e rst . | xargs rg -l "GPIO|LED"

# Look for related tests
fd test -e cpp | xargs rg -l "SetPinValue"

Length of output: 1009


Script:

#!/bin/bash
# Check test file content for timing-related tests
cat panther_hardware_interfaces/test/panther_system/gpio/test_gpio_driver.cpp

# Check documentation for timing requirements
rg -A 5 -B 5 "timing|wait" panther_hardware_interfaces/CODE_STRUCTURE.md panther_hardware_interfaces/README.md panther_lights/README.md panther_lights/LIGHTS_API.md

# Look for any existing timing constants or parameters
rg "wait_time|delay|timing" panther_hardware_interfaces/src/panther_system/gpio/

Length of output: 9344

panther_hardware_interfaces/include/panther_hardware_interfaces/panther_system/gpio/gpio_driver.hpp (2)

192-193: Enhance documentation for pin validation wait time parameter

While the basic purpose is documented, consider adding more context about:

  • Why a validation wait time might be needed (e.g., hardware timing constraints)
  • What happens during the wait period (validation process)
  • Typical use cases or recommended values for different scenarios

This additional context would be particularly helpful for understanding timing-sensitive GPIO operations like LED control.


200-202: Consider pin-specific validation strategies

The current change applies a generic validation wait time to all GPIO operations. Consider a more flexible design:

  1. Define pin-specific validation strategies or timing constraints (especially for LEDs)
  2. Create a configuration structure for pin-specific timing requirements
  3. Consider moving LED-specific timing logic to a dedicated LED controller class

This would make the code more maintainable and allow for pin-specific optimizations.

Example approach:

struct GPIOPinConfig {
  std::chrono::milliseconds min_validation_wait_time{0};
  std::chrono::milliseconds max_validation_wait_time{1000};
  bool requires_validation{false};
};

class GPIODriver {
private:
  std::map<GPIOPin, GPIOPinConfig> pin_configs_;
  // ...
};
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 05324f5 and 6969a31.

📒 Files selected for processing (3)
  • panther_hardware_interfaces/include/panther_hardware_interfaces/panther_system/gpio/gpio_driver.hpp (1 hunks)
  • panther_hardware_interfaces/src/panther_system/gpio/gpio_controller.cpp (1 hunks)
  • panther_hardware_interfaces/src/panther_system/gpio/gpio_driver.cpp (2 hunks)
🔇 Additional comments (6)
panther_hardware_interfaces/src/panther_system/gpio/gpio_controller.cpp (3)

Line range hint 290-293: Verify if PTH10X needs similar delay handling.

The PTH10X version's LEDControlEnable implementation doesn't include the delay parameter. Please verify if:

  1. PTH10X uses different hardware that doesn't require the delay
  2. The same LED bug could affect PTH10X robots

Let's check for any hardware differences:

#!/bin/bash
# Search for hardware-specific documentation or constants
rg -g '*.{cpp,hpp,md}' -B 5 -A 5 'PTH10X|SBC Overlay|LED_SBC_SEL'

180-182: Consider defining the delay as a named constant.

The implementation correctly addresses the hardware limitation with the 100nF capacitor. However, the magic number 10 should be defined as a named constant to improve maintainability.

Consider this improvement:

+ // Time required for pin state transition due to 100nF capacity
+ static constexpr auto LED_PIN_TRANSITION_DELAY = std::chrono::milliseconds(10);
+
  bool GPIOControllerPTH12X::LEDControlEnable(const bool enable)
  {
    // pin_validation_wait_time=10ms used due to slow pin state transition
    // on pin loaded by high 100nF capacity in SBC Overlay v1.4
-   return gpio_driver_->SetPinValue(GPIOPin::LED_SBC_SEL, enable, std::chrono::milliseconds(10));
+   return gpio_driver_->SetPinValue(GPIOPin::LED_SBC_SEL, enable, LED_PIN_TRANSITION_DELAY);
  }

Let's verify if the 10ms delay is sufficient:

✅ Verification successful

Let me search for any timing-related constants or delays in the GPIO operations to verify if the 10ms delay is sufficient based on similar timing patterns in the codebase.


Based on the search results, I can now verify the 10ms delay for LED pin state transition. The codebase shows:

  1. The delay is used specifically for the LED_SBC_SEL pin due to the 100nF capacitor in SBC Overlay v1.4
  2. Similar GPIO operations in the codebase use delays ranging from 5ms to 100ms:
    • GPIO debounce period is configurable
    • GPIO monitor thread uses 10ms polling interval
    • E-stop operations use 100ms wait times
    • Watchdog toggles every 10ms

The 10ms delay appears to be sufficient and consistent with other GPIO timing patterns in the codebase. The suggestion to define it as a constant is still valid for maintainability.

Consider defining the 10ms LED pin transition delay as a named constant

The delay value is appropriate for the hardware limitation (100nF capacitor), but should be defined as a constant to improve code maintainability.

Example:

static constexpr auto LED_PIN_TRANSITION_DELAY = std::chrono::milliseconds(10);
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any timing-related constants or delays in GPIO operations
rg -g '*.{cpp,hpp}' -A 2 -B 2 'std::chrono::milliseconds|usleep|sleep_for' .

Length of output: 117799


Script:

#!/bin/bash
# Search for timing-related constants or delays in GPIO operations
rg -g '*.{cpp,hpp}' -B 2 -A 2 'std::chrono::milliseconds|delay|sleep|wait' panther_hardware_interfaces/

Length of output: 61130


180-182: Hardware testing is critical for this timing-sensitive fix.

The PR checklist indicates that both robot and container testing are incomplete. Given that this fix:

  1. Addresses hardware-specific timing issues
  2. Involves different robot versions (PTH12X vs PTH10X)
  3. Depends on capacitor behavior

Please ensure thorough testing on actual hardware before merging.

Consider testing with this script:

panther_hardware_interfaces/src/panther_system/gpio/gpio_driver.cpp (2)

167-168: LGTM: Method signature change is well-designed

The addition of pin_validation_wait_time parameter is a good solution for hardware-related timing issues. Using std::chrono::milliseconds is the correct choice for duration parameters, and passing by const reference is appropriate for this type.


178-188: Verify the thread safety implications of lock release

The change from lock_guard to unique_lock with temporary lock release during sleep is a significant threading behavior change. While the implementation looks correct, we should verify:

  1. No other threads modify the GPIO state during the unlocked period
  2. The validation check after re-acquiring the lock is sufficient

Let's analyze the thread safety:

Additionally, consider adding a comment explaining why the lock needs to be released during the sleep, as this is a non-obvious implementation detail that affects thread safety.

Add a comment explaining the lock release:

    if (pin_validation_wait_time.count() > 0) {
+     // Release lock during sleep to prevent blocking other GPIO operations
      lock.unlock();
      std::this_thread::sleep_for(pin_validation_wait_time);
      lock.lock();
    }
✅ Verification successful

Let me gather more information about the GPIO driver implementation to better understand the thread safety implications.


After analyzing the implementation, I can now provide a final response about the thread safety implications.

The lock release during sleep is safe and well-implemented

The temporary lock release during sleep is thread-safe because:

  1. The gpio_info_storage_mutex_ protects all GPIO state modifications, as evidenced by its consistent usage in:

    • SetPinValue() - uses unique_lock for state changes
    • HandleEdgeEvent() - uses lock_guard for event handling
    • ChangePinDirection() - uses lock_guard for direction changes
  2. The implementation correctly validates the pin state after re-acquiring the lock by checking:

    if (line_request_->get_value(gpio_info.offset) != gpio_value) {
      throw std::runtime_error("Failed to change GPIO state.");
    }
  3. The GPIO state is only modified through the line_request_ interface, which is properly synchronized with the mutex.

The lock release during sleep is actually beneficial as it prevents unnecessarily blocking other GPIO operations during the validation wait time.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other methods that might modify GPIO state
rg -A 5 "gpio_info_storage_mutex_" --type cpp

# Look for other GPIO state modifications
ast-grep --pattern 'line_request_->set_value($$$)'

Length of output: 1009


Script:

#!/bin/bash
# Check the full GPIO driver implementation
cat panther_hardware_interfaces/src/panther_system/gpio/gpio_driver.cpp

# Check the test file for any threading scenarios
cat panther_hardware_interfaces/test/panther_system/gpio/test_gpio_driver.cpp

Length of output: 15107

panther_hardware_interfaces/include/panther_hardware_interfaces/panther_system/gpio/gpio_driver.hpp (1)

200-202: Verify timing constraints and usage

The signature change looks well-designed with type-safe duration and backward compatibility. However, given this is fixing an LED bug:

  1. Consider if a 0ms default wait time is appropriate for all GPIO operations
  2. Consider adding runtime validation for minimum required wait time for specific pins (especially LEDs)

Let's verify the usage of this method across the codebase:

✅ Verification successful

Based on the search results, I can now provide a final response:

Default wait time of 0ms is safe for most GPIO operations

The codebase search reveals:

  • Most SetPinValue calls don't use the wait time parameter, which is appropriate as they don't require timing constraints
  • The LED-specific operation in gpio_controller.cpp:182 explicitly uses a 10ms wait time: SetPinValue(GPIOPin::LED_SBC_SEL, enable, std::chrono::milliseconds(10))

The implementation correctly handles timing constraints where needed:

  • Regular GPIO operations work with the 0ms default
  • LED operations explicitly specify the required wait time
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of SetPinValue across the codebase
# Look for both old (2 params) and new (3 params) usage patterns

echo "Searching for SetPinValue calls:"
rg -p "SetPinValue\s*\([^)]*\)" --type cpp

echo -e "\nSearching for LED-related GPIO operations:"
rg -p "LED_SBC_SEL.*SetPinValue" --type cpp

Length of output: 1687

@BOOTCFG BOOTCFG merged commit 3dced4d into ros2-devel Nov 19, 2024
1 check passed
@BOOTCFG BOOTCFG deleted the ros2-fix-led-bug branch November 19, 2024 10:20
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.

3 participants