@crazyhappyone/auto-graph 0.2.11 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.cjs +112 -8
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +112 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +112 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +112 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.cjs
CHANGED
|
@@ -4164,7 +4164,10 @@ function findObstacleFreePath(source, target, obstacles, options = {}, diagnosti
|
|
|
4164
4164
|
detail: {
|
|
4165
4165
|
xsCount: xs.length,
|
|
4166
4166
|
ysCount: ys.length,
|
|
4167
|
-
maxNodes
|
|
4167
|
+
maxNodes,
|
|
4168
|
+
obstacleCount: obstacles.length,
|
|
4169
|
+
stage: "corridor-filtered",
|
|
4170
|
+
...corridorMargin === void 0 ? {} : { corridorMargin }
|
|
4168
4171
|
}
|
|
4169
4172
|
});
|
|
4170
4173
|
return null;
|
|
@@ -4210,7 +4213,14 @@ function findObstacleFreePath(source, target, obstacles, options = {}, diagnosti
|
|
|
4210
4213
|
severity: "warning",
|
|
4211
4214
|
code: "routing.astar.grid_overflow",
|
|
4212
4215
|
message: `A* full-retry grid overflow: ${xsFull.length * ysFull.length} nodes > ${maxNodes} limit. Falling back to heuristic routing.`,
|
|
4213
|
-
detail: {
|
|
4216
|
+
detail: {
|
|
4217
|
+
xsCount: xsFull.length,
|
|
4218
|
+
ysCount: ysFull.length,
|
|
4219
|
+
maxNodes,
|
|
4220
|
+
obstacleCount: obstacles.length,
|
|
4221
|
+
stage: "full-retry",
|
|
4222
|
+
...corridorMargin === void 0 ? {} : { corridorMargin }
|
|
4223
|
+
}
|
|
4214
4224
|
});
|
|
4215
4225
|
return null;
|
|
4216
4226
|
}
|
|
@@ -4453,6 +4463,64 @@ function areCollinear(a, b, c) {
|
|
|
4453
4463
|
return a.x === b.x && b.x === c.x || a.y === b.y && b.y === c.y;
|
|
4454
4464
|
}
|
|
4455
4465
|
|
|
4466
|
+
// src/routing/budget.ts
|
|
4467
|
+
var MIN_CORNER_BUDGET = 600;
|
|
4468
|
+
var MAX_CORNER_BUDGET = 3e3;
|
|
4469
|
+
var MIN_NODE_BUDGET = 4e3;
|
|
4470
|
+
var MAX_NODE_BUDGET = 64e3;
|
|
4471
|
+
var CORNERS_PER_OBSTACLE = 12;
|
|
4472
|
+
var CORNER_HEADROOM = 2;
|
|
4473
|
+
var GRID_SAFETY_FACTOR = 3;
|
|
4474
|
+
var CORRIDOR_SCALING_K = 0.5;
|
|
4475
|
+
var CORRIDOR_SCALING_BASE = 200;
|
|
4476
|
+
function computeRoutingBudget(cornerObstacles, allObstacles, corridorMargin, overrides = {}) {
|
|
4477
|
+
const adaptiveMaxCorners = deriveMaxCorners(
|
|
4478
|
+
cornerObstacles.length,
|
|
4479
|
+
corridorMargin
|
|
4480
|
+
);
|
|
4481
|
+
const adaptiveMaxNodes = deriveMaxNodes(
|
|
4482
|
+
allObstacles.length,
|
|
4483
|
+
corridorMargin
|
|
4484
|
+
);
|
|
4485
|
+
return {
|
|
4486
|
+
maxCorners: resolveBudget(
|
|
4487
|
+
overrides.maxCorners,
|
|
4488
|
+
adaptiveMaxCorners,
|
|
4489
|
+
MIN_CORNER_BUDGET,
|
|
4490
|
+
MAX_CORNER_BUDGET
|
|
4491
|
+
),
|
|
4492
|
+
maxNodes: resolveBudget(
|
|
4493
|
+
overrides.maxNodes,
|
|
4494
|
+
adaptiveMaxNodes,
|
|
4495
|
+
MIN_NODE_BUDGET,
|
|
4496
|
+
MAX_NODE_BUDGET
|
|
4497
|
+
),
|
|
4498
|
+
cornerObstacleCount: cornerObstacles.length,
|
|
4499
|
+
gridObstacleCount: allObstacles.length,
|
|
4500
|
+
corridorMargin
|
|
4501
|
+
};
|
|
4502
|
+
}
|
|
4503
|
+
function deriveMaxCorners(obstacleCount, corridorMargin) {
|
|
4504
|
+
const base = 2 + obstacleCount * CORNERS_PER_OBSTACLE * CORNER_HEADROOM;
|
|
4505
|
+
const corridorFactor = corridorScalingFactor(corridorMargin);
|
|
4506
|
+
return Math.ceil(base * corridorFactor);
|
|
4507
|
+
}
|
|
4508
|
+
function deriveMaxNodes(obstacleCount, corridorMargin) {
|
|
4509
|
+
const base = 4 * obstacleCount * obstacleCount + 4 * obstacleCount + 100;
|
|
4510
|
+
const corridorFactor = corridorScalingFactor(corridorMargin);
|
|
4511
|
+
return Math.ceil(base * GRID_SAFETY_FACTOR * corridorFactor);
|
|
4512
|
+
}
|
|
4513
|
+
function corridorScalingFactor(corridorMargin) {
|
|
4514
|
+
return 1 + corridorMargin / CORRIDOR_SCALING_BASE * CORRIDOR_SCALING_K;
|
|
4515
|
+
}
|
|
4516
|
+
function resolveBudget(override, adaptive, min, max) {
|
|
4517
|
+
const chosen = override !== void 0 && Number.isFinite(override) && override >= 1 ? override : adaptive;
|
|
4518
|
+
return clamp(chosen, min, max);
|
|
4519
|
+
}
|
|
4520
|
+
function clamp(value, min, max) {
|
|
4521
|
+
return Math.max(min, Math.min(max, value));
|
|
4522
|
+
}
|
|
4523
|
+
|
|
4456
4524
|
// src/routing/visibility-router.ts
|
|
4457
4525
|
function findCornerGraphPath(source, target, obstacles, options = {}, diagnostics) {
|
|
4458
4526
|
const margin = options.margin ?? 0;
|
|
@@ -4466,7 +4534,12 @@ function findCornerGraphPath(source, target, obstacles, options = {}, diagnostic
|
|
|
4466
4534
|
severity: "warning",
|
|
4467
4535
|
code: "routing.visibility.corner_overflow",
|
|
4468
4536
|
message: `Corner graph overflow: ${vertices.length} vertices > ${maxCorners}. Falling back to grid A*.`,
|
|
4469
|
-
detail: {
|
|
4537
|
+
detail: {
|
|
4538
|
+
vertexCount: vertices.length,
|
|
4539
|
+
maxCorners,
|
|
4540
|
+
obstacleCount: obstacles.length,
|
|
4541
|
+
...options.corridorMargin === void 0 ? {} : { corridorMargin: options.corridorMargin }
|
|
4542
|
+
}
|
|
4470
4543
|
});
|
|
4471
4544
|
return null;
|
|
4472
4545
|
}
|
|
@@ -4851,11 +4924,22 @@ function routeEdge(input) {
|
|
|
4851
4924
|
corridorMargin
|
|
4852
4925
|
);
|
|
4853
4926
|
const cornerObstacles = corridorObstacles.length === 0 && allObstacles.length > 0 ? allObstacles : corridorObstacles;
|
|
4927
|
+
const budget = computeRoutingBudget(
|
|
4928
|
+
cornerObstacles,
|
|
4929
|
+
allObstacles,
|
|
4930
|
+
corridorMargin,
|
|
4931
|
+
{ maxCorners: input.maxCorners, maxNodes: input.maxNodes }
|
|
4932
|
+
);
|
|
4854
4933
|
let cornerPath = findCornerGraphPath(
|
|
4855
4934
|
source,
|
|
4856
4935
|
target,
|
|
4857
4936
|
cornerObstacles,
|
|
4858
|
-
{
|
|
4937
|
+
{
|
|
4938
|
+
endpointObstacles,
|
|
4939
|
+
margin: 2,
|
|
4940
|
+
maxCorners: budget.maxCorners,
|
|
4941
|
+
corridorMargin
|
|
4942
|
+
},
|
|
4859
4943
|
diagnostics
|
|
4860
4944
|
);
|
|
4861
4945
|
if (cornerPath === null && cornerObstacles.length < allObstacles.length) {
|
|
@@ -4863,7 +4947,12 @@ function routeEdge(input) {
|
|
|
4863
4947
|
source,
|
|
4864
4948
|
target,
|
|
4865
4949
|
allObstacles,
|
|
4866
|
-
{
|
|
4950
|
+
{
|
|
4951
|
+
endpointObstacles,
|
|
4952
|
+
margin: 2,
|
|
4953
|
+
maxCorners: budget.maxCorners,
|
|
4954
|
+
corridorMargin
|
|
4955
|
+
},
|
|
4867
4956
|
diagnostics
|
|
4868
4957
|
);
|
|
4869
4958
|
}
|
|
@@ -4871,7 +4960,12 @@ function routeEdge(input) {
|
|
|
4871
4960
|
source,
|
|
4872
4961
|
target,
|
|
4873
4962
|
allObstacles,
|
|
4874
|
-
{
|
|
4963
|
+
{
|
|
4964
|
+
endpointObstacles,
|
|
4965
|
+
margin: 0,
|
|
4966
|
+
corridorMargin,
|
|
4967
|
+
maxNodes: budget.maxNodes
|
|
4968
|
+
},
|
|
4875
4969
|
diagnostics
|
|
4876
4970
|
);
|
|
4877
4971
|
if (path !== null && path.length >= 2) {
|
|
@@ -4903,7 +4997,12 @@ function routeEdge(input) {
|
|
|
4903
4997
|
source,
|
|
4904
4998
|
target,
|
|
4905
4999
|
allObstacles,
|
|
4906
|
-
{
|
|
5000
|
+
{
|
|
5001
|
+
endpointObstacles,
|
|
5002
|
+
margin: 2,
|
|
5003
|
+
maxCorners: budget.maxCorners,
|
|
5004
|
+
corridorMargin
|
|
5005
|
+
},
|
|
4907
5006
|
diagnostics
|
|
4908
5007
|
) : null;
|
|
4909
5008
|
if (fullCornerPath !== null && fullCornerPath.length >= 2) {
|
|
@@ -4939,7 +5038,12 @@ function routeEdge(input) {
|
|
|
4939
5038
|
source,
|
|
4940
5039
|
target,
|
|
4941
5040
|
allObstacles,
|
|
4942
|
-
{
|
|
5041
|
+
{
|
|
5042
|
+
endpointObstacles,
|
|
5043
|
+
margin: 0,
|
|
5044
|
+
corridorMargin,
|
|
5045
|
+
maxNodes: budget.maxNodes
|
|
5046
|
+
},
|
|
4943
5047
|
diagnostics
|
|
4944
5048
|
);
|
|
4945
5049
|
if (gridPath !== null && gridPath.length >= 2) {
|