Files
sim-link/README.md
2026-03-05 20:47:28 +00:00

97 lines
6.3 KiB
Markdown

# Sim-Link
Sim-Link is a web application designed to take the results of Gazebo simulations, save them, rank the best-performing simulations, and display the detailed results in a clean, easy-to-understand format.
## Tech Stack
- **Frontend:** SvelteKit (built into a completely Static Single Page Application using Bun).
- **Backend:** Golang.
- **Database:** SQLite3.
- **Containerization:** Docker & Docker Compose.
## Running with Docker (Recommended)
The easiest way to run Sim-Link is by using the provided `docker-compose` environment. This encapsulates the build steps for both the SvelteKit frontend and the Go backend.
```bash
# Build and start the container in the background
docker compose up -d --build
```
*Note: The `results/` folder and `server/` folder are native volume mounts in Docker Compose. This ensures your simulation logs update live, and the `sim-link.db` SQLite file persists on your host machine.*
You can then access the interface at: [http://localhost:8080](http://localhost:8080)
## Running Locally Manually
If you prefer to run the system directly on your OS without Docker, you will need `Bun` and `Go` (with CGO enabled) installed.
### 1. Build the Frontend
Navigate to the root directory and use `npm` to install dependencies and build the static HTML/JS payload.
```bash
npm install
npm run build
```
*(This produces a `build/` directory that the Go backend expects).*
### 2. Run the Backend Server
Because the backend uses `go-sqlite3`, it requires CGO to compile. Navigate completely into the `server` directory so the relative paths for serving the `../build` and `../results` folders remain accurate.
```bash
cd server
go run .
```
The server will automatically scan the `../results` folder on startup, index the simulations into the SQLite database, and host the web interface at [http://localhost:8080](http://localhost:8080).
## API Endpoints
The Go backend provides a simple REST API to interact with the simulations:
### `GET /api/simulations`
Returns a JSON array of all indexed simulations, including their ID, name, created date, and configuration string.
### `POST /api/simulations/create`
Creates a new simulation entry.
- **Request Body:** JSON object containing the combined configurations (e.g., `search`, `uav`, `ugv`). The configuration *must* contain at least one search pattern definition (either `spiral`, `lawnmower`, `levy`, or `sar`) inside the JSON.
- **Behavior:** Checks if an identical config exists. If so, it returns the existing simulation ID/Name for overwriting. If not, it allocates a new `simulation_X` incrementally, inserts it into the database, builds the file directory in `../results`, and returns the new ID/Name. Returns `400 Bad Request` if payload is not valid JSON or lacks a known search pattern.
- **Response:** JSON object `{"id": <int>, "name": <string>}`
### `GET /api/simulations/:id`
Provides detailed JSON metadata for a specific simulation ID, including its name, JSON config string, creation timestamp, and a dynamically fetched array of all the internal resources (images, logs, videos) located within its folder.
### `PUT /api/simulations/:id/time`
Updates the numeric benchmarking metrics (`search_time` and `total_time`) for a specific simulation run.
- **Request Body:** JSON object containing floats: `{"search_time": 25.4, "total_time": 105.8}`
- **Response:** JSON object `{"status": "success"}`
### `PUT /api/simulations/:id/hardware`
Updates the physical hardware strings tied directly to a specific simulation run to properly map system configurations to benchmark outcomes.
- **Request Body:** JSON object containing string fields (nullable): `{"cpu_info": "Intel i9", "gpu_info": "RTX 4090", "ram_info": "64GB DDR5"}`
- **Response:** JSON object `{"status": "success"}`
### `PUT /api/simulations/:id/rename`
Renames a specific simulation. Automatically updates the database and physically renames the matching directory path on the system filesystem to mirror structural links.
- **Request Body:** JSON object containing the new underlying name: `{"name": "new_simulation_name"}`
- **Response:** JSON object `{"status": "success", "new_name": "new_simulation_name"}`
### `POST /api/simulations/:id/upload`
Uploads a new media or data resource file directly into a completed simulation run. Supports both images (e.g., PNGs) and heavy video files (e.g., AVIs) out of the box with an initial multi-part memory bounds mapping of 32 MB (spilling to disk for larger files).
- **Request Data:** `multipart/form-data` packet using the `file` keyword carrying the binary data blocks.
- **Behavior:** The Go service validates the simulation ID exists, dynamically builds the memory pool, opens a stream writer caching the binary blob into the `../results/simulation_X/filename.ext` directory path, and records the resource in the primary SQLite instance.
- **Response:** JSON object `{"status": "success", "filename": "example.png"}`
### `DELETE /api/simulations/:id`
Permanently deletes a complete simulation from the platform.
- **Behavior:** Deletes the record from the SQLite database along with any bound resource hooks. It subsequently initiates a full removal of the linked `../results/:name` directory natively off the OS to completely recover physical disk space.
- **Response:** JSON object `{"status": "success"}`
### `DELETE /api/simulations/:id/resources/:filename`
Deletes a specific user-uploaded media asset or log file dynamically out of a simulation without dropping the core simulation entity itself.
- **Behavior:** Detaches the file association string from SQLite and forces an OS-level file drop directly onto the specific asset file stored within the simulation's results directory.
- **Response:** JSON object `{"status": "success"}`
### `DELETE /api/simulations/clear-fails`
Purges all failed tracking simulations globally from the database and physically drops their filesystem result nodes off the host system. A simulation is identified natively as "failed" when its `total_time` tracking variable maps to a `0.0` or numeric `null` value during extraction.
- **Response:** JSON object `{"status": "success", "cleared": <int>}`
### `GET /api/stats`
Retrieves globally aggregated system statistics across the entire database resolving UI constraints.
- **Response:** JSON object `{"total_simulations": <int>, "fastest_sim_id": <int>, "total_storage_bytes": <int>}`