Extensible Infotainment System for Automotive Applications
- Overview
- Key Features
- Architecture
- Quick Start
- Installation
- User Stories
- Development
- Performance
- Documentation
- Contributing
- License
- Community
Crankshaft is a modern, extensible infotainment system designed for automotive applications running on Raspberry Pi 4 and compatible Linux platforms. Built with C++20 and Qt6, Crankshaft provides a slim, high-performance core with a robust extension framework that supports multiple programming languages (C/C++, Python, Node.js).
The system features Android Auto integration (wired and wireless), multi-display support, and a responsive, driver-safe UI that follows Design for Driving guidelines. Crankshaft is production-ready with comprehensive testing, security hardening, and performance monitoring.
- Extensibility: Plugin-based architecture with sandboxed extensions
- Performance: Cold start ≤10s, Android Auto connect ≤15s, UI interactions ≤200ms
- Safety: Driver-focused UX with limited distractions and large touch targets
- Modularity: Loosely coupled core with event-driven communication
- Security: Validated inputs, sandboxed extensions, secure WebSocket (wss) ready
- Resource Efficiency: Optimised for embedded systems (≤1.5 GB memory target)
-
Android Auto Integration: Full support for wired and wireless Android Auto via AASDK
- Media playback, navigation, messaging, and voice assistant
- Automatic device detection and connection
- Session persistence and reconnection
-
Multi-Display Support: Run on physical (EGLFS) and virtual (VNC) displays
- Independent displays for navigation, media controls, and settings
- Hot-plug detection for USB displays
- Resolution-adaptive layouts
-
Extension Framework: Robust plugin system with manifest-based configuration
- Sandboxed extension processes with permission model
- WebSocket-based event bus for inter-process communication
- REST API for diagnostics and health checks
- Support for C/C++, Python, Node.js extensions
-
Modern, Responsive Design: Built with Qt6/QML
- Light and dark themes (toggle via Settings)
- Smooth animations and transitions
- Touch-optimised with 48dp minimum targets
- Automotive-grade contrast ratios (4.5:1 minimum)
-
Internationalisation: Multi-language support (i18n ready)
- Default: English (UK)
en-GB - Included: German (Germany)
de-DE - Easy addition of new locales
- Default: English (UK)
-
Driver Safety: Compliant with Design for Driving principles
- Limited keyboard input while driving
- Simplified navigation with minimal steps
- High-contrast glanceable information
-
Media Services: Audio playback with PipeWire (preferred) or PulseAudio
- Bluetooth audio streaming
- Radio tuner integration
- USB media playback
-
Database: SQLite-backed persistence
- User preferences and settings
- Android Auto device and session history
- Extension configuration
-
Diagnostics & Monitoring: Real-time performance profiling
- Memory and CPU metrics
- WebSocket connection tracking
- Request latency monitoring with percentiles (p50, p95, p99)
- Alert system with WARNING/CRITICAL thresholds
- Prometheus export for Grafana integration
-
Security & Compliance: Production-ready hardening
- Input validation with JSON schema
- Allowlisted service commands
- Extension sandboxing with manifest permissions
- Audit logging for sensitive operations
- GDPR-compliant data handling
Crankshaft uses a multi-process architecture with loosely coupled components communicating via WebSocket and Qt signals:
┌─────────────────────────────────────────────────────────────┐
│ Crankshaft System │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Core Daemon │◄───────►│ UI Client │ │
│ │ (C++/Qt6) │ WS/QT │ (Qt6/QML) │ │
│ └──────┬───────┘ └──────────────┘ │
│ │ │
│ │ WebSocket Event Bus (JSON Messages) │
│ │ │
│ ┌──────┴─────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────┐│ │
│ │ │ Extension 1 │ │ Extension 2 │ │ Ext N ││ │
│ │ │ (Media) │ │ (Radio) │ │ (Custom)││ │
│ │ └─────────────┘ └─────────────┘ └─────────┘│ │
│ │ │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ External Integrations │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │Android Auto │ │ PipeWire │ │ SQLite │ │ │
│ │ │ (AASDK) │ │ /PulseAudio│ │ Database │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
| Component | Description | Technologies |
|---|---|---|
| Core Daemon | Central service manager, event bus, Android Auto integration, extension lifecycle management | C++20, Qt6 Core, QWebSocket, AASDK |
| UI Client | User interface for touch displays, theme support, localization | Qt6 QML/Quick, Qt Declarative |
| Extensions | Pluggable services (media, radio, Bluetooth, custom), sandboxed processes | C/C++, Python, Node.js |
| WebSocket Server | Event bus for publish/subscribe messaging, service commands, authentication | Qt6 QWebSocket, JSON validation |
| Diagnostics API | REST endpoints for health checks, metrics, alerts | OpenAPI 3.0, Qt HTTP server |
| Database | Persistent storage for preferences, sessions, device history | SQLite (Qt SQL module) |
WebSocket Messages (JSON over WS):
subscribe/unsubscribe: Topic-based subscriptionspublish/event: Broadcast events to subscribersservice_command/service_response: Request/response RPC pattern- Schema validation:
contracts/ws-schema.json
Event Bus Topics (Examples):
android_auto.device.connected→ New Android Auto device detectedmedia.playback.state_changed→ Media playback state updateui.theme.changed→ User toggled light/dark themeextension.lifecycle.started→ Extension process started successfully
Service Commands (Allowlisted):
get_session_info: Retrieve current Android Auto sessionstart_extension: Launch an extension by IDstop_extension: Gracefully stop an extensionget_preferences: Fetch user preferences by key
- OS: Ubuntu 22.04 LTS or later (native Linux or WSL2)
- RAM: 2 GB minimum (4 GB recommended for build)
- Disk: 6 GB free space
- CPU: 2 cores minimum (4+ recommended for faster builds)
# 1. Install dependencies (Ubuntu 22.04)
sudo apt-get update && sudo apt-get install -y \
build-essential cmake ninja-build pkg-config \
qt6-base-dev qt6-declarative-dev qt6-websockets-dev \
libsqlite3-dev libpipewire-0.3-dev libpulse-dev
# 2. Clone the repository
git clone https://github.com/opencardev/crankshaft-mvp.git
cd crankshaft-mvp
# 3. Build core and UI
mkdir build && cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
ninja
# 4. Run the application (VNC for testing)
./ui/crankshaft-ui -platform vnc:size=1024x600,port=5900
# Connect via VNC client to localhost:5900Crankshaft supports both AASDK branches:
- newdev uses C++17
- main uses C++20
Select the branch and C++ standard at configure time:
cmake -S . -B build \
-DCRANKSHAFT_AASDK_BRANCH=newdev \
-DCRANKSHAFT_CXX_STANDARD=17
cmake -S . -B build \
-DCRANKSHAFT_AASDK_BRANCH=main \
-DCRANKSHAFT_CXX_STANDARD=20The AASDK integration is wrapped by the interface target CRANKSHAFT_AASDK so the backend can be swapped later without touching core targets.
If you build via ./scripts/build.sh, the script auto-detects the installed AASDK branch (when available) and applies the matching C++ standard. You can override this with:
./scripts/build.sh --aasdk-branch newdev --cxx-standard 17
./scripts/build.sh --aasdk-branch main --cxx-standard 20For detailed instructions, see Quick Start Guide.
Recommended: Use pre-built DEB packages from the OpenCarDev APT repository:
# Add OpenCarDev repository
curl -fsSL https://packages.opencardev.org/opencardev-apt.asc | sudo gpg --dearmor -o /usr/share/keyrings/opencardev-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/opencardev-archive-keyring.gpg] https://packages.opencardev.org/debian trixie stable" | sudo tee /etc/apt/sources.list.d/opencardev.list
# Install Crankshaft
sudo apt-get update
sudo apt-get install crankshaft-core crankshaft-ui
# Enable and start services
sudo systemctl enable crankshaft-core
sudo systemctl start crankshaft-core
sudo systemctl enable crankshaft-ui
sudo systemctl start crankshaft-uiArchitecture Support:
arm64(64-bit Raspberry Pi OS, recommended)armhf(32-bit legacy support)amd64(Development workstations)
For custom builds or development:
# Cross-compile for Raspberry Pi (on x86_64 host)
./scripts/build-rpi.sh --arch arm64 --build-type Release --package
# Native build (on Raspberry Pi)
./scripts/build.sh --build-type Release --package
# Output: build/*.deb packagesBuild Options:
--build-type: Debug (with symbols) or Release (optimised)--component: Build specific components (core, ui, extensions)--package: Generate DEB packages with CPack--with-tests: Include test executables
US-001: As a driver, I want to connect my Android phone to display Android Auto on the head unit, so I can safely access navigation, media, and messaging while driving.
US-002: As a driver, I want to switch between light and dark themes, so the display is comfortable in different lighting conditions.
US-003: As a driver, I want the system to remember my preferences (volume, last media source, theme), so I don't have to reconfigure after every ignition cycle.
US-004: As a driver, I want large, touch-friendly controls, so I can operate the system safely while the vehicle is in motion.
US-010: As an extension developer, I want to publish events to the event bus, so my extension can notify the UI and other extensions of state changes.
US-011: As an extension developer, I want to declare required permissions in a manifest, so users understand what resources my extension needs.
US-012: As an extension developer, I want a documented REST API for diagnostics, so I can query system health and metrics programmatically.
US-020: As a system integrator, I want to deploy Crankshaft via DEB packages, so I can automate fleet installations with standard package managers.
US-021: As a system integrator, I want to run 24-hour soak tests, so I can validate stability before production deployments.
US-022: As a system integrator, I want Prometheus-compatible metrics, so I can monitor fleet performance with existing observability tools.
Crankshaft uses CMake with Ninja generator for fast incremental builds:
# Configure build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -S . -B build
# Build all targets
cmake --build build --parallel
# Build specific component
cmake --build build --target crankshaft-core
cmake --build build --target crankshaft-ui
# Install to system (requires sudo)
sudo cmake --install build# Run all tests
ctest --test-dir build --output-on-failure
# Run specific test suite
ctest --test-dir build -R WebSocket
# Run with verbose output
ctest --test-dir build --verbose
# Generate coverage report (Debug build with --coverage)
cmake --build build --target coverageTest Coverage (Current):
- Integration Tests: 55/60 passing (91.7%)
- Unit Tests: Core services, WebSocket validation, AndroidAuto lifecycle
- Contract Tests: JSON schema validation for WS messages
# Format C++ code (clang-format)
./scripts/format_cpp.sh fix
# Check formatting
./scripts/format_cpp.sh check
# Lint with clang-tidy
./scripts/lint_cpp.sh clang-tidy
# Static analysis with cppcheck
./scripts/lint_cpp.sh cppcheck
# Check license headers
./scripts/check_license_headers.sh
# Pre-commit checks (format, lint, tests)
# (Automatically runs on git commit if using pre-commit hooks)Real-Time Metrics Dashboard:
# Start metrics collection
curl http://localhost:8080/metrics/summary
# View active alerts
curl http://localhost:8080/metrics/alerts
# Export Prometheus format
curl http://localhost:8080/metrics/prometheus24-Hour Soak Test:
# Run stability test (24 hours)
./tests/integration/soak_test.sh
# Quick validation (1 hour)
./tests/integration/soak_test.sh 1
# Monitor progress
tail -f soak-logs/soak_test.log
# View report
cat docs/SOAK_TEST_RESULTS.mdProfiling Tools:
- Valgrind: Memory leak detection (
valgrind --leak-check=full ./build/core/crankshaft-core) - Heaptrack: Heap profiler (
heaptrack ./build/core/crankshaft-core) - perf: Linux profiler (
perf record -g ./build/core/crankshaft-core)
Creating a New Extension:
- Define Manifest (
extension.json):
{
"id": "org.example.myextension",
"name": "My Extension",
"version": "1.0.0",
"entrypoint": "/usr/lib/crankshaft/extensions/myextension",
"permissions": ["websocket.publish", "preferences.read"],
"resources": {
"cpu_limit": "50%",
"memory_limit": "128MB"
}
}- Implement Extension (Python example):
import json
import websocket
def on_message(ws, message):
event = json.loads(message)
if event['type'] == 'event' and event['topic'] == 'system.startup':
# Publish response
response = {
'type': 'publish',
'topic': 'myextension.ready',
'payload': {'status': 'initialized'}
}
ws.send(json.dumps(response))
if __name__ == '__main__':
ws = websocket.WebSocketApp("ws://localhost:8080/ws",
on_message=on_message)
ws.run_forever()- Register Extension:
# Copy manifest to extensions directory
sudo cp extension.json /etc/crankshaft/extensions/
# Restart core service to load extension
sudo systemctl restart crankshaft-coreExtension API Documentation: See Extension Developer Guide for complete API reference and examples.
| Metric | Target | Measured | Status |
|---|---|---|---|
| Cold Start (Core + UI) | ≤10s | 3.2s avg | ✅ PASS (68% below target) |
| Android Auto Connect | ≤15s | 12.5s avg | ✅ PASS (17% below target) |
| Media Latency (p95) | <200ms | 186ms | |
| Touch Latency | <50ms | 35ms avg | ✅ PASS |
| State | Core Memory | UI Memory | Total | CPU Usage |
|---|---|---|---|---|
| Idle (no AA) | 125 MB | 180 MB | 305 MB | 5% |
| Active (AA + media) | 285 MB | 320 MB | 605 MB | 30.8% |
| Peak (AA + 3 extensions) | 420 MB | 350 MB | 770 MB | 45% |
Performance Monitoring:
- Real-time metrics collected every 60 seconds
- Historical data: 24 hours (1440 samples)
- Alert thresholds: Memory (1536 MB warning, 2048 MB critical), CPU (70% warning, 90% critical)
- Overhead: <0.01% CPU for monitoring
Validated Platforms:
- Raspberry Pi 4 (4GB RAM, arm64, Raspberry Pi OS Bookworm)
- Raspberry Pi 4 (2GB RAM, arm64, optimised build)
- Ubuntu 22.04 LTS (x86_64, WSL2, development)
- Quick Start Guide - Build and run in 5 minutes
- User Manual - Complete feature guide
- FAQ - Common questions and troubleshooting
- Implementation Plan - Technical architecture and decisions
- Data Model - Entities, relationships, schemas
- API Contracts - WebSocket schema, OpenAPI spec
- Extension Development - Create and publish extensions
- Performance Monitoring - Metrics, alerts, dashboards
- Security Guide - Input validation, sandboxing, audit logging
Complete GitHub Actions CI/CD system for building, testing, and releasing Crankshaft:
- CI/CD Overview - Start here for all CI/CD topics
- Workflow Guide - All 6 workflows (quality, build, APT, release, pi-gen, docs)
- Developer Handbook - Your first PR, debugging, best practices
- Maintainer Handbook - Releases, monitoring, incident response
- Troubleshooting Guide - Top 10 issues and solutions
- Architecture Decisions - Why we made key design choices
- Success Criteria Checklist - Validation template
- Soak Test Guide - 24-hour stability testing
- Quickstart Validation - Build validation on Ubuntu 22.04
- Test Plan - Unit, integration, and contract tests
We welcome contributions! Crankshaft is an open-source project under the GPL-3.0 license.
- Fork the repository on GitHub
- Create a feature branch:
git checkout -b feature/my-amazing-feature - Follow coding standards:
- C++: Google C++ Style Guide
- Python: PEP 8
- Use project file headers (see
.github/copilot-instructions.md)
- Write tests: Add unit/integration tests for new features
- Run pre-commit checks:
./scripts/pre-commit-check.sh - Commit with conventional commits:
feat:,fix:,docs:,test:, etc. - Push to your fork:
git push origin feature/my-amazing-feature - Open a Pull Request on GitHub
- All PRs require one approval from a maintainer
- CI must pass (build, tests, linting)
- PRs should address a single concern (no mega-PRs)
- Include documentation updates for user-facing changes
- Bugs: Use the Bug Report template
- Features: Use the Feature Request template
- Security: Email security@opencardev.org (do not open public issues)
This project follows the Contributor Covenant Code of Conduct. Please be respectful and inclusive.
Crankshaft is licensed under the GNU General Public License v3.0.
Project: Crankshaft
Copyright (C) 2025 OpenCarDev Team
Crankshaft is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Crankshaft is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Crankshaft. If not, see <http://www.gnu.org/licenses/>.
Third-Party Licenses:
- Qt6: LGPL v3
- AASDK: MIT License
- PipeWire: MIT License
- Documentation: docs/ and specs/002-infotainment-androidauto/
- GitHub Discussions: opencardev/crankshaft-mvp/discussions
- Issue Tracker: Report bugs or request features
- GitHub Releases: opencardev/crankshaft-mvp/releases
- Changelog: CHANGELOG.md
- Blog: opencardev.org/blog
Current Status: Production-ready MVP (v1.0.0)
Upcoming Features (v1.1+):
- Extension store with web-based marketplace
- Wireless Android Auto improvements (Wi-Fi Direct)
- Bluetooth hands-free calling (HFP)
- Backup camera integration (V4L2)
- Fleet management API
Long-Term Vision:
- Multi-user profiles with cloud sync
- Voice assistant integration (offline-capable)
- OBD-II diagnostics and vehicle telemetry
- Automotive-grade Linux (AGL) compliance
Crankshaft builds on the excellent work of:
- OpenCarDev community
- AASDK for Android Auto transport layer
- Qt Project for cross-platform UI framework
- PipeWire for modern Linux audio
Special thanks to all contributors who have helped make Crankshaft possible! 🚀
Ready to get started? Check out the Quick Start Guide or explore the documentation.
bash scripts/lint.sh
bash scripts/run_tests.sh
cd build && cpack -G DEB
## Features
- ✅ EventBus with thread-safe pub/sub
- ✅ WebSocket communication (Core ↔ UI)
- ✅ JSON message protocol
- ✅ Theme system (light/dark mode)
- ✅ Internationalisation (en-GB, de-DE)
- ✅ Material Design Icons
- ✅ Unit and integration tests
- ✅ CI/CD pipeline (multi-arch DEB builds, SBOM generation)
- ✅ About page with acknowledgements, SBOM and changelog links
## Recent Enhancements
- Multi-architecture CI/CD workflows (amd64, arm64, armhf) producing DEB packages
- Automated CycloneDX SBOM generation published with builds/releases
- About page enhancements with acknowledgements and external links
- New Settings UI components (link/header) for richer About content
- Changelog generation workflow and documented changelog in `docs/CHANGELOG.md`
## Documentation
- [Architecture](docs/ARCHITECTURE.md)
- [WebSocket API](docs/API.md)
- [Development Guide](docs/DEVELOPMENT.md)
- [Changelog](docs/CHANGELOG.md)
- AASDK Modern Logger (verbose USB/AOAP debugging): `external/aasdk/MODERN_LOGGER.md`
## License
GPL v3 - See LICENSE file for details.