diff --git a/source/Motor.m b/source/Motor.m index a0ed2715c26aa0fb218c7bd8aae00e55f314f6af..c70b203160309ab6312880dbd798925231f36d5c 100644 --- a/source/Motor.m +++ b/source/Motor.m @@ -199,10 +199,7 @@ classdef Motor < MaskedHandle & dynamicprops function start(motor) % Starts the motor. - if ~motor.physicalMotorConnected - error('Could not detect motor at Port %s',... - port2str('Motor', motor.port)); - elseif motor.isRunning + if motor.isRunning error('Motor is already running!'); end @@ -270,7 +267,7 @@ classdef Motor < MaskedHandle & dynamicprops end - motor.handleCommand(@outputStart, 0, motor.port); + motor.handleCommand(@outputStart, true, 0, motor.port); motor.state.startedNotBusy = true; else @@ -282,21 +279,21 @@ classdef Motor < MaskedHandle & dynamicprops if strcmpi(motor.limitMode, 'Tacho') if motor.speedRegulation - motor.handleCommand(@outputStepSpeed, 0, motor.port, motor.power,... + motor.handleCommand(@outputStepSpeed, true, 0, motor.port, motor.power,... motor.smoothStart, limit, motor.smoothStop,... motor.brakeMode_); else - motor.handleCommand(@outputStepPower, 0, motor.port, motor.power,... + motor.handleCommand(@outputStepPower, true, 0, motor.port, motor.power,... motor.smoothStart, limit, motor.smoothStop,... motor.brakeMode_); end elseif strcmpi(motor.limitMode, 'Time') if motor.speedRegulation - motor.handleCommand(@outputTimeSpeed, 0, motor.port, motor.power,... + motor.handleCommand(@outputTimeSpeed, true, 0, motor.port, motor.power,... motor.smoothStart, limit, motor.smoothStop,... motor.brakeMode_); else - motor.handleCommand(@outputTimePower, 0, motor.port, motor.power,... + motor.handleCommand(@outputTimePower, true, 0, motor.port, motor.power,... motor.smoothStart, limit, motor.smoothStop,... motor.brakeMode_); end @@ -314,15 +311,12 @@ classdef Motor < MaskedHandle & dynamicprops % % See also MOTOR.START, MOTOR.SYNCEDSTOP / :meth:`start`, :meth:`syncedStop` - if ~motor.physicalMotorConnected - error('Could not detect motor at Port %s',... - port2str('Motor', motor.port)); - elseif motor.isSynced && motor.isRunning + if motor.isSynced && motor.isRunning motor.syncedStop(); return; end - motor.handleCommand(@outputStop, 0, motor.port, motor.brakeMode_); + motor.handleCommand(@outputStop, false, 0, motor.port, motor.brakeMode_); motor.state.startedNotBusy = false; end @@ -389,10 +383,7 @@ classdef Motor < MaskedHandle & dynamicprops end % Check connection and motor parameter - if ~motor.physicalMotorConnected || ~syncMotor.physicalMotorConnected - error('Could not detect motor at Port %s or %s.',... - port2str('Motor', motor.port), port2str('Motor', syncMotor.port)); - elseif motor.speedRegulation + if motor.speedRegulation error(['Cannot run motors synchronized if ',... 'speedRegulation is turned on.']); elseif motor.isRunning || syncMotor.isRunning @@ -441,11 +432,11 @@ classdef Motor < MaskedHandle & dynamicprops if strcmpi(motor.limitMode, 'Tacho') - motor.handleCommand(@outputStepSync, 0, motor.port+syncMotor.port, ... + motor.handleCommand(@outputStepSync, true, 0, motor.port+syncMotor.port, ... motor.power, turnRatio, ... motor.limitValue, motor.brakeMode_); elseif strcmpi(motor.limitMode, 'Time') - motor.handleCommand(@outputTimeSync, 0, motor.port+syncMotor.port, ... + motor.handleCommand(@outputTimeSync, true, 0, motor.port+syncMotor.port, ... motor.power, turnRatio, ... motor.limitValue, motor.brakeMode_); end @@ -475,17 +466,12 @@ classdef Motor < MaskedHandle & dynamicprops end end - if ~motor.physicalMotorConnected || ~syncMotor.physicalMotorConnected - error('Could not detect motor at Port %s or %s.',... - port2str('Motor', motor.port), port2str('Motor', syncMotor.port)); - end - % Reset state motor.applyState(); syncMotor.applyState(); % Synced stopping - motor.handleCommand(@outputStop, 0, motor.port+syncMotor.port, motor.brakeMode_); + motor.handleCommand(@outputStop, false, 0, motor.port+syncMotor.port, motor.brakeMode_); % On next start, both motors have to send power-opcode again if motor.state.sendPowerOnSet @@ -532,12 +518,7 @@ classdef Motor < MaskedHandle & dynamicprops % % See also MOTOR.RESETTACHOCOUNT / :attr:`resetTachoCount` - if ~motor.physicalMotorConnected - error('Could not detect motor at Port %s',... - port2str('Motor', motor.port)); - end - - motor.handleCommand(@outputReset, 0, motor.port); + motor.handleCommand(@outputReset, false, 0, motor.port); end function resetTachoCount(motor) @@ -545,12 +526,7 @@ classdef Motor < MaskedHandle & dynamicprops % % See also MOTOR.TACHOCOUNT / :attr:`tachoCount` - if ~motor.physicalMotorConnected - error('Could not detect motor at Port %s',... - port2str('Motor', motor.port)); - end - - motor.handleCommand(@outputClrCount, 0, motor.port); + motor.handleCommand(@outputClrCount, false, 0, motor.port); end function setBrake(motor, brake) @@ -671,8 +647,7 @@ classdef Motor < MaskedHandle & dynamicprops % If new brakeMode is 'Brake': reset internal tachocount once % Note: if new brakeMode is 'Coast', internal tachocount is always reset % right before starting, so it's not necessary here - if ~motor.init && strcmpi(brakeMode,'Brake') && ... - motor.connectedToBrick && motor.physicalMotorConnected + if ~motor.init && strcmpi(brakeMode,'Brake') motor.internalReset(); end @@ -869,6 +844,28 @@ classdef Motor < MaskedHandle & dynamicprops running = motor.state.startedNotBusy || busyFlag; end + function motorType = get.type(motor) + motorType = DeviceType.Unknown; + + if motor.connectedToBrick + [motorType, ~] = motor.getTypeMode(); + end + end + + function conn = get.physicalMotorConnected(motor) +% try +% conn = motor.isPhysicalMotorConnected(); +% catch ME +% if ~isempty(strfind(ME.identifier, 'NotConnected')) +% conn = DeviceType.Unknown; +% else +% throw(ME); +% end +% end + currentType = motor.type; + conn = (currentType==DeviceType.MediumMotor || currentType==DeviceType.LargeMotor); + end + function synced = get.isSynced(motor) synced = motor.isSlave || motor.isMaster; end @@ -881,19 +878,6 @@ classdef Motor < MaskedHandle & dynamicprops isMaster = length(findprop(motor, 'slave'))==1; end - function motorType = get.type(motor) - if motor.connectedToBrick - [motorType, ~] = motor.getTypeMode(); - else - motorType = DeviceType.Unknown; - end - end - - function conn = get.physicalMotorConnected(motor) - currentType = motor.type; - conn = (currentType==DeviceType.MediumMotor || currentType==DeviceType.LargeMotor); - end - %% Display function display(motor) displayProperties(motor); @@ -901,7 +885,7 @@ classdef Motor < MaskedHandle & dynamicprops end methods (Access = private) % Private functions that directly interact with commLayer - function varargout = handleCommand(motor, commandHandle, varargin) + function varargout = handleCommand(motor, commandHandle, checkDevice, varargin) % Execute a CommunicationInterface-method given as a handle % % As those methods have different, fixed numbers of output arguments, this quantity @@ -910,7 +894,12 @@ classdef Motor < MaskedHandle & dynamicprops if ~motor.connectedToBrick msg = ['Not connected to physical brick. ',... 'You have to call connect(...) on the EV3 object first!']; - id = [ID(), ':', 'NotConnected']; + id = [ID(), ':', 'NoConnection']; + + throw(MException(id, msg)); + elseif checkDevice && ~motor.physicalMotorConnected + msg = ['Could not detect motor at port ', port2str('Motor', motor.port), '.']; + id = [ID(), ':', 'NoDevice']; throw(MException(id, msg)); end @@ -926,21 +915,20 @@ classdef Motor < MaskedHandle & dynamicprops try [varargout{1:nOut}] = commandHandle(motor.commInterface, varargin{:}); catch ME - %motor.ev3Handle.detectedCommError(ME.identifier, ME.message); if ~isempty(strfind(ME.identifier, 'CommError')) warning('Lost connection to the Brick!'); - motor.disconnect(); +% motor.disconnect(); else - warning('Something went wrong. Trying to reset the connection...'); - motor.disconnect(); - motor.connect(); + warning('Something went wrong. Try to reset the connection.'); +% motor.disconnect(); +% motor.connect(); end throw(exception); end end - function success = setPower(motor, power) + function success = setPower(motor, power) %% TODO % Sets given power value on the physical Brick. % % Notes: @@ -959,38 +947,56 @@ classdef Motor < MaskedHandle & dynamicprops end; if motor.currentSpeedRegulation - motor.handleCommand(@outputSpeed, 0, motor.port, power); + motor.handleCommand(@outputSpeed, true, 0, motor.port, power); else - motor.handleCommand(@outputPower, 0, motor.port, power); + motor.handleCommand(@outputPower, true, 0, motor.port, power); end success = true; return; end function [type,mode] = getTypeMode(motor) - [typeNo, modeNo] = motor.handleCommand(@inputDeviceGetTypeMode, 0, motor.portInput); +% try +% [typeNo, modeNo] = motor.handleCommand(@inputDeviceGetTypeMode, false, 0, motor.portInput); +% type = DeviceType(typeNo); +% mode = DeviceMode(type,modeNo); +% catch ME +% if ~isempty(strfind(ME.identifier, 'NotConnected')) +% type = DeviceType.Unknown; +% mode = DeviceMode.Default; +% end +% end + [typeNo, modeNo] = motor.handleCommand(@inputDeviceGetTypeMode, false, 0, motor.portInput); type = DeviceType(typeNo); mode = DeviceMode(type,modeNo); end function status = getStatus(motor) - statusNo = motor.handleCommand(@inputDeviceGetConnection, 0, motor.portInput); +% try +% statusNo = motor.handleCommand(@inputDeviceGetConnection, false, 0, motor.portInput); +% status = ConnectionType(statusNo); +% catch ME +% if ~isempty(strfind(ME.identifier, 'NotConnected')) +% status = ConnectionType.Unknown; +% end +% end + statusNo = motor.handleCommand(@inputDeviceGetConnection, false, 0, motor.portInput); status = ConnectionType(statusNo); end function cnt = getTachoCount(motor) - cnt = motor.handleCommand(@outputGetCount, 0, motor.portNo); + cnt = motor.handleCommand(@outputGetCount, false, 0, motor.portNo); end function cnt = getInternalTachoCount(motor) - [~, cnt] = motor.handleCommand(@outputRead, 0, motor.portNo); + [~, cnt] = motor.handleCommand(@outputRead, false, 0, motor.portNo); end function speed = getSpeed(motor) - speed = motor.handleCommand(@inputReadSI, 0, motor.portInput, DeviceMode.Motor.Speed); + speed = motor.handleCommand(@inputReadSI, false, 0, motor.portInput, DeviceMode.Motor.Speed); end - function busy = getBusyFlag(motor) + function busy = getBusyFlag(motor) %% TODO %getMotorStatus Returns whether motor is busy or not. % % Notes: @@ -998,41 +1004,35 @@ classdef Motor < MaskedHandle & dynamicprops % called immediately after starting the motor. % * Busy is set to true if motor is running with tacholimit or synced % - busy = motor.handleCommand(@outputTest, 0, motor.port); + busy = motor.handleCommand(@outputTest, false, 0, motor.port); end function applyBrake(motor) - if ~motor.physicalMotorConnected - error('Could not detect motor at Port %s',... - port2str('Motor', motor.port)); - elseif motor.currentSpeed~=0 + if motor.currentSpeed~=0 error('Can''t apply brake because Motor is moving'); end if motor.speedRegulation - motor.handleCommand(@outputPower, 0, motor.port, 0); + motor.handleCommand(@outputPower, true, 0, motor.port, 0); else - motor.handleCommand(@outputSpeed, 0, motor.port, 0); + motor.handleCommand(@outputSpeed, true, 0, motor.port, 0); end - motor.handleCommand(@outputStart, 0, motor.port); - motor.handleCommand(@outputStop, 0, motor.port, BrakeMode.Brake); + motor.handleCommand(@outputStart, false, 0, motor.port); + motor.handleCommand(@outputStop, false, 0, motor.port, BrakeMode.Brake); end function releaseBrake(motor) - if ~motor.physicalMotorConnected - error('Could not detect motor at Port %s',... - port2str('Motor', motor.port)); - elseif motor.currentSpeed~=0 + if motor.currentSpeed~=0 error('Can''t release brake because Motor is moving'); end if motor.speedRegulation - motor.handleCommand(@outputPower, 0, motor.port, 0); + motor.handleCommand(@outputPower, true, 0, motor.port, 0); else - motor.handleCommand(@outputSpeed, 0, motor.port, 0); + motor.handleCommand(@outputSpeed, true, 0, motor.port, 0); end - motor.handleCommand(@outputStart, 0, motor.port); - motor.handleCommand(@outputStop, 0, motor.port, BrakeMode.Coast); + motor.handleCommand(@outputStart, false, 0, motor.port); + motor.handleCommand(@outputStop, false, 0, motor.port, BrakeMode.Coast); end end diff --git a/source/Sensor.m b/source/Sensor.m index ffdb7aca409ae40bc95f8b73b92357a23a82aa49..89507751c6da37752df7c6d2607dbc8b9c75c53b 100644 --- a/source/Sensor.m +++ b/source/Sensor.m @@ -243,14 +243,9 @@ classdef Sensor < MaskedHandle % * This clears ALL the sensors right now, no other Op-Code available... :( % - if ~sensor.physicalSensorConnected - error('Could not detect sensor at Port %d',... - sensor.port+1); - end - % warning(['Current version of reset resets ALL devices, that is, ',... % 'all motor tacho counts and all other sensor counters!']); - sensor.handleCommand(@inputDeviceClrAll, 0); + sensor.handleCommand(@inputDeviceClrAll, false, 0); end %% Setter @@ -381,13 +376,7 @@ classdef Sensor < MaskedHandle methods (Access = private) % Private brick functions that are wrapped by dependent params function setMode(sensor, mode) - if ~sensor.physicalSensorConnected - error('Could not detect sensor at Port %d',... - sensor.port+1); - end - - sensor.handleCommand(@inputReadSI, 0, sensor.port, mode); % Reading a value implicitly - % sets the mode. + sensor.handleCommand(@inputReadSI, true, 0, sensor.port, mode); % Reading a value implicitly sets the mode. end function val = getValue(sensor, varargin) @@ -415,7 +404,7 @@ classdef Sensor < MaskedHandle mode = sensor.mode; end - val = sensor.handleCommand(@inputReadSI, 0, sensor.port, sensor.mode); + val = sensor.handleCommand(@inputReadSI, false, 0, sensor.port, sensor.mode); if strcmp(class(sensor.mode), 'DeviceMode.Color') @@ -426,12 +415,12 @@ classdef Sensor < MaskedHandle % See note if isnan(val) - val = sensor.handleCommand(@inputReadSI, 0, sensor.port, sensor.mode); + val = sensor.handleCommand(@inputReadSI, false, 0, sensor.port, sensor.mode); end end function status = getStatus(sensor) - statusNo = sensor.handleCommand(@inputDeviceGetConnection, 0, sensor.port); + statusNo = sensor.handleCommand(@inputDeviceGetConnection, false, 0, sensor.port); status = ConnectionType(statusNo); end @@ -440,7 +429,7 @@ classdef Sensor < MaskedHandle for i = 1:10 try - [typeNo,modeNo] = sensor.handleCommand(@inputDeviceGetTypeMode, 0, sensor.port); + [typeNo,modeNo] = sensor.handleCommand(@inputDeviceGetTypeMode, false, 0, sensor.port); type = DeviceType(typeNo); catch ME continue; @@ -455,7 +444,7 @@ classdef Sensor < MaskedHandle end end - function varargout = handleCommand(sensor, commandHandle, varargin) + function varargout = handleCommand(sensor, commandHandle, checkDevice, varargin) % Execute a CommunicationInterface-method given as a handle % % As those methods have different, fixed numbers of output arguments, this quantity @@ -466,6 +455,11 @@ classdef Sensor < MaskedHandle 'You have to call connect(...) on the EV3 object first!']; id = [ID(), ':', 'NotConnected']; + throw(MException(id, msg)); + elseif checkDevice && ~sensor.physicalSensorConnected + msg = ['Could not detect sensor at port %d', sensor.port+1, '.']; + id = [ID(), ':', 'NoDevice']; + throw(MException(id, msg)); end @@ -483,11 +477,11 @@ classdef Sensor < MaskedHandle %sensor.ev3Handle.detectedCommError(ME.identifier, ME.message); if ~isempty(strfind(ME.identifier, 'CommError')) warning('Lost connection to the Brick!'); - sensor.disconnect(); +% sensor.disconnect(); else - warning('Something went wrong. Trying to reset the connection...'); - sensor.disconnect(); - sensor.connect(); + warning('Something went wrong. Try to reset the connection.'); +% sensor.disconnect(); +% sensor.connect(); end throw(exception);