# Frontend — Basics

**Location: src/ and src/routes/**

The frontend is a SvelteKit TypeScript application. It uses Svelte 5's runes-based reactivity (**$effect, $props, $state**<span>) throughout. All communication with the Rust backend goes through Tauri's </span>**invoke()**<span> function. Incoming rover data arrives as Tauri events listened to with </span>**listen().**

# routes/+layout.svelte — Navigation Bar

<span style="white-space: pre-wrap;">The layout wraps every page in the application. It renders the persistent navigation bar at the top and then the current page's content via </span>`<span class="editor-theme-code">{@render children()}</span>`.

### Navigation bar

The navbar contains the following controls, always visible regardless of which route is active:

**Task dropdown**<span style="white-space: pre-wrap;"> — lists the four task routes (Science, Navigation, Maintenance, Probing). Selecting one navigates to that route and updates the displayed task name.</span>

**Drive Control Mode dropdown**<span style="white-space: pre-wrap;"> — toggles between Manual and Automatic drive. Calls </span>`<span class="editor-theme-code">set_state</span>`<span style="white-space: pre-wrap;"> with </span>`<span class="editor-theme-code">DriveManual</span>`<span style="white-space: pre-wrap;"> to sync the mode to the backend.</span>

**Arm Control Mode dropdown**<span style="white-space: pre-wrap;"> — toggles between Manual and Automatic arm control. Calls </span>`<span class="editor-theme-code">set_state</span>`<span style="white-space: pre-wrap;"> with </span>`<span class="editor-theme-code">ArmManual</span>`<span style="white-space: pre-wrap;"> to sync the mode to the backend.</span>

**Start / Pause / Resume Task button**<span style="white-space: pre-wrap;"> — controls a task timer. Displays the elapsed time next to the label. The button label cycles through </span>`<span class="editor-theme-code">▶︎ Start Task</span>`<span style="white-space: pre-wrap;"> → </span>`<span class="editor-theme-code">❚❚ Pause <task></span>`<span style="white-space: pre-wrap;"> → </span>`<span class="editor-theme-code">▶︎ Resume <task></span>`<span style="white-space: pre-wrap;"> depending on state.</span>

**Mode icon**<span style="white-space: pre-wrap;"> — a centred icon that shows either a driving icon or an arm icon depending on the current </span>`<span class="editor-theme-code">pickup_mode</span>`<span style="white-space: pre-wrap;"> state. Polled from the backend every 250ms.</span>

**END TASK button**<span style="white-space: pre-wrap;"> — stops the timer and saves a task result file. Prompts the operator for confirmation before ending. The saved JSON file includes the task name, completion time, finish timestamp, and all attached samples. The filename is auto-generated as </span>`<span class="editor-theme-code">{NNNN}_{task_name}.json</span>`<span style="white-space: pre-wrap;"> where </span>`<span class="editor-theme-code">NNNN</span>`<span style="white-space: pre-wrap;"> is an incrementing zero-padded number.</span>

**Settings / Home icons**<span style="white-space: pre-wrap;"> — navigation shortcuts in the top right.</span>

### Task file naming

<span style="white-space: pre-wrap;">When a task ends, the layout reads the existing task files and finds the highest existing prefix number for that task type, then increments it. This ensures task files are always uniquely numbered in order (e.g. </span>`<span class="editor-theme-code">0000_science.json</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">0001_science.json</span>`).

### Camera health

`<span class="editor-theme-code">initCameraHealthListener()</span>`<span style="white-space: pre-wrap;"> from </span>`<span class="editor-theme-code">state.svelte.js</span>`<span style="white-space: pre-wrap;"> is called directly in the layout's </span>`<span class="editor-theme-code"><script></span>`<span style="white-space: pre-wrap;"> (outside </span>`<span class="editor-theme-code">onMount</span>`) so it is initialised as early as possible.

# routes/  — Pages

### / — Dashboard (Home)

**File:* `<em class="editor-theme-code editor-theme-italic">routes/+page.svelte</em>`*

The main operator screen. A CSS grid layout combining six components into a single view.

<span style="white-space: pre-wrap;">Components: </span>`<span class="editor-theme-code">Double_Video</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Map</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">NavigationPlan</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">TaskCompletion</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">IMU</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Model</span>`<span style="white-space: pre-wrap;"> (3D scene).</span>

---

### /navigation — Navigation

**File:* `<em class="editor-theme-code editor-theme-italic">routes/navigation/+page.svelte</em>`*

The navigation task screen. Focuses on map-based rover guidance.

Layout: a 2×2 grid with the map top-left, navigation plan and IMU bottom-left, double video feed top-right, and costmap bottom-right.

<span style="white-space: pre-wrap;">Components: </span>`<span class="editor-theme-code">Map</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">NavigationPlan</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">IMU</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">DoubleVideo</span>`<span style="white-space: pre-wrap;"> (depth + front cameras), </span>`<span class="editor-theme-code">Costmap</span>`.

---

### /maintenance — Maintenance

**File:* `<em class="editor-theme-code editor-theme-italic">routes/maintenance/+page.svelte</em>`*

The maintenance task screen. Focuses on the rover arm and diagnostics.

Layout: left side has two video feeds (arm camera and depth camera) each with a side panel for arm feedback and arm position data. Right side shows the maintenance task list.

<span style="white-space: pre-wrap;">Components: </span>`<span class="editor-theme-code">Video</span>`<span style="white-space: pre-wrap;"> (arm camera), </span>`<span class="editor-theme-code">Video</span>`<span style="white-space: pre-wrap;"> (depth camera), </span>`<span class="editor-theme-code">MaintenanceTasks</span>`.

---

### /probing — Probing

**File:* `<em class="editor-theme-code editor-theme-italic">routes/probing/+page.svelte</em>`*

The probing task screen. Used when the rover is searching for and picking up probes.

Layout: map top-left, interest locations and probes list top-right, double video bottom-left, pickup mode toggle and IMU bottom-right.

<span style="white-space: pre-wrap;">The page reads and syncs </span>`<span class="editor-theme-code">pickup_mode</span>`<span style="white-space: pre-wrap;"> from the backend on mount, and toggles it via the Drive/Pick-up Mode button, which also switches camera 1 between the depth camera and arm camera.</span>

<span style="white-space: pre-wrap;">Components: </span>`<span class="editor-theme-code">Map</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">InterestLocations</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">Probes</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">DoubleVideo</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">IMU</span>`.

---

### /science — Science

**File:* `<em class="editor-theme-code editor-theme-italic">routes/science/+page.svelte</em>`*

The science task screen. Used when the rover is collecting and analysing rock or soil samples.

<span style="white-space: pre-wrap;">Layout: left side has a map and double video feed with small side panels for locations of interest and the pickup mode toggle. Right side is fully occupied by the </span>`<span class="editor-theme-code">SamplingLocations</span>`<span style="white-space: pre-wrap;"> component.</span>

<span style="white-space: pre-wrap;">Like the probing route, it syncs </span>`<span class="editor-theme-code">pickup_mode</span>`<span style="white-space: pre-wrap;"> on mount and switches camera 1 between depth and arm camera accordingly.</span>

<span style="white-space: pre-wrap;">Components: </span>`<span class="editor-theme-code">Map</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">DoubleVideo</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">SamplingLocations</span>`.

---

### /settings — Settings

**File:* `<em class="editor-theme-code editor-theme-italic">routes/settings/+page.svelte</em>`*

The settings page. Contains developer and diagnostic utilities, not used during rover operation.

**Diagnostic controls:**<span style="white-space: pre-wrap;"> Ping Rust, Clear Cache, Ping UDP, Ping GPS, Ping pH — these call the corresponding backend commands and are used to verify the Tauri bridge and UDP connection are working.</span>

**Dummy stream controls:**<span style="white-space: pre-wrap;"> Start/Stop dummy IMU stream, Start/Stop full dummy stream — start or stop the backend simulator for development without hardware.</span>

**File management:**<span style="white-space: pre-wrap;"> List, view, and delete files from the </span>`<span class="editor-theme-code">tasks/</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">images/</span>`<span style="white-space: pre-wrap;">, and </span>`<span class="editor-theme-code">maps/</span>`<span style="white-space: pre-wrap;"> storage directories. Files can be clicked to view their contents inline.</span>

**Snapshot:**<span style="white-space: pre-wrap;"> Saves a single JPEG frame from port 5000 as a test image.</span>

**Model debug:**<span style="white-space: pre-wrap;"> Calls </span>`<span class="editor-theme-code">debug_resource_dir</span>`<span style="white-space: pre-wrap;"> and prints the result to the console — useful for verifying model bundling in a production build.</span>

**IP check:**<span style="white-space: pre-wrap;"> Fetches the operator laptop's public IP from </span>`<span class="editor-theme-code">api.ipify.org</span>`<span style="white-space: pre-wrap;"> and displays it. Useful for network configuration when connecting to the rover.</span>

# types.ts — Types

Shared TypeScript types used across the frontend.

**`<strong class="editor-theme-bold editor-theme-code">Sample</strong>`**<span style="white-space: pre-wrap;"> — represents a single science sample collected by the rover. Contains location name, coordinates, before/after image paths, measurement, weight, and a set of boolean </span>`<span class="editor-theme-code">_check</span>`<span style="white-space: pre-wrap;"> flags tracking which fields have been filled in. The </span>`<span class="editor-theme-code">all_check</span>`<span style="white-space: pre-wrap;"> flag is true when all required fields are complete.</span>

**`<strong class="editor-theme-bold editor-theme-code">Waypoint</strong>`**<span style="white-space: pre-wrap;"> — a map waypoint with an </span>`<span class="editor-theme-code">id</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">lat</span>`<span style="white-space: pre-wrap;">, and </span>`<span class="editor-theme-code">lng</span>`. Used for start point, end point, and the waypoints list in the map store.

**`<strong class="editor-theme-bold editor-theme-code">Probe</strong>`**<span style="white-space: pre-wrap;"> — a probe location with an </span>`<span class="editor-theme-code">id</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">lat</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">lng</span>`<span style="white-space: pre-wrap;">, and </span>`<span class="editor-theme-code">timestamp</span>`. Used in the probing task to record where soil probes were taken.

# state.svelte.js — Global State

`<span class="editor-theme-code">state.svelte.js</span>`<span style="white-space: pre-wrap;"> is the single source of truth for shared reactive state that needs to be accessible across multiple components and routes. Currently it manages the three camera objects.</span>

### Camera objects

<span style="white-space: pre-wrap;">Three camera state objects are exported as Svelte 5 </span>`<span class="editor-theme-code">$state</span>`<span style="white-space: pre-wrap;"> runes:</span>

<table id="bkmrk-exportportcameradept"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr><th>**Export**

</th><th>**Port**

</th><th>**Camera**

</th></tr><tr><td>`<span class="editor-theme-code">depthCamera</span>`

</td><td>5000

</td><td>Depth / front-facing camera

</td></tr><tr><td>`<span class="editor-theme-code">frontCamera</span>`

</td><td>5001

</td><td>Secondary front camera

</td></tr><tr><td>`<span class="editor-theme-code">armCamera</span>`

</td><td>5002

</td><td>Arm-mounted camera

</td></tr></tbody></table>

<span style="white-space: pre-wrap;">Each object has three fields: </span>`<span class="editor-theme-code">name</span>`<span style="white-space: pre-wrap;"> (display string), </span>`<span class="editor-theme-code">port</span>`<span style="white-space: pre-wrap;"> (full </span>`<span class="editor-theme-code">http://localhost:PORT</span>`<span style="white-space: pre-wrap;"> URL used as the </span>`<span class="editor-theme-code"><img></span>`<span style="white-space: pre-wrap;"> src), and </span>`<span class="editor-theme-code">stale</span>`<span style="white-space: pre-wrap;"> (boolean set to </span>`<span class="editor-theme-code">true</span>`<span style="white-space: pre-wrap;"> when the backend reports no frames for 2+ seconds).</span>

### Camera health listener — initCameraHealthListener()

<span style="white-space: pre-wrap;">This function is called once from </span>`<span class="editor-theme-code">+layout.svelte</span>`<span style="white-space: pre-wrap;"> on app startup. It listens for the </span>`<span class="editor-theme-code">camera-feed-status</span>`<span style="white-space: pre-wrap;"> Tauri event emitted by the GStreamer health watcher in the backend, and updates the </span>`<span class="editor-theme-code">stale</span>`<span style="white-space: pre-wrap;"> flag on the matching camera object. A 500ms startup delay is included to ensure the Tauri bridge is ready before the listener is attached.</span>

<span style="white-space: pre-wrap;">Components that display video can read the </span>`<span class="editor-theme-code">stale</span>`<span style="white-space: pre-wrap;"> flag to show a warning overlay when a feed is lost.</span>