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

Change internal flag-semantics in Motor-class

This is done to facilitate their usage, and even fixes some bugs at the
same time (Issues #29 and #34).
parent 38f3fbf4
No related branches found
No related tags found
No related merge requests found
......@@ -94,16 +94,17 @@ classdef Motor < MaskedHandle & dynamicprops
% to be sent, is saved (hidden from the user).
brakeMode_;
%% Miscallenous flags
connectedToBrick = false; % Connection to physical Brick?
sendPowerOnNextStart = false; % Indicates whether current power parameter should be sent
% to the Brick right before starting it next time
sendPowerOnSet = false; % Indicates whether power parameter should be sent to the Brick
% immediately after setting it
limitSetToZero = false; % Indicates whether limitValue has been set to zero
% (workaround for a bug, see motor.start, Note 2)
init = true; % Indicates 'init-phase' (True as long as constructor is running)
%% Flags
connectedToBrick = false; % Connection to physical Brick?
init = true; % Indicates 'init-phase' (True as long as constructor is running)
sendPowerOnSet = false; % If true, OUTPUT_POWER is sent when setting power
% Bitfield representing which opCodes should be sent on Motor.start()
% The corresponding opCodes for each bit are (in Big Endian):
% * 1st Bit: OUTPUT_POWER (sets power on physical Brick)
% * 2nd Bit: OUTPUT_STOP (stops Brick; workaround for a bug, see motor.start, Note 2)
sendOnStart = 0;
end
properties (Hidden, Dependent, Access = 'private') % Hidden, dependent properties for internal use only
......@@ -165,29 +166,33 @@ classdef Motor < MaskedHandle & dynamicprops
if motor.isSynced
delete(motor.findprop('syncCache'));
end
% Trigger warning if power = 0 (as it still sets the motor internally in a
% 'running' mode
% if motor.power == 0
% warning('Motor::start: Motor starting with power=0.');
% end
if motor.brakeMode_ == BrakeMode.Coast
motor.reset();
motor.internalReset();
end
% if motor.internalTachoCount ~= 0
% motor.reset();
% end
% Call right function in commInterface depending on limitValue and limitMode
% Call appropriate function in commInterface depending on limitValue and limitMode
if motor.limitValue==0
if motor.sendPowerOnNextStart
if motor.limitSetToZero
motor.stop();
motor.limitSetToZero = false;
if motor.sendOnStart > 0
if bitget(motor.sendOnStart, SendOnStart.Stop)
motor.stop();
motor.sendOnStart = bitset(motor.sendOnStart, SendOnStart.Stop, 0);
end
if bitget(motor.sendOnStart, SendOnStart.Power)
success = motor.setPower(motor.power);
if ~success
motor.sendOnStart = bitset(motor.sendOnStart, SendOnStart.Power, 1);
else
motor.sendOnStart = bitset(motor.sendOnStart, SendOnStart.Power, 0);
end
end
motor.setPower(motor.power);
end
motor.commInterface.outputStart(0, motor.port);
......@@ -444,16 +449,16 @@ classdef Motor < MaskedHandle & dynamicprops
% -> No need to check if motor is connected as speed correctly
% returns 0 if it's not
%
motor.commInterface.outputReady(0, motor.port);
% % if ~motor.connectedToBrick
% % error(['Motor::waitFor: Motor-Object not connected to comm handle.',...
% % 'You have to call motor.connect(commInterface) first!']);
% % end
% %
% % pause(0.1);
% % while motor.isRunning
% % pause(0.03);
% % end
if ~motor.connectedToBrick
error(['Motor::waitFor: Motor-Object not connected to comm handle.',...
'You have to call motor.connect(commInterface) first!']);
end
%pause(0.1);
while motor.isRunning
pause(0.03);
end
% elseif ~motor.limitValue
% error(['Motor::waitFor: Motor has no tacho limit. ' ,...
% 'Can''t reliably determine whether it is running or not.']);
......@@ -485,28 +490,31 @@ classdef Motor < MaskedHandle & dynamicprops
% end
end
function reset(motor)
%reset Resets internal tacho count
% The internal tacho count is used for positioning the motor. For example, when the
function internalReset(motor)
%internalReset Resets internal tacho count
% Use this if motor behaves weird (i.e. not starting at all, or not correctly
% running to limitValue)
%
% The internal tacho count is used for positioning the motor. When the
% motor is running with a tacho limit, internally it uses another counter than the
% one read by tachoCount. This internal tacho count needs to be reset if you
% physically change the motor's position.
% physically change the motor's position or it coasted into a stop.
%
% See also MOTOR.RESETTACHOCOUNT
%
if ~motor.connectedToBrick
error(['Motor::reset: Motor-Object not connected to brick handle.',...
error(['Motor::internalReset: Motor-Object not connected to brick handle.',...
'You have to call motor.connect(brick) first!']);
elseif ~motor.physicalMotorConnected
error('Motor::reset: No physical motor connected to Port %s',...
error('Motor::internalReset: No physical motor connected to Port %s',...
port2str('Motor', motor.port));
end
motor.commInterface.outputReset(0, motor.port);
if motor.debug
fprintf('(DEBUG) Motor::reset: Called outputReset on Port %s\n',...
fprintf('(DEBUG) Motor::internalReset: Called outputReset on Port %s\n',...
port2str('Motor', motor.port));
end
end
......@@ -529,6 +537,28 @@ classdef Motor < MaskedHandle & dynamicprops
end
end
function releaseBrake(motor)
if ~motor.connectedToBrick
error(['Motor::releaseBrake: Motor-Object not connected to comm handle.',...
'You have to call motor.connect(commInterface) first!']);
elseif ~motor.physicalMotorConnected
error('Motor::releaseBrake: No physical motor connected to Port %s',...
port2str('Motor', motor.port));
elseif motor.isRunning
error('Motor::releaseBrake: Can''t loose brake because Motor is runnning');
end
motor.commInterface.outputPower(0, motor.port, 0);
motor.commInterface.outputStart(0, motor.port);
motor.commInterface.outputStop(0, motor.port, BrakeMode.Coast);
motor.sendPowerOnNextStart = true;
end
function state(motor)
fprintf('sendPowerOnSet: %d\n', uint8(motor.sendPowerOnSet));
fprintf('sendOnStart: %d\n', uint8(motor.sendOnStart));
end
%% Setter
function set.power(motor, power)
if ~isnumeric(power)
......@@ -539,22 +569,33 @@ classdef Motor < MaskedHandle & dynamicprops
end
motor.power = power; % Set power parameter.
motor.sendPowerOnNextStart = true; % Indicate that virtual and physical brick have different power
% parameters right now. See 'setPower' for more info.
if motor.sendPowerOnSet && motor.connectedToBrick && ...
motor.physicalMotorConnected
motor.setPower(power); % Update physical brick's power parameter.
if motor.sendPowerOnSet
success = motor.setPower(power);
if ~success
motor.sendOnStart = bitset(motor.sendOnStart, SendOnStart.Power, 1);
else
motor.sendOnStart = bitset(motor.sendOnStart, SendOnStart.Power, 0);
end
end
end
function set.speedRegulation(motor, speedRegulation)
if ~isBool(speedRegulation)
error('Motor::set.speedRegulation: Given parameter is not a bool.');
elseif motor.connectedToBrick && motor.physicalMotorConnected && ...
motor.currentSpeed ~= 0
error(['Motor::set.speedRegulation: Cannot change speed regulation while ', ...
'is motor is moving.']);
end
if any(motor.speedRegulation) && speedRegulation ~= motor.speedRegulation
if motor.sendPowerOnSet
motor.sendOnStart = bitset(motor.sendOnStart, SendOnStart.Power, 1);
end
end
motor.speedRegulation = str2bool(speedRegulation);
motor.sendPowerOnNextStart = true;
end
function set.smoothStart(motor, steps)
......@@ -593,11 +634,10 @@ classdef Motor < MaskedHandle & dynamicprops
motor.brakeMode_ = str2brake(brakeMode);
if ~motor.init && motor.brakeMode_~=oldMode && ...
motor.connectedToBrick && motor.physicalMotorConnected
motor.reset();
% motor.setBrakeMode();
end
% if ~motor.init && motor.brakeMode_~=oldMode && ...
% motor.connectedToBrick && motor.physicalMotorConnected
% motor.internalReset();
% end
end
function set.limitMode(motor, limitMode)
......@@ -615,16 +655,16 @@ classdef Motor < MaskedHandle & dynamicprops
elseif limitValue<0
warning('Motor::set.limitValue: limitValue has to be positive!');
error('Motor::set.limitValue: Given limitValue is out of bounds.');
elseif any(motor.limitValue)
if limitValue==0 && motor.limitValue~=0
motor.sendPowerOnNextStart = true;
motor.limitSetToZero = true;
end
end
end
if limitValue == 0
motor.sendOnStart = SendOnStart.Power;
if any(motor.limitValue) && motor.limitValue > 0
motor.sendOnStart = motor.sendOnStart + SendOnStart.Stop;
end
motor.sendPowerOnSet = true;
else
motor.sendOnStart = 0;
motor.sendPowerOnSet = false;
end
......@@ -731,9 +771,9 @@ classdef Motor < MaskedHandle & dynamicprops
motor.smoothStart = p.Results.smoothStart;
motor.smoothStop = p.Results.smoothStop;
if motor.limitValue == 0
motor.sendPowerOnSet = true;
end
% if motor.limitValue == 0
% motor.sendPowerOnSet = true;
% end
end
%% Getter
......@@ -797,8 +837,8 @@ classdef Motor < MaskedHandle & dynamicprops
end
end
methods (Access = 'private') % Private brick functions that are wrapped by dependent params
function setPower(motor, power)
methods (Access = 'private') % Private Getter/Setter that directly get/set values on the physical Brick
function success = setPower(motor, power)
%setPower Sets given power value on the physical Brick.
%
% Notes:
......@@ -808,9 +848,11 @@ classdef Motor < MaskedHandle & dynamicprops
% with the new value instantly. However, this sometimes leads to unexpected behaviour.
% Therefore, if motor is running with a limit, setPower aborts with a warning.
%
if ~motor.connectedToBrick
error(['Motor::getTachoCount: Motor-Object not connected to comm handle.',...
'You have to call motor.connect(commInterface) first!']);
if ~motor.connectedToBrick || ~motor.physicalMotorConnected
% error(['Motor::getTachoCount: Motor-Object not connected to comm handle.',...
% 'You have to call motor.connect(commInterface) first!']);
success = false;
return;
end
% assert(motor.physicalMotorConnected==true);
......@@ -829,8 +871,10 @@ classdef Motor < MaskedHandle & dynamicprops
fprintf('(DEBUG) Motor::setPower: Called outputPower on Port %s\n', port2str('Motor', motor.port));
end
end
motor.sendPowerOnNextStart = false;
end
%motor.sendPowerOnNextStart = false;
success = true;
return;
end
function setMode(motor, mode) %% DEPRECATED
if ~motor.connectedToBrick
......
classdef SendOnStart < uint8
enumeration
Power (1)
Stop (2)
end
end
  • Tim Stadtmann @tim.stadtmann ·
    Author Developer

    Also temporarily added functions for test-purposes

  • Tim Stadtmann @tim.stadtmann

    Mentioned in commit 789341a4

    ·

    Mentioned in commit 789341a4

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