added collision barrier function and gradient

This commit is contained in:
2025-12-04 18:24:49 -08:00
parent d70781fadc
commit 96c91c3988
4 changed files with 51 additions and 0 deletions

View File

@@ -20,6 +20,8 @@ classdef agent
% Collision % Collision
collisionGeometry; collisionGeometry;
barrierFunction;
dBarrierFunction;
% FOV cone % FOV cone
fovGeometry; fovGeometry;

View File

@@ -9,6 +9,12 @@ function obj = run(obj, domain, partitioning, t)
obj (1, 1) {mustBeA(obj, 'agent')}; obj (1, 1) {mustBeA(obj, 'agent')};
end end
% Update collision barrier function
% first part evaluates to +/-1 if the point is outside/inside the collision geometry
% Second part determines the distance from the point to the boundary of the collision geometry
obj.barrierFunction = @(x) (1 - 2 * obj.collisionGeometry.contains(x)) * obj.collisionGeometry.distance(x); % x is 1x3
obj.dBarrierFunction = @(x) obj.collisionGeometry.distanceGradient(x); % x is 1x3
% Collect objective function values across partition % Collect objective function values across partition
partitionMask = partitioning == obj.index; partitionMask = partitioning == obj.index;
objectiveValues = domain.objective.values(partitionMask); % f(omega) on W_n objectiveValues = domain.objective.values(partitionMask); % f(omega) on W_n

View File

@@ -0,0 +1,42 @@
function g = distanceGradient(obj, pos)
arguments (Input)
obj (1, 1) {mustBeA(obj, 'rectangularPrism')};
pos (:, 3) double;
end
arguments (Output)
g (:, 3) double
end
% find nearest point on surface to query position
q = min(max(pos, obj.minCorner), obj.maxCorner);
% Find distance and direction between pos and q
v = pos - q;
vNorm = norm(v);
% position is outside geometry
if vNorm > 0
% gradient is normalized vector from q to p
g = v / vNorm;
return;
end
% position is on or in geometry
% find distances to each face in each dimension
distances = [pos(1) - obj.minCorner(1), obj.maxCorner(1) - pos(1), pos(2) - obj.minCorner(2), obj.maxCorner(2) - pos(2), pos(3) - obj.minCorner(3), obj.maxCorner(3) - pos(3)];
[~, idx] = min(distances);
% I think there needs to be additional handling here for the
% edge/corner cases, where there are ways to balance or resolve ties
% when two faces are equidistant to the query position
assert(sum(idx) == idx, "Implement edge case handling");
% select gradient that brings us quickest to the nearest face
g = [ 1, 0, 0; ...
-1, 0, 0; ...
0, 1, 0; ...
0, -1, 0; ...
0, 0, 1; ...
0, 0, -1;];
g = g(idx, :);
end

View File

@@ -32,6 +32,7 @@ classdef rectangularPrism
[r ] = random(obj); [r ] = random(obj);
[c ] = contains(obj, pos); [c ] = contains(obj, pos);
[d ] = distance(obj, pos); [d ] = distance(obj, pos);
[g ] = distanceGradient(obj, pos);
[c ] = containsLine(obj, pos1, pos2); [c ] = containsLine(obj, pos1, pos2);
[obj, f] = plotWireframe(obj, ind, f); [obj, f] = plotWireframe(obj, ind, f);
end end