Add production-ready features for MotorHandPro parameter sweeps #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: MotorHandPro Continuous Testing | ||
| on: | ||
| push: | ||
| branches: [ main, develop, 'claude/**' ] | ||
| pull_request: | ||
| branches: [ main, develop ] | ||
| schedule: | ||
| # Run daily at 2 AM UTC | ||
| - cron: '0 2 * * *' | ||
| workflow_dispatch: | ||
| inputs: | ||
| mode: | ||
| description: 'Test mode (quick or full)' | ||
| required: false | ||
| default: 'quick' | ||
| jobs: | ||
| motorhand-sweep: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.11' | ||
| - name: Install dependencies | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install numpy | ||
| - name: Run quick parameter sweep | ||
| if: github.event.inputs.mode != 'full' | ||
| run: | | ||
| python sweep_motorhand_drive.py --quick | ||
| env: | ||
| PYTHONPATH: ${{ github.workspace }} | ||
| - name: Run full parameter sweep | ||
| if: github.event.inputs.mode == 'full' | ||
| run: | | ||
| python sweep_motorhand_drive.py | ||
| env: | ||
| PYTHONPATH: ${{ github.workspace }} | ||
| - name: Export best configuration | ||
| if: success() | ||
| run: | | ||
| python sweep_motorhand_drive.py --export-best | ||
| - name: Upload results artifact | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: motorhand-results-${{ github.sha }} | ||
| path: | | ||
| ~/Multi-Heart-Model-Results/motorhand_* | ||
| motorhand_best_params.json | ||
| retention-days: 30 | ||
| - name: Upload best config | ||
| if: success() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: motorhand-best-config | ||
| path: motorhand_best_params.json | ||
| retention-days: 90 | ||
| - name: Create results summary | ||
| if: success() | ||
| run: | | ||
| echo "## MotorHandPro Parameter Sweep Results" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Mode:** ${{ github.event.inputs.mode || 'quick' }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "### Best Configuration" >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`json" >> $GITHUB_STEP_SUMMARY | ||
| cat motorhand_best_params.json >> $GITHUB_STEP_SUMMARY | ||
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | ||
| echo "" >> $GITHUB_STEP_SUMMARY | ||
| echo "✓ Results saved to artifacts" >> $GITHUB_STEP_SUMMARY | ||
| - name: Comment PR with results | ||
| if: github.event_name == 'pull_request' && success() | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const fs = require('fs'); | ||
| const bestConfig = JSON.parse(fs.readFileSync('motorhand_best_params.json', 'utf8')); | ||
| const comment = `## MotorHandPro Parameter Sweep Results ✓ | ||
| **Mode:** ${{ github.event.inputs.mode || 'quick' }} | ||
| **Commit:** ${{ github.sha }} | ||
| ### Best Configuration | ||
| | Parameter | Value | | ||
| |-----------|-------| | ||
| | K_gain | ${bestConfig.firmware_config.K_gain.toFixed(3)} | | ||
| | lambda_decay | ${bestConfig.firmware_config.lambda_decay.toFixed(3)} | | ||
| | num_IPUs | ${bestConfig.firmware_config.num_integral_units} | | ||
| ### Performance | ||
| | Metric | Value | | ||
| |--------|-------| | ||
| | Comfort Index | ${bestConfig.performance_metrics.comfort_index.toFixed(1)}/100 | | ||
| | Settling Time | ${bestConfig.performance_metrics.settling_time_s.toFixed(2)}s | | ||
| | RMS Jerk | ${bestConfig.performance_metrics.rms_jerk.toFixed(3)} | | ||
| | Smoothness | ${bestConfig.performance_metrics.smoothness.toFixed(3)} | | ||
| **Tested Configurations:** ${bestConfig.metadata.total_configurations_tested} | ||
| **Stable Configurations:** ${bestConfig.metadata.stable_configurations} | ||
| 📦 Download full results from [Actions artifacts](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) | ||
| `; | ||
| github.rest.issues.createComment({ | ||
| issue_number: context.issue.number, | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| body: comment | ||
| }); | ||