This guide is for a user or integrator who understands REST principles. It describes the purpose of RTK-EASY WAYPOINT SERVER, its main REST endpoints, its data formats, and how it connects RTK AUTOPILOT, the WAYPOINT SERVER itself, and an external Java route planning service.
The server runs on an ESP32 and uses HTTP port 80.
User Guide
RTK-EASY WAYPOINT SERVER does not do the heavy route computation itself. Its main jobs are:
Flow: RTK AUTOPILOT → POST /api/waypoints (measured line/area) → WAYPOINT SERVER → (web UI sends a planning request) → JAVA ROUTE PLANNER → POST /api/plan returns the computed trajectory → WAYPOINT SERVER → GET /api/waypoints → RTK AUTOPILOT.
Once the server has joined Wi-Fi successfully, its IP address is shown on the OLED display. Open in a browser:
http://SERVER_IP/
For example: http://192.168.1.50/
If the server cannot join the configured Wi-Fi network, it starts its own Access Point:
SSID: RTK-EASY-SERVER Password: 12345678
After joining this network, the server's IP address is shown on the OLED display.
Returns the server's main status.
{ "ok": true, "mode": "STA", "ip": "192.168.1.50", "hasData": true,
"payloadBytes": 4521, "receivedAtMs": 185430, "activePlot": "P1" }
| Field | Meaning |
|---|---|
mode | STA — connected to a Wi-Fi network; AP — running as an Access Point |
ip | The server's current IP address |
hasData | true — the server holds received geometry |
payloadBytes | Size of the stored source data, in bytes |
receivedAtMs | Time since the ESP32 booted when the data was received |
activePlot | The currently active plot, P1–P6 |
Returns the server's network information.
{ "activePlot": "P1", "mapLat": 54.6874, "mapLng": 25.2798,
"wifiSsid": "MyWiFi", "wifiPassword": "********", "connected": true,
"mode": "STA", "ip": "192.168.1.50", "rssi": -61,
"signalQuality": "Very good" }
| Field | Meaning |
|---|---|
connected | Whether the server is connected to Wi-Fi |
mode | STA or AP |
ip | The server's IP address |
rssi | Wi-Fi signal level, in dBm |
signalQuality | Text rating of the Wi-Fi signal |
Content-Type: application/json
{ "wifiSsid": "MyWiFi", "wifiPassword": "MyPassword",
"passwordChanged": true }
{ "ok": true, "restarting": true }
After saving the settings, the ESP32 restarts and tries to join the specified Wi-Fi network. If passwordChanged is false, the stored Wi-Fi password is left unchanged.
Returns the address of the external Java route planning service.
{ "plannerUrl": "http://192.168.1.100:8080" }
Content-Type: application/json
{ "plannerUrl": "http://192.168.1.100:8080" }
{ "ok": true }
Give the base address of the Java service. The web UI appends /api/plan itself, so enter http://192.168.1.100:8080 — not http://192.168.1.100:8080/api/plan.
The main endpoint RTK AUTOPILOT sends field-collected points, lines or areas to. Content-Type: application/json.
{
"deviceId": "AA:BB:CC:DD:EE:FF", "source": "rover",
"routes": [
{ "id": 0, "type": "area", "name": "Area 1",
"points": [
{ "lat": 54.898765, "lng": 23.912345, "alt": 82.3, "quality": "FIX" },
{ "lat": 54.898800, "lng": 23.912500, "alt": 82.4, "quality": "FIX" },
{ "lat": 54.898900, "lng": 23.912400, "alt": 82.2, "quality": "FIX" }
] }
]
}
type can be line or area.
The first area object is treated as the main area perimeter. Any other area objects are treated as obstacles once the main perimeter is set. An obstacle can also be marked explicitly with "role": "obstacle" or "role": "exclusion".
A line object is treated as an already-finished trajectory / waypoint sequence. Its points can be used directly as the rover's route.
{ "ok": true, "routes": 1, "points": 25 }
routes — number of objects received. points — total number of points received.
Returns the last geometry the server received, or generated from the active plot.
{ "source": "rover", "routes": [
{ "type": "area", "points": [ { "lat": 54.898765, "lng": 23.912345 } ] }
] }
Useful for the web map and other applications that want to display the original area or the rover's measured line.
The main endpoint RTK AUTOPILOT uses to fetch the finished driving route.
{ "routeId": "P1", "points": [
{ "lat": 54.898700, "lng": 23.912300 },
{ "lat": 54.898750, "lng": 23.912450 },
{ "lat": 54.898810, "lng": 23.912600 }
] }
points — waypoints in order, for the robot to drive. If there is no route: { "routeId": "server-route", "points": [] }
Deletes the source geometry and the generated rover route.
{ "ok": true }
{ "plotId": "P1", "hasRoute": true }
plotId — the active plot. hasRoute — whether the active plot has a route ready for the rover.
The server can store six separate plots: P1 P2 P3 P4 P5 P6. Each plot can hold:
{ "plotId": "P1", "plotName": "Garden", "wpSpacing": 1.5, "wpAngle": 96,
"missionPolygon": [ { "lat": 54.8987, "lng": 23.9123 } ],
"polyObstacles": [], "waypoints": [ { "lat": 54.8987, "lng": 23.9123 } ] }
If the plot does not exist: HTTP 404, { "ok": false, "error": "PLOT_NOT_FOUND" }
Content-Type: application/json
{ "plotId": "P1", "plotName": "Garden", "wpSpacing": 1.5, "wpAngle": 90,
"missionPolygon": [
{ "lat": 54.8987, "lng": 23.9123 },
{ "lat": 54.8988, "lng": 23.9125 },
{ "lat": 54.8989, "lng": 23.9122 }
],
"polyObstacles": [],
"waypoints": [
{ "lat": 54.8987, "lng": 23.9123 },
{ "lat": 54.89875, "lng": 23.9124 }
] }
{ "ok": true, "plotSaved": true, "size": 1520, "perimeter": 3,
"obstacles": 0, "waypoints": 2 }
The saved plot becomes the active plot. Its waypoints also become the route RTK AUTOPILOT can fetch via GET /api/waypoints.
{ "ok": true }
If the active plot is deleted, the active source geometry and generated rover route are removed as well.
The web UI does not plan the route inside the ESP32. It calls the configured Java Route Planner:
POST http://JAVA_SERVER:8080/api/plan Content-Type: application/json
Request format
{ "perimeter": [
{ "x": 23.9123, "y": 54.8987 },
{ "x": 23.9125, "y": 54.8988 },
{ "x": 23.9122, "y": 54.8989 }
],
"obstacles": [], "spacing": 1.5, "cutWidth": 1.5, "angleDeg": 90,
"algorithm": "boustrophedon" }
Important for API coordinates: x = longitude, y = latitude. E.g. longitude 23.9123, latitude 54.8987 is sent as { "x": 23.9123, "y": 54.8987 }.
The Java planning service must return the route as segments.
{ "route": [
{ "a": { "x": 23.912300, "y": 54.898700 },
"b": { "x": 23.912400, "y": 54.898750 }, "type": "coverage" },
{ "a": { "x": 23.912400, "y": 54.898750 },
"b": { "x": 23.912500, "y": 54.898800 }, "type": "connector" }
], "cellCount": 1 }
Possible segment types: coverage, perimeter-pass, obstacle-pass, connector, connector-local, return-home.
The web UI turns these segments into one continuous waypoint sequence. When the plot is saved, that sequence is written into waypoints — so RTK AUTOPILOT never needs to understand the planner's segment types; it is given a plain, sequential waypoint list.
POST /api/waypoints.http://SERVER_IP/ in a browser.POST JAVA_SERVER/api/plan.GET /api/waypoints.The area does not have to come from RTK AUTOPILOT — it can be drawn directly on the web map.
http://SERVER_IP/GET /api/waypoints.If RTK AUTOPILOT sends { "routes": [ { "type": "line", "points": [ ... ] } ] }, that line is treated as an already-finished waypoint route — the Java Planner is not needed. WAYPOINT SERVER can serve this waypoint sequence to RTK AUTOPILOT via GET /api/waypoints.
| Limit | Value |
|---|---|
| Maximum size of one JSON payload | 96,000 bytes |
| Maximum points in one waypoint array | 1,024 |
| Maximum total points when receiving source routes | 4,096 |
If a route becomes too large for the ESP32's memory, increase the planning line spacing so fewer waypoints are generated.
| Error | Meaning |
|---|---|
BODY_REQUIRED | No request body was provided |
INVALID_JSON | Malformed JSON |
ROOT_MUST_BE_OBJECT | The JSON root must be an object |
ROUTES_ARRAY_REQUIRED | Missing "routes" array |
ROUTE_POINTS_ARRAY_REQUIRED | Route object is missing a "points" array |
PAYLOAD_TOO_LARGE | JSON too large |
TOO_MANY_SOURCE_POINTS | Too many source waypoints |
INVALID_PLOT_ID | Invalid plot ID — only P1–P6 are allowed |
PLOT_NOT_FOUND | The selected plot has not been saved yet |
FILESYSTEM_SAVE_FAILED | Could not write data to the ESP32 filesystem |
INVALID_WIFI_SETTINGS | Invalid Wi-Fi settings |
SAVE_FAILED | Could not save the settings |
NOT_FOUND | No such API endpoint |
| Endpoint | Purpose |
|---|---|
GET /api/status | Server status |
GET /api/config | Wi-Fi and server network information |
POST /api/config | Change Wi-Fi settings |
GET /api/planner-config | Get the Java Planner address |
POST /api/planner-config | Set the Java Planner address |
POST /api/waypoints | Receive an area/line from RTK AUTOPILOT or another system |
GET /api/waypoints | Get the active final waypoint route for the rover |
GET /api/source-routes | Get the original source geometry |
DELETE /api/waypoints | Delete the active source geometry and final route |
GET /api/active-plot | Get active P1–P6 plot information |
GET /api/rover/_/plot/P1 | Get plot P1 |
POST /api/rover/_/plot/P1 | Save plot P1 and make it active |
DELETE /api/rover/_/plot/P1 | Delete plot P1 |
P2–P6 are used the same way as P1.
RTK AUTOPILOT → WAYPOINT SERVER: POST /api/waypoints
WAYPOINT SERVER → RTK AUTOPILOT: GET /api/waypoints
WAYPOINT SERVER Web UI → JAVA ROUTE PLANNER: POST /api/plan
The system has three clearly separated parts: