Thank you for your interest in contributing to the W Prime Extension for Hammerhead Karoo 3! This document provides guidelines and instructions for contributors.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Testing
- Submitting Changes
- Coding Standards
- Adding New Algorithms
This project follows a code of conduct. By participating, you are expected to:
- Be respectful and inclusive
- Accept constructive criticism gracefully
- Focus on what is best for the community
- Show empathy towards other community members
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/WPrimeExtension.git cd WPrimeExtension - Add upstream remote:
git remote add upstream https://github.com/ORIGINAL_OWNER/WPrimeExtension.git
- Android Studio Hedgehog (2023.1.1) or later
- JDK 17+
- Hammerhead Karoo 3 device (for testing)
- ADB for device communication
The project uses the karoo-ext library from GitHub Packages. You need to configure authentication:
- Create a GitHub Personal Access Token with
read:packagesscope - Add to
~/.gradle/gradle.properties:gpr.user=YOUR_GITHUB_USERNAME gpr.key=YOUR_GITHUB_TOKEN
./gradlew clean build./gradlew installDebug
# Or manually:
adb install app/build/outputs/apk/debug/WPrimeExtension-v1.0-debug.apkmain- Production-ready codedevelop- Development branch- Feature branches:
feature/your-feature-name - Bug fixes:
bugfix/issue-description - Hotfixes:
hotfix/critical-fix
git checkout develop
git pull upstream develop
git checkout -b feature/your-feature-nameFollow conventional commit format:
type(scope): subject
body
footer
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringperf: Performance improvementstest: Adding or updating testschore: Maintenance tasks
Example:
feat(calculator): add Chorley 2023 bi-exponential model
Implement the bi-exponential recovery model from Chorley et al. 2023
with fast and slow recovery components.
Closes #42
Run unit tests before submitting:
./gradlew test- Install the APK on your Karoo 3
- Configure test parameters (CP, W', algorithm)
- Test with both indoor and outdoor rides
- Verify data appears in FIT files
- Extension appears in app drawer
- Configuration UI works correctly
- Settings persist after restart
- Data field displays during ride
- W Prime depletes correctly above CP
- W Prime recovers correctly below CP
- FIT file contains W Prime data
- Multiple algorithms tested
- No crashes or errors in logcat
-
Update from upstream:
git checkout develop git pull upstream develop git checkout your-feature-branch git rebase develop
-
Run tests:
./gradlew test ./gradlew lint -
Build successfully:
./gradlew build
-
Update documentation if needed
-
Push to your fork:
git push origin feature/your-feature-name
-
Open a Pull Request on GitHub:
- Target:
developbranch - Fill out the PR template completely
- Link related issues
- Add screenshots/videos if applicable
- Target:
-
Wait for review and address feedback
- Follow official Kotlin style guide
- Use
ktlintfor formatting - Prefer explicit types when it improves readability
- Use meaningful variable names
- MVVM pattern for UI components
- Dependency Injection with Hilt
- Repository pattern for data access
- Single responsibility principle
Example of proper Kotlin file structure:
// 1. Package declaration
package com.itl.wprimeext.extension
// 2. Imports (grouped and sorted)
import android.content.Context
import androidx.compose.runtime.Composable
import io.hammerhead.karooext.KarooSystemService
// 3. Constants
private const val TAG = "WPrimeCalculator"
private const val DEFAULT_CP = 250.0
// 4. Class/Interface definition
class WPrimeCalculator(
private val cp: Double,
private val wPrime: Double,
) {
private var wBal: Double = wPrime
fun update(power: Double): Double {
// Implementation
return wBal
}
}
-
Add KDoc for public APIs:
/** * Calculates W Prime balance using the specified algorithm. * * @param power Current power output in watts * @param dt Time delta in seconds * @return Updated W Prime balance in joules */ fun update(power: Double, dt: Double): Double { // Implementation return 0.0 } -
Comment complex algorithms with references:
// Skiba et al. 2014 differential model // τ = 2287 * D_CP^(-0.688) val tau = 2287 * dcp.pow(-0.688)
If you're adding a new W Prime algorithm:
- Provide scientific reference (paper, author, year)
- Explain the model's unique characteristics
- Document when it should be used
-
Create model class implementing
IWPrimeModel:class YourNewModel( cp: Double, wPrime: Double, // Additional parameters ) : BaseWPrimeModel(cp, wPrime) { override fun update(power: Double, dt: Double): Double { // Your implementation } }
-
Add to enum:
enum class WPrimeModelType { // ...existing YOUR_NEW_MODEL, }
-
Update factory:
object WPrimeFactory { fun create( type: WPrimeModelType, cp: Double, wPrime: Double, tauOverride: Double?, kIn: Double ): IWPrimeModel = when (type) { // ...existing models... WPrimeModelType.YOUR_NEW_MODEL -> YourNewModel(cp, wPrime, additionalParam) } }
-
Update UI in
ConfigurationScreen.kt -
Add documentation to
docs/wprime-algorithms.md -
Update README.md with the new algorithm
- Unit tests for the model
- Comparison with reference implementation (if available)
- Real-world ride data validation
- Edge case handling (negative power, zero CP, etc.)
We welcome contributions in these areas:
- Additional W Prime algorithms
- Visual gauge/graph for data field
- Low W Prime alerts during ride
- Post-ride W Prime analysis
- UI/UX improvements
- Localization/translations
- Performance optimizations
- Better documentation
- Integration with training platforms
- Automatic CP/W' estimation
- Multi-athlete profiles
- Advanced data export
- Issues: Open an issue for bugs or feature requests
- Discussions: Use GitHub Discussions for questions
- Community: Join r/Karoo on Reddit
- Forum: Hammerhead Extensions Developers forum
By contributing, you agree that your contributions will be licensed under the Apache License 2.0.
Thank you for contributing to the W Prime Extension!