8 properties (GetAccess=public,SetAccess=private,Hidden=false) % Set Hidden=true afterwards
11 biograph_struct =
struct;
14 properties (GetAccess=
protected,SetAccess=
private,Hidden=
false) % Set Hidden=
true afterwards
15 destInternalUnits = {};
16 destInternalInputs = [];
19 properties (GetAccess=
protected,SetAccess=
protected)
20 outputBuffer; % initialized to be a
sink with obj.nOutputs inputs
23 methods (Access=private)
25 function createGraphOrdering(obj)
26 N = numel(obj.internalUnits);
27 % Traverse all internal units sequentially to discover graph structure
29 for i=1:numel(obj.internalUnits)
30 UIDs{i} = obj.internalUnits{i}.ID;
33 dg = logical(sparse(N,N));
36 % tmp = obj.internalUnits{i};
37 %
for j=1:tmp.nOutputs
38 % nextNodeID = obj.internalUnits{i}.nextNodes{j}.ID;
39 for nextNode = obj.internalUnits{i}.nextNodes
40 nextNodeID = nextNode{:}.ID;
41 k = find(cellfun(@(UID)isequal(nextNodeID,UID),UIDs));
43 robolog(
'Something is wrong. Should return just one or zero match. Is it a DAG?',
'ERR');
47 labels{i} = obj.internalUnits{i}.label;
49 obj.biograph_struct.dg = dg;
50 obj.biograph_struct.labels = labels;
52 obj.traversingOrder = graphtopoorder(sparse(dg)); % Doesn
't work for one vertex 59 methods (Access=protected) 61 function exportModule(obj,varargin) 62 if isempty(varargin) % Automatic export 63 vars = evalin('caller
','who
'); % Get variables from the caller 64 vars(strcmp(inputname(1),vars)) = []; % Remove from the export list the module itself 66 % For some reason, the line above doesn't work and we need
68 isunit =
false(size(vars)); % Check which variables inherit after
unit 70 isunit(i) = evalin('caller',['
inherits_from(' vars{i}
',''unit'')']);
72 if ~any(isunit) % If no units found, show a warning
73 robolog(
'Module does not enclose any unit. To manually export module use exportModule(obj,unit1,unit2,...).',
'WRN');
74 else % If there are units to export, call exportModule with appropriate arguments
75 evalin(
'caller',[
'exportModule(obj,' strjoin(vars(isunit)
',',
') ');
']); 77 else % Manual export / second call of automatic export 78 if all(cellfun(@(o)inherits_from(o,'unit'),varargin)) 79 obj.internalUnits = varargin; 81 createGraphOrdering(obj); 85 function connectInputs(obj,destInternalUnits,destInternalInputs) 86 %make sure destination array is cell array 87 if ~iscell(destInternalUnits) 88 destInternalUnits = mat2cell(destInternalUnits(:), ones(1, numel(destInternalUnits)), 1); 90 %make sure destination inputs make sense 91 if ~isnumeric(destInternalInputs)||~isvector(destInternalInputs) 92 robolog('Destination inputs must be specified as a vector of integers.
', 'ERR
'); 94 %check that numbers add up 95 if numel(destInternalUnits)~=obj.nInputs 96 robolog('Number of external connections must be equal to the number of inputs. %s has %d inputs; %d destination units were specified
', 'ERR
', obj.label, obj.nInputs, numel(destInternalUnits)); 98 obj.destInternalUnits = destInternalUnits; 99 obj.destInternalInputs = destInternalInputs; 102 % function connectInternalOutputs(obj,srcInternalUnits,destExternalOutputs) 103 % %TODO error checking, etc. 104 % for i=1:obj.nOutputs 105 % srcInternalUnits{i}.connectOutput(obj.outputBuffer,i,destExternalOutputs(i)); 112 methods (Access=public) 114 function obj = module 115 % Create sink for internal output buffers 116 obj.outputBuffer = sink(obj.nOutputs); 120 module_view(obj.biograph_struct,obj.internalUnits,obj.label); 123 function output = getOutput(obj) 124 output = obj.outputBuffer.inputBuffer{1}; 127 function keepOutput(obj) 128 obj.outputBuffer.setKeep(1); 131 function varargout = traverse(obj,varargin) 132 % Rewrite internal buffers to appropriate objects 134 %FIXME when there's only one obj.destInternalUnits it must
135 %be also packaged into cell array. Otherwise
this line will
136 %fail with
"Cell contents reference from a non-cell array 138 % Ensure that in a call obj.connectInputs(units,no) units
139 % is always a cell array of units.
141 writeInputBuffer(obj.destInternalUnits{i},varargin{i},obj.destInternalInputs(i));
143 robolog(
'Failed to write input buffer while traversing %s. Check connections and that traverse has been called enough input signals.',
'ERR', obj.label);
147 for i=obj.traversingOrder
148 traverseNode(obj.internalUnits{i});
150 [varargout{1:obj.nOutputs}] = readBuffer(obj.outputBuffer);
Superclass: basic building block to hold functions.
function inherits_from(in obj, in className)
Determine whether an object inherits from a specified superclass.
function robolog(in msg, in varargin)
This function allows the user to print log messages in a standard way.
Superclass: collection/sequence of unit.