better routing solution
This commit is contained in:
1 parent
56cc4fced5
commit
37598479cc
10 files changed
+469
-66
No files matched your search
+16
-2
@@ -1,4 +1,4 @@
|
||||
function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo, useDoubleIntegrator, dampingCoeff, useFixedTopology, optimizeSensorPointing, useSinrComms, sinrThreshold, pathLossExponent, ambientTemp, centerFreq, bandwidth)
|
||||
function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo, useDoubleIntegrator, dampingCoeff, useFixedTopology, optimizeSensorPointing, useSinrComms, sinrThreshold, pathLossExponent, ambientTemp, centerFreq, bandwidth, useRoutingTopology, routingFlowThreshold)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, "miSim")};
|
||||
domain (1, 1) {mustBeGeometry};
|
||||
@@ -21,6 +21,8 @@ function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, m
|
||||
ambientTemp (1, 1) double = 290.0;
|
||||
centerFreq (1, 1) double = 2.4e9;
|
||||
bandwidth (1, 1) double = 20e6;
|
||||
useRoutingTopology (1, 1) logical = false;
|
||||
routingFlowThreshold (1, 1) double = 0.02;
|
||||
end
|
||||
arguments (Output)
|
||||
obj (1, 1) {mustBeA(obj, "miSim")};
|
||||
@@ -112,12 +114,24 @@ function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, m
|
||||
obj.centerFreq = centerFreq;
|
||||
obj.bandwidth = bandwidth;
|
||||
|
||||
% Compute adjacency matrix and network topology
|
||||
% Set topology-selection algorithm and routing parameters
|
||||
obj.useRoutingTopology = useRoutingTopology;
|
||||
obj.routingFlowThreshold = routingFlowThreshold;
|
||||
|
||||
% Compute adjacency matrix and network topology. Lesser-neighbor always
|
||||
% provides the low-level connectivity topology (basic traffic must be
|
||||
% routable between any two drones at all times); routing mode overlays
|
||||
% the bulk-data links on top of it. The routing LP uses linprog (no
|
||||
% codegen support); the compiled path never sets the flag, so linprog
|
||||
% is never compiled.
|
||||
obj = obj.updateAdjacency();
|
||||
if obj.useFixedTopology
|
||||
obj.constraintAdjacencyMatrix = obj.adjacency;
|
||||
else
|
||||
obj = obj.lesserNeighbor();
|
||||
if coder.target('MATLAB') && obj.useRoutingTopology
|
||||
obj = obj.routeTopology();
|
||||
end
|
||||
end
|
||||
|
||||
% Set up times to iterate over
|
||||
|
||||
@@ -147,6 +147,18 @@ else
|
||||
BANDWIDTH = 20e6;
|
||||
end
|
||||
|
||||
% Routing topology selection (optional columns; MATLAB sim only)
|
||||
if isfield(scenario, 'useRoutingTopology')
|
||||
USE_ROUTING_TOPOLOGY = logical(scenario.useRoutingTopology);
|
||||
else
|
||||
USE_ROUTING_TOPOLOGY = false;
|
||||
end
|
||||
if isfield(scenario, 'routingFlowThreshold')
|
||||
ROUTING_FLOW_THRESHOLD = scenario.routingFlowThreshold;
|
||||
else
|
||||
ROUTING_FLOW_THRESHOLD = 0.02;
|
||||
end
|
||||
|
||||
% ---- Build domain --------------------------------------------------------
|
||||
dom = rectangularPrism;
|
||||
dom = dom.initialize([DOMAIN_MIN; DOMAIN_MAX], REGION_TYPE.DOMAIN, "Guidance Domain");
|
||||
@@ -195,6 +207,7 @@ end
|
||||
obj = obj.initialize(dom, agentList, BARRIER_GAIN, BARRIER_EXPONENT, ...
|
||||
MIN_ALT, TIMESTEP, MAX_ITER, obstacleList, false, false, ...
|
||||
USE_DOUBLE_INTEGRATOR, DAMPING_COEFF, USE_FIXED_TOPOLOGY, false, ...
|
||||
USE_SINR_COMMS, SINR_THRESHOLD, PATH_LOSS_EXPONENT, AMBIENT_TEMP, CENTER_FREQ, BANDWIDTH);
|
||||
USE_SINR_COMMS, SINR_THRESHOLD, PATH_LOSS_EXPONENT, AMBIENT_TEMP, CENTER_FREQ, BANDWIDTH, ...
|
||||
USE_ROUTING_TOPOLOGY, ROUTING_FLOW_THRESHOLD);
|
||||
|
||||
end
|
||||
@@ -111,11 +111,22 @@ if isfield(inits, 'bandwidth')
|
||||
else
|
||||
bandwidth = 20e6;
|
||||
end
|
||||
if isfield(inits, 'useRoutingTopology')
|
||||
useRoutingTopology = logical(inits.useRoutingTopology);
|
||||
else
|
||||
useRoutingTopology = false;
|
||||
end
|
||||
if isfield(inits, 'routingFlowThreshold')
|
||||
routingFlowThreshold = inits.routingFlowThreshold;
|
||||
else
|
||||
routingFlowThreshold = 0.02;
|
||||
end
|
||||
|
||||
% ---- Initialize simulation (plots and video disabled) ------------------------
|
||||
obj = obj.initialize(dom, agentList, inits.barrierGain, inits.barrierExponent, ...
|
||||
inits.minAlt, inits.timestep, inits.maxIter, obstacleList, ...
|
||||
false, false, useDoubleIntegrator, dampingCoeff, useFixedTopology, false, ...
|
||||
useSinrComms, sinrThreshold, pathLossExponent, ambientTemp, centerFreq, bandwidth);
|
||||
useSinrComms, sinrThreshold, pathLossExponent, ambientTemp, centerFreq, bandwidth, ...
|
||||
useRoutingTopology, routingFlowThreshold);
|
||||
|
||||
end
|
||||
+10
-1
@@ -30,6 +30,14 @@ classdef miSim
|
||||
ambientTemp = 290.0; % ambient temperature (K) for thermal noise N = k_B*T*B
|
||||
centerFreq = 2.4e9; % carrier frequency (Hz); sets path-loss offset K = (4*pi*f_c/c)^2
|
||||
bandwidth = 20e6; % channel bandwidth (Hz) for thermal noise N = k_B*T*B
|
||||
% Topology-selection algorithm (requires useSinrComms; MATLAB sim only).
|
||||
% false -> lesser-neighbor; true -> min-max-workload LP routing, which
|
||||
% picks the links that route all sensing data to the network endpoints
|
||||
% (agents 1 and the largest odd index) with minimal peak node workload.
|
||||
useRoutingTopology = false;
|
||||
routingFlowThreshold = 0.02; % prune links carrying less flow than this (units of one node's production)
|
||||
routingAdjacencyMatrix = false(0, 0); % directed adjacency chosen by the routing LP: (i, j) = link i -> j
|
||||
routingFlows = zeros(0, 0); % data flow carried by each directed link (units/timestep)
|
||||
artifactName = "";
|
||||
f; % main plotting tiled layout figure
|
||||
fPerf; % performance plot figure
|
||||
@@ -79,12 +87,13 @@ classdef miSim
|
||||
obj.obstacles = {rectangularPrism};
|
||||
obj.agents = {agent};
|
||||
end
|
||||
[obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo, useDoubleIntegrator, dampingCoeff, useFixedTopology, optimizeSensorPointing, useSinrComms, sinrThreshold, pathLossExponent, ambientTemp, centerFreq, bandwidth);
|
||||
[obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo, useDoubleIntegrator, dampingCoeff, useFixedTopology, optimizeSensorPointing, useSinrComms, sinrThreshold, pathLossExponent, ambientTemp, centerFreq, bandwidth, useRoutingTopology, routingFlowThreshold);
|
||||
[obj] = initializeFromCsv(obj, csvPath);
|
||||
[obj] = initializeFromInits(obj, initsPath);
|
||||
[obj] = plotFromSimHist(obj, initsPath, histPath);
|
||||
[obj] = run(obj);
|
||||
[obj] = lesserNeighbor(obj);
|
||||
[obj] = routeTopology(obj);
|
||||
[obj] = constrainMotion(obj);
|
||||
[sinr, grad] = sinrLink(obj, positions, rxIdx, txIdx);
|
||||
[obj] = partition(obj);
|
||||
|
||||
+58
-58
@@ -6,7 +6,12 @@ function obj = plotGraph(obj)
|
||||
obj (1, 1) {mustBeA(obj, "miSim")};
|
||||
end
|
||||
|
||||
nAgents = size(obj.agents, 1);
|
||||
% The maintained (low-level connectivity) links are always drawn as a
|
||||
% dotted undirected graph: basic traffic must be routable between any
|
||||
% two drones at all times. In routing mode the bulk-data links selected
|
||||
% by the LP are overlaid as SOLID DIRECTED edges (arrow = transmitter ->
|
||||
% receiver) on the same node layout.
|
||||
G = graph(obj.constraintAdjacencyMatrix, "omitselfloops");
|
||||
|
||||
% Resolve the target axes for the network graph tile
|
||||
if isnan(obj.networkGraphIndex)
|
||||
@@ -15,72 +20,67 @@ function obj = plotGraph(obj)
|
||||
ax = obj.f.Children(1).Children(obj.networkGraphIndex(1));
|
||||
end
|
||||
|
||||
% Build the graph to plot. The fixed-radius model is undirected. In SINR
|
||||
% mode the link set (lesser-neighbor topology) is kept exactly as-is, but
|
||||
% each connection is given an orientation: of the two directional SINRs on
|
||||
% a link, the larger one wins, and the edge is directed from that
|
||||
% direction's transmitter to its receiver (arrow = transmitter -> receiver).
|
||||
% Plot graph object(s)
|
||||
hold(ax, "on");
|
||||
o = plot(ax, G, "LineStyle", "--", "EdgeColor", "g", "NodeColor", "k", "LineWidth", 2);
|
||||
if obj.useRoutingTopology
|
||||
% Bulk overlay: reuse the base layout's node coordinates and hide
|
||||
% the overlay's own nodes/labels so only its edges show. Sizeable
|
||||
% arrowheads so the flow direction reads at tile size.
|
||||
D = digraph(obj.routingAdjacencyMatrix);
|
||||
o = [o; plot(ax, D, "XData", o(1).XData, "YData", o(1).YData, ...
|
||||
"LineStyle", "-", "EdgeColor", "g", "LineWidth", 2, ...
|
||||
"ArrowSize", 12, "Marker", "none", "NodeLabel", {})];
|
||||
end
|
||||
hold(ax, "off");
|
||||
nBase = size(o, 1);
|
||||
if ~isnan(obj.networkGraphIndex) && size(obj.networkGraphIndex, 2) > 1
|
||||
for ii = 2:size(obj.networkGraphIndex, 2)
|
||||
o = [o; copyobj(o(1:nBase), obj.f.Children(1).Children(obj.networkGraphIndex(ii)))];
|
||||
end
|
||||
end
|
||||
|
||||
% In SINR comms mode, label each edge with the connection's SINR and report
|
||||
% the connectivity threshold in the tile title. The fixed-radius model is
|
||||
% left unchanged (no edge labels, title stays as set in firstPlotSetup).
|
||||
if obj.useSinrComms
|
||||
endNodes = G.Edges.EndNodes;
|
||||
nAgents = size(obj.agents, 1);
|
||||
positions = zeros(nAgents, 3);
|
||||
for kk = 1:nAgents
|
||||
positions(kk, :) = obj.agents{kk}.pos;
|
||||
end
|
||||
D = false(nAgents); % directed adjacency: D(tx, rx) = true
|
||||
for aa = 1:(nAgents - 1)
|
||||
for bb = (aa + 1):nAgents
|
||||
if obj.constraintAdjacencyMatrix(aa, bb)
|
||||
sinrARx = obj.sinrLink(positions, aa, bb); % aa receives bb
|
||||
sinrBRx = obj.sinrLink(positions, bb, aa); % bb receives aa
|
||||
if sinrARx >= sinrBRx
|
||||
D(bb, aa) = true; % better as bb -> aa (tx bb, rx aa)
|
||||
else
|
||||
D(aa, bb) = true; % better as aa -> bb (tx aa, rx bb)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
G = digraph(D);
|
||||
else
|
||||
G = graph(obj.constraintAdjacencyMatrix, "omitselfloops");
|
||||
end
|
||||
|
||||
% Plot graph object (digraph renders arrowheads automatically)
|
||||
hold(ax, "on");
|
||||
o = plot(ax, G, "LineStyle", "--", "EdgeColor", "g", "NodeColor", "k", "LineWidth", 2);
|
||||
hold(ax, "off");
|
||||
if ~isnan(obj.networkGraphIndex) && size(obj.networkGraphIndex, 2) > 1
|
||||
for ii = 2:size(obj.networkGraphIndex, 2)
|
||||
o = [o; copyobj(o(1), obj.f.Children(1).Children(obj.networkGraphIndex(ii)))];
|
||||
end
|
||||
end
|
||||
|
||||
% Mark ground-station-connected nodes with an "x" (others keep the default
|
||||
% dot). Ground stations attach to the two "router" agents: agent 1 and the
|
||||
% agent with the largest ODD index (that is nAgents when odd, else
|
||||
% nAgents-1). With one or two agents only agent 1 qualifies.
|
||||
routers = unique([1, 2 * ceil(nAgents / 2) - 1]);
|
||||
for oo = 1:numel(o)
|
||||
highlight(o(oo), routers, "Marker", "x", "MarkerSize", 8);
|
||||
end
|
||||
|
||||
% In SINR comms mode, label each directed edge with the better SINR that set
|
||||
% its orientation and report the threshold in the tile title. The
|
||||
% fixed-radius model is left unchanged (no edge labels, title from setup).
|
||||
if obj.useSinrComms
|
||||
endNodes = G.Edges.EndNodes; % each row [tx rx] for a directed edge
|
||||
% Label with the SINR of the chosen (better) direction: the receiver is
|
||||
% the edge target, the transmitter the edge source. Bare numbers (no
|
||||
% units) keep the small tile uncluttered; GraphPlot draws labels
|
||||
% horizontally, left-to-right.
|
||||
% Labels are bare numbers (no units) so they stay compact; GraphPlot
|
||||
% renders them horizontally, left-to-right. Dotted (low-level) edges
|
||||
% are labelled with the binding (worse) directional SINR — a link is
|
||||
% feasible only if BOTH directions clear the threshold. Links that
|
||||
% also carry a bulk overlay leave the label to the solid edge, which
|
||||
% shows the SINR of the transmission direction.
|
||||
edgeLabels = strings(size(endNodes, 1), 1);
|
||||
for ee = 1:size(endNodes, 1)
|
||||
sinrLin = obj.sinrLink(positions, endNodes(ee, 2), endNodes(ee, 1)); % rx, tx
|
||||
edgeLabels(ee) = sprintf("%.1f", 10 * log10(sinrLin));
|
||||
lo = endNodes(ee, 1);
|
||||
hi = endNodes(ee, 2);
|
||||
if obj.useRoutingTopology && (obj.routingAdjacencyMatrix(lo, hi) || obj.routingAdjacencyMatrix(hi, lo))
|
||||
edgeLabels(ee) = ""; % solid overlay carries this link's label
|
||||
else
|
||||
sinrLoRx = obj.sinrLink(positions, lo, hi); % receiver lo (lower index)
|
||||
sinrHiRx = obj.sinrLink(positions, hi, lo); % receiver hi (higher index)
|
||||
edgeLabels(ee) = sprintf("%.1f", 10 * log10(min(sinrLoRx, sinrHiRx)));
|
||||
end
|
||||
end
|
||||
o(1).EdgeLabel = edgeLabels;
|
||||
% Threshold in the existing single-line title (not a subtitle) so the
|
||||
% small tile isn't compressed, and disable the hover toolbar so the
|
||||
% R2026 "..." menu stops covering the readout.
|
||||
if obj.useRoutingTopology
|
||||
endNodesD = D.Edges.EndNodes; % each row [tx rx]
|
||||
bulkLabels = strings(size(endNodesD, 1), 1);
|
||||
for ee = 1:size(endNodesD, 1)
|
||||
sinrTx = obj.sinrLink(positions, endNodesD(ee, 2), endNodesD(ee, 1)); % rx, tx
|
||||
bulkLabels(ee) = sprintf("%.1f", 10 * log10(sinrTx));
|
||||
end
|
||||
o(2).EdgeLabel = bulkLabels;
|
||||
end
|
||||
% Threshold goes in the existing single-line title (not a subtitle) so
|
||||
% the small tile is not compressed further, and the hover toolbar is
|
||||
% disabled so the R2026 "..." menu stops covering the readout.
|
||||
title(ax, sprintf("Network Graph (\\geq %.1f dB)", obj.sinrThreshold));
|
||||
ax.Toolbar.Visible = "off";
|
||||
end
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
function obj = routeTopology(obj)
|
||||
% ROUTETOPOLOGY Select the network topology by solving a min-max-workload
|
||||
% routing LP (alternative to the lesser-neighbor algorithm).
|
||||
%
|
||||
% Every agent produces one unit of sensing data per timestep, all of which
|
||||
% must reach one of the network endpoints (agents 1 and the largest odd
|
||||
% index), which output data off-network for free (bottomless sinks). Data
|
||||
% may split across paths, but relayed data accumulates at intermediate
|
||||
% nodes, so each node experiences a workload: the share of a timestep it
|
||||
% spends transmitting and receiving, with per-link effort flow/capacity and
|
||||
% Shannon capacity c = log2(1 + SINR). The LP minimizes the maximum
|
||||
% workload over all nodes, since the busiest node bounds system capacity.
|
||||
%
|
||||
% Candidate links are the threshold-feasible pairs in obj.adjacency (both
|
||||
% directional SINRs clear sinrThreshold, per updateAdjacency). After the
|
||||
% first solve, links carrying negligible flow (< routingFlowThreshold) are
|
||||
% disallowed and the LP is re-solved so they cannot reappear: feasible but
|
||||
% impractical links add system complexity for very little gain.
|
||||
%
|
||||
% The routed links are a HIGH-QUALITY OVERLAY on top of the low-level
|
||||
% connectivity topology, not a replacement for it: basic command/telemetry
|
||||
% traffic must always be routable between any two drones, so the caller
|
||||
% runs lesserNeighbor first and this method ORs the bulk links into the
|
||||
% maintained set. Both tiers are held above threshold by the CBF.
|
||||
%
|
||||
% Outputs (set on obj):
|
||||
% routingAdjacencyMatrix directed adjacency, (i, j) = bulk link i -> j
|
||||
% routingFlows flow carried by each directed link
|
||||
% constraintAdjacencyMatrix existing (lesser-neighbor) links OR the
|
||||
% symmetrized routed links (the CBF maintains
|
||||
% both directions of every link)
|
||||
%
|
||||
% Uses linprog (Optimization Toolbox): MATLAB simulation only, no codegen.
|
||||
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, "miSim")};
|
||||
end
|
||||
arguments (Output)
|
||||
obj (1, 1) {mustBeA(obj, "miSim")};
|
||||
end
|
||||
|
||||
nAgents = size(obj.agents, 1);
|
||||
|
||||
% Network endpoints: agent 1 and the largest ODD index (nAgents when
|
||||
% odd, nAgents-1 when even); with one or two agents only agent 1.
|
||||
endpoints = unique([1, 2 * ceil(nAgents / 2) - 1]);
|
||||
isEndpoint = false(1, nAgents);
|
||||
isEndpoint(endpoints) = true;
|
||||
|
||||
% Trivial network: every node is an endpoint, no bulk routing needed
|
||||
% (the lesser-neighbor constraint topology is left untouched)
|
||||
if all(isEndpoint)
|
||||
obj.routingAdjacencyMatrix = false(nAgents);
|
||||
obj.routingFlows = zeros(nAgents);
|
||||
return;
|
||||
end
|
||||
|
||||
positions = zeros(nAgents, 3);
|
||||
for kk = 1:nAgents
|
||||
positions(kk, :) = obj.agents{kk}.pos;
|
||||
end
|
||||
|
||||
% Candidate directed links: threshold-feasible pairs, excluding
|
||||
% endpoint-sourced links (endpoints only sink; allowing them to
|
||||
% transmit only enables useless cycles). Capacity is the Shannon
|
||||
% spectral efficiency of the transmission direction.
|
||||
src = zeros(nAgents^2, 1);
|
||||
dst = zeros(nAgents^2, 1);
|
||||
cap = zeros(nAgents^2, 1);
|
||||
nE = 0;
|
||||
for ii = 1:nAgents
|
||||
if isEndpoint(ii)
|
||||
continue;
|
||||
end
|
||||
for jj = 1:nAgents
|
||||
if jj == ii || ~obj.adjacency(ii, jj)
|
||||
continue;
|
||||
end
|
||||
nE = nE + 1;
|
||||
src(nE) = ii;
|
||||
dst(nE) = jj;
|
||||
cap(nE) = log2(1 + obj.sinrLink(positions, jj, ii)); % tx ii -> rx jj
|
||||
end
|
||||
end
|
||||
src = src(1:nE);
|
||||
dst = dst(1:nE);
|
||||
cap = cap(1:nE);
|
||||
|
||||
% --- LP over x = [f_1 .. f_nE, W] ------------------------------------
|
||||
% min W + eps*sum(f) (eps breaks ties toward sparse, cycle-free flow)
|
||||
% s.t. flow conservation (per non-endpoint i): out(i) - in(i) = 1
|
||||
% workload (per node i): sum(f_out/c) + sum(f_in/c) - W <= 0
|
||||
% f >= 0
|
||||
relays = find(~isEndpoint);
|
||||
nRelays = numel(relays);
|
||||
|
||||
fObj = [1e-6 * ones(nE, 1); 1];
|
||||
|
||||
Aeq = zeros(nRelays, nE + 1);
|
||||
for rr = 1:nRelays
|
||||
Aeq(rr, 1:nE) = double(src == relays(rr))' - double(dst == relays(rr))';
|
||||
end
|
||||
beq = ones(nRelays, 1);
|
||||
|
||||
Aineq = zeros(nAgents, nE + 1);
|
||||
for ii = 1:nAgents
|
||||
Aineq(ii, 1:nE) = (double(src == ii)' + double(dst == ii)') ./ cap';
|
||||
Aineq(ii, nE + 1) = -1;
|
||||
end
|
||||
bineq = zeros(nAgents, 1);
|
||||
|
||||
lb = zeros(nE + 1, 1);
|
||||
options = optimoptions("linprog", "Display", "off");
|
||||
|
||||
[x, ~, exitflag] = linprog(fObj, Aineq, bineq, Aeq, beq, lb, [], options);
|
||||
if exitflag <= 0
|
||||
error("Routing LP infeasible: feasible links cannot route all data to an endpoint");
|
||||
end
|
||||
|
||||
% Prune trivial links and re-solve with them disallowed, so negligible
|
||||
% flows cannot reappear in the final solution
|
||||
ub = inf(nE + 1, 1);
|
||||
ub(x(1:nE) < obj.routingFlowThreshold) = 0;
|
||||
[x, ~, exitflag] = linprog(fObj, Aineq, bineq, Aeq, beq, lb, ub, options);
|
||||
if exitflag <= 0
|
||||
error("Routing LP infeasible after pruning: routingFlowThreshold eliminated links needed to route all data to an endpoint");
|
||||
end
|
||||
|
||||
% Extract the directed topology from the pruned solution
|
||||
flows = x(1:nE);
|
||||
obj.routingFlows = zeros(nAgents);
|
||||
obj.routingAdjacencyMatrix = false(nAgents);
|
||||
for ee = 1:nE
|
||||
if flows(ee) > 1e-9
|
||||
obj.routingFlows(src(ee), dst(ee)) = flows(ee);
|
||||
obj.routingAdjacencyMatrix(src(ee), dst(ee)) = true;
|
||||
end
|
||||
end
|
||||
|
||||
% OR the bulk links into the low-level (lesser-neighbor) constraint
|
||||
% topology already on obj: the CBF maintains both tiers, keeping the
|
||||
% network connected for basic traffic while holding the routed links.
|
||||
% Both directions of every link are maintained (feasibility requires
|
||||
% both to clear the threshold anyway).
|
||||
obj.constraintAdjacencyMatrix = obj.constraintAdjacencyMatrix | obj.routingAdjacencyMatrix | obj.routingAdjacencyMatrix';
|
||||
end
|
||||
+5
-1
@@ -42,9 +42,13 @@ function [obj] = run(obj)
|
||||
% plotting purposes, the real partitioning is done by the agents)
|
||||
[obj.partitioning, obj.agents] = obj.agents{1}.partition(obj.agents, obj.domain.objective);
|
||||
|
||||
% Determine desired communications links
|
||||
% Determine desired communications links: lesser-neighbor gives the
|
||||
% low-level connectivity topology; routing mode overlays bulk links
|
||||
if ~obj.useFixedTopology
|
||||
obj = obj.lesserNeighbor();
|
||||
if coder.target('MATLAB') && obj.useRoutingTopology
|
||||
obj = obj.routeTopology();
|
||||
end
|
||||
end
|
||||
|
||||
% Log constraint adjacency for this timestep
|
||||
|
||||
@@ -5,6 +5,15 @@ function validate(obj)
|
||||
arguments (Output)
|
||||
end
|
||||
|
||||
%% Mode Validators
|
||||
if obj.useRoutingTopology && ~obj.useSinrComms
|
||||
error("Routing topology requires SINR comms mode (useSinrComms)");
|
||||
end
|
||||
|
||||
if obj.useRoutingTopology && obj.useFixedTopology
|
||||
error("useRoutingTopology and useFixedTopology are mutually exclusive topology selectors");
|
||||
end
|
||||
|
||||
%% Communications Network Validators
|
||||
if max(conncomp(graph(obj.adjacency))) ~= 1
|
||||
error("Network is not connected");
|
||||
|
||||
@@ -62,6 +62,7 @@ function writeInits(obj)
|
||||
"useDoubleIntegrator", obj.useDoubleIntegrator, "dampingCoeff", obj.dampingCoeff, "useFixedTopology", obj.useFixedTopology, ...
|
||||
"useSinrComms", obj.useSinrComms, "sinrThreshold", obj.sinrThreshold, "pathLossExponent", obj.pathLossExponent, "ambientTemp", obj.ambientTemp, ...
|
||||
"centerFreq", obj.centerFreq, "bandwidth", obj.bandwidth, "txPower", txPower, ... % SINR comms model parameters
|
||||
"useRoutingTopology", obj.useRoutingTopology, "routingFlowThreshold", obj.routingFlowThreshold, ... % routing topology parameters
|
||||
"tilt", tilt, "azimuth", azimuth, ... % joint sensor parameters
|
||||
"alphaDist", alphaDist, "betaDist", betaDist, "alphaTilt", alphaTilt, "betaTilt", betaTilt, ... % sigmoid sensor parameters
|
||||
"lossExponent", lossExponent, "P_TX", P_TX, "BW", BW, "f_c", f_c, "G_RX_dBi", G_RX_dBi, "beamwidthExponent", beamwidthExponent, ... % RF sensor parameters
|
||||
|
||||
Reference in new issue
Block a user