2 properties (GetAccess=
public,SetAccess=
protected,Hidden=
true)
8 properties (GetAccess=
public,SetAccess=
public)
14 properties (GetAccess=public,SetAccess=private,Hidden)
18 properties (Abstract=true,Hidden=true)
24 varargout = traverse(obj,varargin);
30 obj.ID = java.rmi.server.UID();
31 obj.label = class(obj);
34 if isempty(obj.draw), obj.draw = true; end
37 function traverseNode(obj)
39 %Check
# of inputs and outputs 40 if obj.nInputs~=numel(obj.inputBuffer);
41 robolog(
'Number of connected inputs must be equal to the number of module inputs. %s has %d inputs; %d in were given',
'ERR', obj.label, obj.nInputs, numel(obj.inputBuffer));
43 if obj.nOutputs~=numel(obj.nextNodes);
44 robolog(
'Number of outputs must be equal to the number of connected units. %s has %d outputs; %d destination units were specified',
'ERR', obj.label, obj.nOutputs, numel(obj.nextNodes));
47 % Helper
function with one argument. Checks
if all elements of
49 areallsignalinterfaces = @(var)all(cellfun(@(obj)isa(obj,
'signal_interface'),var));
51 % Check
if inputs are ready
52 if ~areallsignalinterfaces(obj.inputBuffer)
53 robolog('The inputs are not ready yet. Incorrect topology ordering.', 'ERR');
55 [outputs{1:obj.nOutputs}] = traverse(obj,obj.inputBuffer{:}); % Traverse the
unit 56 if(~ispref(
'robochameleon',
'debugMode') || ~getpref(
'robochameleon',
'debugMode'))
57 obj.
inputBuffer = {}; % Remove processed inputs to save memory
61 if obj.draw, drawnow;
end 63 % Check
if outputs are correctly returned: as a cell array, all
66 if ~iscell(outputs) || ~areallsignalinterfaces(outputs)
67 robolog('Output from the traverse function is not a cell array or not all of its elements are of class
signal_interface.', 'ERR');
69 if numel(outputs)~=obj.nOutputs
70 %Changed from error to warning on June 12 2014 by Molly
71 %
robolog('Size of the outputs cell is incorrect (expected vector with length %d, got %d).',obj.nOutputs,numel(outputs));
72 robolog('Size of the outputs cell has changed (expected vector with length %d, got %d).', 'WRN', obj.nOutputs,numel(outputs));
75 % Find all connected outputs
77 % Write all outputs to the inputBuffer of the connected units
79 writeInputBuffer(obj.nextNodes{i},outputs{i},obj.destInputs(i));
84 function connectOutput(obj,uobj,unitOutput,nextUnitInput)
85 % Connects a single output to a single input
87 robolog(
'All successive nodes must inherit from unit.',
'ERR');
89 obj.nextNodes{unitOutput} = uobj;
90 obj.destInputs(unitOutput) = nextUnitInput;
93 function connectOutputs(obj,units,destInputs)
95 %convert input array of units to cell array
96 %necessary to keep
this to deal with 1x1
case - overwriting
97 %horzcat and vertcat doesn
't cover this case 99 units = mat2cell(units(:), ones(1, numel(units)), 1); 102 % If destination port not specified, assign based on context. 103 % Throw an error if this is not possible. 105 if numel(units)==obj.nOutputs 106 destInputs = ones(1,obj.nOutputs); 107 elseif (numel(units)==1) && (units{1}.nInputs == obj.nOutputs) 108 destInputs = 1:obj.nOutputs; 109 units = repmat(units, obj.nOutputs, 1); 111 robolog('Destination inputs must be specified.
', 'ERR
'); 113 elseif ~isnumeric(destInputs)||~isvector(destInputs) 114 robolog('Destination inputs must be specified as a vector of integers.
', 'ERR
'); 117 if numel(units)~=obj.nOutputs || ~isvector(units) 118 robolog('Number of connected units must be equal to the number of output signals. %s has %d outputs; %d destination units were specified
', 'ERR
', obj.label, obj.nOutputs, numel(units)); 121 % Check that destination makes basic sense 122 destMax = cellfun(@(x)x.nInputs, units); 123 if any(destInputs(:)>destMax(:)) 124 badone = find(destInputs(:)>destMax(:)); 125 robolog('Specified input exceeds allowed number of inputs. \n%s has %d inputs, so you cannot connect to port %d.
', 'ERR
', units{badone}.label, units{badone}.nInputs, destInputs(badone)); 127 if any(destInputs(:)<1) 128 robolog('Input numbers must be 1 or greater
', 'ERR
'); 133 obj.connectOutput(units{i},i,destInputs(i)); 137 function writeInputBuffer(obj,sig,inputId) 138 obj.inputBuffer{inputId} = sig; 141 function newobj = horzcat(varargin) 143 newobj{jj} = varargin{jj}; 147 function newobj = vertcat(varargin) 149 newobj{jj} = varargin{jj}; 154 function setparams(obj,
params,REQUIRED_PARAMS, QUIET_PARAMS)
155 DEFAULT_QUIET_PARAMS = {
'nInputs',
'nOutputs',
'results',
'label',
'draw'};
156 if nargin<3, REQUIRED_PARAMS = {};
end 158 QUIET_PARAMS = DEFAULT_QUIET_PARAMS;
160 QUIET_PARAMS = [QUIET_PARAMS DEFAULT_QUIET_PARAMS];
162 PROTECTED_NAMES = {
'inputBuffer',
'nextNodes',
'destInputs'};
167 f =
params; %Some units pass empty cell to setparams -
this is not ideal, but not a huge problem
172 %Check
if required properties are specified
173 reqm = ismember(REQUIRED_PARAMS,f);
174 if ~isempty(reqm) && ~all(reqm)
175 robolog(
'Required parameters %s were not passed.',
'ERR', strjoin(strcat(
'''',REQUIRED_PARAMS(~reqm),''''),
', '));
178 % Remove
protected properties
179 [
protected,protected_idx] = intersect(f,PROTECTED_NAMES);
180 if ~isempty(
protected)
181 robolog(
'Protected class properties %s were removed from being assigned.',
'WRN', strjoin(strcat(
'''',protected,''''),
', '),
'WRN');
183 xi2 =
false(size(f)); xi2(protected_idx)=
true;
186 % Find unused parameters
187 props = properties(obj); props=props(:)
'; 188 [fassign,ai,bi] = intersect(f,props); 189 [~,~,ci] = intersect(QUIET_PARAMS,props); 190 ai2 = false(size(f)); ai2(ai)=true; ai2=~ai2; 191 bi2 = false(size(props)); bi2(bi)=true; bi2(ci)=true; bi2=~bi2; 192 if any(ai2), robolog('Following properties: %s are not used by the
class.
', 'NFO0
', strjoin(strcat('''',f(ai2),
''''),',
')); end 194 robolog('The following properties use
default value from %s (%s):
', 'NFO0
', obj.label, class(obj)); 195 defProp = props(bi2); 196 mTxtL = max(cellfun(@(x) numel(x), defProp)); 197 for pri=1:numel(defProp) 198 prVal = obj.(defProp{pri}); 199 if isnumeric(prVal) || islogical(prVal) 200 strVal = num2str(prVal); 204 strVal = sprintf('Default value of type %s
', class(prVal)); 206 robolog(['%
' num2str(mTxtL + 3) 's: %s
'], 'NFO0
', defProp{pri}, strVal); 209 for i=1:numel(fassign) 210 mp = findprop(obj,fassign{i}); 211 if strcmp(mp.SetAccess, 'public') % Assign only public properties 212 obj.(fassign{i}) = params.(fassign{i}); 214 robolog('Private
property:
''%s
'' not assigned.
', 'NFO0
', fassign{i}); 220 unit_view(obj.nextNodes,obj.destInputs,obj.label); Superclass: basic building block to hold functions.
Signal description class.
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.
function end(in obj, in k, in n)
Overload of indexing end statement.
Property inputBuffer
Buffer for storing inputs as we traverse the graph.
function params(in obj)
Returns signal parameters in a struct.