@jetta/cargo-stabilizer 0.1.0-10
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/CHANGELOG.md +39 -0
- package/README.md +144 -0
- package/build/core/adapters/axle_adapter.d.ts +16 -0
- package/build/core/adapters/axle_adapter.d.ts.map +1 -0
- package/build/core/adapters/axle_adapter.js +35 -0
- package/build/core/adapters/build_axle_request.d.ts +15 -0
- package/build/core/adapters/build_axle_request.d.ts.map +1 -0
- package/build/core/adapters/build_axle_request.js +39 -0
- package/build/core/adapters/coordinate_mapper.d.ts +36 -0
- package/build/core/adapters/coordinate_mapper.d.ts.map +1 -0
- package/build/core/adapters/coordinate_mapper.js +40 -0
- package/build/core/adapters/empty_space_adapter.d.ts +10 -0
- package/build/core/adapters/empty_space_adapter.d.ts.map +1 -0
- package/build/core/adapters/empty_space_adapter.js +24 -0
- package/build/core/adapters/map_item_to_positioned_cube.d.ts +9 -0
- package/build/core/adapters/map_item_to_positioned_cube.d.ts.map +1 -0
- package/build/core/adapters/map_item_to_positioned_cube.js +16 -0
- package/build/core/adapters/run_axle_calculator.d.ts +16 -0
- package/build/core/adapters/run_axle_calculator.d.ts.map +1 -0
- package/build/core/adapters/run_axle_calculator.js +32 -0
- package/build/core/adapters/stability_adapter.d.ts +36 -0
- package/build/core/adapters/stability_adapter.d.ts.map +1 -0
- package/build/core/adapters/stability_adapter.js +61 -0
- package/build/core/candidates/build_candidate_context.d.ts +13 -0
- package/build/core/candidates/build_candidate_context.d.ts.map +1 -0
- package/build/core/candidates/build_candidate_context.js +17 -0
- package/build/core/candidates/candidate_context.d.ts +13 -0
- package/build/core/candidates/candidate_context.d.ts.map +1 -0
- package/build/core/candidates/candidate_context.js +1 -0
- package/build/core/candidates/candidate_generator.d.ts +9 -0
- package/build/core/candidates/candidate_generator.d.ts.map +1 -0
- package/build/core/candidates/candidate_generator.js +42 -0
- package/build/core/candidates/candidate_validation.d.ts +14 -0
- package/build/core/candidates/candidate_validation.d.ts.map +1 -0
- package/build/core/candidates/candidate_validation.js +72 -0
- package/build/core/candidates/collect_container_slots.d.ts +16 -0
- package/build/core/candidates/collect_container_slots.d.ts.map +1 -0
- package/build/core/candidates/collect_container_slots.js +20 -0
- package/build/core/candidates/enumerate_empty_space_slots.d.ts +15 -0
- package/build/core/candidates/enumerate_empty_space_slots.d.ts.map +1 -0
- package/build/core/candidates/enumerate_empty_space_slots.js +44 -0
- package/build/core/candidates/enumerate_supporter_top_slots.d.ts +11 -0
- package/build/core/candidates/enumerate_supporter_top_slots.d.ts.map +1 -0
- package/build/core/candidates/enumerate_supporter_top_slots.js +36 -0
- package/build/core/candidates/is_elevated_on_supporter_origin.d.ts +14 -0
- package/build/core/candidates/is_elevated_on_supporter_origin.d.ts.map +1 -0
- package/build/core/candidates/is_elevated_on_supporter_origin.js +28 -0
- package/build/core/candidates/rank_candidates.d.ts +9 -0
- package/build/core/candidates/rank_candidates.d.ts.map +1 -0
- package/build/core/candidates/rank_candidates.js +22 -0
- package/build/core/constants/ReorderStrategy.d.ts +11 -0
- package/build/core/constants/ReorderStrategy.d.ts.map +1 -0
- package/build/core/constants/ReorderStrategy.js +9 -0
- package/build/core/constants/TieRatioOrientation.d.ts +6 -0
- package/build/core/constants/TieRatioOrientation.d.ts.map +1 -0
- package/build/core/constants/TieRatioOrientation.js +5 -0
- package/build/core/evaluation/compute_reorder_objective.d.ts +13 -0
- package/build/core/evaluation/compute_reorder_objective.d.ts.map +1 -0
- package/build/core/evaluation/compute_reorder_objective.js +13 -0
- package/build/core/evaluation/evaluation_context.d.ts +14 -0
- package/build/core/evaluation/evaluation_context.d.ts.map +1 -0
- package/build/core/evaluation/evaluation_context.js +1 -0
- package/build/core/evaluation/state_evaluator.d.ts +50 -0
- package/build/core/evaluation/state_evaluator.d.ts.map +1 -0
- package/build/core/evaluation/state_evaluator.js +95 -0
- package/build/core/exceptions/AxleCalculationError.d.ts +4 -0
- package/build/core/exceptions/AxleCalculationError.d.ts.map +1 -0
- package/build/core/exceptions/AxleCalculationError.js +6 -0
- package/build/core/exceptions/InvalidStabilizerInputError.d.ts +4 -0
- package/build/core/exceptions/InvalidStabilizerInputError.d.ts.map +1 -0
- package/build/core/exceptions/InvalidStabilizerInputError.js +6 -0
- package/build/core/exceptions/InvalidStabilizerOutputError.d.ts +4 -0
- package/build/core/exceptions/InvalidStabilizerOutputError.d.ts.map +1 -0
- package/build/core/exceptions/InvalidStabilizerOutputError.js +6 -0
- package/build/core/exceptions/MixedWaypointIdError.d.ts +4 -0
- package/build/core/exceptions/MixedWaypointIdError.d.ts.map +1 -0
- package/build/core/exceptions/MixedWaypointIdError.js +6 -0
- package/build/core/exceptions/UnknownReorderStrategyError.d.ts +4 -0
- package/build/core/exceptions/UnknownReorderStrategyError.d.ts.map +1 -0
- package/build/core/exceptions/UnknownReorderStrategyError.js +6 -0
- package/build/core/factory/read_stabilizer_config.d.ts +10 -0
- package/build/core/factory/read_stabilizer_config.d.ts.map +1 -0
- package/build/core/factory/read_stabilizer_config.js +26 -0
- package/build/core/factory/read_stabilizer_config_helpers.d.ts +29 -0
- package/build/core/factory/read_stabilizer_config_helpers.d.ts.map +1 -0
- package/build/core/factory/read_stabilizer_config_helpers.js +73 -0
- package/build/core/factory/strategy_factory.d.ts +9 -0
- package/build/core/factory/strategy_factory.d.ts.map +1 -0
- package/build/core/factory/strategy_factory.js +29 -0
- package/build/core/filters/collect_movable_items.d.ts +18 -0
- package/build/core/filters/collect_movable_items.d.ts.map +1 -0
- package/build/core/filters/collect_movable_items.js +72 -0
- package/build/core/filters/loose_item_filter.d.ts +20 -0
- package/build/core/filters/loose_item_filter.d.ts.map +1 -0
- package/build/core/filters/loose_item_filter.js +28 -0
- package/build/core/geometry/box_geometry.d.ts +48 -0
- package/build/core/geometry/box_geometry.d.ts.map +1 -0
- package/build/core/geometry/box_geometry.js +98 -0
- package/build/core/logging/stabilizer_logger.d.ts +3 -0
- package/build/core/logging/stabilizer_logger.d.ts.map +1 -0
- package/build/core/logging/stabilizer_logger.js +2 -0
- package/build/core/move/apply_move.d.ts +26 -0
- package/build/core/move/apply_move.d.ts.map +1 -0
- package/build/core/move/apply_move.js +26 -0
- package/build/core/orchestration/StabilizerFlow.d.ts +15 -0
- package/build/core/orchestration/StabilizerFlow.d.ts.map +1 -0
- package/build/core/orchestration/StabilizerFlow.js +29 -0
- package/build/core/orchestration/build_milkrun_bands_from_config.d.ts +13 -0
- package/build/core/orchestration/build_milkrun_bands_from_config.d.ts.map +1 -0
- package/build/core/orchestration/build_milkrun_bands_from_config.js +14 -0
- package/build/core/orchestration/build_reorder_context.d.ts +11 -0
- package/build/core/orchestration/build_reorder_context.d.ts.map +1 -0
- package/build/core/orchestration/build_reorder_context.js +27 -0
- package/build/core/orchestration/read_primary_env.d.ts +9 -0
- package/build/core/orchestration/read_primary_env.d.ts.map +1 -0
- package/build/core/orchestration/read_primary_env.js +13 -0
- package/build/core/strategies/reorder/BeamSearchReorder.d.ts +9 -0
- package/build/core/strategies/reorder/BeamSearchReorder.d.ts.map +1 -0
- package/build/core/strategies/reorder/BeamSearchReorder.js +68 -0
- package/build/core/strategies/reorder/GeneticReorder.d.ts +9 -0
- package/build/core/strategies/reorder/GeneticReorder.d.ts.map +1 -0
- package/build/core/strategies/reorder/GeneticReorder.js +43 -0
- package/build/core/strategies/reorder/GravityCompaction.d.ts +9 -0
- package/build/core/strategies/reorder/GravityCompaction.d.ts.map +1 -0
- package/build/core/strategies/reorder/GravityCompaction.js +48 -0
- package/build/core/strategies/reorder/GreedyReorder.d.ts +9 -0
- package/build/core/strategies/reorder/GreedyReorder.d.ts.map +1 -0
- package/build/core/strategies/reorder/GreedyReorder.js +20 -0
- package/build/core/strategies/reorder/ReorderStrategy.d.ts +19 -0
- package/build/core/strategies/reorder/ReorderStrategy.d.ts.map +1 -0
- package/build/core/strategies/reorder/ReorderStrategy.js +1 -0
- package/build/core/strategies/reorder/SimulatedAnnealingReorder.d.ts +9 -0
- package/build/core/strategies/reorder/SimulatedAnnealingReorder.d.ts.map +1 -0
- package/build/core/strategies/reorder/SimulatedAnnealingReorder.js +61 -0
- package/build/core/strategies/reorder/anneal_helpers.d.ts +18 -0
- package/build/core/strategies/reorder/anneal_helpers.d.ts.map +1 -0
- package/build/core/strategies/reorder/anneal_helpers.js +39 -0
- package/build/core/strategies/reorder/apply_if_gates_pass.d.ts +12 -0
- package/build/core/strategies/reorder/apply_if_gates_pass.d.ts.map +1 -0
- package/build/core/strategies/reorder/apply_if_gates_pass.js +19 -0
- package/build/core/strategies/reorder/beam_context.d.ts +16 -0
- package/build/core/strategies/reorder/beam_context.d.ts.map +1 -0
- package/build/core/strategies/reorder/beam_context.js +1 -0
- package/build/core/strategies/reorder/genetic/Chromosome.d.ts +39 -0
- package/build/core/strategies/reorder/genetic/Chromosome.d.ts.map +1 -0
- package/build/core/strategies/reorder/genetic/Chromosome.js +84 -0
- package/build/core/strategies/reorder/greedy_improvement.d.ts +12 -0
- package/build/core/strategies/reorder/greedy_improvement.d.ts.map +1 -0
- package/build/core/strategies/reorder/greedy_improvement.js +63 -0
- package/build/core/strategies/reorder/select_beam_expansion_candidates.d.ts +9 -0
- package/build/core/strategies/reorder/select_beam_expansion_candidates.d.ts.map +1 -0
- package/build/core/strategies/reorder/select_beam_expansion_candidates.js +28 -0
- package/build/core/validation/contract/cargo_movement_wire_field_map.d.ts +37 -0
- package/build/core/validation/contract/cargo_movement_wire_field_map.d.ts.map +1 -0
- package/build/core/validation/contract/cargo_movement_wire_field_map.js +43 -0
- package/build/core/validation/contract/cargo_movement_wire_mapper.d.ts +14 -0
- package/build/core/validation/contract/cargo_movement_wire_mapper.d.ts.map +1 -0
- package/build/core/validation/contract/cargo_movement_wire_mapper.js +34 -0
- package/build/core/validation/contract/format_zod_error.d.ts +8 -0
- package/build/core/validation/contract/format_zod_error.d.ts.map +1 -0
- package/build/core/validation/contract/format_zod_error.js +11 -0
- package/build/core/validation/contract/index.d.ts +9 -0
- package/build/core/validation/contract/index.d.ts.map +1 -0
- package/build/core/validation/contract/index.js +8 -0
- package/build/core/validation/contract/map_contract_to_wire_shape.d.ts +3 -0
- package/build/core/validation/contract/map_contract_to_wire_shape.d.ts.map +1 -0
- package/build/core/validation/contract/map_contract_to_wire_shape.js +42 -0
- package/build/core/validation/contract/map_wire_input_to_contract_shape.d.ts +2 -0
- package/build/core/validation/contract/map_wire_input_to_contract_shape.d.ts.map +1 -0
- package/build/core/validation/contract/map_wire_input_to_contract_shape.js +60 -0
- package/build/core/validation/contract/map_wire_item_to_contract.d.ts +12 -0
- package/build/core/validation/contract/map_wire_item_to_contract.d.ts.map +1 -0
- package/build/core/validation/contract/map_wire_item_to_contract.js +49 -0
- package/build/core/validation/contract/parse_stabilizer_input.d.ts +48 -0
- package/build/core/validation/contract/parse_stabilizer_input.d.ts.map +1 -0
- package/build/core/validation/contract/parse_stabilizer_input.js +26 -0
- package/build/core/validation/contract/parse_stabilizer_output.d.ts +50 -0
- package/build/core/validation/contract/parse_stabilizer_output.d.ts.map +1 -0
- package/build/core/validation/contract/parse_stabilizer_output.js +24 -0
- package/build/core/validation/contract/stabilizer_domain_schema.d.ts +101 -0
- package/build/core/validation/contract/stabilizer_domain_schema.d.ts.map +1 -0
- package/build/core/validation/contract/stabilizer_domain_schema.js +64 -0
- package/build/core/validation/contract/stabilizer_input_schema.d.ts +36 -0
- package/build/core/validation/contract/stabilizer_input_schema.d.ts.map +1 -0
- package/build/core/validation/contract/stabilizer_input_schema.js +11 -0
- package/build/core/validation/contract/stabilizer_output_schema.d.ts +76 -0
- package/build/core/validation/contract/stabilizer_output_schema.d.ts.map +1 -0
- package/build/core/validation/contract/stabilizer_output_schema.js +16 -0
- package/build/core/validation/contract/wire_mapper_record_utils.d.ts +34 -0
- package/build/core/validation/contract/wire_mapper_record_utils.d.ts.map +1 -0
- package/build/core/validation/contract/wire_mapper_record_utils.js +66 -0
- package/build/core/validation/schemas/stabilizer_config_schema.d.ts +20 -0
- package/build/core/validation/schemas/stabilizer_config_schema.d.ts.map +1 -0
- package/build/core/validation/schemas/stabilizer_config_schema.js +17 -0
- package/build/core/waypoint/WaypointMode.d.ts +16 -0
- package/build/core/waypoint/WaypointMode.d.ts.map +1 -0
- package/build/core/waypoint/WaypointMode.js +1 -0
- package/build/core/waypoint/build_waypoint_zones.d.ts +21 -0
- package/build/core/waypoint/build_waypoint_zones.d.ts.map +1 -0
- package/build/core/waypoint/build_waypoint_zones.js +48 -0
- package/build/core/waypoint/milkrun_wall_reservation.d.ts +24 -0
- package/build/core/waypoint/milkrun_wall_reservation.d.ts.map +1 -0
- package/build/core/waypoint/milkrun_wall_reservation.js +57 -0
- package/build/core/waypoint/milkrun_wall_reservation_helpers.d.ts +15 -0
- package/build/core/waypoint/milkrun_wall_reservation_helpers.d.ts.map +1 -0
- package/build/core/waypoint/milkrun_wall_reservation_helpers.js +48 -0
- package/build/core/waypoint/milkrun_wall_reservation_types.d.ts +16 -0
- package/build/core/waypoint/milkrun_wall_reservation_types.d.ts.map +1 -0
- package/build/core/waypoint/milkrun_wall_reservation_types.js +1 -0
- package/build/core/waypoint/preserves_waypoint_order.d.ts +24 -0
- package/build/core/waypoint/preserves_waypoint_order.d.ts.map +1 -0
- package/build/core/waypoint/preserves_waypoint_order.js +49 -0
- package/build/core/waypoint/validate_waypoint_ids.d.ts +16 -0
- package/build/core/waypoint/validate_waypoint_ids.d.ts.map +1 -0
- package/build/core/waypoint/validate_waypoint_ids.js +30 -0
- package/build/index.d.ts +27 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +75 -0
- package/package.json +51 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const GEOMETRY_EPSILON = 1e-6;
|
|
2
|
+
/**
|
|
3
|
+
* @param item - Cargo item with position and dimensions.
|
|
4
|
+
* @returns Axis-aligned bounding box.
|
|
5
|
+
*/
|
|
6
|
+
export function item_to_box(item) {
|
|
7
|
+
return {
|
|
8
|
+
x: item.x,
|
|
9
|
+
y: item.y,
|
|
10
|
+
z: item.z,
|
|
11
|
+
w: item.width,
|
|
12
|
+
h: item.height,
|
|
13
|
+
d: item.depth
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* @param left - First box.
|
|
18
|
+
* @param right - Second box.
|
|
19
|
+
* @returns True when boxes overlap in 3D.
|
|
20
|
+
*/
|
|
21
|
+
export function boxes_overlap(left, right) {
|
|
22
|
+
const x_overlap = left.x < right.x + right.w && left.x + left.w > right.x;
|
|
23
|
+
const y_overlap = left.y < right.y + right.h && left.y + left.h > right.y;
|
|
24
|
+
const z_overlap = left.z < right.z + right.d && left.z + left.d > right.z;
|
|
25
|
+
return x_overlap && y_overlap && z_overlap;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* @param candidate - Candidate placement box.
|
|
29
|
+
* @param others - Existing item boxes to avoid.
|
|
30
|
+
* @returns True when candidate overlaps any other box.
|
|
31
|
+
*/
|
|
32
|
+
export function has_overlap(candidate, others) {
|
|
33
|
+
return others.some(other => boxes_overlap(candidate, other));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @param candidate - Candidate box.
|
|
37
|
+
* @returns True when candidate rests on container floor.
|
|
38
|
+
*/
|
|
39
|
+
export function is_on_floor(candidate) {
|
|
40
|
+
return candidate.y <= GEOMETRY_EPSILON;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @param candidate - Candidate placement box.
|
|
44
|
+
* @param container - Container dimensions.
|
|
45
|
+
* @returns True when candidate fits inside container bounds.
|
|
46
|
+
*/
|
|
47
|
+
export function is_inside_container(candidate, container) {
|
|
48
|
+
if (candidate.x < -GEOMETRY_EPSILON || candidate.y < -GEOMETRY_EPSILON || candidate.z < -GEOMETRY_EPSILON) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
if (candidate.x + candidate.w > container.width + GEOMETRY_EPSILON) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (candidate.y + candidate.h > container.height + GEOMETRY_EPSILON) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return candidate.z + candidate.d <= container.length + GEOMETRY_EPSILON;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @param candidate - Candidate placement box.
|
|
61
|
+
* @param supporters - Existing item boxes (excluding candidate).
|
|
62
|
+
* @returns True when bottom face is on floor or supporter tops.
|
|
63
|
+
*/
|
|
64
|
+
export function is_fully_supported(candidate, supporters) {
|
|
65
|
+
if (is_on_floor(candidate)) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return sample_bottom_support_points(candidate).every(point => is_support_point_supported(point, supporters));
|
|
69
|
+
}
|
|
70
|
+
function sample_bottom_support_points(candidate) {
|
|
71
|
+
const { x, y, z, w, d } = candidate;
|
|
72
|
+
const mid_x = x + w / 2;
|
|
73
|
+
const mid_z = z + d / 2;
|
|
74
|
+
return [
|
|
75
|
+
{ x, y, z },
|
|
76
|
+
{ x: x + w, y, z },
|
|
77
|
+
{ x, y, z: z + d },
|
|
78
|
+
{ x: x + w, y, z: z + d },
|
|
79
|
+
{ x: mid_x, y, z: mid_z }
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
function is_support_point_supported(point, supporters) {
|
|
83
|
+
if (point.y <= GEOMETRY_EPSILON) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return supporters.some(supporter => is_point_on_supporter_top(point, supporter));
|
|
87
|
+
}
|
|
88
|
+
function is_point_on_supporter_top(point, supporter) {
|
|
89
|
+
const top_y = supporter.y + supporter.h;
|
|
90
|
+
if (Math.abs(point.y - top_y) > GEOMETRY_EPSILON) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
const within_x = point.x >= supporter.x - GEOMETRY_EPSILON &&
|
|
94
|
+
point.x <= supporter.x + supporter.w + GEOMETRY_EPSILON;
|
|
95
|
+
const within_z = point.z >= supporter.z - GEOMETRY_EPSILON &&
|
|
96
|
+
point.z <= supporter.z + supporter.d + GEOMETRY_EPSILON;
|
|
97
|
+
return within_x && within_z;
|
|
98
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stabilizer_logger.d.ts","sourceRoot":"","sources":["../../../src/core/logging/stabilizer_logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,eAAO,MAAM,iBAAiB,QAAgC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { StabilizerContainer } from '../validation/contract/stabilizer_domain_schema.js';
|
|
2
|
+
export type CandidateSlotKind = 'empty_space' | 'supporter_top';
|
|
3
|
+
export interface MoveCandidate {
|
|
4
|
+
item_id: string;
|
|
5
|
+
source_container_index: number;
|
|
6
|
+
target_container_index: number;
|
|
7
|
+
new_position: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
z: number;
|
|
11
|
+
};
|
|
12
|
+
slot_kind?: CandidateSlotKind;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Applies a move candidate to containers (mutates arrays in place).
|
|
16
|
+
* @param containers - Mutable container list.
|
|
17
|
+
* @param candidate - Move to apply.
|
|
18
|
+
*/
|
|
19
|
+
export declare function apply_move(containers: StabilizerContainer[], candidate: MoveCandidate): void;
|
|
20
|
+
/**
|
|
21
|
+
* Deep-clones containers for trial evaluation.
|
|
22
|
+
* @param containers - Source containers.
|
|
23
|
+
* @returns Cloned containers.
|
|
24
|
+
*/
|
|
25
|
+
export declare function clone_containers(containers: StabilizerContainer[]): StabilizerContainer[];
|
|
26
|
+
//# sourceMappingURL=apply_move.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply_move.d.ts","sourceRoot":"","sources":["../../../src/core/move/apply_move.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAA;AAE7F,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,eAAe,CAAA;AAE/D,MAAM,WAAW,aAAa;IAE1B,OAAO,EAAE,MAAM,CAAA;IACf,sBAAsB,EAAE,MAAM,CAAA;IAC9B,sBAAsB,EAAE,MAAM,CAAA;IAC9B,YAAY,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACjD,SAAS,CAAC,EAAE,iBAAiB,CAAA;CAChC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,UAAU,EAAE,mBAAmB,EAAE,EACjC,SAAS,EAAE,aAAa,GACzB,IAAI,CAgBN;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,mBAAmB,EAAE,GAAG,mBAAmB,EAAE,CAGzF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies a move candidate to containers (mutates arrays in place).
|
|
3
|
+
* @param containers - Mutable container list.
|
|
4
|
+
* @param candidate - Move to apply.
|
|
5
|
+
*/
|
|
6
|
+
export function apply_move(containers, candidate) {
|
|
7
|
+
const source = containers[candidate.source_container_index];
|
|
8
|
+
const item_index = source.items.findIndex(item => item.item_id === candidate.item_id);
|
|
9
|
+
if (item_index < 0) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const [item] = source.items.splice(item_index, 1);
|
|
13
|
+
item.x = candidate.new_position.x;
|
|
14
|
+
item.y = candidate.new_position.y;
|
|
15
|
+
item.z = candidate.new_position.z;
|
|
16
|
+
const target = containers[candidate.target_container_index];
|
|
17
|
+
target.items.push(item);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Deep-clones containers for trial evaluation.
|
|
21
|
+
* @param containers - Source containers.
|
|
22
|
+
* @returns Cloned containers.
|
|
23
|
+
*/
|
|
24
|
+
export function clone_containers(containers) {
|
|
25
|
+
return structuredClone(containers);
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StabilizerInput } from '../validation/contract/stabilizer_input_schema.js';
|
|
2
|
+
import type { StabilizerCargoState } from '../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runs stabilizer flow on validated input.
|
|
5
|
+
* @param input - Raw stabilizer input.
|
|
6
|
+
* @returns Updated cargo_state.
|
|
7
|
+
*/
|
|
8
|
+
export declare function run_stabilizer_flow(input: StabilizerInput): StabilizerCargoState;
|
|
9
|
+
/**
|
|
10
|
+
* Parses and runs stabilizer on unknown input.
|
|
11
|
+
* @param input_data - Unknown wire payload.
|
|
12
|
+
* @returns Updated cargo_state.
|
|
13
|
+
*/
|
|
14
|
+
export declare function run_stabilizer_flow_from_unknown(input_data: unknown): StabilizerCargoState;
|
|
15
|
+
//# sourceMappingURL=StabilizerFlow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StabilizerFlow.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/StabilizerFlow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAA;AACxF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAA;AAO9F;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,oBAAoB,CAiBhF;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,OAAO,GAAG,oBAAoB,CAI1F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { parse_stabilizer_input } from '../validation/contract/parse_stabilizer_input.js';
|
|
2
|
+
import { read_stabilizer_config } from '../factory/read_stabilizer_config.js';
|
|
3
|
+
import { create_reorder_strategy } from '../factory/strategy_factory.js';
|
|
4
|
+
import { build_reorder_context } from './build_reorder_context.js';
|
|
5
|
+
import { stabilizer_logger } from '../logging/stabilizer_logger.js';
|
|
6
|
+
/**
|
|
7
|
+
* Runs stabilizer flow on validated input.
|
|
8
|
+
* @param input - Raw stabilizer input.
|
|
9
|
+
* @returns Updated cargo_state.
|
|
10
|
+
*/
|
|
11
|
+
export function run_stabilizer_flow(input) {
|
|
12
|
+
const config = read_stabilizer_config(input.config, input.cargo_state);
|
|
13
|
+
const context = build_reorder_context(input, config);
|
|
14
|
+
stabilizer_logger.debug('reorder_strategy=' + config.reorder_strategy);
|
|
15
|
+
stabilizer_logger.debug('container_count=' + context.containers.length +
|
|
16
|
+
' loose_item_count=' + context.loose_items.length +
|
|
17
|
+
' waypoint_mode=' + context.waypoint_mode.kind);
|
|
18
|
+
create_reorder_strategy(config).run(context);
|
|
19
|
+
return input.cargo_state;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parses and runs stabilizer on unknown input.
|
|
23
|
+
* @param input_data - Unknown wire payload.
|
|
24
|
+
* @returns Updated cargo_state.
|
|
25
|
+
*/
|
|
26
|
+
export function run_stabilizer_flow_from_unknown(input_data) {
|
|
27
|
+
const input = parse_stabilizer_input(input_data);
|
|
28
|
+
return run_stabilizer_flow(input);
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { StabilizerContainer } from '../validation/contract/stabilizer_domain_schema.js';
|
|
2
|
+
import type { StabilizerConfig } from '../validation/schemas/stabilizer_config_schema.js';
|
|
3
|
+
import type { WaypointMode } from '../waypoint/WaypointMode.js';
|
|
4
|
+
import type { MilkrunReservedBand } from '../waypoint/milkrun_wall_reservation_types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Builds milkrun reserved bands when enforcement is enabled in config.
|
|
7
|
+
* @param baseline_containers - Baseline container layout.
|
|
8
|
+
* @param waypoint_mode - Resolved waypoint mode.
|
|
9
|
+
* @param config - Parsed stabilizer config.
|
|
10
|
+
* @returns Reserved Z bands (empty when milkrun enforcement is disabled).
|
|
11
|
+
*/
|
|
12
|
+
export declare function build_milkrun_bands_from_config(baseline_containers: StabilizerContainer[], waypoint_mode: WaypointMode, config: StabilizerConfig): MilkrunReservedBand[];
|
|
13
|
+
//# sourceMappingURL=build_milkrun_bands_from_config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build_milkrun_bands_from_config.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/build_milkrun_bands_from_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAA;AAC7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAA;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAA;AAExF;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC3C,mBAAmB,EAAE,mBAAmB,EAAE,EAC1C,aAAa,EAAE,YAAY,EAC3B,MAAM,EAAE,gBAAgB,GACzB,mBAAmB,EAAE,CAMvB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { build_milkrun_reserved_z_bands } from '../waypoint/milkrun_wall_reservation.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds milkrun reserved bands when enforcement is enabled in config.
|
|
4
|
+
* @param baseline_containers - Baseline container layout.
|
|
5
|
+
* @param waypoint_mode - Resolved waypoint mode.
|
|
6
|
+
* @param config - Parsed stabilizer config.
|
|
7
|
+
* @returns Reserved Z bands (empty when milkrun enforcement is disabled).
|
|
8
|
+
*/
|
|
9
|
+
export function build_milkrun_bands_from_config(baseline_containers, waypoint_mode, config) {
|
|
10
|
+
const wall_count = config.enforce_milkrun_wall_reservation
|
|
11
|
+
? config.number_of_wall_to_allocate_from_last_waypoints
|
|
12
|
+
: 0;
|
|
13
|
+
return build_milkrun_reserved_z_bands(baseline_containers, waypoint_mode, wall_count);
|
|
14
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StabilizerInput } from '../validation/contract/stabilizer_input_schema.js';
|
|
2
|
+
import type { StabilizerConfig } from '../validation/schemas/stabilizer_config_schema.js';
|
|
3
|
+
import type { ReorderContext } from '../strategies/reorder/ReorderStrategy.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds reorder context from validated stabilizer input.
|
|
6
|
+
* @param input - Validated stabilizer input.
|
|
7
|
+
* @param config - Parsed stabilizer config.
|
|
8
|
+
* @returns Reorder context for strategy execution.
|
|
9
|
+
*/
|
|
10
|
+
export declare function build_reorder_context(input: StabilizerInput, config: StabilizerConfig): ReorderContext;
|
|
11
|
+
//# sourceMappingURL=build_reorder_context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build_reorder_context.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/build_reorder_context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAA;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAA;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAA;AAQ9E;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACjC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,gBAAgB,GACzB,cAAc,CAqBhB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { collect_movable_items } from '../filters/collect_movable_items.js';
|
|
2
|
+
import { validate_waypoint_ids } from '../waypoint/validate_waypoint_ids.js';
|
|
3
|
+
import { build_waypoint_zones } from '../waypoint/build_waypoint_zones.js';
|
|
4
|
+
import { build_milkrun_bands_from_config } from './build_milkrun_bands_from_config.js';
|
|
5
|
+
import { read_primary_env } from './read_primary_env.js';
|
|
6
|
+
import { clone_containers } from '../move/apply_move.js';
|
|
7
|
+
/**
|
|
8
|
+
* Builds reorder context from validated stabilizer input.
|
|
9
|
+
* @param input - Validated stabilizer input.
|
|
10
|
+
* @param config - Parsed stabilizer config.
|
|
11
|
+
* @returns Reorder context for strategy execution.
|
|
12
|
+
*/
|
|
13
|
+
export function build_reorder_context(input, config) {
|
|
14
|
+
const env = read_primary_env(input);
|
|
15
|
+
const waypoint_mode = validate_waypoint_ids(env.containers.flatMap(container => container.items));
|
|
16
|
+
const baseline_containers = clone_containers(env.containers);
|
|
17
|
+
return {
|
|
18
|
+
env,
|
|
19
|
+
containers: env.containers,
|
|
20
|
+
baseline_containers,
|
|
21
|
+
loose_items: collect_movable_items(env.containers, config.pin_tie_ratio_blocks),
|
|
22
|
+
config,
|
|
23
|
+
waypoint_mode,
|
|
24
|
+
waypoint_zones: build_waypoint_zones(baseline_containers, waypoint_mode),
|
|
25
|
+
milkrun_reserved_z_bands: build_milkrun_bands_from_config(baseline_containers, waypoint_mode, config)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StabilizerInput } from '../validation/contract/stabilizer_input_schema.js';
|
|
2
|
+
import type { StabilizerEnv } from '../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Reads the primary env from stabilizer input.
|
|
5
|
+
* @param input - Validated stabilizer input.
|
|
6
|
+
* @returns First cargo env.
|
|
7
|
+
*/
|
|
8
|
+
export declare function read_primary_env(input: StabilizerInput): StabilizerEnv;
|
|
9
|
+
//# sourceMappingURL=read_primary_env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read_primary_env.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/read_primary_env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAA;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oDAAoD,CAAA;AAGvF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,CAQtE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InvalidStabilizerInputError } from '../exceptions/InvalidStabilizerInputError.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reads the primary env from stabilizer input.
|
|
4
|
+
* @param input - Validated stabilizer input.
|
|
5
|
+
* @returns First cargo env.
|
|
6
|
+
*/
|
|
7
|
+
export function read_primary_env(input) {
|
|
8
|
+
const env = input.cargo_state.envs[0];
|
|
9
|
+
if (!env) {
|
|
10
|
+
throw new InvalidStabilizerInputError('cargo_state.envs must contain at least one env');
|
|
11
|
+
}
|
|
12
|
+
return env;
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReorderContext, ReorderStrategy } from './ReorderStrategy.js';
|
|
2
|
+
import type { StabilizerContainer } from '../../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Beam search reorder with configurable width and top-K expansion.
|
|
5
|
+
*/
|
|
6
|
+
export declare class BeamSearchReorder implements ReorderStrategy {
|
|
7
|
+
run(context: ReorderContext): StabilizerContainer[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=BeamSearchReorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BeamSearchReorder.d.ts","sourceRoot":"","sources":["../../../../src/core/strategies/reorder/BeamSearchReorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAA;AAahG;;GAEG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IAErD,GAAG,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE;CAkBtD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { generate_candidates } from '../../candidates/candidate_generator.js';
|
|
2
|
+
import { candidate_context_for_loose } from '../../candidates/build_candidate_context.js';
|
|
3
|
+
import { select_beam_expansion_candidates } from './select_beam_expansion_candidates.js';
|
|
4
|
+
import { apply_move, clone_containers } from '../../move/apply_move.js';
|
|
5
|
+
import { evaluate_trial_layout, evaluation_context_from_reorder } from '../../evaluation/state_evaluator.js';
|
|
6
|
+
import { read_item_score } from '../../adapters/stability_adapter.js';
|
|
7
|
+
/**
|
|
8
|
+
* Beam search reorder with configurable width and top-K expansion.
|
|
9
|
+
*/
|
|
10
|
+
export class BeamSearchReorder {
|
|
11
|
+
run(context) {
|
|
12
|
+
const eval_context = evaluation_context_from_reorder(context);
|
|
13
|
+
const sorted = sort_loose_by_stability(context, eval_context);
|
|
14
|
+
let beam = [{
|
|
15
|
+
containers: clone_containers(context.containers),
|
|
16
|
+
objective: evaluate_trial_layout(context.containers, eval_context).objective
|
|
17
|
+
}];
|
|
18
|
+
for (const loose of sorted) {
|
|
19
|
+
beam = expand_beam({ reorder: context, evaluation: eval_context, beam, loose });
|
|
20
|
+
}
|
|
21
|
+
const best = beam[0]?.containers ?? context.containers;
|
|
22
|
+
context.containers.splice(0, context.containers.length, ...best);
|
|
23
|
+
return best;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function expand_beam(request) {
|
|
27
|
+
const expanded = [];
|
|
28
|
+
for (const state of request.beam) {
|
|
29
|
+
append_beam_branches({
|
|
30
|
+
reorder: request.reorder,
|
|
31
|
+
evaluation: request.evaluation,
|
|
32
|
+
expanded,
|
|
33
|
+
state,
|
|
34
|
+
loose: request.loose
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
expanded.sort((left, right) => right.objective - left.objective);
|
|
38
|
+
return expanded.slice(0, request.reorder.config.beam_width);
|
|
39
|
+
}
|
|
40
|
+
function append_beam_branches(beam_context) {
|
|
41
|
+
const { reorder, evaluation, expanded, state, loose } = beam_context;
|
|
42
|
+
const loose_ref = { ...loose, container_index: find_container_index(state.containers, loose.item_id) };
|
|
43
|
+
const candidates = select_beam_expansion_candidates(generate_candidates(candidate_context_for_loose(reorder, state.containers, loose_ref)), reorder.config.beam_top_k);
|
|
44
|
+
for (const candidate of candidates) {
|
|
45
|
+
const trial = clone_containers(state.containers);
|
|
46
|
+
apply_move(trial, candidate);
|
|
47
|
+
const result = evaluate_trial_layout(trial, evaluation);
|
|
48
|
+
if (!result.all_gates_pass) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
expanded.push({ containers: trial, objective: result.objective });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function sort_loose_by_stability(context, eval_context) {
|
|
55
|
+
const evaluation = evaluate_trial_layout(context.containers, eval_context);
|
|
56
|
+
return [...context.loose_items].sort((left, right) => {
|
|
57
|
+
const left_index = context.containers[left.container_index].items
|
|
58
|
+
.findIndex(item => item.item_id === left.item_id);
|
|
59
|
+
const right_index = context.containers[right.container_index].items
|
|
60
|
+
.findIndex(item => item.item_id === right.item_id);
|
|
61
|
+
const left_score = read_item_score(evaluation.stability, left.container_index, left_index);
|
|
62
|
+
const right_score = read_item_score(evaluation.stability, right.container_index, right_index);
|
|
63
|
+
return left_score - right_score;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function find_container_index(containers, item_id) {
|
|
67
|
+
return containers.findIndex(container => container.items.some(item => item.item_id === item_id));
|
|
68
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReorderContext, ReorderStrategy } from './ReorderStrategy.js';
|
|
2
|
+
import type { StabilizerContainer } from '../../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Genetic algorithm reorder optimizing loose-item stability sum.
|
|
5
|
+
*/
|
|
6
|
+
export declare class GeneticReorder implements ReorderStrategy {
|
|
7
|
+
run(context: ReorderContext): StabilizerContainer[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=GeneticReorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GeneticReorder.d.ts","sourceRoot":"","sources":["../../../../src/core/strategies/reorder/GeneticReorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAA;AAahG;;GAEG;AACH,qBAAa,cAAe,YAAW,eAAe;IAElD,GAAG,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE;CAgBtD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { build_initial_population, crossover_organisms, materialize_organism, mutate_organism } from './genetic/Chromosome.js';
|
|
2
|
+
import { evaluate_trial_layout, evaluation_context_from_reorder } from '../../evaluation/state_evaluator.js';
|
|
3
|
+
/**
|
|
4
|
+
* Genetic algorithm reorder optimizing loose-item stability sum.
|
|
5
|
+
*/
|
|
6
|
+
export class GeneticReorder {
|
|
7
|
+
run(context) {
|
|
8
|
+
const eval_context = evaluation_context_from_reorder(context);
|
|
9
|
+
let population = build_initial_population(context, context.config.genetic_population);
|
|
10
|
+
score_population(context, eval_context, population);
|
|
11
|
+
for (let generation = 0; generation < context.config.genetic_generations; generation++) {
|
|
12
|
+
population = evolve_generation(context, eval_context, population);
|
|
13
|
+
}
|
|
14
|
+
population.sort((left, right) => right.fitness - left.fitness);
|
|
15
|
+
const best_layout = materialize_organism(context.baseline_containers, population[0]);
|
|
16
|
+
context.containers.splice(0, context.containers.length, ...best_layout);
|
|
17
|
+
return best_layout;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function evolve_generation(context, eval_context, population) {
|
|
21
|
+
const next = [];
|
|
22
|
+
population.sort((left, right) => right.fitness - left.fitness);
|
|
23
|
+
next.push(structuredClone(population[0]));
|
|
24
|
+
while (next.length < context.config.genetic_population) {
|
|
25
|
+
const parent_a = population[Math.floor(Math.random() * population.length)];
|
|
26
|
+
const parent_b = population[Math.floor(Math.random() * population.length)];
|
|
27
|
+
const child = crossover_organisms(parent_a, parent_b);
|
|
28
|
+
mutate_organism(child, context, context.config.genetic_mutation_rate);
|
|
29
|
+
score_organism(context, eval_context, child);
|
|
30
|
+
next.push(child);
|
|
31
|
+
}
|
|
32
|
+
return next;
|
|
33
|
+
}
|
|
34
|
+
function score_population(context, eval_context, population) {
|
|
35
|
+
for (const organism of population) {
|
|
36
|
+
score_organism(context, eval_context, organism);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function score_organism(context, eval_context, organism) {
|
|
40
|
+
const layout = materialize_organism(context.baseline_containers, organism);
|
|
41
|
+
const evaluation = evaluate_trial_layout(layout, eval_context);
|
|
42
|
+
organism.fitness = evaluation.all_gates_pass ? evaluation.objective : Number.NEGATIVE_INFINITY;
|
|
43
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReorderContext, ReorderStrategy } from './ReorderStrategy.js';
|
|
2
|
+
import type { StabilizerContainer } from '../../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Single-pass gravity compaction: unstable loose items to lowest feasible floor slot.
|
|
5
|
+
*/
|
|
6
|
+
export declare class GravityCompaction implements ReorderStrategy {
|
|
7
|
+
run(context: ReorderContext): StabilizerContainer[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=GravityCompaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GravityCompaction.d.ts","sourceRoot":"","sources":["../../../../src/core/strategies/reorder/GravityCompaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAA;AAWhG;;GAEG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IAErD,GAAG,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE;CAatD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { generate_candidates } from '../../candidates/candidate_generator.js';
|
|
2
|
+
import { candidate_context_for_loose } from '../../candidates/build_candidate_context.js';
|
|
3
|
+
import { clone_containers } from '../../move/apply_move.js';
|
|
4
|
+
import { apply_if_gates_pass } from './apply_if_gates_pass.js';
|
|
5
|
+
import { evaluate_trial_layout, evaluation_context_from_reorder } from '../../evaluation/state_evaluator.js';
|
|
6
|
+
import { read_item_score } from '../../adapters/stability_adapter.js';
|
|
7
|
+
/**
|
|
8
|
+
* Single-pass gravity compaction: unstable loose items to lowest feasible floor slot.
|
|
9
|
+
*/
|
|
10
|
+
export class GravityCompaction {
|
|
11
|
+
run(context) {
|
|
12
|
+
const working = clone_containers(context.containers);
|
|
13
|
+
const sorted = sort_loose_by_stability(context, working);
|
|
14
|
+
for (const loose of sorted) {
|
|
15
|
+
compact_loose_item(context, working, loose);
|
|
16
|
+
}
|
|
17
|
+
context.containers.splice(0, context.containers.length, ...working);
|
|
18
|
+
return working;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function compact_loose_item(context, working, loose) {
|
|
22
|
+
const loose_ref = context.loose_items.find(item => item.item_id === loose.item_id);
|
|
23
|
+
if (!loose_ref) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
loose_ref.container_index = find_container_index(working, loose.item_id);
|
|
27
|
+
const candidates = generate_candidates(candidate_context_for_loose(context, working, loose_ref));
|
|
28
|
+
for (const candidate of candidates) {
|
|
29
|
+
if (apply_if_gates_pass(context, working, candidate)) {
|
|
30
|
+
loose_ref.container_index = candidate.target_container_index;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function sort_loose_by_stability(context, containers) {
|
|
36
|
+
const evaluation = evaluate_trial_layout(containers, evaluation_context_from_reorder(context));
|
|
37
|
+
return context.loose_items
|
|
38
|
+
.map(loose => {
|
|
39
|
+
const item_index = containers[loose.container_index].items
|
|
40
|
+
.findIndex(item => item.item_id === loose.item_id);
|
|
41
|
+
const score = read_item_score(evaluation.stability, loose.container_index, item_index);
|
|
42
|
+
return { item_id: loose.item_id, container_index: loose.container_index, score };
|
|
43
|
+
})
|
|
44
|
+
.sort((left, right) => left.score - right.score);
|
|
45
|
+
}
|
|
46
|
+
function find_container_index(containers, item_id) {
|
|
47
|
+
return containers.findIndex(container => container.items.some(item => item.item_id === item_id));
|
|
48
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReorderContext, ReorderStrategy } from './ReorderStrategy.js';
|
|
2
|
+
import type { StabilizerContainer } from '../../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Greedy iterative reorder: fix worst loose item until plateau or max iterations.
|
|
5
|
+
*/
|
|
6
|
+
export declare class GreedyReorder implements ReorderStrategy {
|
|
7
|
+
run(context: ReorderContext): StabilizerContainer[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=GreedyReorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GreedyReorder.d.ts","sourceRoot":"","sources":["../../../../src/core/strategies/reorder/GreedyReorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAA;AAKhG;;GAEG;AACH,qBAAa,aAAc,YAAW,eAAe;IAEjD,GAAG,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE;CAiBtD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { clone_containers } from '../../move/apply_move.js';
|
|
2
|
+
import { evaluation_context_from_reorder } from '../../evaluation/state_evaluator.js';
|
|
3
|
+
import { improve_worst_loose } from './greedy_improvement.js';
|
|
4
|
+
/**
|
|
5
|
+
* Greedy iterative reorder: fix worst loose item until plateau or max iterations.
|
|
6
|
+
*/
|
|
7
|
+
export class GreedyReorder {
|
|
8
|
+
run(context) {
|
|
9
|
+
const working = clone_containers(context.containers);
|
|
10
|
+
const eval_context = evaluation_context_from_reorder(context);
|
|
11
|
+
for (let iteration = 0; iteration < context.config.max_iteration; iteration++) {
|
|
12
|
+
const improved = improve_worst_loose(context, working, eval_context);
|
|
13
|
+
if (!improved) {
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
context.containers.splice(0, context.containers.length, ...working);
|
|
18
|
+
return working;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { StabilizerConfig } from '../../validation/schemas/stabilizer_config_schema.js';
|
|
2
|
+
import type { StabilizerContainer, StabilizerEnv } from '../../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
import type { LooseItemRef } from '../../filters/loose_item_filter.js';
|
|
4
|
+
import type { WaypointMode, WaypointZone } from '../../waypoint/WaypointMode.js';
|
|
5
|
+
import type { MilkrunReservedBand } from '../../waypoint/milkrun_wall_reservation.js';
|
|
6
|
+
export interface ReorderContext {
|
|
7
|
+
env: StabilizerEnv;
|
|
8
|
+
containers: StabilizerContainer[];
|
|
9
|
+
baseline_containers: StabilizerContainer[];
|
|
10
|
+
loose_items: LooseItemRef[];
|
|
11
|
+
config: StabilizerConfig;
|
|
12
|
+
waypoint_mode: WaypointMode;
|
|
13
|
+
waypoint_zones: WaypointZone[];
|
|
14
|
+
milkrun_reserved_z_bands: MilkrunReservedBand[];
|
|
15
|
+
}
|
|
16
|
+
export interface ReorderStrategy {
|
|
17
|
+
run(context: ReorderContext): StabilizerContainer[];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ReorderStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReorderStrategy.d.ts","sourceRoot":"","sources":["../../../../src/core/strategies/reorder/ReorderStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sDAAsD,CAAA;AAC5F,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,uDAAuD,CAAA;AAC/G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAA;AAErF,MAAM,WAAW,cAAc;IAE3B,GAAG,EAAE,aAAa,CAAA;IAClB,UAAU,EAAE,mBAAmB,EAAE,CAAA;IACjC,mBAAmB,EAAE,mBAAmB,EAAE,CAAA;IAC1C,WAAW,EAAE,YAAY,EAAE,CAAA;IAC3B,MAAM,EAAE,gBAAgB,CAAA;IACxB,aAAa,EAAE,YAAY,CAAA;IAC3B,cAAc,EAAE,YAAY,EAAE,CAAA;IAC9B,wBAAwB,EAAE,mBAAmB,EAAE,CAAA;CAClD;AAED,MAAM,WAAW,eAAe;IAE5B,GAAG,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE,CAAA;CACtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReorderContext, ReorderStrategy } from './ReorderStrategy.js';
|
|
2
|
+
import type { StabilizerContainer } from '../../validation/contract/stabilizer_domain_schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* Simulated annealing reorder with hard gate rejection on invalid neighbors.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SimulatedAnnealingReorder implements ReorderStrategy {
|
|
7
|
+
run(context: ReorderContext): StabilizerContainer[];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=SimulatedAnnealingReorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimulatedAnnealingReorder.d.ts","sourceRoot":"","sources":["../../../../src/core/strategies/reorder/SimulatedAnnealingReorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAA;AAyBhG;;GAEG;AACH,qBAAa,yBAA0B,YAAW,eAAe;IAE7D,GAAG,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,EAAE;CAqBtD"}
|