6 Commits

9 changed files with 123 additions and 57 deletions
+1
View File
@@ -4,6 +4,7 @@
*.autosave *.autosave
*.slx.r* *.slx.r*
*.mdl.r* *.mdl.r*
*.bak
# Derived content-obscured files # Derived content-obscured files
*.p *.p
+6 -4
View File
@@ -72,18 +72,20 @@ function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, m
obj.constraintAdjacencyMatrix = logical(eye(size(agents, 1))); obj.constraintAdjacencyMatrix = logical(eye(size(agents, 1)));
% Set labels for agents and collision geometries in cases where they % Set labels for agents and collision geometries in cases where they
% were not provieded at the time of their initialization % were not provieded at the time of their initialization.
% Guarded by coder.target: label is a fixed-size "" in codegen, and
% sprintf returns variable-length incompatible even in a dead branch.
% On the compiled path agents always receive explicit labels from the caller.
if coder.target('MATLAB')
for ii = 1:size(obj.agents, 1) for ii = 1:size(obj.agents, 1)
% Agent
if isempty(char(obj.agents{ii}.label)) if isempty(char(obj.agents{ii}.label))
obj.agents{ii}.label = sprintf("Agent %d", int8(ii)); obj.agents{ii}.label = sprintf("Agent %d", int8(ii));
end end
% Collision geometry
if isempty(char(obj.agents{ii}.collisionGeometry.label)) if isempty(char(obj.agents{ii}.collisionGeometry.label))
obj.agents{ii}.collisionGeometry.label = sprintf("Agent %d Collision Geometry", int8(ii)); obj.agents{ii}.collisionGeometry.label = sprintf("Agent %d Collision Geometry", int8(ii));
end end
end end
end
% Set CBF parameters % Set CBF parameters
obj.barrierGain = barrierGain; obj.barrierGain = barrierGain;
+1 -1
View File
@@ -1,2 +1,2 @@
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
1, 100, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 80.0", "0.25, 0.25", "8.0, 8.0", "0.1, 0.1", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "66.6, 66.6", "55, 35, 35, 55", 0.15, "15.0, 15.0, 50.0, 40.0, 15.0, 50.0", 1, "0.0, 35.0, 0.0", "50, 40.0, 60", 1, 2.0, 1 1, 80, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "60.0, 80.0, 45.0, 70.0", "70, 15, 15, 20, 20, 15, 15, 70", 0.15, "15.0, 15.0, 50.0, 40.0, 10.0, 45.0", 8, "0.0, 30.0, 0.0, 42.0, 30.0, 0.0, 84.0, 30.0, 0.0, 13.0, 60.0, 0.0, 55.0, 60.0, 0.0, 0.0, 90, 0.0, 42.0, 90.0, 0.0, 84.0, 90.0, 0.0", "16.0, 40.0, 100.0, 58.0, 40.0, 100.0, 100.0, 40.0, 100.0, 29.0, 70.0, 100.0, 71.0, 70.0, 100.0, 16.0, 100.0, 100.0, 58.0, 100.0, 100.0, 100.0, 100.0, 100.0", 0, 2.0, 1
1 timestep maxIter minAlt discretizationStep protectedRange initialStepSize barrierGain barrierExponent collisionRadius comRange alphaDist betaDist alphaTilt betaTilt domainMin domainMax objectivePos objectiveVar sensorPerformanceMinimum initialPositions numObstacles obstacleMin obstacleMax useDoubleIntegrator dampingCoeff useFixedTopology
2 1 100 80 35.0 0.1 2.0 6 1 1 8.0, 8.0 35.0, 35.0 80.0, 80.0 80.0, 50.0 0.25, 0.25 0.25, 1.0 8.0, 8.0 8.0, 25.0 0.1, 0.1 0.1, 0.02 0.0, 0.0, 0.0 100.0, 100.0, 100.0 66.6, 66.6 60.0, 80.0, 45.0, 70.0 55, 35, 35, 55 70, 15, 15, 20, 20, 15, 15, 70 0.15 15.0, 15.0, 50.0, 40.0, 15.0, 50.0 15.0, 15.0, 50.0, 40.0, 10.0, 45.0 1 8 0.0, 35.0, 0.0 0.0, 30.0, 0.0, 42.0, 30.0, 0.0, 84.0, 30.0, 0.0, 13.0, 60.0, 0.0, 55.0, 60.0, 0.0, 0.0, 90, 0.0, 42.0, 90.0, 0.0, 84.0, 90.0, 0.0 50, 40.0, 60 16.0, 40.0, 100.0, 58.0, 40.0, 100.0, 100.0, 40.0, 100.0, 29.0, 70.0, 100.0, 71.0, 70.0, 100.0, 16.0, 100.0, 100.0, 58.0, 100.0, 100.0, 100.0, 100.0, 100.0 1 0 2.0 1
+1 -1
View File
@@ -1,2 +1,2 @@
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
1, 50, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "60.0, 80.0, 45.0, 70.0", "70, 15, 15, 20, 20, 15, 15, 70", 0.15, "10.0, 10.0, 50.0, 40.0, 15.0, 45.0", 8, "0.0, 30.0, 0.0, 42.0, 30.0, 0.0, 84.0, 30.0, 0.0, 13.0, 60.0, 0.0, 55.0, 60.0, 0.0, 0.0, 90, 0.0, 42.0, 90.0, 0.0, 84.0, 90.0, 0.0", "16.0, 40.0, 100.0, 58.0, 40.0, 100.0, 100.0, 40.0, 100.0, 29.0, 70.0, 100.0, 71.0, 70.0, 100.0, 16.0, 100.0, 100.0, 58.0, 100.0, 100.0, 100.0, 100.0, 100.0", 0, 2.0, 1 1, 80, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "60.0, 80.0, 45.0, 70.0", "70, 15, 15, 20, 20, 15, 15, 70", 0.15, "15.0, 15.0, 50.0, 40.0, 10.0, 45.0", 8, "0.0, 30.0, 0.0, 42.0, 30.0, 0.0, 84.0, 30.0, 0.0, 13.0, 60.0, 0.0, 55.0, 60.0, 0.0, 0.0, 90, 0.0, 42.0, 90.0, 0.0, 84.0, 90.0, 0.0", "16.0, 40.0, 100.0, 58.0, 40.0, 100.0, 100.0, 40.0, 100.0, 29.0, 70.0, 100.0, 71.0, 70.0, 100.0, 16.0, 100.0, 100.0, 58.0, 100.0, 100.0, 100.0, 100.0, 100.0", 0, 2.0, 1
1 timestep maxIter minAlt discretizationStep protectedRange initialStepSize barrierGain barrierExponent collisionRadius comRange alphaDist betaDist alphaTilt betaTilt domainMin domainMax objectivePos objectiveVar sensorPerformanceMinimum initialPositions numObstacles obstacleMin obstacleMax useDoubleIntegrator dampingCoeff useFixedTopology
2 1 50 80 35.0 0.1 2.0 6 1 1 8.0, 8.0 35.0, 35.0 80.0, 50.0 0.25, 1.0 8.0, 25.0 0.1, 0.02 0.0, 0.0, 0.0 100.0, 100.0, 100.0 60.0, 80.0, 45.0, 70.0 70, 15, 15, 20, 20, 15, 15, 70 0.15 10.0, 10.0, 50.0, 40.0, 15.0, 45.0 15.0, 15.0, 50.0, 40.0, 10.0, 45.0 8 0.0, 30.0, 0.0, 42.0, 30.0, 0.0, 84.0, 30.0, 0.0, 13.0, 60.0, 0.0, 55.0, 60.0, 0.0, 0.0, 90, 0.0, 42.0, 90.0, 0.0, 84.0, 90.0, 0.0 16.0, 40.0, 100.0, 58.0, 40.0, 100.0, 100.0, 40.0, 100.0, 29.0, 70.0, 100.0, 71.0, 70.0, 100.0, 16.0, 100.0, 100.0, 58.0, 100.0, 100.0, 100.0, 100.0, 100.0 0 2.0 1
+1 -1
View File
@@ -1,2 +1,2 @@
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
1, 65, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "30.0, 80.0", "60, 20, 20, 30", 0.15, "65.0, 15.0, 65.0, 65.0, 15.0, 45.0", 3, "0.0, 25.0, 55.0, 40.0, 10.0, 0.0, 40.0, 45.0, 60.0", "100.0, 70.0, 60.0, 45.0, 80.0, 55.0, 100.0, 50.0, 100.0", 0, 2.0, 1 1, 125, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "30.0, 80.0", "60, 20, 20, 30", 0.15, "65.0, 15.0, 65.0, 65.0, 15.0, 45.0", 3, "0.0, 25.0, 55.0, 40.0, 10.0, 0.0, 40.0, 45.0, 60.0", "100.0, 70.0, 60.0, 45.0, 80.0, 55.0, 100.0, 50.0, 100.0", 0, 2.0, 1
1 timestep maxIter minAlt discretizationStep protectedRange initialStepSize barrierGain barrierExponent collisionRadius comRange alphaDist betaDist alphaTilt betaTilt domainMin domainMax objectivePos objectiveVar sensorPerformanceMinimum initialPositions numObstacles obstacleMin obstacleMax useDoubleIntegrator dampingCoeff useFixedTopology
2 1 65 125 35.0 0.1 2.0 6 1 1 8.0, 8.0 35.0, 35.0 80.0, 50.0 0.25, 1.0 8.0, 25.0 0.1, 0.02 0.0, 0.0, 0.0 100.0, 100.0, 100.0 30.0, 80.0 60, 20, 20, 30 0.15 65.0, 15.0, 65.0, 65.0, 15.0, 45.0 3 0.0, 25.0, 55.0, 40.0, 10.0, 0.0, 40.0, 45.0, 60.0 100.0, 70.0, 60.0, 45.0, 80.0, 55.0, 100.0, 50.0, 100.0 0 2.0 1
+1 -1
View File
@@ -1,2 +1,2 @@
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
1, 65, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "30.0, 80.0", "60, 20, 20, 30", 0.15, "90.0, 10.0, 50.0, 65.0, 15.0, 45.0", 4, "0.0, 30.0, 0.0, 70.0, 30.0, 0.0, 0.0, 60.0, 0.0, 55.0, 60.0, 0.0", "50.0, 40.0, 100.0, 100.0, 40.0, 100.0, 35.0, 70.0, 100.0, 100.0, 70.0, 100.0", 0, 2.0, 1 1, 125, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "30.0, 80.0", "60, 20, 20, 30", 0.15, "90.0, 10.0, 50.0, 65.0, 15.0, 45.0", 4, "0.0, 30.0, 0.0, 70.0, 30.0, 0.0, 0.0, 60.0, 0.0, 55.0, 60.0, 0.0", "50.0, 40.0, 100.0, 100.0, 40.0, 100.0, 35.0, 70.0, 100.0, 100.0, 70.0, 100.0", 0, 2.0, 1
1 timestep maxIter minAlt discretizationStep protectedRange initialStepSize barrierGain barrierExponent collisionRadius comRange alphaDist betaDist alphaTilt betaTilt domainMin domainMax objectivePos objectiveVar sensorPerformanceMinimum initialPositions numObstacles obstacleMin obstacleMax useDoubleIntegrator dampingCoeff useFixedTopology
2 1 65 125 35.0 0.1 2.0 6 1 1 8.0, 8.0 35.0, 35.0 80.0, 50.0 0.25, 1.0 8.0, 25.0 0.1, 0.02 0.0, 0.0, 0.0 100.0, 100.0, 100.0 30.0, 80.0 60, 20, 20, 30 0.15 90.0, 10.0, 50.0, 65.0, 15.0, 45.0 4 0.0, 30.0, 0.0, 70.0, 30.0, 0.0, 0.0, 60.0, 0.0, 55.0, 60.0, 0.0 50.0, 40.0, 100.0, 100.0, 40.0, 100.0, 35.0, 70.0, 100.0, 100.0, 70.0, 100.0 0 2.0 1
+102 -40
View File
@@ -7,54 +7,43 @@ coder.extrinsic('disp', 'readScenarioCsv');
% Maximum clients supported (one initial position per UAV) % Maximum clients supported (one initial position per UAV)
MAX_CLIENTS = 4; MAX_CLIENTS = 4;
% Two waypoints per UAV: altitude-staggered transit + final position % Three waypoints per UAV: one axis-aligned move per dimension (taxicab flyout/flyback)
MAX_TARGETS = MAX_CLIENTS * 2; MAX_TARGETS = MAX_CLIENTS * 3;
% Taxicab flyout/flyback only supports exactly 2 UAVs
if numClients ~= int32(2)
error('Taxicab flyout/flyback requires exactly 2 UAVs');
end
% Allocate targets array (MAX_TARGETS x 3) % Allocate targets array (MAX_TARGETS x 3)
targets = zeros(MAX_TARGETS, 3); targets = zeros(MAX_TARGETS, 3);
numWaypoints = int32(0); numWaypoints = int32(0);
totalLoaded = int32(0); % pre-declare type for coder.ceval %#ok<NASGU> totalLoaded = int32(0); % pre-declare type for coder.ceval %#ok<NASGU>
% Load initial UAV positions from scenario CSV % Experiment start positions from scenario CSV (N x 3)
scenarioPositions = zeros(MAX_CLIENTS, 3);
% Load experiment start positions from scenario CSV
if coder.target('MATLAB') if coder.target('MATLAB')
disp('Loading initial positions from scenario.csv (simulation)...'); disp('Loading initial positions from scenario.csv (simulation)...');
tmpSim = miSim; tmpSim = miSim;
sc = tmpSim.readScenarioCsv('aerpaw/config/scenario.csv'); sc = tmpSim.readScenarioCsv('aerpaw/config/scenario.csv');
flatPos = double(sc.initialPositions); % 1×(3*N) flat vector flatPos = double(sc.initialPositions); % 1×(3*N) flat vector
posMatrix = reshape(flatPos, 3, [])'; % N×3, same layout as initializeFromCsv posMatrix = reshape(flatPos, 3, [])'; % N×3
totalLoaded = int32(size(posMatrix, 1)); totalLoaded = int32(size(posMatrix, 1));
scenarioPositions(1:totalLoaded, :) = posMatrix;
% MATLAB path: send directly to scenario positions in one waypoint
targets(1:totalLoaded, :) = posMatrix; targets(1:totalLoaded, :) = posMatrix;
numWaypoints = int32(1); numWaypoints = int32(1);
disp(['Loaded ', num2str(double(totalLoaded)), ' initial positions']); disp(['Loaded ', num2str(double(totalLoaded)), ' initial positions']);
else else
coder.cinclude('controller_impl.h'); coder.cinclude('controller_impl.h');
filename = ['config/scenario.csv', char(0)]; filename = ['config/scenario.csv', char(0)];
% Load into targets temporarily; copy to scenarioPositions below
totalLoaded = coder.ceval('loadInitialPositions', coder.ref(filename), ... totalLoaded = coder.ceval('loadInitialPositions', coder.ref(filename), ...
coder.ref(targets), int32(MAX_TARGETS)); coder.ref(targets), int32(MAX_TARGETS));
numWaypoints = totalLoaded / int32(numClients); scenarioPositions(1:totalLoaded, :) = targets(1:totalLoaded, :);
end numWaypoints = int32(3);
% In the compiled path, inject altitude-staggered transit waypoints so UAVs
% are vertically separated while flying horizontally to their start positions.
% ArduPilot reaches target altitude before horizontal movement, so UAV i is at
% altitude (TRANSIT_ALT_BASE + (i-1)*TRANSIT_ALT_STEP) throughout its transit,
% preventing collisions regardless of horizontal path geometry.
% TRANSIT_ALT_STEP must exceed 2 * max(collisionRadius).
% Waypoint 1: each UAV flies to (finalX, finalY) at its unique transit altitude.
% Waypoint 2: each UAV adjusts to its actual target altitude.
% These constants are also used for the altitude-staggered return before RTL.
TRANSIT_ALT_BASE = 25.0; % must match drone.takeoff() altitude in uav_runner.py
TRANSIT_ALT_STEP = 25; % vertical separation per UAV (m); must exceed 2*collisionRadius
if ~coder.target('MATLAB')
for ii = double(totalLoaded):-1:1
transitRow = (ii - 1) * 2 + 1;
finalRow = (ii - 1) * 2 + 2;
finalPos = targets(ii, :);
transitAlt = TRANSIT_ALT_BASE + (ii - 1) * TRANSIT_ALT_STEP;
targets(finalRow, :) = finalPos;
targets(transitRow, :) = [finalPos(1), finalPos(2), transitAlt];
end
numWaypoints = int32(2);
end end
% Load guidance scenario from CSV (parameters for guidance_step) % Load guidance scenario from CSV (parameters for guidance_step)
@@ -92,6 +81,46 @@ for i = 1:numClients
end end
end end
% Query takeoff-pad GPS positions before sending any waypoints.
% These are also the flyback targets so each UAV lands where it took off.
initialPositions = zeros(MAX_CLIENTS, 3);
if ~coder.target('MATLAB')
coder.ceval('sendRequestPositions', int32(numClients));
coder.ceval('recvPositions', int32(numClients), coder.ref(initialPositions), int32(MAX_CLIENTS));
else
% Simulation: treat scenario positions as the takeoff locations
initialPositions(1:totalLoaded, :) = scenarioPositions(1:totalLoaded, :);
end
% ---- Build taxicab flyout waypoints ------------------------------------------
% Determine which UAV has the higher final altitude; it moves Z first so it
% clears vertical separation before the lower UAV converges on the same X/Y.
% Higher UAV order: Z Y X
% Lower UAV order: X Y Z
if ~coder.target('MATLAB')
if scenarioPositions(1, 3) >= scenarioPositions(2, 3)
higherIdx = int32(1);
lowerIdx = int32(2);
else
higherIdx = int32(2);
lowerIdx = int32(1);
end
hBase = double(higherIdx - 1) * double(numWaypoints);
lBase = double(lowerIdx - 1) * double(numWaypoints);
% Higher UAV: Z first
targets(hBase + 1, :) = [initialPositions(higherIdx,1), initialPositions(higherIdx,2), scenarioPositions(higherIdx,3)];
targets(hBase + 2, :) = [initialPositions(higherIdx,1), scenarioPositions(higherIdx,2), scenarioPositions(higherIdx,3)];
targets(hBase + 3, :) = scenarioPositions(higherIdx, :);
% Lower UAV: X first
targets(lBase + 1, :) = [scenarioPositions(lowerIdx,1), initialPositions(lowerIdx,2), initialPositions(lowerIdx,3)];
targets(lBase + 2, :) = [scenarioPositions(lowerIdx,1), scenarioPositions(lowerIdx,2), initialPositions(lowerIdx,3)];
targets(lBase + 3, :) = scenarioPositions(lowerIdx, :);
end
% ------------------------------------------------------------------------------
% Waypoint loop: send each waypoint to all clients, wait for all to arrive % Waypoint loop: send each waypoint to all clients, wait for all to arrive
for w = 1:numWaypoints for w = 1:numWaypoints
% Send TARGET for waypoint w to each client % Send TARGET for waypoint w to each client
@@ -127,8 +156,13 @@ for w = 1:numWaypoints
end end
% ---- Phase 2: miSim guidance loop ---------------------------------------- % ---- Phase 2: miSim guidance loop ----------------------------------------
% Guidance parameters (adjust here and recompile as needed) % Number of guidance steps comes from maxIter in scenario.csv (scenarioParams(2))
MAX_GUIDANCE_STEPS = int32(100); % number of guidance iterations % so the controller and the agent step-decay schedule stay in sync.
if coder.target('MATLAB')
MAX_GUIDANCE_STEPS = int32(sc.maxIter);
else
MAX_GUIDANCE_STEPS = int32(scenarioParams(2));
end
% Enter guidance mode on all clients % Enter guidance mode on all clients
if ~coder.target('MATLAB') if ~coder.target('MATLAB')
@@ -141,8 +175,8 @@ if ~coder.target('MATLAB')
coder.ceval('sendRequestPositions', int32(numClients)); coder.ceval('sendRequestPositions', int32(numClients));
coder.ceval('recvPositions', int32(numClients), coder.ref(positions), int32(MAX_CLIENTS)); coder.ceval('recvPositions', int32(numClients), coder.ref(positions), int32(MAX_CLIENTS));
else else
% Simulation: seed positions from CSV waypoints so agents don't start at origin % Simulation: seed positions from scenario positions so agents don't start at origin
positions(1:totalLoaded, :) = targets(1:totalLoaded, :); positions(1:totalLoaded, :) = scenarioPositions(1:totalLoaded, :);
end end
guidance_step(positions(1:numClients, :), true, ... guidance_step(positions(1:numClients, :), true, ...
scenarioParams, obstacleMin, obstacleMax, numObstacles); scenarioParams, obstacleMin, obstacleMax, numObstacles);
@@ -197,20 +231,48 @@ if ~coder.target('MATLAB')
end end
% -------------------------------------------------------------------------- % --------------------------------------------------------------------------
% Altitude-staggered return: separate UAVs vertically before issuing RTL, % ---- Taxicab flyback: return each UAV to its takeoff-pad position ---------
% mirroring the initial positioning stagger so UAVs transit laterally at % The UAV that ended guidance at the higher altitude moves Z last (X Y Z)
% unique altitudes and cannot collide during the return flight. % so it stays high while the lower UAV descends first, maintaining separation
% as both converge back on their respective home X/Y positions.
NUM_RETURN_WP = int32(3);
returnTargets = zeros(MAX_TARGETS, 3);
if ~coder.target('MATLAB') if ~coder.target('MATLAB')
if positions(1, 3) >= positions(2, 3)
higherRetIdx = int32(1);
lowerRetIdx = int32(2);
else
higherRetIdx = int32(2);
lowerRetIdx = int32(1);
end
hRetBase = double(higherRetIdx - 1) * double(NUM_RETURN_WP);
lRetBase = double(lowerRetIdx - 1) * double(NUM_RETURN_WP);
% Higher post-guidance UAV: X Y Z (descend last)
returnTargets(hRetBase + 1, :) = [initialPositions(higherRetIdx,1), positions(higherRetIdx,2), positions(higherRetIdx,3)];
returnTargets(hRetBase + 2, :) = [initialPositions(higherRetIdx,1), initialPositions(higherRetIdx,2), positions(higherRetIdx,3)];
returnTargets(hRetBase + 3, :) = initialPositions(higherRetIdx, :);
% Lower post-guidance UAV: Z Y X (descend first)
returnTargets(lRetBase + 1, :) = [positions(lowerRetIdx,1), positions(lowerRetIdx,2), initialPositions(lowerRetIdx,3)];
returnTargets(lRetBase + 2, :) = [positions(lowerRetIdx,1), initialPositions(lowerRetIdx,2), initialPositions(lowerRetIdx,3)];
returnTargets(lRetBase + 3, :) = initialPositions(lowerRetIdx, :);
for w = 1:NUM_RETURN_WP
for i = 1:numClients for i = 1:numClients
transitAlt = TRANSIT_ALT_BASE + (double(i) - 1) * TRANSIT_ALT_STEP; retIdx = double(i - 1) * double(NUM_RETURN_WP) + w;
target = [positions(i, 1), positions(i, 2), transitAlt]; retTarget = returnTargets(retIdx, :);
coder.ceval('sendTarget', int32(i), coder.ref(target)); coder.ceval('sendTarget', int32(i), coder.ref(retTarget));
end end
coder.ceval('waitForAllMessageType', int32(numClients), int32(MESSAGE_TYPE.ACK)); coder.ceval('waitForAllMessageType', int32(numClients), int32(MESSAGE_TYPE.ACK));
coder.ceval('waitForAllMessageType', int32(numClients), int32(MESSAGE_TYPE.READY)); coder.ceval('waitForAllMessageType', int32(numClients), int32(MESSAGE_TYPE.READY));
else
disp('Altitude-staggered return (simulation): UAVs commanded to transit altitudes.');
end end
else
disp('Taxicab return (simulation): UAVs commanded back to takeoff positions.');
end
% --------------------------------------------------------------------------
% Send RTL command to all clients % Send RTL command to all clients
for i = 1:numClients for i = 1:numClients
+1
View File
@@ -13,6 +13,7 @@ function f = objectiveFunctionWrapper(center, sigma)
if size(sigma, 1) == 1 && size(center, 1) > 1 if size(sigma, 1) == 1 && size(center, 1) > 1
sigma = repmat(sigma, size(center, 1), 1, 1); sigma = repmat(sigma, size(center, 1), 1, 1);
end end
assert(size(center, 1) == size(sigma, 1)); assert(size(center, 1) == size(sigma, 1));
f = @(x,y) sum(cell2mat(arrayfun(@(i) mvnpdf([x(:), y(:)], center(i,:), squeeze(sigma(i, :, :))), 1:size(center,1), "UniformOutput", false)), 2); f = @(x,y) sum(cell2mat(arrayfun(@(i) mvnpdf([x(:), y(:)], center(i,:), squeeze(sigma(i, :, :))), 1:size(center,1), "UniformOutput", false)), 2);
end end