286 lines
9.3 KiB
Markdown
286 lines
9.3 KiB
Markdown
# Ship Routing System – boWave Navigation
|
||
|
||
## Current Route: Lokale Rundfahrt in Lingen
|
||
|
||
Die Mock-Daten simulieren eine **lokale Rundfahrt in Lingen** über den **Dortmund-Ems-Kanal** und die **Ems**. Das Boot bleibt in der Region!
|
||
|
||
### Route Details
|
||
|
||
```
|
||
Start: EYC Segelclub Lingen (52.5236°N, 7.3200°E)
|
||
Ziel: EYC Segelclub Lingen (zurück zum Start)
|
||
Strecke: ~15 km Rundfahrt
|
||
Dauer: ~2-3 Stunden bei 6 Knoten
|
||
```
|
||
|
||
## Waypoints (14 Punkte - Lokale Schleife)
|
||
|
||
1. **EYC Segelclub Lingen** (52.5236°N, 7.3200°E) - Start
|
||
2. **Kanal Ausfahrt** (52.5280°N, 7.3150°E) - Hafen verlassen
|
||
3. **DEK Westlich** (52.5400°N, 7.3000°E) - Kanal westwärts
|
||
4. **DEK Schleife West** (52.5500°N, 7.2800°E) - Westschleife
|
||
5. **DEK Nord** (52.5600°N, 7.2700°E) - Nordwärts
|
||
6. **Brücke Nord** (52.5700°N, 7.2800°E) - Nordbrücke
|
||
7. **Ems Einfahrt** (52.5750°N, 7.3000°E) - In die Ems
|
||
8. **Ems Fluss Ost** (52.5800°N, 7.3200°E) - Ems ostwärts
|
||
9. **Ems Kurve** (52.5750°N, 7.3400°E) - Ems Kurve
|
||
10. **Ems Süd** (52.5650°N, 7.3500°E) - Ems südwärts
|
||
11. **Ems Rückkehr** (52.5500°N, 7.3450°E) - Rückweg
|
||
12. **Kanal Rückkehr** (52.5400°N, 7.3350°E) - Zurück zum Kanal
|
||
13. **Hafen Approach** (52.5300°N, 7.3250°E) - Hafen Annäherung
|
||
14. **EYC Segelclub (Ziel)** (52.5236°N, 7.3200°E) - Zurück am Start! ⚓
|
||
|
||
**→ Route loopt automatisch und beginnt von vorne!**
|
||
|
||
---
|
||
|
||
## Visualisierung der Route
|
||
|
||
```
|
||
Brücke Nord
|
||
|
|
||
DEK Nord
|
||
|
|
||
DEK Schleife ← DEK West
|
||
|
|
||
Kanal Ausfahrt
|
||
|
|
||
🏁 EYC ← Hafen Approach
|
||
↑
|
||
Kanal Rückkehr
|
||
↑
|
||
Ems Rückkehr
|
||
|
|
||
Ems Süd
|
||
|
|
||
Ems Ost → Ems Kurve
|
||
|
|
||
Ems Einfahrt
|
||
```
|
||
|
||
**Boot fährt eine schöne Schleife: DEK raus → Ems hoch → Ems runter → zurück zum EYC!**
|
||
|
||
---
|
||
|
||
## Automatischer Fallback
|
||
|
||
Das Dashboard nutzt **automatisch Mock-Daten**, wenn kein echtes SignalK läuft:
|
||
|
||
```javascript
|
||
// Nach 5 Sekunden ohne echte Daten → Mock aktiviert
|
||
setTimeout(() => {
|
||
console.log('⚠️ SignalK not connected - using mock data (EYC Lingen → Ems route)')
|
||
}, 5000)
|
||
```
|
||
|
||
### So erkennst du Mock-Daten:
|
||
- Browser Console zeigt: `⚠️ SignalK not connected - using mock data`
|
||
- Boot fährt automatisch die Route
|
||
- Updates alle 1 Sekunde
|
||
- Loop: Nach Norddeich zurück nach Lingen
|
||
|
||
---
|
||
|
||
#### 1. **Course Calculation**
|
||
```javascript
|
||
bearing = getBearing(currentLat, currentLon, targetLat, targetLon)
|
||
```
|
||
Uses the haversine formula to calculate the great circle bearing from current position to target waypoint.
|
||
|
||
#### 2. **Distance Calculation**
|
||
```javascript
|
||
distance = getDistance(currentLat, currentLon, targetLat, targetLon)
|
||
```
|
||
Returns distance in nautical miles to the next waypoint.
|
||
|
||
#### 3. **Speed Adjustment**
|
||
Based on proximity to waypoint:
|
||
- **Far from waypoint (>2 nm):** Cruise at 6±0.25 knots
|
||
- **Approaching waypoint (0.5-2 nm):** Gradual speed reduction to 5-5.5 knots
|
||
- **Near waypoint (<0.5 nm):** Speed reduces based on distance: `distance * 10` knots
|
||
- **At waypoint (<0.1 nm):** Waypoint complete, move to next
|
||
|
||
#### 4. **Heading & Drift**
|
||
- **Desired course:** Calculated bearing to waypoint
|
||
- **Actual heading:** `bearing + wind_drift` (simulates wind/current pushing the boat)
|
||
- **Drift amount:** Varies sinusoidally 2-5° to create realistic deviation
|
||
|
||
#### 5. **Position Update**
|
||
```javascript
|
||
dLat = (speed_m/s * cos(heading_rad) * interval_s) / 111320
|
||
dLon = (speed_m/s * sin(heading_rad) * interval_s) / (111320 * cos(lat_rad))
|
||
```
|
||
Updates latitude and longitude based on speed, heading, and time interval (1 second).
|
||
|
||
### Real-Time Display
|
||
|
||
#### Navigation Page - Chart
|
||
Shows:
|
||
- **Ship position** (triangle pointing in heading direction)
|
||
- **Ship track** (cyan line showing historical path)
|
||
- **Waypoints** (numbered circles)
|
||
- **Cyan** = Current waypoint
|
||
- **Yellow/Orange** = Upcoming waypoints
|
||
- **Distance to current waypoint** in bottom-left
|
||
- **Current position** in decimal degrees
|
||
|
||
#### Navigation Page - Instrument Panel
|
||
Shows:
|
||
- **Current Waypoint:** Name and number
|
||
- **Distance to Waypoint:** Nautical miles (3 decimal places)
|
||
- **Route indicator:** Visual representation of all 6 waypoints with current position highlighted
|
||
- **Full NMEA data:** COG, heading, speed, depth, wind, temperature, fuel, coordinates
|
||
|
||
#### Navigation Page - Data Table
|
||
Key fields for navigation:
|
||
- **COG** – Course over ground (calculated bearing to waypoint)
|
||
- **Heading** – Actual heading with wind drift applied
|
||
- **SOG** – Speed adjusting based on waypoint proximity
|
||
- **Lat/Lon** – Current position updating in real-time
|
||
- **Distance to WP** – Highlighted in blue for easy reference
|
||
|
||
### Realism Features
|
||
|
||
✓ **Great Circle Navigation** – Uses proper geodetic formulas, not flat-earth calculation
|
||
✓ **Automatic Waypoint Progression** – Ship automatically moves to next waypoint when within 0.1 nm
|
||
✓ **Speed Variation** – Not constant speed; slows approaching waypoints
|
||
✓ **Heading Lag** – Actual heading lags slightly behind desired course (wind/current)
|
||
✓ **Smooth Motion** – Position advances every 1 second with proper bearing/speed calculations
|
||
✓ **Rudder Feedback** – Rudder angle reflects heading error: `(heading - cog) * 0.5`
|
||
✓ **Fuel Consumption** – Fuel rate varies with RPM, fuel depletes based on consumption
|
||
✓ **Engine Hours** – Continuous tracking of engine runtime
|
||
✓ **Environmental Effects** – Wind, depth, water temperature vary realistically
|
||
|
||
## Technical Details
|
||
|
||
### API Integration
|
||
|
||
#### SignalK Mock (`src/mock/signalk.mock.js`)
|
||
- **getWaypoints()** – Returns array of all 6 waypoints
|
||
- **getSnapshot()** – Returns current state including:
|
||
- `currentWaypoint` – Current waypoint object
|
||
- `distanceToWaypoint` – Distance in nm to next waypoint
|
||
- `waypoints` – All waypoints array
|
||
|
||
#### Navigation Hook (`src/hooks/useNMEA.js`)
|
||
```javascript
|
||
{
|
||
lat, lon, // Current position
|
||
heading, cog, // Heading and course
|
||
sog, // Speed over ground
|
||
distanceToWaypoint, // Distance to waypoint (nm)
|
||
depth, windSpeed, // Environmental data
|
||
// ... 10+ other NMEA fields
|
||
}
|
||
```
|
||
|
||
#### Navigation Components
|
||
- **ChartPlaceholder.jsx** – Canvas-based chart showing track, waypoints, ship position
|
||
- **InstrumentPanel.jsx** – Data display and waypoint routing information
|
||
|
||
### Performance
|
||
|
||
- **Update frequency:** 1 Hz (1 second interval)
|
||
- **Track history:** Last 500 positions stored (8+ minutes of track)
|
||
- **Canvas redraw:** 60 FPS (browser requestAnimationFrame)
|
||
- **Memory footprint:** < 100KB for entire navigation system
|
||
|
||
## Customization
|
||
|
||
### Modify Waypoints
|
||
Edit `src/mock/signalk.mock.js`:
|
||
```javascript
|
||
const WAYPOINTS = [
|
||
{ lat: 54.3233, lon: 10.1394, name: 'Your Location 1' },
|
||
{ lat: 55.0500, lon: 13.5500, name: 'Your Location 2' },
|
||
// ... add more waypoints
|
||
]
|
||
```
|
||
|
||
### Adjust Route Speed
|
||
In `buildDelta()` function:
|
||
```javascript
|
||
// Cruising speed base (currently 6 knots)
|
||
state.sog = 7 + (Math.random() - 0.5) * 0.5 // Change 7 to your preferred speed
|
||
```
|
||
|
||
### Change Waypoint Arrival Threshold
|
||
```javascript
|
||
if (state.distanceToWaypoint < 0.1) { // Change 0.1 to your preferred threshold
|
||
state.currentWaypoint++
|
||
}
|
||
```
|
||
|
||
### Adjust Drift Simulation
|
||
```javascript
|
||
// Drift amount (currently ±2-5°)
|
||
const drift = Math.sin(Date.now() / 5000) * 3 // Change 3 to your preferred drift
|
||
```
|
||
|
||
## Example Scenarios
|
||
|
||
### Long Crossing
|
||
Create waypoints across the North Sea:
|
||
```javascript
|
||
const WAYPOINTS = [
|
||
{ lat: 52.0, lon: 4.0, name: 'Amsterdam' },
|
||
{ lat: 53.5, lon: 0.0, name: 'East Anglia' },
|
||
{ lat: 56.0, lon: -2.0, name: 'Edinburgh' },
|
||
]
|
||
```
|
||
|
||
### Mediterranean Cruise
|
||
Route around Greek islands:
|
||
```javascript
|
||
const WAYPOINTS = [
|
||
{ lat: 38.9, lon: 20.7, name: 'Corfu' },
|
||
{ lat: 38.0, lon: 24.5, name: 'Mykonos' },
|
||
{ lat: 37.5, lon: 25.5, name: 'Rhodes' },
|
||
]
|
||
```
|
||
|
||
### Coastal Tour
|
||
Local harbor hopping:
|
||
```javascript
|
||
const WAYPOINTS = [
|
||
{ lat: 40.7, lon: -74.0, name: 'New York' },
|
||
{ lat: 41.3, lon: -72.0, name: 'Connecticut' },
|
||
{ lat: 42.4, lon: -71.0, name: 'Boston' },
|
||
]
|
||
```
|
||
|
||
## Testing
|
||
|
||
Start dev environment:
|
||
```bash
|
||
make dev
|
||
```
|
||
|
||
Navigate to **Navigation** tab (Tab 2):
|
||
1. **Left side (Chart):** Watch ship move along track, approaching waypoints
|
||
2. **Right side (Instruments):**
|
||
- See current waypoint name
|
||
- Distance to waypoint decreases as ship approaches
|
||
- Waypoint indicator shows progress through route
|
||
- Heading/COG values update in real-time
|
||
|
||
Expected behavior:
|
||
- ✓ Ship follows smooth track toward waypoint
|
||
- ✓ Course/heading align with waypoint direction
|
||
- ✓ Distance reduces continuously
|
||
- ✓ Speed slows as waypoint approaches
|
||
- ✓ Waypoint updates automatically when reached
|
||
- ✓ Route loops after 6th waypoint
|
||
|
||
## NMEA2000 Compliance
|
||
|
||
The routing system integrates with realistic NMEA2000 data:
|
||
- **Position data** updates based on calculated bearing and speed
|
||
- **COG** automatically set to waypoint bearing
|
||
- **Heading** includes drift simulation
|
||
- **SOG** varies with waypoint proximity
|
||
- **Rudder** angle reflects course correction needed
|
||
|
||
The navigation is so realistic that your dashboard will work identically when connected to real SignalK server with actual NMEA2000 instruments! ⛵
|
||
|