|
1318 | 1318 | function toHeadingDegrees(point: Point, position: "start" | "end"): number { |
1319 | 1319 | if (!point) return 0; |
1320 | 1320 | if (point.heading === "linear") { |
1321 | | - return position === "start" ? point.startDeg ?? 0 : point.endDeg ?? 0; |
| 1321 | + return position === "start" ? (point.startDeg ?? 0) : (point.endDeg ?? 0); |
1322 | 1322 | } |
1323 | 1323 | if (point.heading === "constant") { |
1324 | 1324 | return point.degrees ?? 0; |
|
1330 | 1330 | const line = lines[lineIndex]; |
1331 | 1331 | if (!line) throw new Error("Line not found"); |
1332 | 1332 |
|
1333 | | - const startPt = lineIndex === 0 ? startPoint : lines[lineIndex - 1]?.endPoint; |
| 1333 | + const startPt = |
| 1334 | + lineIndex === 0 ? startPoint : lines[lineIndex - 1]?.endPoint; |
1334 | 1335 | if (!startPt) throw new Error("Missing start point for optimization"); |
1335 | 1336 |
|
1336 | | - const waypoints = [startPt, ...line.controlPoints, line.endPoint].map((p) => [p.x, p.y]); |
| 1337 | + const waypoints = [startPt, ...line.controlPoints, line.endPoint].map( |
| 1338 | + (p) => [p.x, p.y], |
| 1339 | + ); |
1337 | 1340 |
|
1338 | 1341 | return { |
1339 | 1342 | waypoints, |
|
1353 | 1356 | : line.endPoint.heading === "constant" |
1354 | 1357 | ? "constant" |
1355 | 1358 | : "linear", |
| 1359 | + obstacles: shapes.map((shape) => shape.vertices.map((v) => [v.x, v.y])), |
1356 | 1360 | }; |
1357 | 1361 | } |
1358 | 1362 |
|
1359 | 1363 | function sleep(ms: number) { |
1360 | 1364 | return new Promise((res) => setTimeout(res, ms)); |
1361 | 1365 | } |
1362 | 1366 |
|
1363 | | - async function createOptimizationTask(payload: any) { |
1364 | | - const response = await fetch(`${OPTIMIZER_BASE_URL}/optimize`, { |
| 1367 | + async function runOptimization(payload: any) { |
| 1368 | + const response = await fetch(`${OPTIMIZER_BASE_URL}`, { |
1365 | 1369 | method: "POST", |
1366 | 1370 | headers: { "Content-Type": "application/json" }, |
1367 | 1371 | body: JSON.stringify(payload), |
1368 | 1372 | }); |
1369 | 1373 |
|
1370 | | - if (response.status === 503) { |
1371 | | - const errorData = await response.json().catch(() => ({})); |
1372 | | - if ((errorData as any).error === "offline") { |
1373 | | - throw new Error(`OFFLINE: ${(errorData as any).message || "Service unavailable"}`); |
1374 | | - } |
1375 | | - } |
1376 | | -
|
1377 | 1374 | if (!response.ok) { |
1378 | 1375 | const errorText = await response.text().catch(() => ""); |
1379 | | - throw new Error(`Optimizer request failed (${response.status}): ${errorText || response.statusText}`); |
| 1376 | + throw new Error( |
| 1377 | + `Optimizer request failed (${response.status}): ${errorText || response.statusText}`, |
| 1378 | + ); |
1380 | 1379 | } |
1381 | 1380 |
|
1382 | 1381 | const data = await response.json(); |
1383 | | - if (!data?.job_id) throw new Error("Optimizer did not return a job id"); |
1384 | | - return data.job_id as string; |
1385 | | - } |
1386 | | -
|
1387 | | - async function pollOptimizationResult(jobId: string, pollInterval = 1000, maxTries = 60) { |
1388 | | - for (let i = 0; i < maxTries; i++) { |
1389 | | - const response = await fetch(`${OPTIMIZER_BASE_URL}/job/${jobId}`); |
1390 | | -
|
1391 | | - if (response.status === 503) { |
1392 | | - const errorData = await response.json().catch(() => ({})); |
1393 | | - if ((errorData as any).error === "offline") { |
1394 | | - throw new Error(`OFFLINE: ${(errorData as any).message || "Service unavailable"}`); |
1395 | | - } |
1396 | | - } |
1397 | | -
|
1398 | | - if (!response.ok) { |
1399 | | - const errorText = await response.text().catch(() => ""); |
1400 | | - throw new Error(`Optimizer status failed (${response.status}): ${errorText || response.statusText}`); |
1401 | | - } |
1402 | | -
|
1403 | | - const data = await response.json(); |
1404 | | - if (data?.status === "completed" && data.result) { |
1405 | | - return data.result; |
1406 | | - } |
1407 | | - if (data?.status === "error") { |
1408 | | - throw new Error("Optimization failed with server error."); |
1409 | | - } |
1410 | | -
|
1411 | | - await sleep(pollInterval); |
| 1382 | + if (data?.status === "completed" && data.result) { |
| 1383 | + return data.result; |
1412 | 1384 | } |
1413 | | -
|
1414 | | - throw new Error("Timed out waiting for optimization result."); |
1415 | | - } |
1416 | | -
|
1417 | | - async function runOptimization(payload: any, pollInterval = 1000, maxTries = 60) { |
1418 | | - const jobId = await createOptimizationTask(payload); |
1419 | | - return pollOptimizationResult(jobId, pollInterval, maxTries); |
| 1385 | + if (data?.status === "error") { |
| 1386 | + throw new Error( |
| 1387 | + `Optimization failed: ${data.message || "Unknown error"}`, |
| 1388 | + ); |
| 1389 | + } |
| 1390 | + throw new Error("Unexpected API response format"); |
1420 | 1391 | } |
1421 | 1392 |
|
1422 | | - async function optimizeLine(lineId: string, targetControlPointIndex?: number) { |
| 1393 | + async function optimizeLine( |
| 1394 | + lineId: string, |
| 1395 | + targetControlPointIndex?: number, |
| 1396 | + ) { |
1423 | 1397 | const lineIndex = lines.findIndex((l) => l.id === lineId); |
1424 | 1398 | if (lineIndex === -1) { |
1425 | 1399 | alert("Could not find line to optimize."); |
|
0 commit comments