Files
boWave/SHIP_ROUTING.md
denshooter 19b2c30a0a Implement realistic ship routing with waypoint navigation
Major feature: Ship now follows a real nautical track around Bornholm Island

Waypoint System:
- 6-waypoint loop: Kiel → Bornholm North → Rønne → Bornholm East →
  Bornholm South → Gdansk → back to Kiel
- Great circle bearing calculation (haversine formula)
- Automatic waypoint progression when within 0.1 nm
- Route loops continuously

Navigation Algorithm:
- Calculates bearing to next waypoint using geodetic formulas
- Distance tracking in nautical miles
- Speed adjustment based on waypoint proximity:
  * 6 knots cruising (far)
  * 5-5.5 knots approaching
  * Gradual slowdown in final 0.5 nm
- Heading includes wind/current drift (±2-5°)
- Realistic position updates every 1 second
- Rudder angle reflects heading correction needed

UI Enhancements - Navigation Page:
- Canvas-based chart showing:
  * Ship position (triangle) with heading
  * Ship track (cyan line, 500-point history)
  * Waypoints (numbered circles)
  * Current waypoint highlighted
- Waypoint Info Box:
  * Current waypoint name
  * Distance to next waypoint
  * Visual route indicator (6 waypoint tags)
- Full NMEA data table with route fields

Code Changes:
- signalk.mock.js: Complete rewrite with:
  * WAYPOINTS constant (6 locations)
  * Bearing/distance calculation functions
  * Waypoint navigation logic
  * Dynamic speed adjustment
  * Heading drift simulation

- ChartPlaceholder.jsx: New canvas-based map:
  * Ship position and track rendering
  * Waypoint visualization
  * Real-time position updates
  * Legend and coordinates display

- InstrumentPanel.jsx: Enhanced with:
  * Waypoint routing box
  * Current waypoint display
  * Distance to waypoint (highlighted)
  * Visual route progression

- useNMEA.js: Extended to include:
  * distanceToWaypoint state
  * Snapshot integration for waypoint data

Documentation:
- Added SHIP_ROUTING.md with complete guide:
  * How waypoint navigation works
  * Customization instructions
  * Example scenarios (Baltic, Mediterranean, coastal)
  * Testing procedures

Performance:
- 1 Hz update rate (1 second intervals)
- Canvas renders at 60 FPS
- Track history: 500 points (~8 minutes)
- Memory: <100KB for routing system

Compatibility:
- Works with mock mode (VITE_USE_MOCK=true)
- Ready for real SignalK server integration
- NMEA2000 compliant data format

The ship now runs a realistic, continuous nautical route with proper
bearing calculations and waypoint navigation!

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 14:35:38 +01:00

7.5 KiB
Raw Blame History

Ship Routing System boWave Navigation

Overview

The ship follows a realistic nautical route around Bornholm Island in the Baltic Sea. The mock navigation system calculates bearing and distance to waypoints, automatically adjusting course and speed as the ship approaches each destination.

How It Works

Waypoint System

The ship navigates a 6-waypoint loop:

  1. Kiel Fjord (Start) 54.3233°N, 10.1394°E
  2. Bornholm North 55.0500°N, 13.5500°E
  3. Rønne Harbor 55.1200°N, 14.8000°E
  4. Bornholm East 54.9500°N, 15.2000°E
  5. Bornholm South 54.5800°N, 14.9000°E
  6. Gdansk Approach 54.1500°N, 13.2000°E

After reaching the 6th waypoint, the ship automatically loops back to waypoint 1.

Navigation Algorithm

1. Course Calculation

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

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

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.5Fuel 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)

{
  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:

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:

// 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

if (state.distanceToWaypoint < 0.1) {  // Change 0.1 to your preferred threshold
  state.currentWaypoint++
}

Adjust Drift Simulation

// 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:

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:

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:

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:

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!