Skip to content
Snippets Groups Projects
Commit c392fc8d authored by Tim Stadtmann's avatar Tim Stadtmann
Browse files

Merge branch 'issue-highLevelDispatch' in develop

Implements a central dispatch method (handleCommand()) on the
convenience layer through which every call to the CommInterface is
now done (as opposed to directly calling the CommInterface's
methods). This mainly facilitates debugging and is in line with
the lower layer's interfaces. It slows down each call by .5us
(because function handles are used) - imo this is an acceptable
tradeoff.
parents 22d352ce 0726e13a
Branches
Tags
No related merge requests found
classdef EV3 < MaskedHandle
classdef EV3 < MaskedHandle
% High-level class to work with physical bricks.
%
% This is the 'central' class (from user's view) when working with this toolbox. It
......@@ -295,11 +295,7 @@ classdef EV3 < MaskedHandle
'You have to call ev3.connect(...) first!']);
end
ev3.commInterface.soundPlayTone(10, 1000, 100);
if ev3.debug
fprintf('(DEBUG) EV3::beep: Sent ''soundPlayTone''-command\n');
end
ev3.handleCommand(@soundPlayTone, 10, 1000, 100);
end
function playTone(ev3, volume, frequency, duration)
......@@ -322,11 +318,7 @@ classdef EV3 < MaskedHandle
'You have to call ev3.connect(...) first!']);
end
ev3.commInterface.soundPlayTone(volume, frequency, duration);
if ev3.debug
fprintf('(DEBUG) EV3::playTone: Sent ''soundPlayTone''-command\n');
end
ev3.handleCommand(@soundPlayTone, volume, frequency, duration);
end
function stopTone(ev3)
......@@ -344,11 +336,7 @@ classdef EV3 < MaskedHandle
'You have to call ev3.connect(...) first!']);
end
ev3.commInterface.soundStopTone();
if ev3.debug
fprintf('(DEBUG) EV3::stopTone: Called ''soundStopTone''-command\n');
end
ev3.handleCommand(@soundStopTone);
end
function status = tonePlayed(ev3)
......@@ -370,11 +358,7 @@ classdef EV3 < MaskedHandle
'You have to call ev3.connect(...) first!']);
end
status = ev3.commInterface.soundTest;
if ev3.debug
fprintf('(DEBUG) EV3::tonePlayed: Called ''soundTest''-command\n');
end
status = ev3.handleCommand(@soundTest);
end
%% Setter
......@@ -488,21 +472,30 @@ classdef EV3 < MaskedHandle
end
methods (Access = private) % Private brick functions that are wrapped by dependent params
function varargout = handleCommand(ev3, commandHandle, varargin)
% Execute a CommunicationInterface-method given as a handle
%
% As those methods have different, fixed numbers of output arguments, this quantity
% has to be retrieved first.
if ev3.debug
fprintf('(DEBUG) Sending %s\n', func2str(commandHandle));
end
% Note: Arrg. MATLAB does not support nargout for class methods directly, so I have to
% do this ugly workaround using strings. See
% https://de.mathworks.com/matlabcentral/answers/96617-how-can-i-use-nargin-nargout-to-determine-the-number-of-input-output-arguments-of-an-object-method
nOut = nargout(strcat('CommunicationInterface>CommunicationInterface.', func2str(commandHandle)));
[varargout{1:nOut}] = commandHandle(ev3.commInterface, varargin{:});
end
function bat = getBattery(ev3)
% Retrieve batteryValue from brick in current mode. (Wrapped by EV3.batteryValue)
if strcmpi(ev3.batteryMode, 'Percentage')
bat = ev3.commInterface.uiReadLbatt();
if ev3.debug
fprintf('(DEBUG) EV3::getBattery: Called ''uiReadLBatt''-command\n');
end
bat = ev3.handleCommand(@uiReadLbatt);
else
bat = ev3.commInterface.uiReadVbatt();
if ev3.debug
fprintf('(DEBUG) EV3::getBattery: Called ''uiReadVBatt''-command\n');
end
bat = ev3.handleCommand(@uiReadVbatt);
end
end
......
......@@ -272,10 +272,7 @@ classdef Motor < MaskedHandle & dynamicprops
end
if motor.debug
fprintf('\n(DEBUG) Motor::start: Calling ''outputStart''-command on Port %s...\n', port2str('Motor', motor.port));
end
motor.commInterface.outputStart(0, motor.port);
motor.handleCommand(@outputStart, 0, motor.port);
motor.state.startedNotBusy = true;
else
......@@ -287,41 +284,21 @@ classdef Motor < MaskedHandle & dynamicprops
if strcmpi(motor.limitMode, 'Tacho')
if motor.speedRegulation
if motor.debug
fprintf('\n(DEBUG) Motor::start: Calling ''outputStepSpeed''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
motor.commInterface.outputStepSpeed(0, motor.port, motor.power,...
motor.handleCommand(@outputStepSpeed, 0, motor.port, motor.power,...
motor.smoothStart, limit, motor.smoothStop,...
motor.brakeMode_);
else
if motor.debug
fprintf('\n(DEBUG) Motor::start: Calling ''outputStepPower''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
motor.commInterface.outputStepPower(0, motor.port, motor.power,...
motor.handleCommand(@outputStepPower, 0, motor.port, motor.power,...
motor.smoothStart, limit, motor.smoothStop,...
motor.brakeMode_);
end
elseif strcmpi(motor.limitMode, 'Time')
if motor.speedRegulation
if motor.debug
fprintf('\n(DEBUG) Motor::start: Calling ''outputTimeSpeed''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
motor.commInterface.outputTimeSpeed(0, motor.port, motor.power,...
motor.handleCommand(@outputTimeSpeed, 0, motor.port, motor.power,...
motor.smoothStart, limit, motor.smoothStop,...
motor.brakeMode_);
else
if motor.debug
fprintf('\n(DEBUG) Motor::start: Calling ''outputTimePower''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
motor.commInterface.outputTimePower(0, motor.port, motor.power,...
motor.handleCommand(@outputTimePower, 0, motor.port, motor.power,...
motor.smoothStart, limit, motor.smoothStop,...
motor.brakeMode_);
end
......@@ -349,10 +326,7 @@ classdef Motor < MaskedHandle & dynamicprops
return;
end
if motor.debug
fprintf('\n(DEBUG) Motor::stop: Calling ''outputStop''-command on Port %s...\n', port2str('Motor', motor.port));
end
motor.commInterface.outputStop(0, motor.port, motor.brakeMode_);
motor.handleCommand(@outputStop, 0, motor.port, motor.brakeMode_);
motor.state.startedNotBusy = false;
end
......@@ -473,19 +447,11 @@ classdef Motor < MaskedHandle & dynamicprops
if strcmpi(motor.limitMode, 'Tacho')
if motor.debug
fprintf(['\n(DEBUG) Motor::syncedStart: Calling ''outputStepSync''-command on ' ,...
'Ports %s and %s.\n'], port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
end
motor.commInterface.outputStepSync(0, motor.port+syncMotor.port, ...
motor.handleCommand(@outputStepSync, 0, motor.port+syncMotor.port, ...
motor.power, turnRatio, ...
motor.limitValue, motor.brakeMode_);
elseif strcmpi(motor.limitMode, 'Time')
if motor.debug
fprintf('\n(DEBUG) Motor::start: Calling ''outputStepSync''-command on Ports %s and %s.\n',...
port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
end
motor.commInterface.outputTimeSync(0, motor.port+syncMotor.port, ...
motor.handleCommand(@outputTimeSync, 0, motor.port+syncMotor.port, ...
motor.power, turnRatio, ...
motor.limitValue, motor.brakeMode_);
end
......@@ -527,11 +493,7 @@ classdef Motor < MaskedHandle & dynamicprops
syncMotor.applyState();
% Synced stopping
if motor.debug
fprintf('\n(DEBUG) Motor::syncedStop: Calling ''outputStop''-command on Ports %s and %s.\n', ...
port2str('Motor', motor.port), port2str('Motor', syncMotor.port));
end
motor.commInterface.outputStop(0, motor.port+syncMotor.port, motor.brakeMode_);
motor.handleCommand(@outputStop, 0, motor.port+syncMotor.port, motor.brakeMode_);
% On next start, both motors have to send power-opcode again
if motor.state.sendPowerOnSet
......@@ -590,11 +552,7 @@ classdef Motor < MaskedHandle & dynamicprops
port2str('Motor', motor.port));
end
if motor.debug
fprintf('\n(DEBUG) Motor::internalReset: Calling ''outputReset''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
motor.commInterface.outputReset(0, motor.port);
motor.handleCommand(@outputReset, 0, motor.port);
end
function resetTachoCount(motor)
......@@ -609,11 +567,7 @@ classdef Motor < MaskedHandle & dynamicprops
port2str('Motor', motor.port));
end
if motor.debug
fprintf('\n(DEBUG) Motor::resetTachoCount: Calling ''outputClrCount''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
motor.commInterface.outputClrCount(0, motor.port);
motor.handleCommand(@outputClrCount, 0, motor.port);
end
function setBrake(motor, brake)
......@@ -963,7 +917,24 @@ classdef Motor < MaskedHandle & dynamicprops
end
end
methods (Access = private) % Private functions that directly interact with commLayer
methods (Access = private) % Private functions that directly interact with commLayer#
function varargout = handleCommand(motor, commandHandle, varargin)
% Execute a CommunicationInterface-method given as a handle
%
% As those methods have different, fixed numbers of output arguments, this quantity
% has to be retrieved first.
if motor.debug
fprintf('(DEBUG) Sending %s\n', func2str(commandHandle));
end
% Note: Arrg. MATLAB does not support nargout for class methods directly, so I have to
% do this ugly workaround using strings. See
% https://de.mathworks.com/matlabcentral/answers/96617-how-can-i-use-nargin-nargout-to-determine-the-number-of-input-output-arguments-of-an-object-method
nOut = nargout(strcat('CommunicationInterface>CommunicationInterface.', func2str(commandHandle)));
[varargout{1:nOut}] = commandHandle(motor.commInterface, varargin{:});
end
function success = setPower(motor, power)
% Sets given power value on the physical Brick.
%
......@@ -983,15 +954,9 @@ classdef Motor < MaskedHandle & dynamicprops
end;
if motor.currentSpeedRegulation
if motor.debug
fprintf('\n(DEBUG) Motor::setPower: Calling ''outputSpeed''-command on Port %s...\n', port2str('Motor', motor.port));
end
motor.commInterface.outputSpeed(0, motor.port, power);
motor.handleCommand(@outputSpeed, 0, motor.port, power);
else
if motor.debug
fprintf('\n(DEBUG) Motor::setPower: Calling ''outputPower''-command on Port %s...\n', port2str('Motor', motor.port));
end
motor.commInterface.outputPower(0, motor.port, power);
motor.handleCommand(@outputPower, 0, motor.port, power);
end
success = true;
return;
......@@ -1002,12 +967,7 @@ classdef Motor < MaskedHandle & dynamicprops
error('Motor::getTypeMode: Motor-Object not connected to comm handle.');
end
if motor.debug
fprintf('\n(DEBUG) Motor::getTypeMode: Calling ''inputDeviceGetTypeMode''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
[typeNo,modeNo] = motor.commInterface.inputDeviceGetTypeMode(0, motor.portInput);
[typeNo, modeNo] = motor.handleCommand(@inputDeviceGetTypeMode, 0, motor.portInput);
type = DeviceType(typeNo);
mode = DeviceMode(type,modeNo);
end
......@@ -1017,11 +977,7 @@ classdef Motor < MaskedHandle & dynamicprops
error('Motor::getStatus: Motor-Object not connected to comm handle.');
end
if motor.debug
fprintf('\n(DEBUG) Motor::getStatus: Calling ''inputDeviceGetConnection''-command on Port %s...\n',...
port2str('Motor', motor.port));
end
statusNo = motor.commInterface.inputDeviceGetConnection(0, motor.portInput);
statusNo = motor.handleCommand(@inputDeviceGetConnection, 0, motor.portInput);
status = ConnectionType(statusNo);
end
......@@ -1030,17 +986,11 @@ classdef Motor < MaskedHandle & dynamicprops
error('Motor::getTachoCount: Motor-Object not connected to comm handle.');
end
if motor.debug
fprintf('\n(DEBUG) Motor::getTachoCount: Calling ''outputGetCount''-command on Port %s...\n', port2str('Motor', motor.port));
end
cnt = motor.commInterface.outputGetCount(0, motor.portNo);
cnt = motor.handleCommand(@outputGetCount, 0, motor.portNo);
end
function cnt = getInternalTachoCount(motor)
if motor.debug
fprintf('\n(DEBUG) Motor::getInternalTachoCount: Calling ''outputRead''-command on Port %s...\n', port2str('Motor', motor.port));
end
[~, cnt] = motor.commInterface.outputRead(0, motor.portNo);
[~, cnt] = motor.handleCommand(@outputRead, 0, motor.portNo);
end
function speed = getSpeed(motor)
......@@ -1048,10 +998,7 @@ classdef Motor < MaskedHandle & dynamicprops
error('Motor::getSpeed: Motor-Object not connected to comm handle.');
end
if motor.debug
fprintf('\n(DEBUG) Motor::getSpeed: Calling ''inputReadSI''-command on Port %s...\n', port2str('Motor', motor.port));
end
speed = motor.commInterface.inputReadSI(0, motor.portInput, DeviceMode.Motor.Speed);
speed = motor.handleCommand(@inputReadSI, 0, motor.portInput, DeviceMode.Motor.Speed);
end
function busy = getBusyFlag(motor)
......@@ -1067,10 +1014,7 @@ classdef Motor < MaskedHandle & dynamicprops
error('Motor::getBusyFlag: Motor-Object not connected to comm handle.');
end
if motor.debug
fprintf('\n(DEBUG) Motor::getBusyFlag: Calling ''outputTest''-command on Port %s...\n', port2str('Motor', motor.port));
end
busy = motor.commInterface.outputTest(0, motor.port);
busy = motor.handleCommand(@outputTest, 0, motor.port);
end
function applyBrake(motor)
......@@ -1083,18 +1027,13 @@ classdef Motor < MaskedHandle & dynamicprops
error('Motor::applyBrake: Can''t apply brake because Motor is moving');
end
if motor.debug
fprintf(['\n(DEBUG) Motor::applyBrake: Calling ''outputPower'', ''outputStart'' and' ,...
'''outputStop'' on Port %s...\n'], port2str('Motor', motor.port));
end
if motor.speedRegulation
motor.commInterface.outputPower(0, motor.port, 0);
motor.handleCommand(@outputPower, 0, motor.port, 0);
else
motor.commInterface.outputSpeed(0, motor.port, 0);
motor.handleCommand(@outputSpeed, 0, motor.port, 0);
end
motor.commInterface.outputStart(0, motor.port);
motor.commInterface.outputStop(0, motor.port, BrakeMode.Brake);
motor.handleCommand(@outputStart, 0, motor.port);
motor.handleCommand(@outputStop, 0, motor.port, BrakeMode.Brake);
end
function releaseBrake(motor)
......@@ -1107,17 +1046,13 @@ classdef Motor < MaskedHandle & dynamicprops
error('Motor::releaseBrake: Can''t release brake because Motor is moving');
end
if motor.debug
fprintf(['\n(DEBUG) Motor::releaseBrake: Calling ''outputPower'', ''outputStart'' and' ,...
'''outputStop'' on Port %s...\n'], port2str('Motor', motor.port));
end
if motor.speedRegulation
motor.commInterface.outputPower(0, motor.port, 0);
motor.handleCommand(@outputPower, 0, motor.port, 0);
else
motor.commInterface.outputSpeed(0, motor.port, 0);
motor.handleCommand(@outputSpeed, 0, motor.port, 0);
end
motor.commInterface.outputStart(0, motor.port);
motor.commInterface.outputStop(0, motor.port, BrakeMode.Coast);
motor.handleCommand(@outputStart, 0, motor.port);
motor.handleCommand(@outputStop, 0, motor.port, BrakeMode.Coast);
end
end
......
......@@ -252,11 +252,7 @@ classdef Sensor < MaskedHandle
% warning(['Sensor::reset: Current version of reset resets ALL devices, that is, ',...
% 'all motor tacho counts and all other sensor counters!']);
if sensor.debug
fprintf('\n(DEBUG) Sensor::reset: Calling ''inputReadSI''-command on Port %d...\n',...
sensor.port+1);
end
sensor.commInterface.inputDeviceClrAll(0);
sensor.handleCommand(@inputDeviceClrAll, 0);
end
%% Setter
......@@ -394,11 +390,7 @@ classdef Sensor < MaskedHandle
sensor.port+1);
end
if sensor.debug
fprintf('\n(DEBUG) Sensor::setMode: Calling ''inputReadSI''-command on Port %d...\n',...
sensor.port+1);
end
sensor.commInterface.inputReadSI(0, sensor.port, mode); % Reading a value implicitly
sensor.handleCommand(@inputReadSI, 0, sensor.port, mode); % Reading a value implicitly
% sets the mode.
end
......@@ -431,11 +423,7 @@ classdef Sensor < MaskedHandle
mode = sensor.mode;
end
if sensor.debug
fprintf('\n(DEBUG) Sensor::getValue: Calling ''inputReadSI''-command on Port %d...\n',...
sensor.port+1);
end
val = sensor.commInterface.inputReadSI(0, sensor.port, sensor.mode);
val = sensor.handleCommand(@inputReadSI, 0, sensor.port, sensor.mode);
if strcmp(class(sensor.mode), 'DeviceMode.Color')
......@@ -446,11 +434,7 @@ classdef Sensor < MaskedHandle
% See note
if isnan(val)
if sensor.debug
fprintf('\n(DEBUG) Sensor::getValue: Calling ''inputReadSI''-command on Port %d...\n',...
sensor.port+1);
end
val = sensor.commInterface.inputReadSI(0, sensor.port, sensor.mode);
val = sensor.handleCommand(@inputReadSI, 0, sensor.port, sensor.mode);
end
end
......@@ -459,12 +443,7 @@ classdef Sensor < MaskedHandle
error('Sensor::getStatus: Sensor-Object not connected to comm handle.');
end
if sensor.debug
fprintf(['\n(DEBUG) Sensor::getStatus: Calling ''inputDeviceGetConnection''-command on ' ,...
'Port %d...\n'], sensor.port+1);
end
statusNo = sensor.commInterface.inputDeviceGetConnection(0, sensor.port);
statusNo = sensor.handleCommand(@inputDeviceGetConnection, 0, sensor.port);
status = ConnectionType(statusNo);
end
......@@ -475,13 +454,9 @@ classdef Sensor < MaskedHandle
type = DeviceType.Error;
if sensor.debug
fprintf(['\n(DEBUG) Sensor::getStatus: Calling ''inputDeviceGetConnection''-command on ' ,...
'Port %d...\n'], sensor.port+1);
end
for i = 1:10
try
[typeNo,modeNo] = sensor.commInterface.inputDeviceGetTypeMode(0, sensor.port);
[typeNo,modeNo] = sensor.handleCommand(@inputDeviceGetTypeMode, 0, sensor.port);
type = DeviceType(typeNo);
catch ME
continue;
......@@ -498,6 +473,25 @@ classdef Sensor < MaskedHandle
end
methods (Access = private)
function varargout = handleCommand(sensor, commandHandle, varargin)
% Execute a CommunicationInterface-method given as a handle
%
% As those methods have different, fixed numbers of output arguments, this quantity
% has to be retrieved first.
if sensor.debug
fprintf('(DEBUG) Sending %s\n', func2str(commandHandle));
end
% Note: Arrg. MATLAB does not support nargout for class methods directly, so I have to
% do this ugly workaround using strings. See
% https://de.mathworks.com/matlabcentral/answers/96617-how-can-i-use-nargin-nargout-to-determine-the-number-of-input-output-arguments-of-an-object-method
nOut = nargout(strcat('CommunicationInterface>CommunicationInterface.', func2str(commandHandle)));
[varargout{1:nOut}] = commandHandle(sensor.commInterface, varargin{:});
end
end
methods (Access = ?EV3)
function connect(sensor,commInterface)
%connect Connects Sensor-object to physical brick
......
  • Tim Stadtmann @tim.stadtmann ·
    Author Developer

    It slows down each call by .5 MILLIseconds, not microseconds...

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment